dsh-ptc-plus 0.3.1 → 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 (200) hide show
  1. package/README.en.md +66 -73
  2. package/README.md +66 -73
  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 +30610 -722
  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 +6 -4
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
  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 +9 -3
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
  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 +8 -6
  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 +17 -3
  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 +82 -22
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +96 -20
  51. package/docs/durability-design.md +61 -24
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/program-data-plane.md +6 -0
  55. package/docs/publishing.md +5 -3
  56. package/docs/runtime-reference.md +79 -25
  57. package/docs/semantic-validation.md +29 -0
  58. package/docs/stateful-binding-updates-proposal.md +755 -0
  59. package/docs/user-bindings.en.md +64 -0
  60. package/docs/user-bindings.md +64 -0
  61. package/docs/value-wire.md +3 -3
  62. package/docs/verification.md +57 -0
  63. package/index.js +374 -92
  64. package/internal/ast-traversal.js +5 -2
  65. package/internal/binding-descriptors.js +1 -0
  66. package/internal/binding-pattern-traversal.js +25 -0
  67. package/internal/binding-pattern.js +26 -29
  68. package/internal/binding-source-analysis.js +391 -0
  69. package/internal/binding-update-policy.js +66 -0
  70. package/internal/bounded-worker-round.js +56 -0
  71. package/internal/callable-definition-environment.js +42 -0
  72. package/internal/callable-source-catalog.js +129 -0
  73. package/internal/callable-source-encoding.js +47 -0
  74. package/internal/callable-source-facts.js +459 -0
  75. package/internal/callable-source-format.js +2 -0
  76. package/internal/callable-source-lowering.js +123 -0
  77. package/internal/cell-analysis-contract.js +25 -0
  78. package/internal/cell-analysis.js +252 -242
  79. package/internal/cell-completion.js +15 -0
  80. package/internal/cell-error.js +7 -0
  81. package/internal/cell-parser.js +66 -0
  82. package/internal/cell-rewriter.js +3 -553
  83. package/internal/commonjs-export-evidence.js +63 -0
  84. package/internal/commonjs-source-evidence.js +72 -0
  85. package/internal/compiler-amaro.cjs +2 -0
  86. package/internal/compiler-compression.js +12 -0
  87. package/internal/compiler-data.js +58 -0
  88. package/internal/compiler-descriptors.js +54 -0
  89. package/internal/compiler-dynamic-cache.js +48 -0
  90. package/internal/compiler-entry.js +35 -0
  91. package/internal/compiler-generated-names.js +17 -0
  92. package/internal/compiler-intrinsics.js +84 -0
  93. package/internal/compiler-module-links.js +34 -0
  94. package/internal/compiler-operations.js +61 -0
  95. package/internal/compiler-platform-factory.js +84 -0
  96. package/internal/compiler-platform.js +136 -0
  97. package/internal/compiler-record-roles.js +53 -0
  98. package/internal/compiler-region-output.js +259 -0
  99. package/internal/compiler-resource-lowering.js +103 -0
  100. package/internal/compiler-scope-facts.js +115 -0
  101. package/internal/compiler-service.js +109 -0
  102. package/internal/compiler-source-cache.js +32 -0
  103. package/internal/compiler-source-pieces.js +93 -0
  104. package/internal/compiler-source-regions.js +132 -0
  105. package/internal/compiler-storage-source.js +54 -0
  106. package/internal/compiler-text.js +15 -0
  107. package/internal/compiler-typescript.cjs +2 -0
  108. package/internal/config-spec.js +91 -25
  109. package/internal/cordis-tools-owner.js +130 -21
  110. package/internal/diagnostic.js +27 -1
  111. package/internal/direct-surface-owner.js +76 -23
  112. package/internal/dynamic-binding-evidence.js +16 -0
  113. package/internal/dynamic-environment-compiler.js +779 -0
  114. package/internal/dynamic-environment-integration.js +87 -0
  115. package/internal/dynamic-environment-runtime.js +362 -0
  116. package/internal/dynamic-native-calls.js +150 -0
  117. package/internal/dynamic-native-runtime.js +248 -0
  118. package/internal/dynamic-scope-analysis.js +90 -0
  119. package/internal/edit-transport-owner.js +28 -3
  120. package/internal/execution-seam-compat.js +193 -0
  121. package/internal/failure-reporting.js +118 -18
  122. package/internal/host-rpc.js +66 -0
  123. package/internal/isolated-worker.js +548 -0
  124. package/internal/kernel-child.js +139 -0
  125. package/internal/kernel-worker.js +911 -116
  126. package/internal/language-semantics.js +14 -0
  127. package/internal/legacy-binding-catalog.js +48 -0
  128. package/internal/legacy-cell-analysis.js +600 -0
  129. package/internal/legacy-cell-parser.js +50 -0
  130. package/internal/legacy-cell-rewriter.js +631 -0
  131. package/internal/legacy-repl-convenience.js +291 -0
  132. package/internal/managed-module-operations.js +170 -0
  133. package/internal/module-compilation.js +321 -0
  134. package/internal/module-runtime-platform.js +19 -0
  135. package/internal/module-transform-contract.js +12 -0
  136. package/internal/native-await-declarations.js +68 -0
  137. package/internal/native-root-compilation.js +54 -0
  138. package/internal/native-root-dynamic.js +67 -0
  139. package/internal/recovery-tips.js +27 -15
  140. package/internal/rejected-cell-editor.js +13 -8
  141. package/internal/repl-convenience.js +2 -201
  142. package/internal/repl-memory-projection.js +81 -12
  143. package/internal/repl-observation-interest.js +70 -0
  144. package/internal/repl-rewrite-contract.js +21 -0
  145. package/internal/repl-scope-normalizer.js +2091 -0
  146. package/internal/repl-value-observer.js +114 -0
  147. package/internal/rpc-contract.js +52 -0
  148. package/internal/runtime-bridge-owner.js +172 -28
  149. package/internal/runtime-config.js +48 -51
  150. package/internal/runtime-contexts.js +82 -10
  151. package/internal/runtime-messages.js +111 -0
  152. package/internal/session-cell-executor.js +455 -91
  153. package/internal/session-journal-recovery.js +684 -0
  154. package/internal/session-journal-schema.js +106 -0
  155. package/internal/session-journal.js +237 -440
  156. package/internal/session-log-view.js +42 -9
  157. package/internal/session-runtime.js +325 -80
  158. package/internal/session-state.js +249 -40
  159. package/internal/source-position-map.js +211 -71
  160. package/internal/stateful-module-compiler.js +154 -0
  161. package/internal/stateful-module-runtime.js +303 -0
  162. package/internal/stateful-root-compiler.js +598 -0
  163. package/internal/stateful-root-runtime.js +340 -0
  164. package/internal/typert-codec-compat.js +28 -0
  165. package/internal/typescript-transform.js +29 -0
  166. package/internal/user-binding-authoring.js +70 -0
  167. package/internal/user-binding-console-worker.js +184 -0
  168. package/internal/user-binding-console.js +148 -0
  169. package/internal/user-binding-draft-projection.js +335 -0
  170. package/internal/user-binding-model-context.js +31 -0
  171. package/internal/user-binding-runner.js +56 -0
  172. package/internal/user-bindings-owner.js +1065 -0
  173. package/internal/user-bindings-store.js +293 -0
  174. package/internal/user-bindings.js +353 -0
  175. package/internal/value-wire-schema.js +28 -0
  176. package/internal/value-wire.js +29 -20
  177. package/internal/worker-client.js +57 -67
  178. package/internal/worker-environment.js +45 -0
  179. package/internal/worker-output-relay.js +29 -0
  180. package/internal/worker-shutdown.js +14 -0
  181. package/package.json +81 -11
  182. package/src/client-activity.js +109 -45
  183. package/src/client-authoring-view.js +580 -0
  184. package/src/client-binding-review.js +230 -0
  185. package/src/client-bindings-data.js +29 -0
  186. package/src/client-catalog.js +127 -0
  187. package/src/client-code-editor.js +84 -0
  188. package/src/client-console.js +112 -0
  189. package/src/client-copy.js +370 -0
  190. package/src/client-feature-gates.js +62 -0
  191. package/src/client-host-compat.js +150 -0
  192. package/src/client-indicator-view.js +267 -0
  193. package/src/client-repl-view.js +292 -0
  194. package/src/client-rpc.js +20 -0
  195. package/src/client-settings-view.js +221 -0
  196. package/src/client-styles.js +106 -0
  197. package/src/client-tool-view.js +108 -0
  198. package/src/client-transport.js +159 -0
  199. package/src/client-workbench.js +521 -0
  200. package/src/client.js +233 -615
