@optique/core 1.0.0-dev.1776 → 1.0.0-dev.1785

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.
@@ -5,6 +5,7 @@ import { validateLabel } from "./validate.js";
5
5
  import { extractArgumentMetavars, extractCommandNames, extractOptionNames, isDocHidden, mergeHidden } from "./usage.js";
6
6
  import { deduplicateDocFragments } from "./doc.js";
7
7
  import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
8
+ import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
8
9
  import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, findSimilar } from "./suggestion.js";
9
10
  import { collectLeadingCandidates } from "./usage-internals.js";
10
11
  import { defineInheritedAnnotationParser, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "./parser.js";
@@ -26,6 +27,21 @@ function withChildExecPath(exec, segment) {
26
27
  path: [...exec.path ?? [], segment]
27
28
  };
28
29
  }
30
+ function withDependencyRuntimeExec(usage, exec, runtime) {
31
+ if (exec == null) return {
32
+ usage,
33
+ phase: "complete",
34
+ path: [],
35
+ trace: void 0,
36
+ dependencyRuntime: runtime,
37
+ dependencyRegistry: runtime.registry
38
+ };
39
+ return {
40
+ ...exec,
41
+ dependencyRuntime: runtime,
42
+ dependencyRegistry: runtime.registry
43
+ };
44
+ }
29
45
  function mergeChildExec(parent, child) {
30
46
  if (parent == null) return child;
31
47
  if (child == null) return parent;
@@ -199,6 +215,69 @@ function unwrapCompleteResult(result) {
199
215
  value
200
216
  };
201
217
  }
