@scriptc/compiler 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +63 -15
  2. package/ambient/scriptc.d.ts +2 -2
  3. package/dist/backend/cc.d.ts +2 -2
  4. package/dist/backend/emission/emit-async.js +1 -1
  5. package/dist/backend/emission/emit-exprs.js +131 -54
  6. package/dist/backend/emission/emit-exprs.js.map +1 -1
  7. package/dist/backend/emission/emit-island.js +1 -1
  8. package/dist/backend/emission/emit-shapes.js +1 -1
  9. package/dist/backend/emission/emit-walkers.d.ts +14 -14
  10. package/dist/backend/emission/emit-walkers.js +44 -44
  11. package/dist/backend/emission/emit-walkers.js.map +1 -1
  12. package/dist/backend/emission/emitter.d.ts +3 -3
  13. package/dist/backend/emission/emitter.js +33 -9
  14. package/dist/backend/emission/emitter.js.map +1 -1
  15. package/dist/backend/emission/may-throw.js +1 -1
  16. package/dist/backend/llvm/dyn.d.ts +10 -10
  17. package/dist/backend/llvm/dyn.js +26 -26
  18. package/dist/backend/llvm/dyn.js.map +1 -1
  19. package/dist/backend/llvm/emitter.js +156 -47
  20. package/dist/backend/llvm/emitter.js.map +1 -1
  21. package/dist/backend/llvm/shapes.js +1 -1
  22. package/dist/backend/llvm/walkers.js +2 -2
  23. package/dist/backend/llvm/walkers.js.map +1 -1
  24. package/dist/coverage/surface-manifest.js +16 -2
  25. package/dist/coverage/surface-manifest.js.map +1 -1
  26. package/dist/diagnostics/diagnostic.d.ts +21 -8
  27. package/dist/diagnostics/diagnostic.js +48 -14
  28. package/dist/diagnostics/diagnostic.js.map +1 -1
  29. package/dist/frontend/lowering/lib-boundary.js +5 -5
  30. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  31. package/dist/frontend/lowering/lower-assert.js +12 -12
  32. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  33. package/dist/frontend/lowering/lower-builtins.d.ts +63 -7
  34. package/dist/frontend/lowering/lower-builtins.js +327 -35
  35. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  36. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  37. package/dist/frontend/lowering/lower-calls.js +104 -70
  38. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  39. package/dist/frontend/lowering/lower-classes.d.ts +7 -0
  40. package/dist/frontend/lowering/lower-classes.js +82 -6
  41. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  42. package/dist/frontend/lowering/lower-containers.d.ts +9 -5
  43. package/dist/frontend/lowering/lower-containers.js +88 -26
  44. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  45. package/dist/frontend/lowering/lower-emitter.d.ts +70 -3
  46. package/dist/frontend/lowering/lower-emitter.js +438 -31
  47. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  48. package/dist/frontend/lowering/lower-exprs.d.ts +87 -12
  49. package/dist/frontend/lowering/lower-exprs.js +630 -125
  50. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  51. package/dist/frontend/lowering/lower-inspect.js +5 -5
  52. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  53. package/dist/frontend/lowering/lower-island.js +12 -3
  54. package/dist/frontend/lowering/lower-island.js.map +1 -1
  55. package/dist/frontend/lowering/lower-modules.d.ts +8 -5
  56. package/dist/frontend/lowering/lower-modules.js +157 -63
  57. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  58. package/dist/frontend/lowering/lower-namespaces.d.ts +24 -0
  59. package/dist/frontend/lowering/lower-namespaces.js +158 -16
  60. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  61. package/dist/frontend/lowering/lower-server.js +11 -11
  62. package/dist/frontend/lowering/lower-server.js.map +1 -1
  63. package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
  64. package/dist/frontend/lowering/lower-stmts.js +271 -36
  65. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  66. package/dist/frontend/lowering/lower-stream.js +171 -20
  67. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  68. package/dist/frontend/lowering/lowerer.d.ts +27 -10
  69. package/dist/frontend/lowering/lowerer.js +156 -54
  70. package/dist/frontend/lowering/lowerer.js.map +1 -1
  71. package/dist/frontend/lowering/surfaces.d.ts +44 -0
  72. package/dist/frontend/lowering/surfaces.js +236 -5
  73. package/dist/frontend/lowering/surfaces.js.map +1 -1
  74. package/dist/frontend/npm.d.ts +12 -0
  75. package/dist/frontend/npm.js +30 -0
  76. package/dist/frontend/npm.js.map +1 -1
  77. package/dist/frontend/program.d.ts +25 -0
  78. package/dist/frontend/program.js +145 -136
  79. package/dist/frontend/program.js.map +1 -1
  80. package/dist/frontend/shared.d.ts +1 -1
  81. package/dist/frontend/shared.js +8 -8
  82. package/dist/frontend/shared.js.map +1 -1
  83. package/dist/frontend/types.d.ts +2 -2
  84. package/dist/frontend/types.js +15 -15
  85. package/dist/frontend/types.js.map +1 -1
  86. package/dist/index.d.ts +2 -1
  87. package/dist/index.js +169 -5
  88. package/dist/index.js.map +1 -1
  89. package/dist/ir/nodes.d.ts +174 -106
  90. package/dist/ir/nodes.js +69 -24
  91. package/dist/ir/nodes.js.map +1 -1
  92. package/dist/ir/validate.js +55 -36
  93. package/dist/ir/validate.js.map +1 -1
  94. package/dist/library/fence-eval.js +12 -2
  95. package/dist/library/fence-eval.js.map +1 -1
  96. package/dist/library/int-infer.d.ts +119 -0
  97. package/dist/library/int-infer.js +1314 -0
  98. package/dist/library/int-infer.js.map +1 -0
  99. package/dist/library/int-infer.test.d.ts +1 -0
  100. package/dist/library/int-infer.test.js +279 -0
  101. package/dist/library/int-infer.test.js.map +1 -0
  102. package/dist/library/profile.d.ts +34 -5
  103. package/dist/library/profile.js +77 -13
  104. package/dist/library/profile.js.map +1 -1
  105. package/dist/library/sidecar-validate.js +1 -1
  106. package/dist/library/sidecar-validate.js.map +1 -1
  107. package/dist/library/sidecar.d.ts +24 -1
  108. package/dist/library/sidecar.js +163 -16
  109. package/dist/library/sidecar.js.map +1 -1
  110. package/package.json +2 -2
  111. package/surface-manifest.json +210 -12
