@scriptc/compiler 0.1.2 → 0.1.4

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 (206) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +258 -64
  2. package/dist/backend/c/async.d.ts +30 -0
  3. package/dist/backend/c/async.js +224 -0
  4. package/dist/backend/c/async.js.map +1 -1
  5. package/dist/backend/c/c-emitter.d.ts +13 -0
  6. package/dist/backend/c/c-emitter.js +28 -9
  7. package/dist/backend/c/c-emitter.js.map +1 -1
  8. package/dist/backend/c/exprs.d.ts +8 -1
  9. package/dist/backend/c/exprs.js +445 -60
  10. package/dist/backend/c/exprs.js.map +1 -1
  11. package/dist/backend/c/shapes.js +15 -13
  12. package/dist/backend/c/shapes.js.map +1 -1
  13. package/dist/backend/c/types.d.ts +4 -0
  14. package/dist/backend/c/types.js +20 -1
  15. package/dist/backend/c/types.js.map +1 -1
  16. package/dist/backend/c/types.test.js +8 -1
  17. package/dist/backend/c/types.test.js.map +1 -1
  18. package/dist/backend/c/walkers.js +32 -11
  19. package/dist/backend/c/walkers.js.map +1 -1
  20. package/dist/backend/json-literal.d.ts +7 -0
  21. package/dist/backend/json-literal.js +17 -0
  22. package/dist/backend/json-literal.js.map +1 -0
  23. package/dist/backend/json-literal.test.d.ts +1 -0
  24. package/dist/backend/json-literal.test.js +17 -0
  25. package/dist/backend/json-literal.test.js.map +1 -0
  26. package/dist/backend/link-plan.d.ts +2 -1
  27. package/dist/backend/link-plan.js +6 -1
  28. package/dist/backend/link-plan.js.map +1 -1
  29. package/dist/backend/llvm/classes.js +8 -7
  30. package/dist/backend/llvm/classes.js.map +1 -1
  31. package/dist/backend/llvm/common.d.ts +4 -0
  32. package/dist/backend/llvm/common.js +6 -0
  33. package/dist/backend/llvm/common.js.map +1 -1
  34. package/dist/backend/llvm/common.test.d.ts +1 -0
  35. package/dist/backend/llvm/common.test.js +9 -0
  36. package/dist/backend/llvm/common.test.js.map +1 -0
  37. package/dist/backend/llvm/dyn.d.ts +4 -0
  38. package/dist/backend/llvm/dyn.js +24 -13
  39. package/dist/backend/llvm/dyn.js.map +1 -1
  40. package/dist/backend/llvm/emitter.js +54 -12
  41. package/dist/backend/llvm/emitter.js.map +1 -1
  42. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  43. package/dist/backend/llvm/expr-bytes.js +8 -8
  44. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  45. package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
  46. package/dist/backend/llvm/expr-callbacks.js +125 -0
  47. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  48. package/dist/backend/llvm/expr-context.d.ts +18 -2
  49. package/dist/backend/llvm/expr-dispatch.js +1 -0
  50. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  51. package/dist/backend/llvm/expr-dynamic.js +9 -0
  52. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  53. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  54. package/dist/backend/llvm/expr-primitives.js +38 -9
  55. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  56. package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
  57. package/dist/backend/llvm/expr-primitives.test.js +38 -0
  58. package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
  59. package/dist/backend/llvm/expr-records.js +3 -3
  60. package/dist/backend/llvm/expr-records.js.map +1 -1
  61. package/dist/backend/llvm/expr-stream-bridges.js +2 -1
  62. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  63. package/dist/backend/llvm/expr-stream-callbacks.d.ts +6 -0
  64. package/dist/backend/llvm/expr-stream-callbacks.js +122 -0
  65. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  66. package/dist/backend/llvm/lib-dispatch.js +22 -0
  67. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  68. package/dist/backend/llvm/lib-filesystem.js +68 -10
  69. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  70. package/dist/backend/llvm/lib-network.js +18 -2
  71. package/dist/backend/llvm/lib-network.js.map +1 -1
  72. package/dist/backend/llvm/lib-process.js +206 -11
  73. package/dist/backend/llvm/lib-process.js.map +1 -1
  74. package/dist/backend/llvm/lib-shared.js +82 -0
  75. package/dist/backend/llvm/lib-shared.js.map +1 -1
  76. package/dist/backend/llvm/lib-stream.js +23 -0
  77. package/dist/backend/llvm/lib-stream.js.map +1 -1
  78. package/dist/backend/llvm/shapes.js +10 -8
  79. package/dist/backend/llvm/shapes.js.map +1 -1
  80. package/dist/backend/llvm/walkers.js +7 -5
  81. package/dist/backend/llvm/walkers.js.map +1 -1
  82. package/dist/backend/native-link-info.d.ts +2 -1
  83. package/dist/backend/native-link-info.js +4 -0
  84. package/dist/backend/native-link-info.js.map +1 -1
  85. package/dist/backend/native-link-info.test.js +24 -1
  86. package/dist/backend/native-link-info.test.js.map +1 -1
  87. package/dist/backend/native-toolchain.d.ts +11 -6
  88. package/dist/backend/native-toolchain.js +30 -13
  89. package/dist/backend/native-toolchain.js.map +1 -1
  90. package/dist/backend/native-toolchain.test.js +36 -1
  91. package/dist/backend/native-toolchain.test.js.map +1 -1
  92. package/dist/backend/runtime-pack-targets.test.js +1 -1
  93. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  94. package/dist/backend/runtime-pack.test.js +29 -10
  95. package/dist/backend/runtime-pack.test.js.map +1 -1
  96. package/dist/backend/targets.d.ts +9 -0
  97. package/dist/backend/targets.js +22 -0
  98. package/dist/backend/targets.js.map +1 -1
  99. package/dist/backend/targets.test.js +13 -1
  100. package/dist/backend/targets.test.js.map +1 -1
  101. package/dist/coverage/surface-manifest.js +9 -0
  102. package/dist/coverage/surface-manifest.js.map +1 -1
  103. package/dist/diagnostics/diagnostic.js +4 -4
  104. package/dist/diagnostics/diagnostic.js.map +1 -1
  105. package/dist/executable/executable-cache.d.ts +3 -0
  106. package/dist/executable/executable-cache.js +4 -0
  107. package/dist/executable/executable-cache.js.map +1 -1
  108. package/dist/executable/executable-cache.test.js +1 -0
  109. package/dist/executable/executable-cache.test.js.map +1 -1
  110. package/dist/frontend/fork-target.d.ts +17 -0
  111. package/dist/frontend/fork-target.js +256 -0
  112. package/dist/frontend/fork-target.js.map +1 -0
  113. package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
  114. package/dist/frontend/lowering/abstract-equality.js +250 -0
  115. package/dist/frontend/lowering/abstract-equality.js.map +1 -0
  116. package/dist/frontend/lowering/containers/bytes.d.ts +0 -4
  117. package/dist/frontend/lowering/containers/bytes.js +112 -28
  118. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  119. package/dist/frontend/lowering/lower-assert.js +87 -12
  120. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  121. package/dist/frontend/lowering/lower-builtins.d.ts +72 -44
  122. package/dist/frontend/lowering/lower-builtins.js +1323 -165
  123. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  124. package/dist/frontend/lowering/lower-calls.d.ts +37 -27
  125. package/dist/frontend/lowering/lower-calls.js +682 -132
  126. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  127. package/dist/frontend/lowering/lower-classes.js +39 -8
  128. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  129. package/dist/frontend/lowering/lower-containers.js +162 -8
  130. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  131. package/dist/frontend/lowering/lower-event-emitter.js +212 -21
  132. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  133. package/dist/frontend/lowering/lower-exprs.js +238 -87
  134. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  135. package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
  136. package/dist/frontend/lowering/lower-inspect.js +8 -1
  137. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  138. package/dist/frontend/lowering/lower-island.d.ts +6 -3
  139. package/dist/frontend/lowering/lower-island.js +165 -6
  140. package/dist/frontend/lowering/lower-island.js.map +1 -1
  141. package/dist/frontend/lowering/lower-modules.d.ts +6 -0
  142. package/dist/frontend/lowering/lower-modules.js +192 -38
  143. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  144. package/dist/frontend/lowering/lower-namespaces.js +7 -0
  145. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  146. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  147. package/dist/frontend/lowering/lower-server.js +130 -27
  148. package/dist/frontend/lowering/lower-server.js.map +1 -1
  149. package/dist/frontend/lowering/lower-stmts.d.ts +5 -4
  150. package/dist/frontend/lowering/lower-stmts.js +141 -21
  151. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  152. package/dist/frontend/lowering/lower-stream.d.ts +3 -0
  153. package/dist/frontend/lowering/lower-stream.js +7 -0
  154. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  155. package/dist/frontend/lowering/lowerer.d.ts +90 -13
  156. package/dist/frontend/lowering/lowerer.js +416 -76
  157. package/dist/frontend/lowering/lowerer.js.map +1 -1
  158. package/dist/frontend/lowering/surfaces.d.ts +31 -3
  159. package/dist/frontend/lowering/surfaces.js +173 -90
  160. package/dist/frontend/lowering/surfaces.js.map +1 -1
  161. package/dist/frontend/npm-static-declarations.d.ts +4 -0
  162. package/dist/frontend/npm-static-declarations.js +83 -14
  163. package/dist/frontend/npm-static-declarations.js.map +1 -1
  164. package/dist/frontend/npm-static-declarations.test.js +33 -2
  165. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  166. package/dist/frontend/npm-static.js +6 -5
  167. package/dist/frontend/npm-static.js.map +1 -1
  168. package/dist/frontend/npm.d.ts +15 -3
  169. package/dist/frontend/npm.js +80 -8
  170. package/dist/frontend/npm.js.map +1 -1
  171. package/dist/frontend/npm.test.js +76 -9
  172. package/dist/frontend/npm.test.js.map +1 -1
  173. package/dist/frontend/program.js +110 -12
  174. package/dist/frontend/program.js.map +1 -1
  175. package/dist/frontend/resolve.d.ts +28 -7
  176. package/dist/frontend/resolve.js +90 -26
  177. package/dist/frontend/resolve.js.map +1 -1
  178. package/dist/frontend/resolve.test.js +21 -1
  179. package/dist/frontend/resolve.test.js.map +1 -1
  180. package/dist/frontend/type-mapper.d.ts +5 -0
  181. package/dist/frontend/type-mapper.js +115 -33
  182. package/dist/frontend/type-mapper.js.map +1 -1
  183. package/dist/index.d.ts +5 -0
  184. package/dist/index.js +30 -3
  185. package/dist/index.js.map +1 -1
  186. package/dist/ir/analysis.js +1 -0
  187. package/dist/ir/analysis.js.map +1 -1
  188. package/dist/ir/ir.d.ts +155 -66
  189. package/dist/ir/ir.js +143 -6
  190. package/dist/ir/ir.js.map +1 -1
  191. package/dist/ir/ir.test.js +14 -1
  192. package/dist/ir/ir.test.js.map +1 -1
  193. package/dist/ir/serialize.d.ts +1 -1
  194. package/dist/ir/serialize.js +1 -1
  195. package/dist/ir/serialize.js.map +1 -1
  196. package/dist/ir/validate.js +242 -18
  197. package/dist/ir/validate.js.map +1 -1
  198. package/dist/library/int-infer.test.js +4 -4
  199. package/dist/library/int-infer.test.js.map +1 -1
  200. package/dist/library/library-cache.d.ts +1 -0
  201. package/dist/library/library-cache.js +1 -0
  202. package/dist/library/library-cache.js.map +1 -1
  203. package/dist/library/library-cache.test.js +18 -5
  204. package/dist/library/library-cache.test.js.map +1 -1
  205. package/package.json +17 -17
  206. package/surface-manifest.json +163 -54