218
+ function reusePreCompletedPhase2Seed(parser, state, preCompletedResult, exec) {
219
+ const result = unwrapCompleteResult(preCompletedResult);
220
+ return result.success ? phase2SeedFromValueResult(result) : extractPhase2Seed(parser, state, exec);
221
+ }
222
+ async function reusePreCompletedPhase2SeedAsync(parser, state, preCompletedResult, exec) {
223
+ const result = unwrapCompleteResult(preCompletedResult);
224
+ return result.success ? phase2SeedFromValueResult(result) : await extractPhase2Seed(parser, state, exec);
225
+ }
226
+ function extractOrCompletePhase2SeedSync(parser, state, exec) {
227
+ const extracted = extractPhase2Seed(parser, state, exec);
228
+ if (extracted != null) return extracted;
229
+ const result = parser.complete(state, exec);
230
+ return result.success ? phase2SeedFromValueResult(result) : null;
231
+ }
232
+ async function extractOrCompletePhase2SeedAsync(parser, state, exec) {
233
+ const extracted = await extractPhase2Seed(parser, state, exec);
234
+ if (extracted != null) return extracted;
235
+ const result = await parser.complete(state, exec);
236
+ return result.success ? phase2SeedFromValueResult(result) : null;
237
+ }
238
+ function appendFlattenedPhase2Seed(results, deferredKeys, seed) {
239
+ const baseIndex = results.length;
240
+ if (Array.isArray(seed.value)) {
241
+ results.push(...seed.value);
242
+ if (seed.deferred && seed.deferredKeys) {
243
+ for (const [key, value] of seed.deferredKeys) {
244
+ const numKey = typeof key === "string" ? Number(key) : key;
245
+ if (typeof numKey === "number" && Number.isInteger(numKey)) deferredKeys.set(baseIndex + numKey, value);
246
+ else deferredKeys.set(key, value);
247
+ }
248
+ return false;
249
+ }
250
+ return seed.deferred === true;
251
+ }
252
+ results.push(seed.value);
253
+ if (seed.deferred && seed.deferredKeys) {
254
+ deferredKeys.set(baseIndex, seed.deferredKeys);
255
+ return false;
256
+ }
257
+ if (seed.deferred && (seed.value == null || typeof seed.value !== "object")) {
258
+ deferredKeys.set(baseIndex, null);
259
+ return false;
260
+ }
261
+ return seed.deferred === true;
262
+ }
263
+ function combineTuplePhase2Seeds(first, second) {
264
+ if (first == null && second == null) return null;
265
+ const deferredKeys = /* @__PURE__ */ new Map();
266
+ let hasDeferred = false;
267
+ if (first?.deferred) if (first.deferredKeys) deferredKeys.set(0, first.deferredKeys);
268
+ else if (first.value == null || typeof first.value !== "object") deferredKeys.set(0, null);
269
+ else hasDeferred = true;
270
+ if (second?.deferred) if (second.deferredKeys) deferredKeys.set(1, second.deferredKeys);
271
+ else if (second.value == null || typeof second.value !== "object") deferredKeys.set(1, null);
272
+ else hasDeferred = true;
273
+ return {
274
+ value: [first?.value, second?.value],
275
+ ...deferredKeys.size > 0 || hasDeferred ? {
276
+ deferred: true,
277
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
278
+ } : {}
279
+ };
280
+ }
202
281
  /**
203
282
  * Prepares a field state for completion by wrapping `undefined` state
204
283
  * with the parser's initial pending dependency state when needed.
@@ -513,70 +592,22 @@ function createExclusiveComplete(parsers, options, noMatchContext, mode) {
513
592
  return (state, exec) => {
514
593
  const activeState = normalizeExclusiveState(state);
515
594
  if (activeState == null) return dispatchByMode(mode, () => {
516
- const emptyCtx = {
517
- buffer: [],
518
- optionsTerminated: false,
519
- usage: [],
520
- exec,
521
- dependencyRegistry: exec?.dependencyRegistry
522
- };
523
- let candidateIndex = -1;
524
- let candidateCount = 0;
525
- let candidateParseResult;
526
- for (let i$1 = 0; i$1 < syncParsers.length; i$1++) {
527
- const p = syncParsers[i$1];
528
- if (p.leadingNames.size > 0 || p.acceptingAnyToken) continue;
529
- const parseResult = p.parse({
530
- ...emptyCtx,
531
- state: getAnnotatedChildState(state, p.initialState, p)
532
- });
533
- if (!parseResult.success || parseResult.provisional) continue;
534
- candidateCount++;
535
- if (candidateIndex < 0) {
536
- candidateIndex = i$1;
537
- candidateParseResult = parseResult;
538
- }
539
- if (candidateCount > 1) break;
540
- }
541
- if (candidateCount === 1 && candidateIndex >= 0 && candidateParseResult) {
542
- const p = syncParsers[candidateIndex];
543
- const annotatedState = getAnnotatedChildState(state, candidateParseResult.next.state, p);
544
- return p.complete(annotatedState, withChildExecPath(exec, candidateIndex));
595
+ const candidate = findExclusiveZeroInputCandidateSync(syncParsers, state, exec);
596
+ if (candidate != null) {
597
+ const p = syncParsers[candidate.index];
598
+ const annotatedState = getAnnotatedChildState(state, candidate.parseResult.next.state, p);
599
+ return p.complete(annotatedState, withChildExecPath(exec, candidate.index));
545
600
  }
546
601
  return {
547
602
  success: false,
548
603
  error: getNoMatchError(options, noMatchContext)
549
604
  };
550
605
  }, async () => {
551
- const emptyCtx = {
552
- buffer: [],
553
- optionsTerminated: false,
554
- usage: [],
555
- exec,
556
- dependencyRegistry: exec?.dependencyRegistry
557
- };
558
- let candidateIndex = -1;
559
- let candidateCount = 0;
560
- let candidateParseResult;
561
- for (let i$1 = 0; i$1 < parsers.length; i$1++) {
562
- const p = parsers[i$1];
563
- if (p.leadingNames.size > 0 || p.acceptingAnyToken) continue;
564
- const parseResult = await p.parse({
565
- ...emptyCtx,
566
- state: getAnnotatedChildState(state, p.initialState, p)
567
- });
568
- if (!parseResult.success || parseResult.provisional) continue;
569
- candidateCount++;
570
- if (candidateIndex < 0) {
571
- candidateIndex = i$1;
572
- candidateParseResult = parseResult;
573
- }
574
- if (candidateCount > 1) break;
575
- }
576
- if (candidateCount === 1 && candidateIndex >= 0 && candidateParseResult && (parsers[candidateIndex].$mode === "sync" || exec?.phase !== "parse" && exec?.phase !== "suggest")) {
577
- const p = parsers[candidateIndex];
578
- const annotatedState = getAnnotatedChildState(state, candidateParseResult.next.state, p);
579
- return await p.complete(annotatedState, withChildExecPath(exec, candidateIndex));
606
+ const candidate = await findExclusiveZeroInputCandidateAsync(parsers, state, exec);
607
+ if (candidate != null && (parsers[candidate.index].$mode === "sync" || exec?.phase !== "parse" && exec?.phase !== "suggest")) {
608
+ const p = parsers[candidate.index];
609
+ const annotatedState = getAnnotatedChildState(state, candidate.parseResult.next.state, p);
610
+ return await p.complete(annotatedState, withChildExecPath(exec, candidate.index));
580
611
  }
581
612
  return {
582
613
  success: false,
@@ -648,6 +679,83 @@ function getExclusiveSuggestRuntimeNodes(parsers, state, path) {
648
679
  const parser = parsers[index];
649
680
  return getParserSuggestRuntimeNodes(parser, parserResult.next.state, [...path, index]);
650
681
  }
682
+ function findExclusiveZeroInputCandidateSync(parsers, state, exec) {
683
+ const emptyCtx = {
684
+ buffer: [],
685
+ optionsTerminated: false,
686
+ usage: [],
687
+ exec,
688
+ dependencyRegistry: exec?.dependencyRegistry
689
+ };
690
+ let candidateIndex = -1;
691
+ let candidateCount = 0;
692
+ let candidateParseResult;
693
+ for (let i = 0; i < parsers.length; i++) {
694
+ const parser = parsers[i];
695
+ if (parser.leadingNames.size > 0 || parser.acceptingAnyToken) continue;
696
+ const parseResult = parser.parse({
697
+ ...emptyCtx,
698
+ state: getAnnotatedChildState(state, parser.initialState, parser)
699
+ });
700
+ if (!parseResult.success || parseResult.provisional) continue;
701
+ candidateCount++;
702
+ if (candidateIndex < 0) {
703
+ candidateIndex = i;
704
+ candidateParseResult = parseResult;
705
+ }
706
+ if (candidateCount > 1) break;
707
+ }
708
+ return candidateCount === 1 && candidateIndex >= 0 && candidateParseResult != null ? {
709
+ index: candidateIndex,
710
+ parseResult: candidateParseResult
711
+ } : null;
712
+ }
713
+ async function findExclusiveZeroInputCandidateAsync(parsers, state, exec) {
714
+ const emptyCtx = {
715
+ buffer: [],
716
+ optionsTerminated: false,
717
+ usage: [],
718
+ exec,
719
+ dependencyRegistry: exec?.dependencyRegistry
720
+ };
721
+ let candidateIndex = -1;
722
+ let candidateCount = 0;
723
+ let candidateParseResult;
724
+ for (let i = 0; i < parsers.length; i++) {
725
+ const parser = parsers[i];
726
+ if (parser.leadingNames.size > 0 || parser.acceptingAnyToken) continue;
727
+ const parseResult = await parser.parse({
728
+ ...emptyCtx,
729
+ state: getAnnotatedChildState(state, parser.initialState, parser)
730
+ });
731
+ if (!parseResult.success || parseResult.provisional) continue;
732
+ candidateCount++;
733
+ if (candidateIndex < 0) {
734
+ candidateIndex = i;
735
+ candidateParseResult = parseResult;
736
+ }
737
+ if (candidateCount > 1) break;
738
+ }
739
+ return candidateCount === 1 && candidateIndex >= 0 && candidateParseResult != null ? {
740
+ index: candidateIndex,
741
+ parseResult: candidateParseResult
742
+ } : null;
743
+ }
744
+ function extractExclusivePhase2Seed(parsers, state, exec, mode) {
745
+ const activeState = normalizeExclusiveState(state);
746
+ if (activeState == null) return dispatchByMode(mode, () => {
747
+ const candidate = findExclusiveZeroInputCandidateSync(parsers, state, exec);
748
+ if (candidate == null) return null;
749
+ return extractOrCompletePhase2SeedSync(parsers[candidate.index], candidate.parseResult.next.state, withChildExecPath(exec, candidate.index));
750
+ }, async () => {
751
+ const candidate = await findExclusiveZeroInputCandidateAsync(parsers, state, exec);
752
+ if (candidate == null) return null;
753
+ return await extractOrCompletePhase2SeedAsync(parsers[candidate.index], candidate.parseResult.next.state, withChildExecPath(exec, candidate.index));
754
+ });
755
+ if (!activeState[1].success) return dispatchByMode(mode, () => null, () => Promise.resolve(null));
756
+ const [index, parserResult] = activeState;
757
+ return completeOrExtractPhase2Seed(parsers[index], parserResult.next.state, withChildExecPath(exec, index));
758
+ }
651
759
  /**
652
760
  * Gets the no-match error, either from custom options or default.
653
761
  * Shared by or() and longestMatch().
@@ -1112,6 +1220,9 @@ function or(...args) {
1112
1220
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
1113
1221
  initialState: void 0,
1114
1222
  complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
1223
+ [extractPhase2SeedKey](state, exec) {
1224
+ return extractExclusivePhase2Seed(parsers, state, exec, combinedMode);
1225
+ },
1115
1226
  parse(context) {
1116
1227
  return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
1117
1228
  },
@@ -1272,6 +1383,9 @@ function longestMatch(...args) {
1272
1383
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
1273
1384
  initialState: void 0,
1274
1385
  complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
1386
+ [extractPhase2SeedKey](state, exec) {
1387
+ return extractExclusivePhase2Seed(parsers, state, exec, combinedMode);
1388
+ },
1275
1389
  parse(context) {
1276
1390
  return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
1277
1391
  },
@@ -2072,6 +2186,95 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2072
2186
  };
2073
2187
  });
2074
2188
  },
2189
+ [extractPhase2SeedKey](state, exec) {
2190
+ return dispatchByMode(combinedMode, () => {
2191
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2192
+ const childExec = withDependencyRuntimeExec(objectParser.usage, exec, runtime);
2193
+ const typedParserPairs = filterExcludedFieldParsers(parserPairs, exec?.excludedSourceFields);
2194
+ const preCompleted = preCompleteAndRegisterDependencies(state, typedParserPairs, runtime.registry, childExec);
2195
+ const phase3Exec = {
2196
+ ...childExec,
2197
+ preCompletedByParser: void 0
2198
+ };
2199
+ const getFieldState = createFieldStateGetter(state);
2200
+ const annotatedState = {};
2201
+ for (const field of parserKeys) {
2202
+ const fieldKey = field;
2203
+ const fieldParser = parsers[field];
2204
+ annotatedState[fieldKey] = getFieldState(field, fieldParser);
2205
+ }
2206
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromPairs(typedParserPairs, annotatedState, exec?.path), new Set(preCompleted.keys())), runtime);
2207
+ const resolvedFieldStates = resolveStateWithRuntime(annotatedState, runtime);
2208
+ const result = {};
2209
+ const deferredKeys = /* @__PURE__ */ new Map();
2210
+ let hasDeferred = false;
2211
+ let hasAnySeed = false;
2212
+ for (const field of parserKeys) {
2213
+ const fieldKey = field;
2214
+ const fieldParser = parsers[field];
2215
+ const childExec$1 = withChildExecPath(phase3Exec, fieldKey);
2216
+ const preCompletedResult = preCompleted.get(fieldKey);
2217
+ const seed = preCompletedResult !== void 0 ? reusePreCompletedPhase2Seed(fieldParser, resolvedFieldStates[fieldKey], preCompletedResult, childExec$1) : completeOrExtractPhase2Seed(fieldParser, resolvedFieldStates[fieldKey], childExec$1);
2218
+ if (seed == null) continue;
2219
+ hasAnySeed = true;
2220
+ result[fieldKey] = seed.value;
2221
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(fieldKey, seed.deferredKeys);
2222
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(fieldKey, null);
2223
+ else hasDeferred = true;
2224
+ }
2225
+ if (!hasAnySeed) return null;
2226
+ return {
2227
+ value: result,
2228
+ ...deferredKeys.size > 0 || hasDeferred ? {
2229
+ deferred: true,
2230
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2231
+ } : {}
2232
+ };
2233
+ }, async () => {
2234
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2235
+ const childExec = withDependencyRuntimeExec(objectParser.usage, exec, runtime);
2236
+ const asyncParserPairs = filterExcludedFieldParsers(parserPairs, exec?.excludedSourceFields);
2237
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, asyncParserPairs, runtime.registry, childExec);
2238
+ const phase3Exec = {
2239
+ ...childExec,
2240
+ preCompletedByParser: void 0
2241
+ };
2242
+ const getFieldState = createFieldStateGetter(state);
2243
+ const annotatedState = {};
2244
+ for (const field of parserKeys) {
2245
+ const fieldKey = field;
2246
+ const fieldParser = parsers[field];
2247
+ annotatedState[fieldKey] = getFieldState(field, fieldParser);
2248
+ }
2249
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path), new Set(preCompleted.keys())), runtime);
2250
+ const resolvedFieldStates = await resolveStateWithRuntimeAsync(annotatedState, runtime);
2251
+ const result = {};
2252
+ const deferredKeys = /* @__PURE__ */ new Map();
2253
+ let hasDeferred = false;
2254
+ let hasAnySeed = false;
2255
+ for (const field of parserKeys) {
2256
+ const fieldKey = field;
2257
+ const fieldParser = parsers[field];
2258
+ const childExec$1 = withChildExecPath(phase3Exec, fieldKey);
2259
+ const preCompletedResult = preCompleted.get(fieldKey);
2260
+ const seed = preCompletedResult !== void 0 ? await reusePreCompletedPhase2SeedAsync(fieldParser, resolvedFieldStates[fieldKey], preCompletedResult, childExec$1) : await completeOrExtractPhase2Seed(fieldParser, resolvedFieldStates[fieldKey], childExec$1);
2261
+ if (seed == null) continue;
2262
+ hasAnySeed = true;
2263
+ result[fieldKey] = seed.value;
2264
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(fieldKey, seed.deferredKeys);
2265
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(fieldKey, null);
2266
+ else hasDeferred = true;
2267
+ }
2268
+ if (!hasAnySeed) return null;
2269
+ return {
2270
+ value: result,
2271
+ ...deferredKeys.size > 0 || hasDeferred ? {
2272
+ deferred: true,
2273
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2274
+ } : {}
2275
+ };
2276
+ });
2277
+ },
2075
2278
  suggest(context, prefix) {
2076
2279
  if (options.hidden === true) return dispatchIterableByMode(combinedMode, function* () {}, async function* () {});
2077
2280
  return dispatchIterableByMode(combinedMode, () => {
@@ -2624,6 +2827,83 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2624
2827
  };
2625
2828
  });
