152 lines
9.1 KiB
Markdown
152 lines
9.1 KiB
Markdown
# Architecture
|
|
|
|
Regex Tools is a static browser application with framework-neutral regex
|
|
boundaries.
|
|
|
|
```text
|
|
React workbench
|
|
├─ Pattern SyntaxSupervisor → syntax.worker
|
|
│ ├─ Regexpp ECMAScript provider → normalized AST
|
|
│ ├─ PCRE2 lexical provider → partial normalized structure
|
|
│ ├─ Python lexical provider → partial normalized structure
|
|
│ └─ Java lexical provider → partial normalized structure
|
|
├─ Replacement SyntaxSupervisor → syntax.worker → typed replacement tokens
|
|
├─ EngineSupervisor
|
|
│ ├─ ecmascript.worker → native RegExp → match DTOs
|
|
│ ├─ pcre2.worker → PCRE2 10.47 WASM ABI → match DTOs
|
|
│ ├─ python.worker → Pyodide 314.0.3 → CPython 3.14.2 re → match DTOs
|
|
│ └─ java.worker → TeaVM 0.15.0 java.util.regex module → match DTOs
|
|
├─ Pcre2TraceSupervisor → pcre2-trace.worker
|
|
│ └─ separate ABI-v3 PCRE2_AUTO_CALLOUT operation → bounded trace DTOs
|
|
├─ AnalysisPanel
|
|
│ ├─ normalized-AST ECMAScript static heuristics
|
|
│ └─ AnalysisSupervisor → analysis.worker → native RegExp benchmark/growth probes
|
|
├─ ComparisonOrchestrator
|
|
│ ├─ two exact syntax snapshots + independently killable engine workers
|
|
│ └─ normalized UTF-16 match/capture alignment + explicit incomplete states
|
|
├─ PCRE2 C17 generator → validated snapshot → exact UTF-8 byte-array source
|
|
├─ SubjectMinimizer
|
|
│ ├─ fixed syntax snapshots + exact real-engine failure or comparison oracle
|
|
│ └─ deterministic Unicode-scalar reducer → bounded local-minimal result
|
|
├─ CaseGenerationOrchestrator
|
|
│ ├─ generation.worker → deterministic bounded ECMAScript AST candidates
|
|
│ └─ EngineSupervisor → selected actual-engine label verification
|
|
├─ ECMAScript literal/control formatter
|
|
│ ├─ exact regexpp literal-token ranges → idempotent candidate preview
|
|
│ └─ PatternFormatValidator → paired syntax + actual-engine workers and exact tests
|
|
├─ Corpus EngineSupervisor → sequential bounded document jobs → summaries/outputs
|
|
├─ Test SyntaxSupervisor + EngineSupervisor → isolated cancellable test runs
|
|
└─ project validator / serializer / IndexedDB persistence
|
|
```
|
|
|
|
Provider AST objects never cross the worker boundary. The syntax worker emits
|
|
application-owned nodes, tokens, diagnostics, capture definitions and explicit
|
|
provenance. React never imports or traverses regexpp's cyclic AST.
|
|
|
|
Every engine request carries a protocol version, monotonically increasing
|
|
request ID and worker generation. A supervisor allows one active request,
|
|
rejects stale responses, terminates on timeout/crash/cancel, and lazily creates
|
|
a new generation. Timeout is a distinct error state. A separate idempotent
|
|
load operation verifies a worker's runtime identity before execution; its
|
|
flavour-specific startup deadline is not charged to the 250 ms live or selected
|
|
manual execution deadline. A killed generation must load and verify again.
|
|
|
|
The Python worker imports only the self-hosted Pyodide loader and pack, then
|
|
evaluates the application-owned bounded bridge in CPython. The bridge returns
|
|
code-point ranges, which are retained as native values and converted only at
|
|
valid boundaries to editor UTF-16. The Java worker imports a verified TeaVM
|
|
ES2015 module. That module executes TeaVM's own `java.util.regex.Pattern` and
|
|
`Matcher` class-library implementation and returns native UTF-16 ranges; it is
|
|
not OpenJDK.
|
|
|
|
PCRE2 tracing is not an `EngineSupervisor` match or replacement operation. Its
|
|
own worker compiles with `PCRE2_AUTO_CALLOUT`, copies only complete fixed
|
|
records and bounded mark bytes, and stops natively at either trace cap.
|
|
Reported callout fields retain byte positions; movement classifications are a
|
|
separate derived UI layer. Normal execution, corpus, tests and benchmarks never
|
|
run through the trace operation.
|
|
|
|
Static analysis traverses the normalized ECMAScript tree on the UI side under
|
|
node/finding caps. Timing and generated-input growth probes use the independent
|
|
analysis worker. Timeout, cancellation or crash discards that worker; no trace
|
|
mode is benchmarked.
|
|
|
|
Comparison is a separate orchestration layer, not an `EngineSupervisor`
|
|
operation. It runs explicit ECMAScript and PCRE2 syntax/execution snapshots,
|
|
retains each engine identity and native range model, and aligns only normalized
|
|
editor ranges. Timeout, cancellation, compile rejection and truncation remain
|
|
distinct non-comparable outcomes. Shared patterns are sent unchanged;
|
|
per-flavour ports are user-owned variants.
|
|
|
|
The PCRE2 C generator is application-owned and never implements browser
|
|
execution. It validates one exact PCRE2 snapshot, emits user strings as
|
|
independent UTF-8 byte arrays, and states the host-level mappings that the
|
|
PCRE2 API cannot express directly. Its advertised C17 target is protected by
|
|
deterministic golden identities and an exact PCRE2 10.47 compile/execute gate.
|
|
|
|
Subject minimization is a main-thread bounded reducer whose expensive predicate
|
|
checks stay in independently terminable ECMAScript or PCRE2 workers. Fixed
|
|
pattern syntax is parsed once for capture metadata. Python and Java are blocked
|
|
at this feature boundary rather than routed to a different engine. The baseline
|
|
and every accepted candidate retain the exact target and engine identity.
|
|
Timeout, crash, cancellation, worker failure and incomplete output are separate
|
|
outcomes. Deterministic ddmin deletion is followed by a fixed-point local sweep
|
|
over Unicode-scalar deletion and lower-rank canonical replacement; only
|
|
completion of that sweep permits a transform-local minimality claim.
|
|
|
|
Generated-case synthesis and verification are separate trust boundaries. The
|
|
dedicated generation worker receives only a validated, complete ECMAScript
|
|
normalized tree plus explicit settings and seed. The main-thread orchestrator
|
|
then sends each bounded candidate to `EngineSupervisor`; only the selected real
|
|
adapter can establish a `should-match` or `should-not-match` label. Worker
|
|
timeout, crash, cancellation, compile rejection, wrong outcome and ordinary
|
|
failure stay distinct. Settings/results are ephemeral, while explicitly added
|
|
unit tests retain field-validated generator provenance.
|
|
|
|
Formatting is not an engine operation and never rewrites from heuristic text
|
|
alone. The ECMAScript formatter consumes an exact accepted regexpp snapshot and
|
|
changes only parser-reported literal/control token ranges. Its validator
|
|
reparses source and candidate separately, preserves capture shape, runs both in
|
|
separate actual-engine workers against the current replacement snapshot, then
|
|
replays every enabled test tied to the exact active pattern/version/flags/options.
|
|
Any difference, incomplete output, one-sided timeout, identity change or
|
|
inconclusive worker outcome blocks apply. The preview and observations are
|
|
ephemeral, and user confirmation is required even after all bounded gates pass.
|
|
|
|
Pattern and replacement syntax use independent supervisors. A pattern snapshot
|
|
is bound to its exact pattern, ordered flags and revision; execution cannot use
|
|
acceptance or capture metadata from an earlier input. Replacement output is
|
|
built while the native engine produces the same bounded authoritative match
|
|
sequence that is returned to the UI.
|
|
|
|
Per-match replacement ranges and token contributions are deterministic mappings
|
|
over those actual matches, the complete replacement-token model and the bounded
|
|
output. They execute no replacement callback or user code and have separate
|
|
presentation and token-evaluation limits.
|
|
|
|
Corpus documents are ephemeral React session state, not project state. A
|
|
dedicated engine supervisor processes one document at a time and is terminated
|
|
on cancellation, timeout or workspace exit. Batch orchestration retains only
|
|
per-document summaries and, for apply runs, bounded outputs. It enforces
|
|
document-count, per-document byte, aggregate input byte, aggregate match,
|
|
aggregate output and batch wall-time limits. Exact-output export is unavailable
|
|
if any document is partial, failed, cancelled or not run.
|
|
|
|
Whole-document mode sends each document to the engine once. Independent-line
|
|
mode segments CRLF, CR, LF, U+2028 and U+2029 without discarding them, executes
|
|
each logical line as its own subject, and reattaches the exact original
|
|
separator during apply. This makes anchor and cross-line behavior deliberately
|
|
different rather than silently rewriting the pattern. Match DTOs are reduced to
|
|
bounded per-group participation counts and samples before the next document.
|
|
|
|
Native ranges are retained in the engine's declared unit. ECMAScript and Java
|
|
use UTF-16 code units. PCRE2 always uses UTF/UCP and exposes UTF-8 byte ranges;
|
|
its ABI copies scalar records and names out of WebAssembly before returning and
|
|
retains no code pointer. CPython `re` exposes Unicode code-point indices.
|
|
Browser editor ranges are half-open UTF-16 code-unit ranges. Reusable
|
|
converters cover UTF-8 byte and Unicode code-point offsets, including
|
|
invalid-boundary rejection and lone-surrogate detection.
|
|
|
|
The release boundary is `dist/` plus checked-in legal/source documents. The
|
|
Portal consumes the resulting immutable ZIP and never imports React source.
|