@@ -10,19 +10,76 @@ import { isJsSourceFileName } from "../tsc-codes.js";
10
10
  import { isRelativeSpecifier } from "../workspace-registry.js";
11
11
  import { canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, isCjsJsFile, isJsSourceFile, isRequireStatement, locOf, makeCycleAdmission, orderedImportsOf, resolveImport, resolveNpmImport } from "../program.js";
12
12
  import { invalidJsonModuleDiag, npmEmbedFailedDiag, requiresDynamicImportDiag } from "../../diagnostics/diagnostic.js";
13
- import { BOOL, DYN, JSVAL, RUNTIME_ERROR_CLASSES, STRING, VOID, arrayOf, canConvertToDyn, isUnitType } from "../../ir/ir.js";
14
- import { ENTRY_NAME, PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, newFnCtx, uncheckedOverloadHandleCall } from "./lowerer.js";
15
- import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireSpecOf, isPromisifyCall, textCodecBindingDecl } from "./lower-builtins.js";
16
- import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, nullishGenericBindingUnitOf } from "./lower-calls.js";
13
+ import { BOOL, DYN, F64, JSVAL, RUNTIME_ERROR_CLASSES, STRING, VOID, arrayOf, canConvertToDyn, isUnitType } from "../../ir/ir.js";
14
+ import { ENTRY_NAME, PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefinedExpr, importCallHandleType, newFnCtx, staticImportNamespaceType, uncheckedOverloadHandleCall } from "./lowerer.js";
15
+ import { builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireSpecOf, isPromisifyCall, registerBuiltinCallableAlias, textCodecBindingDecl } from "./lower-builtins.js";
16
+ import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, implicitLocalFnInfoOf, implicitLocalFnNodeOf, nullishGenericBindingUnitOf, registerOverloadedCallableAlias } from "./lower-calls.js";
17
17
  import { isVarDeclared, numericIteratorSourceOf, provenanceElidedConstDecl } from "./lower-stmts.js";