2626
2829
  },
2830
+ [extractPhase2SeedKey](state, exec) {
2831
+ return dispatchByMode(combinedMode, () => {
2832
+ const stateArray = state;
2833
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2834
+ const childExec = withDependencyRuntimeExec(tupleParser.usage, exec, runtime);
2835
+ const tuplePairs = buildIndexedParserPairs(syncParsers);
2836
+ const tupleState = createAnnotatedArrayStateRecord(stateArray);
2837
+ const preCompleted = preCompleteAndRegisterDependencies(tupleState, tuplePairs, runtime.registry, childExec);
2838
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
2839
+ const phase3Exec = {
2840
+ ...childExec,
2841
+ preCompletedByParser: void 0
2842
+ };
2843
+ const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
2844
+ const result = [];
2845
+ const deferredKeys = /* @__PURE__ */ new Map();
2846
+ let hasDeferred = false;
2847
+ let hasAnySeed = false;
2848
+ for (let i = 0; i < syncParsers.length; i++) {
2849
+ const elementParser = syncParsers[i];
2850
+ const childExec$1 = withChildExecPath(phase3Exec, i);
2851
+ const preCompletedResult = preCompleted.get(String(i));
2852
+ const seed = preCompletedResult !== void 0 ? reusePreCompletedPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), preCompletedResult, childExec$1) : completeOrExtractPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), childExec$1);
2853
+ if (seed == null) continue;
2854
+ hasAnySeed = true;
2855
+ result[i] = seed.value;
2856
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(i, seed.deferredKeys);
2857
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(i, null);
2858
+ else hasDeferred = true;
2859
+ }
2860
+ if (!hasAnySeed) return null;
2861
+ return {
2862
+ value: result,
2863
+ ...deferredKeys.size > 0 || hasDeferred ? {
2864
+ deferred: true,
2865
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2866
+ } : {}
2867
+ };
2868
+ }, async () => {
2869
+ const stateArray = state;
2870
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2871
+ const childExec = withDependencyRuntimeExec(tupleParser.usage, exec, runtime);
2872
+ const tuplePairs = buildIndexedParserPairs(parsers);
2873
+ const tupleState = createAnnotatedArrayStateRecord(stateArray);
2874
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(tupleState, tuplePairs, runtime.registry, childExec);
2875
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
2876
+ const phase3Exec = {
2877
+ ...childExec,
2878
+ preCompletedByParser: void 0
2879
+ };
2880
+ const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
2881
+ const result = [];
2882
+ const deferredKeys = /* @__PURE__ */ new Map();
2883
+ let hasDeferred = false;
2884
+ let hasAnySeed = false;
2885
+ for (let i = 0; i < parsers.length; i++) {
2886
+ const elementParser = parsers[i];
2887
+ const childExec$1 = withChildExecPath(phase3Exec, i);
2888
+ const preCompletedResult = preCompleted.get(String(i));
2889
+ const seed = preCompletedResult !== void 0 ? await reusePreCompletedPhase2SeedAsync(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), preCompletedResult, childExec$1) : await completeOrExtractPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), childExec$1);
2890
+ if (seed == null) continue;
2891
+ hasAnySeed = true;
2892
+ result[i] = seed.value;
2893
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(i, seed.deferredKeys);
2894
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(i, null);
2895
+ else hasDeferred = true;
2896
+ }
2897
+ if (!hasAnySeed) return null;
2898
+ return {
2899
+ value: result,
2900
+ ...deferredKeys.size > 0 || hasDeferred ? {
2901
+ deferred: true,
2902
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2903
+ } : {}
2904
+ };
2905
+ });
2906
+ },
2627
2907
  suggest(context, prefix) {
2628
2908
  return dispatchIterableByMode(combinedMode, () => suggestTupleSync(context, prefix, syncParsers), () => suggestTupleAsync(context, prefix, parsers));
2629
2909
  },
