@optique/core 1.3.0-dev.2381 → 1.3.0-dev.2385
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 +34 -10
- package/dist/constructs.js +34 -10
- package/dist/dependency-runtime.cjs +9 -17
- package/dist/dependency-runtime.js +9 -17
- package/dist/facade.cjs +27 -14
- package/dist/facade.js +27 -14
- package/dist/internal/parser.d.cts +3 -3
- package/dist/internal/parser.d.ts +3 -3
- package/package.json +2 -2
package/dist/constructs.cjs
CHANGED
|
@@ -59,6 +59,26 @@ function filterPreCompletedRuntimeNodes(nodes, preCompletedKeys) {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
+
* Filters a construct's runtime nodes for the effectful scheduling pass.
|
|
63
|
+
*
|
|
64
|
+
* A settled Phase 1 pre-completion excludes an *effectful* node: its
|
|
65
|
+
* completion already ran and must not run again. Structural
|
|
66
|
+
* (non-effectful) nodes always stay in the pass, whether pre-completed
|
|
67
|
+
* or not: the scheduler re-registers their extracted values so that
|
|
68
|
+
* registration order follows declaration order across structural and
|
|
69
|
+
* effectful occurrences of a shared source.
|
|
70
|
+
*/
|
|
71
|
+
function filterSchedulableRuntimeNodes(nodes, preCompleted) {
|
|
72
|
+
const settledKeys = settledPreCompletedKeys(preCompleted);
|
|
73
|
+
if (settledKeys.size < 1) return nodes;
|
|
74
|
+
return nodes.filter((node) => {
|
|
75
|
+
if (node.parser.dependencyMetadata?.source?.completeSource == null) return true;
|
|
76
|
+
const segment = node.path.at(-1);
|
|
77
|
+
if (typeof segment === "number") return !settledKeys.has(String(segment));
|
|
78
|
+
return segment == null || !settledKeys.has(segment);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
62
82
|
* Runs the effectful source completion pass for a construct's direct
|
|
63
83
|
* children and merges the completed results into the construct's
|
|
64
84
|
* pre-completed cache so its final completion phase reuses them instead
|
|
@@ -130,7 +150,8 @@ function isDeferredCompletionResult(result) {
|
|
|
130
150
|
function settledPreCompletedKeys(preCompleted) {
|
|
131
151
|
const keys = /* @__PURE__ */ new Set();
|
|
132
152
|
for (const [key, result] of preCompleted) {
|
|
133
|
-
|
|
153
|
+
const completion = require_internal_dependency.isDependencySourceState(result) ? result.result : result;
|
|
154
|
+
if (isDeferredCompletionResult(completion)) continue;
|
|
134
155
|
keys.add(key);
|
|
135
156
|
}
|
|
136
157
|
return keys;
|
|
@@ -145,7 +166,10 @@ function settledPreCompletedKeys(preCompleted) {
|
|
|
145
166
|
* immediately.
|
|
146
167
|
*/
|
|
147
168
|
function firstPreCompletedFailure(preCompleted) {
|
|
148
|
-
for (const result of preCompleted.values())
|
|
169
|
+
for (const result of preCompleted.values()) {
|
|
170
|
+
const completion = require_internal_dependency.isDependencySourceState(result) ? result.result : result;
|
|
171
|
+
if (typeof completion === "object" && completion !== null && "success" in completion && completion.success === false && "error" in completion) return completion.error;
|
|
172
|
+
}
|
|
149
173
|
return void 0;
|
|
150
174
|
}
|
|
151
175
|
async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, preCompleted, demandNodes) {
|
|
@@ -2463,7 +2487,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2463
2487
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path);
|
|
2464
2488
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
2465
2489
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
2466
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
2490
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), annotatedState, runtime, childExec, preCompleted);
|
|
2467
2491
|
if (effectfulFailure != null) return effectfulFailure;
|
|
2468
2492
|
const resolvedFieldStates = await require_dependency_runtime.resolveStateWithRuntimeAsync(annotatedState, runtime);
|
|
2469
2493
|
const result = {};
|
|
@@ -2589,7 +2613,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2589
2613
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path);
|
|
2590
2614
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
2591
2615
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
2592
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
2616
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), annotatedState, runtime, childExec, preCompleted);
|
|
2593
2617
|
if (effectfulFailure != null) return null;
|
|
2594
2618
|
const resolvedFieldStates = await require_dependency_runtime.resolveStateWithRuntimeAsync(annotatedState, runtime);
|
|
2595
2619
|
const result = {};
|
|
@@ -3012,7 +3036,7 @@ function createSeqComplete(parsers, combinedMode) {
|
|
|
3012
3036
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3013
3037
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3014
3038
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3015
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3039
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3016
3040
|
if (effectfulFailure != null) return effectfulFailure;
|
|
3017
3041
|
const phase3Exec = {
|
|
3018
3042
|
...childExec,
|
|
@@ -3507,7 +3531,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
3507
3531
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3508
3532
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3509
3533
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3510
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3534
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3511
3535
|
if (effectfulFailure != null) return effectfulFailure;
|
|
3512
3536
|
const phase3Exec = {
|
|
3513
3537
|
...childExec,
|
|
@@ -3595,7 +3619,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
3595
3619
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3596
3620
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3597
3621
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3598
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3622
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3599
3623
|
if (effectfulFailure != null) return null;
|
|
3600
3624
|
const phase3Exec = {
|
|
3601
3625
|
...childExec,
|
|
@@ -3861,7 +3885,7 @@ function seq(...rawArgs) {
|
|
|
3861
3885
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3862
3886
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3863
3887
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3864
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3888
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3865
3889
|
if (effectfulFailure != null) return null;
|
|
3866
3890
|
const phase3Exec = {
|
|
3867
3891
|
...childExec,
|
|
@@ -5443,7 +5467,7 @@ function concat(...parsers) {
|
|
|
5443
5467
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
5444
5468
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
5445
5469
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
5446
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
5470
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
5447
5471
|
if (effectfulFailure != null) return effectfulFailure;
|
|
5448
5472
|
const phase3Exec = {
|
|
5449
5473
|
...childExec,
|
|
@@ -5551,7 +5575,7 @@ function concat(...parsers) {
|
|
|
5551
5575
|
const allRuntimeNodes = require_dependency_runtime.buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
5552
5576
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
5553
5577
|
await require_dependency_runtime.collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
5554
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
5578
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
5555
5579
|
if (effectfulFailure != null) return null;
|
|
5556
5580
|
const phase3Exec = {
|
|
5557
5581
|
...childExec,
|
package/dist/constructs.js
CHANGED
|
@@ -59,6 +59,26 @@ function filterPreCompletedRuntimeNodes(nodes, preCompletedKeys) {
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
+
* Filters a construct's runtime nodes for the effectful scheduling pass.
|
|
63
|
+
*
|
|
64
|
+
* A settled Phase 1 pre-completion excludes an *effectful* node: its
|
|
65
|
+
* completion already ran and must not run again. Structural
|
|
66
|
+
* (non-effectful) nodes always stay in the pass, whether pre-completed
|
|
67
|
+
* or not: the scheduler re-registers their extracted values so that
|
|
68
|
+
* registration order follows declaration order across structural and
|
|
69
|
+
* effectful occurrences of a shared source.
|
|
70
|
+
*/
|
|
71
|
+
function filterSchedulableRuntimeNodes(nodes, preCompleted) {
|
|
72
|
+
const settledKeys = settledPreCompletedKeys(preCompleted);
|
|
73
|
+
if (settledKeys.size < 1) return nodes;
|
|
74
|
+
return nodes.filter((node) => {
|
|
75
|
+
if (node.parser.dependencyMetadata?.source?.completeSource == null) return true;
|
|
76
|
+
const segment = node.path.at(-1);
|
|
77
|
+
if (typeof segment === "number") return !settledKeys.has(String(segment));
|
|
78
|
+
return segment == null || !settledKeys.has(segment);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
62
82
|
* Runs the effectful source completion pass for a construct's direct
|
|
63
83
|
* children and merges the completed results into the construct's
|
|
64
84
|
* pre-completed cache so its final completion phase reuses them instead
|
|
@@ -130,7 +150,8 @@ function isDeferredCompletionResult(result) {
|
|
|
130
150
|
function settledPreCompletedKeys(preCompleted) {
|
|
131
151
|
const keys = /* @__PURE__ */ new Set();
|
|
132
152
|
for (const [key, result] of preCompleted) {
|
|
133
|
-
|
|
153
|
+
const completion = isDependencySourceState(result) ? result.result : result;
|
|
154
|
+
if (isDeferredCompletionResult(completion)) continue;
|
|
134
155
|
keys.add(key);
|
|
135
156
|
}
|
|
136
157
|
return keys;
|
|
@@ -145,7 +166,10 @@ function settledPreCompletedKeys(preCompleted) {
|
|
|
145
166
|
* immediately.
|
|
146
167
|
*/
|
|
147
168
|
function firstPreCompletedFailure(preCompleted) {
|
|
148
|
-
for (const result of preCompleted.values())
|
|
169
|
+
for (const result of preCompleted.values()) {
|
|
170
|
+
const completion = isDependencySourceState(result) ? result.result : result;
|
|
171
|
+
if (typeof completion === "object" && completion !== null && "success" in completion && completion.success === false && "error" in completion) return completion.error;
|
|
172
|
+
}
|
|
149
173
|
return void 0;
|
|
150
174
|
}
|
|
151
175
|
async function scheduleEffectfulSourceCompletions(nodes, state, runtime, exec, preCompleted, demandNodes) {
|
|
@@ -2463,7 +2487,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2463
2487
|
const allRuntimeNodes = buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path);
|
|
2464
2488
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
2465
2489
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
2466
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
2490
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), annotatedState, runtime, childExec, preCompleted);
|
|
2467
2491
|
if (effectfulFailure != null) return effectfulFailure;
|
|
2468
2492
|
const resolvedFieldStates = await resolveStateWithRuntimeAsync(annotatedState, runtime);
|
|
2469
2493
|
const result = {};
|
|
@@ -2589,7 +2613,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2589
2613
|
const allRuntimeNodes = buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path);
|
|
2590
2614
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
2591
2615
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
2592
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
2616
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), annotatedState, runtime, childExec, preCompleted);
|
|
2593
2617
|
if (effectfulFailure != null) return null;
|
|
2594
2618
|
const resolvedFieldStates = await resolveStateWithRuntimeAsync(annotatedState, runtime);
|
|
2595
2619
|
const result = {};
|
|
@@ -3012,7 +3036,7 @@ function createSeqComplete(parsers, combinedMode) {
|
|
|
3012
3036
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3013
3037
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3014
3038
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3015
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3039
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3016
3040
|
if (effectfulFailure != null) return effectfulFailure;
|
|
3017
3041
|
const phase3Exec = {
|
|
3018
3042
|
...childExec,
|
|
@@ -3507,7 +3531,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
3507
3531
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3508
3532
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3509
3533
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3510
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3534
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3511
3535
|
if (effectfulFailure != null) return effectfulFailure;
|
|
3512
3536
|
const phase3Exec = {
|
|
3513
3537
|
...childExec,
|
|
@@ -3595,7 +3619,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
3595
3619
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3596
3620
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3597
3621
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3598
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3622
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3599
3623
|
if (effectfulFailure != null) return null;
|
|
3600
3624
|
const phase3Exec = {
|
|
3601
3625
|
...childExec,
|
|
@@ -3861,7 +3885,7 @@ function seq(...rawArgs) {
|
|
|
3861
3885
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
3862
3886
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
3863
3887
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
3864
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
3888
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
3865
3889
|
if (effectfulFailure != null) return null;
|
|
3866
3890
|
const phase3Exec = {
|
|
3867
3891
|
...childExec,
|
|
@@ -5443,7 +5467,7 @@ function concat(...parsers) {
|
|
|
5443
5467
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
5444
5468
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
5445
5469
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
5446
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
5470
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
5447
5471
|
if (effectfulFailure != null) return effectfulFailure;
|
|
5448
5472
|
const phase3Exec = {
|
|
5449
5473
|
...childExec,
|
|
@@ -5551,7 +5575,7 @@ function concat(...parsers) {
|
|
|
5551
5575
|
const allRuntimeNodes = buildRuntimeNodesFromArray(parsers, stateArray, exec?.path);
|
|
5552
5576
|
const runtimeNodes = filterPreCompletedRuntimeNodes(allRuntimeNodes, new Set(preCompleted.keys()));
|
|
5553
5577
|
await collectExplicitSourceValuesAsync(runtimeNodes, runtime);
|
|
5554
|
-
const effectfulFailure = await scheduleEffectfulSourceCompletions(
|
|
5578
|
+
const effectfulFailure = await scheduleEffectfulSourceCompletions(filterSchedulableRuntimeNodes(allRuntimeNodes, preCompleted), stateArray, runtime, childExec, preCompleted);
|
|
5555
5579
|
if (effectfulFailure != null) return null;
|
|
5556
5580
|
const phase3Exec = {
|
|
5557
5581
|
...childExec,
|
|
@@ -627,15 +627,16 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
627
627
|
}
|
|
628
628
|
const schedulable = nodes.filter((node) => node.parser.dependencyMetadata?.source?.completeSource != null);
|
|
629
629
|
if (schedulable.length === 0) return empty;
|
|
630
|
-
const preexisting = /* @__PURE__ */ new Set();
|
|
631
|
-
for (const node of schedulable) {
|
|
632
|
-
const source = node.parser.dependencyMetadata?.source;
|
|
633
|
-
if (source != null && runtime.hasSource(source.sourceId) && session?.effectfulSources.has(source.sourceId) !== true) preexisting.add(source.sourceId);
|
|
634
|
-
}
|
|
635
630
|
const completed = [];
|
|
636
|
-
for (const node of
|
|
631
|
+
for (const node of nodes) {
|
|
637
632
|
const source = node.parser.dependencyMetadata?.source;
|
|
638
|
-
if (source
|
|
633
|
+
if (source == null) continue;
|
|
634
|
+
if (source.completeSource == null) {
|
|
635
|
+
if (source.extractSourceValue == null || (options?.isReusable?.(node) ?? true) === false) continue;
|
|
636
|
+
const extracted = await source.extractSourceValue(node.state);
|
|
637
|
+
if (extracted?.success === true && extracted.value !== void 0) runtime.registerSource(source.sourceId, extracted.value);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
639
640
|
const pathKey = serializeSchedulingPath(node.path);
|
|
640
641
|
const priorResult = session?.completedByPath.get(pathKey);
|
|
641
642
|
if (priorResult != null) {
|
|
@@ -645,7 +646,6 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
645
646
|
});
|
|
646
647
|
continue;
|
|
647
648
|
}
|
|
648
|
-
if (preexisting.has(source.sourceId)) continue;
|
|
649
649
|
const reusable = source.preservesSourceValue && (options?.isReusable?.(node) ?? true);
|
|
650
650
|
if (!reusable && session == null) continue;
|
|
651
651
|
const childExec = {
|
|
@@ -679,15 +679,7 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
679
679
|
* length-prefixed segments so no separator escaping is needed.
|
|
680
680
|
*/
|
|
681
681
|
function serializeSchedulingPath(path) {
|
|
682
|
-
return path.map((
|
|
683
|
-
if (typeof segment === "symbol") {
|
|
684
|
-
const key = stableSymbolKey(segment);
|
|
685
|
-
return `y${key.length}:${key}`;
|
|
686
|
-
}
|
|
687
|
-
const tag = typeof segment === "number" ? "n" : "s";
|
|
688
|
-
const text = String(segment);
|
|
689
|
-
return `${tag}${text.length}:${text}`;
|
|
690
|
-
}).join("");
|
|
682
|
+
return path.map(serializePathSegment).join("");
|
|
691
683
|
}
|
|
692
684
|
/**
|
|
693
685
|
* Checks if a value is a plain object (not a class instance) for the
|
|
@@ -627,15 +627,16 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
627
627
|
}
|
|
628
628
|
const schedulable = nodes.filter((node) => node.parser.dependencyMetadata?.source?.completeSource != null);
|
|
629
629
|
if (schedulable.length === 0) return empty;
|
|
630
|
-
const preexisting = /* @__PURE__ */ new Set();
|
|
631
|
-
for (const node of schedulable) {
|
|
632
|
-
const source = node.parser.dependencyMetadata?.source;
|
|
633
|
-
if (source != null && runtime.hasSource(source.sourceId) && session?.effectfulSources.has(source.sourceId) !== true) preexisting.add(source.sourceId);
|
|
634
|
-
}
|
|
635
630
|
const completed = [];
|
|
636
|
-
for (const node of
|
|
631
|
+
for (const node of nodes) {
|
|
637
632
|
const source = node.parser.dependencyMetadata?.source;
|
|
638
|
-
if (source
|
|
633
|
+
if (source == null) continue;
|
|
634
|
+
if (source.completeSource == null) {
|
|
635
|
+
if (source.extractSourceValue == null || (options?.isReusable?.(node) ?? true) === false) continue;
|
|
636
|
+
const extracted = await source.extractSourceValue(node.state);
|
|
637
|
+
if (extracted?.success === true && extracted.value !== void 0) runtime.registerSource(source.sourceId, extracted.value);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
639
640
|
const pathKey = serializeSchedulingPath(node.path);
|
|
640
641
|
const priorResult = session?.completedByPath.get(pathKey);
|
|
641
642
|
if (priorResult != null) {
|
|
@@ -645,7 +646,6 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
645
646
|
});
|
|
646
647
|
continue;
|
|
647
648
|
}
|
|
648
|
-
if (preexisting.has(source.sourceId)) continue;
|
|
649
649
|
const reusable = source.preservesSourceValue && (options?.isReusable?.(node) ?? true);
|
|
650
650
|
if (!reusable && session == null) continue;
|
|
651
651
|
const childExec = {
|
|
@@ -679,15 +679,7 @@ async function completeEffectfulSourcesAsync(nodes, state, runtime, exec, option
|
|
|
679
679
|
* length-prefixed segments so no separator escaping is needed.
|
|
680
680
|
*/
|
|
681
681
|
function serializeSchedulingPath(path) {
|
|
682
|
-
return path.map((
|
|
683
|
-
if (typeof segment === "symbol") {
|
|
684
|
-
const key = stableSymbolKey(segment);
|
|
685
|
-
return `y${key.length}:${key}`;
|
|
686
|
-
}
|
|
687
|
-
const tag = typeof segment === "number" ? "n" : "s";
|
|
688
|
-
const text = String(segment);
|
|
689
|
-
return `${tag}${text.length}:${text}`;
|
|
690
|
-
}).join("");
|
|
682
|
+
return path.map(serializePathSegment).join("");
|
|
691
683
|
}
|
|
692
684
|
/**
|
|
693
685
|
* Checks if a value is a plain object (not a class instance) for the
|
package/dist/facade.cjs
CHANGED
|
@@ -126,6 +126,31 @@ function withEffectfulSessionOption(options, session) {
|
|
|
126
126
|
[effectfulSessionOptionsKey]: session
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates the run-scoped effectful completion sessions shared by a
|
|
131
|
+
* `runWith()` two-phase run, so an effectful source (e.g., a prompt)
|
|
132
|
+
* runs at most once per invocation. The seed pass uses the demand-only
|
|
133
|
+
* policy: an effectful source completes there only when a phase-one
|
|
134
|
+
* consumer demands its value; others defer to the final pass. The
|
|
135
|
+
* final pass shares the run-scoped results cache and demand set, but
|
|
136
|
+
* recomputes structural precedence from scratch: phase-two annotations
|
|
137
|
+
* may introduce environment/configuration values that must win over a
|
|
138
|
+
* cached seed prompt answer, so the effectful-source markers do not
|
|
139
|
+
* carry over.
|
|
140
|
+
*/
|
|
141
|
+
function createRunWithSessions() {
|
|
142
|
+
const seedSession = require_internal_parser.createEffectfulCompletionSession("demand-only");
|
|
143
|
+
const finalSession = {
|
|
144
|
+
...seedSession,
|
|
145
|
+
policy: "eager",
|
|
146
|
+
effectfulSources: /* @__PURE__ */ new Set(),
|
|
147
|
+
completedByPath: /* @__PURE__ */ new Map()
|
|
148
|
+
};
|
|
149
|
+
return {
|
|
150
|
+
seedSession,
|
|
151
|
+
finalSession
|
|
152
|
+
};
|
|
153
|
+
}
|
|
129
154
|
function createCompleteExec(exec, context, session) {
|
|
130
155
|
const runtime = require_dependency_runtime.createDependencyRuntimeContext();
|
|
131
156
|
return {
|
|
@@ -1615,13 +1640,7 @@ async function runWithBody(parser, programName, contexts, args, options) {
|
|
|
1615
1640
|
if (parser.mode === "async") return runParser(augmentedParser1, programName, args, options);
|
|
1616
1641
|
return Promise.resolve(runParser(augmentedParser1, programName, args, options));
|
|
1617
1642
|
}
|
|
1618
|
-
const seedSession =
|
|
1619
|
-
const finalSession = {
|
|
1620
|
-
...seedSession,
|
|
1621
|
-
policy: "eager",
|
|
1622
|
-
effectfulSources: /* @__PURE__ */ new Set(),
|
|
1623
|
-
completedByPath: /* @__PURE__ */ new Map()
|
|
1624
|
-
};
|
|
1643
|
+
const { seedSession, finalSession } = createRunWithSessions();
|
|
1625
1644
|
const sessionOptions = withEffectfulSessionOption(options, finalSession);
|
|
1626
1645
|
const firstPassSeed = await require_mode_dispatch.dispatchByMode(parser.mode, () => extractPhase2SeedSync(augmentedParser1, args, seedSession), () => extractPhase2SeedAsync(augmentedParser1, args, seedSession));
|
|
1627
1646
|
if (firstPassSeed == null) {
|
|
@@ -1738,13 +1757,7 @@ function runWithSyncBody(parser, programName, contexts, args, options) {
|
|
|
1738
1757
|
}
|
|
1739
1758
|
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1740
1759
|
if (!needsTwoPhase) return runParser(augmentedParser1, programName, args, options);
|
|
1741
|
-
const seedSession =
|
|
1742
|
-
const finalSession = {
|
|
1743
|
-
...seedSession,
|
|
1744
|
-
policy: "eager",
|
|
1745
|
-
effectfulSources: /* @__PURE__ */ new Set(),
|
|
1746
|
-
completedByPath: /* @__PURE__ */ new Map()
|
|
1747
|
-
};
|
|
1760
|
+
const { seedSession, finalSession } = createRunWithSessions();
|
|
1748
1761
|
const sessionOptions = withEffectfulSessionOption(options, finalSession);
|
|
1749
1762
|
const firstPassSeed = extractPhase2SeedSync(augmentedParser1, args, seedSession);
|
|
1750
1763
|
if (firstPassSeed == null) {
|
package/dist/facade.js
CHANGED
|
@@ -126,6 +126,31 @@ function withEffectfulSessionOption(options, session) {
|
|
|
126
126
|
[effectfulSessionOptionsKey]: session
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates the run-scoped effectful completion sessions shared by a
|
|
131
|
+
* `runWith()` two-phase run, so an effectful source (e.g., a prompt)
|
|
132
|
+
* runs at most once per invocation. The seed pass uses the demand-only
|
|
133
|
+
* policy: an effectful source completes there only when a phase-one
|
|
134
|
+
* consumer demands its value; others defer to the final pass. The
|
|
135
|
+
* final pass shares the run-scoped results cache and demand set, but
|
|
136
|
+
* recomputes structural precedence from scratch: phase-two annotations
|
|
137
|
+
* may introduce environment/configuration values that must win over a
|
|
138
|
+
* cached seed prompt answer, so the effectful-source markers do not
|
|
139
|
+
* carry over.
|
|
140
|
+
*/
|
|
141
|
+
function createRunWithSessions() {
|
|
142
|
+
const seedSession = createEffectfulCompletionSession("demand-only");
|
|
143
|
+
const finalSession = {
|
|
144
|
+
...seedSession,
|
|
145
|
+
policy: "eager",
|
|
146
|
+
effectfulSources: /* @__PURE__ */ new Set(),
|
|
147
|
+
completedByPath: /* @__PURE__ */ new Map()
|
|
148
|
+
};
|
|
149
|
+
return {
|
|
150
|
+
seedSession,
|
|
151
|
+
finalSession
|
|
152
|
+
};
|
|
153
|
+
}
|
|
129
154
|
function createCompleteExec(exec, context, session) {
|
|
130
155
|
const runtime = createDependencyRuntimeContext();
|
|
131
156
|
return {
|
|
@@ -1615,13 +1640,7 @@ async function runWithBody(parser, programName, contexts, args, options) {
|
|
|
1615
1640
|
if (parser.mode === "async") return runParser(augmentedParser1, programName, args, options);
|
|
1616
1641
|
return Promise.resolve(runParser(augmentedParser1, programName, args, options));
|
|
1617
1642
|
}
|
|
1618
|
-
const seedSession =
|
|
1619
|
-
const finalSession = {
|
|
1620
|
-
...seedSession,
|
|
1621
|
-
policy: "eager",
|
|
1622
|
-
effectfulSources: /* @__PURE__ */ new Set(),
|
|
1623
|
-
completedByPath: /* @__PURE__ */ new Map()
|
|
1624
|
-
};
|
|
1643
|
+
const { seedSession, finalSession } = createRunWithSessions();
|
|
1625
1644
|
const sessionOptions = withEffectfulSessionOption(options, finalSession);
|
|
1626
1645
|
const firstPassSeed = await dispatchByMode(parser.mode, () => extractPhase2SeedSync(augmentedParser1, args, seedSession), () => extractPhase2SeedAsync(augmentedParser1, args, seedSession));
|
|
1627
1646
|
if (firstPassSeed == null) {
|
|
@@ -1738,13 +1757,7 @@ function runWithSyncBody(parser, programName, contexts, args, options) {
|
|
|
1738
1757
|
}
|
|
1739
1758
|
const augmentedParser1 = injectAnnotationsIntoParser(parser, phase1Annotations);
|
|
1740
1759
|
if (!needsTwoPhase) return runParser(augmentedParser1, programName, args, options);
|
|
1741
|
-
const seedSession =
|
|
1742
|
-
const finalSession = {
|
|
1743
|
-
...seedSession,
|
|
1744
|
-
policy: "eager",
|
|
1745
|
-
effectfulSources: /* @__PURE__ */ new Set(),
|
|
1746
|
-
completedByPath: /* @__PURE__ */ new Map()
|
|
1747
|
-
};
|
|
1760
|
+
const { seedSession, finalSession } = createRunWithSessions();
|
|
1748
1761
|
const sessionOptions = withEffectfulSessionOption(options, finalSession);
|
|
1749
1762
|
const firstPassSeed = extractPhase2SeedSync(augmentedParser1, args, seedSession);
|
|
1750
1763
|
if (firstPassSeed == null) {
|
|
@@ -419,9 +419,9 @@ type ExecutionPhase = "parse" | "precomplete" | "resolve" | "complete" | "sugges
|
|
|
419
419
|
* run, shared by the phase-two seed pass and the final pass) and threaded
|
|
420
420
|
* through {@link ExecutionContext}. It guarantees that an effectful source
|
|
421
421
|
* completion runs at most once per run: the completion result is cached by
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* when the run ends.
|
|
422
|
+
* completion occurrence (see {@link EffectfulCompletionSession.results}),
|
|
423
|
+
* and a cache hit is returned without repeating the effect. Results never
|
|
424
|
+
* leak between runs because the session is discarded when the run ends.
|
|
425
425
|
*
|
|
426
426
|
* @internal
|
|
427
427
|
* @since 1.3.0
|
|
@@ -419,9 +419,9 @@ type ExecutionPhase = "parse" | "precomplete" | "resolve" | "complete" | "sugges
|
|
|
419
419
|
* run, shared by the phase-two seed pass and the final pass) and threaded
|
|
420
420
|
* through {@link ExecutionContext}. It guarantees that an effectful source
|
|
421
421
|
* completion runs at most once per run: the completion result is cached by
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
* when the run ends.
|
|
422
|
+
* completion occurrence (see {@link EffectfulCompletionSession.results}),
|
|
423
|
+
* and a cache hit is returned without repeating the effect. Results never
|
|
424
|
+
* leak between runs because the session is discarded when the run ends.
|
|
425
425
|
*
|
|
426
426
|
* @internal
|
|
427
427
|
* @since 1.3.0
|
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.2385",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
"sideEffects": false,
|
|
223
223
|
"devDependencies": {
|
|
224
|
-
"@optique/env": "1.3.0-dev.
|
|
224
|
+
"@optique/env": "1.3.0-dev.2385+011936e3",
|
|
225
225
|
"@types/node": "^24.0.0",
|
|
226
226
|
"fast-check": "^4.7.0",
|
|
227
227
|
"tsdown": "^0.13.0",
|