Answer the architecture pass: the config that owns the contract, and what each runtime leg buys
CI / gate (push) Successful in 8s
CI / gate (push) Successful in 8s
This commit is contained in:
@@ -65,8 +65,8 @@ they never reach a consumer.
|
||||
`tsconfig.build.json` is that gate, typechecking the shipped files alone with `types: []` and
|
||||
`lib: ES2022`, so `node:fs`, `process` and an ES2024 method are compile errors here rather than a
|
||||
consumer's crash there. Node's test runner, the corpus reads and the build are the repo's own,
|
||||
never the library's, and `engines.node` states the floor the shipped JavaScript needs — `>=18`,
|
||||
the lowest line carrying ES2022 — never the higher one those repo-only tools want.
|
||||
never the library's, and `engines.node` states the floor the shipped JavaScript needs — `>=18` —
|
||||
never the higher one those repo-only tools want.
|
||||
- ESM only — no CommonJS build, no dual-package hazard.
|
||||
- One entrypoint: built JavaScript, `.d.ts` beside it. Do not add a TypeScript-source entrypoint —
|
||||
Node refuses to type-strip under `node_modules` (`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`),
|
||||
@@ -120,9 +120,12 @@ Test for the behaviour wanted first, then implement until green. `node --test`,
|
||||
Node, tsc and npm never run on the host — only via the pinned images (§9). Tests are independent,
|
||||
coverage does not decline, containers are torn down after a run.
|
||||
|
||||
The gate runs that same suite under Deno and Bun as well as Node, the three images pinned alike:
|
||||
§6's compile gate proves no host API is named, and only running proves those engines execute what
|
||||
is written. Both refuse a run that matches no test, so Node's is the only vacuous-green guard.
|
||||
The gate runs that same suite under Deno and Bun as well as Node, the three images pinned alike,
|
||||
and neither extra leg is Node's proof twice. Deno refuses an extensionless or directory specifier,
|
||||
so it holds the module graph to the fully-spelled form a browser can load; Bun runs
|
||||
JavaScriptCore, the one engine of the three that is not V8, where the Unicode property escapes
|
||||
emphasis matching leans on can disagree. Both refuse a run matching no test, so Node's is the only
|
||||
vacuous-green guard.
|
||||
|
||||
The floors live in the `test` script, so `npm test` and the gate are one path: 100% of lines and
|
||||
functions, and a branch floor that only ever moves upward. It sits below 100 because the guards
|
||||
|
||||
@@ -5,7 +5,11 @@ cd "$(dirname "$0")"
|
||||
bun_image=oven/bun:1.4.0-alpine
|
||||
deno_image=denoland/deno:2.9.6
|
||||
node_image=node:24.19.0-alpine3.24
|
||||
in_image() { docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/app" -w /app --entrypoint "$2" "$1" "${@:3}"; }
|
||||
in_image() {
|
||||
local image=$1 entrypoint=$2
|
||||
shift 2
|
||||
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -v "$PWD:/app" -w /app --entrypoint "$entrypoint" "$image" "$@"
|
||||
}
|
||||
|
||||
in_image "$node_image" npm ci
|
||||
in_image "$node_image" npm run typecheck
|
||||
@@ -21,4 +25,4 @@ if printf '%s' "$test_output" | grep -q 'ℹ tests 0'; then
|
||||
fi
|
||||
|
||||
in_image "$deno_image" deno test --allow-read --no-check src/
|
||||
in_image "$bun_image" bun test
|
||||
in_image "$bun_image" bun test src/
|
||||
|
||||
@@ -139,13 +139,16 @@ numbering is the order the work was planned in, not the order it ships.
|
||||
additions are read here as one list before that freeze — nine sessions mint them
|
||||
independently, and one cause wearing two codes is breaking to undo after `0.1.0`. `0.1.0`
|
||||
is the markdown round-trip: both markdown directions, the types, `isAdfDocument`. The build
|
||||
lands here: `tsconfig.build.json` gains emit of JS and `.d.ts` to `dist/` (the dev config's
|
||||
`allowImportingTsExtensions` forces `noEmit`, so the build config needs
|
||||
`rewriteRelativeImportExtensions`), plus `exports`/`files` in `package.json`. The
|
||||
lands here: `tsconfig.build.json` gains emit of JS and `.d.ts` to `dist/` (its own
|
||||
`allowImportingTsExtensions` forces `noEmit`, so `rewriteRelativeImportExtensions` lands
|
||||
beside it), plus `exports`/`files` in `package.json`. The
|
||||
maintainer's bump PR also removes `private: true`, the guard against any earlier publish.
|
||||
§6's browser half is first checkable here, on the emitted `dist/index.js` a browser can
|
||||
load — the compile gate names no host API, and a real page converting a document is the
|
||||
other half.
|
||||
other half; name the engines that page covers, since Bun's JavaScriptCore is not Safari's
|
||||
and none of the three legs is SpiderMonkey. `engines.node` gets its one-line proof here
|
||||
too — `import('./dist/index.js')` under a pinned `node:18` image, which cannot run the
|
||||
suite that type stripping wants 22+ for, but proves exactly what the field claims.
|
||||
**Settled** (the maintainer, 2026-09-01): the round-trip proved over the checked-in corpus
|
||||
is what `0.1.0` ships on, and the open-ended proof work follows it rather than gating it —
|
||||
3k's spec suite and 4's generators and maintainer-supplied payloads are `0.2.0`, 4b's retry
|
||||
|
||||
+23
-3
@@ -1,9 +1,29 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2022"],
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"target": "ES2022",
|
||||
"types": []
|
||||
"types": [],
|
||||
|
||||
"allowImportingTsExtensions": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
|
||||
"strict": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
"exclude": ["src/**/*.test.ts"],
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
+3
-22
@@ -1,28 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"target": "ESNext",
|
||||
"types": ["node"],
|
||||
|
||||
"allowImportingTsExtensions": true,
|
||||
"erasableSyntaxOnly": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
|
||||
"strict": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"skipLibCheck": true
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src"]
|
||||
"exclude": []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user