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.
- package/README.en.md +65 -78
- package/README.md +65 -78
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-repair-zh.png +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +30596 -742
- package/compiler-amaro.cjs +5 -0
- package/compiler-amaro.cjs.map +6 -0
- package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
- package/compiler-assets.json +3 -0
- package/compiler-core.cjs +554 -0
- package/compiler-core.cjs.map +6 -0
- package/compiler-platform.cjs +2 -0
- package/compiler-platform.cjs.map +6 -0
- package/compiler-typescript.cjs +388 -0
- package/compiler-typescript.cjs.map +6 -0
- package/docs/README.md +6 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
- package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
- package/docs/adr/0023-global-user-bindings.md +104 -0
- package/docs/adr/0024-repl-console-observation.md +33 -0
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
- package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
- package/docs/architecture.md +73 -21
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +95 -19
- package/docs/durability-design.md +25 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +72 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +755 -0
- package/docs/user-bindings.en.md +64 -0
- package/docs/user-bindings.md +64 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification.md +57 -0
- package/index.js +369 -92
- package/internal/ast-traversal.js +5 -2
- package/internal/binding-descriptors.js +1 -0
- package/internal/binding-pattern-traversal.js +25 -0
- package/internal/binding-pattern.js +26 -29
- package/internal/binding-source-analysis.js +391 -0
- package/internal/binding-update-policy.js +66 -0
- package/internal/bounded-worker-round.js +56 -0
- package/internal/callable-definition-environment.js +42 -0
- package/internal/callable-source-catalog.js +129 -0
- package/internal/callable-source-encoding.js +47 -0
- package/internal/callable-source-facts.js +459 -0
- package/internal/callable-source-format.js +2 -0
- package/internal/callable-source-lowering.js +123 -0
- package/internal/cell-analysis-contract.js +25 -0
- package/internal/cell-analysis.js +240 -290
- package/internal/cell-completion.js +15 -0
- package/internal/cell-error.js +7 -0
- package/internal/cell-parser.js +66 -0
- package/internal/cell-rewriter.js +3 -677
- package/internal/commonjs-export-evidence.js +63 -0
- package/internal/commonjs-source-evidence.js +72 -0
- package/internal/compiler-amaro.cjs +2 -0
- package/internal/compiler-compression.js +12 -0
- package/internal/compiler-data.js +58 -0
- package/internal/compiler-descriptors.js +54 -0
- package/internal/compiler-dynamic-cache.js +48 -0
- package/internal/compiler-entry.js +35 -0
- package/internal/compiler-generated-names.js +17 -0
- package/internal/compiler-intrinsics.js +84 -0
- package/internal/compiler-module-links.js +34 -0
- package/internal/compiler-operations.js +61 -0
- package/internal/compiler-platform-factory.js +84 -0
- package/internal/compiler-platform.js +136 -0
- package/internal/compiler-record-roles.js +53 -0
- package/internal/compiler-region-output.js +259 -0
- package/internal/compiler-resource-lowering.js +103 -0
- package/internal/compiler-scope-facts.js +115 -0
- package/internal/compiler-service.js +109 -0
- package/internal/compiler-source-cache.js +32 -0
- package/internal/compiler-source-pieces.js +93 -0
- package/internal/compiler-source-regions.js +132 -0
- package/internal/compiler-storage-source.js +54 -0
- package/internal/compiler-text.js +15 -0
- package/internal/compiler-typescript.cjs +2 -0
- package/internal/config-spec.js +83 -27
- package/internal/cordis-tools-owner.js +130 -21
- package/internal/diagnostic.js +27 -1
- package/internal/direct-surface-owner.js +76 -23
- package/internal/dynamic-binding-evidence.js +16 -0
- package/internal/dynamic-environment-compiler.js +779 -0
- package/internal/dynamic-environment-integration.js +87 -0
- package/internal/dynamic-environment-runtime.js +362 -0
- package/internal/dynamic-native-calls.js +150 -0
- package/internal/dynamic-native-runtime.js +248 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +27 -2
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +118 -18
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +548 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +904 -120
- package/internal/language-semantics.js +14 -0
- package/internal/legacy-binding-catalog.js +48 -0
- package/internal/legacy-cell-analysis.js +600 -0
- package/internal/legacy-cell-parser.js +50 -0
- package/internal/legacy-cell-rewriter.js +631 -0
- package/internal/legacy-repl-convenience.js +291 -0
- package/internal/managed-module-operations.js +170 -0
- package/internal/module-compilation.js +321 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +12 -0
- package/internal/native-await-declarations.js +68 -0
- package/internal/native-root-compilation.js +54 -0
- package/internal/native-root-dynamic.js +67 -0
- package/internal/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -289
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +6 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +114 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -52
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +401 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +184 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +256 -95
- package/internal/session-state.js +247 -71
- package/internal/source-position-map.js +211 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +598 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +29 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +184 -0
- package/internal/user-binding-console.js +148 -0
- package/internal/user-binding-draft-projection.js +335 -0
- package/internal/user-binding-model-context.js +31 -0
- package/internal/user-binding-runner.js +56 -0
- package/internal/user-bindings-owner.js +1065 -0
- package/internal/user-bindings-store.js +293 -0
- package/internal/user-bindings.js +353 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +29 -20
- package/internal/worker-client.js +57 -67
- package/internal/worker-environment.js +45 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +75 -7
- package/src/client-activity.js +88 -53
- package/src/client-authoring-view.js +580 -0
- package/src/client-binding-review.js +230 -0
- package/src/client-bindings-data.js +29 -0
- package/src/client-catalog.js +127 -0
- package/src/client-code-editor.js +84 -0
- package/src/client-console.js +112 -0
- package/src/client-copy.js +370 -0
- package/src/client-feature-gates.js +62 -0
- package/src/client-host-compat.js +150 -0
- package/src/client-indicator-view.js +267 -0
- package/src/client-repl-view.js +292 -0
- package/src/client-rpc.js +20 -0
- package/src/client-settings-view.js +221 -0
- package/src/client-styles.js +106 -0
- package/src/client-tool-view.js +108 -0
- package/src/client-transport.js +159 -0
- package/src/client-workbench.js +521 -0
- 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,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
|
+
}
|