18
18
  import { streamClassAliasDecl } from "./lower-stream.js";
19
- import { stdlibGlobalAliasDecl } from "./surfaces.js";
19
+ import { stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf } from "./surfaces.js";
20
20
  import { collectNamespaceStmt, nsPathPrefix, trapDeclRootOf } from "./lower-namespaces.js";
21
21
  import { collectExpandoMembers } from "./lower-expando.js";
22
22
  import { isUnitOnlyTsType, unitOnlyUnion } from "../type-mapper.js";
23
23
  import { decoratorNodesOf, genericIfaceBindingKeepsClass, guaranteedDecorationThrow } from "./lower-classes.js";
24
24
  import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
25
25
  import { cjsModuleRef, cjsModuleRegistryPrelude } from "./lower-node-module.js";
26
+ import { forkTargetPaths } from "../fork-target.js";
27
+ /** Program modules selected by statically resolved child_process.fork()
28
+ * calls join the compiled graph without becoming startup dependencies of
29
+ * the parent entry. Their guarded init functions are selected by %main only
30
+ * in a re-executed fork child. `targets` is append-only so ids stay stable
31
+ * across the dynamic-import/fork discovery fixpoint. */
32
+ export function appendForkModules(program, order, targets, onCycle) {
33
+ if (order.length === 0)
34
+ return;
35
+ const byPath = new Map(program.getSourceFiles().map((sf) => [resolvePath(sf.fileName), sf]));
36
+ const state = new Map();
37
+ for (const sf of order)
38
+ state.set(sf, "done");
39
+ const added = [];
40
+ const stack = [];
41
+ const staticEdgesOf = (sf) => orderedImportsOf(program, sf).flatMap(({ stmt, dep }) => dep !== null && dep !== sf
42
+ ? [{ dep, stmt: stmt }]
43
+ : []);
44
+ const cycleAdmissionReason = makeCycleAdmission(program, staticEdgesOf);
45
+ const visit = (sf) => {
46
+ const prior = state.get(sf);
47
+ if (prior === "done")
48
+ return;
49
+ state.set(sf, "visiting");
50
+ stack.push(sf.fileName);
51
+ for (const edge of staticEdgesOf(sf)) {
52
+ const edgeState = state.get(edge.dep);
53
+ if (edgeState === "done")
54
+ continue;
55
+ if (edgeState === "visiting") {
56
+ const reason = cycleAdmissionReason(sf, edge);
57
+ if (reason !== null) {
58
+ const cycleStart = stack.indexOf(edge.dep.fileName);
59
+ onCycle([...stack.slice(cycleStart), edge.dep.fileName].join(" → "), reason);
60
+ }
61
+ continue;
62
+ }
63
+ visit(edge.dep);
64
+ }
65
+ stack.pop();
66
+ state.set(sf, "done");
67
+ added.push(sf);
68
+ };
69
+ const knownTargets = new Set(targets);
70
+ for (const path of forkTargetPaths(program, order)) {
71
+ const target = byPath.get(resolvePath(path));
72
+ if (!target || target.isDeclarationFile || target.fileName.endsWith(".json"))
73
+ continue;
74
+ if (!knownTargets.has(target)) {
75
+ knownTargets.add(target);
76
+ targets.push(target);
77
+ }
78
+ visit(target);
79
+ }
80
+ if (added.length > 0)
81
+ order.splice(order.length - 1, 0, ...added);
82
+ }
26
83
  /** Splits each file into function/class declarations and the top-level
27
84
  * statements that form its init body. Node's evaluation order (depth-first
28
85
  * postorder, entry last), computed by preflight. Single-file programs
@@ -255,6 +312,14 @@ export function collectNpmImports(lowerer, parts) {
255
312
  // fences are the whole story.
256
313
  if (lowerer.externalTypes.has(spec))
257
314
  continue;
315
+ // A source-only workspace package is part of the program module
316
+ // graph: resolveImport follows its node_modules link to the loaded
317
+ // TypeScript entry. Its internal `.js` spellings have already been
318
+ // resolved to `.ts` by that graph, and no source may be handed to
319
+ // the JavaScript island.
320
+ if (!isRelativeSpecifier(spec) && resolveImport(lowerer.program, fp.sf, spec) !== null) {
321
+ continue;
322
+ }
258
323
  const npm = resolveNpmImport(fp.sf.fileName, spec);
259
324
  // --npm-static: an opted-in package that made it through preflight
260
325
  // is a PROGRAM-MODULE dependency — its entry sits in the module
@@ -374,9 +439,9 @@ export function collectNpmImports(lowerer, parts) {
374
439
  }
375
440
  }
376
441
  }
442
+ for (const fp of parts)
443
+ collectDynamicImports(lowerer, builder, fp.sf);
377
444
  if (builder) {
378
- for (const fp of parts)
379
- collectDynamicImports(lowerer, builder, fp.sf);
380
445
  for (const fp of parts)
381
446
  collectCreateRequires(lowerer, builder, fp.sf);
382
447
  const graph = builder.finish();
@@ -389,11 +454,13 @@ export function collectNpmImports(lowerer, parts) {
389
454
  lowerer.npmLazyTraps = graph.lazyTraps;
390
455
  }
391
456
  }
392
- /** The dynamic-import half of the npm chokepoint (--dynamic only): every
457
+ /** Literal dynamic-import collection: every
393
458
  * `import("literal")` in the file — whatever body it sits in — resolves
394
459
  * and embeds AT COLLECTION time, so the per-site lowering later just
395
460
  * looks its key up (the emitted tables are assembled once, here; a
396
461
  * site lowered in any pass finds its module embedded). Resolution
462
+ * In static builds this records compiled program modules and supported
463
+ * builtins without constructing an npm graph. Dynamic package-resolution
397
464
  * failures and unshimmed builtins are diagnostics HERE, at the import
398
465
  * expression, exactly like static npm imports at their statements; the
399
466
  * lowering poisons those sites without re-reporting. Non-literal
@@ -401,7 +468,7 @@ export function collectNpmImports(lowerer, parts) {
401
468
  * graph is a build-time artifact; there is nothing to embed for a
402
469
  * runtime-computed name). */