@@ -4,19 +4,19 @@
4
4
  * the module artifacts (globals, embedded npm tables) the IR module carries. */
5
5
  import * as ts from "../ts7/adapter.js";
6
6
  import { dirname as dirnamePath, resolve as resolvePath } from "node:path";
7
- import { NpmGraphBuilder, packageNameOfPath, probeNodeImportRefusal } from "../npm.js";
7
+ import { NpmGraphBuilder, packageNameOfPath, probeNodeImportRefusal, probeNodeRequireRefusal } from "../npm.js";
8
8
  import { isNpmStaticPackage } from "../npm-static.js";
9
9
  import { isJsSourceFileName, isRelativeSpecifier } from "../shared.js";
10
- import { cjsExportAssignmentOf, cjsExportDiscardReason, isCjsJsFile, isJsSourceFile, isRequireStatement, locOf, orderedImportsOf, resolveImport, resolveNpmImport } from "../program.js";
10
+ import { canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, isCjsJsFile, isJsSourceFile, isRequireStatement, locOf, makeCycleAdmission, orderedImportsOf, resolveImport, resolveNpmImport } from "../program.js";
11
11
  import { invalidJsonModuleDiag, npmEmbedFailedDiag, requiresDynamicImportDiag } from "../../diagnostics/diagnostic.js";
12
12
  import { BOOL, DYN, JSVAL, RUNTIME_ERROR_CLASSES, STRING, VOID, arrayOf, canConvertToDyn, isUnitType } from "../../ir/nodes.js";
