dsh-ptc-plus 0.3.2 → 0.4.1

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 (199) hide show
  1. package/README.en.md +65 -78
  2. package/README.md +65 -78
  3. package/assets/ptc-plus-bindings-en.png +0 -0
  4. package/assets/ptc-plus-bindings-zh.png +0 -0
  5. package/assets/ptc-plus-repair-en.png +0 -0
  6. package/assets/ptc-plus-repair-zh.png +0 -0
  7. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  8. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  9. package/assets/ptc-plus-settings-en.png +0 -0
  10. package/assets/ptc-plus-settings-zh.png +0 -0
  11. package/client.js +30596 -742
  12. package/compiler-amaro.cjs +5 -0
  13. package/compiler-amaro.cjs.map +6 -0
  14. package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
  15. package/compiler-assets.json +3 -0
  16. package/compiler-core.cjs +554 -0
  17. package/compiler-core.cjs.map +6 -0
  18. package/compiler-platform.cjs +2 -0
  19. package/compiler-platform.cjs.map +6 -0
  20. package/compiler-typescript.cjs +388 -0
  21. package/compiler-typescript.cjs.map +6 -0
  22. package/docs/README.md +6 -0
  23. package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
  24. package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
  26. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
  27. package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
  28. package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
  29. package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
  30. package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
  32. package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
  33. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  34. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
  35. package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
  36. package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
  37. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  38. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
  39. package/docs/adr/0023-global-user-bindings.md +104 -0
  40. package/docs/adr/0024-repl-console-observation.md +33 -0
  41. package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
  42. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
  43. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
  44. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
  45. package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
  46. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
  47. package/docs/architecture.md +73 -21
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +95 -19
  51. package/docs/durability-design.md +25 -10
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/publishing.md +5 -3
  55. package/docs/runtime-reference.md +72 -25
  56. package/docs/semantic-validation.md +29 -0
  57. package/docs/stateful-binding-updates-proposal.md +755 -0
  58. package/docs/user-bindings.en.md +64 -0
  59. package/docs/user-bindings.md +64 -0
  60. package/docs/value-wire.md +3 -3
  61. package/docs/verification.md +57 -0
  62. package/index.js +369 -92
  63. package/internal/ast-traversal.js +5 -2
  64. package/internal/binding-descriptors.js +1 -0
  65. package/internal/binding-pattern-traversal.js +25 -0
  66. package/internal/binding-pattern.js +26 -29
  67. package/internal/binding-source-analysis.js +391 -0
  68. package/internal/binding-update-policy.js +66 -0
  69. package/internal/bounded-worker-round.js +56 -0
  70. package/internal/callable-definition-environment.js +42 -0
  71. package/internal/callable-source-catalog.js +129 -0
  72. package/internal/callable-source-encoding.js +47 -0
  73. package/internal/callable-source-facts.js +459 -0
  74. package/internal/callable-source-format.js +2 -0
  75. package/internal/callable-source-lowering.js +123 -0
  76. package/internal/cell-analysis-contract.js +25 -0
  77. package/internal/cell-analysis.js +240 -290
  78. package/internal/cell-completion.js +15 -0
  79. package/internal/cell-error.js +7 -0
  80. package/internal/cell-parser.js +66 -0
  81. package/internal/cell-rewriter.js +3 -677
  82. package/internal/commonjs-export-evidence.js +63 -0
  83. package/internal/commonjs-source-evidence.js +72 -0
  84. package/internal/compiler-amaro.cjs +2 -0
  85. package/internal/compiler-compression.js +12 -0
  86. package/internal/compiler-data.js +58 -0
  87. package/internal/compiler-descriptors.js +54 -0
  88. package/internal/compiler-dynamic-cache.js +48 -0
  89. package/internal/compiler-entry.js +35 -0
  90. package/internal/compiler-generated-names.js +17 -0
  91. package/internal/compiler-intrinsics.js +84 -0
  92. package/internal/compiler-module-links.js +34 -0
  93. package/internal/compiler-operations.js +61 -0
  94. package/internal/compiler-platform-factory.js +84 -0
  95. package/internal/compiler-platform.js +136 -0
  96. package/internal/compiler-record-roles.js +53 -0
  97. package/internal/compiler-region-output.js +259 -0
  98. package/internal/compiler-resource-lowering.js +103 -0
  99. package/internal/compiler-scope-facts.js +115 -0
  100. package/internal/compiler-service.js +109 -0
  101. package/internal/compiler-source-cache.js +32 -0
  102. package/internal/compiler-source-pieces.js +93 -0
  103. package/internal/compiler-source-regions.js +132 -0
  104. package/internal/compiler-storage-source.js +54 -0
  105. package/internal/compiler-text.js +15 -0
  106. package/internal/compiler-typescript.cjs +2 -0
  107. package/internal/config-spec.js +83 -27
  108. package/internal/cordis-tools-owner.js +130 -21
  109. package/internal/diagnostic.js +27 -1
  110. package/internal/direct-surface-owner.js +76 -23
  111. package/internal/dynamic-binding-evidence.js +16 -0
  112. package/internal/dynamic-environment-compiler.js +779 -0
  113. package/internal/dynamic-environment-integration.js +87 -0
  114. package/internal/dynamic-environment-runtime.js +362 -0
  115. package/internal/dynamic-native-calls.js +150 -0
  116. package/internal/dynamic-native-runtime.js +248 -0
  117. package/internal/dynamic-scope-analysis.js +90 -0
  118. package/internal/edit-transport-owner.js +27 -2
  119. package/internal/execution-seam-compat.js +193 -0
  120. package/internal/failure-reporting.js +118 -18
  121. package/internal/host-rpc.js +66 -0
  122. package/internal/isolated-worker.js +548 -0
  123. package/internal/kernel-child.js +139 -0
  124. package/internal/kernel-worker.js +904 -120
  125. package/internal/language-semantics.js +14 -0
  126. package/internal/legacy-binding-catalog.js +48 -0
  127. package/internal/legacy-cell-analysis.js +600 -0
  128. package/internal/legacy-cell-parser.js +50 -0
  129. package/internal/legacy-cell-rewriter.js +631 -0
  130. package/internal/legacy-repl-convenience.js +291 -0
  131. package/internal/managed-module-operations.js +170 -0
  132. package/internal/module-compilation.js +321 -0
  133. package/internal/module-runtime-platform.js +19 -0
  134. package/internal/module-transform-contract.js +12 -0
  135. package/internal/native-await-declarations.js +68 -0
  136. package/internal/native-root-compilation.js +54 -0
  137. package/internal/native-root-dynamic.js +67 -0
  138. package/internal/recovery-tips.js +27 -15
  139. package/internal/rejected-cell-editor.js +13 -8
  140. package/internal/repl-convenience.js +2 -289
  141. package/internal/repl-memory-projection.js +81 -12
  142. package/internal/repl-observation-interest.js +70 -0
  143. package/internal/repl-rewrite-contract.js +6 -0
  144. package/internal/repl-scope-normalizer.js +2091 -0
  145. package/internal/repl-value-observer.js +114 -0
  146. package/internal/rpc-contract.js +52 -0
  147. package/internal/runtime-bridge-owner.js +172 -28
  148. package/internal/runtime-config.js +48 -52
  149. package/internal/runtime-contexts.js +82 -10
  150. package/internal/runtime-messages.js +111 -0
  151. package/internal/session-cell-executor.js +401 -87
  152. package/internal/session-journal-recovery.js +684 -0
  153. package/internal/session-journal-schema.js +106 -0
  154. package/internal/session-journal.js +184 -654
  155. package/internal/session-log-view.js +42 -9
  156. package/internal/session-runtime.js +256 -95
  157. package/internal/session-state.js +247 -71
  158. package/internal/source-position-map.js +211 -71
  159. package/internal/stateful-module-compiler.js +154 -0
  160. package/internal/stateful-module-runtime.js +303 -0
  161. package/internal/stateful-root-compiler.js +598 -0
  162. package/internal/stateful-root-runtime.js +340 -0
  163. package/internal/typert-codec-compat.js +28 -0
  164. package/internal/typescript-transform.js +29 -0
  165. package/internal/user-binding-authoring.js +70 -0
  166. package/internal/user-binding-console-worker.js +184 -0
  167. package/internal/user-binding-console.js +148 -0
  168. package/internal/user-binding-draft-projection.js +335 -0
  169. package/internal/user-binding-model-context.js +31 -0
  170. package/internal/user-binding-runner.js +56 -0
  171. package/internal/user-bindings-owner.js +1065 -0
  172. package/internal/user-bindings-store.js +293 -0
  173. package/internal/user-bindings.js +353 -0
  174. package/internal/value-wire-schema.js +28 -0
  175. package/internal/value-wire.js +29 -20
  176. package/internal/worker-client.js +57 -67
  177. package/internal/worker-environment.js +45 -0
  178. package/internal/worker-output-relay.js +29 -0
  179. package/internal/worker-shutdown.js +14 -0
  180. package/package.json +75 -7
  181. package/src/client-activity.js +88 -53
  182. package/src/client-authoring-view.js +580 -0
  183. package/src/client-binding-review.js +230 -0
  184. package/src/client-bindings-data.js +29 -0
  185. package/src/client-catalog.js +127 -0
  186. package/src/client-code-editor.js +84 -0
  187. package/src/client-console.js +112 -0
  188. package/src/client-copy.js +370 -0
  189. package/src/client-feature-gates.js +62 -0
  190. package/src/client-host-compat.js +150 -0
  191. package/src/client-indicator-view.js +267 -0
  192. package/src/client-repl-view.js +292 -0
  193. package/src/client-rpc.js +20 -0
  194. package/src/client-settings-view.js +221 -0
  195. package/src/client-styles.js +106 -0
  196. package/src/client-tool-view.js +108 -0
  197. package/src/client-transport.js +159 -0
  198. package/src/client-workbench.js +521 -0
  199. package/src/client.js +233 -615
