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
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
// Runtime state transitions shared by the session coordinator and cell executor.
|
|
2
2
|
|
|
3
|
+
import { userBindingCatalogEntries } from './user-bindings.js'
|
|
4
|
+
import { LEGACY_USER_BINDINGS_SHADOW_POLICY } from './session-journal-schema.js'
|
|
5
|
+
import { advanceLegacyBindings } from './legacy-binding-catalog.js'
|
|
6
|
+
import { dynamicBindingOrigin } from './dynamic-binding-evidence.js'
|
|
7
|
+
import { LEGACY_LANGUAGE_SEMANTICS, normalizeLanguageSemantics } from './language-semantics.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reuse counts belong to a logical binding identity, not to one declaration
|
|
11
|
+
* occurrence. Every catalog transition carries the previous count forward by
|
|
12
|
+
* name, so a redeclaration can change the definition without resetting how many
|
|
13
|
+
* later cells reused the binding.
|
|
14
|
+
*/
|
|
15
|
+
function carryReuseCounts(entries, previousEntries) {
|
|
16
|
+
for (const [name, entry] of entries) {
|
|
17
|
+
const previous = previousEntries.get(name)
|
|
18
|
+
if (previous?.reuseCount === undefined || entry.reuseCount === previous.reuseCount) continue
|
|
19
|
+
entries.set(name, { ...entry, reuseCount: previous.reuseCount })
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** One settled cell contributes at most one reuse event per identity its
|
|
24
|
+
* rewritten source statically references; the count is a source fact, not a
|
|
25
|
+
* runtime trace of which references executed. */
|
|
26
|
+
function applyReuseEvents(entries, previousEntries, reusedNames) {
|
|
27
|
+
for (const name of new Set(reusedNames ?? [])) {
|
|
28
|
+
const entry = entries.get(name)
|
|
29
|
+
if (entry === undefined || previousEntries.get(name) === undefined) continue
|
|
30
|
+
entries.set(name, { ...entry, reuseCount: (entry.reuseCount ?? 0) + 1 })
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
3
34
|
export function durabilityState(overrides = {}) {
|
|
4
35
|
return Object.freeze({
|
|
5
36
|
status: 'durable',
|
|
@@ -18,102 +49,247 @@ export function transitionDurability(state, transition) {
|
|
|
18
49
|
}
|
|
19
50
|
|
|
20
51
|
export class BindingCatalog {
|
|
21
|
-
#
|
|
22
|
-
#kinds
|
|
23
|
-
#definitions
|
|
24
|
-
#imports
|
|
52
|
+
#entries
|
|
25
53
|
#namespaces
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
kinds = new Map(),
|
|
33
|
-
definitions = new Map(),
|
|
34
|
-
writable = new Set(),
|
|
35
|
-
) {
|
|
36
|
-
this.#known = new Set(known)
|
|
37
|
-
this.#kinds = new Map([...this.#known].map(name => [name, kinds.get(name) ?? 'variable']))
|
|
38
|
-
this.#definitions = new Map([...this.#known]
|
|
39
|
-
.filter(name => definitions.has(name))
|
|
40
|
-
.map(name => [name, definitions.get(name)]))
|
|
41
|
-
this.#imports = new Map(imports)
|
|
54
|
+
#userBindingAncestry
|
|
55
|
+
#rootCandidates
|
|
56
|
+
#dynamicOrigins
|
|
57
|
+
|
|
58
|
+
constructor({ entries = new Map(), namespaces = new Set(), userBindingAncestry = new Set(), rootCandidates = new Map(), dynamicOrigins = new Map() } = {}) {
|
|
59
|
+
this.#entries = new Map([...entries].map(([name, entry]) => [name, Object.freeze({ ...entry })]))
|
|
42
60
|
this.#namespaces = new Set(namespaces)
|
|
43
|
-
|
|
61
|
+
// A closure can perform its first implicit assignment in a later cell.
|
|
62
|
+
// Its source plan is ancestry, not an initialized binding or provider shadow.
|
|
63
|
+
this.#rootCandidates = new Map(rootCandidates)
|
|
64
|
+
this.#dynamicOrigins = new Map(dynamicOrigins)
|
|
65
|
+
// Escaped provider setters may create local values after their entries are
|
|
66
|
+
// removed. Eligibility follows the catalog ancestry, not the visible inventory.
|
|
67
|
+
this.#userBindingAncestry = new Set([
|
|
68
|
+
...userBindingAncestry,
|
|
69
|
+
...[...entries].filter(([, entry]) => entry.origin?.kind === 'user-global').map(([name]) => name),
|
|
70
|
+
])
|
|
44
71
|
Object.freeze(this)
|
|
45
72
|
}
|
|
46
73
|
|
|
47
74
|
inputs() {
|
|
48
75
|
return {
|
|
49
|
-
knownBindings: new Set(this.#
|
|
50
|
-
|
|
76
|
+
knownBindings: new Set([...this.#entries]
|
|
77
|
+
.filter(([, entry]) => entry.unavailable !== true)
|
|
78
|
+
.map(([name]) => name)),
|
|
79
|
+
importBindings: new Map([...this.#entries]
|
|
80
|
+
.filter(([, entry]) => entry.import !== undefined)
|
|
81
|
+
.map(([name, entry]) => [name, entry.import])),
|
|
51
82
|
importNamespaces: new Set(this.#namespaces),
|
|
52
|
-
writableBindings: new Set(this.#
|
|
83
|
+
writableBindings: new Set([...this.#entries]
|
|
84
|
+
.filter(([, entry]) => entry.writable === true)
|
|
85
|
+
.map(([name]) => name)),
|
|
86
|
+
nativeBindings: new Set([...this.#entries].filter(([, entry]) => entry.native === true).map(([name]) => name)),
|
|
87
|
+
nativeLexicalBindings: new Set([...this.#entries].filter(([, entry]) => entry.nativeLexical === true).map(([name]) => name)),
|
|
88
|
+
rootCandidates: new Map([...this.#rootCandidates].map(([target, declaration]) => [target, declaration.name])),
|
|
89
|
+
dynamicOrigins: [...this.#dynamicOrigins.keys()],
|
|
90
|
+
establishedRoots: new Map([...this.#entries].filter(([, entry]) => entry.rootSource !== undefined)
|
|
91
|
+
.map(([name, entry]) => [name, entry.rootSource])),
|
|
53
92
|
}
|
|
54
93
|
}
|
|
55
94
|
|
|
56
|
-
advance(prepared, source = undefined, committedRedeclarations = undefined) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: new Set([...redeclared, ...commitGated])
|
|
67
|
-
const uncommitted = new Set()
|
|
68
|
-
const extractDefinition = sourceDefinitionExtractor(source)
|
|
69
|
-
for (const declaration of prepared.declarations ?? []) {
|
|
70
|
-
if (typeof declaration?.name !== 'string') continue
|
|
71
|
-
const dependency = typeof declaration.commitDependency === 'string'
|
|
72
|
-
&& commitGated.has(declaration.commitDependency)
|
|
73
|
-
? declaration.commitDependency
|
|
74
|
-
: commitGated.has(declaration.name) ? declaration.name : undefined
|
|
75
|
-
if (dependency !== undefined && !committed.has(dependency)) {
|
|
76
|
-
uncommitted.add(declaration.name)
|
|
77
|
-
continue
|
|
95
|
+
advance(prepared, source = undefined, committedRedeclarations = undefined, rootBindingFacts = undefined) {
|
|
96
|
+
const semantics = normalizeLanguageSemantics(prepared.languageSemantics ?? LEGACY_LANGUAGE_SEMANTICS)
|
|
97
|
+
if (semantics === LEGACY_LANGUAGE_SEMANTICS) {
|
|
98
|
+
const legacy = advanceLegacyBindings(this.#entries, prepared, sourceDefinitionExtractor(source), committedRedeclarations)
|
|
99
|
+
const nativePublications = new Set(prepared.moduleLoads.flatMap(load => (load.nativePublications ?? []).map(binding => binding.name)))
|
|
100
|
+
for (const [name, entry] of legacy.entries) {
|
|
101
|
+
if (entry.rootSource === undefined && entry.origin === undefined && entry.userBindingState === undefined) {
|
|
102
|
+
legacy.entries.set(name, { ...entry, native: true,
|
|
103
|
+
nativeLexical: this.#entries.get(name)?.nativeLexical === true || prepared.nativeLexicals?.has(name) === true })
|
|
104
|
+
}
|
|
78
105
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else writable.delete(declaration.name)
|
|
106
|
+
for (const fact of rootBindingFacts ?? []) {
|
|
107
|
+
const previous = legacy.entries.get(fact.name)
|
|
108
|
+
if (previous !== undefined) legacy.entries.set(fact.name, { ...previous,
|
|
109
|
+
native: this.#entries.get(fact.name)?.native || nativePublications.has(fact.name) && fact.source !== 'absent',
|
|
110
|
+
import: this.#entries.get(fact.name)?.import,
|
|
111
|
+
})
|
|
86
112
|
}
|
|
113
|
+
applyRootBindingFacts(legacy.entries, rootBindingFacts, this.#rootCandidates, this.#dynamicOrigins,
|
|
114
|
+
prepared.imports, this.#entries)
|
|
115
|
+
// The frozen legacy-v1 preparation reports no reference facts, so a
|
|
116
|
+
// legacy cell contributes no reuse event; accumulated counts still carry
|
|
117
|
+
// across the transition.
|
|
118
|
+
carryReuseCounts(legacy.entries, this.#entries)
|
|
119
|
+
return new BindingCatalog({
|
|
120
|
+
...legacy,
|
|
121
|
+
userBindingAncestry: this.#userBindingAncestry,
|
|
122
|
+
rootCandidates: this.#rootCandidates,
|
|
123
|
+
dynamicOrigins: this.#dynamicOrigins,
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
const entries = new Map(this.#entries)
|
|
127
|
+
const committed = committedRedeclarations ?? prepared.commitTargets
|
|
128
|
+
const extractDefinition = sourceDefinitionExtractor(source)
|
|
129
|
+
const rootCandidates = new Map(this.#rootCandidates)
|
|
130
|
+
const dynamicOrigins = new Map(this.#dynamicOrigins)
|
|
131
|
+
for (const origin of prepared.dynamicOrigins ?? []) {
|
|
132
|
+
dynamicOrigins.set(origin.target, extractDefinition(origin.definitionSpan))
|
|
133
|
+
}
|
|
134
|
+
for (const declaration of prepared.implicitDeclarations ?? []) {
|
|
135
|
+
rootCandidates.set(declaration.target, { name: declaration.name, kind: 'variable', writable: true,
|
|
136
|
+
definition: extractDefinition(declaration.definitionSpan) })
|
|
87
137
|
}
|
|
88
|
-
|
|
89
|
-
|
|
138
|
+
const commitOrder = new Map([...committed].map((target, index) => [target, index]))
|
|
139
|
+
const declarations = prepared.declarations.filter(declaration => committed.has(declaration.commitDependency))
|
|
140
|
+
.sort((left, right) => commitOrder.get(left.commitDependency) - commitOrder.get(right.commitDependency))
|
|
141
|
+
for (const declaration of declarations) {
|
|
142
|
+
const previous = entries.get(declaration.name)
|
|
143
|
+
entries.set(declaration.name, { kind: declaration.kind,
|
|
144
|
+
writable: declaration.writable,
|
|
145
|
+
...(previous?.nativeLexical === true ? { nativeLexical: true } : {}),
|
|
146
|
+
definition: extractDefinition(declaration.definitionSpan) ?? previous?.definition,
|
|
147
|
+
import: declaration.kind === 'import' ? prepared.imports.get(declaration.name) : undefined,
|
|
148
|
+
})
|
|
90
149
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
150
|
+
// Value provenance follows actual commits, including repeated loop targets.
|
|
151
|
+
// The inventory separately presents accepted declarations in source order.
|
|
152
|
+
for (const { name } of declarations.sort((left, right) => left.span.line - right.span.line
|
|
153
|
+
|| left.span.column - right.span.column)) {
|
|
154
|
+
const entry = entries.get(name)
|
|
155
|
+
entries.delete(name)
|
|
156
|
+
entries.set(name, entry)
|
|
94
157
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
158
|
+
applyRootBindingFacts(entries, rootBindingFacts, rootCandidates, dynamicOrigins, prepared.imports, this.#entries)
|
|
159
|
+
carryReuseCounts(entries, this.#entries)
|
|
160
|
+
applyReuseEvents(entries, this.#entries, prepared.reusedNames)
|
|
161
|
+
return new BindingCatalog({ entries, namespaces: this.#namespaces, userBindingAncestry: this.#userBindingAncestry, rootCandidates, dynamicOrigins })
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
userBindings(snapshot, activeEntryIds = undefined, shadowPolicy = LEGACY_USER_BINDINGS_SHADOW_POLICY) {
|
|
165
|
+
const candidates = (snapshot === undefined ? [] : userBindingCatalogEntries(snapshot))
|
|
166
|
+
.filter(entry => activeEntryIds === undefined || activeEntryIds.has(entry.entryId))
|
|
167
|
+
const shadowedNames = new Set([...this.#entries]
|
|
168
|
+
.filter(([, entry]) => entry.origin?.kind !== 'user-global')
|
|
169
|
+
.map(([name]) => name))
|
|
170
|
+
const shadowedEntryIds = new Set(candidates
|
|
171
|
+
.filter(entry => shadowedNames.has(entry.name))
|
|
172
|
+
.map(entry => entry.entryId))
|
|
173
|
+
const desired = new Map(candidates.filter(entry => shadowPolicy === LEGACY_USER_BINDINGS_SHADOW_POLICY
|
|
174
|
+
? !shadowedEntryIds.has(entry.entryId) : !shadowedNames.has(entry.name))
|
|
175
|
+
.map(entry => [entry.name, entry]))
|
|
176
|
+
const entries = new Map(this.#entries)
|
|
177
|
+
for (const [name, { origin }] of entries) {
|
|
178
|
+
if (origin?.kind !== 'user-global') continue
|
|
179
|
+
const next = desired.get(name)
|
|
180
|
+
if (next !== undefined && next.entryId === origin.entryId
|
|
181
|
+
&& next.fingerprint === origin.fingerprint) continue
|
|
182
|
+
entries.delete(name)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
for (const entry of desired.values()) {
|
|
186
|
+
entries.delete(entry.name)
|
|
187
|
+
entries.set(entry.name, {
|
|
188
|
+
kind: entry.kind,
|
|
189
|
+
definition: entry.definition,
|
|
190
|
+
writable: true,
|
|
191
|
+
origin: Object.freeze({ kind: 'user-global', entryId: entry.entryId, fingerprint: entry.fingerprint }),
|
|
192
|
+
})
|
|
102
193
|
}
|
|
103
|
-
|
|
194
|
+
carryReuseCounts(entries, this.#entries)
|
|
195
|
+
return Object.freeze({
|
|
196
|
+
catalog: new BindingCatalog({ entries, namespaces: this.#namespaces, userBindingAncestry: this.#userBindingAncestry, rootCandidates: this.#rootCandidates, dynamicOrigins: this.#dynamicOrigins }),
|
|
197
|
+
shadowedNames,
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
userBindingNameSet(snapshot, includeProviderAncestry = false) {
|
|
202
|
+
return new Set([
|
|
203
|
+
...(includeProviderAncestry ? this.#userBindingAncestry : []),
|
|
204
|
+
...[...this.#entries].filter(([, entry]) => (entry.userBindingState !== undefined
|
|
205
|
+
&& (includeProviderAncestry || entry.userBindingState !== 'provider'))
|
|
206
|
+
|| (includeProviderAncestry && entry.origin?.kind === 'user-global')).map(([name]) => name),
|
|
207
|
+
...(snapshot === undefined ? [] : userBindingCatalogEntries(snapshot).map(entry => entry.name)),
|
|
208
|
+
])
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Actual worker sources override static declaration plans at this one boundary. */
|
|
212
|
+
reconcileUserBindingNames(snapshot, facts, source = undefined) {
|
|
213
|
+
const entries = new Map(this.#entries)
|
|
214
|
+
const candidates = new Map((snapshot === undefined ? [] : userBindingCatalogEntries(snapshot)).map(entry => [entry.name, entry]))
|
|
215
|
+
for (const [name, entry] of entries) {
|
|
216
|
+
if (entry.origin?.kind === 'user-global') entries.delete(name)
|
|
217
|
+
}
|
|
218
|
+
for (const fact of facts) {
|
|
219
|
+
const previous = this.#entries.get(fact.name)
|
|
220
|
+
if (fact.state === 'provider') {
|
|
221
|
+
const candidate = candidates.get(fact.name)
|
|
222
|
+
entries.set(fact.name, {
|
|
223
|
+
kind: candidate.kind, definition: candidate.definition, writable: true, userBindingState: 'provider',
|
|
224
|
+
origin: Object.freeze({ kind: 'user-global', entryId: candidate.entryId, fingerprint: candidate.fingerprint }),
|
|
225
|
+
})
|
|
226
|
+
} else {
|
|
227
|
+
entries.set(fact.name, {
|
|
228
|
+
kind: previous?.kind ?? 'variable',
|
|
229
|
+
// Preserve compiler-owned import accessors while replacing only the
|
|
230
|
+
// per-name user-binding proof. Imports are the canonical storage for
|
|
231
|
+
// aliases and must remain available to the next preparation pass.
|
|
232
|
+
import: previous?.import,
|
|
233
|
+
rootSource: previous?.rootSource,
|
|
234
|
+
native: previous?.native,
|
|
235
|
+
nativeLexical: previous?.nativeLexical,
|
|
236
|
+
definition: previous?.origin === undefined && previous?.definition !== undefined
|
|
237
|
+
? previous.definition
|
|
238
|
+
: fact.state === 'local' && typeof source === 'string' && source.length > 0
|
|
239
|
+
? Object.freeze({ source: source.slice(0, MAX_DEFINITION_SOURCE_LENGTH), line: 1, column: 1 }) : undefined,
|
|
240
|
+
writable: previous?.writable ?? true,
|
|
241
|
+
userBindingState: fact.state,
|
|
242
|
+
unavailable: fact.state !== 'local',
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
carryReuseCounts(entries, this.#entries)
|
|
247
|
+
return new BindingCatalog({ entries, namespaces: this.#namespaces, userBindingAncestry: this.#userBindingAncestry, rootCandidates: this.#rootCandidates, dynamicOrigins: this.#dynamicOrigins })
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
withoutUserBindings() {
|
|
251
|
+
const entries = new Map([...this.#entries].filter(([, entry]) => entry.origin?.kind !== 'user-global'))
|
|
252
|
+
return new BindingCatalog({ entries, namespaces: this.#namespaces, userBindingAncestry: this.#userBindingAncestry, rootCandidates: this.#rootCandidates, dynamicOrigins: this.#dynamicOrigins })
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
shadowUserBindings(names) {
|
|
256
|
+
const entries = new Map(this.#entries)
|
|
257
|
+
for (const name of names) {
|
|
258
|
+
const entry = entries.get(name)
|
|
259
|
+
if (entry?.origin?.kind !== 'user-global') continue
|
|
260
|
+
entries.set(name, { ...entry, origin: undefined, definition: undefined })
|
|
261
|
+
}
|
|
262
|
+
return new BindingCatalog({ entries, namespaces: this.#namespaces, userBindingAncestry: this.#userBindingAncestry, rootCandidates: this.#rootCandidates, dynamicOrigins: this.#dynamicOrigins })
|
|
104
263
|
}
|
|
105
264
|
|
|
106
265
|
snapshot() {
|
|
107
|
-
return [...this.#
|
|
108
|
-
.filter(name => !this.#namespaces.has(name))
|
|
109
|
-
.map(name => ({
|
|
266
|
+
return [...this.#entries].reverse()
|
|
267
|
+
.filter(([name, entry]) => !this.#namespaces.has(name) && entry.unavailable !== true)
|
|
268
|
+
.map(([name, entry]) => ({
|
|
110
269
|
name,
|
|
111
|
-
kind:
|
|
112
|
-
|
|
270
|
+
kind: entry.kind,
|
|
271
|
+
reuseCount: entry.reuseCount ?? 0,
|
|
272
|
+
...(entry.definition === undefined ? {} : { definition: entry.definition }),
|
|
113
273
|
}))
|
|
114
274
|
}
|
|
115
275
|
}
|
|
116
276
|
|
|
277
|
+
function applyRootBindingFacts(entries, facts, rootCandidates, dynamicOrigins, imports, previousEntries) {
|
|
278
|
+
for (const fact of facts ?? []) {
|
|
279
|
+
const origin = dynamicBindingOrigin(fact.write, fact.name, dynamicOrigins)
|
|
280
|
+
const write = rootCandidates.get(fact.write) ?? (origin === undefined ? undefined
|
|
281
|
+
: { name: fact.name, kind: 'variable', writable: true, definition: dynamicOrigins.get(origin) })
|
|
282
|
+
const previous = entries.get(fact.name) ?? write
|
|
283
|
+
if (previous === undefined) continue
|
|
284
|
+
const root = { ...previous, rootSource: fact.source,
|
|
285
|
+
...(write === undefined ? {} : { definition: write.definition }) }
|
|
286
|
+
if (fact.source === 'local') entries.set(fact.name, { ...root, unavailable: false, import: undefined, origin: undefined,
|
|
287
|
+
...(previous.import === undefined && write === undefined ? {} : { kind: 'variable', writable: true }) })
|
|
288
|
+
else if (fact.source === 'absent') entries.set(fact.name, { ...root, unavailable: true, import: undefined })
|
|
289
|
+
else entries.set(fact.name, { ...root, unavailable: false, import: imports.get(fact.name) ?? previousEntries.get(fact.name)?.import })
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
117
293
|
const MAX_DEFINITION_SOURCE_LENGTH = 1024
|
|
118
294
|
|
|
119
295
|
function lineOffsets(source) {
|