Files
regex-tools/src/components/HelpDialog.tsx

295 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useEffect, useRef } from "react";
import { DEFAULT_REGEX_LIMITS } from "../regex/execution/request-limits";
import {
DEFAULT_GENERATION_SETTINGS,
GENERATION_LIMITS,
} from "../regex/generation/generation-limits";
import { manifest } from "../toolbox/manifest";
const releaseSourceUrl = `https://git.add-ideas.de/lotobo/regex-tools/src/tag/v${manifest.version}`;
export function HelpDialog({
open,
onClose,
}: {
readonly open: boolean;
readonly onClose: () => void;
}) {
const dialog = useRef<HTMLDialogElement>(null);
useEffect(() => {
const element = dialog.current;
if (!element) return;
if (open && !element.open) element.showModal();
if (!open && element.open) element.close();
}, [open]);
return (
<dialog
ref={dialog}
className="app-dialog"
aria-labelledby="help-title"
onClose={onClose}
>
<header>
<div>
<p className="eyebrow">Regex Tools {manifest.version}</p>
<h2 id="help-title">Local regex workbench</h2>
</div>
<button
type="button"
className="icon-button"
aria-label="Close help"
onClick={onClose}
>
×
</button>
</header>
<div className="dialog-content">
<section>
<h3>What runs where</h3>
<p>
Syntax parsing and active-engine execution run in separate, killable
browser workers. JavaScript uses the browser&apos;s ECMAScript
RegExp implementation, while the standalone PCRE2 profile uses the
bundled 10.47 WebAssembly engine. The other profiles name their
selected runtime explicitly: PHP 8.5.8 preg with PCRE2 10.44, legacy
Perl 5.28.1 through WebPerl 0.09-beta, CPython 3.14, CRuby 4.0,
TeaVM java.util.regex, libc++ std::regex, Go regexp, Rust regex and
.NET System.Text.RegularExpressions. Scala is explicitly a Scala/JVM
regex-syntax compatibility profile over the same TeaVM Java runtime,
not a Scala VM. Result metadata names the runtime actually used.
</p>
<p>
Structural coverage varies by profile. Only the ECMAScript provider
currently exposes a complete grammar-backed tree; the additional
community providers retain partial lexical captures and replacement
tokens while their selected runtime compiler remains authoritative.
Patterns, subjects and projects are never uploaded. There is no
backend, account, telemetry, CDN dependency, or executable
replacement function.
</p>
<p>
TeaVM 0.15.0 is not OpenJDK. Its replacement implementation accepts
single-digit $n references, so $12 means $1 followed by literal 2.
Java SE ${"{name}"} references are reported as unavailable.
</p>
</section>
<section>
<h3>Trees and replacement mapping</h3>
<p>
The explanation tree is deterministic structure derived from the
syntax provider. The extraction tree contains actual browser-engine
matches and captures. Replacement mode adds a typed token tree and
bounded per-match contribution/range mapping over those actual
matches. These views are not internal engine traces. The separate
PCRE trace viewer shows actual bounded automatic callouts reported
by PCRE2; its adjacent-position movement labels are derived and it
is not a complete record of every internal action. Browser
ECMAScript exposes no corresponding V8, SpiderMonkey or
JavaScriptCore trace API.
</p>
</section>
<section>
<h3>Advisory analysis</h3>
<p>
Static risk findings are ECMAScript-2025-specific heuristics, and
generated-input growth observations describe only the selected
bounded samples. Neither proves safety or general complexity. Growth
and cold/warm benchmark timing run in a separate killable worker and
never include the PCRE2 trace path.
</p>
</section>
<section>
<h3>Generated cases</h3>
<p>
ECMAScript generator v1 deterministically samples supported
normalized-AST paths from an explicit seed. Every intended positive
and negative subject runs through the selected actual engine before
it can become a test; candidates with the wrong outcome are
discarded. The coverage report names unsupported constructs.
Sampling is not proof of complete language coverage. Other flavours
remain unavailable until their structural providers expose the
required AST; their syntax is never reinterpreted as ECMAScript.
</p>
</section>
<section>
<h3>Pattern formatting</h3>
<p>
The ECMAScript formatter makes only grammar-backed literal/control
escape changes; it does not insert layout whitespace or reinterpret
another flavour&apos;s syntax. Applying a preview requires
independent source and candidate reparsing, actual-engine
match/replacement comparison, every applicable exact unit test, and
an explicit confirmation. Passing bounded checks is evidence for
those snapshots, not proof for every possible subject.
</p>
</section>
<section>
<h3>Timeouts and limits</h3>
<dl className="help-limits">
<div>
<dt>Live execution</dt>
<dd>{DEFAULT_REGEX_LIMITS.liveExecutionTimeoutMs} ms</dd>
</div>
<div>
<dt>Manual execution</dt>
<dd>{DEFAULT_REGEX_LIMITS.manualExecutionTimeoutMs} ms</dd>
</div>
<div>
<dt>Maximum matches</dt>
<dd>{DEFAULT_REGEX_LIMITS.maximumMatches.toLocaleString()}</dd>
</div>
<div>
<dt>Maximum capture rows</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCaptureRows.toLocaleString()}
</dd>
</div>
<div>
<dt>Maximum capture groups</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCaptureGroups.toLocaleString()}
</dd>
</div>
<div>
<dt>Replacement template</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumReplacementTemplateUtf16.toLocaleString()}{" "}
UTF-16 units
</dd>
</div>
<div>
<dt>List template</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumListTemplateUtf16.toLocaleString()}{" "}
UTF-16 units
</dd>
</div>
<div>
<dt>Unit-test suite wall time</dt>
<dd>60 seconds</dd>
</div>
<div>
<dt>Corpus input</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCorpusDocuments.toLocaleString()}{" "}
documents · {DEFAULT_REGEX_LIMITS.corpusHardBytes / 1024 / 1024}{" "}
MiB
</dd>
</div>
<div>
<dt>Corpus wall time</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCorpusWallTimeMs / 60_000} minutes
</dd>
</div>
<div>
<dt>Analysis wall time</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumBenchmarkWallTimeMs / 1_000}{" "}
seconds
</dd>
</div>
<div>
<dt>Benchmark iteration cap</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumBenchmarkIterations.toLocaleString()}
</dd>
</div>
<div>
<dt>Growth probe steps</dt>
<dd>24</dd>
</div>
<div>
<dt>Generated cases</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumGeneratedCases.toLocaleString()}{" "}
retained ·{" "}
{GENERATION_LIMITS.maximumCandidateAttempts.toLocaleString()}{" "}
attempts
</dd>
</div>
<div>
<dt>Generation defaults</dt>
<dd>
{DEFAULT_GENERATION_SETTINGS.perCaseTimeoutMs} ms per case ·{" "}
{DEFAULT_GENERATION_SETTINGS.maximumWallTimeMs / 1_000} seconds
aggregate
</dd>
</div>
<div>
<dt>Generated subject text</dt>
<dd>
{GENERATION_LIMITS.maximumTotalSubjectBytes / 1024 / 1024} MiB
aggregate hard cap
</dd>
</div>
<div>
<dt>Formatter validation</dt>
<dd>1,000 tests · 60 seconds aggregate</dd>
</div>
<div>
<dt>Independent corpus lines</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCorpusLines.toLocaleString()}
</dd>
</div>
<div>
<dt>Corpus applied output</dt>
<dd>
{DEFAULT_REGEX_LIMITS.maximumCorpusOutputBytes / 1024 / 1024}{" "}
MiB
</dd>
</div>
</dl>
<p>
A timeout terminates the worker. It means timed out, never no
match. The following run uses a fresh worker.
</p>
</section>
<section>
<h3>Persistence</h3>
<p>
Ad-hoc test text is excluded from local saves and exports by
default. Test definitions are deliberate project data. Import is
validated and paused until you review and run it. Corpus documents,
contents, outputs and results are always ephemeral and excluded from
projects and IndexedDB. Analysis settings and results are likewise
ephemeral. Generated-case settings and review results are ephemeral;
only cases explicitly added to the test suite persist, together with
their bounded seed and generator provenance. Test subjects remain
excluded unless separately opted in. Formatter previews and
validation observations are ephemeral; only an explicitly applied
pattern enters workbench/project state.
</p>
</section>
<section>
<h3>Legal notice</h3>
<p>
Copyright © 2026 Albrecht Degering. Regex Tools is free software:
you may redistribute it and/or modify it under the terms of the GNU
General Public License, version 3 or (at your option) any later
version. It comes without any warranty, to the extent permitted by
law.
</p>
<p>
Read the{" "}
<a href="./LICENSE" target="_blank" rel="noreferrer">
complete licence
</a>{" "}
or inspect and obtain the{" "}
<a href={releaseSourceUrl} target="_blank" rel="noreferrer">
corresponding source code
</a>
.
</p>
</section>
</div>
<footer>
<button type="button" className="primary-button" onClick={onClose}>
Close
</button>
</footer>
</dialog>
);
}