@@ -0,0 +1,598 @@
1
+ /** Compile each cell into a private native frame backed by session identities. */
2
+ import { adaptRootModuleImports } from './managed-module-operations.js'
3
+ import { parse } from '@babel/parser'
4
+ import { createHash } from 'node:crypto'
5
+ import traverseModule from '@babel/traverse'
6
+ import { bindingNodes, createGeneratedNameAllocator, isWriteIdentifier } from './binding-pattern.js'
7
+ import { applySourceEdits, createMappedTextBuilder, identitySourceMap, mapSourceSpan } from './source-position-map.js'
8
+ import { CELL_PARSER_PLUGINS, RECOVERABLE_CELL_PARSE_ERRORS } from './repl-scope-normalizer.js'
9
+ import { adaptDynamicCell } from './dynamic-environment-integration.js'
10
+ import { sourceBinding, varInitializerTarget } from './dynamic-scope-analysis.js'
11
+
12
+ const traverse = traverseModule.default ?? traverseModule
13
+ const PARSER_OPTIONS = {
14
+ sourceType: 'script', allowAwaitOutsideFunction: true, allowReturnOutsideFunction: true,
15
+ allowImportExportEverywhere: true, allowUndeclaredExports: true, plugins: CELL_PARSER_PLUGINS,
16
+ }
17
+ const TYPE_ONLY = new Set(['TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'TSDeclareFunction'])
18
+
19
+ function span(node) {
20
+ return { line: node.loc.start.line, column: node.loc.start.column + 1,
21
+ end: { line: node.loc.end.line, column: node.loc.end.column + 1 } }
22
+ }
23
+
24
+ function rootDeclarations(tree) {
25
+ const declarations = []
26
+ traverse(tree, { noScope: true,
27
+ VariableDeclaration(path) {
28
+ if (path.node.declare === true) return
29
+ const direct = path.parent.type === 'Program' || path.parent.type === 'ExportNamedDeclaration'
30
+ if (direct || path.node.kind === 'var' && path.getFunctionParent() === null
31
+ && path.findParent(parent => parent.isClass() || parent.isStaticBlock()) === null) declarations.push(path)
32
+ },
33
+ FunctionDeclaration(path) {
34
+ let owner = path.parentPath
35
+ while (owner.isLabeledStatement()) owner = owner.parentPath
36
+ if (owner.isProgram() || owner.isExportNamedDeclaration()
37
+ || owner.isExportDefaultDeclaration()) declarations.push(path)
38
+ },
39
+ ClassDeclaration(path) {
40
+ if (path.parent.type === 'Program' || path.parent.type === 'ExportNamedDeclaration'
41
+ || path.parent.type === 'ExportDefaultDeclaration') declarations.push(path)
42
+ },
43
+ })
44
+ return declarations
45
+ }
46
+
47
+ function patternText(pattern, code, reference) {
48
+ const ids = new Set(bindingNodes(pattern))
49
+ const edits = []
50
+ const visit = (node, parent, grandparent) => {
51
+ if (node === null || typeof node !== 'object') return
52
+ if (ids.has(node)) {
53
+ const shorthand = parent?.type === 'ObjectProperty' && parent.shorthand && parent.value === node
54
+ || parent?.type === 'AssignmentPattern' && grandparent?.type === 'ObjectProperty' && grandparent.shorthand
55
+ edits.push({ start: node.start, end: node.end,
56
+ text: `${shorthand ? `[${JSON.stringify(node.name)}]: ` : ''}${reference(node)}` })
57
+ return
58
+ }
59
+ for (const [key, value] of Object.entries(node)) {
60
+ if (['loc', 'start', 'end', 'extra'].includes(key)) continue
61
+ if (Array.isArray(value)) value.forEach(child => visit(child, node, parent))
62
+ else if (value?.type !== undefined) visit(value, node, parent)
63
+ }
64
+ }
65
+ visit(pattern)
66
+ const selected = edits.sort((a, b) => a.start - b.start)
67
+ const builder = createMappedTextBuilder(code)
68
+ let offset = pattern.start
69
+ for (const edit of selected) {
70
+ builder.appendSource(offset, edit.start)
71
+ builder.appendMapped(edit.text, edit.start, edit.end)
72
+ offset = edit.end
73
+ }
74
+ builder.appendSource(offset, pattern.end)
75
+ return builder.result()
76
+ }
77
+
78
+ function ownsImplicitArguments(path) {
79
+ return path.node.name === 'arguments'
80
+ && path.findParent(parent => parent.isFunction() && !parent.isArrowFunctionExpression()) !== null
81
+ }
82
+
83
+ function rewriteRootReferences(code, sourceMap, runtime, candidateNames, candidateReferences, originalSource) {
84
+ const tree = parse(code, PARSER_OPTIONS)
85
+ const edits = []
86
+ const classificationEdits = []
87
+ const handled = new Set()
88
+ const implicitDeclarations = new Map()
89
+ const readNames = new Set()
90
+ const dynamicFunctions = new WeakSet()
91
+ traverse(tree, { CallExpression(path) {
92
+ if (path.node.callee.type === 'Identifier' && path.node.callee.name === 'eval') {
93
+ const fn = path.getFunctionParent()
94
+ if (fn !== null) dynamicFunctions.add(fn.node)
95
+ }
96
+ } })
97
+ const sourceIdentity = createHash('sha256').update(originalSource).digest('hex')
98
+ traverse(tree, { Identifier(path) {
99
+ if (!isWriteIdentifier(path) || sourceBinding(path, path.node.name) !== undefined || ownsImplicitArguments(path)) return
100
+ const assignment = path.findParent(parent => parent.isAssignmentExpression() || parent.isUpdateExpression()
101
+ || parent.isForOfStatement() || parent.isForInStatement())
102
+ const position = mapSourceSpan(span(path.node), code, originalSource, sourceMap)
103
+ implicitDeclarations.set(path.node.start, { name: path.node.name, kind: 'variable', writable: true,
104
+ target: `write:${sourceIdentity}:${position.line}:${position.column}:${path.node.name}`,
105
+ definitionSpan: mapSourceSpan(span(assignment.node), code, originalSource, sourceMap) })
106
+ } })
107
+ const candidateFor = path => {
108
+ const assignment = path.findParent(parent => parent.isAssignmentExpression()
109
+ && (parent.node.left.type === 'ArrayPattern' || parent.node.left.type === 'ObjectPattern'))
110
+ if (assignment === null || path.node.start > assignment.node.left.end) return undefined
111
+ for (const [candidate, names] of candidateNames) {
112
+ if (!names.has(path.node.name)) continue
113
+ const mentions = node => {
114
+ if (node === null || typeof node !== 'object') return false
115
+ if (node.type === 'Identifier' && node.name === candidate) return true
116
+ return Object.values(node).some(value => Array.isArray(value)
117
+ ? value.some(mentions) : value?.type !== undefined && mentions(value))
118
+ }
119
+ if (mentions(assignment.node.left)) return candidate
120
+ }
121
+ return undefined
122
+ }
123
+ traverse(tree, { Decorator(path) {
124
+ const expression = path.node.expression
125
+ if (expression.extra?.parenthesized) return
126
+ // A computed root reference has a wider grammar than a bare decorator name.
127
+ const boundaries = [{ start: expression.start, end: expression.start, text: '(' },
128
+ { start: expression.end, end: expression.end, text: ')' }]
129
+ edits.push(...boundaries)
130
+ classificationEdits.push(...boundaries)
131
+ }, TSTypeAssertion(path) {
132
+ const edit = { start: path.node.start, end: path.node.expression.start,
133
+ text: ' '.repeat(path.node.expression.start - path.node.start) }
134
+ edits.push(edit)
135
+ classificationEdits.push(edit)
136
+ }, Identifier(path) {
137
+ if (handled.has(path.node.start) || sourceBinding(path, path.node.name) !== undefined || ownsImplicitArguments(path)) return
138
+ if (!path.isReferencedIdentifier() && !isWriteIdentifier(path)) return
139
+ if (path.findParent(parent => parent.isVariableDeclarator() && parent.node.id.name === runtime
140
+ || parent.isCallExpression() && parent.node.callee.type === 'MemberExpression'
141
+ && parent.node.callee.object.name === runtime && parent.node.callee.property.name === 'import'
142
+ && path.node.start >= parent.node.arguments[1].start && path.node.end <= parent.node.arguments[1].end) !== null) return
143
+ const parent = path.parent
144
+ // The direct-eval environment adapter owns this syntax and its callable
145
+ // identity check. A property read here would turn it into indirect eval.
146
+ if (path.node.name === 'eval' && parent.type === 'CallExpression' && parent.callee === path.node) return
147
+ const selectedCandidate = candidateFor(path)
148
+ if (selectedCandidate === undefined && path.findParent(parent => parent.isWithStatement() && parent.get('body').isAncestor(path)) !== null) return
149
+ if (path.findParent(parent => parent.isFunction() && dynamicFunctions.has(parent.node)) !== null) return
150
+ if (parent.type.startsWith('TS') && parent.expression !== path.node) return
151
+ // A static reference to an outer identity is a reuse event candidate.
152
+ // `for (x of ...)` and `for (x in ...)` bind the left target without
153
+ // reading its previous value, and `delete x` removes the reference without
154
+ // reading it, so both stay out; compound assignment, updates and `typeof`
155
+ // do read it.
156
+ const write = isWriteIdentifier(path)
157
+ const forHeadWrite = (parent.type === 'ForOfStatement' || parent.type === 'ForInStatement') && path.key === 'left'
158
+ const deleted = parent.type === 'UnaryExpression' && parent.operator === 'delete'
159
+ if ((path.isReferencedIdentifier() && !forHeadWrite && !deleted)
160
+ || write && parent.type === 'AssignmentExpression' && parent.operator !== '=') readNames.add(path.node.name)
161
+ const owner = selectedCandidate ?? runtime
162
+ const selectedReference = candidateReferences.has(owner)
163
+ let text = selectedReference ? `${owner}().value` : `${owner}.values[${JSON.stringify(path.node.name)}]`
164
+ if (!selectedReference && isWriteIdentifier(path)) {
165
+ text = `${owner}.reference(${JSON.stringify(path.node.name)}, ${path.isInStrictMode()}, ${JSON.stringify(implicitDeclarations.get(path.node.start).target)}).value`
166
+ }
167
+ if (parent.type === 'UnaryExpression' && (parent.operator === 'typeof' && owner === runtime
168
+ || selectedReference && ['typeof', 'delete'].includes(parent.operator))) {
169
+ edits.push({ start: parent.start, end: parent.end,
170
+ text: selectedReference ? `${owner}().${parent.operator}()` : `${runtime}.typeof(${JSON.stringify(path.node.name)})` })
171
+ handled.add(path.node.start)
172
+ return
173
+ }
174
+ const callable = (parent.type === 'CallExpression' || parent.type === 'OptionalCallExpression') && parent.callee === path.node
175
+ || parent.type === 'TaggedTemplateExpression' && parent.tag === path.node
176
+ if (callable) text = selectedReference ? `${owner}().callee` : `(0, ${text})`
177
+ if (parent.type === 'ObjectProperty' && parent.shorthand && parent.value === path.node) text = `[${JSON.stringify(path.node.name)}]: ${text}`
178
+ edits.push({ start: path.node.start, end: path.node.end, text,
179
+ ...(callable ? { mappings: [{ generatedStart: 0, generatedEnd: text.length,
180
+ originalStart: path.node.start, originalEnd: path.node.start + 1 }] } : {}) })
181
+ if (callable) {
182
+ // V8 reports an indirect call at its opening argument delimiter. Keep
183
+ // that generated call frame anchored to the source callee; arguments
184
+ // retain their own independent mappings.
185
+ const end = parent.type === 'TaggedTemplateExpression' ? parent.quasi.start + 1
186
+ : parent.arguments[0]?.start ?? parent.end
187
+ const punctuation = code.slice(path.node.end, end)
188
+ edits.push({ start: path.node.end, end, text: punctuation,
189
+ mappings: [{ generatedStart: 0, generatedEnd: punctuation.length,
190
+ originalStart: path.node.start, originalEnd: path.node.start + 1 }] })
191
+ }
192
+ handled.add(path.node.start)
193
+ } })
194
+ return { ...applySourceEdits(code, sourceMap, edits),
195
+ classificationCode: applySourceEdits(code, sourceMap, classificationEdits).code,
196
+ implicitDeclarations: [...implicitDeclarations.values()],
197
+ readNames: [...readNames] }
198
+ }
199
+
200
+ export function compileStatefulRoot(program, {
201
+ sourceMap = identitySourceMap(program.length), knownBindings = new Set(), reservedBindings = new Set(),
202
+ originalSource = program,
203
+ unavailableNames = [], languageSemantics = 'stateful-v1',
204
+ importBindings = new Map(), writableBindings = new Set(),
205
+ nativeBindings = new Set(),
206
+ nativeLexicalBindings = new Set(),
207
+ internalBindings = new Set(),
208
+ dynamicBindings = [],
209
+ privateBindings = [],
210
+ dynamicOrigins = [],
211
+ rootCandidates = new Map(),
212
+ establishedRoots = new Map(),
213
+ runtimeExpression, moduleExpression = global => `this[${JSON.stringify(global)}]`,
214
+ } = {}) {
215
+ let file = parse(program, { ...PARSER_OPTIONS, errorRecovery: true })
216
+ // Identifier name inference must precede root and pattern reference lowering.
217
+ const inferredNames = []
218
+ traverse(file, { noScope: true, 'AssignmentExpression|AssignmentPattern|VariableDeclarator'(path) {
219
+ if (path.node.type === 'AssignmentExpression' && !['=', '&&=', '||=', '??='].includes(path.node.operator)) return
220
+ const initializer = path.node.type === 'VariableDeclarator' ? path.node.init : path.node.right
221
+ if (initializer === null) return
222
+ let name = path.node.type === 'VariableDeclarator' ? path.node.id : path.node.left
223
+ let value = initializer
224
+ while ((name.type.startsWith('TS') || name.type === 'ParenthesizedExpression') && name.expression) name = name.expression
225
+ while ((value.type.startsWith('TS') || value.type === 'ParenthesizedExpression') && value.expression) value = value.expression
226
+ if (name.type !== 'Identifier' || !(value.type === 'ArrowFunctionExpression'
227
+ || ['FunctionExpression', 'ClassExpression'].includes(value.type) && value.id === null)) return
228
+ inferredNames.push({ start: initializer.start, end: initializer.start, text: `({[${JSON.stringify(name.name)}]:(` },
229
+ { start: initializer.end, end: initializer.end, text: `)})[${JSON.stringify(name.name)}]` })
230
+ } })
231
+ if (inferredNames.length !== 0) {
232
+ const named = applySourceEdits(program, sourceMap, inferredNames)
233
+ program = named.code
234
+ sourceMap = named.sourceMap
235
+ file = parse(program, { ...PARSER_OPTIONS, errorRecovery: true })
236
+ }
237
+ const protectedError = file.errors.find(error => error.reasonCode !== 'UnexpectedUsingDeclaration')
238
+ if (languageSemantics === 'protected-v1' && protectedError !== undefined) throw protectedError
239
+ const syntaxError = file.errors.find(error => !RECOVERABLE_CELL_PARSE_ERRORS.has(error.reasonCode))
240
+ if (syntaxError !== undefined) throw syntaxError
241
+ const root = rootDeclarations(file).filter(path => path.node.type === 'VariableDeclaration'
242
+ ? !path.node.declarations.every(declarator => {
243
+ const bindings = bindingNodes(declarator.id)
244
+ return bindings.length > 0 && bindings.every(binding => internalBindings.has(binding.name))
245
+ })
246
+ : !internalBindings.has(path.node.id?.name))
247
+ const paths = new Map()
248
+ traverse(file, { noScope: true, enter(path) { paths.set(path.node, path) } })
249
+ const logicalNames = new Map(dynamicBindings.map(binding => [binding.physicalName, binding.name]))
250
+ const allocate = createGeneratedNameAllocator(file, [...knownBindings, ...reservedBindings, ...unavailableNames])
251
+ const runtime = allocate('root')
252
+ const rootRuntimeName = allocate('root_runtime')
253
+ const commitSignal = allocate('root_commit')
254
+ const declarations = []
255
+ const declarationKinds = new Map()
256
+ const commitTargets = new Set()
257
+ const candidateNames = new Map()
258
+ const candidateReferences = new Set()
259
+ const moduleLoads = []
260
+ const imports = new Map()
261
+ const rewrites = []
262
+ const edits = []
263
+ const prologue = []
264
+ let varReferenceMarker
265
+ const varReference = () => {
266
+ if (!varReferenceMarker) {
267
+ varReferenceMarker = allocate('var_reference')
268
+ internalBindings.add(varReferenceMarker)
269
+ dynamicBindings.push({ physicalName: varReferenceMarker, role: 'var-reference' })
270
+ prologue.push(`const ${varReferenceMarker}=void 0;`)
271
+ }
272
+ return varReferenceMarker
273
+ }
274
+ const hoisted = []
275
+ const readOnly = new Set()
276
+ const rootKinds = new Map()
277
+ const sourceCopies = new Map()
278
+ const remember = (text, mappings) => { sourceCopies.set(text, mappings); return text }
279
+ const mapParts = parts => {
280
+ let offset = 0
281
+ return parts.flatMap(text => {
282
+ const mappings = (sourceCopies.get(text) ?? []).map(mapping => ({ ...mapping,
283
+ generatedStart: mapping.generatedStart + offset, generatedEnd: mapping.generatedEnd + offset }))
284
+ offset += text.length
285
+ return mappings
286
+ })
287
+ }
288
+ const emptyCompletion = expression => `const ${allocate('declaration_completion')} = (${expression});`
289
+ for (const path of root) {
290
+ const node = path.node
291
+ for (const binding of node.type === 'VariableDeclaration'
292
+ ? node.declarations.flatMap(declarator => bindingNodes(declarator.id)) : node.id === null ? [] : [node.id]) {
293
+ const kinds = rootKinds.get(binding.name) ?? new Set()
294
+ kinds.add(node.type === 'VariableDeclaration' ? node.kind : node.type)
295
+ rootKinds.set(binding.name, kinds)
296
+ }
297
+ }
298
+ const canInstantiate = name => !knownBindings.has(name) && !imports.has(name)
299
+ && rootKinds.has(name)
300
+ && [...rootKinds.get(name)].every(kind => kind === 'var' || kind === 'FunctionDeclaration')
301
+ const record = (name, kind, node, binding = node, suffix = '') => {
302
+ const target = `root:${node.start}:${name}${suffix}`
303
+ declarationKinds.set(target, kind === 'import' ? 'const' : kind === 'function' ? 'hoisted'
304
+ : kind === 'class' ? 'let' : node.kind ?? 'const')
305
+ declarations.push({ name, kind, writable: languageSemantics === 'stateful-v1'
306
+ || kind !== 'import' && (kind !== 'variable' || node.kind === 'let' || node.kind === 'var'),
307
+ original: true, span: mapSourceSpan(span(binding), program, originalSource, sourceMap),
308
+ definitionSpan: mapSourceSpan(span(node), program, originalSource, sourceMap), commitDependency: target })
309
+ commitTargets.add(target)
310
+ return target
311
+ }
312
+ const variable = (node, declarator, supplied = undefined) => {
313
+ const bindings = bindingNodes(declarator.id)
314
+ const names = [...new Set(bindings.map(binding => binding.name))]
315
+ if (names.length === 0) {
316
+ const original = supplied === undefined ? declarator : declarator.id
317
+ const source = program.slice(original.start, original.end)
318
+ const text = `const ${source}${supplied === undefined ? '' : ` = (${supplied})`};`
319
+ return remember(text, [{ generatedStart: 6, generatedEnd: 6 + source.length,
320
+ originalStart: original.start, originalEnd: original.end }])
321
+ }
322
+ const target = record(names[0], 'variable', node, bindings[0], `:${declarator.start}`)
323
+ for (const binding of bindings.slice(1)) {
324
+ record(binding.name, 'variable', node, binding, `:${declarator.start}`)
325
+ declarations.at(-1).commitDependency = target
326
+ }
327
+ if (declarator.init === null && supplied === undefined) {
328
+ return emptyCompletion(`${runtime}.declare(${JSON.stringify(names[0])}, ${JSON.stringify(target)})`)
329
+ }
330
+ let value = supplied ?? program.slice(declarator.init.start, declarator.init.end)
331
+ const redirected = new Map()
332
+ const initializerTargets = new Map()
333
+ if (node.kind === 'var') for (const binding of bindings) {
334
+ const selected = varInitializerTarget(paths.get(binding), file.program, binding.name,
335
+ node => logicalNames.get(node.name) ?? node.name)
336
+ initializerTargets.set(binding.name, selected)
337
+ if (selected.catchNode) {
338
+ redirected.set(binding.name, selected.catchNode.param.name)
339
+ }
340
+ }
341
+ if (declarator.id.type === 'Identifier') {
342
+ const selected = redirected.get(names[0])
343
+ const withDepth = initializerTargets.get(names[0])?.withNodes.length
344
+ const fallbackRead = selected ?? `${runtime}.values[${JSON.stringify(names[0])}]`
345
+ const fallbackWrite = selected === undefined
346
+ ? `${runtime}.assign(${JSON.stringify(names[0])}, next, ${JSON.stringify(target)})` : `${selected}=next`
347
+ const text = withDepth
348
+ ? emptyCompletion(`${varReference()}(${JSON.stringify(names[0])},${withDepth},{get:()=>${fallbackRead},set:next=>${fallbackWrite}}).value = (${value})`)
349
+ : selected === undefined
350
+ ? emptyCompletion(`${runtime}.assign(${JSON.stringify(names[0])}, (${value}), ${JSON.stringify(target)})`)
351
+ : emptyCompletion(`(${selected} = (${value}), ${runtime}.declare(${JSON.stringify(names[0])}, ${JSON.stringify(target)}))`)
352
+ if (supplied === undefined) {
353
+ const original = program.slice(declarator.init.start, declarator.init.end)
354
+ const start = text.indexOf(withDepth ? `= (${value})` : selected === undefined ? `, (${value}),` : `= (${value}),`) + 3 + value.indexOf(original)
355
+ remember(text, [{ generatedStart: start, generatedEnd: start + original.length,
356
+ originalStart: declarator.init.start, originalEnd: declarator.init.end }])
357
+ }
358
+ return text
359
+ }
360
+ const candidate = allocate('candidate')
361
+ const rhs = allocate('candidate_rhs')
362
+ const stored = names.filter(name => !redirected.has(name))
363
+ candidateNames.set(candidate, new Set(stored))
364
+ const captured = stored.filter(name => !initializerTargets.get(name)?.withNodes.length)
365
+ if (captured.length > 0) dynamicBindings.push({ physicalName: candidate, names: captured,
366
+ kind: node.kind, role: 'candidate', property: 'values', referenceMethod: 'reference' })
367
+ const references = new Map()
368
+ const referenceDeclarations = []
369
+ for (const name of names) {
370
+ const withDepth = initializerTargets.get(name)?.withNodes.length
371
+ if (!withDepth) continue
372
+ const reference = allocate('candidate_reference')
373
+ const caught = redirected.get(name)
374
+ const pending = allocate('candidate_written')
375
+ const fallback = caught ?? `${candidate}.values[${JSON.stringify(name)}]`
376
+ const get = caught ?? `${pending}?${fallback}:${runtime}.values[${JSON.stringify(name)}]`
377
+ const set = caught === undefined ? `(${pending}=true,${fallback}=next)` : `${caught}=next`
378
+ referenceDeclarations.push(`${caught === undefined ? `let ${pending}=false;` : ''}const ${reference}=()=>${varReference()}(${JSON.stringify(name)},${withDepth},{get:()=>${get},set:next=>${set}});`)
379
+ internalBindings.add(pending)
380
+ candidateReferences.add(reference)
381
+ candidateNames.set(reference, new Set([name]))
382
+ references.set(name, `${reference}().value`)
383
+ dynamicBindings.push({ physicalName: reference, name, kind: 'let', role: 'candidate', reference: true, accessor: true })
384
+ }
385
+ const pattern = patternText(declarator.id, program, binding => references.get(binding.name) ?? redirected.get(binding.name)
386
+ ?? `${candidate}.values[${JSON.stringify(binding.name)}]`)
387
+ const text = `{ const ${rhs} = (${value}); const ${candidate} = ${runtime}.candidate(${JSON.stringify(stored)}); ${referenceDeclarations.join('')} ${emptyCompletion(`((${pattern.text} = ${rhs}), ${candidate}.commit(${JSON.stringify(target)}))`)} }`
388
+ const valueStart = text.indexOf(`= (${value})`) + 3
389
+ const patternStart = text.indexOf(pattern.text)
390
+ return remember(text, [...(supplied === undefined ? [{ generatedStart: valueStart, generatedEnd: valueStart + value.length,
391
+ originalStart: declarator.init.start, originalEnd: declarator.init.end }] : []),
392
+ ...pattern.mappings.map(mapping => ({ ...mapping, generatedStart: patternStart + mapping.generatedStart,
393
+ generatedEnd: patternStart + mapping.generatedEnd }))])
394
+ }
395
+ const addLoad = node => {
396
+ const global = allocate('root_module')
397
+ const requiredExports = node.type === 'ImportDeclaration' ? node.specifiers
398
+ .filter(specifier => specifier.importKind !== 'type' && specifier.type !== 'ImportNamespaceSpecifier')
399
+ .map(specifier => specifier.type === 'ImportDefaultSpecifier' ? 'default' : specifier.imported.name ?? specifier.imported.value) : []
400
+ const attributes = node.attributes?.length > 0 ? { with: Object.fromEntries(node.attributes
401
+ .map(attribute => [attribute.key.name ?? attribute.key.value, attribute.value.value])) } : undefined
402
+ moduleLoads.push({ source: node.source.value, global, position: mapSourceSpan(span(node.source), program, originalSource, sourceMap),
403
+ ...(requiredExports.length === 0 ? {} : { requiredExports: [...new Set(requiredExports)] }),
404
+ ...(attributes === undefined ? {} : { options: attributes }) })
405
+ return global
406
+ }
407
+ for (const node of file.program.body) {
408
+ if (node.type === 'ImportDeclaration') {
409
+ if (node.importKind !== 'type' && (node.specifiers.length === 0
410
+ || node.specifiers.some(specifier => specifier.importKind !== 'type'))) {
411
+ const global = addLoad(node)
412
+ for (const specifier of node.specifiers.filter(specifier => specifier.importKind !== 'type')) {
413
+ const name = specifier.local.name
414
+ readOnly.add(name)
415
+ const imported = specifier.type === 'ImportNamespaceSpecifier' ? null
416
+ : specifier.type === 'ImportDefaultSpecifier' ? 'default' : specifier.imported.name ?? specifier.imported.value
417
+ const target = record(name, 'import', node, specifier.local)
418
+ imports.set(name, { namespace: global, ...(imported === null ? {} : { imported }), commitDependency: target })
419
+ prologue.push(emptyCompletion(`${runtime}.import(${JSON.stringify(name)}, ${moduleExpression(global)}, ${JSON.stringify(imported)}, ${JSON.stringify(target)})`))
420
+ }
421
+ rewrites.push({ kind: 'import', description: `adapted the static import of ${JSON.stringify(node.source.value)}`, source: node.source.value })
422
+ } else {
423
+ rewrites.push({ kind: 'import', description: `removed the type-only import of ${JSON.stringify(node.source.value)}`, source: node.source.value })
424
+ }
425
+ edits.push({ start: node.start, end: node.end, text: '' })
426
+ } else if (node.type === 'ExportAllDeclaration' || node.type === 'ExportNamedDeclaration' && node.declaration === null) {
427
+ if (node.source !== null && node.exportKind !== 'type') addLoad(node)
428
+ rewrites.push({ kind: 'export', description: node.exportKind === 'type'
429
+ ? 'removed a type-only export declaration'
430
+ : node.source == null ? 'removed a local re-export declaration'
431
+ : `converted the re-export of ${JSON.stringify(node.source.value)} into a side-effect import` })
432
+ edits.push({ start: node.start, end: node.end, text: '' })
433
+ } else if (node.type === 'ExportNamedDeclaration') {
434
+ rewrites.push({ kind: 'export', description: 'stripped the export modifier from a top-level declaration' })
435
+ edits.push({ start: node.start, end: node.declaration.start, text: '' })
436
+ } else if (node.type === 'ExportDefaultDeclaration') {
437
+ rewrites.push({ kind: 'export', description: TYPE_ONLY.has(node.declaration.type)
438
+ ? 'removed a type-only export declaration'
439
+ : 'converted the default export into a local __default binding' })
440
+ if (TYPE_ONLY.has(node.declaration.type)) {
441
+ edits.push({ start: node.start, end: node.end, text: '' })
442
+ } else if (!['FunctionDeclaration', 'ClassDeclaration'].includes(node.declaration.type)) {
443
+ const target = record('__default', 'variable', node)
444
+ edits.push({ start: node.start, end: node.end,
445
+ text: emptyCompletion(`${runtime}.assign("__default", (${program.slice(node.declaration.start, node.declaration.end)}), ${JSON.stringify(target)})`) })
446
+ }
447
+ }
448
+ }
449
+ for (const path of root) {
450
+ const node = path.node
451
+ if (node.type === 'VariableDeclaration') {
452
+ if (node.kind === 'const' || node.kind === 'using' || node.kind === 'await using') {
453
+ for (const binding of node.declarations.flatMap(declarator => bindingNodes(declarator.id))) readOnly.add(binding.name)
454
+ }
455
+ if (node.kind === 'using' || node.kind === 'await using') {
456
+ // Resource lifetime owns the acquired value even when the public
457
+ // logical binding is replaced before the scope ends.
458
+ const parts = node.declarations.flatMap(declarator => {
459
+ const resource = allocate('root_resource')
460
+ const value = program.slice(declarator.init.start, declarator.init.end)
461
+ const resourceText = `${node.kind} ${resource} = (${value});`
462
+ const valueStart = resourceText.indexOf(`= (${value})`) + 3
463
+ remember(resourceText, [{ generatedStart: valueStart, generatedEnd: valueStart + value.length,
464
+ originalStart: declarator.init.start, originalEnd: declarator.init.end }])
465
+ return [resourceText, variable(node, declarator, resource)]
466
+ })
467
+ edits.push({ start: node.start, end: node.end, text: parts.join(''), mappings: mapParts(parts) })
468
+ continue
469
+ }
470
+ for (const declarator of node.declarations) {
471
+ if (node.kind !== 'var') continue
472
+ for (const binding of bindingNodes(declarator.id)) {
473
+ if (!canInstantiate(binding.name) || hoisted.includes(binding.name)) continue
474
+ hoisted.push(binding.name)
475
+ const target = record(binding.name, 'variable', node, binding, ':hoist')
476
+ prologue.push(emptyCompletion(`${runtime}.declare(${JSON.stringify(binding.name)}, ${JSON.stringify(target)})`))
477
+ }
478
+ }
479
+ if (path.parent.type === 'ForOfStatement' || path.parent.type === 'ForInStatement') {
480
+ if (node.declarations[0].init !== null) {
481
+ let owner = path.parentPath
482
+ while (owner.parentPath?.isLabeledStatement()) owner = owner.parentPath
483
+ const prefix = ['{ ', variable(node, node.declarations[0]), '\n']
484
+ edits.push({ start: owner.node.start, end: owner.node.start, text: prefix.join(''), mappings: mapParts(prefix) })
485
+ edits.push({ start: owner.node.end, end: owner.node.end, text: ' }' })
486
+ }
487
+ const temporary = allocate('iteration')
488
+ edits.push({ start: node.start, end: node.end, text: `const ${temporary}` })
489
+ const body = path.parent.body
490
+ const assignments = variable(node, node.declarations[0], temporary)
491
+ if (body.type === 'BlockStatement') edits.push({ start: body.start + 1, end: body.start + 1, text: assignments,
492
+ mappings: sourceCopies.get(assignments) })
493
+ else {
494
+ edits.push({ start: body.start, end: body.start, text: `{ ${assignments}`, mappings: mapParts(['{ ', assignments]) })
495
+ edits.push({ start: body.end, end: body.end, text: '}' })
496
+ }
497
+ } else {
498
+ const variables = node.declarations.flatMap(declarator => [variable(node, declarator), '\n'])
499
+ const parts = ['{ ', ...variables, ' }']
500
+ if (path.parent.type === 'ForStatement') {
501
+ let owner = path.parentPath
502
+ while (owner.parentPath?.isLabeledStatement()) owner = owner.parentPath
503
+ const prefix = ['{ ', ...parts]
504
+ edits.push({ start: owner.node.start, end: owner.node.start, text: prefix.join(''), mappings: mapParts(prefix) })
505
+ edits.push({ start: node.start, end: node.end, text: '' })
506
+ edits.push({ start: owner.node.end, end: owner.node.end, text: ' }' })
507
+ } else edits.push({ start: node.start, end: node.end, text: parts.join(''), mappings: mapParts(parts) })
508
+ }
509
+ continue
510
+ }
511
+ const name = node.id?.name ?? '__default'
512
+ const kind = node.type === 'FunctionDeclaration' ? 'function' : 'class'
513
+ const target = record(name, kind, node, node.id ?? node)
514
+ let expression = program.slice(node.start, node.end)
515
+ if (kind === 'function' && node.id !== null) {
516
+ expression = `({ [${JSON.stringify(name)}]: ${program.slice(node.start, node.id.start)}${program.slice(node.id.end, node.end)} })[${JSON.stringify(name)}]`
517
+ }
518
+ if (node.id === null && path.parent.type === 'ExportDefaultDeclaration') {
519
+ expression = `({ ["default"]: (${expression}) })["default"]`
520
+ }
521
+ const text = emptyCompletion(`${runtime}.assign(${JSON.stringify(name)}, (${expression}), ${JSON.stringify(target)})`)
522
+ const expressionStart = text.indexOf(`, (${expression}),`) + 3
523
+ const sourceStart = kind === 'function' && node.id !== null ? node.id.end : node.start
524
+ const copied = program.slice(sourceStart, node.end)
525
+ const copiedStart = expressionStart + expression.indexOf(copied)
526
+ remember(text, [{ generatedStart: copiedStart, generatedEnd: copiedStart + copied.length,
527
+ originalStart: sourceStart, originalEnd: node.end }])
528
+ const canHoist = kind === 'function' && canInstantiate(name)
529
+ if (canHoist) prologue.push(text)
530
+ const defaultExport = path.parent.type === 'ExportDefaultDeclaration'
531
+ const suffix = defaultExport
532
+ ? emptyCompletion(`${runtime}.link("__default", ${JSON.stringify(name)}, ${JSON.stringify(record('__default', kind, path.parent))})`) : ''
533
+ const replacement = [canHoist ? '' : text, suffix]
534
+ if (path.parentPath.isLabeledStatement()) {
535
+ replacement.unshift('{')
536
+ replacement.push('}')
537
+ }
538
+ edits.push({ start: defaultExport ? path.parent.start : node.start,
539
+ end: defaultExport ? path.parent.end : node.end, text: replacement.join(''),
540
+ mappings: mapParts(replacement) })
541
+ }
542
+ const declared = new Set(declarations.map(declaration => declaration.name))
543
+ const rootBindings = { declared: [...declared], known: [...knownBindings], candidates: [...rootCandidates],
544
+ declarationKinds: [...declarationKinds],
545
+ declaredKinds: [...new Map(declarations.map(declaration => [declaration.name, declarationKinds.get(declaration.commitDependency)]))],
546
+ established: [...establishedRoots], readOnly: [...readOnly], languageSemantics,
547
+ legacyImports: [...importBindings], legacyLexicals: [...knownBindings].filter(name => !importBindings.has(name)),
548
+ legacyWritable: [...writableBindings].filter(name => !importBindings.has(name)),
549
+ legacyNative: [...nativeBindings], legacyNativeLexicals: [...nativeLexicalBindings] }
550
+ const accessRuntime = runtimeExpression === undefined ? `this[${JSON.stringify(rootRuntimeName)}]`
551
+ : runtimeExpression(rootBindings)
552
+ const prefixParts = [`;{\nconst ${runtime} = ${accessRuntime};\n`, ...prologue.flatMap(text => [text, '\n'])]
553
+ const directiveEnd = file.program.directives.at(-1)?.end ?? 0
554
+ if (directiveEnd === program.length) prefixParts.push('\n}')
555
+ edits.unshift({ start: directiveEnd, end: directiveEnd, text: prefixParts.join(''), mappings: mapParts(prefixParts) })
556
+ if (directiveEnd !== program.length) edits.push({ start: program.length, end: program.length, text: '\n}' })
557
+ const merged = []
558
+ for (const edit of edits.sort((left, right) => left.start - right.start || left.end - right.end)) {
559
+ const previous = merged.at(-1)
560
+ if (edit.start === edit.end && previous?.start === edit.start && previous.end === edit.end) {
561
+ previous.mappings = [...(previous.mappings ?? []), ...(edit.mappings ?? []).map(mapping => ({ ...mapping,
562
+ generatedStart: mapping.generatedStart + previous.text.length, generatedEnd: mapping.generatedEnd + previous.text.length }))]
563
+ previous.text += edit.text
564
+ } else merged.push({ ...edit })
565
+ }
566
+ const framed = applySourceEdits(program, sourceMap, merged)
567
+ let rewritten = rewriteRootReferences(framed.code, framed.sourceMap, runtime, candidateNames, candidateReferences,
568
+ originalSource)
569
+ rewritten = adaptRootModuleImports(rewritten, runtime)
570
+ rewritten = { ...rewritten, ...adaptDynamicCell(rewritten.code, rewritten.sourceMap, {
571
+ rootRuntime: runtime, bindings: dynamicBindings, privateBindings, internalBindings, parserPlugins: CELL_PARSER_PLUGINS, originalSource,
572
+ }) }
573
+ rootBindings.dynamicOrigins = [...dynamicOrigins, ...rewritten.dynamicOrigins.map(origin => origin.target)]
574
+ rootBindings.candidates = [...new Map([...rootCandidates, ...rewritten.implicitDeclarations.map(declaration => [declaration.target, declaration.name])])]
575
+ // Each record carries the reason this owner determined, so the diagnostic surface does not
576
+ // re-derive reserved-ness or protected policy from the request descriptors.
577
+ const collisions = declarations.filter(declaration => reservedBindings.has(declaration.name)
578
+ || languageSemantics === 'protected-v1' && knownBindings.has(declaration.name))
579
+ .map(declaration => ({ name: declaration.name, kind: declaration.kind,
580
+ reason: reservedBindings.has(declaration.name)
581
+ ? 'reserved-program-binding-not-shadowable' : 'protected-root-redeclaration',
582
+ start: { line: declaration.span.line, column: declaration.span.column }, end: declaration.span.end }))
583
+ // A binding is reused only when this cell's rewritten source statically
584
+ // references an identity that already existed and does not (re)declare that
585
+ // same name. The count is a source fact, not a runtime trace: an unreached or
586
+ // never-invoked reference still counts, and a redeclaration neither counts as
587
+ // a reuse here nor resets the accumulated count it carries.
588
+ const reusedNames = [...(rewritten.readNames ?? [])]
589
+ .filter(name => knownBindings.has(name) && !declared.has(name))
590
+ return {
591
+ ...rewritten, languageSemantics, rootRuntimeName, rootFrameBinding: runtime, commitSignal, commitTargets, declarations, declared,
592
+ rootPlan: rootBindings,
593
+ rootBindings,
594
+ rootBindingFacts: true, moduleLoads, imports, importNamespaces: new Set(), collisions,
595
+ redeclared: declarations.filter(declaration => knownBindings.has(declaration.name)), rewrites,
596
+ establishedRootLexicals: new Set(), reusedNames,
597
+ }
598
+ }