@@ -3015,6 +3295,153 @@ function merge(...args) {
3015
3295
  };
3016
3296
  })();
3017
3297
  },
3298
+ [extractPhase2SeedKey](state, exec) {
3299
+ const extractMergeCompleteState = (parser, resolvedState, index) => {
3300
+ if (parser.initialState === void 0) {
3301
+ const key = parserStateKey(index);
3302
+ if (resolvedState && typeof resolvedState === "object" && key in resolvedState) return resolvedState[key];
3303
+ return void 0;
3304
+ } else if (parser.initialState && typeof parser.initialState === "object") {
3305
+ const key = localObjectStateKey(index);
3306
+ if (shouldPreserveLocalChildState(parser) && resolvedState && typeof resolvedState === "object" && key in resolvedState) return resolvedState[key];
3307
+ if (resolvedState && typeof resolvedState === "object") {
3308
+ const extractedState = {};
3309
+ for (const field in parser.initialState) extractedState[field] = field in resolvedState ? resolvedState[field] : parser.initialState[field];
3310
+ return inheritAnnotations(resolvedState, extractedState);
3311
+ }
3312
+ return parser.initialState;
3313
+ }
3314
+ return parser.initialState;
3315
+ };
3316
+ return dispatchByMode(combinedMode, () => {
3317
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
3318
+ const childExec = withDependencyRuntimeExec(mergeParser.usage, exec, runtime);
3319
+ const duplicateFieldNames = collectDuplicateFieldNames(mergedFieldParsers);
3320
+ const unambiguousFieldParsers = filterDuplicateFieldParsers(mergedFieldParsers);
3321
+ const perChildPhase1 = syncParsers.map((parser, i) => {
3322
+ if (fieldParsersKey in parser) {
3323
+ const pairs = parser[fieldParsersKey];
3324
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames.has(field)));
3325
+ const phase1Pairs = filterExcludedFieldParsers(pairs, excludedSourceFields);
3326
+ const preCompleted = preCompleteAndRegisterDependencies(state, phase1Pairs, runtime.registry, withChildExecPath(childExec, i));
3327
+ return {
3328
+ cache: filterDuplicateKeys(preCompleted, phase1Pairs),
3329
+ excludedSourceFields: excludedSourceFields.size > 0 ? excludedSourceFields : void 0
3330
+ };
3331
+ }
3332
+ return {
3333
+ cache: void 0,
3334
+ excludedSourceFields: void 0
3335
+ };
3336
+ });
3337
+ collectExplicitSourceValues(buildRuntimeNodesFromPairs(unambiguousFieldParsers, state, exec?.path), runtime);
3338
+ const resolvedState = resolveStateWithRuntime(state, runtime);
3339
+ const object$1 = {};
3340
+ const deferredKeys = /* @__PURE__ */ new Map();
3341
+ let hasDeferred = false;
3342
+ let hasAnySeed = false;
3343
+ for (let i = 0; i < syncParsers.length; i++) {
3344
+ const parser = syncParsers[i];
3345
+ const parserState = extractMergeCompleteState(parser, resolvedState, i);
3346
+ const { cache, excludedSourceFields } = perChildPhase1[i];
3347
+ const childCompleteExec = withChildExecPath(childExec, i);
3348
+ const completeExec = excludedSourceFields == null ? {
3349
+ ...childCompleteExec,
3350
+ preCompletedByParser: cache
3351
+ } : (() => {
3352
+ const childRuntime = createDependencyRuntimeContext(runtime.registry.clone());
3353
+ return {
3354
+ ...childCompleteExec,
3355
+ dependencyRuntime: childRuntime,
3356
+ dependencyRegistry: childRuntime.registry,
3357
+ preCompletedByParser: cache
3358
+ };
3359
+ })();
3360
+ const seed = completeOrExtractPhase2Seed(parser, parserState, completeExec);
3361
+ if (seed == null) continue;
3362
+ hasAnySeed = true;
3363
+ const seedValue = seed.value;
3364
+ for (const field in seedValue) {
3365
+ object$1[field] = seedValue[field];
3366
+ if (deferredKeys.has(field) && !(seed.deferred && seed.deferredKeys?.has(field))) deferredKeys.delete(field);
3367
+ }
3368
+ if (seed.deferred && seed.deferredKeys) for (const [key, value] of seed.deferredKeys) deferredKeys.set(key, value);
3369
+ else if (seed.deferred) hasDeferred = true;
3370
+ }
3371
+ if (!hasAnySeed) return null;
3372
+ return {
3373
+ value: object$1,
3374
+ ...deferredKeys.size > 0 || hasDeferred ? {
3375
+ deferred: true,
3376
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
3377
+ } : {}
3378
+ };
3379
+ }, async () => {
3380
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
3381
+ const childExec = withDependencyRuntimeExec(mergeParser.usage, exec, runtime);
3382
+ const duplicateFieldNames = collectDuplicateFieldNames(mergedFieldParsers);
3383
+ const unambiguousFieldParsers = filterDuplicateFieldParsers(mergedFieldParsers);
3384
+ const perChildPhase1 = [];
3385
+ for (let i = 0; i < parsers.length; i++) {
3386
+ const parser = parsers[i];
3387
+ if (fieldParsersKey in parser) {
3388
+ const pairs = parser[fieldParsersKey];
3389
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames.has(field)));
3390
+ const phase1Pairs = filterExcludedFieldParsers(pairs, excludedSourceFields);
3391
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, phase1Pairs, runtime.registry, withChildExecPath(childExec, i));
3392
+ perChildPhase1.push({
3393
+ cache: filterDuplicateKeys(preCompleted, phase1Pairs),
3394
+ excludedSourceFields: excludedSourceFields.size > 0 ? excludedSourceFields : void 0
3395
+ });
3396
+ } else perChildPhase1.push({
3397
+ cache: void 0,
3398
+ excludedSourceFields: void 0
3399
+ });
3400
+ }
3401
+ await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs(unambiguousFieldParsers, state, exec?.path), runtime);
3402
+ const resolvedState = await resolveStateWithRuntimeAsync(state, runtime);
3403
+ const object$1 = {};
3404
+ const deferredKeys = /* @__PURE__ */ new Map();
3405
+ let hasDeferred = false;
3406
+ let hasAnySeed = false;
3407
+ for (let i = 0; i < parsers.length; i++) {
3408
+ const parser = parsers[i];
3409
+ const parserState = extractMergeCompleteState(parser, resolvedState, i);
3410
+ const { cache: asyncCache, excludedSourceFields } = perChildPhase1[i];
3411
+ const childCompleteExec = withChildExecPath(childExec, i);
3412
+ const completeExec = excludedSourceFields == null ? {
3413
+ ...childCompleteExec,
3414
+ preCompletedByParser: asyncCache
3415
+ } : (() => {
3416
+ const childRuntime = createDependencyRuntimeContext(runtime.registry.clone());
3417
+ return {
3418
+ ...childCompleteExec,
3419
+ dependencyRuntime: childRuntime,
3420
+ dependencyRegistry: childRuntime.registry,
3421
+ preCompletedByParser: asyncCache
3422
+ };
3423
+ })();
3424
+ const seed = await completeOrExtractPhase2Seed(parser, parserState, completeExec);
3425
+ if (seed == null) continue;
3426
+ hasAnySeed = true;
3427
+ const seedValue = seed.value;
3428
+ for (const field in seedValue) {
3429
+ object$1[field] = seedValue[field];
3430
+ if (deferredKeys.has(field) && !(seed.deferred && seed.deferredKeys?.has(field))) deferredKeys.delete(field);
3431
+ }
3432
+ if (seed.deferred && seed.deferredKeys) for (const [key, value] of seed.deferredKeys) deferredKeys.set(key, value);
3433
+ else if (seed.deferred) hasDeferred = true;
3434
+ }
3435
+ if (!hasAnySeed) return null;
3436
+ return {
3437
+ value: object$1,
3438
+ ...deferredKeys.size > 0 || hasDeferred ? {
3439
+ deferred: true,
3440
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
3441
+ } : {}
3442
+ };
3443
+ });
3444
+ },
3018
3445
  suggest(context, prefix) {
3019
3446
  if (options.hidden === true) return dispatchIterableByMode(combinedMode, function* () {}, async function* () {});
3020
3447
  const extractState = (p, i) => {
@@ -3663,6 +4090,77 @@ function concat(...parsers) {
3663
4090
  if (isAsync) return completeAsync(state, exec);
3664
4091
  return completeSync(state, exec);
3665
4092
  },
4093
+ [extractPhase2SeedKey](state, exec) {
4094
+ return dispatchByMode(combinedMode, () => {
4095
+ const stateArray = state;
4096
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
4097
+ const childExec = withDependencyRuntimeExec(concatParser.usage, exec, runtime);
4098
+ const concatPairs = buildIndexedParserPairs(syncParsers);
4099
+ const concatState = createAnnotatedArrayStateRecord(stateArray);
4100
+ const preCompleted = preCompleteAndRegisterDependencies(concatState, concatPairs, runtime.registry, childExec);
4101
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
4102
+ const phase3Exec = {
4103
+ ...childExec,
4104
+ preCompletedByParser: void 0
4105
+ };
4106
+ const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
4107
+ const results = [];
4108
+ const deferredKeys = /* @__PURE__ */ new Map();
4109
+ let hasDeferred = false;
4110
+ let hasAnySeed = false;
4111
+ for (let i = 0; i < syncParsers.length; i++) {
4112
+ const parser = syncParsers[i];
4113
+ const childExec$1 = withChildExecPath(phase3Exec, i);
4114
+ const preCompletedResult = preCompleted.get(String(i));
4115
+ const seed = preCompletedResult !== void 0 ? reusePreCompletedPhase2Seed(parser, prepareStateForCompletion(resolvedArray[i], parser), preCompletedResult, childExec$1) : completeOrExtractPhase2Seed(parser, prepareStateForCompletion(resolvedArray[i], parser), childExec$1);
4116
+ if (seed == null) continue;
4117
+ hasAnySeed = true;
4118
+ hasDeferred = appendFlattenedPhase2Seed(results, deferredKeys, seed) || hasDeferred;
4119
+ }
4120
+ if (!hasAnySeed) return null;
4121
+ return {
4122
+ value: results,
4123
+ ...deferredKeys.size > 0 || hasDeferred ? {
4124
+ deferred: true,
4125
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
4126
+ } : {}
4127
+ };
4128
+ }, async () => {
4129
+ const stateArray = state;
4130
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
4131
+ const childExec = withDependencyRuntimeExec(concatParser.usage, exec, runtime);
4132
+ const concatPairs = buildIndexedParserPairs(parsers);
4133
+ const concatState = createAnnotatedArrayStateRecord(stateArray);
4134
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(concatState, concatPairs, runtime.registry, childExec);
4135
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
4136
+ const phase3Exec = {
4137
+ ...childExec,
4138
+ preCompletedByParser: void 0
4139
+ };
4140
+ const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
4141
+ const results = [];
4142
+ const deferredKeys = /* @__PURE__ */ new Map();
4143
+ let hasDeferred = false;
4144
+ let hasAnySeed = false;
4145
+ for (let i = 0; i < parsers.length; i++) {
4146
+ const parser = parsers[i];
4147
+ const childExec$1 = withChildExecPath(phase3Exec, i);
4148
+ const preCompletedResult = preCompleted.get(String(i));
4149
+ const seed = preCompletedResult !== void 0 ? await reusePreCompletedPhase2SeedAsync(parser, prepareStateForCompletion(resolvedArray[i], parser), preCompletedResult, childExec$1) : await completeOrExtractPhase2Seed(parser, prepareStateForCompletion(resolvedArray[i], parser), childExec$1);
4150
+ if (seed == null) continue;
4151
+ hasAnySeed = true;
4152
+ hasDeferred = appendFlattenedPhase2Seed(results, deferredKeys, seed) || hasDeferred;
4153
+ }
4154
+ if (!hasAnySeed) return null;
4155
+ return {
4156
+ value: results,
4157
+ ...deferredKeys.size > 0 || hasDeferred ? {
4158
+ deferred: true,
4159
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
4160
+ } : {}
4161
+ };
4162
+ });
4163
+ },
3666
4164
  suggest(context, prefix) {
3667
4165
  if (isAsync) return async function* () {
3668
4166
  const preParsedContext$1 = await preParseSuggestContextAsync(context, parsers);
@@ -3783,6 +4281,13 @@ function group(label, parser, options = {}) {
3783
4281
  };
3784
4282
  }
3785
4283
  };
4284
+ Object.defineProperty(groupParser, extractPhase2SeedKey, {
4285
+ value(state, exec) {
4286
+ return extractPhase2Seed(parser, state, exec);
4287
+ },
4288
+ configurable: true,
4289
+ enumerable: false
4290
+ });
3786
4291
  if ("placeholder" in parser) Object.defineProperty(groupParser, "placeholder", {
3787
4292
  get() {
3788
4293
  return parser.placeholder;
@@ -4544,6 +5049,16 @@ function conditional(discriminator, branches, defaultBranch, options) {
4544
5049
  } : {}
4545
5050
  };
4546
5051
  };
5052
+ const getConditionalBranchSeedSync = (currentState, branchParser, branchState, exec) => {
5053
+ const branchExec = withChildExecPath(exec, "_branch");
5054
+ const annotatedState = getAnnotatedChildState(currentState, branchState, branchParser);
5055
+ return extractOrCompletePhase2SeedSync(branchParser, annotatedState, branchExec);
5056
+ };
5057
+ const getConditionalBranchSeedAsync = async (currentState, branchParser, branchState, exec) => {
5058
+ const branchExec = withChildExecPath(exec, "_branch");
5059
+ const annotatedState = getAnnotatedChildState(currentState, branchState, branchParser);
5060
+ return await extractOrCompletePhase2SeedAsync(branchParser, annotatedState, branchExec);
5061
+ };
4547
5062
  function* suggestSync(context, prefix) {
4548
5063
  const state = context.state ?? initialState;
4549
5064
  const syncDiscriminator = discriminator;
@@ -4675,6 +5190,54 @@ function conditional(discriminator, branches, defaultBranch, options) {
4675
5190
  if (isAsync) return completeAsync(state, exec);
4676
5191
  return completeSync(state, exec);
4677
5192
  },
5193
+ [extractPhase2SeedKey](state, exec) {
5194
+ return dispatchByMode(combinedMode, () => {
5195
+ const syncDiscriminator = discriminator;
5196
+ const syncDefaultBranch = defaultBranch;
5197
+ const syncBranches = branches;
5198
+ const discriminatorExec = withChildExecPath(exec, "_discriminator");
5199
+ if (state.selectedBranch === void 0) {
5200
+ const discriminatorSeed$1 = completeOrExtractPhase2Seed(syncDiscriminator, getAnnotatedChildState(state, state.discriminatorState, syncDiscriminator), discriminatorExec);
5201
+ if (typeof discriminatorSeed$1?.value === "string") {
5202
+ const branchParser$1 = syncBranches[discriminatorSeed$1.value];
5203
+ if (branchParser$1 != null) {
5204
+ const branchSeed$1 = getConditionalBranchSeedSync(state, branchParser$1, branchParser$1.initialState, exec);
5205
+ return combineTuplePhase2Seeds(discriminatorSeed$1, branchSeed$1);
5206
+ }
5207
+ }
5208
+ if (syncDefaultBranch != null) {
5209
+ const branchSeed$1 = getConditionalBranchSeedSync(state, syncDefaultBranch, state.branchState ?? syncDefaultBranch.initialState, exec);
5210
+ return combineTuplePhase2Seeds(null, branchSeed$1);
5211
+ }
5212
+ return combineTuplePhase2Seeds(discriminatorSeed$1, null);
5213
+ }
5214
+ const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
5215
+ const branchSeed = getConditionalBranchSeedSync(state, branchParser, state.branchState ?? branchParser.initialState, exec);
5216
+ const discriminatorSeed = state.selectedBranch.kind === "default" ? null : state.discriminatorValue != null && state.discriminatorValue === state.selectedBranch.key ? { value: state.discriminatorValue } : completeOrExtractPhase2Seed(syncDiscriminator, getAnnotatedChildState(state, state.discriminatorState, syncDiscriminator), discriminatorExec) ?? { value: state.selectedBranch.key };
5217
+ return combineTuplePhase2Seeds(discriminatorSeed, branchSeed);
5218
+ }, async () => {
5219
+ const discriminatorExec = withChildExecPath(exec, "_discriminator");
5220
+ if (state.selectedBranch === void 0) {
5221
+ const discriminatorSeed$1 = await completeOrExtractPhase2Seed(discriminator, getAnnotatedChildState(state, state.discriminatorState, discriminator), discriminatorExec);
5222
+ if (typeof discriminatorSeed$1?.value === "string") {
5223
+ const branchParser$1 = branches[discriminatorSeed$1.value];
5224
+ if (branchParser$1 != null) {
5225
+ const branchSeed$1 = await getConditionalBranchSeedAsync(state, branchParser$1, branchParser$1.initialState, exec);
5226
+ return combineTuplePhase2Seeds(discriminatorSeed$1, branchSeed$1);
5227
+ }
5228
+ }
5229
+ if (defaultBranch != null) {
5230
+ const branchSeed$1 = await getConditionalBranchSeedAsync(state, defaultBranch, state.branchState ?? defaultBranch.initialState, exec);
5231
+ return combineTuplePhase2Seeds(null, branchSeed$1);
5232
+ }
5233
+ return combineTuplePhase2Seeds(discriminatorSeed$1, null);
5234
+ }
5235
+ const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
5236
+ const branchSeed = await getConditionalBranchSeedAsync(state, branchParser, state.branchState ?? branchParser.initialState, exec);
5237
+ const discriminatorSeed = state.selectedBranch.kind === "default" ? null : state.discriminatorValue != null && state.discriminatorValue === state.selectedBranch.key ? { value: state.discriminatorValue } : await completeOrExtractPhase2Seed(discriminator, getAnnotatedChildState(state, state.discriminatorState, discriminator), discriminatorExec) ?? { value: state.selectedBranch.key };
5238
+ return combineTuplePhase2Seeds(discriminatorSeed, branchSeed);
5239
+ });
5240
+ },
4678
5241
  suggest(context, prefix) {
4679
5242
  if (isAsync) return suggestAsync(context, prefix);
4680
5243
  return suggestSync(context, prefix);