Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions docs/adr/0004-isolated-parser-execution.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ node-sql-parser/build/bigquery.js

The worker verifies that `self === globalThis` and that no DOM window exists.
It snapshots and restores the exact `NodeSQLParser` and `global` descriptors
around dialect loading. Cleanup failure poisons that worker generation.
around the complete backend operation: dialect loading, module decoding,
parser construction, parsing, and output normalization. Cleanup failure
poisons that worker generation.

### Private wire protocol

Expand All @@ -139,7 +141,7 @@ The initial response contains only one closed outcome:
- Parsed normalized statement kind
- Syntax rejection
- Bounded unsupported reason
- Bounded failure code plus retryability
- Bounded failure code; retryability is derived from that code

Messages do not contain:

Expand All @@ -150,6 +152,11 @@ Messages do not contain:
- Absolute document ranges
- Raw ASTs or generic payload bags

The wire does not transport an independently supplied retryability boolean.
The host treats only `module-load` as retryable; `backend` and
`malformed-output` are terminal. A module-load failure closes the current
worker generation so a retry cannot reuse a rejected dynamic-import realm.

The host requires the current protocol version and correlation ID, validates
all keys and closed values, and copies accepted data into new frozen objects.
It then constructs an authentic `SqlParserAnalysis` with the exact pending
Expand Down
41 changes: 39 additions & 2 deletions docs/vnext/node-sql-parser-adapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,45 @@ exists, or `global` does not resolve exactly to `globalThis`, before loading a
bundle. This blocks browser windows and Node DOM shims from exposing an
unguarded secondary target. Pure Node loads restore the exact prior descriptors
synchronously after module evaluation, including removing names that were
previously absent. Cleanup failure permanently poisons loading. A
dedicated-worker loader remains future work.
previously absent. Cleanup failure permanently poisons loading. The dedicated
worker applies the same exact restoration rule around the complete backend
operation, including module evaluation, module decoding, parser construction,
parsing, and output normalization.

### Private browser worker endpoint

The package contains a production-shaped but private module-worker endpoint.
It is not exported from the package and is not reachable through `/vnext`.
There is no public worker constructor, executor, queue, language-service
module, or session integration yet.

The endpoint:

- uses only the extension-qualified PostgreSQL and BigQuery builds above;
- loads each grammar lazily after a valid request;
- reuses the realm-neutral backend engine for module, AST, and parser-error
normalization;
- accepts and emits only a closed, versioned plain-data protocol;
- returns normalized statement kind, bounded unsupported or failure evidence,
and never returns source text, raw errors, or backend ASTs;
- derives retryability from the closed failure code instead of trusting a
separate wire flag;
- restores the exact prior `NodeSQLParser` and `global` descriptors around
each complete backend operation; and
- permanently poisons and closes its worker realm if cleanup cannot be proven
exact.

The endpoint accepts only one request at a time. Overlap and malformed messages
fail closed instead of creating an implicit worker-side queue. The future
service-owned executor is responsible for serialization, correlation,
deadlines, cancellation, generation replacement, and disposal.

Direct Chromium tests construct this source module worker and exercise both
real grammar builds. The separate worker-placement fixture remains
diagnostic packaging evidence: it records resource timing, emitted chunk
reachability, and bundle sizes with a fixture-owned protocol. It is not the
public integration boundary and must not be read as evidence that an executor
or session API already exists.

Approximate local Node 24 arm64 measurements for the installed package were:

Expand Down
3 changes: 2 additions & 1 deletion scripts/changed-coverage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const changedProductionFiles = execFileSync(
!path.endsWith(".test.ts") &&
!path.includes("/__tests__/") &&
!path.includes("/browser_tests/") &&
path !== "src/debug.ts",
path !== "src/debug.ts" &&
path !== "src/vnext/node-sql-parser-browser-worker.ts",
);
const changedRuntimeFiles = (
await Promise.all(
Expand Down
15 changes: 15 additions & 0 deletions scripts/package-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,21 @@ try {
if (typeof packedPackage.dependencies?.["node-sql-parser"] !== "string") {
throw new Error("Packed manifest does not declare node-sql-parser");
}
const privateWorkerArtifacts = [
"dist/vnext/node-sql-parser-browser-worker.d.ts",
"dist/vnext/node-sql-parser-browser-worker.js",
"dist/vnext/node-sql-parser-browser-worker-endpoint.d.ts",
"dist/vnext/node-sql-parser-browser-worker-endpoint.js",
"dist/vnext/node-sql-parser-wire.d.ts",
"dist/vnext/node-sql-parser-wire.js",
];
for (const artifact of privateWorkerArtifacts) {
if (!existsSync(join(packageDirectory, artifact))) {
throw new Error(
`Packed archive omitted private worker artifact ${artifact}`,
);
}
}

writeFileSync(
join(temporaryDirectory, "vnext-consumer.mjs"),
Expand Down
Loading
Loading