403
470
  function collectDynamicImports(lowerer, builder, sf) {
404
- const visit = (node) => {
471
+ ts.walkPreorder(sf, (node) => {
405
472
  if (ts.isCallExpression(node) &&
406
473
  node.expression.kind === ts.SyntaxKind.ImportKeyword &&
407
474
  node.arguments.length >= 1 &&
@@ -409,8 +476,7 @@ function collectDynamicImports(lowerer, builder, sf) {
409
476
  ts.isStringLiteralLike(node.arguments[0])) {
410
477
  const spec = node.arguments[0].text;
411
478
  if (lowerer.externalTypes.has(spec)) {
412
- ts.forEachChild(node, visit);
413
- return;
479
+ return undefined;
414
480
  }
415
481
  const mapKey = `${sf.fileName}\u0000${spec}`;
416
482
  if (!lowerer.dynImports.has(mapKey)) {
@@ -421,9 +487,15 @@ function collectDynamicImports(lowerer, builder, sf) {
421
487
  // .d.mts typing shipped JS is the EMBED case, not this one.
422
488
  const modSym = lowerer.checker.getSymbolAtLocation(node.arguments[0]);
423
489
  const ownModule = modSym !== undefined && lowerer.checker.declarationsOf(modSym).some((d) => ts.isSourceFile(d) && !d.isDeclarationFile);
490
+ const builtin = canonicalBuiltinModule(spec);
424
491
  const res = ownModule
425
492
  ? { kind: "program-module" }
426
- : builder.addDynamicImport(sf.fileName, spec);
493
+ : !lowerer.dynamic && builtin !== null
494
+ ? { kind: "static-builtin", module: builtin }
495
+ : builder?.addDynamicImport(sf.fileName, spec);
496
+ if (res === undefined) {
497
+ return undefined;
498
+ }
427
499
  lowerer.dynImports.set(mapKey, res);
428
500
  if (res.kind === "unsupported-builtin") {
429
501
  lowerer.pushDiag(npmEmbedFailedDiag(`'${spec}' is a Node builtin the island does not provide a shim for`, locOf(node)));
@@ -433,9 +505,8 @@ function collectDynamicImports(lowerer, builder, sf) {
433
505
  }
434
506
  }
435
507
  }
436
- ts.forEachChild(node, visit);
437
- };
438
- visit(sf);
508
+ return undefined;
509
+ });
439
510
  }
440
511
  /** The createRequire half of the npm chokepoint (--dynamic only): every
441
512
  * `require("bare-literal")` through a createRequire binding — whatever
@@ -957,11 +1028,20 @@ export function collectGlobals(lowerer, sf, topStmts) {
957
1028
  // included); unmappable pieces take the JS checked-dynamic
958
1029
  // fallback like every JS binding.
959
1030
  const fnValued = ts.isFunctionExpression(rhs) || ts.isArrowFunction(rhs);
960
- if (cjsScalarLiteral(rhs) || fnValued) {
1031
+ // A factory-returned CommonJS root (`module.exports = make()`)
1032
+ // is a single value just like the scalar/function forms above
1033
+ // when its result has a static or checked-dynamic representation. Register one
1034
+ // snapshot slot keyed by the export-assignment declaration; the
1035
+ // statement lowering evaluates the call exactly once at its
1036
+ // source position and assigns that slot. Unmappable calls retain
1037
+ // the existing statement-level fence.
1038
+ const factoryValued = ts.isCallExpression(rhs);
1039
+ if (cjsScalarLiteral(rhs) || fnValued || factoryValued) {
961
1040
  const diagsBefore = lowerer.diags.length;
962
1041
  try {
963
1042
  const strict = lowerer.typeOf(rhs);
964
- const t = lowerer.mapTypeOf(strict) ?? (fnValued ? dynFallbackType(lowerer, rhs, strict) : null);
1043
+ const t = lowerer.mapTypeOf(strict) ??
1044
+ (fnValued || factoryValued ? dynFallbackType(lowerer, rhs, strict) : null);
965
1045
  if (t && t.kind !== "void") {
966
1046
  const g = { id: `%g.${tag}exports`, name: "exports", type: t, mutable: false };
967
1047
  lowerer.globalsByDeclNode.set(cjs.expr, g);
@@ -1203,6 +1283,13 @@ export function collectGlobals(lowerer, sf, topStmts) {
1203
1283
  if (aliased)
1204
1284
  continue;
1205
1285
  }
1286
+ // An immutable alias of an overloaded declared function is a
1287
+ // compile-time callable projection: calls retain per-site overload
1288
+ // resolution and value reads reuse the source's interned closure.
1289
+ if (isConst && registerOverloadedCallableAlias(lowerer, decl))
1290
+ continue;
1291
+ if (isConst && registerBuiltinCallableAlias(lowerer, decl.name, decl.initializer))
1292
+ continue;
1206
1293
  // `const f = (x) => ...` at file scope of an npm-static JS file
1207
1294
  // whose params are implicit-any: the implicit-monomorphization
1208
1295
  // twin of the generic binding above — no global exists; calls and
@@ -1256,7 +1343,7 @@ export function collectGlobals(lowerer, sf, topStmts) {
1256
1343
  // lowering poisons too, like every collectGlobals failure).
1257
1344
  if (ts.isIdentifier(decl.name) && decl.initializer && isPromisifyCall(lowerer, decl.initializer)) {
1258
1345
  try {
1259
- lowerer.promisifiedExecFileDecl(decl.name, decl.initializer);
1346
+ lowerer.registerPromisifiedBuiltinDecl(decl.name, decl.initializer);
1260
1347
  }
1261
1348
  catch (e) {
1262
1349
  if (!(e instanceof PoisonError))
@@ -1279,6 +1366,12 @@ export function collectGlobals(lowerer, sf, topStmts) {
1279
1366
  // scope — a namespace import in const clothing, same story.
1280
1367
  if (isConst && createRequireNamespaceDecl(lowerer, decl.name, decl.initializer))
1281
1368
  continue;
1369
+ // `const local = require("./local.cjs")` through createRequire:
1370
+ // the binding is static module alias plumbing. Its statement emits
1371
+ // the dependency init at this exact source position; no value slot
1372
+ // represents the namespace object itself.
1373
+ if (isConst && createRequireProgramModuleDecl(lowerer, decl.name, decl.initializer))
1374
+ continue;
1282
1375
  // `const { createSign } = crypto` over a builtin NAMESPACE binding
1283
1376
  // at file scope: alias plumbing like the destructured-require form
1284
1377
  // — no storage (the statement lowering skips by the same test).
@@ -1300,7 +1393,15 @@ export function collectGlobals(lowerer, sf, topStmts) {
1300
1393
  // global snapshot — alias plumbing, no global storage (see
1301
1394
  // stdlibGlobalAliasDecl; the statement lowering skips it by the
1302
1395
  // same test).
1303
- if (isConst && stdlibGlobalAliasDecl(lowerer, decl.name, decl.initializer))
1396
+ const stableStdlibAlias = isConst ||
1397
+ ((list.flags & ts.NodeFlags.Let) !== 0 &&
1398
+ ts.isIdentifier(decl.name) &&
1399
+ stdlibGlobalAliasNameOf(lowerer, decl.initializer) !== null &&
1400
+ (() => {
1401
+ const symbol = lowerer.checker.getSymbolAtLocation(decl.name);
1402
+ return symbol !== undefined && bindingNeverReassigned(lowerer, symbol, decl);
1403
+ })());
1404
+ if (stableStdlibAlias && stdlibGlobalAliasDecl(lowerer, decl.name, decl.initializer))
1304
1405
  continue;
1305
1406
  // Stored default TextEncoder/TextDecoder instances are the same
1306
1407
  // compile-time alias plumbing as their statement lowering: calls
@@ -1429,11 +1530,12 @@ export function collectGlobals(lowerer, sf, topStmts) {
1429
1530
  // production — whatever the checker's namespace type mapped to
1430
1531
  // (lowerVarDecl's rule at module scope; the init body assigns
1431
1532
  // it).
1432
- const handleT = lowerer.dynamic && ts.isIdentifier(decl.name) && nameNode === decl.name
1433
- ? (importCallHandleType(decl.initializer) ??
1434
- // An unchecked-overload call result stores the handle,
1435
- // exactly the local rule (uncheckedOverloadHandleCall).
1436
- (uncheckedOverloadHandleCall(lowerer, decl.initializer) ? JSVAL : null))
1533
+ const handleT = ts.isIdentifier(decl.name) && nameNode === decl.name
1534
+ ? (lowerer.dynamic ? importCallHandleType(decl.initializer) : staticImportNamespaceType(lowerer, decl.initializer)) ??
1535
+ (lowerer.dynamic ?
1536
+ // An unchecked-overload call result stores the handle,
1537
+ // exactly the local rule (uncheckedOverloadHandleCall).
1538
+ (uncheckedOverloadHandleCall(lowerer, decl.initializer) ? JSVAL : null) : null)
1437
1539
  : null;
1438
1540
  let type = handleT ?? lowerer.irTypeOf(nameNode);
1439
1541
  // An evolving-`any` array's DERIVED file-scope binding under
@@ -1999,24 +2101,76 @@ export function lowerFileInit(lowerer, sf, stmts, name) {
1999
2101
  * re-imports, re-requires) into a cache hit. */
2000
2102
  export function buildMain(lowerer) {
2001
2103
  const loc = { file: lowerer.entry.fileName, start: 0, end: 0 };
2002
- const entryInit = lowerer.initNameOf.get(lowerer.entry);
2003
- const isAsync = lowerer.asyncInitFiles.has(lowerer.entry);
2004
- const initCall = entryInit !== undefined
2005
- ? {
2104
+ const body = [...cjsModuleRegistryPrelude(lowerer, loc)];
2105
+ const roots = [lowerer.entry, ...lowerer.forkTargets];
2106
+ const isAsync = roots.some((root) => lowerer.asyncInitFiles.has(root));
2107
+ const callRoot = (root) => {
2108
+ const init = lowerer.initNameOf.get(root);
2109
+ if (init === undefined)
2110
+ return [];
2111
+ const rootAsync = lowerer.asyncInitFiles.has(root);
2112
+ const call = {
2006
2113
  kind: "call",
2007
- callee: entryInit,
2114
+ callee: init,
2008
2115
  args: [],
2009
- type: isAsync ? { kind: "promise", inner: VOID } : VOID,
2116
+ type: rootAsync ? { kind: "promise", inner: VOID } : VOID,
2010
2117
  loc,
2118
+ };
2119
+ return [{
2120
+ kind: "exprStmt",
2121
+ expr: rootAsync ? { kind: "awaitExpr", value: call, type: VOID, loc } : call,
2122
+ loc,
2123
+ }];
2124
+ };
2125
+ const locals = [];
2126
+ if (lowerer.forkTargets.length === 0) {
2127
+ body.push(...callRoot(lowerer.entry));
2128
+ }
2129
+ else {
2130
+ const targetId = "%forkTarget.0";
2131
+ locals.push({ id: targetId, name: "%forkTarget", type: F64, mutable: false });
2132
+ body.push({
2133
+ kind: "varDecl",
2134
+ localId: targetId,
2135
+ init: {
2136
+ kind: "libCall",
2137
+ fn: "process.forkTarget",
2138
+ args: [{ kind: "numLit", value: lowerer.forkTargets.length, type: F64, loc }],
2139
+ type: F64,
2140
+ loc,
2141
+ },
2142
+ loc,
2143
+ });
2144
+ const selector = () => ({ kind: "varRef", localId: targetId, type: F64, loc });
2145
+ let workerBranch = null;
2146
+ for (let id = lowerer.forkTargets.length - 1; id >= 0; id--) {
2147
+ workerBranch = [{
2148
+ kind: "if",
2149
+ cond: {
2150
+ kind: "bin",
2151
+ op: "===",
2152
+ left: selector(),
2153
+ right: { kind: "numLit", value: id, type: F64, loc },
2154
+ type: BOOL,
2155
+ loc,
2156
+ },
2157
+ then: callRoot(lowerer.forkTargets[id]),
2158
+ else_: workerBranch,
2159
+ loc,
2160
+ }];
2011
2161
  }
2012
- : null;
2013
- const body = [...cjsModuleRegistryPrelude(lowerer, loc)];
2014
- if (initCall !== null) {
2015
2162
  body.push({
2016
- kind: "exprStmt",
2017
- expr: isAsync
2018
- ? { kind: "awaitExpr", value: initCall, type: VOID, loc }
2019
- : initCall,
2163
+ kind: "if",
2164
+ cond: {
2165
+ kind: "bin",
2166
+ op: "<",
2167
+ left: selector(),
2168
+ right: { kind: "numLit", value: 0, type: F64, loc },
2169
+ type: BOOL,
2170
+ loc,
2171
+ },
2172
+ then: callRoot(lowerer.entry),
2173
+ else_: workerBranch,
2020
2174
  loc,
2021
2175
  });
2022
2176
  }
@@ -2046,7 +2200,7 @@ export function buildMain(lowerer) {
2046
2200
  name: ENTRY_NAME,
2047
2201
  params: [],
2048
2202
  returnType: VOID,
2049
- locals: [],
2203
+ locals,
2050
2204
  body,
2051
2205
  ...(isAsync ? { async: true } : {}),
2052
2206
  loc,