@optique/core 1.3.0-dev.2576 → 1.3.0-dev.2581
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/dist/constructs.cjs +23 -2
- package/dist/constructs.js +24 -3
- package/dist/dependency-runtime.cjs +109 -2
- package/dist/dependency-runtime.d.cts +40 -1
- package/dist/dependency-runtime.d.ts +40 -1
- package/dist/dependency-runtime.js +107 -3
- package/package.json +2 -2
package/dist/constructs.cjs
CHANGED
|
@@ -438,8 +438,12 @@ async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, p
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
const republish = exec?.republishCachedCompletions === true;
|
|
441
|
+
const publishedSourceIds = /* @__PURE__ */ new Set();
|
|
441
442
|
const effectful = await require_dependency_runtime.completeEffectfulSourcesAsync(expandedNodes, state, runtime, exec, {
|
|
442
443
|
...demandNodes != null ? { demandNodes: expandEffectfulRuntimeNodes(demandNodes) } : {},
|
|
444
|
+
onPublish: (id) => {
|
|
445
|
+
publishedSourceIds.add(id);
|
|
446
|
+
},
|
|
443
447
|
isReusable: (node) => direct.has(node),
|
|
444
448
|
isCollected: republish ? () => true : (node) => collected.has(node),
|
|
445
449
|
...republish ? { includeStructural: true } : {}
|
|
@@ -452,6 +456,13 @@ async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, p
|
|
|
452
456
|
const cacheKey = typeof key === "number" ? String(key) : key;
|
|
453
457
|
preCompleted.set(cacheKey, result);
|
|
454
458
|
}
|
|
459
|
+
require_dependency_runtime.recordSourceScope(runtime, publishedSourceIds, [...collected].flatMap((node) => {
|
|
460
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
461
|
+
return source == null ? [] : [{
|
|
462
|
+
sourceId: source.sourceId,
|
|
463
|
+
path: node.path
|
|
464
|
+
}];
|
|
465
|
+
}));
|
|
455
466
|
return void 0;
|
|
456
467
|
}
|
|
457
468
|
function buildIndexedParserPairs(parsers) {
|
|
@@ -2251,6 +2262,7 @@ function filterExcludedFieldParsers(pairs, excludedFields) {
|
|
|
2251
2262
|
* @internal
|
|
2252
2263
|
*/
|
|
2253
2264
|
function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, exec) {
|
|
2265
|
+
if (exec?.dependencyRuntime != null) require_dependency_runtime.releaseUncollectedSourceValues(expandSourceCollectionNodes(require_dependency_runtime.buildRuntimeNodesFromPairs(fieldParserPairs, state, exec.path)), exec.dependencyRuntime);
|
|
2254
2266
|
const preCompleted = /* @__PURE__ */ new Map();
|
|
2255
2267
|
const parentResults = exec?.preCompletedByParser;
|
|
2256
2268
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
@@ -2304,6 +2316,7 @@ function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, e
|
|
|
2304
2316
|
* @internal
|
|
2305
2317
|
*/
|
|
2306
2318
|
async function preCompleteAndRegisterDependenciesAsync(state, fieldParserPairs, registry, exec) {
|
|
2319
|
+
if (exec?.dependencyRuntime != null) require_dependency_runtime.releaseUncollectedSourceValues(expandSourceCollectionNodes(require_dependency_runtime.buildRuntimeNodesFromPairs(fieldParserPairs, state, exec.path)), exec.dependencyRuntime);
|
|
2307
2320
|
const preCompleted = /* @__PURE__ */ new Map();
|
|
2308
2321
|
const parentResults = exec?.preCompletedByParser;
|
|
2309
2322
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
@@ -6618,7 +6631,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
6618
6631
|
_discriminator: annotatedDiscriminatorState,
|
|
6619
6632
|
_branch: require_annotation_state.getWrappedChildState(state, state.branchState, branchParser)
|
|
6620
6633
|
};
|
|
6621
|
-
const runtime = require_dependency_runtime.createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
|
|
6634
|
+
const runtime = state.speculative === true ? require_dependency_runtime.createDependencyRuntimeContext(exec?.dependencyRegistry?.clone()) : require_dependency_runtime.forkRuntimeForCommittedSubtree(exec, committedSourceIds(state, exec?.path));
|
|
6622
6635
|
require_dependency_runtime.collectExplicitSourceValues(expandSourceCollectionNodes(require_dependency_runtime.buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path)), runtime);
|
|
6623
6636
|
require_dependency_runtime.collectSourcesFromState(combinedState, runtime);
|
|
6624
6637
|
const resolvedBranchState = require_annotation_state.getWrappedChildState(state, require_dependency_runtime.resolveStateWithRuntime(state.branchState, runtime), branchParser);
|
|
@@ -6757,6 +6770,14 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
6757
6770
|
barrierDependenciesByKey: byKey
|
|
6758
6771
|
};
|
|
6759
6772
|
})();
|
|
6773
|
+
const committedSourceIds = (state, path) => {
|
|
6774
|
+
const ids = /* @__PURE__ */ new Set();
|
|
6775
|
+
for (const node of expandEffectfulRuntimeNodes(buildConditionalSchedulingNodes(state, path))) {
|
|
6776
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
6777
|
+
if (source != null) ids.add(source.sourceId);
|
|
6778
|
+
}
|
|
6779
|
+
return ids;
|
|
6780
|
+
};
|
|
6760
6781
|
const buildConditionalSchedulingNodes = (state, parentPath) => {
|
|
6761
6782
|
if (state == null || typeof state !== "object") return [];
|
|
6762
6783
|
const conditionalState = state;
|
|
@@ -7048,7 +7069,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
7048
7069
|
_discriminator: annotatedDiscriminatorState,
|
|
7049
7070
|
_branch: require_annotation_state.getWrappedChildState(state, state.branchState, branchParser)
|
|
7050
7071
|
};
|
|
7051
|
-
const runtime = require_dependency_runtime.createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
|
|
7072
|
+
const runtime = wasSpeculative ? require_dependency_runtime.createDependencyRuntimeContext(exec?.dependencyRegistry?.clone()) : require_dependency_runtime.forkRuntimeForCommittedSubtree(exec, committedSourceIds(state, exec?.path));
|
|
7052
7073
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(expandSourceCollectionNodes(require_dependency_runtime.buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path)), runtime);
|
|
7053
7074
|
require_dependency_runtime.collectSourcesFromState(combinedState, runtime);
|
|
7054
7075
|
const completionExec = {
|
package/dist/constructs.js
CHANGED
|
@@ -5,7 +5,7 @@ import { message, optionName, text, values } from "./message.js";
|
|
|
5
5
|
import { deduplicateDocFragments } from "./doc.js";
|
|
6
6
|
import { dispatchByMode, dispatchIterableByMode } from "./internal/mode-dispatch.js";
|
|
7
7
|
import { createDependencySourceState, dependencyId, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, wrappedDependencySourceMarker } from "./internal/dependency.js";
|
|
8
|
-
import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyRuntimeContext, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, guaranteedStaticSourceIdsKey, hasInactiveCompletion, replaceCachedBarrierFailure, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
|
|
8
|
+
import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyRuntimeContext, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, guaranteedStaticSourceIdsKey, hasInactiveCompletion, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
|
|
9
9
|
import { defineInheritedAnnotationParser, defineParseLanes, getOwnParseLanes, getParserSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
10
10
|
import { annotationViewTargets, getWrappedChildParseState, getWrappedChildState, reconcileObjectChildState, unwrapAnnotationView } from "./annotation-state.js";
|
|
11
11
|
import { allowDuplicateLeadingCommandNamesKey } from "./internal/command-alias.js";
|
|
@@ -438,8 +438,12 @@ async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, p
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
const republish = exec?.republishCachedCompletions === true;
|
|
441
|
+
const publishedSourceIds = /* @__PURE__ */ new Set();
|
|
441
442
|
const effectful = await completeEffectfulSourcesAsync(expandedNodes, state, runtime, exec, {
|
|
442
443
|
...demandNodes != null ? { demandNodes: expandEffectfulRuntimeNodes(demandNodes) } : {},
|
|
444
|
+
onPublish: (id) => {
|
|
445
|
+
publishedSourceIds.add(id);
|
|
446
|
+
},
|
|
443
447
|
isReusable: (node) => direct.has(node),
|
|
444
448
|
isCollected: republish ? () => true : (node) => collected.has(node),
|
|
445
449
|
...republish ? { includeStructural: true } : {}
|
|
@@ -452,6 +456,13 @@ async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, p
|
|
|
452
456
|
const cacheKey = typeof key === "number" ? String(key) : key;
|
|
453
457
|
preCompleted.set(cacheKey, result);
|
|
454
458
|
}
|
|
459
|
+
recordSourceScope(runtime, publishedSourceIds, [...collected].flatMap((node) => {
|
|
460
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
461
|
+
return source == null ? [] : [{
|
|
462
|
+
sourceId: source.sourceId,
|
|
463
|
+
path: node.path
|
|
464
|
+
}];
|
|
465
|
+
}));
|
|
455
466
|
return void 0;
|
|
456
467
|
}
|
|
457
468
|
function buildIndexedParserPairs(parsers) {
|
|
@@ -2251,6 +2262,7 @@ function filterExcludedFieldParsers(pairs, excludedFields) {
|
|
|
2251
2262
|
* @internal
|
|
2252
2263
|
*/
|
|
2253
2264
|
function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, exec) {
|
|
2265
|
+
if (exec?.dependencyRuntime != null) releaseUncollectedSourceValues(expandSourceCollectionNodes(buildRuntimeNodesFromPairs(fieldParserPairs, state, exec.path)), exec.dependencyRuntime);
|
|
2254
2266
|
const preCompleted = /* @__PURE__ */ new Map();
|
|
2255
2267
|
const parentResults = exec?.preCompletedByParser;
|
|
2256
2268
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
@@ -2304,6 +2316,7 @@ function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, e
|
|
|
2304
2316
|
* @internal
|
|
2305
2317
|
*/
|
|
2306
2318
|
async function preCompleteAndRegisterDependenciesAsync(state, fieldParserPairs, registry, exec) {
|
|
2319
|
+
if (exec?.dependencyRuntime != null) releaseUncollectedSourceValues(expandSourceCollectionNodes(buildRuntimeNodesFromPairs(fieldParserPairs, state, exec.path)), exec.dependencyRuntime);
|
|
2307
2320
|
const preCompleted = /* @__PURE__ */ new Map();
|
|
2308
2321
|
const parentResults = exec?.preCompletedByParser;
|
|
2309
2322
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
@@ -6618,7 +6631,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
6618
6631
|
_discriminator: annotatedDiscriminatorState,
|
|
6619
6632
|
_branch: getWrappedChildState(state, state.branchState, branchParser)
|
|
6620
6633
|
};
|
|
6621
|
-
const runtime = createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
|
|
6634
|
+
const runtime = state.speculative === true ? createDependencyRuntimeContext(exec?.dependencyRegistry?.clone()) : forkRuntimeForCommittedSubtree(exec, committedSourceIds(state, exec?.path));
|
|
6622
6635
|
collectExplicitSourceValues(expandSourceCollectionNodes(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path)), runtime);
|
|
6623
6636
|
collectSourcesFromState(combinedState, runtime);
|
|
6624
6637
|
const resolvedBranchState = getWrappedChildState(state, resolveStateWithRuntime(state.branchState, runtime), branchParser);
|
|
@@ -6757,6 +6770,14 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
6757
6770
|
barrierDependenciesByKey: byKey
|
|
6758
6771
|
};
|
|
6759
6772
|
})();
|
|
6773
|
+
const committedSourceIds = (state, path) => {
|
|
6774
|
+
const ids = /* @__PURE__ */ new Set();
|
|
6775
|
+
for (const node of expandEffectfulRuntimeNodes(buildConditionalSchedulingNodes(state, path))) {
|
|
6776
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
6777
|
+
if (source != null) ids.add(source.sourceId);
|
|
6778
|
+
}
|
|
6779
|
+
return ids;
|
|
6780
|
+
};
|
|
6760
6781
|
const buildConditionalSchedulingNodes = (state, parentPath) => {
|
|
6761
6782
|
if (state == null || typeof state !== "object") return [];
|
|
6762
6783
|
const conditionalState = state;
|
|
@@ -7048,7 +7069,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
|
|
|
7048
7069
|
_discriminator: annotatedDiscriminatorState,
|
|
7049
7070
|
_branch: getWrappedChildState(state, state.branchState, branchParser)
|
|
7050
7071
|
};
|
|
7051
|
-
const runtime = createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
|
|
7072
|
+
const runtime = wasSpeculative ? createDependencyRuntimeContext(exec?.dependencyRegistry?.clone()) : forkRuntimeForCommittedSubtree(exec, committedSourceIds(state, exec?.path));
|
|
7052
7073
|
await collectExplicitSourceValuesAsync(expandSourceCollectionNodes(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path)), runtime);
|
|
7053
7074
|
collectSourcesFromState(combinedState, runtime);
|
|
7054
7075
|
const completionExec = {
|
|
@@ -55,6 +55,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
55
55
|
this.registry = new FailedAwareRegistry(registry, this.#failedSources);
|
|
56
56
|
}
|
|
57
57
|
registerSource(sourceId, value) {
|
|
58
|
+
if (this.registry.isPreserved(sourceId)) return;
|
|
58
59
|
this.registry.set(sourceId, value);
|
|
59
60
|
this.#sourceFailures.delete(sourceId);
|
|
60
61
|
}
|
|
@@ -74,6 +75,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
74
75
|
this.#replayCache.set(serializeReplayKey(key), result);
|
|
75
76
|
}
|
|
76
77
|
markSourceFailed(sourceId) {
|
|
78
|
+
if (this.registry.isPreserved(sourceId)) return;
|
|
77
79
|
this.#failedSources.add(sourceId);
|
|
78
80
|
const lineage = this.#getSourceLineage(sourceId, /* @__PURE__ */ new Set());
|
|
79
81
|
const failure = {
|
|
@@ -104,7 +106,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
104
106
|
participants,
|
|
105
107
|
diagnosticChain: chain
|
|
106
108
|
};
|
|
107
|
-
if (sourceId != null) {
|
|
109
|
+
if (sourceId != null && !this.registry.isPreserved(sourceId)) {
|
|
108
110
|
this.#failedSources.add(sourceId);
|
|
109
111
|
this.#sourceFailures.set(sourceId, failure);
|
|
110
112
|
}
|
|
@@ -159,11 +161,13 @@ var DependencyRuntimeContextImpl = class {
|
|
|
159
161
|
var FailedAwareRegistry = class FailedAwareRegistry {
|
|
160
162
|
#inner;
|
|
161
163
|
#failedSources;
|
|
164
|
+
#preserved = /* @__PURE__ */ new Map();
|
|
162
165
|
constructor(inner, failedSources) {
|
|
163
166
|
this.#inner = inner;
|
|
164
167
|
this.#failedSources = failedSources;
|
|
165
168
|
}
|
|
166
169
|
set(id, value) {
|
|
170
|
+
if (this.isPreserved(id)) return;
|
|
167
171
|
this.#inner.set(id, value);
|
|
168
172
|
this.#failedSources.delete(id);
|
|
169
173
|
}
|
|
@@ -175,12 +179,24 @@ var FailedAwareRegistry = class FailedAwareRegistry {
|
|
|
175
179
|
if (this.#failedSources.has(id)) return false;
|
|
176
180
|
return this.#inner.has(id);
|
|
177
181
|
}
|
|
182
|
+
preserve(id, paths) {
|
|
183
|
+
this.#preserved.set(id, paths);
|
|
184
|
+
}
|
|
185
|
+
allowUncollectedOccurrence(id, path) {
|
|
186
|
+
const paths = this.#preserved.get(id);
|
|
187
|
+
if (paths != null && !paths.some((covered) => covered.length === path.length && covered.every((segment, index) => segment === path[index]))) this.#preserved.delete(id);
|
|
188
|
+
}
|
|
189
|
+
isPreserved(id) {
|
|
190
|
+
return this.#preserved.has(id);
|
|
191
|
+
}
|
|
178
192
|
copyFailedSources(target) {
|
|
179
193
|
for (const sourceId of this.#failedSources) target.add(sourceId);
|
|
180
194
|
}
|
|
181
195
|
rebindFailedSources(target) {
|
|
182
196
|
this.copyFailedSources(target);
|
|
183
|
-
|
|
197
|
+
const rebound = new FailedAwareRegistry(this.#inner, target);
|
|
198
|
+
for (const [id, paths] of this.#preserved) rebound.preserve(id, paths);
|
|
199
|
+
return rebound;
|
|
184
200
|
}
|
|
185
201
|
clone() {
|
|
186
202
|
const failedSources = new Set(this.#failedSources);
|
|
@@ -188,6 +204,90 @@ var FailedAwareRegistry = class FailedAwareRegistry {
|
|
|
188
204
|
return innerClone instanceof FailedAwareRegistry ? innerClone.rebindFailedSources(failedSources) : new FailedAwareRegistry(innerClone, failedSources);
|
|
189
205
|
}
|
|
190
206
|
};
|
|
207
|
+
const sourceScopes = /* @__PURE__ */ new WeakMap();
|
|
208
|
+
function recordSourceCollection(nodes, runtime) {
|
|
209
|
+
const sources = nodes.flatMap((node) => {
|
|
210
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
211
|
+
return source == null ? [] : [{
|
|
212
|
+
sourceId: source.sourceId,
|
|
213
|
+
path: node.path
|
|
214
|
+
}];
|
|
215
|
+
});
|
|
216
|
+
recordSourceScope(runtime, /* @__PURE__ */ new Set(), sources);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Allows a source occurrence first discovered inside an opaque subtree to
|
|
220
|
+
* publish. Preservation covers the enclosing collector's known occurrences,
|
|
221
|
+
* not every later occurrence of the same dependency ID.
|
|
222
|
+
* @param nodes The source occurrences about to complete or be collected.
|
|
223
|
+
* @param runtime The runtime shared with the enclosing construct.
|
|
224
|
+
* @internal
|
|
225
|
+
* @since 1.3.0
|
|
226
|
+
*/
|
|
227
|
+
function releaseUncollectedSourceValues(nodes, runtime) {
|
|
228
|
+
if (!(runtime instanceof DependencyRuntimeContextImpl)) return;
|
|
229
|
+
for (const node of nodes) {
|
|
230
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
231
|
+
if (source != null) runtime.registry.allowUncollectedOccurrence(source.sourceId, node.path);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Records effective source values after a collection or scheduling pass.
|
|
236
|
+
* Each pass retains its own coverage, so a sibling sharing the runtime cannot
|
|
237
|
+
* replace its parent's snapshot. A newer pass only supersedes scopes for
|
|
238
|
+
* the source paths it actually collects.
|
|
239
|
+
* @param runtime The owning pass's runtime.
|
|
240
|
+
* @param sourceIds Additional IDs published by the pass's scheduling barriers.
|
|
241
|
+
* @param collectedSources The sources included in the owning scope's collection.
|
|
242
|
+
* @internal
|
|
243
|
+
* @since 1.3.0
|
|
244
|
+
*/
|
|
245
|
+
function recordSourceScope(runtime, sourceIds, collectedSources) {
|
|
246
|
+
if (collectedSources.length === 0) return;
|
|
247
|
+
const values = /* @__PURE__ */ new Map();
|
|
248
|
+
const ids = new Set([...sourceIds, ...collectedSources.map((source) => source.sourceId)]);
|
|
249
|
+
for (const id of ids) if (runtime.hasSource(id)) values.set(id, {
|
|
250
|
+
success: true,
|
|
251
|
+
value: runtime.getSource(id)
|
|
252
|
+
});
|
|
253
|
+
else if (runtime.isSourceFailed(id)) values.set(id, { success: false });
|
|
254
|
+
let scopes = sourceScopes.get(runtime);
|
|
255
|
+
if (scopes == null) {
|
|
256
|
+
scopes = [];
|
|
257
|
+
sourceScopes.set(runtime, scopes);
|
|
258
|
+
}
|
|
259
|
+
scopes.push({
|
|
260
|
+
values,
|
|
261
|
+
collectedSources
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Forks a CLI-committed subtree without letting its repeated collection
|
|
266
|
+
* replace the enclosing scope's final source occurrences. Unknown sources
|
|
267
|
+
* remain writable, including when no enclosing construct collected them.
|
|
268
|
+
* Ordinary registry clones drop this protection so completion-selected
|
|
269
|
+
* branches can establish their own scope.
|
|
270
|
+
* @param exec The enclosing execution context.
|
|
271
|
+
* @param sourceIds The sources exposed by the committed subtree.
|
|
272
|
+
* @returns A runtime preserving the enclosing values for those sources.
|
|
273
|
+
* @internal
|
|
274
|
+
* @since 1.3.0
|
|
275
|
+
*/
|
|
276
|
+
function forkRuntimeForCommittedSubtree(exec, sourceIds) {
|
|
277
|
+
const runtime = new DependencyRuntimeContextImpl(exec?.dependencyRegistry?.clone() ?? new SimpleRegistry());
|
|
278
|
+
const scopes = exec?.dependencyRuntime == null ? void 0 : sourceScopes.get(exec.dependencyRuntime);
|
|
279
|
+
for (const id of sourceIds) {
|
|
280
|
+
const scope = scopes?.findLast((candidate) => candidate.collectedSources.some((source) => source.sourceId === id && exec?.path.every((segment, index) => source.path[index] === segment)));
|
|
281
|
+
if (scope == null) continue;
|
|
282
|
+
const publication = scope.values.get(id);
|
|
283
|
+
if (publication?.success) runtime.registerSource(id, publication.value);
|
|
284
|
+
else if (publication != null) runtime.markSourceFailed(id);
|
|
285
|
+
else if (runtime.hasSource(id)) {} else if (!runtime.isSourceFailed(id)) continue;
|
|
286
|
+
const paths = scope.collectedSources.filter((source) => source.sourceId === id).map((source) => source.path);
|
|
287
|
+
runtime.registry.preserve(id, paths);
|
|
288
|
+
}
|
|
289
|
+
return runtime;
|
|
290
|
+
}
|
|
191
291
|
function resolveRequest(ctx, request) {
|
|
192
292
|
const values = [];
|
|
193
293
|
const usedDefaults = [];
|
|
@@ -344,6 +444,7 @@ function createReplayKey(path, rawInput, dependencyValues, replayParse) {
|
|
|
344
444
|
* @since 1.0.0
|
|
345
445
|
*/
|
|
346
446
|
function collectExplicitSourceValues(nodes, runtime) {
|
|
447
|
+
releaseUncollectedSourceValues(nodes, runtime);
|
|
347
448
|
registerRuntimeSourceMetadata(nodes, runtime);
|
|
348
449
|
for (const node of nodes) {
|
|
349
450
|
const meta = node.parser.dependencyMetadata;
|
|
@@ -355,6 +456,7 @@ function collectExplicitSourceValues(nodes, runtime) {
|
|
|
355
456
|
registerExplicitSourceValue(meta.source.sourceId, result, runtime);
|
|
356
457
|
}
|
|
357
458
|
resolveDerivedSourceValues(nodes, runtime);
|
|
459
|
+
recordSourceCollection(nodes, runtime);
|
|
358
460
|
}
|
|
359
461
|
function registerExplicitSourceValue(sourceId, result, runtime) {
|
|
360
462
|
if (result == null) return;
|
|
@@ -376,6 +478,7 @@ function isPromiseLike(value) {
|
|
|
376
478
|
* @since 1.0.0
|
|
377
479
|
*/
|
|
378
480
|
async function collectExplicitSourceValuesAsync(nodes, runtime) {
|
|
481
|
+
releaseUncollectedSourceValues(nodes, runtime);
|
|
379
482
|
registerRuntimeSourceMetadata(nodes, runtime);
|
|
380
483
|
for (const node of nodes) {
|
|
381
484
|
const meta = node.parser.dependencyMetadata;
|
|
@@ -386,6 +489,7 @@ async function collectExplicitSourceValuesAsync(nodes, runtime) {
|
|
|
386
489
|
registerExplicitSourceValue(meta.source.sourceId, result, runtime);
|
|
387
490
|
}
|
|
388
491
|
await resolveDerivedSourceValuesAsync(nodes, runtime);
|
|
492
|
+
recordSourceCollection(nodes, runtime);
|
|
389
493
|
}
|
|
390
494
|
/**
|
|
391
495
|
* Orders runtime nodes so every in-scope provider precedes a derived source
|
|
@@ -1860,11 +1964,14 @@ exports.exclusiveSourceScopeKey = exclusiveSourceScopeKey;
|
|
|
1860
1964
|
exports.extractRawInputFromState = extractRawInputFromState;
|
|
1861
1965
|
exports.fillMissingSourceDefaults = fillMissingSourceDefaults;
|
|
1862
1966
|
exports.fillMissingSourceDefaultsAsync = fillMissingSourceDefaultsAsync;
|
|
1967
|
+
exports.forkRuntimeForCommittedSubtree = forkRuntimeForCommittedSubtree;
|
|
1863
1968
|
exports.guaranteedStaticSourceIdsKey = guaranteedStaticSourceIdsKey;
|
|
1864
1969
|
exports.hasInactiveCompletion = hasInactiveCompletion;
|
|
1865
1970
|
exports.includeSourceFailureChain = includeSourceFailureChain;
|
|
1866
1971
|
exports.orderDependencyNodes = orderDependencyNodes;
|
|
1867
1972
|
exports.recordDerivedRawInput = recordDerivedRawInput;
|
|
1973
|
+
exports.recordSourceScope = recordSourceScope;
|
|
1974
|
+
exports.releaseUncollectedSourceValues = releaseUncollectedSourceValues;
|
|
1868
1975
|
exports.replaceCachedBarrierFailure = replaceCachedBarrierFailure;
|
|
1869
1976
|
exports.replayDerivedParser = replayDerivedParser;
|
|
1870
1977
|
exports.replayDerivedParserAsync = replayDerivedParserAsync;
|
|
@@ -393,6 +393,45 @@ interface DependencyRuntimeContext {
|
|
|
393
393
|
/** Resolve dependencies for suggestions (same semantics as resolve). */
|
|
394
394
|
getSuggestionDependencies(request: DependencyRequest): DependencyResolution;
|
|
395
395
|
}
|
|
396
|
+
interface CollectedSource {
|
|
397
|
+
readonly sourceId: symbol;
|
|
398
|
+
readonly path: readonly PropertyKey[];
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Allows a source occurrence first discovered inside an opaque subtree to
|
|
402
|
+
* publish. Preservation covers the enclosing collector's known occurrences,
|
|
403
|
+
* not every later occurrence of the same dependency ID.
|
|
404
|
+
* @param nodes The source occurrences about to complete or be collected.
|
|
405
|
+
* @param runtime The runtime shared with the enclosing construct.
|
|
406
|
+
* @internal
|
|
407
|
+
* @since 1.3.0
|
|
408
|
+
*/
|
|
409
|
+
declare function releaseUncollectedSourceValues(nodes: readonly RuntimeNode[], runtime: DependencyRuntimeContext): void;
|
|
410
|
+
/**
|
|
411
|
+
* Records effective source values after a collection or scheduling pass.
|
|
412
|
+
* Each pass retains its own coverage, so a sibling sharing the runtime cannot
|
|
413
|
+
* replace its parent's snapshot. A newer pass only supersedes scopes for
|
|
414
|
+
* the source paths it actually collects.
|
|
415
|
+
* @param runtime The owning pass's runtime.
|
|
416
|
+
* @param sourceIds Additional IDs published by the pass's scheduling barriers.
|
|
417
|
+
* @param collectedSources The sources included in the owning scope's collection.
|
|
418
|
+
* @internal
|
|
419
|
+
* @since 1.3.0
|
|
420
|
+
*/
|
|
421
|
+
declare function recordSourceScope(runtime: DependencyRuntimeContext, sourceIds: ReadonlySet<symbol>, collectedSources: readonly CollectedSource[]): void;
|
|
422
|
+
/**
|
|
423
|
+
* Forks a CLI-committed subtree without letting its repeated collection
|
|
424
|
+
* replace the enclosing scope's final source occurrences. Unknown sources
|
|
425
|
+
* remain writable, including when no enclosing construct collected them.
|
|
426
|
+
* Ordinary registry clones drop this protection so completion-selected
|
|
427
|
+
* branches can establish their own scope.
|
|
428
|
+
* @param exec The enclosing execution context.
|
|
429
|
+
* @param sourceIds The sources exposed by the committed subtree.
|
|
430
|
+
* @returns A runtime preserving the enclosing values for those sources.
|
|
431
|
+
* @internal
|
|
432
|
+
* @since 1.3.0
|
|
433
|
+
*/
|
|
434
|
+
declare function forkRuntimeForCommittedSubtree(exec: ExecutionContext | undefined, sourceIds: ReadonlySet<symbol>): DependencyRuntimeContext;
|
|
396
435
|
/**
|
|
397
436
|
* Creates a new {@link DependencyRuntimeContext}.
|
|
398
437
|
*
|
|
@@ -923,4 +962,4 @@ declare function buildRuntimeNodesFromArray(parsers: ReadonlyArray<{
|
|
|
923
962
|
readonly initialState?: unknown;
|
|
924
963
|
}>, stateArray: readonly unknown[], parentPath?: readonly PropertyKey[]): readonly RuntimeNode[];
|
|
925
964
|
//#endregion
|
|
926
|
-
export { BarrierCompletionDemandEdge, BarrierCompletionDependencies, BarrierResolution, CompleteEffectfulSourcesOptions, DependencyRequest, DependencyResolution, DependencyRuntimeContext, EffectfulSchedulingNodesFn, EffectfulSourceCompletion, EffectfulSourceCompletionResult, ReplayKey, ResolveDerivedSourceValuesOptions, RuntimeNode, SchedulingBarrierContext, SourceDefaultFailure, buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
|
965
|
+
export { BarrierCompletionDemandEdge, BarrierCompletionDependencies, BarrierResolution, CompleteEffectfulSourcesOptions, DependencyRequest, DependencyResolution, DependencyRuntimeContext, EffectfulSchedulingNodesFn, EffectfulSourceCompletion, EffectfulSourceCompletionResult, ReplayKey, ResolveDerivedSourceValuesOptions, RuntimeNode, SchedulingBarrierContext, SourceDefaultFailure, buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
|
@@ -393,6 +393,45 @@ interface DependencyRuntimeContext {
|
|
|
393
393
|
/** Resolve dependencies for suggestions (same semantics as resolve). */
|
|
394
394
|
getSuggestionDependencies(request: DependencyRequest): DependencyResolution;
|
|
395
395
|
}
|
|
396
|
+
interface CollectedSource {
|
|
397
|
+
readonly sourceId: symbol;
|
|
398
|
+
readonly path: readonly PropertyKey[];
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Allows a source occurrence first discovered inside an opaque subtree to
|
|
402
|
+
* publish. Preservation covers the enclosing collector's known occurrences,
|
|
403
|
+
* not every later occurrence of the same dependency ID.
|
|
404
|
+
* @param nodes The source occurrences about to complete or be collected.
|
|
405
|
+
* @param runtime The runtime shared with the enclosing construct.
|
|
406
|
+
* @internal
|
|
407
|
+
* @since 1.3.0
|
|
408
|
+
*/
|
|
409
|
+
declare function releaseUncollectedSourceValues(nodes: readonly RuntimeNode[], runtime: DependencyRuntimeContext): void;
|
|
410
|
+
/**
|
|
411
|
+
* Records effective source values after a collection or scheduling pass.
|
|
412
|
+
* Each pass retains its own coverage, so a sibling sharing the runtime cannot
|
|
413
|
+
* replace its parent's snapshot. A newer pass only supersedes scopes for
|
|
414
|
+
* the source paths it actually collects.
|
|
415
|
+
* @param runtime The owning pass's runtime.
|
|
416
|
+
* @param sourceIds Additional IDs published by the pass's scheduling barriers.
|
|
417
|
+
* @param collectedSources The sources included in the owning scope's collection.
|
|
418
|
+
* @internal
|
|
419
|
+
* @since 1.3.0
|
|
420
|
+
*/
|
|
421
|
+
declare function recordSourceScope(runtime: DependencyRuntimeContext, sourceIds: ReadonlySet<symbol>, collectedSources: readonly CollectedSource[]): void;
|
|
422
|
+
/**
|
|
423
|
+
* Forks a CLI-committed subtree without letting its repeated collection
|
|
424
|
+
* replace the enclosing scope's final source occurrences. Unknown sources
|
|
425
|
+
* remain writable, including when no enclosing construct collected them.
|
|
426
|
+
* Ordinary registry clones drop this protection so completion-selected
|
|
427
|
+
* branches can establish their own scope.
|
|
428
|
+
* @param exec The enclosing execution context.
|
|
429
|
+
* @param sourceIds The sources exposed by the committed subtree.
|
|
430
|
+
* @returns A runtime preserving the enclosing values for those sources.
|
|
431
|
+
* @internal
|
|
432
|
+
* @since 1.3.0
|
|
433
|
+
*/
|
|
434
|
+
declare function forkRuntimeForCommittedSubtree(exec: ExecutionContext | undefined, sourceIds: ReadonlySet<symbol>): DependencyRuntimeContext;
|
|
396
435
|
/**
|
|
397
436
|
* Creates a new {@link DependencyRuntimeContext}.
|
|
398
437
|
*
|
|
@@ -923,4 +962,4 @@ declare function buildRuntimeNodesFromArray(parsers: ReadonlyArray<{
|
|
|
923
962
|
readonly initialState?: unknown;
|
|
924
963
|
}>, stateArray: readonly unknown[], parentPath?: readonly PropertyKey[]): readonly RuntimeNode[];
|
|
925
964
|
//#endregion
|
|
926
|
-
export { BarrierCompletionDemandEdge, BarrierCompletionDependencies, BarrierResolution, CompleteEffectfulSourcesOptions, DependencyRequest, DependencyResolution, DependencyRuntimeContext, EffectfulSchedulingNodesFn, EffectfulSourceCompletion, EffectfulSourceCompletionResult, ReplayKey, ResolveDerivedSourceValuesOptions, RuntimeNode, SchedulingBarrierContext, SourceDefaultFailure, buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
|
965
|
+
export { BarrierCompletionDemandEdge, BarrierCompletionDependencies, BarrierResolution, CompleteEffectfulSourcesOptions, DependencyRequest, DependencyResolution, DependencyRuntimeContext, EffectfulSchedulingNodesFn, EffectfulSourceCompletion, EffectfulSourceCompletionResult, ReplayKey, ResolveDerivedSourceValuesOptions, RuntimeNode, SchedulingBarrierContext, SourceDefaultFailure, buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
|
@@ -55,6 +55,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
55
55
|
this.registry = new FailedAwareRegistry(registry, this.#failedSources);
|
|
56
56
|
}
|
|
57
57
|
registerSource(sourceId, value) {
|
|
58
|
+
if (this.registry.isPreserved(sourceId)) return;
|
|
58
59
|
this.registry.set(sourceId, value);
|
|
59
60
|
this.#sourceFailures.delete(sourceId);
|
|
60
61
|
}
|
|
@@ -74,6 +75,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
74
75
|
this.#replayCache.set(serializeReplayKey(key), result);
|
|
75
76
|
}
|
|
76
77
|
markSourceFailed(sourceId) {
|
|
78
|
+
if (this.registry.isPreserved(sourceId)) return;
|
|
77
79
|
this.#failedSources.add(sourceId);
|
|
78
80
|
const lineage = this.#getSourceLineage(sourceId, /* @__PURE__ */ new Set());
|
|
79
81
|
const failure = {
|
|
@@ -104,7 +106,7 @@ var DependencyRuntimeContextImpl = class {
|
|
|
104
106
|
participants,
|
|
105
107
|
diagnosticChain: chain
|
|
106
108
|
};
|
|
107
|
-
if (sourceId != null) {
|
|
109
|
+
if (sourceId != null && !this.registry.isPreserved(sourceId)) {
|
|
108
110
|
this.#failedSources.add(sourceId);
|
|
109
111
|
this.#sourceFailures.set(sourceId, failure);
|
|
110
112
|
}
|
|
@@ -159,11 +161,13 @@ var DependencyRuntimeContextImpl = class {
|
|
|
159
161
|
var FailedAwareRegistry = class FailedAwareRegistry {
|
|
160
162
|
#inner;
|
|
161
163
|
#failedSources;
|
|
164
|
+
#preserved = /* @__PURE__ */ new Map();
|
|
162
165
|
constructor(inner, failedSources) {
|
|
163
166
|
this.#inner = inner;
|
|
164
167
|
this.#failedSources = failedSources;
|
|
165
168
|
}
|
|
166
169
|
set(id, value) {
|
|
170
|
+
if (this.isPreserved(id)) return;
|
|
167
171
|
this.#inner.set(id, value);
|
|
168
172
|
this.#failedSources.delete(id);
|
|
169
173
|
}
|
|
@@ -175,12 +179,24 @@ var FailedAwareRegistry = class FailedAwareRegistry {
|
|
|
175
179
|
if (this.#failedSources.has(id)) return false;
|
|
176
180
|
return this.#inner.has(id);
|
|
177
181
|
}
|
|
182
|
+
preserve(id, paths) {
|
|
183
|
+
this.#preserved.set(id, paths);
|
|
184
|
+
}
|
|
185
|
+
allowUncollectedOccurrence(id, path) {
|
|
186
|
+
const paths = this.#preserved.get(id);
|
|
187
|
+
if (paths != null && !paths.some((covered) => covered.length === path.length && covered.every((segment, index) => segment === path[index]))) this.#preserved.delete(id);
|
|
188
|
+
}
|
|
189
|
+
isPreserved(id) {
|
|
190
|
+
return this.#preserved.has(id);
|
|
191
|
+
}
|
|
178
192
|
copyFailedSources(target) {
|
|
179
193
|
for (const sourceId of this.#failedSources) target.add(sourceId);
|
|
180
194
|
}
|
|
181
195
|
rebindFailedSources(target) {
|
|
182
196
|
this.copyFailedSources(target);
|
|
183
|
-
|
|
197
|
+
const rebound = new FailedAwareRegistry(this.#inner, target);
|
|
198
|
+
for (const [id, paths] of this.#preserved) rebound.preserve(id, paths);
|
|
199
|
+
return rebound;
|
|
184
200
|
}
|
|
185
201
|
clone() {
|
|
186
202
|
const failedSources = new Set(this.#failedSources);
|
|
@@ -188,6 +204,90 @@ var FailedAwareRegistry = class FailedAwareRegistry {
|
|
|
188
204
|
return innerClone instanceof FailedAwareRegistry ? innerClone.rebindFailedSources(failedSources) : new FailedAwareRegistry(innerClone, failedSources);
|
|
189
205
|
}
|
|
190
206
|
};
|
|
207
|
+
const sourceScopes = /* @__PURE__ */ new WeakMap();
|
|
208
|
+
function recordSourceCollection(nodes, runtime) {
|
|
209
|
+
const sources = nodes.flatMap((node) => {
|
|
210
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
211
|
+
return source == null ? [] : [{
|
|
212
|
+
sourceId: source.sourceId,
|
|
213
|
+
path: node.path
|
|
214
|
+
}];
|
|
215
|
+
});
|
|
216
|
+
recordSourceScope(runtime, /* @__PURE__ */ new Set(), sources);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Allows a source occurrence first discovered inside an opaque subtree to
|
|
220
|
+
* publish. Preservation covers the enclosing collector's known occurrences,
|
|
221
|
+
* not every later occurrence of the same dependency ID.
|
|
222
|
+
* @param nodes The source occurrences about to complete or be collected.
|
|
223
|
+
* @param runtime The runtime shared with the enclosing construct.
|
|
224
|
+
* @internal
|
|
225
|
+
* @since 1.3.0
|
|
226
|
+
*/
|
|
227
|
+
function releaseUncollectedSourceValues(nodes, runtime) {
|
|
228
|
+
if (!(runtime instanceof DependencyRuntimeContextImpl)) return;
|
|
229
|
+
for (const node of nodes) {
|
|
230
|
+
const source = node.parser.dependencyMetadata?.source;
|
|
231
|
+
if (source != null) runtime.registry.allowUncollectedOccurrence(source.sourceId, node.path);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Records effective source values after a collection or scheduling pass.
|
|
236
|
+
* Each pass retains its own coverage, so a sibling sharing the runtime cannot
|
|
237
|
+
* replace its parent's snapshot. A newer pass only supersedes scopes for
|
|
238
|
+
* the source paths it actually collects.
|
|
239
|
+
* @param runtime The owning pass's runtime.
|
|
240
|
+
* @param sourceIds Additional IDs published by the pass's scheduling barriers.
|
|
241
|
+
* @param collectedSources The sources included in the owning scope's collection.
|
|
242
|
+
* @internal
|
|
243
|
+
* @since 1.3.0
|
|
244
|
+
*/
|
|
245
|
+
function recordSourceScope(runtime, sourceIds, collectedSources) {
|
|
246
|
+
if (collectedSources.length === 0) return;
|
|
247
|
+
const values = /* @__PURE__ */ new Map();
|
|
248
|
+
const ids = new Set([...sourceIds, ...collectedSources.map((source) => source.sourceId)]);
|
|
249
|
+
for (const id of ids) if (runtime.hasSource(id)) values.set(id, {
|
|
250
|
+
success: true,
|
|
251
|
+
value: runtime.getSource(id)
|
|
252
|
+
});
|
|
253
|
+
else if (runtime.isSourceFailed(id)) values.set(id, { success: false });
|
|
254
|
+
let scopes = sourceScopes.get(runtime);
|
|
255
|
+
if (scopes == null) {
|
|
256
|
+
scopes = [];
|
|
257
|
+
sourceScopes.set(runtime, scopes);
|
|
258
|
+
}
|
|
259
|
+
scopes.push({
|
|
260
|
+
values,
|
|
261
|
+
collectedSources
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Forks a CLI-committed subtree without letting its repeated collection
|
|
266
|
+
* replace the enclosing scope's final source occurrences. Unknown sources
|
|
267
|
+
* remain writable, including when no enclosing construct collected them.
|
|
268
|
+
* Ordinary registry clones drop this protection so completion-selected
|
|
269
|
+
* branches can establish their own scope.
|
|
270
|
+
* @param exec The enclosing execution context.
|
|
271
|
+
* @param sourceIds The sources exposed by the committed subtree.
|
|
272
|
+
* @returns A runtime preserving the enclosing values for those sources.
|
|
273
|
+
* @internal
|
|
274
|
+
* @since 1.3.0
|
|
275
|
+
*/
|
|
276
|
+
function forkRuntimeForCommittedSubtree(exec, sourceIds) {
|
|
277
|
+
const runtime = new DependencyRuntimeContextImpl(exec?.dependencyRegistry?.clone() ?? new SimpleRegistry());
|
|
278
|
+
const scopes = exec?.dependencyRuntime == null ? void 0 : sourceScopes.get(exec.dependencyRuntime);
|
|
279
|
+
for (const id of sourceIds) {
|
|
280
|
+
const scope = scopes?.findLast((candidate) => candidate.collectedSources.some((source) => source.sourceId === id && exec?.path.every((segment, index) => source.path[index] === segment)));
|
|
281
|
+
if (scope == null) continue;
|
|
282
|
+
const publication = scope.values.get(id);
|
|
283
|
+
if (publication?.success) runtime.registerSource(id, publication.value);
|
|
284
|
+
else if (publication != null) runtime.markSourceFailed(id);
|
|
285
|
+
else if (runtime.hasSource(id)) {} else if (!runtime.isSourceFailed(id)) continue;
|
|
286
|
+
const paths = scope.collectedSources.filter((source) => source.sourceId === id).map((source) => source.path);
|
|
287
|
+
runtime.registry.preserve(id, paths);
|
|
288
|
+
}
|
|
289
|
+
return runtime;
|
|
290
|
+
}
|
|
191
291
|
function resolveRequest(ctx, request) {
|
|
192
292
|
const values = [];
|
|
193
293
|
const usedDefaults = [];
|
|
@@ -344,6 +444,7 @@ function createReplayKey(path, rawInput, dependencyValues, replayParse) {
|
|
|
344
444
|
* @since 1.0.0
|
|
345
445
|
*/
|
|
346
446
|
function collectExplicitSourceValues(nodes, runtime) {
|
|
447
|
+
releaseUncollectedSourceValues(nodes, runtime);
|
|
347
448
|
registerRuntimeSourceMetadata(nodes, runtime);
|
|
348
449
|
for (const node of nodes) {
|
|
349
450
|
const meta = node.parser.dependencyMetadata;
|
|
@@ -355,6 +456,7 @@ function collectExplicitSourceValues(nodes, runtime) {
|
|
|
355
456
|
registerExplicitSourceValue(meta.source.sourceId, result, runtime);
|
|
356
457
|
}
|
|
357
458
|
resolveDerivedSourceValues(nodes, runtime);
|
|
459
|
+
recordSourceCollection(nodes, runtime);
|
|
358
460
|
}
|
|
359
461
|
function registerExplicitSourceValue(sourceId, result, runtime) {
|
|
360
462
|
if (result == null) return;
|
|
@@ -376,6 +478,7 @@ function isPromiseLike(value) {
|
|
|
376
478
|
* @since 1.0.0
|
|
377
479
|
*/
|
|
378
480
|
async function collectExplicitSourceValuesAsync(nodes, runtime) {
|
|
481
|
+
releaseUncollectedSourceValues(nodes, runtime);
|
|
379
482
|
registerRuntimeSourceMetadata(nodes, runtime);
|
|
380
483
|
for (const node of nodes) {
|
|
381
484
|
const meta = node.parser.dependencyMetadata;
|
|
@@ -386,6 +489,7 @@ async function collectExplicitSourceValuesAsync(nodes, runtime) {
|
|
|
386
489
|
registerExplicitSourceValue(meta.source.sourceId, result, runtime);
|
|
387
490
|
}
|
|
388
491
|
await resolveDerivedSourceValuesAsync(nodes, runtime);
|
|
492
|
+
recordSourceCollection(nodes, runtime);
|
|
389
493
|
}
|
|
390
494
|
/**
|
|
391
495
|
* Orders runtime nodes so every in-scope provider precedes a derived source
|
|
@@ -1843,4 +1947,4 @@ function getDefaultDependencySnapshotInner(state, visited) {
|
|
|
1843
1947
|
}
|
|
1844
1948
|
|
|
1845
1949
|
//#endregion
|
|
1846
|
-
export { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
|
1950
|
+
export { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectDemandedDependencyIds, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyFingerprint, createDependencyRuntimeContext, createReplayKey, defineForwardedEffectfulSchedulingNodes, derivedRawInputKey, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, guaranteedStaticSourceIdsKey, hasInactiveCompletion, includeSourceFailureChain, orderDependencyNodes, recordDerivedRawInput, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, replayDerivedParser, replayDerivedParserAsync, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.3.0-dev.
|
|
3
|
+
"version": "1.3.0-dev.2581",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
},
|
|
238
238
|
"sideEffects": false,
|
|
239
239
|
"devDependencies": {
|
|
240
|
-
"@optique/env": "1.3.0-dev.
|
|
240
|
+
"@optique/env": "1.3.0-dev.2581+50dd484c",
|
|
241
241
|
"@types/node": "^24.0.0",
|
|
242
242
|
"fast-check": "^4.7.0",
|
|
243
243
|
"tsdown": "^0.13.0",
|