13
13
  import { ENTRY_NAME, PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, newFnCtx, uncheckedOverloadHandleCall } from "./lowerer.js";
14
- import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, isPromisifyCall } from "./lower-builtins.js";
14
+ import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireSpecOf, isPromisifyCall } from "./lower-builtins.js";
15
15
  import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, nullishGenericBindingUnitOf } from "./lower-calls.js";
16
16
  import { isVarDeclared, provenanceElidedConstDecl } from "./lower-stmts.js";
17
17
  import { streamClassAliasDecl } from "./lower-stream.js";
18
18
  import { stdlibGlobalAliasDecl } from "./surfaces.js";
19
- import { ambientUndefVarRootOf, collectNamespaceStmt, nsPathPrefix } from "./lower-namespaces.js";
19
+ import { collectNamespaceStmt, nsPathPrefix, trapDeclRootOf } from "./lower-namespaces.js";
20
20
  import { collectExpandoMembers } from "./lower-expando.js";
21
21
  import { isUnitOnlyTsType, unitOnlyUnion } from "../types.js";
22
22
  import { decoratorNodesOf, genericIfaceBindingKeepsClass, guaranteedDecorationThrow } from "./lower-classes.js";
@@ -101,10 +101,13 @@ function dynamicProgramImportsOf(program, sf) {
101
101
  * still evaluates exactly when Node evaluates it: the import() site's
102
102
  * namespace builder calls the guarded init on the engine microtask.
103
103
  * Fixpoint: an added module's own import() sites are scanned too. Static
104
- * cycles inside the added subgraph get preflight's SC1016 via `onCycle`
105
- * (preflight only walked the entry's static graph, so it never saw
106
- * these). Idempotent — re-running on an already-extended order adds
107
- * nothing (both lowering passes share one array). */
104
+ * cycles inside the added subgraph ride preflight's own admission engine
105
+ * (makeCycleAdmission — preflight only walked the entry's static graph,
106
+ * so it never judged these): benign back edges are Node cache hits the
107
+ * run-once init guards reproduce, and inadmissible ones get preflight's
108
+ * SC1016 with the same narrowed reason via `onCycle`. Idempotent —
109
+ * re-running on an already-extended order adds nothing (both lowering
110
+ * passes share one array). */
108
111
  export function appendDynamicImportModules(program, order, onCycle) {
109
112
  if (order.length === 0)
110
113
  return; // no preflight order — sites keep their fences
@@ -113,20 +116,31 @@ export function appendDynamicImportModules(program, order, onCycle) {
113
116
  state.set(sf, "done");
114
117
  const added = [];
115
118
  const stack = [];
119
+ const staticEdgesOf = (sf) => orderedImportsOf(program, sf).flatMap(({ stmt, dep }) => dep !== null && dep !== sf
120
+ ? [{ dep, stmt: stmt }]
121
+ : []);
122
+ const cycleAdmissionReason = makeCycleAdmission(program, staticEdgesOf);
116
123
  const visit = (sf) => {
117
- const s = state.get(sf);
118
- if (s === "done")
124
+ if (state.get(sf) !== undefined)
119
125
  return;
120
- if (s === "visiting") {
121
- const cycleStart = stack.indexOf(sf.fileName);
122
- onCycle([...stack.slice(cycleStart), sf.fileName].join(" → "));
123
- return;
124
- }
125
126
  state.set(sf, "visiting");
126
127
  stack.push(sf.fileName);
127
- for (const { dep } of orderedImportsOf(program, sf))
128
- if (dep && dep !== sf)
129
- visit(dep);
128
+ for (const e of staticEdgesOf(sf)) {
129
+ const s = state.get(e.dep);
130
+ if (s === "done")
131
+ continue;
132
+ if (s === "visiting") {
133
+ // A back edge: Node answers it from the cache. Same admission
134
+ // question as preflight's static walk, same fence when refused.
135
+ const reason = cycleAdmissionReason(sf, e);
136
+ if (reason !== null) {
137
+ const cycleStart = stack.indexOf(e.dep.fileName);
138
+ onCycle([...stack.slice(cycleStart), e.dep.fileName].join(" → "), reason);
139
+ }
140
+ continue;
141
+ }
142
+ visit(e.dep);
143
+ }
130
144
  stack.pop();
131
145
  state.set(sf, "done");
132
146
  added.push(sf);
@@ -356,6 +370,8 @@ export function collectNpmImports(L, parts) {
356
370
  if (builder) {
357
371
  for (const fp of parts)
358
372
  collectDynamicImports(L, builder, fp.sf);
373
+ for (const fp of parts)
374
+ collectCreateRequires(L, builder, fp.sf);
359
375
  const graph = builder.finish();
360
376
  if (graph.modules.length > 0) {
361
377
  L.npmEmbedded = { modules: graph.modules, edges: graph.edges };
@@ -410,6 +426,47 @@ function collectDynamicImports(L, builder, sf) {
410
426
  };
411
427
  visit(sf);
412
428
  }
429
+ /** The createRequire half of the npm chokepoint (--dynamic only): every
430
+ * `require("bare-literal")` through a createRequire binding — whatever
431
+ * body it sits in — resolves under Node's "require" condition and
432
+ * embeds AT COLLECTION time, so the per-site lowering later just looks
433
+ * its entry up (lowerCreateRequireCall). Builtins, relative documents,
434
+ * "#" specifiers, --npm-static opt-ins, and Node-refused bare names
435
+ * are the lowering's own arms — only resolvable installed packages
436
+ * register here; resolution failures are diagnostics at the call
437
+ * expression, exactly like static npm imports at their statements. */
438
+ function collectCreateRequires(L, builder, sf) {
439
+ const visit = (node) => {
440
+ if (ts.isCallExpression(node)) {
441
+ const cr = createRequireSpecOf(L, node);
442
+ const spec = cr?.spec ?? null;
443
+ if (cr !== null &&
444
+ spec !== null &&
445
+ canonicalBuiltinModule(spec) === null &&
446
+ !isRelativeSpecifier(spec) &&
447
+ !spec.startsWith("/") &&
448
+ !spec.startsWith("#") &&
449
+ probeNodeRequireRefusal(cr.baseFile.fileName, spec) === null) {
450
+ const pkgName = spec.startsWith("@")
451
+ ? spec.split("/").slice(0, 2).join("/")
452
+ : spec.split("/")[0];
453
+ const mapKey = `${cr.baseFile.fileName}\u0000${spec}`;
454
+ if (!L.createRequireImports.has(mapKey) && !isNpmStaticPackage(pkgName)) {
455
+ const before = builder.errors.length;
456
+ const entryKey = builder.addRequire(cr.baseFile.fileName, spec);
457
+ for (const err of builder.errors.slice(before)) {
458
+ L.pushDiag(npmEmbedFailedDiag(err.message, locOf(node)));
459
+ }
460
+ L.createRequireImports.set(mapKey, entryKey === null
461
+ ? ""
462
+ : { entryKey, format: builder.moduleFormatOf(entryKey) ?? "cjs" });
463
+ }
464
+ }
465
+ }
466
+ ts.forEachChild(node, visit);
467
+ };
468
+ visit(sf);
469
+ }
413
470
  /** JSON module default imports (`import pkg from "../package.json"`):
414
471
  * the document is DATA known at build time, so the binding bakes into a
415
472
  * record global — the checker's structural type for the module (thanks
@@ -639,7 +696,7 @@ function cjsScalarLiteral(e) {
639
696
  /** True when a JS file-scope declaration's initializer provably LOWERS to
640
697
  * a checked-dynamic (or unit) value, so a DYN module global can hold it:
641
698
  * no initializer, a unit literal, or a checker-`any` call/member/
642
- * identifier read (any-typed operations lower through the DOM in JS).
699
+ * identifier read (any-typed operations lower through the checked-dynamic tree in JS).
643
700
  * `new` expressions stay OUT even when checker-any (`new Anon.Sub()` over
644
701
  * an expando class member constructs a TYPED instance — corpus 2032), as
645
702
  * does everything else (object/array literals have their own rules;
@@ -661,7 +718,7 @@ function jsDynHoldableInitializer(L, init) {
661
718
  // A CALL whose inferred type has no static mapping and whose residue
662
719
  // falls to the checked-dynamic kind (`const exec = common.mustCall(() =>
663
720
  // ... exec ...)` — the wrapper's rest-args type is not checker-`any`,
664
- // but the VALUE lowers through the DOM the same way): registering the
721
+ // but the VALUE lowers through the checked-dynamic tree the same way): registering the
665
722
  // dyn global BEFORE the initializer lowers is what lets the callback
666
723
  // capture the binding itself — the Node-suite self-referential-const
667
724
  // idiom. Non-dyn residues (pure single-signature function types, typed
@@ -802,7 +859,7 @@ export function collectGlobals(L, sf, topStmts) {
802
859
  const t = L.mapTypeOf(strict) ?? dynFallbackType(L, nameNode, strict);
803
860
  if (!t || t.kind === "void")
804
861
  L.badType(typeNode, strict);
805
- // `module.exports.Strings = Strings` naming a DOM-HOLDING
862
+ // `module.exports.Strings = Strings` naming a dyn-HOLDING
806
863
  // const (the JS file-scope object-literal identity story): the
807
864
  // export ALIASES the const's own dyn global — one storage, one
808
865
  // owner, identity by construction (a record-typed second slot
@@ -826,7 +883,7 @@ export function collectGlobals(L, sf, topStmts) {
826
883
  L.globalsByDeclNode.set(d, vG);
827
884
  return;
828
885
  }
829
- // A mutable (`let`) DOM source: separate DYN storage IS
886
+ // A mutable (`let`) dyn source: separate DYN storage IS
830
887
  // Node's copy-of-the-reference at this statement (later
831
888
  // reassignments of the let stay invisible through the
832
889
  // export). The id must not collide with the let's own
@@ -1025,37 +1082,65 @@ export function collectGlobals(L, sf, topStmts) {
1025
1082
  // and put its fences on the build.
1026
1083
  if (provenanceElidedConstDecl(L, decl))
1027
1084
  continue;
1028
- // A TRAP declaration at file scope — the initializer's chain roots
1029
- // at an ambient-undefined name (`declare const t: Type<string>;
1030
- // export const out = t.pipe(...)`): Node throws the root's
1031
- // ReferenceError evaluating the initializer, so no value ever
1032
- // exists and no reference can ever run. No global registers; the
1033
- // binding enters trapBindings (registered HERE, before any body
1034
- // lowers, so hoisted-function references resolve the trap), and
1035
- // the statement lowering emits the throw at its position.
1036
- if (decl.initializer !== undefined && ambientUndefVarRootOf(L, decl.initializer) !== null) {
1037
- for (const nameNode of boundIdentifiersOf(decl.name)) {
1038
- const sym = L.checker.getSymbolAtLocation(nameNode);
1039
- if (sym)
1040
- L.trapBindings.add(sym);
1085
+ // The trap/nullish/dead classification probes below resolve
1086
+ // symbols INSIDE the initializer, and resolution can fence (the
1087
+ // cross-block merged-namespace SC1090, resolveValueSymbol →
1088
+ // fenceCrossBlockNsRef): a fence mid-probe means the probe cannot
1089
+ // classify the declaration, not that collection dies — the
1090
+ // diagnostic is recorded, the binding falls through to ordinary
1091
+ // registration, and the statement lowering re-fences at its own
1092
+ // site (pushDiag dedupes), exactly the per-probe recovery the
1093
+ // alias/generic-fn registrations below already use.
1094
+ const classifyDiagsBefore = L.diags.length;
1095
+ const classified = (() => {
1096
+ try {
1097
+ // A TRAP declaration at file scope — the initializer's chain roots
1098
+ // at an ambient-undefined name (`declare const t: Type<string>;
1099
+ // export const out = t.pipe(...)`): Node throws the root's
1100
+ // ReferenceError evaluating the initializer, so no value ever
1101
+ // exists and no reference can ever run. No global registers; the
1102
+ // binding enters trapBindings (registered HERE, before any body
1103
+ // lowers, so hoisted-function references resolve the trap), and
1104
+ // the statement lowering emits the throw at its position.
1105
+ // Written bindings keep ordinary storage (trapDeclRootOf).
1106
+ if (trapDeclRootOf(L, decl) !== null) {
1107
+ for (const nameNode of boundIdentifiersOf(decl.name)) {
1108
+ const sym = L.checker.getSymbolAtLocation(nameNode);
1109
+ if (sym)
1110
+ L.trapBindings.add(sym);
1111
+ }
1112
+ return true;
1113
+ }
1114
+ // A NULLISH generic binding at file scope (`export const Mixin:
1115
+ // MixinHelperFunc = null as any`): no storage — reads know the
1116
+ // value (lower-exprs/lower-calls claim them); the statement
1117
+ // lowering emits nothing by the same test.
1118
+ if (ts.isIdentifier(decl.name) &&
1119
+ nullishGenericBindingUnitOf(L, L.checker.getSymbolAtLocation(decl.name) ?? null) !== null) {
1120
+ return true;
1121
+ }
1122
+ // A DEAD unmappable binding at file scope (`var xs2: typeof
1123
+ // Array;` — never read anywhere): no global, no statement, no
1124
+ // type fence for a value the program never consumes.
1125
+ if (ts.isIdentifier(decl.name) &&
1126
+ deadUnmappableBinding(L, L.checker.getSymbolAtLocation(decl.name) ?? null, decl)) {
1127
+ return true;
1128
+ }
1041
1129
  }
1130
+ catch (e) {
1131
+ if (!(e instanceof PoisonError))
1132
+ throw e;
1133
+ // A probe fenced mid-classification: JS files defer the
1134
+ // recorded diagnostics to runtime fences like every other
1135
+ // collection failure; TS keeps the eager report (the
1136
+ // statement lowering re-fences at its own site — pushDiag
1137
+ // dedupes).
1138
+ deferJsCollectionDiags(L, sf, classifyDiagsBefore);
1139
+ }
1140
+ return false;
1141
+ })();
1142
+ if (classified)
1042
1143
  continue;
1043
- }
1044
- // A NULLISH generic binding at file scope (`export const Mixin:
1045
- // MixinHelperFunc = null as any`): no storage — reads know the
1046
- // value (lower-exprs/lower-calls claim them); the statement
1047
- // lowering emits nothing by the same test.
1048
- if (ts.isIdentifier(decl.name) &&
1049
- nullishGenericBindingUnitOf(L, L.checker.getSymbolAtLocation(decl.name) ?? null) !== null) {
1050
- continue;
1051
- }
1052
- // A DEAD unmappable binding at file scope (`var xs2: typeof
1053
- // Array;` — never read anywhere): no global, no statement, no
1054
- // type fence for a value the program never consumes.
1055
- if (ts.isIdentifier(decl.name) &&
1056
- deadUnmappableBinding(L, L.checker.getSymbolAtLocation(decl.name) ?? null, decl)) {
1057
- continue;
1058
- }
1059
1144
  // `const f = <T>(x: T) => x` at file scope: a generic function
1060
1145
  // value binding — no global exists (the binding is never read;
1061
1146
  // calls and pinned references monomorphize against the
@@ -1163,6 +1248,15 @@ export function collectGlobals(L, sf, topStmts) {
1163
1248
  // same test.
1164
1249
  if (builtinMemberRequireDecl(decl.name, decl.initializer))
1165
1250
  continue;
1251
+ // `const require = createRequire(import.meta.url)` at file scope:
1252
+ // compile-time plumbing — no global storage; the statement
1253
+ // lowering skips it by the same test.
1254
+ if (isConst && createRequireBindingDecl(L, decl.name, decl.initializer))
1255
+ continue;
1256
+ // `const fs = require("node:fs")` through that binding at file
1257
+ // scope — a namespace import in const clothing, same story.
1258
+ if (isConst && createRequireNamespaceDecl(L, decl.name, decl.initializer))
1259
+ continue;
1166
1260
  // `const { createSign } = crypto` over a builtin NAMESPACE binding
1167
1261
  // at file scope: alias plumbing like the destructured-require form
1168
1262
  // — no storage (the statement lowering skips by the same test).
@@ -1194,7 +1288,7 @@ export function collectGlobals(L, sf, topStmts) {
1194
1288
  try {
1195
1289
  // A JS file-scope evolving ARRAY (`const mustCallChecks = [];`
1196
1290
  // — test/common's exit-accounting ledger): the strict type
1197
- // (any[]) has no mapping, but the VALUE is the DOM array the
1291
+ // (any[]) has no mapping, but the VALUE is the dyn array the
1198
1292
  // literal builds (lowerArrayLiteral's JS fallback) — register
1199
1293
  // a checked-dynamic global so separately-declared function
1200
1294
  // bodies (runCallChecks, _mustCallInner) reach the SAME
@@ -1217,11 +1311,11 @@ export function collectGlobals(L, sf, topStmts) {
1217
1311
  // the literal's contract — the SAME object flows into untyped
1218
1312
  // callees, gets stamped by them, and is compared back against
1219
1313
  // the binding (assert.strictEqual(found, input)). A static
1220
- // record global would re-box at every DOM crossing and lose
1221
- // that identity, so the binding holds the DOM object itself.
1314
+ // record global would re-box at every dyn crossing and lose
1315
+ // that identity, so the binding holds the dyn object itself.
1222
1316
  // Gated to literals that are PURE DATA WRITTEN INLINE — every
1223
1317
  // property a non-computed PropertyAssignment whose value is
1224
- // dyn-representable (unmappable member types are the DOM
1318
+ // dyn-representable (unmappable member types are the checked-dynamic tree
1225
1319
  // fallback's own case) — so shorthand aggregates (test/common's
1226
1320
  // export object: alias plumbing importers resolve THROUGH),
1227
1321
  // spreads, accessors, and literals holding unconvertible typed
@@ -1245,7 +1339,7 @@ export function collectGlobals(L, sf, topStmts) {
1245
1339
  continue;
1246
1340
  }
1247
1341
  // A JS file-scope ANY-RESIDUE binding whose VALUE provably
1248
- // lives in the DOM: no initializer (`let catchWarning;` —
1342
+ // lives in the checked-dynamic tree: no initializer (`let catchWarning;` —
1249
1343
  // test/common's warning ledger), a unit initializer (`let
1250
1344
  // localhostIPv4 = null;` — the lazy-cache idiom), or an
1251
1345
  // initializer whose own checker type is `any` (`const handler
@@ -1255,7 +1349,7 @@ export function collectGlobals(L, sf, topStmts) {
1255
1349
  // storage instead of fencing per reference. Typed-but-
1256
1350
  // unmappable initializers (`new Set(...)` — a real Set the
1257
1351
  // decl keeps as an %init local) stay OUT: forcing those into
1258
- // the DOM would trade their working typed representation for
1352
+ // the checked-dynamic tree would trade their working typed representation for
1259
1353
  // fences.
1260
1354
  if (isJsSourceFile(sf) && !L.mapTypeOf(L.typeOf(nameNode)) &&
1261
1355
  ts.isIdentifier(decl.name) && nameNode === decl.name &&
@@ -1266,7 +1360,7 @@ export function collectGlobals(L, sf, topStmts) {
1266
1360
  const g = { id: `%g.${tag}${nsPrefix}${nameNode.text}`, name: nameNode.text, type: DYN, mutable: isLet };
1267
1361
  L.globalsBySymbol.set(symbol, g);
1268
1362
  L.globalsList.push(g);
1269
- // Mutable dyn globals hold the DOM undefined from module
1363
+ // Mutable dyn globals hold the dyn undefined from module
1270
1364
  // entry (the main path's rule below): a closure called
1271
1365
  // above the declaration reads undefined instead of
1272
1366
  // faulting on NULL.
@@ -1370,7 +1464,7 @@ export function collectGlobals(L, sf, topStmts) {
1370
1464
  // infers a record (`const wrapped = function () { return
1371
1465
  // expectedResult; }`): the closure VALUE lowers with a dyn
1372
1466
  // return (declaredReturnType's record twin — JS object
1373
- // literals are DOM values, and a record return would copy
1467
+ // literals are dyn values, and a record return would copy
1374
1468
  // identity away), so the binding's slot must agree or an
1375
1469
  // adapter would re-copy at the assignment.
1376
1470
  if (isJsSourceFile(sf) &&
@@ -1407,7 +1501,7 @@ export function collectGlobals(L, sf, topStmts) {
1407
1501
  L.globalsList.push(g);
1408
1502
  // Mutable checked-dynamic LET globals ride the same entry
1409
1503
  // init: a closure called above the declaration statement
1410
- // reads the DOM undefined instead of faulting on NULL — the
1504
+ // reads the dyn undefined instead of faulting on NULL — the
1411
1505
  // dyn face of let's documented pre-declaration window (Node
1412
1506
  // throws the TDZ ReferenceError there).
1413
1507
  if (isVarDeclared(decl) || (g.type.kind === "dyn" && g.mutable)) {
@@ -1457,7 +1551,7 @@ function handleArrayPreservingCall(L, e) {
1457
1551
  * must hold the interned undefined arm BEFORE the body runs (a function
1458
1552
  * called above the declaration statement may read it — lowerFileInit
1459
1553
  * emits the assigns right after the run-once guard). Checked-dynamic
1460
- * slots hold the DOM undefined the same way (a NULL dyn is a trap, not
1554
+ * slots hold the dyn undefined the same way (a NULL dyn is a trap, not
1461
1555
  * a value). Other types need nothing: tsc's flow analysis rejects their
1462
1556
  * direct early reads, and closure reads share let's documented
1463
1557
  * zero/NULL divergence window. */
@@ -1465,7 +1559,7 @@ function noteVarGlobalEntryInit(L, sf, g) {
1465
1559
  // 'any' globals need the entry init exactly like undefined-armed
1466
1560
  // unions: tsc never guards `any` reads, so `var x: any;` is readable
1467
1561
  // before any assignment and its slot must hold its world's undefined
1468
- // — the ENGINE's for jsval (--dynamic), the DOM's for dyn (static) —
1562
+ // — the ENGINE's for jsval (--dynamic), the checked-dynamic tree's for dyn (static) —
1469
1563
  // rather than a C-level NULL (an op or validated exit on NULL is
1470
1564
  // memory-unsafe, not a TypeError).
1471
1565
  if (g.type.kind !== "union" && g.type.kind !== "jsval" && g.type.kind !== "dyn")
@@ -1667,7 +1761,7 @@ export function lowerFileInit(L, sf, stmts, name) {
1667
1761
  // Module-scope `var` hoisting: undefined-armed var globals hold the
1668
1762
  // interned undefined from module entry (before any body statement —
1669
1763
  // a function called above the declaration reads `undefined`, exactly
1670
- // Node); checked-dynamic var globals hold the DOM undefined the same
1764
+ // Node); checked-dynamic var globals hold the dyn undefined the same
1671
1765
  // way. After the guard: a cache-hit revisit must not reset them.
1672
1766
  for (const g of L.varGlobalEntryInits.get(sf) ?? []) {
1673
1767
  const wrapped = g.type.kind === "dyn" ? dynUndefinedExpr(loc0) : L.unassignedSlotInit(g.type, loc0);