@@ -0,0 +1,63 @@
1
+ import { createRequire } from 'node:module'
2
+ import { linkCommonJsEvidenceSource } from './compiler-service.js'
3
+ import { moduleRuntimeIntrinsics } from './compiler-intrinsics.js'
4
+ import { compilerPlatformBridge } from './compiler-platform.js'
5
+ import { registerModuleResolutionHook } from './module-runtime-platform.js'
6
+
7
+ const { Map, mapGet, mapHas, mapSet, mapDelete, startsWith, sliceString, stringify } = moduleRuntimeIntrinsics
8
+ const nativeCreateRequire = createRequire
9
+
10
+ let nextEvidence = 0
11
+
12
+ /** Own analysis-only source companions for modules that actually enter Node. */
13
+ export function createCommonJsEvidence({ linkSource = linkCommonJsEvidenceSource } = {}) {
14
+ const sources = new Map()
15
+ const modules = new Map()
16
+ return {
17
+ attach(url, code, source) {
18
+ let record = mapGet(modules, url)
19
+ if (record?.source !== source) {
20
+ if (record !== undefined) mapDelete(sources, record.reference)
21
+ // CJS resolution uses its native parent filename as well as the public
22
+ // context. A sibling preserves package and extension lookup semantics.
23
+ const reference = compilerPlatformBridge.url(`.__ptc_commonjs_evidence_${++nextEvidence}.cjs`, url)
24
+ const prefix = `ptc-module:evidence-link/${nextEvidence}/`
25
+ record = { url, source, reference, prefix, evidence: linkSource(source, prefix) }
26
+ mapSet(modules, url, record)
27
+ mapSet(sources, reference, record)
28
+ }
29
+ // This final assignment only contributes native linking evidence. The
30
+ // original module executes once and remains the source of every value.
31
+ return `${code}\n;if(false)module.exports=require(${stringify(record.reference)});\n`
32
+ },
33
+ resolve(specifier, context, recordResolution) {
34
+ if (mapHas(sources, specifier)) return { url: specifier, format: 'commonjs', shortCircuit: true }
35
+ const source = mapGet(sources, context.parentURL)
36
+ if (source === undefined || !startsWith(specifier, source.prefix)) return undefined
37
+ const originalSpecifier = sliceString(specifier, source.prefix.length)
38
+ let resolution
39
+ const request = `ptc-module:evidence-resolution/${++nextEvidence}`
40
+ const resolved = {}
41
+ const forwardedContext = { ...context, parentURL: source.url }
42
+ const dispose = registerModuleResolutionHook((value, details, next) => {
43
+ if (value !== request) return next(value, details)
44
+ resolution = next(originalSpecifier, forwardedContext)
45
+ // Stop this private request at resolution. Node's existing CJS linker
46
+ // owns the subsequent load; neither the evidence nor user code runs.
47
+ throw resolved
48
+ })
49
+ try { nativeCreateRequire(source.url)(request) } catch (error) {
50
+ if (error !== resolved) throw error
51
+ } finally { dispose() }
52
+ recordResolution(source.url, originalSpecifier, context.importAttributes, resolution)
53
+ return { ...resolution, shortCircuit: true }
54
+ },
55
+ load(url) {
56
+ const record = mapGet(sources, url)
57
+ if (record === undefined) return undefined
58
+ // Node scans reexported CJS source without executing it. A return also
59
+ // keeps accidental direct execution from running its original body.
60
+ return { format: 'commonjs', shortCircuit: true, source: `return;\n${record.evidence}` }
61
+ },
62
+ }
63
+ }
@@ -0,0 +1,72 @@
1
+ import { parse } from '@babel/parser'
2
+ import { types as t } from '@babel/core'
3
+ import { transformTypeScriptSource } from './typescript-transform.js'
4
+ import { CELL_PARSER_PLUGINS, normalizeTypeScriptValues } from './repl-scope-normalizer.js'
5
+ import { visitSource } from './compiler-source-regions.js'
6
+ import { applySourceEdits, identitySourceMap } from './source-position-map.js'
7
+
8
+ export function linkCommonJsEvidenceSource(source, prefix) {
9
+ const tree = parse(source, { sourceType: 'commonjs', errorRecovery: true, plugins: CELL_PARSER_PLUGINS })
10
+ const starts = []
11
+ t.traverseFast(tree, node => {
12
+ if (node.type === 'CallExpression' && node.callee.type === 'Identifier'
13
+ && node.callee.name === 'require' && node.arguments[0]?.type === 'StringLiteral') {
14
+ starts.push(node.arguments[0].start + 1)
15
+ }
16
+ })
17
+ const pieces = []
18
+ let previous = 0
19
+ for (const start of starts.sort((left, right) => left - right)) {
20
+ pieces.push(source.slice(previous, start), prefix)
21
+ previous = start
22
+ }
23
+ pieces.push(source.slice(previous))
24
+ return pieces.join('')
25
+ }
26
+
27
+ /** Preserve original spelling for the native CommonJS linker's source analysis. */
28
+ export function commonJsExportEvidence(source, { legacy = false } = {}) {
29
+ try {
30
+ parse(source, { sourceType: 'commonjs' })
31
+ return source
32
+ } catch {
33
+ // Syntax validation belongs to the executable compiler. Evidence only
34
+ // removes type ranges that would interfere with Node's lexical analysis.
35
+ }
36
+ if (!legacy) {
37
+ const normalized = normalizeTypeScriptValues(source, identitySourceMap(source.length), 'commonjs').code
38
+ const tree = parse(normalized, { sourceType: 'commonjs', errorRecovery: true, plugins: CELL_PARSER_PLUGINS })
39
+ const edits = []
40
+ visitSource(tree, { enter(path) {
41
+ const node = path.node
42
+ if (path.isTSType() || path.isTSTypeAnnotation() || path.isTSTypeParameterDeclaration()
43
+ || path.isTSTypeParameterInstantiation()) {
44
+ edits.push({ start: node.start, end: node.end, text: '' })
45
+ path.skip()
46
+ } else if (node.type.startsWith('TS') && node.expression !== undefined) {
47
+ edits.push({ start: node.start, end: node.expression.start, text: '' },
48
+ { start: node.expression.end, end: node.end, text: '' })
49
+ for (const key of t.VISITOR_KEYS[node.type]) if (key !== 'expression') path.skipKey(key)
50
+ }
51
+ } })
52
+ return applySourceEdits(normalized, identitySourceMap(normalized.length), edits.map(edit => ({ ...edit,
53
+ text: normalized.slice(edit.start, edit.end).replace(/[^\s]/gu, ' ') }))).code
54
+ }
55
+ // Strip types without printing JavaScript: even parentheses and property
56
+ // spellings affect Node's lexical detection. The wrapper permits CJS return
57
+ // and new.target, and is removed before top-level reexport analysis.
58
+ const prefix = 'function __ptc_commonjs_evidence__(){\n'
59
+ const wrapped = `${prefix}${source}\n}`
60
+ let javascript
61
+ try {
62
+ javascript = transformTypeScriptSource(wrapped, { mode: 'strip-only' }).code.slice(prefix.length, -2)
63
+ } catch (error) {
64
+ if (error.cause?.code !== 'UnsupportedSyntax') throw error
65
+ // Legacy TypeScript runtime constructs still use their recorded lowering.
66
+ const transformed = transformTypeScriptSource(wrapped, { module: false,
67
+ transform: { noEmptyExport: true } }).code
68
+ const body = parse(transformed).program.body[0].body
69
+ javascript = transformed.slice(body.start + 1, body.end - 1)
70
+ }
71
+ return javascript
72
+ }
@@ -0,0 +1,2 @@
1
+ // Resolve through the private platform at operation time, not core startup.
2
+ module.exports = () => require('amaro')
@@ -0,0 +1,12 @@
1
+ import { deflateSync, inflateSync } from 'fflate/browser'
2
+
3
+ /** Callable catalog blocks retain the raw DEFLATE wire format. The private
4
+ * compiler owns the library's JavaScript globals and typed-array operations. */
5
+ export const deflateRawSync = input => Buffer.from(deflateSync(input))
6
+
7
+ export function inflateRawSync(input, { maxOutputLength } = {}) {
8
+ const output = maxOutputLength === undefined ? undefined : new Uint8Array(maxOutputLength + 1)
9
+ const result = inflateSync(input, { out: output })
10
+ if (output !== undefined && result.length > maxOutputLength) throw new RangeError('callable source block exceeds its declared limit')
11
+ return Buffer.from(result)
12
+ }
@@ -0,0 +1,58 @@
1
+ import { types } from 'node:util'
2
+ import { SourceMapRuns, SOURCE_MAP_RUNS } from './source-position-map.js'
3
+ import { compilerDescriptors } from './compiler-descriptors.js'
4
+
5
+ const { isMap, isSet, isUint32Array } = types
6
+ const ownKeys = Reflect.ownKeys
7
+ const descriptor = Object.getOwnPropertyDescriptor
8
+ const defineData = compilerDescriptors.defineDataProperty
9
+ const setPrototypeOf = Object.setPrototypeOf
10
+ const stringify = JSON.stringify
11
+ const array = Array.isArray
12
+ const NativeMap = Map, NativeSet = Set, NativeUint32Array = Uint32Array, NativeTypeError = TypeError
13
+ const uncurry = Function.prototype.bind.bind(Function.prototype.call)
14
+ const mapForEach = uncurry(Map.prototype.forEach), mapSet = uncurry(Map.prototype.set)
15
+ const setForEach = uncurry(Set.prototype.forEach), setAdd = uncurry(Set.prototype.add)
16
+
17
+ /** Compiler messages contain data only. Rehome collections instead of invoking
18
+ * methods inherited from a caller's mutable realm. No user value crosses here. */
19
+ export function copyCompilerData(value) {
20
+ return copyData(value, false)
21
+ }
22
+
23
+ /** Internal JSON keys have data fields, never inherited source serialization
24
+ * hooks. Source values continue to use their own realm's JSON operations. */
25
+ export function stringifyCompilerData(value) {
26
+ return stringify(copyData(value, true))
27
+ }
28
+
29
+ function copyData(value, json) {
30
+ if (value === null || typeof value !== 'object') {
31
+ if (typeof value === 'function' || typeof value === 'symbol') throw new NativeTypeError('compiler messages must contain data')
32
+ return value
33
+ }
34
+ if (!json && isUint32Array(value)) return new NativeUint32Array(value)
35
+ if (!json && descriptor(value, SOURCE_MAP_RUNS)?.value === true) return new SourceMapRuns(copyData(value.data, false))
36
+ if (!json && isMap(value)) {
37
+ const result = new NativeMap()
38
+ mapForEach(value, (item, key) => mapSet(result, copyData(key, false), copyData(item, false)))
39
+ return result
40
+ }
41
+ if (!json && isSet(value)) {
42
+ const result = new NativeSet()
43
+ setForEach(value, item => setAdd(result, copyData(item, false)))
44
+ return result
45
+ }
46
+ const result = array(value) ? [] : {}
47
+ if (json) setPrototypeOf(result, null)
48
+ const keys = ownKeys(value)
49
+ for (let index = 0; index < keys.length; index++) {
50
+ const key = keys[index]
51
+ if (key === 'length' && array(value)) continue
52
+ const field = descriptor(value, key)
53
+ if (!('value' in field)) throw new NativeTypeError('compiler messages must not contain accessors')
54
+ defineData(result, key, copyData(field.value, json), field.enumerable)
55
+ }
56
+ if (array(value)) result.length = value.length
57
+ return result
58
+ }
@@ -0,0 +1,54 @@
1
+ /** Private descriptors contain own fields only. Native source reflection keeps
2
+ * its separate ToPropertyDescriptor behavior, including inherited fields. */
3
+ export function createCompilerDescriptors(object, reflect) {
4
+ const define = object.defineProperty, defineMany = object.defineProperties
5
+ const ownKeys = reflect.ownKeys, ownField = object.getOwnPropertyDescriptor
6
+ const reflectDefine = reflect.defineProperty
7
+ const descriptor = fields => ({ __proto__: null, ...fields })
8
+ const ownedObject = function(value) { return object(value) }
9
+ const names = object.getOwnPropertyNames(object)
10
+ for (let index = 0; index < names.length; index++) {
11
+ const name = names[index]
12
+ if (name !== 'name' && name !== 'length' && name !== 'prototype') {
13
+ define(ownedObject, name, descriptor(ownField(object, name)))
14
+ }
15
+ }
16
+ const operations = {
17
+ Object: ownedObject,
18
+ descriptor,
19
+ getOwnPropertyDescriptor(target, key) {
20
+ const fields = ownField(target, key)
21
+ return fields === void 0 ? void 0 : descriptor(fields)
22
+ },
23
+ defineProperty: (target, key, fields) => define(target, key, descriptor(fields)),
24
+ reflectDefineProperty: (target, key, fields) => reflectDefine(target, key, descriptor(fields)),
25
+ // Rehomed compiler data always writes an owned data field. The null
26
+ // prototype still keeps native descriptor conversion from reaching an
27
+ // inherited field, and this writer reaches it without the intermediate
28
+ // own-field descriptor the generic path copies for every property.
29
+ defineDataProperty(target, key, value, enumerable) {
30
+ const fields = { __proto__: null }
31
+ fields.value = value
32
+ fields.enumerable = enumerable
33
+ fields.writable = true
34
+ fields.configurable = true
35
+ return define(target, key, fields)
36
+ },
37
+ defineProperties(target, fields) {
38
+ const table = { __proto__: null }, keys = ownKeys(fields)
39
+ for (let index = 0; index < keys.length; index++) {
40
+ const key = keys[index]
41
+ if (ownField(fields, key).enumerable) table[key] = descriptor(fields[key])
42
+ }
43
+ return defineMany(target, table)
44
+ },
45
+ }
46
+ ownedObject.defineProperty = operations.defineProperty
47
+ ownedObject.defineProperties = operations.defineProperties
48
+ ownedObject.getOwnPropertyDescriptor = operations.getOwnPropertyDescriptor
49
+ return operations
50
+ }
51
+
52
+ // The same construction contract is instantiated in emitted realms.
53
+ export const compilerDescriptorSource = Function.prototype.toString.call(createCompilerDescriptors)
54
+ export const compilerDescriptors = createCompilerDescriptors(Object, Reflect)
@@ -0,0 +1,48 @@
1
+ import { copyCompilerData } from './compiler-data.js'
2
+
3
+ /** Reuse syntax preparation, never an eval activation or its values. Callable
4
+ * source facts are live inputs and must still match before a result is reused. */
5
+ export function createCachedDynamicCompiler(compute, { maxEntries = 64, maxCharacters = 2 * 1024 * 1024 } = {}) {
6
+ const entries = new Map()
7
+ let characters = 0
8
+ return (source, options = {}) => {
9
+ const { resolveOriginalSource, ...syntax } = options
10
+ // Cell plans carry operation owners and generation-specific callbacks.
11
+ if (syntax.cell !== undefined || typeof source !== 'string') return compute(source, options)
12
+ const key = JSON.stringify([source, syntax])
13
+ if (maxEntries <= 0 || key.length > maxCharacters) return compute(source, options)
14
+ const resolved = new Map()
15
+ const resolve = text => {
16
+ if (!resolved.has(text)) resolved.set(text, resolveOriginalSource?.(text))
17
+ return resolved.get(text)
18
+ }
19
+ const cached = entries.get(key)
20
+ if (cached !== undefined) {
21
+ entries.delete(key)
22
+ characters -= cached.characters
23
+ if (cached.sources.every(([text, original]) => resolve(text) === original)) {
24
+ entries.set(key, cached)
25
+ characters += cached.characters
26
+ return copyCompilerData(cached.value)
27
+ }
28
+ }
29
+ const sources = new Map()
30
+ const value = compute(source, { ...syntax, resolveOriginalSource(text) {
31
+ const original = resolve(text)
32
+ sources.set(text, original)
33
+ return original
34
+ } })
35
+ const record = { value, sources: [...sources] }
36
+ record.characters = key.length + JSON.stringify(record).length
37
+ if (record.characters <= maxCharacters) {
38
+ while (entries.size >= maxEntries || characters + record.characters > maxCharacters) {
39
+ const oldest = entries.keys().next().value
40
+ characters -= entries.get(oldest).characters
41
+ entries.delete(oldest)
42
+ }
43
+ entries.set(key, record)
44
+ characters += record.characters
45
+ }
46
+ return copyCompilerData(value)
47
+ }
48
+ }
@@ -0,0 +1,35 @@
1
+ import { prepareProgram, prepareConsoleProgram, classifyDurability } from './cell-analysis.js'
2
+ import { PreflightError } from './cell-analysis-contract.js'
3
+ import { ModuleRewriteError } from './cell-rewriter.js'
4
+ import { compileDynamicEnvironmentSource } from './dynamic-environment-compiler.js'
5
+ import { compileStatefulModule, detectModuleSourceFormat, attachModuleNamespace,
6
+ linkCommonJsEvidenceSource } from './module-compilation.js'
7
+ import { copyCompilerData } from './compiler-data.js'
8
+ import { identifier, exportedSymbols, sourceDurability } from './binding-source-analysis.js'
9
+ import { hashText, deflateText, inflateText } from './compiler-text.js'
10
+ import { createCallableSourceCatalog } from './callable-source-encoding.js'
11
+ import { createCachedDynamicCompiler } from './compiler-dynamic-cache.js'
12
+
13
+ const operations = { prepareProgram, prepareConsoleProgram, classifyDurability,
14
+ compileDynamicEnvironmentSource: createCachedDynamicCompiler(compileDynamicEnvironmentSource),
15
+ compileStatefulModule, detectModuleSourceFormat, attachModuleNamespace, linkCommonJsEvidenceSource,
16
+ identifier, exportedSymbols, sourceDurability, hashText, deflateText, inflateText, createCallableSourceCatalog }
17
+
18
+ /** Synchronous source preparation has no module loader or runtime state. */
19
+ export function compile(operation, input, originalSource) {
20
+ try {
21
+ const args = copyCompilerData(input)
22
+ if (originalSource !== undefined) args[1].resolveOriginalSource = source => originalSource(source)
23
+ return { value: operations[operation](...args) }
24
+ } catch (error) {
25
+ const properties = {}
26
+ // Parser errors may own methods for cloning diagnostics. Only diagnostic
27
+ // data crosses the boundary; native error prototypes belong to the caller.
28
+ for (const [name, field] of Object.entries(Object.getOwnPropertyDescriptors(error))) {
29
+ if ('value' in field && typeof field.value !== 'function') properties[name] = field
30
+ }
31
+ return { error: { kind: error instanceof ModuleRewriteError ? 'ModuleRewriteError'
32
+ : error instanceof PreflightError ? 'PreflightError' : error.name,
33
+ message: error.message, properties } }
34
+ }
35
+ }
@@ -0,0 +1,17 @@
1
+ /** Babel's transform retains its scope and declaration machinery, while the
2
+ * complete compilation unit owns uniqueness across separately parsed regions. */
3
+ export function withGeneratedNameAllocator(scope, allocate, transform) {
4
+ const previous = Object.getOwnPropertyDescriptor(scope, 'generateUid')
5
+ Object.defineProperty(scope, 'generateUid', { configurable: true, writable: true, value() {
6
+ const name = allocate('native_temporary')
7
+ const program = this.getProgramParent()
8
+ program.references[name] = true
9
+ program.uids[name] = true
10
+ return name
11
+ } })
12
+ try { return transform() }
13
+ finally {
14
+ if (previous === undefined) delete scope.generateUid
15
+ else Object.defineProperty(scope, 'generateUid', previous)
16
+ }
17
+ }
@@ -0,0 +1,84 @@
1
+ import { stringifyCompilerData } from './compiler-data.js'
2
+ import { compilerStorageSource } from './compiler-storage-source.js'
3
+ import { compilerDescriptorSource } from './compiler-descriptors.js'
4
+
5
+ /** Compiler operations are captured before an owned realm executes user code. */
6
+ const defaultRealmFunction = Function
7
+ const realms = new WeakMap()
8
+ const uncurry = Function.prototype.bind.bind(Function.prototype.call)
9
+ const weakMapGet = uncurry(WeakMap.prototype.get)
10
+ const weakMapSet = uncurry(WeakMap.prototype.set)
11
+ const mapKeys = uncurry(Map.prototype.keys)
12
+ const mapIteratorNext = uncurry(Object.getPrototypeOf(new Map().keys()).next)
13
+
14
+ export function captureCompilerIntrinsics(realmFunction = defaultRealmFunction) {
15
+ let intrinsics = weakMapGet(realms, realmFunction)
16
+ if (intrinsics !== undefined) return intrinsics
17
+ intrinsics = realmFunction(`
18
+ const nativeObject=Object;
19
+ const nativeReflect=Reflect;
20
+ const properties=(${compilerDescriptorSource})(nativeObject,nativeReflect);
21
+ const object=properties.Object;
22
+ const symbol=Symbol;
23
+ return {Object:object,WeakMap,WeakSet,unscopables:symbol.unscopables,Reflect:{apply:nativeReflect.apply,
24
+ construct:nativeReflect.construct,ownKeys:nativeReflect.ownKeys,defineProperty:properties.reflectDefineProperty,
25
+ get decorate(){return nativeReflect.decorate}},TypeError,ReferenceError,SyntaxError,Error,Symbol,String,Number,
26
+ Promise:{resolve:Promise.resolve.bind(Promise),reject:Promise.reject.bind(Promise)},
27
+ SuppressedError:typeof SuppressedError==='function'?SuppressedError:undefined,
28
+ ...(${compilerStorageSource})(object,WeakMap,WeakSet,symbol,Promise,nativeReflect,Array,Function.prototype)};
29
+ `)()
30
+ weakMapSet(realms, realmFunction, intrinsics)
31
+ return intrinsics
32
+ }
33
+
34
+ export const moduleCompilerIntrinsics = captureCompilerIntrinsics()
35
+
36
+ /** Internal graph records use captured collection operations. Source-owned
37
+ * objects and callbacks keep their original realm and observable methods. */
38
+ export const moduleRuntimeIntrinsics = {
39
+ Object: moduleCompilerIntrinsics.Object,
40
+ Reflect: moduleCompilerIntrinsics.Reflect,
41
+ Error: moduleCompilerIntrinsics.Error,
42
+ Map, Set, WeakMap, Proxy,
43
+ mapGet: uncurry(Map.prototype.get),
44
+ mapHas: uncurry(Map.prototype.has),
45
+ mapSet: uncurry(Map.prototype.set),
46
+ mapDelete: uncurry(Map.prototype.delete),
47
+ mapClear: uncurry(Map.prototype.clear),
48
+ mapSize: uncurry(Object.getOwnPropertyDescriptor(Map.prototype, 'size').get),
49
+ mapFirstKey: value => mapIteratorNext(mapKeys(value)).value,
50
+ mapForEach: uncurry(Map.prototype.forEach),
51
+ setHas: uncurry(Set.prototype.has),
52
+ setAdd: uncurry(Set.prototype.add),
53
+ setDelete: uncurry(Set.prototype.delete),
54
+ setClear: uncurry(Set.prototype.clear),
55
+ setForEach: uncurry(Set.prototype.forEach),
56
+ weakMapHas: uncurry(WeakMap.prototype.has),
57
+ weakMapGet, weakMapSet,
58
+ isArray: Array.isArray,
59
+ includes: uncurry(Array.prototype.includes),
60
+ join: uncurry(Array.prototype.join),
61
+ sliceString: uncurry(String.prototype.slice),
62
+ replaceAllString: uncurry(String.prototype.replaceAll),
63
+ includesString: uncurry(String.prototype.includes),
64
+ floor: Math.floor,
65
+ min: Math.min,
66
+ max: Math.max,
67
+ // Only private native Promises enter this boundary. Source promises and the
68
+ // public result keep their prototypes; private reactions cannot select a
69
+ // source constructor/species or dynamically dispatch through then/catch.
70
+ observeOwnedPromise: moduleCompilerIntrinsics.observeOwnedPromise,
71
+ appendArray(target, value) {
72
+ moduleCompilerIntrinsics.Object.defineProperty(target, target.length,
73
+ { value, writable: true, enumerable: true, configurable: true })
74
+ return target
75
+ },
76
+ copyArray(source, start = 0, end = source.length, target = []) {
77
+ for (let index = start; index < end; index++) this.appendArray(target, source[index])
78
+ return target
79
+ },
80
+ sort: uncurry(Array.prototype.sort),
81
+ compare: uncurry(String.prototype.localeCompare),
82
+ startsWith: uncurry(String.prototype.startsWith),
83
+ stringify: stringifyCompilerData,
84
+ }
@@ -0,0 +1,34 @@
1
+ import { fileURLToPath } from 'node:url'
2
+
3
+ const encodeReference = encodeURIComponent
4
+
5
+ // These ambient inputs must remain outside source-owned CommonJS bindings.
6
+ export const commonJsCompilerGlobals = new Set(['process'])
7
+
8
+ /** Node's synchronous ESM linker validates protocols before public hooks.
9
+ * Private references therefore use a native protocol and fail if unclaimed. */
10
+ export function compilerModuleReference(kind, identity) {
11
+ return `data:text/javascript,throw%20new%20Error(%22Unresolved%20PTC%20module%20link%22)#ptc-${kind}/${encodeReference(identity)}`
12
+ }
13
+
14
+ const STATIC_LINK_KIND = 'static'
15
+ const ATTRIBUTED_LINK_KIND = 'static-attributed'
16
+
17
+ /** Reference one static link. Node 22.19 binds every edge that shares a request
18
+ * URL to the module of the last resolution, so attribute-distinct imports of
19
+ * one source need distinct native requests. Attribute-bearing links use their
20
+ * own reference kind and a JSON identity, which no source specifier can equal;
21
+ * attribute-free links keep the reference they had before attributes were
22
+ * distinguished. */
23
+ export function staticModuleLinkReference(source, attributes) {
24
+ const entries = Object.entries(attributes ?? {})
25
+ if (entries.length === 0) return compilerModuleReference(STATIC_LINK_KIND, source)
26
+ entries.sort((left, right) => left[0] < right[0] ? -1 : left[0] > right[0] ? 1 : 0)
27
+ return compilerModuleReference(ATTRIBUTED_LINK_KIND, JSON.stringify([source, entries]))
28
+ }
29
+
30
+ /** Compiler helpers resolve from their own URL, independently of source-owned
31
+ * wrapper bindings and the ESM translator's restricted CommonJS require. */
32
+ export function commonJsCompilerImport(url) {
33
+ return `process.getBuiltinModule('module').createRequire(${JSON.stringify(url.href)})(${JSON.stringify(fileURLToPath(url))})`
34
+ }
@@ -0,0 +1,61 @@
1
+ import { types as t } from '@babel/core'
2
+
3
+ /** Binding descriptors belong to a compilation; each AST owns its new operations. */
4
+ export function createCompilerOperationPlanner({ bindings = [], internalBindings = [], environmentName, rootRuntime } = {}) {
5
+ const compilerBindings = new Set(internalBindings)
6
+ const sourceInitializers = new Set(bindings.filter(binding => binding.role === 'source-initializer')
7
+ .map(binding => binding.physicalName))
8
+ const transports = new Map(bindings.filter(binding => binding.property !== undefined || binding.accessor === true)
9
+ .map(binding => [binding.physicalName, binding]))
10
+ const roots = new Set([environmentName, rootRuntime].filter(name => name !== undefined))
11
+ const ownedBindings = new Set([...compilerBindings, ...transports.keys(), ...roots])
12
+ const declaration = path => (path.isVariableDeclarator() || path.isFunctionDeclaration())
13
+ && (compilerBindings.has(path.node.id?.name) || roots.has(path.node.id?.name)) && !sourceInitializers.has(path.node.id.name)
14
+ const transport = node => t.isIdentifier(node) ? transports.get(node.name)
15
+ : t.isCallExpression(node) && t.isIdentifier(node.callee) && transports.get(node.callee.name)?.accessor === true
16
+ ? transports.get(node.callee.name) : undefined
17
+ const privateReceiver = node => t.isIdentifier(node) && roots.has(node.name)
18
+ const compilerCall = node => {
19
+ const callee = node.callee
20
+ if (t.isIdentifier(callee)) return compilerBindings.has(callee.name) && !sourceInitializers.has(callee.name)
21
+ || transports.get(callee.name)?.accessor === true
22
+ if (!t.isMemberExpression(callee) || callee.computed) return false
23
+ const owner = transport(callee.object)
24
+ return privateReceiver(callee.object) || owner !== undefined && owner.property !== undefined
25
+ && callee.property.name !== owner.property
26
+ }
27
+ return tree => {
28
+ const addedBindings = new Set()
29
+ const internal = { has: name => ownedBindings.has(name) || addedBindings.has(name), add: name => addedBindings.add(name) }
30
+ const sourceNodes = new WeakSet()
31
+ const operations = new WeakSet()
32
+ const values = new WeakSet()
33
+ const callees = new WeakSet()
34
+ const operation = node => {
35
+ operations.add(node)
36
+ if (node.callee !== undefined) {
37
+ callees.add(node.callee)
38
+ t.traverseFast(node.callee, child => operations.add(child))
39
+ }
40
+ return node
41
+ }
42
+ t.traverseFast(tree, node => sourceNodes.add(node))
43
+ t.traverseFast(tree, node => {
44
+ if ((t.isCallExpression(node) || t.isNewExpression(node)) && compilerCall(node)) operation(node)
45
+ })
46
+ return {
47
+ internal,
48
+ sourceInitializers,
49
+ declaration,
50
+ owns: node => operations.has(node),
51
+ callee: node => callees.has(node),
52
+ isValue: node => values.has(node),
53
+ value(node) { values.add(node); return node },
54
+ operation,
55
+ generated(output) {
56
+ // Original argument nodes remain source-owned inside new helper shells.
57
+ t.traverseFast(output, node => { if (!sourceNodes.has(node)) operations.add(node) })
58
+ },
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,84 @@
1
+ /** Compiler dependencies see only containers and callable prototypes owned by
2
+ * their private realm. The host bridge supplies captured data operations. */
3
+ export function createPlatform(bridge) {
4
+ const copyBytes = bytes => {
5
+ const result = new Uint8Array(bytes.length)
6
+ for (let index = 0; index < bytes.length; index++) result[index] = bytes[index]
7
+ return result
8
+ }
9
+ const copyRecord = record => {
10
+ const result = {}
11
+ for (const key of Object.keys(record)) result[key] = record[key]
12
+ return result
13
+ }
14
+ // This is the compiler's text codec subset, not a general Node Buffer shim.
15
+ class CompilerBuffer extends Uint8Array {
16
+ static from(value, encoding = 'utf8') {
17
+ if (typeof value !== 'string') {
18
+ const result = new CompilerBuffer(value.length)
19
+ for (let index = 0; index < value.length; index++) result[index] = value[index]
20
+ return result
21
+ }
22
+ if (!['utf8', 'utf16le', 'base64'].includes(encoding)) throw new TypeError(`unsupported compiler encoding: ${encoding}`)
23
+ const { buffer, length } = bridge.encode(value, encoding)
24
+ const result = new CompilerBuffer(length)
25
+ for (let index = 0; index < length; index++) result[index] = buffer[index]
26
+ return result
27
+ }
28
+ toString(encoding = 'utf8') {
29
+ if (!['utf8', 'utf16le', 'base64'].includes(encoding)) throw new TypeError(`unsupported compiler encoding: ${encoding}`)
30
+ return bridge.decode(this, encoding)
31
+ }
32
+ }
33
+ class CompilerURL {
34
+ constructor(input, base) { this.href = bridge.url(String(input), base === undefined ? undefined : String(base)) }
35
+ toString() { return this.href }
36
+ }
37
+ class TextEncoder {
38
+ #encoder = bridge.textEncoder()
39
+ encode(source = '') { return copyBytes(this.#encoder.encode(source)) }
40
+ encodeInto(source, output) { return copyRecord(this.#encoder.encodeInto(source, output)) }
41
+ }
42
+ class TextDecoder {
43
+ #decode
44
+ constructor(label, options) { this.#decode = bridge.textDecoder(label, options) }
45
+ decode(input, options) { return this.#decode(input, options) }
46
+ }
47
+ class SourceMap {
48
+ #map
49
+ constructor(payload) { this.#map = bridge.sourceMap(payload) }
50
+ findEntry(line, column) { return copyRecord(this.#map.findEntry(line, column)) }
51
+ findOrigin(line, column) { return copyRecord(this.#map.findOrigin(line, column)) }
52
+ }
53
+ const unavailable = () => { throw new Error('compiler dependencies cannot access the filesystem or load configuration') }
54
+ const modules = {
55
+ buffer: { Buffer: CompilerBuffer },
56
+ crypto: { createHash(algorithm) {
57
+ const hash = bridge.hash(algorithm)
58
+ return { update(source, encoding) { hash.update(source, encoding); return this },
59
+ digest(encoding) { return hash.digest(encoding) } }
60
+ } },
61
+ module: { SourceMap, stripTypeScriptTypes: (source, options) => bridge.stripTypeScriptTypes(source, options) },
62
+ url: { URL: CompilerURL, fileURLToPath: url => bridge.fileURLToPath(String(url)) },
63
+ util: { TextEncoder, TextDecoder, deprecate: callback => callback,
64
+ types: { isMap: value => bridge.typeChecks.isMap(value), isSet: value => bridge.typeChecks.isSet(value),
65
+ isUint32Array: value => bridge.typeChecks.isUint32Array(value) } },
66
+ tty: { isatty: () => false },
67
+ fs: { existsSync: unavailable, statSync: unavailable, readFileSync: unavailable,
68
+ readFile: unavailable, stat: unavailable },
69
+ assert(value, message) { if (!value) throw new Error(message) },
70
+ }
71
+ return {
72
+ require(name) {
73
+ const key = name.startsWith('node:') ? name.slice(5) : name
74
+ if (key.startsWith('compiler-asset:')) return bridge.loadAsset(key)
75
+ if (key === 'typescript' || key === 'amaro') return bridge.loadDependency(key)
76
+ if (!Object.hasOwn(modules, key)) throw new Error(`compiler cannot load dependency: ${name}`)
77
+ return modules[key]
78
+ },
79
+ process: { env: {}, version: `v${bridge.nodeVersion}`, versions: { node: bridge.nodeVersion },
80
+ platform: bridge.platform, features: { typescript: bridge.typescript }, cwd: () => bridge.cwd,
81
+ argv: [], stdout: { fd: 1, isTTY: false }, stderr: { fd: 2, isTTY: false } },
82
+ Buffer: CompilerBuffer, URL: CompilerURL, TextEncoder, TextDecoder,
83
+ }
84
+ }