@optique/core 1.0.0-dev.1616 → 1.0.0-dev.1659

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.
@@ -1,13 +1,14 @@
1
- import { getAnnotations, inheritAnnotations, injectAnnotations } from "./annotations.js";
1
+ import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, injectAnnotations } from "./annotations.js";
2
2
  import { message, optionName, text, values } from "./message.js";
3
- import { DependencyRegistry, createDependencySourceState, dependencyId, isDeferredParseState, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, wrappedDependencySourceMarker } from "./dependency.js";
4
- import { buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectSourcesFromState, createDependencyRuntimeContext, resolveStateWithRuntime, resolveStateWithRuntimeAsync } from "./dependency-runtime.js";
5
- import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
3
+ import { createDependencySourceState, dependencyId, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, wrappedDependencySourceMarker } from "./dependency.js";
6
4
  import { validateLabel } from "./validate.js";
7
5
  import { extractArgumentMetavars, extractCommandNames, extractOptionNames, isDocHidden, mergeHidden } from "./usage.js";
8
6
  import { deduplicateDocFragments } from "./doc.js";
7
+ import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
9
8
  import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, findSimilar } from "./suggestion.js";
10
9
  import { collectLeadingCandidates } from "./usage-internals.js";
10
+ import { defineInheritedAnnotationParser, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "./parser.js";
11
+ import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, createDependencyRuntimeContext, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync } from "./dependency-runtime.js";
11
12
 
12
13
  //#region src/constructs.ts
13
14
  /**
@@ -15,6 +16,67 @@ import { collectLeadingCandidates } from "./usage-internals.js";
15
16
  * do not match any specific name at the first buffer position.
16
17
  */
17
18
  const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
19
+ function isNonCliBoundSourceState(state, parser) {
20
+ return parser[unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object" && Object.hasOwn(state, "hasCliValue") && state.hasCliValue === false;
21
+ }
22
+ function withChildExecPath(exec, segment) {
23
+ if (exec == null) return void 0;
24
+ return {
25
+ ...exec,
26
+ path: [...exec.path ?? [], segment]
27
+ };
28
+ }
29
+ function mergeChildExec(parent, child) {
30
+ if (parent == null) return child;
31
+ if (child == null) return parent;
32
+ return {
33
+ ...parent,
34
+ trace: child.trace ?? parent.trace,
35
+ dependencyRuntime: child.dependencyRuntime ?? parent.dependencyRuntime,
36
+ dependencyRegistry: child.dependencyRegistry ?? parent.dependencyRegistry,
37
+ preCompletedByParser: child.preCompletedByParser ?? parent.preCompletedByParser,
38
+ excludedSourceFields: child.excludedSourceFields ?? parent.excludedSourceFields
39
+ };
40
+ }
41
+ function withChildContext(context, segment, state, parser, usage) {
42
+ const exec = withChildExecPath(context.exec, segment);
43
+ const dependencyRegistry = context.dependencyRegistry ?? exec?.dependencyRegistry;
44
+ const childState = parser == null ? state : getParseChildState(context.state, state, parser);
45
+ return {
46
+ ...context,
47
+ state: childState,
48
+ ...usage != null ? { usage } : {},
49
+ ...exec != null ? {
50
+ exec: dependencyRegistry === exec.dependencyRegistry ? exec : {
51
+ ...exec,
52
+ dependencyRegistry
53
+ },
54
+ dependencyRegistry
55
+ } : {}
56
+ };
57
+ }
58
+ function isUnmatchedDependencyState(state, parser) {
59
+ if (state === void 0) return true;
60
+ if (Array.isArray(state) && state.length === 1 && isPendingDependencySourceState(state[0])) return true;
61
+ if (isPendingDependencySourceState(state)) return true;
62
+ if (isNonCliBoundSourceState(state, parser)) return true;
63
+ return state === parser.initialState;
64
+ }
65
+ function filterPreCompletedRuntimeNodes(nodes, preCompletedKeys) {
66
+ if (preCompletedKeys.size < 1) return nodes;
67
+ return nodes.filter((node) => {
68
+ const segment = node.path.at(-1);
69
+ if (typeof segment === "number") return !preCompletedKeys.has(String(segment));
70
+ return segment == null || !preCompletedKeys.has(segment);
71
+ });
72
+ }
73
+ function buildIndexedParserPairs(parsers) {
74
+ return parsers.map((parser, index) => [String(index), parser]);
75
+ }
76
+ function createAnnotatedArrayStateRecord(stateArray) {
77
+ const stateRecord = Object.fromEntries(stateArray.map((state, index) => [String(index), state]));
78
+ return inheritAnnotations(stateArray, stateRecord);
79
+ }
18
80
  /**
19
81
  * Computes the union of `leadingNames` from all given parsers.
20
82
  * Used for alternative combinators (`or()`, `longestMatch()`) where all
@@ -47,7 +109,6 @@ function sharedBufferLeadingNames(parsers) {
47
109
  }
48
110
  return names.size === 0 ? EMPTY_LEADING_NAMES : names;
49
111
  }
50
- const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnotations");
51
112
  /**
52
113
  * Internal symbol for exposing field-level parser pairs from `object()`
53
114
  * and `merge()` parsers. This allows `merge()` to pre-complete dependency
@@ -62,9 +123,73 @@ const fieldParsersKey = Symbol("fieldParsers");
62
123
  * to consume results from parsers that still return `DependencySourceState`.
63
124
  * @internal
64
125
  */
126
+ function unwrapAnnotationView(value) {
127
+ if (value == null || typeof value !== "object") return value;
128
+ return annotationViewTargets.get(value) ?? value;
129
+ }
130
+ function containsAnnotationView(value, seen = /* @__PURE__ */ new WeakSet()) {
131
+ if (value == null || typeof value !== "object") return false;
132
+ const candidate = value;
133
+ if (annotationViewTargets.has(candidate)) return true;
134
+ const source = unwrapAnnotationView(candidate);
135
+ if (seen.has(source)) return false;
136
+ seen.add(source);
137
+ if (Array.isArray(source)) return source.some((item) => containsAnnotationView(item, seen));
138
+ const proto = Object.getPrototypeOf(source);
139
+ if (proto !== Object.prototype && proto !== null) return false;
140
+ return Reflect.ownKeys(source).some((key) => containsAnnotationView(source[key], seen));
141
+ }
142
+ function unwrapNestedAnnotationViews(value, seen = /* @__PURE__ */ new WeakMap()) {
143
+ if (value == null || typeof value !== "object") return value;
144
+ const source = unwrapAnnotationView(value);
145
+ if (seen.has(source)) return seen.get(source);
146
+ if (Array.isArray(source)) {
147
+ let changed$1 = false;
148
+ const clone$1 = [...source];
149
+ seen.set(source, clone$1);
150
+ for (let i = 0; i < source.length; i++) {
151
+ const nextValue = unwrapNestedAnnotationViews(source[i], seen);
152
+ if (nextValue !== source[i]) {
153
+ clone$1[i] = nextValue;
154
+ changed$1 = true;
155
+ }
156
+ }
157
+ return changed$1 ? clone$1 : source;
158
+ }
159
+ const proto = Object.getPrototypeOf(source);
160
+ if (proto !== Object.prototype && proto !== null) return source;
161
+ const descriptors = Object.getOwnPropertyDescriptors(source);
162
+ let changed = false;
163
+ const clone = Object.create(proto);
164
+ seen.set(source, clone);
165
+ for (const key of Reflect.ownKeys(descriptors)) {
166
+ const descriptor = descriptors[key];
167
+ if (descriptor != null && "value" in descriptor) {
168
+ const nextValue = unwrapNestedAnnotationViews(descriptor.value, seen);
169
+ if (nextValue !== descriptor.value) {
170
+ descriptors[key] = {
171
+ ...descriptor,
172
+ value: nextValue
173
+ };
174
+ changed = true;
175
+ }
176
+ }
177
+ }
178
+ if (!changed) {
179
+ seen.set(source, source);
180
+ return source;
181
+ }
182
+ Object.defineProperties(clone, descriptors);
183
+ return clone;
184
+ }
65
185
  function unwrapCompleteResult(result) {
66
- if (isDependencySourceState(result)) return result.result;
67
- return result;
186
+ const unwrappedResult = isDependencySourceState(result) ? result.result : result;
187
+ if (!unwrappedResult.success || !containsAnnotationView(unwrappedResult.value)) return unwrappedResult;
188
+ const value = unwrapNestedAnnotationViews(unwrappedResult.value);
189
+ return value === unwrappedResult.value ? unwrappedResult : {
190
+ ...unwrappedResult,
191
+ value
192
+ };
68
193
  }
69
194
  /**
70
195
  * Prepares a field state for completion by wrapping `undefined` state
@@ -85,18 +210,80 @@ function prepareStateForCompletion(fieldState, parser) {
85
210
  }
86
211
  /**
87
212
  * Returns the field state with parent annotations inherited, respecting
88
- * the parser's {@link inheritParentAnnotationsKey} flag. This is the
89
- * same logic as {@link createFieldStateGetter} inside `object()` but
90
- * without the per-state cache, for use in module-level helpers like
213
+ * the parser's annotation-inheritance contract. This is the same logic as
214
+ * {@link createFieldStateGetter} inside `object()` but without the per-state
215
+ * cache, for use in module-level helpers like
91
216
  * {@link pendingDependencyDefaults}.
92
217
  * @internal
93
218
  */
94
219
  function getAnnotatedFieldState(parentState, field, parser) {
95
220
  const sourceState = parentState != null && typeof parentState === "object" && field in parentState ? parentState[field] : parser.initialState;
96
- if (sourceState == null || typeof sourceState !== "object") return sourceState;
221
+ return getAnnotatedChildState(parentState, sourceState, parser);
222
+ }
223
+ const annotationViewTargets = /* @__PURE__ */ new WeakMap();
224
+ function withAnnotationView(state, annotations) {
225
+ const view = new Proxy(state, {
226
+ get(target, key) {
227
+ if (key === annotationKey) return annotations;
228
+ const value = Reflect.get(target, key, target);
229
+ return typeof value === "function" ? value.bind(target) : value;
230
+ },
231
+ has(target, key) {
232
+ return key === annotationKey || Reflect.has(target, key);
233
+ }
234
+ });
235
+ annotationViewTargets.set(view, state);
236
+ return view;
237
+ }
238
+ function getParseChildState(parentState, childState, parser) {
239
+ const annotations = getAnnotations(parentState);
240
+ const shouldInheritAnnotations = Reflect.get(parser, inheritParentAnnotationsKey) === true;
241
+ if (childState == null) {
242
+ if (annotations !== void 0 && shouldInheritAnnotations) return injectAnnotations({}, annotations);
243
+ return childState;
244
+ }
245
+ if (annotations === void 0 || typeof childState !== "object" || getAnnotations(childState) === annotations || !shouldInheritAnnotations) return childState;
246
+ const injectedState = injectAnnotations(childState, annotations);
247
+ return getAnnotations(injectedState) === annotations ? injectedState : childState;
248
+ }
249
+ function getObjectParseChildState(parentState, childState, _parser) {
97
250
  const annotations = getAnnotations(parentState);
98
- if (annotations === void 0 || getAnnotations(sourceState) === annotations) return sourceState;
99
- return Reflect.get(parser, inheritParentAnnotationsKey) === true ? injectAnnotations(sourceState, annotations) : inheritAnnotations(parentState, sourceState);
251
+ if (annotations === void 0 || childState == null || typeof childState !== "object" || getAnnotations(childState) === annotations) return childState;
252
+ return injectAnnotations(childState, annotations);
253
+ }
254
+ function getAnnotatedChildState(parentState, childState, parser) {
255
+ const annotations = getAnnotations(parentState);
256
+ const shouldInheritAnnotations = Reflect.get(parser, inheritParentAnnotationsKey) === true;
257
+ if (childState == null) {
258
+ if (annotations !== void 0 && shouldInheritAnnotations) return injectAnnotations({}, annotations);
259
+ return childState;
260
+ }
261
+ if (typeof childState !== "object") return childState;
262
+ if (annotations === void 0 || getAnnotations(childState) === annotations) return childState;
263
+ if (shouldInheritAnnotations) {
264
+ const injectedState = injectAnnotations(childState, annotations);
265
+ if (getAnnotations(injectedState) === annotations) return injectedState;
266
+ }
267
+ return withAnnotationView(childState, annotations);
268
+ }
269
+ function buildSuggestRuntimeNodesFromPairs(pairs, state, parentPath) {
270
+ const prefix = parentPath ?? [];
271
+ const nodes = [];
272
+ for (const [field, parser] of pairs) {
273
+ const fieldState = Object.hasOwn(state, field) ? state[field] : parser.initialState;
274
+ nodes.push(...getParserSuggestRuntimeNodes(parser, getAnnotatedChildState(state, fieldState, parser), [...prefix, field]));
275
+ }
276
+ return nodes;
277
+ }
278
+ function buildSuggestRuntimeNodesFromArray(parsers, stateArray, parentPath) {
279
+ const prefix = parentPath ?? [];
280
+ const nodes = [];
281
+ for (let i = 0; i < parsers.length; i++) {
282
+ const parser = parsers[i];
283
+ const elementState = i < stateArray.length ? stateArray[i] : void 0;
284
+ nodes.push(...getParserSuggestRuntimeNodes(parser, getAnnotatedChildState(stateArray, elementState, parser), [...prefix, i]));
285
+ }
286
+ return nodes;
100
287
  }
101
288
  function createUnexpectedInputErrorWithScopedSuggestions(baseError, invalidInput, parsers, customFormatter) {
102
289
  const options = /* @__PURE__ */ new Set();
@@ -304,8 +491,8 @@ function createExclusiveComplete(parsers, options, noMatchContext, mode) {
304
491
  success: false,
305
492
  error: result.error
306
493
  };
307
- return dispatchByMode(mode, () => syncParsers[i].complete(result.next.state, exec), async () => {
308
- const completeResult = await parsers[i].complete(result.next.state, exec);
494
+ return dispatchByMode(mode, () => syncParsers[i].complete(result.next.state, withChildExecPath(exec, i)), async () => {
495
+ const completeResult = await parsers[i].complete(result.next.state, withChildExecPath(exec, i));
309
496
  return completeResult;
310
497
  });
311
498
  };
@@ -319,31 +506,24 @@ function createExclusiveSuggest(parsers, mode) {
319
506
  return (context, prefix) => {
320
507
  return dispatchIterableByMode(mode, function* () {
321
508
  const suggestions = [];
322
- if (context.state == null) for (const parser of syncParsers) {
323
- const parserSuggestions = parser.suggest({
324
- ...context,
325
- state: parser.initialState
326
- }, prefix);
509
+ if (context.state == null) for (let i = 0; i < syncParsers.length; i++) {
510
+ const parser = syncParsers[i];
511
+ const parserSuggestions = parser.suggest(withChildContext(context, i, parser.initialState), prefix);
327
512
  suggestions.push(...parserSuggestions);
328
513
  }
329
514
  else {
330
515
  const [index, parserResult] = context.state;
331
516
  if (parserResult.success) {
332
- const parserSuggestions = syncParsers[index].suggest({
333
- ...context,
334
- state: parserResult.next.state
335
- }, prefix);
517
+ const parserSuggestions = syncParsers[index].suggest(withChildContext(context, index, parserResult.next.state), prefix);
336
518
  suggestions.push(...parserSuggestions);
337
519
  }
338
520
  }
339
521
  yield* deduplicateSuggestions(suggestions);
340
522
  }, async function* () {
341
523
  const suggestions = [];
342
- if (context.state == null) for (const parser of parsers) {
343
- const parserSuggestions = parser.suggest({
344
- ...context,
345
- state: parser.initialState
346
- }, prefix);
524
+ if (context.state == null) for (let i = 0; i < parsers.length; i++) {
525
+ const parser = parsers[i];
526
+ const parserSuggestions = parser.suggest(withChildContext(context, i, parser.initialState), prefix);
347
527
  if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
348
528
  else suggestions.push(...parserSuggestions);
349
529
  }
@@ -351,10 +531,7 @@ function createExclusiveSuggest(parsers, mode) {
351
531
  const [index, parserResult] = context.state;
352
532
  if (parserResult.success) {
353
533
  const parser = parsers[index];
354
- const parserSuggestions = parser.suggest({
355
- ...context,
356
- state: parserResult.next.state
357
- }, prefix);
534
+ const parserSuggestions = parser.suggest(withChildContext(context, index, parserResult.next.state), prefix);
358
535
  if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
359
536
  else suggestions.push(...parserSuggestions);
360
537
  }
@@ -363,6 +540,13 @@ function createExclusiveSuggest(parsers, mode) {
363
540
  });
364
541
  };
365
542
  }
543
+ function getExclusiveSuggestRuntimeNodes(parsers, state, path) {
544
+ if (!Array.isArray(state) || state.length !== 2 || typeof state[0] !== "number") return [];
545
+ const [index, parserResult] = state;
546
+ if (!parserResult?.success || index < 0 || index >= parsers.length) return [];
547
+ const parser = parsers[index];
548
+ return getParserSuggestRuntimeNodes(parser, parserResult.next.state, [...path, index]);
549
+ }
366
550
  /**
367
551
  * Gets the no-match error, either from custom options or default.
368
552
  * Shared by or() and longestMatch().
@@ -372,6 +556,26 @@ function getNoMatchError(options, noMatchContext) {
372
556
  const customNoMatch = options?.errors?.noMatch;
373
557
  return customNoMatch ? typeof customNoMatch === "function" ? customNoMatch(noMatchContext) : customNoMatch : generateNoMatchError(noMatchContext);
374
558
  }
559
+ function composeExclusiveDependencyMetadata(parsers) {
560
+ const sourceBranches = parsers.filter((parser) => parser.dependencyMetadata?.source != null);
561
+ if (sourceBranches.length < 1) return void 0;
562
+ const sourceIds = new Set(sourceBranches.map((parser) => parser.dependencyMetadata.source.sourceId));
563
+ if (sourceIds.size !== 1) return void 0;
564
+ const sharedSource = sourceBranches[0].dependencyMetadata.source;
565
+ return { source: {
566
+ ...sharedSource,
567
+ getMissingSourceValue: void 0,
568
+ preservesSourceValue: sourceBranches.every((parser) => parser.dependencyMetadata?.source?.preservesSourceValue !== false),
569
+ extractSourceValue(state) {
570
+ if (!Array.isArray(state) || state.length !== 2 || typeof state[0] !== "number") return void 0;
571
+ const [index, parserResult] = state;
572
+ if (!parserResult?.success) return void 0;
573
+ const branchSource = parsers[index].dependencyMetadata?.source;
574
+ if (branchSource?.extractSourceValue == null) return void 0;
575
+ return branchSource.extractSourceValue(parserResult.next.state);
576
+ }
577
+ } };
578
+ }
375
579
  /**
376
580
  * @since 0.5.0
377
581
  */
@@ -404,17 +608,13 @@ function or(...args) {
404
608
  const orderedParsers = syncParsers.map((p, i) => [p, i]);
405
609
  orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
406
610
  for (const [parser, i] of orderedParsers) {
407
- const result = parser.parse({
408
- ...context,
409
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
410
- });
611
+ const result = parser.parse(withChildContext(context, i, context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state));
411
612
  if (result.success && result.consumed.length > 0) {
412
613
  if (context.state?.[0] !== i && context.state?.[1].success) {
413
614
  const previouslyConsumed = context.state[1].consumed;
414
615
  const checkResult = parser.parse({
415
- ...context,
416
- buffer: previouslyConsumed,
417
- state: parser.initialState
616
+ ...withChildContext(context, i, parser.initialState),
617
+ buffer: previouslyConsumed
418
618
  });
419
619
  const canConsumeShared = checkResult.success && checkResult.consumed.length === previouslyConsumed.length && checkResult.consumed.every((c, idx) => c === previouslyConsumed[idx]);
420
620
  if (!canConsumeShared) return {
@@ -422,11 +622,19 @@ function or(...args) {
422
622
  consumed: context.buffer.length - result.next.buffer.length,
423
623
  error: message`${values(context.state[1].consumed)} and ${values(result.consumed)} cannot be used together.`
424
624
  };
625
+ const replayExec = mergeChildExec(context.exec, checkResult.next.exec);
425
626
  const replayedResult = parser.parse({
426
- ...context,
627
+ ...withChildContext({
628
+ ...context,
629
+ ...replayExec != null ? {
630
+ exec: replayExec,
631
+ dependencyRegistry: replayExec.dependencyRegistry
632
+ } : {}
633
+ }, i, checkResult.next.state),
427
634
  state: checkResult.next.state
428
635
  });
429
636
  if (!replayedResult.success) return replayedResult;
637
+ const mergedExec$1 = mergeChildExec(replayExec, replayedResult.next.exec);
430
638
  return {
431
639
  success: true,
432
640
  next: {
@@ -436,18 +644,27 @@ function or(...args) {
436
644
  state: [i, {
437
645
  ...replayedResult,
438
646
  consumed: [...previouslyConsumed, ...replayedResult.consumed]
439
- }]
647
+ }],
648
+ ...mergedExec$1 != null ? {
649
+ exec: mergedExec$1,
650
+ dependencyRegistry: mergedExec$1.dependencyRegistry
651
+ } : {}
440
652
  },
441
653
  consumed: replayedResult.consumed
442
654
  };
443
655
  }
656
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
444
657
  return {
445
658
  success: true,
446
659
  next: {
447
660
  ...context,
448
661
  buffer: result.next.buffer,
449
662
  optionsTerminated: result.next.optionsTerminated,
450
- state: [i, result]
663
+ state: [i, result],
664
+ ...mergedExec != null ? {
665
+ exec: mergedExec,
666
+ dependencyRegistry: mergedExec.dependencyRegistry
667
+ } : {}
451
668
  },
452
669
  consumed: result.consumed
453
670
  };
@@ -463,18 +680,14 @@ function or(...args) {
463
680
  const orderedParsers = parsers.map((p, i) => [p, i]);
464
681
  orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
465
682
  for (const [parser, i] of orderedParsers) {
466
- const resultOrPromise = parser.parse({
467
- ...context,
468
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
469
- });
683
+ const resultOrPromise = parser.parse(withChildContext(context, i, context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state));
470
684
  const result = await resultOrPromise;
471
685
  if (result.success && result.consumed.length > 0) {
472
686
  if (context.state?.[0] !== i && context.state?.[1].success) {
473
687
  const previouslyConsumed = context.state[1].consumed;
474
688
  const checkResultOrPromise = parser.parse({
475
- ...context,
476
- buffer: previouslyConsumed,
477
- state: parser.initialState
689
+ ...withChildContext(context, i, parser.initialState),
690
+ buffer: previouslyConsumed
478
691
  });
479
692
  const checkResult = await checkResultOrPromise;
480
693
  const canConsumeShared = checkResult.success && checkResult.consumed.length === previouslyConsumed.length && checkResult.consumed.every((c, idx) => c === previouslyConsumed[idx]);
@@ -483,12 +696,17 @@ function or(...args) {
483
696
  consumed: context.buffer.length - result.next.buffer.length,
484
697
  error: message`${values(context.state[1].consumed)} and ${values(result.consumed)} cannot be used together.`
485
698
  };
486
- const replayedResultOrPromise = parser.parse({
699
+ const replayExec = mergeChildExec(context.exec, checkResult.next.exec);
700
+ const replayedResultOrPromise = parser.parse({ ...withChildContext({
487
701
  ...context,
488
- state: checkResult.next.state
489
- });
702
+ ...replayExec != null ? {
703
+ exec: replayExec,
704
+ dependencyRegistry: replayExec.dependencyRegistry
705
+ } : {}
706
+ }, i, checkResult.next.state) });
490
707
  const replayedResult = await replayedResultOrPromise;
491
708
  if (!replayedResult.success) return replayedResult;
709
+ const mergedExec$1 = mergeChildExec(replayExec, replayedResult.next.exec);
492
710
  return {
493
711
  success: true,
494
712
  next: {
@@ -498,18 +716,27 @@ function or(...args) {
498
716
  state: [i, {
499
717
  ...replayedResult,
500
718
  consumed: [...previouslyConsumed, ...replayedResult.consumed]
501
- }]
719
+ }],
720
+ ...mergedExec$1 != null ? {
721
+ exec: mergedExec$1,
722
+ dependencyRegistry: mergedExec$1.dependencyRegistry
723
+ } : {}
502
724
  },
503
725
  consumed: replayedResult.consumed
504
726
  };
505
727
  }
728
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
506
729
  return {
507
730
  success: true,
508
731
  next: {
509
732
  ...context,
510
733
  buffer: result.next.buffer,
511
734
  optionsTerminated: result.next.optionsTerminated,
512
- state: [i, result]
735
+ state: [i, result],
736
+ ...mergedExec != null ? {
737
+ exec: mergedExec,
738
+ dependencyRegistry: mergedExec.dependencyRegistry
739
+ } : {}
513
740
  },
514
741
  consumed: result.consumed
515
742
  };
@@ -536,6 +763,9 @@ function or(...args) {
536
763
  parse(context) {
537
764
  return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
538
765
  },
766
+ getSuggestRuntimeNodes(state, path) {
767
+ return getExclusiveSuggestRuntimeNodes(parsers, state, path);
768
+ },
539
769
  suggest: createExclusiveSuggest(parsers, combinedMode),
540
770
  getDocFragments(state, _defaultValue) {
541
771
  let brief;
@@ -564,6 +794,8 @@ function or(...args) {
564
794
  };
565
795
  }
566
796
  };
797
+ const singleDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
798
+ if (singleDependencyMetadata != null) singleResult.dependencyMetadata = singleDependencyMetadata;
567
799
  return singleResult;
568
800
  }
569
801
  /**
@@ -598,10 +830,7 @@ function longestMatch(...args) {
598
830
  let error = getInitialError(context);
599
831
  for (let i = 0; i < syncParsers.length; i++) {
600
832
  const parser = syncParsers[i];
601
- const result = parser.parse({
602
- ...context,
603
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
604
- });
833
+ const result = parser.parse(withChildContext(context, i, context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state));
605
834
  if (result.success) {
606
835
  const consumed = context.buffer.length - result.next.buffer.length;
607
836
  if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
@@ -611,16 +840,23 @@ function longestMatch(...args) {
611
840
  };
612
841
  } else if (error.consumed < result.consumed) error = result;
613
842
  }
614
- if (bestMatch && bestMatch.result.success) return {
615
- success: true,
616
- next: {
617
- ...context,
618
- buffer: bestMatch.result.next.buffer,
619
- optionsTerminated: bestMatch.result.next.optionsTerminated,
620
- state: [bestMatch.index, bestMatch.result]
621
- },
622
- consumed: bestMatch.result.consumed
623
- };
843
+ if (bestMatch && bestMatch.result.success) {
844
+ const mergedExec = mergeChildExec(context.exec, bestMatch.result.next.exec);
845
+ return {
846
+ success: true,
847
+ next: {
848
+ ...context,
849
+ buffer: bestMatch.result.next.buffer,
850
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
851
+ state: [bestMatch.index, bestMatch.result],
852
+ ...mergedExec != null ? {
853
+ exec: mergedExec,
854
+ dependencyRegistry: mergedExec.dependencyRegistry
855
+ } : {}
856
+ },
857
+ consumed: bestMatch.result.consumed
858
+ };
859
+ }
624
860
  return {
625
861
  ...error,
626
862
  success: false
@@ -631,10 +867,7 @@ function longestMatch(...args) {
631
867
  let error = getInitialError(context);
632
868
  for (let i = 0; i < parsers.length; i++) {
633
869
  const parser = parsers[i];
634
- const resultOrPromise = parser.parse({
635
- ...context,
636
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
637
- });
870
+ const resultOrPromise = parser.parse(withChildContext(context, i, context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state));
638
871
  const result = await resultOrPromise;
639
872
  if (result.success) {
640
873
  const consumed = context.buffer.length - result.next.buffer.length;
@@ -645,16 +878,23 @@ function longestMatch(...args) {
645
878
  };
646
879
  } else if (error.consumed < result.consumed) error = result;
647
880
  }
648
- if (bestMatch && bestMatch.result.success) return {
649
- success: true,
650
- next: {
651
- ...context,
652
- buffer: bestMatch.result.next.buffer,
653
- optionsTerminated: bestMatch.result.next.optionsTerminated,
654
- state: [bestMatch.index, bestMatch.result]
655
- },
656
- consumed: bestMatch.result.consumed
657
- };
881
+ if (bestMatch && bestMatch.result.success) {
882
+ const mergedExec = mergeChildExec(context.exec, bestMatch.result.next.exec);
883
+ return {
884
+ success: true,
885
+ next: {
886
+ ...context,
887
+ buffer: bestMatch.result.next.buffer,
888
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
889
+ state: [bestMatch.index, bestMatch.result],
890
+ ...mergedExec != null ? {
891
+ exec: mergedExec,
892
+ dependencyRegistry: mergedExec.dependencyRegistry
893
+ } : {}
894
+ },
895
+ consumed: bestMatch.result.consumed
896
+ };
897
+ }
658
898
  return {
659
899
  ...error,
660
900
  success: false
@@ -676,6 +916,9 @@ function longestMatch(...args) {
676
916
  parse(context) {
677
917
  return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
678
918
  },
919
+ getSuggestRuntimeNodes(state, path) {
920
+ return getExclusiveSuggestRuntimeNodes(parsers, state, path);
921
+ },
679
922
  suggest: createExclusiveSuggest(parsers, combinedMode),
680
923
  getDocFragments(state, _defaultValue) {
681
924
  let brief;
@@ -711,6 +954,8 @@ function longestMatch(...args) {
711
954
  };
712
955
  }
713
956
  };
957
+ const multiDependencyMetadata = composeExclusiveDependencyMetadata(parsers);
958
+ if (multiDependencyMetadata != null) multiResult.dependencyMetadata = multiDependencyMetadata;
714
959
  return multiResult;
715
960
  }
716
961
  /**
@@ -719,32 +964,32 @@ function longestMatch(...args) {
719
964
  */
720
965
  function* suggestObjectSync(context, prefix, parserPairs) {
721
966
  const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
722
- const nodes = buildRuntimeNodesFromPairs(parserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
967
+ const sourceParserPairs = filterExcludedFieldParsers(parserPairs, context.exec?.excludedSourceFields);
968
+ const nodes = buildRuntimeNodesFromPairs(sourceParserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
723
969
  collectExplicitSourceValues(nodes, runtime);
724
- if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
725
- completeDependencySourceDefaults(context, parserPairs, runtime.registry, context.exec);
970
+ if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime, /* @__PURE__ */ new WeakSet(), context.exec?.excludedSourceFields);
971
+ completeDependencySourceDefaults(context, sourceParserPairs, runtime.registry, context.exec);
726
972
  const contextWithRegistry = {
727
973
  ...context,
728
- dependencyRegistry: runtime.registry
974
+ dependencyRegistry: runtime.registry,
975
+ ...context.exec != null ? { exec: {
976
+ ...context.exec,
977
+ dependencyRuntime: runtime,
978
+ dependencyRegistry: runtime.registry
979
+ } } : {}
729
980
  };
730
981
  if (context.buffer.length > 0) {
731
982
  const lastToken = context.buffer[context.buffer.length - 1];
732
983
  for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
733
984
  const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
734
- yield* parser.suggest({
735
- ...contextWithRegistry,
736
- state: fieldState
737
- }, prefix);
985
+ yield* parser.suggest(withChildContext(contextWithRegistry, field, fieldState), prefix);
738
986
  return;
739
987
  }
740
988
  }
741
989
  const suggestions = [];
742
990
  for (const [field, parser] of parserPairs) {
743
991
  const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
744
- const fieldSuggestions = parser.suggest({
745
- ...contextWithRegistry,
746
- state: fieldState
747
- }, prefix);
992
+ const fieldSuggestions = parser.suggest(withChildContext(contextWithRegistry, field, fieldState), prefix);
748
993
  suggestions.push(...fieldSuggestions);
749
994
  }
750
995
  yield* deduplicateSuggestions(suggestions);
@@ -755,22 +1000,25 @@ function* suggestObjectSync(context, prefix, parserPairs) {
755
1000
  */
756
1001
  async function* suggestObjectAsync(context, prefix, parserPairs) {
757
1002
  const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
758
- const nodes = buildRuntimeNodesFromPairs(parserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
759
- collectExplicitSourceValues(nodes, runtime);
760
- if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
761
- await completeDependencySourceDefaultsAsync(context, parserPairs, runtime.registry, context.exec);
1003
+ const sourceParserPairs = filterExcludedFieldParsers(parserPairs, context.exec?.excludedSourceFields);
1004
+ const nodes = buildRuntimeNodesFromPairs(sourceParserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
1005
+ await collectExplicitSourceValuesAsync(nodes, runtime);
1006
+ if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime, /* @__PURE__ */ new WeakSet(), context.exec?.excludedSourceFields);
1007
+ await completeDependencySourceDefaultsAsync(context, sourceParserPairs, runtime.registry, context.exec);
762
1008
  const contextWithRegistry = {
763
1009
  ...context,
764
- dependencyRegistry: runtime.registry
1010
+ dependencyRegistry: runtime.registry,
1011
+ ...context.exec != null ? { exec: {
1012
+ ...context.exec,
1013
+ dependencyRuntime: runtime,
1014
+ dependencyRegistry: runtime.registry
1015
+ } } : {}
765
1016
  };
766
1017
  if (context.buffer.length > 0) {
767
1018
  const lastToken = context.buffer[context.buffer.length - 1];
768
1019
  for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
769
1020
  const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
770
- const suggestions$1 = parser.suggest({
771
- ...contextWithRegistry,
772
- state: fieldState
773
- }, prefix);
1021
+ const suggestions$1 = parser.suggest(withChildContext(contextWithRegistry, field, fieldState), prefix);
774
1022
  for await (const s of suggestions$1) yield s;
775
1023
  return;
776
1024
  }
@@ -778,10 +1026,7 @@ async function* suggestObjectAsync(context, prefix, parserPairs) {
778
1026
  const suggestions = [];
779
1027
  for (const [field, parser] of parserPairs) {
780
1028
  const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
781
- const fieldSuggestions = parser.suggest({
782
- ...contextWithRegistry,
783
- state: fieldState
784
- }, prefix);
1029
+ const fieldSuggestions = parser.suggest(withChildContext(contextWithRegistry, field, fieldState), prefix);
785
1030
  for await (const s of fieldSuggestions) suggestions.push(s);
786
1031
  }
787
1032
  yield* deduplicateSuggestions(suggestions);
@@ -802,9 +1047,26 @@ function registerCompletedDependency(completed, registry) {
802
1047
  * @see https://github.com/dahlia/optique/issues/186
803
1048
  * @internal
804
1049
  */
805
- function* pendingDependencyDefaults(context, parserPairs) {
1050
+ function* pendingDependencyDefaults(context, parserPairs, registry) {
806
1051
  for (const [field, fieldParser] of parserPairs) {
1052
+ const sourceId = fieldParser.dependencyMetadata?.source?.sourceId ?? (isWrappedDependencySource(fieldParser) ? fieldParser[wrappedDependencySourceMarker][dependencyId] : isPendingDependencySourceState(fieldParser.initialState) ? fieldParser.initialState[dependencyId] : void 0);
1053
+ if (sourceId != null && registry?.has(sourceId)) continue;
807
1054
  const fieldState = context.state != null && typeof context.state === "object" && field in context.state ? context.state[field] : void 0;
1055
+ const annotatedFieldState = getAnnotatedFieldState(context.state, field, fieldParser);
1056
+ if (fieldParser.dependencyMetadata?.source?.getMissingSourceValue != null && isUnmatchedDependencyState(fieldState, fieldParser)) {
1057
+ yield {
1058
+ parser: fieldParser,
1059
+ state: annotatedFieldState
1060
+ };
1061
+ continue;
1062
+ }
1063
+ if (fieldParser.dependencyMetadata?.source != null && isUnmatchedDependencyState(fieldState, fieldParser) && (annotatedFieldState !== fieldState || isNonCliBoundSourceState(fieldState, fieldParser))) {
1064
+ yield {
1065
+ parser: fieldParser,
1066
+ state: annotatedFieldState
1067
+ };
1068
+ continue;
1069
+ }
808
1070
  if (fieldState != null) {
809
1071
  if (!Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) yield {
810
1072
  parser: fieldParser,
@@ -832,7 +1094,7 @@ function* pendingDependencyDefaults(context, parserPairs) {
832
1094
  * @internal
833
1095
  */
834
1096
  function completeDependencySourceDefaults(context, parserPairs, registry, exec) {
835
- for (const { parser, state } of pendingDependencyDefaults(context, parserPairs)) {
1097
+ for (const { parser, state } of pendingDependencyDefaults(context, parserPairs, registry)) {
836
1098
  const completed = parser.complete(state, exec);
837
1099
  const depState = wrapAsDependencySourceState(completed, parser);
838
1100
  if (depState) registerCompletedDependency(depState, registry);
@@ -851,9 +1113,11 @@ function completeDependencySourceDefaults(context, parserPairs, registry, exec)
851
1113
  */
852
1114
  function wrapAsDependencySourceState(completed, parser) {
853
1115
  if (isDependencySourceState(completed)) return completed;
854
- const hasDep = isWrappedDependencySource(parser) || isPendingDependencySourceState(parser.initialState);
1116
+ const metadataSource = parser.dependencyMetadata?.source;
1117
+ if (metadataSource?.preservesSourceValue === false) return void 0;
1118
+ const hasDep = metadataSource != null || isWrappedDependencySource(parser) || isPendingDependencySourceState(parser.initialState);
855
1119
  if (hasDep && typeof completed === "object" && completed !== null && "success" in completed && completed.success && "value" in completed && completed.value !== void 0) {
856
- const depId = isWrappedDependencySource(parser) ? parser[wrappedDependencySourceMarker][dependencyId] : parser.initialState[dependencyId];
1120
+ const depId = metadataSource?.sourceId ?? (isWrappedDependencySource(parser) ? parser[wrappedDependencySourceMarker][dependencyId] : parser.initialState[dependencyId]);
857
1121
  return createDependencySourceState(completed, depId);
858
1122
  }
859
1123
  return void 0;
@@ -867,7 +1131,7 @@ function wrapAsDependencySourceState(completed, parser) {
867
1131
  * @internal
868
1132
  */
869
1133
  async function completeDependencySourceDefaultsAsync(context, parserPairs, registry, exec) {
870
- for (const { parser, state } of pendingDependencyDefaults(context, parserPairs)) {
1134
+ for (const { parser, state } of pendingDependencyDefaults(context, parserPairs, registry)) {
871
1135
  const completed = await parser.complete(state, exec);
872
1136
  const depState = wrapAsDependencySourceState(completed, parser);
873
1137
  if (depState) registerCompletedDependency(depState, registry);
@@ -909,6 +1173,20 @@ function collectChildFieldParsers(parsers) {
909
1173
  for (const parser of parsers) if (fieldParsersKey in parser) pairs.push(...parser[fieldParsersKey]);
910
1174
  return pairs;
911
1175
  }
1176
+ function filterDuplicateFieldParsers(pairs) {
1177
+ const counts = /* @__PURE__ */ new Map();
1178
+ for (const [field] of pairs) counts.set(field, (counts.get(field) ?? 0) + 1);
1179
+ return pairs.filter(([field]) => (counts.get(field) ?? 0) <= 1);
1180
+ }
1181
+ function collectDuplicateFieldNames(pairs) {
1182
+ const counts = /* @__PURE__ */ new Map();
1183
+ for (const [field] of pairs) counts.set(field, (counts.get(field) ?? 0) + 1);
1184
+ return new Set([...counts.entries()].filter(([, count]) => count > 1).map(([field]) => field));
1185
+ }
1186
+ function filterExcludedFieldParsers(pairs, excludedFields) {
1187
+ if (excludedFields == null || excludedFields.size < 1) return pairs;
1188
+ return pairs.filter(([field]) => !excludedFields.has(field));
1189
+ }
912
1190
  /**
913
1191
  * Pre-completes dependency source fields and registers their values in
914
1192
  * the given registry. Unlike `completeDependencySourceDefaults()` (used
@@ -935,22 +1213,37 @@ function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, e
935
1213
  continue;
936
1214
  }
937
1215
  const fieldState = state[field];
1216
+ const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
1217
+ if (fieldParser.dependencyMetadata?.source?.getMissingSourceValue != null && isUnmatchedDependencyState(fieldState, fieldParser)) {
1218
+ const completed = fieldParser.complete(annotatedFieldState, withChildExecPath(exec, field));
1219
+ preCompleted.set(field, completed);
1220
+ const depState = wrapAsDependencySourceState(completed, fieldParser);
1221
+ if (depState) registerCompletedDependency(depState, registry);
1222
+ continue;
1223
+ }
1224
+ if (fieldParser.dependencyMetadata?.source != null && isUnmatchedDependencyState(fieldState, fieldParser) && (annotatedFieldState !== fieldState || isNonCliBoundSourceState(fieldState, fieldParser))) {
1225
+ const completed = fieldParser.complete(annotatedFieldState, withChildExecPath(exec, field));
1226
+ preCompleted.set(field, completed);
1227
+ const depState = wrapAsDependencySourceState(completed, fieldParser);
1228
+ if (depState) registerCompletedDependency(depState, registry);
1229
+ continue;
1230
+ }
938
1231
  if (Array.isArray(fieldState) && fieldState.length === 1 && isPendingDependencySourceState(fieldState[0])) {
939
- const completed = fieldParser.complete(fieldState, exec);
1232
+ const completed = fieldParser.complete(fieldState, withChildExecPath(exec, field));
940
1233
  preCompleted.set(field, completed);
941
1234
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
942
1235
  } else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
943
- const completed = fieldParser.complete([fieldParser.initialState], exec);
1236
+ const completed = fieldParser.complete([fieldParser.initialState], withChildExecPath(exec, field));
944
1237
  preCompleted.set(field, completed);
945
1238
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
946
1239
  } else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
947
1240
  const pendingState = fieldParser[wrappedDependencySourceMarker];
948
- const completed = fieldParser.complete([pendingState], exec);
1241
+ const completed = fieldParser.complete([pendingState], withChildExecPath(exec, field));
949
1242
  preCompleted.set(field, completed);
950
1243
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
951
1244
  } else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
952
- const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
953
- const completed = fieldParser.complete(annotatedFieldState, exec);
1245
+ const annotatedFieldState$1 = getAnnotatedFieldState(state, field, fieldParser);
1246
+ const completed = fieldParser.complete(annotatedFieldState$1, withChildExecPath(exec, field));
954
1247
  preCompleted.set(field, completed);
955
1248
  const depState = wrapAsDependencySourceState(completed, fieldParser);
956
1249
  if (depState) registerCompletedDependency(depState, registry);
@@ -973,22 +1266,37 @@ async function preCompleteAndRegisterDependenciesAsync(state, fieldParserPairs,
973
1266
  continue;
974
1267
  }
975
1268
  const fieldState = state[field];
1269
+ const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
1270
+ if (fieldParser.dependencyMetadata?.source?.getMissingSourceValue != null && isUnmatchedDependencyState(fieldState, fieldParser)) {
1271
+ const completed = await fieldParser.complete(annotatedFieldState, withChildExecPath(exec, field));
1272
+ preCompleted.set(field, completed);
1273
+ const depState = wrapAsDependencySourceState(completed, fieldParser);
1274
+ if (depState) registerCompletedDependency(depState, registry);
1275
+ continue;
1276
+ }
1277
+ if (fieldParser.dependencyMetadata?.source != null && isUnmatchedDependencyState(fieldState, fieldParser) && (annotatedFieldState !== fieldState || isNonCliBoundSourceState(fieldState, fieldParser))) {
1278
+ const completed = await fieldParser.complete(annotatedFieldState, withChildExecPath(exec, field));
1279
+ preCompleted.set(field, completed);
1280
+ const depState = wrapAsDependencySourceState(completed, fieldParser);
1281
+ if (depState) registerCompletedDependency(depState, registry);
1282
+ continue;
1283
+ }
976
1284
  if (Array.isArray(fieldState) && fieldState.length === 1 && isPendingDependencySourceState(fieldState[0])) {
977
- const completed = await fieldParser.complete(fieldState, exec);
1285
+ const completed = await fieldParser.complete(fieldState, withChildExecPath(exec, field));
978
1286
  preCompleted.set(field, completed);
979
1287
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
980
1288
  } else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
981
- const completed = await fieldParser.complete([fieldParser.initialState], exec);
1289
+ const completed = await fieldParser.complete([fieldParser.initialState], withChildExecPath(exec, field));
982
1290
  preCompleted.set(field, completed);
983
1291
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
984
1292
  } else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
985
1293
  const pendingState = fieldParser[wrappedDependencySourceMarker];
986
- const completed = await fieldParser.complete([pendingState], exec);
1294
+ const completed = await fieldParser.complete([pendingState], withChildExecPath(exec, field));
987
1295
  preCompleted.set(field, completed);
988
1296
  if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
989
1297
  } else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
990
- const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
991
- const completed = await fieldParser.complete(annotatedFieldState, exec);
1298
+ const annotatedFieldState$1 = getAnnotatedFieldState(state, field, fieldParser);
1299
+ const completed = await fieldParser.complete(annotatedFieldState$1, withChildExecPath(exec, field));
992
1300
  preCompleted.set(field, completed);
993
1301
  const depState = wrapAsDependencySourceState(completed, fieldParser);
994
1302
  if (depState) registerCompletedDependency(depState, registry);
@@ -996,153 +1304,6 @@ async function preCompleteAndRegisterDependenciesAsync(state, fieldParserPairs,
996
1304
  }
997
1305
  return preCompleted;
998
1306
  }
999
- /**
1000
- * Recursively collects dependency values from DependencySourceState objects
1001
- * found anywhere in the state tree.
1002
- * @internal
1003
- */
1004
- function collectDependencies(state, registry, visited = /* @__PURE__ */ new WeakSet()) {
1005
- if (state === null || state === void 0) return;
1006
- if (typeof state === "object") {
1007
- if (visited.has(state)) return;
1008
- visited.add(state);
1009
- }
1010
- if (isDependencySourceState(state)) {
1011
- const depId = state[dependencyId];
1012
- const result = state.result;
1013
- if (result.success) registry.set(depId, result.value);
1014
- return;
1015
- }
1016
- if (Array.isArray(state)) {
1017
- for (const item of state) collectDependencies(item, registry, visited);
1018
- return;
1019
- }
1020
- if (typeof state === "object" && !isDeferredParseState(state)) for (const key of Reflect.ownKeys(state)) collectDependencies(state[key], registry, visited);
1021
- }
1022
- /**
1023
- * Checks if a value is a plain object (created with `{}` or `Object.create(null)`).
1024
- * Class instances like `Temporal.PlainDate`, `URL`, `Date`, etc. return false.
1025
- * This is used to determine whether to recursively traverse an object when
1026
- * resolving deferred parse states - we only want to traverse plain objects
1027
- * that are part of the parser state structure, not user values.
1028
- */
1029
- function isPlainObject(value) {
1030
- if (typeof value !== "object" || value === null) return false;
1031
- const proto = Object.getPrototypeOf(value);
1032
- return proto === Object.prototype || proto === null;
1033
- }
1034
- /**
1035
- * Collects dependency values for a DeferredParseState from the registry.
1036
- * Returns the collected values array, or null if any required dependency
1037
- * is missing (and no default is available).
1038
- */
1039
- function collectDependencyValues(deferredState, registry) {
1040
- const depIds = deferredState.dependencyIds;
1041
- if (depIds && depIds.length > 0) {
1042
- const defaults$1 = deferredState.defaultValues;
1043
- const dependencyValues = [];
1044
- for (let i = 0; i < depIds.length; i++) {
1045
- const depId$1 = depIds[i];
1046
- if (registry.has(depId$1)) dependencyValues.push(registry.get(depId$1));
1047
- else if (defaults$1 && i < defaults$1.length) dependencyValues.push(defaults$1[i]);
1048
- else return null;
1049
- }
1050
- return dependencyValues;
1051
- }
1052
- const depId = deferredState.dependencyId;
1053
- if (registry.has(depId)) return registry.get(depId);
1054
- const defaults = deferredState.defaultValues;
1055
- if (defaults && defaults.length > 0) return defaults[0];
1056
- return null;
1057
- }
1058
- /**
1059
- * Recursively resolves DeferredParseState objects found anywhere in the state tree.
1060
- * Returns the resolved state (sync version).
1061
- *
1062
- * Only traverses:
1063
- * - DeferredParseState (to resolve it)
1064
- * - DependencySourceState (skipped, kept as-is)
1065
- * - Arrays (to find nested deferred states)
1066
- * - Plain objects (to find nested deferred states in parser state structures)
1067
- *
1068
- * Does NOT traverse class instances (e.g., Temporal.PlainDate, URL) since these
1069
- * are user values that should be preserved as-is.
1070
- */
1071
- function resolveDeferred(state, registry, visited = /* @__PURE__ */ new WeakSet()) {
1072
- if (state === null || state === void 0) return state;
1073
- if (typeof state === "object") {
1074
- if (visited.has(state)) return state;
1075
- visited.add(state);
1076
- }
1077
- if (isDeferredParseState(state)) {
1078
- const deferredState = state;
1079
- const dependencyValue = collectDependencyValues(deferredState, registry);
1080
- if (dependencyValue === null) return deferredState.preliminaryResult;
1081
- const reParseResult = deferredState.parser[parseWithDependency](deferredState.rawInput, dependencyValue);
1082
- if (reParseResult instanceof Promise) return deferredState.preliminaryResult;
1083
- return reParseResult;
1084
- }
1085
- if (isDependencySourceState(state)) return state;
1086
- if (Array.isArray(state)) return state.map((item) => resolveDeferred(item, registry, visited));
1087
- if (isPlainObject(state)) {
1088
- const resolved = {};
1089
- for (const key of Reflect.ownKeys(state)) resolved[key] = resolveDeferred(state[key], registry, visited);
1090
- return resolved;
1091
- }
1092
- return state;
1093
- }
1094
- function resolveDeferredParseStates(fieldStates, initialRegistry) {
1095
- const registry = initialRegistry ?? new DependencyRegistry();
1096
- collectDependencies(fieldStates, registry);
1097
- return resolveDeferred(fieldStates, registry);
1098
- }
1099
- /**
1100
- * Recursively resolves DeferredParseState objects found anywhere in the state tree.
1101
- * Returns the resolved state (async version).
1102
- *
1103
- * Only traverses:
1104
- * - DeferredParseState (to resolve it)
1105
- * - DependencySourceState (skipped, kept as-is)
1106
- * - Arrays (to find nested deferred states)
1107
- * - Plain objects (to find nested deferred states in parser state structures)
1108
- *
1109
- * Does NOT traverse class instances (e.g., Temporal.PlainDate, URL) since these
1110
- * are user values that should be preserved as-is.
1111
- */
1112
- async function resolveDeferredAsync(state, registry, visited = /* @__PURE__ */ new WeakSet()) {
1113
- if (state === null || state === void 0) return state;
1114
- if (typeof state === "object") {
1115
- if (visited.has(state)) return state;
1116
- visited.add(state);
1117
- }
1118
- if (isDeferredParseState(state)) {
1119
- const deferredState = state;
1120
- const dependencyValue = collectDependencyValues(deferredState, registry);
1121
- if (dependencyValue === null) return deferredState.preliminaryResult;
1122
- const reParseResult = deferredState.parser[parseWithDependency](deferredState.rawInput, dependencyValue);
1123
- return Promise.resolve(reParseResult);
1124
- }
1125
- if (isDependencySourceState(state)) return state;
1126
- if (Array.isArray(state)) return Promise.all(state.map((item) => resolveDeferredAsync(item, registry, visited)));
1127
- if (isPlainObject(state)) {
1128
- const resolved = {};
1129
- const keys = Reflect.ownKeys(state);
1130
- await Promise.all(keys.map(async (key) => {
1131
- resolved[key] = await resolveDeferredAsync(state[key], registry, visited);
1132
- }));
1133
- return resolved;
1134
- }
1135
- return state;
1136
- }
1137
- /**
1138
- * Async version of resolveDeferredParseStates for async parsers.
1139
- * @internal
1140
- */
1141
- async function resolveDeferredParseStatesAsync(fieldStates, initialRegistry) {
1142
- const registry = initialRegistry ?? new DependencyRegistry();
1143
- collectDependencies(fieldStates, registry);
1144
- return await resolveDeferredAsync(fieldStates, registry);
1145
- }
1146
1307
  function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1147
1308
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
1148
1309
  if (label != null) validateLabel(label);
@@ -1164,7 +1325,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1164
1325
  return state;
1165
1326
  };
1166
1327
  const inheritedFieldStateCache = /* @__PURE__ */ new WeakMap();
1167
- const createFieldStateGetter = (parentState) => {
1328
+ const createFieldStateGetter = (parentState, annotateChildState = getAnnotatedChildState) => {
1168
1329
  return (field, parser) => {
1169
1330
  const fieldKey = field;
1170
1331
  const cache = parentState != null && typeof parentState === "object" ? inheritedFieldStateCache.get(parentState) ?? (() => {
@@ -1174,16 +1335,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1174
1335
  })() : void 0;
1175
1336
  if (cache?.has(fieldKey)) return cache.get(fieldKey);
1176
1337
  const sourceState = parentState != null && typeof parentState === "object" && fieldKey in parentState ? parentState[fieldKey] : parser.initialState;
1177
- if (sourceState == null || typeof sourceState !== "object") {
1178
- cache?.set(fieldKey, sourceState);
1179
- return sourceState;
1180
- }
1181
- const annotations = getAnnotations(parentState);
1182
- if (annotations === void 0 || getAnnotations(sourceState) === annotations) {
1183
- cache?.set(fieldKey, sourceState);
1184
- return sourceState;
1185
- }
1186
- const inheritedState = Reflect.get(parser, inheritParentAnnotationsKey) === true ? injectAnnotations(sourceState, annotations) : inheritAnnotations(parentState, sourceState);
1338
+ const inheritedState = annotateChildState(parentState, sourceState, parser);
1187
1339
  cache?.set(fieldKey, inheritedState);
1188
1340
  return inheritedState;
1189
1341
  };
@@ -1212,21 +1364,24 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1212
1364
  let madeProgress = true;
1213
1365
  while (madeProgress && currentContext.buffer.length > 0) {
1214
1366
  madeProgress = false;
1215
- const getFieldState = createFieldStateGetter(currentContext.state);
1367
+ const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
1216
1368
  for (const [field, parser] of parserPairs) {
1217
- const result = parser.parse({
1218
- ...currentContext,
1219
- state: getFieldState(field, parser)
1220
- });
1369
+ const result = parser.parse(withChildContext(currentContext, field, getFieldState(field, parser)));
1221
1370
  if (result.success && result.consumed.length > 0) {
1371
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1222
1372
  currentContext = {
1223
1373
  ...currentContext,
1224
1374
  buffer: result.next.buffer,
1225
1375
  optionsTerminated: result.next.optionsTerminated,
1226
1376
  state: {
1227
1377
  ...currentContext.state,
1228
- [field]: result.next.state
1229
- }
1378
+ [field]: getAnnotatedChildState(currentContext.state, result.next.state, parser)
1379
+ },
1380
+ ...mergedExec != null ? {
1381
+ trace: mergedExec.trace,
1382
+ exec: mergedExec,
1383
+ dependencyRegistry: mergedExec.dependencyRegistry
1384
+ } : {}
1230
1385
  };
1231
1386
  allConsumed.push(...result.consumed);
1232
1387
  anySuccess = true;
@@ -1245,7 +1400,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1245
1400
  const getFieldState = createFieldStateGetter(context.state);
1246
1401
  for (const [field, parser] of parserPairs) {
1247
1402
  const fieldState = getFieldState(field, parser);
1248
- const completeResult = parser.complete(fieldState, context.exec);
1403
+ const completeResult = parser.complete(fieldState, withChildExecPath(context.exec, field));
1249
1404
  if (!completeResult.success) {
1250
1405
  allCanComplete = false;
1251
1406
  break;
@@ -1270,22 +1425,25 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1270
1425
  let madeProgress = true;
1271
1426
  while (madeProgress && currentContext.buffer.length > 0) {
1272
1427
  madeProgress = false;
1273
- const getFieldState = createFieldStateGetter(currentContext.state);
1428
+ const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
1274
1429
  for (const [field, parser] of parserPairs) {
1275
- const resultOrPromise = parser.parse({
1276
- ...currentContext,
1277
- state: getFieldState(field, parser)
1278
- });
1430
+ const resultOrPromise = parser.parse(withChildContext(currentContext, field, getFieldState(field, parser)));
1279
1431
  const result = await resultOrPromise;
1280
1432
  if (result.success && result.consumed.length > 0) {
1433
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1281
1434
  currentContext = {
1282
1435
  ...currentContext,
1283
1436
  buffer: result.next.buffer,
1284
1437
  optionsTerminated: result.next.optionsTerminated,
1285
1438
  state: {
1286
1439
  ...currentContext.state,
1287
- [field]: result.next.state
1288
- }
1440
+ [field]: getAnnotatedChildState(currentContext.state, result.next.state, parser)
1441
+ },
1442
+ ...mergedExec != null ? {
1443
+ trace: mergedExec.trace,
1444
+ exec: mergedExec,
1445
+ dependencyRegistry: mergedExec.dependencyRegistry
1446
+ } : {}
1289
1447
  };
1290
1448
  allConsumed.push(...result.consumed);
1291
1449
  anySuccess = true;
@@ -1304,7 +1462,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1304
1462
  const getFieldState = createFieldStateGetter(context.state);
1305
1463
  for (const [field, parser] of parserPairs) {
1306
1464
  const fieldState = getFieldState(field, parser);
1307
- const completeResult = await parser.complete(fieldState, context.exec);
1465
+ const completeResult = await parser.complete(fieldState, withChildExecPath(context.exec, field));
1308
1466
  if (!completeResult.success) {
1309
1467
  allCanComplete = false;
1310
1468
  break;
@@ -1343,7 +1501,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1343
1501
  ...exec,
1344
1502
  dependencyRuntime: runtime
1345
1503
  };
1346
- const typedParserPairs = parserPairs;
1504
+ const typedParserPairs = filterExcludedFieldParsers(parserPairs, exec?.excludedSourceFields);
1347
1505
  const preCompleted = preCompleteAndRegisterDependencies(state, typedParserPairs, runtime.registry, childExec);
1348
1506
  const phase3Exec = {
1349
1507
  ...childExec,
@@ -1356,6 +1514,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1356
1514
  const fieldParser = parsers[field];
1357
1515
  annotatedState[fieldKey] = getFieldState(field, fieldParser);
1358
1516
  }
1517
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromPairs(typedParserPairs, annotatedState, exec?.path), new Set(preCompleted.keys())), runtime);
1359
1518
  const resolvedFieldStates = resolveStateWithRuntime(annotatedState, runtime);
1360
1519
  const result = {};
1361
1520
  const deferredKeys = /* @__PURE__ */ new Map();
@@ -1368,7 +1527,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1368
1527
  if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
1369
1528
  else {
1370
1529
  const fieldState = resolvedFieldStates[fieldKey];
1371
- valueResult = unwrapCompleteResult(fieldParser.complete(fieldState, phase3Exec));
1530
+ valueResult = unwrapCompleteResult(fieldParser.complete(fieldState, withChildExecPath(phase3Exec, fieldKey)));
1372
1531
  }
1373
1532
  if (valueResult.success) {
1374
1533
  result[fieldKey] = valueResult.value;
@@ -1395,7 +1554,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1395
1554
  ...exec,
1396
1555
  dependencyRuntime: runtime
1397
1556
  };
1398
- const asyncParserPairs = parserPairs;
1557
+ const asyncParserPairs = filterExcludedFieldParsers(parserPairs, exec?.excludedSourceFields);
1399
1558
  const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, asyncParserPairs, runtime.registry, childExec);
1400
1559
  const phase3Exec = {
1401
1560
  ...childExec,
@@ -1408,20 +1567,12 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1408
1567
  const fieldParser = parsers[field];
1409
1568
  annotatedState[fieldKey] = getFieldState(field, fieldParser);
1410
1569
  }
1570
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromPairs(asyncParserPairs, annotatedState, exec?.path), new Set(preCompleted.keys())), runtime);
1411
1571
  const resolvedFieldStates = await resolveStateWithRuntimeAsync(annotatedState, runtime);
1412
1572
  const result = {};
1413
1573
  const deferredKeys = /* @__PURE__ */ new Map();
1414
1574
  let hasDeferred = false;
1415
- for (const field of parserKeys) {
1416
- const fieldKey = field;
1417
- const fieldParser = parsers[field];
1418
- let valueResult;
1419
- const preCompletedResult = preCompleted.get(fieldKey);
1420
- if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
1421
- else {
1422
- const fieldState = resolvedFieldStates[fieldKey];
1423
- valueResult = unwrapCompleteResult(await fieldParser.complete(fieldState, phase3Exec));
1424
- }
1575
+ const applyValueResult = (fieldKey, valueResult) => {
1425
1576
  if (valueResult.success) {
1426
1577
  result[fieldKey] = valueResult.value;
1427
1578
  if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(fieldKey, valueResult.deferredKeys);
@@ -1431,6 +1582,41 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1431
1582
  success: false,
1432
1583
  error: valueResult.error
1433
1584
  };
1585
+ return void 0;
1586
+ };
1587
+ const concurrentFields = [];
1588
+ const deferredFields = [];
1589
+ for (const field of parserKeys) {
1590
+ const fieldKey = field;
1591
+ const fieldParser = parsers[field];
1592
+ const preCompletedResult = preCompleted.get(fieldKey);
1593
+ if (preCompletedResult !== void 0) {
1594
+ const failure = applyValueResult(fieldKey, unwrapCompleteResult(preCompletedResult));
1595
+ if (failure != null) return failure;
1596
+ continue;
1597
+ }
1598
+ if (typeof fieldParser.shouldDeferCompletion === "function" && fieldParser.shouldDeferCompletion(resolvedFieldStates[fieldKey], withChildExecPath(phase3Exec, fieldKey)) === true) deferredFields.push(field);
1599
+ else concurrentFields.push(field);
1600
+ }
1601
+ const concurrentResults = await Promise.all(concurrentFields.map(async (field) => {
1602
+ const fieldKey = field;
1603
+ const fieldParser = parsers[field];
1604
+ const valueResult = unwrapCompleteResult(await fieldParser.complete(resolvedFieldStates[fieldKey], withChildExecPath(phase3Exec, fieldKey)));
1605
+ return {
1606
+ fieldKey,
1607
+ valueResult
1608
+ };
1609
+ }));
1610
+ for (const { fieldKey, valueResult } of concurrentResults) {
1611
+ const failure = applyValueResult(fieldKey, valueResult);
1612
+ if (failure != null) return failure;
1613
+ }
1614
+ for (const field of deferredFields) {
1615
+ const fieldKey = field;
1616
+ const fieldParser = parsers[field];
1617
+ const valueResult = unwrapCompleteResult(await fieldParser.complete(resolvedFieldStates[fieldKey], withChildExecPath(phase3Exec, fieldKey)));
1618
+ const failure = applyValueResult(fieldKey, valueResult);
1619
+ if (failure != null) return failure;
1434
1620
  }
1435
1621
  const isDeferred = deferredKeys.size > 0 || hasDeferred;
1436
1622
  return {
@@ -1498,37 +1684,226 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1498
1684
  configurable: true,
1499
1685
  enumerable: false
1500
1686
  });
1687
+ defineInheritedAnnotationParser(objectParser);
1501
1688
  return objectParser;
1502
1689
  }
1503
1690
  function suggestTupleSync(context, prefix, parsers) {
1504
1691
  const suggestions = [];
1505
- const stateArray = context.state;
1692
+ const advanced = advanceTupleSuggestContextSync(context, parsers);
1693
+ const advancedContext = advanced.context;
1694
+ const stateArray = advancedContext.state;
1695
+ const runtime = createDependencyRuntimeContext(advancedContext.dependencyRegistry?.clone());
1696
+ if (stateArray && Array.isArray(stateArray)) {
1697
+ const nodes = buildSuggestRuntimeNodesFromArray(parsers, stateArray, advancedContext.exec?.path);
1698
+ collectExplicitSourceValues(nodes, runtime);
1699
+ fillMissingSourceDefaults(nodes, runtime);
1700
+ collectSourcesFromState(stateArray, runtime);
1701
+ completeDependencySourceDefaults({
1702
+ ...advancedContext,
1703
+ state: createAnnotatedArrayStateRecord(stateArray)
1704
+ }, buildIndexedParserPairs(parsers), runtime.registry, advancedContext.exec);
1705
+ }
1706
+ markFailedTupleSuggestSources(parsers, stateArray, advanced.failedParserIndexes, runtime, advancedContext.exec?.path);
1707
+ const contextWithRegistry = {
1708
+ ...advancedContext,
1709
+ dependencyRegistry: runtime.registry,
1710
+ ...advancedContext.exec != null ? { exec: {
1711
+ ...advancedContext.exec,
1712
+ dependencyRuntime: runtime,
1713
+ dependencyRegistry: runtime.registry
1714
+ } } : {}
1715
+ };
1506
1716
  for (let i = 0; i < parsers.length; i++) {
1507
1717
  const parser = parsers[i];
1508
1718
  const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
1509
- const parserSuggestions = parser.suggest({
1510
- ...context,
1511
- state: parserState
1512
- }, prefix);
1719
+ const parserSuggestions = parser.suggest(withChildContext(contextWithRegistry, i, parserState, parser), prefix);
1513
1720
  suggestions.push(...parserSuggestions);
1514
1721
  }
1515
1722
  return deduplicateSuggestions(suggestions);
1516
1723
  }
1517
1724
  async function* suggestTupleAsync(context, prefix, parsers) {
1518
1725
  const suggestions = [];
1519
- const stateArray = context.state;
1726
+ const advanced = await advanceTupleSuggestContextAsync(context, parsers);
1727
+ const advancedContext = advanced.context;
1728
+ const stateArray = advancedContext.state;
1729
+ const runtime = createDependencyRuntimeContext(advancedContext.dependencyRegistry?.clone());
1730
+ if (stateArray && Array.isArray(stateArray)) {
1731
+ const nodes = buildSuggestRuntimeNodesFromArray(parsers, stateArray, advancedContext.exec?.path);
1732
+ await collectExplicitSourceValuesAsync(nodes, runtime);
1733
+ await fillMissingSourceDefaultsAsync(nodes, runtime);
1734
+ collectSourcesFromState(stateArray, runtime);
1735
+ await completeDependencySourceDefaultsAsync({
1736
+ ...advancedContext,
1737
+ state: createAnnotatedArrayStateRecord(stateArray)
1738
+ }, buildIndexedParserPairs(parsers), runtime.registry, advancedContext.exec);
1739
+ }
1740
+ markFailedTupleSuggestSources(parsers, stateArray, advanced.failedParserIndexes, runtime, advancedContext.exec?.path);
1741
+ const contextWithRegistry = {
1742
+ ...advancedContext,
1743
+ dependencyRegistry: runtime.registry,
1744
+ ...advancedContext.exec != null ? { exec: {
1745
+ ...advancedContext.exec,
1746
+ dependencyRuntime: runtime,
1747
+ dependencyRegistry: runtime.registry
1748
+ } } : {}
1749
+ };
1520
1750
  for (let i = 0; i < parsers.length; i++) {
1521
1751
  const parser = parsers[i];
1522
1752
  const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
1523
- const parserSuggestions = parser.suggest({
1524
- ...context,
1525
- state: parserState
1526
- }, prefix);
1753
+ const parserSuggestions = parser.suggest(withChildContext(contextWithRegistry, i, parserState, parser), prefix);
1527
1754
  if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
1528
1755
  else suggestions.push(...parserSuggestions);
1529
1756
  }
1530
1757
  yield* deduplicateSuggestions(suggestions);
1531
1758
  }
1759
+ function advanceTupleSuggestContextSync(context, parsers) {
1760
+ let currentContext = context;
1761
+ const matchedParsers = /* @__PURE__ */ new Set();
1762
+ while (currentContext.buffer.length > 0 && matchedParsers.size < parsers.length) {
1763
+ let foundMatch = false;
1764
+ let failedParserIndexes = [];
1765
+ let deepestFailure = 0;
1766
+ const stateArray = Array.isArray(currentContext.state) ? [...currentContext.state] : parsers.map((parser) => parser.initialState);
1767
+ const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1768
+ for (const [parser, index] of remainingParsers) {
1769
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1770
+ if (result.success && result.consumed.length > 0) {
1771
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((state, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : state));
1772
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1773
+ currentContext = {
1774
+ ...currentContext,
1775
+ buffer: result.next.buffer,
1776
+ optionsTerminated: result.next.optionsTerminated,
1777
+ state: newStateArray,
1778
+ ...mergedExec != null ? {
1779
+ exec: mergedExec,
1780
+ dependencyRegistry: mergedExec.dependencyRegistry
1781
+ } : {}
1782
+ };
1783
+ matchedParsers.add(index);
1784
+ foundMatch = true;
1785
+ break;
1786
+ } else if (!result.success && result.consumed > 0) {
1787
+ if (result.consumed > deepestFailure) {
1788
+ deepestFailure = result.consumed;
1789
+ failedParserIndexes = [index];
1790
+ } else if (result.consumed === deepestFailure) failedParserIndexes.push(index);
1791
+ }
1792
+ }
1793
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
1794
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1795
+ if (result.success && result.consumed.length < 1) {
1796
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((state, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : state));
1797
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1798
+ currentContext = {
1799
+ ...currentContext,
1800
+ state: newStateArray,
1801
+ ...mergedExec != null ? {
1802
+ exec: mergedExec,
1803
+ dependencyRegistry: mergedExec.dependencyRegistry
1804
+ } : {}
1805
+ };
1806
+ matchedParsers.add(index);
1807
+ foundMatch = true;
1808
+ break;
1809
+ } else if (!result.success && result.consumed < 1) {
1810
+ matchedParsers.add(index);
1811
+ foundMatch = true;
1812
+ break;
1813
+ }
1814
+ }
1815
+ if (!foundMatch) return {
1816
+ context: currentContext,
1817
+ failedParserIndexes
1818
+ };
1819
+ }
1820
+ return {
1821
+ context: currentContext,
1822
+ failedParserIndexes: []
1823
+ };
1824
+ }
1825
+ async function advanceTupleSuggestContextAsync(context, parsers) {
1826
+ let currentContext = context;
1827
+ const matchedParsers = /* @__PURE__ */ new Set();
1828
+ while (currentContext.buffer.length > 0 && matchedParsers.size < parsers.length) {
1829
+ let foundMatch = false;
1830
+ let failedParserIndexes = [];
1831
+ let deepestFailure = 0;
1832
+ const stateArray = Array.isArray(currentContext.state) ? [...currentContext.state] : parsers.map((parser) => parser.initialState);
1833
+ const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1834
+ for (const [parser, index] of remainingParsers) {
1835
+ const result = await parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1836
+ if (result.success && result.consumed.length > 0) {
1837
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((state, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : state));
1838
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1839
+ currentContext = {
1840
+ ...currentContext,
1841
+ buffer: result.next.buffer,
1842
+ optionsTerminated: result.next.optionsTerminated,
1843
+ state: newStateArray,
1844
+ ...mergedExec != null ? {
1845
+ exec: mergedExec,
1846
+ dependencyRegistry: mergedExec.dependencyRegistry
1847
+ } : {}
1848
+ };
1849
+ matchedParsers.add(index);
1850
+ foundMatch = true;
1851
+ break;
1852
+ } else if (!result.success && result.consumed > 0) {
1853
+ if (result.consumed > deepestFailure) {
1854
+ deepestFailure = result.consumed;
1855
+ failedParserIndexes = [index];
1856
+ } else if (result.consumed === deepestFailure) failedParserIndexes.push(index);
1857
+ }
1858
+ }
1859
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
1860
+ const result = await parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1861
+ if (result.success && result.consumed.length < 1) {
1862
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((state, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : state));
1863
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1864
+ currentContext = {
1865
+ ...currentContext,
1866
+ state: newStateArray,
1867
+ ...mergedExec != null ? {
1868
+ exec: mergedExec,
1869
+ dependencyRegistry: mergedExec.dependencyRegistry
1870
+ } : {}
1871
+ };
1872
+ matchedParsers.add(index);
1873
+ foundMatch = true;
1874
+ break;
1875
+ } else if (!result.success && result.consumed < 1) {
1876
+ matchedParsers.add(index);
1877
+ foundMatch = true;
1878
+ break;
1879
+ }
1880
+ }
1881
+ if (!foundMatch) return {
1882
+ context: currentContext,
1883
+ failedParserIndexes
1884
+ };
1885
+ }
1886
+ return {
1887
+ context: currentContext,
1888
+ failedParserIndexes: []
1889
+ };
1890
+ }
1891
+ function markFailedTupleSuggestSources(parsers, stateArray, failedParserIndexes, runtime, parentPath) {
1892
+ if (failedParserIndexes.length < 1) return;
1893
+ const prefix = parentPath ?? [];
1894
+ const failedSourceIds = /* @__PURE__ */ new Set();
1895
+ for (const index of failedParserIndexes) {
1896
+ const parser = parsers[index];
1897
+ if (parser == null) continue;
1898
+ const parserState = stateArray && Array.isArray(stateArray) ? stateArray[index] : parser.initialState;
1899
+ const nodes = getParserSuggestRuntimeNodes(parser, getAnnotatedChildState(stateArray, parserState, parser), [...prefix, index]);
1900
+ for (const node of nodes) {
1901
+ const sourceId = node.parser.dependencyMetadata?.source?.sourceId;
1902
+ if (sourceId != null) failedSourceIds.add(sourceId);
1903
+ }
1904
+ }
1905
+ for (const sourceId of failedSourceIds) runtime.markSourceFailed(sourceId);
1906
+ }
1532
1907
  function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1533
1908
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
1534
1909
  if (label != null) validateLabel(label);
@@ -1557,17 +1932,19 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1557
1932
  const stateArray = currentContext.state;
1558
1933
  const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1559
1934
  for (const [parser, index] of remainingParsers) {
1560
- const result = parser.parse({
1561
- ...currentContext,
1562
- state: stateArray[index]
1563
- });
1935
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1564
1936
  if (result.success && result.consumed.length > 0) {
1565
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1937
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
1938
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1566
1939
  currentContext = {
1567
1940
  ...currentContext,
1568
1941
  buffer: result.next.buffer,
1569
1942
  optionsTerminated: result.next.optionsTerminated,
1570
- state: newStateArray
1943
+ state: newStateArray,
1944
+ ...mergedExec != null ? {
1945
+ exec: mergedExec,
1946
+ dependencyRegistry: mergedExec.dependencyRegistry
1947
+ } : {}
1571
1948
  };
1572
1949
  allConsumed.push(...result.consumed);
1573
1950
  matchedParsers.add(index);
@@ -1576,15 +1953,17 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1576
1953
  } else if (!result.success && error.consumed < result.consumed) error = result;
1577
1954
  }
1578
1955
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
1579
- const result = parser.parse({
1580
- ...currentContext,
1581
- state: stateArray[index]
1582
- });
1956
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1583
1957
  if (result.success && result.consumed.length < 1) {
1584
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1958
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
1959
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1585
1960
  currentContext = {
1586
1961
  ...currentContext,
1587
- state: newStateArray
1962
+ state: newStateArray,
1963
+ ...mergedExec != null ? {
1964
+ exec: mergedExec,
1965
+ dependencyRegistry: mergedExec.dependencyRegistry
1966
+ } : {}
1588
1967
  };
1589
1968
  matchedParsers.add(index);
1590
1969
  foundMatch = true;
@@ -1619,18 +1998,20 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1619
1998
  const stateArray = currentContext.state;
1620
1999
  const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1621
2000
  for (const [parser, index] of remainingParsers) {
1622
- const resultOrPromise = parser.parse({
1623
- ...currentContext,
1624
- state: stateArray[index]
1625
- });
2001
+ const resultOrPromise = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1626
2002
  const result = await resultOrPromise;
1627
2003
  if (result.success && result.consumed.length > 0) {
1628
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
2004
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
2005
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1629
2006
  currentContext = {
1630
2007
  ...currentContext,
1631
2008
  buffer: result.next.buffer,
1632
2009
  optionsTerminated: result.next.optionsTerminated,
1633
- state: newStateArray
2010
+ state: newStateArray,
2011
+ ...mergedExec != null ? {
2012
+ exec: mergedExec,
2013
+ dependencyRegistry: mergedExec.dependencyRegistry
2014
+ } : {}
1634
2015
  };
1635
2016
  allConsumed.push(...result.consumed);
1636
2017
  matchedParsers.add(index);
@@ -1639,16 +2020,18 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1639
2020
  } else if (!result.success && error.consumed < result.consumed) error = result;
1640
2021
  }
1641
2022
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
1642
- const resultOrPromise = parser.parse({
1643
- ...currentContext,
1644
- state: stateArray[index]
1645
- });
2023
+ const resultOrPromise = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
1646
2024
  const result = await resultOrPromise;
1647
2025
  if (result.success && result.consumed.length < 1) {
1648
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
2026
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
2027
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
1649
2028
  currentContext = {
1650
2029
  ...currentContext,
1651
- state: newStateArray
2030
+ state: newStateArray,
2031
+ ...mergedExec != null ? {
2032
+ exec: mergedExec,
2033
+ dependencyRegistry: mergedExec.dependencyRegistry
2034
+ } : {}
1652
2035
  };
1653
2036
  matchedParsers.add(index);
1654
2037
  foundMatch = true;
@@ -1674,6 +2057,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1674
2057
  $mode: combinedMode,
1675
2058
  $valueType: [],
1676
2059
  $stateType: [],
2060
+ [fieldParsersKey]: parsers.map((parser, index) => [String(index), parser]),
1677
2061
  usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
1678
2062
  leadingNames: sharedBufferLeadingNames(parsers),
1679
2063
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
@@ -1690,9 +2074,10 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1690
2074
  ...exec,
1691
2075
  dependencyRuntime: runtime
1692
2076
  };
1693
- const tuplePairs = syncParsers.map((p, i) => [String(i), p]);
1694
- const tupleState = Object.fromEntries(stateArray.map((s, i) => [String(i), s]));
2077
+ const tuplePairs = buildIndexedParserPairs(syncParsers);
2078
+ const tupleState = createAnnotatedArrayStateRecord(stateArray);
1695
2079
  const preCompleted = preCompleteAndRegisterDependencies(tupleState, tuplePairs, runtime.registry, childExec);
2080
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
1696
2081
  const phase3Exec = {
1697
2082
  ...childExec,
1698
2083
  preCompletedByParser: void 0
@@ -1708,7 +2093,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1708
2093
  if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
1709
2094
  else {
1710
2095
  const elementState = prepareStateForCompletion(resolvedArray[i], elementParser);
1711
- valueResult = unwrapCompleteResult(elementParser.complete(elementState, phase3Exec));
2096
+ valueResult = unwrapCompleteResult(elementParser.complete(elementState, withChildExecPath(phase3Exec, i)));
1712
2097
  }
1713
2098
  if (valueResult.success) {
1714
2099
  result[i] = valueResult.value;
@@ -1736,9 +2121,10 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1736
2121
  ...exec,
1737
2122
  dependencyRuntime: runtime
1738
2123
  };
1739
- const tuplePairs = parsers.map((p, i) => [String(i), p]);
1740
- const tupleState = Object.fromEntries(stateArray.map((s, i) => [String(i), s]));
2124
+ const tuplePairs = buildIndexedParserPairs(parsers);
2125
+ const tupleState = createAnnotatedArrayStateRecord(stateArray);
1741
2126
  const preCompleted = await preCompleteAndRegisterDependenciesAsync(tupleState, tuplePairs, runtime.registry, childExec);
2127
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
1742
2128
  const phase3Exec = {
1743
2129
  ...childExec,
1744
2130
  preCompletedByParser: void 0
@@ -1754,7 +2140,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1754
2140
  if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
1755
2141
  else {
1756
2142
  const elementState = prepareStateForCompletion(resolvedArray[i], elementParser);
1757
- valueResult = unwrapCompleteResult(await elementParser.complete(elementState, phase3Exec));
2143
+ valueResult = unwrapCompleteResult(await elementParser.complete(elementState, withChildExecPath(phase3Exec, i)));
1758
2144
  }
1759
2145
  if (valueResult.success) {
1760
2146
  result[i] = valueResult.value;
@@ -1834,6 +2220,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1834
2220
  configurable: true,
1835
2221
  enumerable: false
1836
2222
  });
2223
+ defineInheritedAnnotationParser(tupleParser);
1837
2224
  return tupleParser;
1838
2225
  }
1839
2226
  function merge(...args) {
@@ -1857,18 +2244,25 @@ function merge(...args) {
1857
2244
  const syncSorted = syncWithIndex.toSorted(([a], [b]) => b.priority - a.priority);
1858
2245
  const syncParsers = syncSorted.map(([p]) => p);
1859
2246
  if (!options.allowDuplicates) checkDuplicateOptionNames(sorted.map(([parser, originalIndex]) => [String(originalIndex), parser.usage]));
2247
+ const mergedFieldParsers = collectChildFieldParsers(parsers);
2248
+ const duplicateOutputFieldNames = collectDuplicateFieldNames(mergedFieldParsers);
2249
+ const parserStateKey = (index) => `__parser_${index}`;
2250
+ const localObjectStateKey = (index) => `__merge_local_${index}`;
2251
+ const shouldPreserveLocalChildState = (parser) => parser.initialState != null && typeof parser.initialState === "object" && Object.keys(parser.initialState).some((field) => duplicateOutputFieldNames.has(field));
1860
2252
  const initialState = {};
1861
2253
  for (let i = 0; i < parsers.length; i++) {
1862
2254
  const parser = parsers[i];
1863
- if (parser.initialState === void 0) initialState[`__parser_${i}`] = void 0;
2255
+ if (parser.initialState === void 0) initialState[parserStateKey(i)] = void 0;
1864
2256
  else if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
1865
2257
  }
1866
2258
  const extractParserState = (parser, context, index) => {
1867
2259
  if (parser.initialState === void 0) {
1868
- const key = `__parser_${index}`;
2260
+ const key = parserStateKey(index);
1869
2261
  if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
1870
2262
  return void 0;
1871
2263
  } else if (parser.initialState && typeof parser.initialState === "object") {
2264
+ const localStateKey = localObjectStateKey(index);
2265
+ if (shouldPreserveLocalChildState(parser) && context.state && typeof context.state === "object" && localStateKey in context.state) return context.state[localStateKey];
1872
2266
  if (context.state && typeof context.state === "object") {
1873
2267
  const extractedState = {};
1874
2268
  for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
@@ -1878,9 +2272,9 @@ function merge(...args) {
1878
2272
  }
1879
2273
  return parser.initialState;
1880
2274
  };
1881
- const mergeResultState = (parser, context, result, index) => {
2275
+ const mergeResultState = (parser, context, parserState, result, index) => {
1882
2276
  if (parser.initialState === void 0) {
1883
- const key = `__parser_${index}`;
2277
+ const key = parserStateKey(index);
1884
2278
  if (result.success) {
1885
2279
  if (result.consumed.length > 0 || result.next.state !== void 0) return {
1886
2280
  ...context.state,
@@ -1889,10 +2283,17 @@ function merge(...args) {
1889
2283
  }
1890
2284
  return { ...context.state };
1891
2285
  }
1892
- return result.success ? {
2286
+ if (!result.success) return { ...context.state };
2287
+ const mergedState = {
1893
2288
  ...context.state,
1894
2289
  ...result.next.state
1895
- } : { ...context.state };
2290
+ };
2291
+ if (!shouldPreserveLocalChildState(parser)) return mergedState;
2292
+ if (result.consumed.length === 0 && result.next.state === parserState) return mergedState;
2293
+ return {
2294
+ ...mergedState,
2295
+ [localObjectStateKey(index)]: result.next.state
2296
+ };
1896
2297
  };
1897
2298
  const parseSync = (context) => {
1898
2299
  let currentContext = context;
@@ -1900,17 +2301,19 @@ function merge(...args) {
1900
2301
  for (let i = 0; i < syncParsers.length; i++) {
1901
2302
  const parser = syncParsers[i];
1902
2303
  const parserState = extractParserState(parser, currentContext, i);
1903
- const result = parser.parse({
1904
- ...currentContext,
1905
- state: parserState
1906
- });
2304
+ const result = parser.parse(withChildContext(currentContext, i, parserState));
1907
2305
  if (result.success) {
1908
- const newState = mergeResultState(parser, currentContext, result, i);
2306
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2307
+ const newState = mergeResultState(parser, currentContext, parserState, result, i);
1909
2308
  const newContext = {
1910
2309
  ...currentContext,
1911
2310
  buffer: result.next.buffer,
1912
2311
  optionsTerminated: result.next.optionsTerminated,
1913
- state: newState
2312
+ state: newState,
2313
+ ...mergedExec != null ? {
2314
+ exec: mergedExec,
2315
+ dependencyRegistry: mergedExec.dependencyRegistry
2316
+ } : {}
1914
2317
  };
1915
2318
  if (result.consumed.length > 0) return {
1916
2319
  success: true,
@@ -1943,18 +2346,20 @@ function merge(...args) {
1943
2346
  for (let i = 0; i < parsers.length; i++) {
1944
2347
  const parser = parsers[i];
1945
2348
  const parserState = extractParserState(parser, currentContext, i);
1946
- const resultOrPromise = parser.parse({
1947
- ...currentContext,
1948
- state: parserState
1949
- });
2349
+ const resultOrPromise = parser.parse(withChildContext(currentContext, i, parserState));
1950
2350
  const result = await resultOrPromise;
1951
2351
  if (result.success) {
1952
- const newState = mergeResultState(parser, currentContext, result, i);
2352
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2353
+ const newState = mergeResultState(parser, currentContext, parserState, result, i);
1953
2354
  const newContext = {
1954
2355
  ...currentContext,
1955
2356
  buffer: result.next.buffer,
1956
2357
  optionsTerminated: result.next.optionsTerminated,
1957
- state: newState
2358
+ state: newState,
2359
+ ...mergedExec != null ? {
2360
+ exec: mergedExec,
2361
+ dependencyRegistry: mergedExec.dependencyRegistry
2362
+ } : {}
1958
2363
  };
1959
2364
  if (result.consumed.length > 0) return {
1960
2365
  success: true,
@@ -1981,7 +2386,6 @@ function merge(...args) {
1981
2386
  error: message`No matching option or argument found.`
1982
2387
  };
1983
2388
  };
1984
- const mergedFieldParsers = collectChildFieldParsers(parsers);
1985
2389
  const mergeParser = {
1986
2390
  $mode: combinedMode,
1987
2391
  $valueType: [],
@@ -1999,10 +2403,12 @@ function merge(...args) {
1999
2403
  complete(state, exec) {
2000
2404
  const extractCompleteState = (parser, resolvedState, index) => {
2001
2405
  if (parser.initialState === void 0) {
2002
- const key = `__parser_${index}`;
2406
+ const key = parserStateKey(index);
2003
2407
  if (resolvedState && typeof resolvedState === "object" && key in resolvedState) return resolvedState[key];
2004
2408
  return void 0;
2005
2409
  } else if (parser.initialState && typeof parser.initialState === "object") {
2410
+ const key = localObjectStateKey(index);
2411
+ if (shouldPreserveLocalChildState(parser) && resolvedState && typeof resolvedState === "object" && key in resolvedState) return resolvedState[key];
2006
2412
  if (resolvedState && typeof resolvedState === "object") {
2007
2413
  const extractedState = {};
2008
2414
  for (const field in parser.initialState) extractedState[field] = field in resolvedState ? resolvedState[field] : parser.initialState[field];
@@ -2020,14 +2426,25 @@ function merge(...args) {
2020
2426
  ...exec,
2021
2427
  dependencyRuntime: runtime
2022
2428
  };
2023
- const perChildCache = syncParsers.map((parser) => {
2429
+ const duplicateFieldNames = collectDuplicateFieldNames(mergedFieldParsers);
2430
+ const unambiguousFieldParsers = filterDuplicateFieldParsers(mergedFieldParsers);
2431
+ const perChildPhase1 = syncParsers.map((parser, i) => {
2024
2432
  if (fieldParsersKey in parser) {
2025
2433
  const pairs = parser[fieldParsersKey];
2026
- const preCompleted = preCompleteAndRegisterDependencies(state, pairs, runtime.registry, childExec);
2027
- return filterDuplicateKeys(preCompleted, pairs);
2434
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames.has(field)));
2435
+ const phase1Pairs = filterExcludedFieldParsers(pairs, excludedSourceFields);
2436
+ const preCompleted = preCompleteAndRegisterDependencies(state, phase1Pairs, runtime.registry, withChildExecPath(childExec, i));
2437
+ return {
2438
+ cache: filterDuplicateKeys(preCompleted, phase1Pairs),
2439
+ excludedSourceFields: excludedSourceFields.size > 0 ? excludedSourceFields : void 0
2440
+ };
2028
2441
  }
2029
- return void 0;
2442
+ return {
2443
+ cache: void 0,
2444
+ excludedSourceFields: void 0
2445
+ };
2030
2446
  });
2447
+ collectExplicitSourceValues(buildRuntimeNodesFromPairs(unambiguousFieldParsers, state, exec?.path), runtime);
2031
2448
  const resolvedState = resolveStateWithRuntime(state, runtime);
2032
2449
  const object$1 = {};
2033
2450
  const deferredKeys = /* @__PURE__ */ new Map();
@@ -2035,11 +2452,21 @@ function merge(...args) {
2035
2452
  for (let i = 0; i < syncParsers.length; i++) {
2036
2453
  const parser = syncParsers[i];
2037
2454
  const parserState = extractCompleteState(parser, resolvedState, i);
2038
- const cache = perChildCache[i];
2039
- const result = unwrapCompleteResult(parser.complete(parserState, {
2040
- ...childExec,
2455
+ const { cache, excludedSourceFields } = perChildPhase1[i];
2456
+ const childCompleteExec = withChildExecPath(childExec, i);
2457
+ const completeExec = excludedSourceFields == null ? {
2458
+ ...childCompleteExec,
2041
2459
  preCompletedByParser: cache
2042
- }));
2460
+ } : (() => {
2461
+ const childRuntime = createDependencyRuntimeContext(runtime.registry.clone());
2462
+ return {
2463
+ ...childCompleteExec,
2464
+ dependencyRuntime: childRuntime,
2465
+ dependencyRegistry: childRuntime.registry,
2466
+ preCompletedByParser: cache
2467
+ };
2468
+ })();
2469
+ const result = unwrapCompleteResult(parser.complete(parserState, completeExec));
2043
2470
  if (!result.success) return result;
2044
2471
  const resultValue = result.value;
2045
2472
  for (const field in resultValue) {
@@ -2065,12 +2492,26 @@ function merge(...args) {
2065
2492
  ...exec,
2066
2493
  dependencyRuntime: runtime
2067
2494
  };
2068
- const perChildCache = [];
2069
- for (const parser of parsers) if (fieldParsersKey in parser) {
2070
- const pairs = parser[fieldParsersKey];
2071
- const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, pairs, runtime.registry, childExec);
2072
- perChildCache.push(filterDuplicateKeys(preCompleted, pairs));
2073
- } else perChildCache.push(void 0);
2495
+ const duplicateFieldNames = collectDuplicateFieldNames(mergedFieldParsers);
2496
+ const unambiguousFieldParsers = filterDuplicateFieldParsers(mergedFieldParsers);
2497
+ const perChildPhase1 = [];
2498
+ for (let i = 0; i < parsers.length; i++) {
2499
+ const parser = parsers[i];
2500
+ if (fieldParsersKey in parser) {
2501
+ const pairs = parser[fieldParsersKey];
2502
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames.has(field)));
2503
+ const phase1Pairs = filterExcludedFieldParsers(pairs, excludedSourceFields);
2504
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, phase1Pairs, runtime.registry, withChildExecPath(childExec, i));
2505
+ perChildPhase1.push({
2506
+ cache: filterDuplicateKeys(preCompleted, phase1Pairs),
2507
+ excludedSourceFields: excludedSourceFields.size > 0 ? excludedSourceFields : void 0
2508
+ });
2509
+ } else perChildPhase1.push({
2510
+ cache: void 0,
2511
+ excludedSourceFields: void 0
2512
+ });
2513
+ }
2514
+ await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs(unambiguousFieldParsers, state, exec?.path), runtime);
2074
2515
  const resolvedState = await resolveStateWithRuntimeAsync(state, runtime);
2075
2516
  const object$1 = {};
2076
2517
  const deferredKeys = /* @__PURE__ */ new Map();
@@ -2078,11 +2519,21 @@ function merge(...args) {
2078
2519
  for (let i = 0; i < parsers.length; i++) {
2079
2520
  const parser = parsers[i];
2080
2521
  const parserState = extractCompleteState(parser, resolvedState, i);
2081
- const asyncCache = perChildCache[i];
2082
- const result = unwrapCompleteResult(await parser.complete(parserState, {
2083
- ...childExec,
2522
+ const { cache: asyncCache, excludedSourceFields } = perChildPhase1[i];
2523
+ const childCompleteExec = withChildExecPath(childExec, i);
2524
+ const completeExec = excludedSourceFields == null ? {
2525
+ ...childCompleteExec,
2084
2526
  preCompletedByParser: asyncCache
2085
- }));
2527
+ } : (() => {
2528
+ const childRuntime = createDependencyRuntimeContext(runtime.registry.clone());
2529
+ return {
2530
+ ...childCompleteExec,
2531
+ dependencyRuntime: childRuntime,
2532
+ dependencyRegistry: childRuntime.registry,
2533
+ preCompletedByParser: asyncCache
2534
+ };
2535
+ })();
2536
+ const result = unwrapCompleteResult(await parser.complete(parserState, completeExec));
2086
2537
  if (!result.success) return result;
2087
2538
  const resultValue = result.value;
2088
2539
  for (const field in resultValue) {
@@ -2107,10 +2558,12 @@ function merge(...args) {
2107
2558
  if (options.hidden === true) return dispatchIterableByMode(combinedMode, function* () {}, async function* () {});
2108
2559
  const extractState = (p, i) => {
2109
2560
  if (p.initialState === void 0) {
2110
- const key = `__parser_${i}`;
2561
+ const key = parserStateKey(i);
2111
2562
  if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
2112
2563
  return void 0;
2113
2564
  } else if (p.initialState && typeof p.initialState === "object") {
2565
+ const key = localObjectStateKey(i);
2566
+ if (shouldPreserveLocalChildState(p) && context.state && typeof context.state === "object" && key in context.state) return context.state[key];
2114
2567
  if (context.state && typeof context.state === "object") {
2115
2568
  const extractedState = {};
2116
2569
  for (const field in p.initialState) extractedState[field] = field in context.state ? context.state[field] : p.initialState[field];
@@ -2122,8 +2575,17 @@ function merge(...args) {
2122
2575
  };
2123
2576
  if (isAsync) return async function* () {
2124
2577
  const runtime$1 = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
2125
- const childFieldPairs$1 = collectChildFieldParsers(parsers);
2126
- if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime$1);
2578
+ const mergedPairs$1 = collectChildFieldParsers(parsers);
2579
+ const duplicateFieldNames$1 = collectDuplicateFieldNames(mergedPairs$1);
2580
+ const childFieldPairs$1 = filterDuplicateFieldParsers(mergedPairs$1);
2581
+ const perChildExcludedSourceFields$1 = parsers.map((parser) => {
2582
+ if (!(fieldParsersKey in parser)) return void 0;
2583
+ const pairs = parser[fieldParsersKey];
2584
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames$1.has(field)));
2585
+ return excludedSourceFields.size > 0 ? excludedSourceFields : void 0;
2586
+ });
2587
+ if (context.state && typeof context.state === "object") await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs(childFieldPairs$1, context.state, context.exec?.path), runtime$1);
2588
+ if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime$1, /* @__PURE__ */ new WeakSet(), duplicateFieldNames$1);
2127
2589
  await completeDependencySourceDefaultsAsync(context, childFieldPairs$1, runtime$1.registry, context.exec);
2128
2590
  const contextWithRegistry$1 = {
2129
2591
  ...context,
@@ -2133,18 +2595,37 @@ function merge(...args) {
2133
2595
  for (let i = 0; i < parsers.length; i++) {
2134
2596
  const parser = parsers[i];
2135
2597
  const parserState = extractState(parser, i);
2136
- const parserSuggestions = parser.suggest({
2137
- ...contextWithRegistry$1,
2138
- state: parserState
2139
- }, prefix);
2598
+ const childContext = withChildContext(contextWithRegistry$1, i, parserState);
2599
+ const excludedSourceFields = perChildExcludedSourceFields$1[i];
2600
+ const contextForChild = excludedSourceFields == null ? childContext : (() => {
2601
+ const childRuntime = createDependencyRuntimeContext(runtime$1.registry.clone());
2602
+ return {
2603
+ ...childContext,
2604
+ dependencyRegistry: childRuntime.registry,
2605
+ exec: childContext.exec == null ? childContext.exec : {
2606
+ ...childContext.exec,
2607
+ dependencyRegistry: childRuntime.registry
2608
+ }
2609
+ };
2610
+ })();
2611
+ const parserSuggestions = parser.suggest(contextForChild, prefix);
2140
2612
  if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
2141
2613
  else suggestions.push(...parserSuggestions);
2142
2614
  }
2143
2615
  yield* deduplicateSuggestions(suggestions);
2144
2616
  }();
2145
2617
  const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
2146
- const childFieldPairs = collectChildFieldParsers(syncParsers);
2147
- if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
2618
+ const mergedPairs = collectChildFieldParsers(syncParsers);
2619
+ const duplicateFieldNames = collectDuplicateFieldNames(mergedPairs);
2620
+ const childFieldPairs = filterDuplicateFieldParsers(mergedPairs);
2621
+ const perChildExcludedSourceFields = syncParsers.map((parser) => {
2622
+ if (!(fieldParsersKey in parser)) return void 0;
2623
+ const pairs = parser[fieldParsersKey];
2624
+ const excludedSourceFields = new Set(pairs.map(([field]) => field).filter((field) => duplicateFieldNames.has(field)));
2625
+ return excludedSourceFields.size > 0 ? excludedSourceFields : void 0;
2626
+ });
2627
+ if (context.state && typeof context.state === "object") collectExplicitSourceValues(buildRuntimeNodesFromPairs(childFieldPairs, context.state, context.exec?.path), runtime);
2628
+ if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime, /* @__PURE__ */ new WeakSet(), duplicateFieldNames);
2148
2629
  completeDependencySourceDefaults(context, childFieldPairs, runtime.registry, context.exec);
2149
2630
  const contextWithRegistry = {
2150
2631
  ...context,
@@ -2155,10 +2636,20 @@ function merge(...args) {
2155
2636
  for (let i = 0; i < syncParsers.length; i++) {
2156
2637
  const parser = syncParsers[i];
2157
2638
  const parserState = extractState(parser, i);
2158
- const parserSuggestions = parser.suggest({
2159
- ...contextWithRegistry,
2160
- state: parserState
2161
- }, prefix);
2639
+ const childContext = withChildContext(contextWithRegistry, i, parserState);
2640
+ const excludedSourceFields = perChildExcludedSourceFields[i];
2641
+ const contextForChild = excludedSourceFields == null ? childContext : (() => {
2642
+ const childRuntime = createDependencyRuntimeContext(runtime.registry.clone());
2643
+ return {
2644
+ ...childContext,
2645
+ dependencyRegistry: childRuntime.registry,
2646
+ exec: childContext.exec == null ? childContext.exec : {
2647
+ ...childContext.exec,
2648
+ dependencyRegistry: childRuntime.registry
2649
+ }
2650
+ };
2651
+ })();
2652
+ const parserSuggestions = parser.suggest(contextForChild, prefix);
2162
2653
  suggestions.push(...parserSuggestions);
2163
2654
  }
2164
2655
  yield* deduplicateSuggestions(suggestions);
@@ -2225,6 +2716,7 @@ function merge(...args) {
2225
2716
  };
2226
2717
  }
2227
2718
  };
2719
+ defineInheritedAnnotationParser(mergeParser);
2228
2720
  return mergeParser;
2229
2721
  }
2230
2722
  /**
@@ -2233,18 +2725,126 @@ function merge(...args) {
2233
2725
  * async branches of `concat().suggest()`.
2234
2726
  * @internal
2235
2727
  */
2236
- function buildSuggestRegistry(preParsedContext) {
2728
+ function buildSuggestRegistry(preParsedContext, parsers) {
2237
2729
  const stateArray = preParsedContext.state;
2238
2730
  const runtime = createDependencyRuntimeContext(preParsedContext.dependencyRegistry?.clone());
2239
- if (stateArray && Array.isArray(stateArray)) collectSourcesFromState(stateArray, runtime);
2731
+ if (stateArray && Array.isArray(stateArray)) {
2732
+ const nodes = buildSuggestRuntimeNodesFromArray(parsers, stateArray, preParsedContext.exec?.path);
2733
+ collectExplicitSourceValues(nodes, runtime);
2734
+ fillMissingSourceDefaults(nodes, runtime);
2735
+ collectSourcesFromState(stateArray, runtime);
2736
+ completeDependencySourceDefaults({
2737
+ ...preParsedContext,
2738
+ state: createAnnotatedArrayStateRecord(stateArray)
2739
+ }, buildIndexedParserPairs(parsers), runtime.registry, preParsedContext.exec);
2740
+ const prefix = preParsedContext.exec?.path ?? [];
2741
+ for (let i = 0; i < parsers.length; i++) seedSuggestRuntimeFromFieldParsers(parsers[i], getAnnotatedChildState(stateArray, stateArray[i], parsers[i]), runtime, [...prefix, i]);
2742
+ }
2240
2743
  return {
2241
2744
  context: {
2242
2745
  ...preParsedContext,
2243
- dependencyRegistry: runtime.registry
2746
+ dependencyRegistry: runtime.registry,
2747
+ ...preParsedContext.exec != null ? { exec: {
2748
+ ...preParsedContext.exec,
2749
+ dependencyRuntime: runtime,
2750
+ dependencyRegistry: runtime.registry
2751
+ } } : {}
2752
+ },
2753
+ stateArray
2754
+ };
2755
+ }
2756
+ async function buildSuggestRegistryAsync(preParsedContext, parsers) {
2757
+ const stateArray = preParsedContext.state;
2758
+ const runtime = createDependencyRuntimeContext(preParsedContext.dependencyRegistry?.clone());
2759
+ if (stateArray && Array.isArray(stateArray)) {
2760
+ const nodes = buildSuggestRuntimeNodesFromArray(parsers, stateArray, preParsedContext.exec?.path);
2761
+ await collectExplicitSourceValuesAsync(nodes, runtime);
2762
+ await fillMissingSourceDefaultsAsync(nodes, runtime);
2763
+ collectSourcesFromState(stateArray, runtime);
2764
+ await completeDependencySourceDefaultsAsync({
2765
+ ...preParsedContext,
2766
+ state: createAnnotatedArrayStateRecord(stateArray)
2767
+ }, buildIndexedParserPairs(parsers), runtime.registry, preParsedContext.exec);
2768
+ const prefix = preParsedContext.exec?.path ?? [];
2769
+ for (let i = 0; i < parsers.length; i++) await seedSuggestRuntimeFromFieldParsersAsync(parsers[i], getAnnotatedChildState(stateArray, stateArray[i], parsers[i]), runtime, [...prefix, i]);
2770
+ }
2771
+ return {
2772
+ context: {
2773
+ ...preParsedContext,
2774
+ dependencyRegistry: runtime.registry,
2775
+ ...preParsedContext.exec != null ? { exec: {
2776
+ ...preParsedContext.exec,
2777
+ dependencyRuntime: runtime,
2778
+ dependencyRegistry: runtime.registry
2779
+ } } : {}
2244
2780
  },
2245
2781
  stateArray
2246
2782
  };
2247
2783
  }
2784
+ function seedSuggestRuntimeFromFieldParsers(parser, state, runtime, parentPath) {
2785
+ if (!(fieldParsersKey in parser)) return;
2786
+ const rawPairs = parser[fieldParsersKey];
2787
+ const duplicateFieldNames = collectDuplicateFieldNames(rawPairs);
2788
+ const pairs = filterDuplicateFieldParsers(rawPairs);
2789
+ const stateRecord = state != null && typeof state === "object" ? state : {};
2790
+ const nodes = buildSuggestRuntimeNodesFromPairs(pairs, stateRecord, parentPath);
2791
+ collectExplicitSourceValues(nodes, runtime);
2792
+ fillMissingSourceDefaults(nodes, runtime);
2793
+ collectSourcesFromState(state, runtime, /* @__PURE__ */ new WeakSet(), duplicateFieldNames);
2794
+ completeDependencySourceDefaults({
2795
+ buffer: [],
2796
+ optionsTerminated: false,
2797
+ state: stateRecord,
2798
+ usage: parser.usage,
2799
+ dependencyRegistry: runtime.registry,
2800
+ exec: {
2801
+ usage: parser.usage,
2802
+ phase: "suggest",
2803
+ path: parentPath,
2804
+ dependencyRuntime: runtime,
2805
+ dependencyRegistry: runtime.registry
2806
+ }
2807
+ }, pairs, runtime.registry, {
2808
+ usage: parser.usage,
2809
+ phase: "suggest",
2810
+ path: parentPath,
2811
+ dependencyRuntime: runtime,
2812
+ dependencyRegistry: runtime.registry
2813
+ });
2814
+ for (const [field, childParser] of pairs) seedSuggestRuntimeFromFieldParsers(childParser, getAnnotatedFieldState(stateRecord, field, childParser), runtime, [...parentPath, field]);
2815
+ }
2816
+ async function seedSuggestRuntimeFromFieldParsersAsync(parser, state, runtime, parentPath) {
2817
+ if (!(fieldParsersKey in parser)) return;
2818
+ const rawPairs = parser[fieldParsersKey];
2819
+ const duplicateFieldNames = collectDuplicateFieldNames(rawPairs);
2820
+ const pairs = filterDuplicateFieldParsers(rawPairs);
2821
+ const stateRecord = state != null && typeof state === "object" ? state : {};
2822
+ const nodes = buildSuggestRuntimeNodesFromPairs(pairs, stateRecord, parentPath);
2823
+ await collectExplicitSourceValuesAsync(nodes, runtime);
2824
+ await fillMissingSourceDefaultsAsync(nodes, runtime);
2825
+ collectSourcesFromState(state, runtime, /* @__PURE__ */ new WeakSet(), duplicateFieldNames);
2826
+ await completeDependencySourceDefaultsAsync({
2827
+ buffer: [],
2828
+ optionsTerminated: false,
2829
+ state: stateRecord,
2830
+ usage: parser.usage,
2831
+ dependencyRegistry: runtime.registry,
2832
+ exec: {
2833
+ usage: parser.usage,
2834
+ phase: "suggest",
2835
+ path: parentPath,
2836
+ dependencyRuntime: runtime,
2837
+ dependencyRegistry: runtime.registry
2838
+ }
2839
+ }, pairs, runtime.registry, {
2840
+ usage: parser.usage,
2841
+ phase: "suggest",
2842
+ path: parentPath,
2843
+ dependencyRuntime: runtime,
2844
+ dependencyRegistry: runtime.registry
2845
+ });
2846
+ for (const [field, childParser] of pairs) await seedSuggestRuntimeFromFieldParsersAsync(childParser, getAnnotatedFieldState(stateRecord, field, childParser), runtime, [...parentPath, field]);
2847
+ }
2248
2848
  /**
2249
2849
  * This helper replays child parsers in priority order (mirroring
2250
2850
  * `concat.parse()`) to accumulate dependency source values for suggestions.
@@ -2252,7 +2852,7 @@ function buildSuggestRegistry(preParsedContext) {
2252
2852
  */
2253
2853
  function preParseSuggestContext(context, parsers) {
2254
2854
  if (context.buffer.length < 1 || !Array.isArray(context.state)) return context;
2255
- return preParseSuggestLoop(context, context.state.slice(), parsers);
2855
+ return preParseSuggestLoop(context, annotateFreshArray(context.state, context.state.slice()), parsers);
2256
2856
  }
2257
2857
  /**
2258
2858
  * Async variant of {@link preParseSuggestContext} that awaits async child
@@ -2261,7 +2861,7 @@ function preParseSuggestContext(context, parsers) {
2261
2861
  */
2262
2862
  async function preParseSuggestContextAsync(context, parsers) {
2263
2863
  if (context.buffer.length < 1 || !Array.isArray(context.state)) return context;
2264
- return await preParseSuggestLoop(context, context.state.slice(), parsers);
2864
+ return await preParseSuggestLoop(context, annotateFreshArray(context.state, context.state.slice()), parsers);
2265
2865
  }
2266
2866
  /**
2267
2867
  * Shared loop for sync and async concat suggest pre-parse. When a child
@@ -2297,21 +2897,23 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
2297
2897
  for (let ri = 0; ri < remaining.length; ri++) {
2298
2898
  const [parser, index] = remaining[ri];
2299
2899
  const parserState = index < stateArray.length ? stateArray[index] : parser.initialState;
2300
- const resultOrPromise = parser.parse({
2301
- ...context,
2302
- state: parserState
2303
- });
2900
+ const resultOrPromise = parser.parse(withChildContext(context, index, parserState, parser));
2304
2901
  if (resultOrPromise != null && typeof resultOrPromise === "object" && "then" in resultOrPromise && typeof resultOrPromise.then === "function") {
2305
2902
  const tail = remaining.slice(ri + 1);
2306
2903
  return resultOrPromise.then((result$1) => {
2307
2904
  if (result$1.success && result$1.consumed.length > 0) {
2308
- stateArray[index] = result$1.next.state;
2905
+ stateArray[index] = getAnnotatedChildState(context.state, result$1.next.state, parser);
2309
2906
  matchedParsers.add(index);
2907
+ const mergedExec = mergeChildExec(context.exec, result$1.next.exec);
2310
2908
  return preParseSuggestLoop({
2311
2909
  ...context,
2312
2910
  buffer: result$1.next.buffer,
2313
2911
  optionsTerminated: result$1.next.optionsTerminated,
2314
- state: stateArray
2912
+ state: stateArray,
2913
+ ...mergedExec != null ? {
2914
+ exec: mergedExec,
2915
+ dependencyRegistry: mergedExec.dependencyRegistry
2916
+ } : {}
2315
2917
  }, stateArray, parsers, matchedParsers);
2316
2918
  }
2317
2919
  const next = tryParseSuggestList(context, stateArray, parsers, matchedParsers, tail);
@@ -2327,13 +2929,18 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
2327
2929
  }
2328
2930
  const result = resultOrPromise;
2329
2931
  if (result.success && result.consumed.length > 0) {
2330
- stateArray[index] = result.next.state;
2932
+ stateArray[index] = getAnnotatedChildState(context.state, result.next.state, parser);
2331
2933
  matchedParsers.add(index);
2934
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
2332
2935
  return {
2333
2936
  ...context,
2334
2937
  buffer: result.next.buffer,
2335
2938
  optionsTerminated: result.next.optionsTerminated,
2336
- state: stateArray
2939
+ state: stateArray,
2940
+ ...mergedExec != null ? {
2941
+ exec: mergedExec,
2942
+ dependencyRegistry: mergedExec.dependencyRegistry
2943
+ } : {}
2337
2944
  };
2338
2945
  }
2339
2946
  }
@@ -2359,17 +2966,19 @@ function concat(...parsers) {
2359
2966
  const stateArray = currentContext.state;
2360
2967
  const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
2361
2968
  for (const [parser, index] of remainingParsers) {
2362
- const result = parser.parse({
2363
- ...currentContext,
2364
- state: stateArray[index]
2365
- });
2969
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
2366
2970
  if (result.success && result.consumed.length > 0) {
2367
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
2971
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
2972
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2368
2973
  currentContext = {
2369
2974
  ...currentContext,
2370
2975
  buffer: result.next.buffer,
2371
2976
  optionsTerminated: result.next.optionsTerminated,
2372
- state: newStateArray
2977
+ state: newStateArray,
2978
+ ...mergedExec != null ? {
2979
+ exec: mergedExec,
2980
+ dependencyRegistry: mergedExec.dependencyRegistry
2981
+ } : {}
2373
2982
  };
2374
2983
  allConsumed.push(...result.consumed);
2375
2984
  matchedParsers.add(index);
@@ -2378,15 +2987,17 @@ function concat(...parsers) {
2378
2987
  } else if (!result.success && error.consumed < result.consumed) error = result;
2379
2988
  }
2380
2989
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
2381
- const result = parser.parse({
2382
- ...currentContext,
2383
- state: stateArray[index]
2384
- });
2990
+ const result = parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
2385
2991
  if (result.success && result.consumed.length < 1) {
2386
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
2992
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
2993
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2387
2994
  currentContext = {
2388
2995
  ...currentContext,
2389
- state: newStateArray
2996
+ state: newStateArray,
2997
+ ...mergedExec != null ? {
2998
+ exec: mergedExec,
2999
+ dependencyRegistry: mergedExec.dependencyRegistry
3000
+ } : {}
2390
3001
  };
2391
3002
  matchedParsers.add(index);
2392
3003
  foundMatch = true;
@@ -2421,17 +3032,19 @@ function concat(...parsers) {
2421
3032
  const stateArray = currentContext.state;
2422
3033
  const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
2423
3034
  for (const [parser, index] of remainingParsers) {
2424
- const result = await parser.parse({
2425
- ...currentContext,
2426
- state: stateArray[index]
2427
- });
3035
+ const result = await parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
2428
3036
  if (result.success && result.consumed.length > 0) {
2429
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
3037
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
3038
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2430
3039
  currentContext = {
2431
3040
  ...currentContext,
2432
3041
  buffer: result.next.buffer,
2433
3042
  optionsTerminated: result.next.optionsTerminated,
2434
- state: newStateArray
3043
+ state: newStateArray,
3044
+ ...mergedExec != null ? {
3045
+ exec: mergedExec,
3046
+ dependencyRegistry: mergedExec.dependencyRegistry
3047
+ } : {}
2435
3048
  };
2436
3049
  allConsumed.push(...result.consumed);
2437
3050
  matchedParsers.add(index);
@@ -2440,15 +3053,17 @@ function concat(...parsers) {
2440
3053
  } else if (!result.success && error.consumed < result.consumed) error = result;
2441
3054
  }
2442
3055
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
2443
- const result = await parser.parse({
2444
- ...currentContext,
2445
- state: stateArray[index]
2446
- });
3056
+ const result = await parser.parse(withChildContext(currentContext, index, stateArray[index], parser));
2447
3057
  if (result.success && result.consumed.length < 1) {
2448
- const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
3058
+ const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getAnnotatedChildState(currentContext.state, result.next.state, parser) : s));
3059
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2449
3060
  currentContext = {
2450
3061
  ...currentContext,
2451
- state: newStateArray
3062
+ state: newStateArray,
3063
+ ...mergedExec != null ? {
3064
+ exec: mergedExec,
3065
+ dependencyRegistry: mergedExec.dependencyRegistry
3066
+ } : {}
2452
3067
  };
2453
3068
  matchedParsers.add(index);
2454
3069
  foundMatch = true;
@@ -2475,7 +3090,14 @@ function concat(...parsers) {
2475
3090
  const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2476
3091
  const childExec = {
2477
3092
  ...exec,
2478
- dependencyRuntime: runtime,
3093
+ dependencyRuntime: runtime
3094
+ };
3095
+ const concatPairs = buildIndexedParserPairs(syncParsers);
3096
+ const concatState = createAnnotatedArrayStateRecord(stateArray);
3097
+ const preCompleted = preCompleteAndRegisterDependencies(concatState, concatPairs, runtime.registry, childExec);
3098
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
3099
+ const phase3Exec = {
3100
+ ...childExec,
2479
3101
  preCompletedByParser: void 0
2480
3102
  };
2481
3103
  const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
@@ -2484,8 +3106,8 @@ function concat(...parsers) {
2484
3106
  let hasDeferred = false;
2485
3107
  for (let i = 0; i < syncParsers.length; i++) {
2486
3108
  const parser = syncParsers[i];
2487
- const parserState = prepareStateForCompletion(resolvedArray[i], parser);
2488
- const result = unwrapCompleteResult(parser.complete(parserState, childExec));
3109
+ const preCompletedResult = preCompleted.get(String(i));
3110
+ const result = preCompletedResult !== void 0 ? unwrapCompleteResult(preCompletedResult) : unwrapCompleteResult(parser.complete(prepareStateForCompletion(resolvedArray[i], parser), withChildExecPath(phase3Exec, i)));
2489
3111
  if (!result.success) return result;
2490
3112
  const baseIndex = results.length;
2491
3113
  if (Array.isArray(result.value)) {
@@ -2518,7 +3140,14 @@ function concat(...parsers) {
2518
3140
  const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2519
3141
  const childExec = {
2520
3142
  ...exec,
2521
- dependencyRuntime: runtime,
3143
+ dependencyRuntime: runtime
3144
+ };
3145
+ const concatPairs = buildIndexedParserPairs(parsers);
3146
+ const concatState = createAnnotatedArrayStateRecord(stateArray);
3147
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(concatState, concatPairs, runtime.registry, childExec);
3148
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
3149
+ const phase3Exec = {
3150
+ ...childExec,
2522
3151
  preCompletedByParser: void 0
2523
3152
  };
2524
3153
  const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
@@ -2527,8 +3156,8 @@ function concat(...parsers) {
2527
3156
  let hasDeferred = false;
2528
3157
  for (let i = 0; i < parsers.length; i++) {
2529
3158
  const parser = parsers[i];
2530
- const parserState = prepareStateForCompletion(resolvedArray[i], parser);
2531
- const result = unwrapCompleteResult(await parser.complete(parserState, childExec));
3159
+ const preCompletedResult = preCompleted.get(String(i));
3160
+ const result = preCompletedResult !== void 0 ? unwrapCompleteResult(preCompletedResult) : unwrapCompleteResult(await parser.complete(prepareStateForCompletion(resolvedArray[i], parser), withChildExecPath(phase3Exec, i)));
2532
3161
  if (!result.success) return result;
2533
3162
  const baseIndex = results.length;
2534
3163
  if (Array.isArray(result.value)) {
@@ -2556,7 +3185,7 @@ function concat(...parsers) {
2556
3185
  } : {}
2557
3186
  };
2558
3187
  };
2559
- return {
3188
+ const concatParser = {
2560
3189
  $mode: combinedMode,
2561
3190
  $valueType: [],
2562
3191
  $stateType: [],
@@ -2576,31 +3205,25 @@ function concat(...parsers) {
2576
3205
  suggest(context, prefix) {
2577
3206
  if (isAsync) return async function* () {
2578
3207
  const preParsedContext$1 = await preParseSuggestContextAsync(context, parsers);
2579
- const { context: contextWithRegistry$1, stateArray: stateArray$1 } = buildSuggestRegistry(preParsedContext$1);
3208
+ const { context: contextWithRegistry$1, stateArray: stateArray$1 } = await buildSuggestRegistryAsync(preParsedContext$1, parsers);
2580
3209
  const suggestions = [];
2581
3210
  for (let i = 0; i < parsers.length; i++) {
2582
3211
  const parser = parsers[i];
2583
3212
  const parserState = stateArray$1 && Array.isArray(stateArray$1) ? stateArray$1[i] : parser.initialState;
2584
- const parserSuggestions = parser.suggest({
2585
- ...contextWithRegistry$1,
2586
- state: parserState
2587
- }, prefix);
3213
+ const parserSuggestions = parser.suggest(withChildContext(contextWithRegistry$1, i, parserState, parser), prefix);
2588
3214
  if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
2589
3215
  else suggestions.push(...parserSuggestions);
2590
3216
  }
2591
3217
  yield* deduplicateSuggestions(suggestions);
2592
3218
  }();
2593
3219
  const preParsedContext = preParseSuggestContext(context, syncParsers);
2594
- const { context: contextWithRegistry, stateArray } = buildSuggestRegistry(preParsedContext);
3220
+ const { context: contextWithRegistry, stateArray } = buildSuggestRegistry(preParsedContext, syncParsers);
2595
3221
  return function* () {
2596
3222
  const suggestions = [];
2597
3223
  for (let i = 0; i < syncParsers.length; i++) {
2598
3224
  const parser = syncParsers[i];
2599
3225
  const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
2600
- const parserSuggestions = parser.suggest({
2601
- ...contextWithRegistry,
2602
- state: parserState
2603
- }, prefix);
3226
+ const parserSuggestions = parser.suggest(withChildContext(contextWithRegistry, i, parserState, parser), prefix);
2604
3227
  suggestions.push(...parserSuggestions);
2605
3228
  }
2606
3229
  yield* deduplicateSuggestions(suggestions);
@@ -2632,6 +3255,8 @@ function concat(...parsers) {
2632
3255
  return { fragments: result };
2633
3256
  }
2634
3257
  };
3258
+ defineInheritedAnnotationParser(concatParser);
3259
+ return concatParser;
2635
3260
  }
2636
3261
  function group(label, parser, options = {}) {
2637
3262
  validateLabel(label);
@@ -2646,6 +3271,13 @@ function group(label, parser, options = {}) {
2646
3271
  initialState: parser.initialState,
2647
3272
  ...fieldParsersKey in parser ? { [fieldParsersKey]: parser[fieldParsersKey] } : {},
2648
3273
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
3274
+ getSuggestRuntimeNodes(state, path) {
3275
+ return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
3276
+ path,
3277
+ parser,
3278
+ state
3279
+ }] : []);
3280
+ },
2649
3281
  parse: (context) => parser.parse(context),
2650
3282
  complete: (state, exec) => parser.complete(state, exec),
2651
3283
  suggest: (context, prefix) => {
@@ -2788,57 +3420,69 @@ function conditional(discriminator, branches, defaultBranch, options) {
2788
3420
  const syncDefaultBranch = defaultBranch;
2789
3421
  if (state.selectedBranch !== void 0) {
2790
3422
  const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
2791
- const branchResult = branchParser.parse({
2792
- ...context,
2793
- state: state.branchState,
2794
- usage: branchParser.usage
2795
- });
2796
- if (branchResult.success) return {
2797
- success: true,
2798
- next: {
2799
- ...branchResult.next,
2800
- state: {
2801
- ...state,
2802
- branchState: branchResult.next.state
2803
- }
2804
- },
2805
- consumed: branchResult.consumed
2806
- };
3423
+ const branchResult = branchParser.parse(withChildContext(context, "_branch", state.branchState, branchParser, branchParser.usage));
3424
+ if (branchResult.success) {
3425
+ const mergedExec = mergeChildExec(context.exec, branchResult.next.exec);
3426
+ return {
3427
+ success: true,
3428
+ next: {
3429
+ ...branchResult.next,
3430
+ state: {
3431
+ ...state,
3432
+ branchState: branchResult.next.state
3433
+ },
3434
+ ...mergedExec != null ? {
3435
+ exec: mergedExec,
3436
+ dependencyRegistry: mergedExec.dependencyRegistry
3437
+ } : {}
3438
+ },
3439
+ consumed: branchResult.consumed
3440
+ };
3441
+ }
2807
3442
  return branchResult;
2808
3443
  }
2809
- const discriminatorResult = syncDiscriminator.parse({
2810
- ...context,
2811
- state: state.discriminatorState
2812
- });
3444
+ const discriminatorResult = syncDiscriminator.parse({ ...withChildContext(context, "_discriminator", state.discriminatorState) });
2813
3445
  if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
2814
- const completionResult = syncDiscriminator.complete(discriminatorResult.next.state, context.exec);
3446
+ const completionResult = syncDiscriminator.complete(discriminatorResult.next.state, withChildExecPath(context.exec, "_discriminator"));
2815
3447
  if (completionResult.success) {
2816
3448
  const value = completionResult.value;
2817
3449
  const branchParser = syncBranches[value];
2818
3450
  if (branchParser) {
3451
+ const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
2819
3452
  const branchParseResult = branchParser.parse({
2820
- ...context,
3453
+ ...withChildContext({
3454
+ ...context,
3455
+ ...discriminatorExec != null ? {
3456
+ exec: discriminatorExec,
3457
+ dependencyRegistry: discriminatorExec.dependencyRegistry
3458
+ } : {}
3459
+ }, "_branch", branchParser.initialState, branchParser, branchParser.usage),
2821
3460
  buffer: discriminatorResult.next.buffer,
2822
- optionsTerminated: discriminatorResult.next.optionsTerminated,
2823
- state: branchParser.initialState,
2824
- usage: branchParser.usage
3461
+ optionsTerminated: discriminatorResult.next.optionsTerminated
2825
3462
  });
2826
- if (branchParseResult.success) return {
2827
- success: true,
2828
- next: {
2829
- ...branchParseResult.next,
2830
- state: {
2831
- discriminatorState: discriminatorResult.next.state,
2832
- discriminatorValue: value,
2833
- selectedBranch: {
2834
- kind: "branch",
2835
- key: value
3463
+ if (branchParseResult.success) {
3464
+ const mergedExec = mergeChildExec(discriminatorExec, branchParseResult.next.exec);
3465
+ return {
3466
+ success: true,
3467
+ next: {
3468
+ ...branchParseResult.next,
3469
+ state: {
3470
+ discriminatorState: discriminatorResult.next.state,
3471
+ discriminatorValue: value,
3472
+ selectedBranch: {
3473
+ kind: "branch",
3474
+ key: value
3475
+ },
3476
+ branchState: branchParseResult.next.state
2836
3477
  },
2837
- branchState: branchParseResult.next.state
2838
- }
2839
- },
2840
- consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
2841
- };
3478
+ ...mergedExec != null ? {
3479
+ exec: mergedExec,
3480
+ dependencyRegistry: mergedExec.dependencyRegistry
3481
+ } : {}
3482
+ },
3483
+ consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
3484
+ };
3485
+ }
2842
3486
  return {
2843
3487
  success: true,
2844
3488
  next: {
@@ -2851,7 +3495,11 @@ function conditional(discriminator, branches, defaultBranch, options) {
2851
3495
  key: value
2852
3496
  },
2853
3497
  branchState: branchParser.initialState
2854
- }
3498
+ },
3499
+ ...discriminatorExec != null ? {
3500
+ exec: discriminatorExec,
3501
+ dependencyRegistry: discriminatorExec.dependencyRegistry
3502
+ } : {}
2855
3503
  },
2856
3504
  consumed: discriminatorResult.consumed
2857
3505
  };
@@ -2859,23 +3507,26 @@ function conditional(discriminator, branches, defaultBranch, options) {
2859
3507
  }
2860
3508
  }
2861
3509
  if (syncDefaultBranch !== void 0) {
2862
- const defaultResult = syncDefaultBranch.parse({
2863
- ...context,
2864
- state: state.branchState ?? syncDefaultBranch.initialState,
2865
- usage: syncDefaultBranch.usage
2866
- });
2867
- if (defaultResult.success && defaultResult.consumed.length > 0) return {
2868
- success: true,
2869
- next: {
2870
- ...defaultResult.next,
2871
- state: {
2872
- ...state,
2873
- selectedBranch: { kind: "default" },
2874
- branchState: defaultResult.next.state
2875
- }
2876
- },
2877
- consumed: defaultResult.consumed
2878
- };
3510
+ const defaultResult = syncDefaultBranch.parse(withChildContext(context, "_branch", state.branchState ?? syncDefaultBranch.initialState, syncDefaultBranch, syncDefaultBranch.usage));
3511
+ if (defaultResult.success && defaultResult.consumed.length > 0) {
3512
+ const mergedExec = mergeChildExec(context.exec, defaultResult.next.exec);
3513
+ return {
3514
+ success: true,
3515
+ next: {
3516
+ ...defaultResult.next,
3517
+ state: {
3518
+ ...state,
3519
+ selectedBranch: { kind: "default" },
3520
+ branchState: defaultResult.next.state
3521
+ },
3522
+ ...mergedExec != null ? {
3523
+ exec: mergedExec,
3524
+ dependencyRegistry: mergedExec.dependencyRegistry
3525
+ } : {}
3526
+ },
3527
+ consumed: defaultResult.consumed
3528
+ };
3529
+ }
2879
3530
  }
2880
3531
  return {
2881
3532
  success: false,
@@ -2887,57 +3538,69 @@ function conditional(discriminator, branches, defaultBranch, options) {
2887
3538
  const state = context.state ?? initialState;
2888
3539
  if (state.selectedBranch !== void 0) {
2889
3540
  const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
2890
- const branchResult = await branchParser.parse({
2891
- ...context,
2892
- state: state.branchState,
2893
- usage: branchParser.usage
2894
- });
2895
- if (branchResult.success) return {
2896
- success: true,
2897
- next: {
2898
- ...branchResult.next,
2899
- state: {
2900
- ...state,
2901
- branchState: branchResult.next.state
2902
- }
2903
- },
2904
- consumed: branchResult.consumed
2905
- };
3541
+ const branchResult = await branchParser.parse(withChildContext(context, "_branch", state.branchState, branchParser, branchParser.usage));
3542
+ if (branchResult.success) {
3543
+ const mergedExec = mergeChildExec(context.exec, branchResult.next.exec);
3544
+ return {
3545
+ success: true,
3546
+ next: {
3547
+ ...branchResult.next,
3548
+ state: {
3549
+ ...state,
3550
+ branchState: branchResult.next.state
3551
+ },
3552
+ ...mergedExec != null ? {
3553
+ exec: mergedExec,
3554
+ dependencyRegistry: mergedExec.dependencyRegistry
3555
+ } : {}
3556
+ },
3557
+ consumed: branchResult.consumed
3558
+ };
3559
+ }
2906
3560
  return branchResult;
2907
3561
  }
2908
- const discriminatorResult = await discriminator.parse({
2909
- ...context,
2910
- state: state.discriminatorState
2911
- });
3562
+ const discriminatorResult = await discriminator.parse({ ...withChildContext(context, "_discriminator", state.discriminatorState) });
2912
3563
  if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
2913
- const completionResult = await discriminator.complete(discriminatorResult.next.state, context.exec);
3564
+ const completionResult = await discriminator.complete(discriminatorResult.next.state, withChildExecPath(context.exec, "_discriminator"));
2914
3565
  if (completionResult.success) {
2915
3566
  const value = completionResult.value;
2916
3567
  const branchParser = branches[value];
2917
3568
  if (branchParser) {
3569
+ const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
2918
3570
  const branchParseResult = await branchParser.parse({
2919
- ...context,
3571
+ ...withChildContext({
3572
+ ...context,
3573
+ ...discriminatorExec != null ? {
3574
+ exec: discriminatorExec,
3575
+ dependencyRegistry: discriminatorExec.dependencyRegistry
3576
+ } : {}
3577
+ }, "_branch", branchParser.initialState, branchParser, branchParser.usage),
2920
3578
  buffer: discriminatorResult.next.buffer,
2921
- optionsTerminated: discriminatorResult.next.optionsTerminated,
2922
- state: branchParser.initialState,
2923
- usage: branchParser.usage
3579
+ optionsTerminated: discriminatorResult.next.optionsTerminated
2924
3580
  });
2925
- if (branchParseResult.success) return {
2926
- success: true,
2927
- next: {
2928
- ...branchParseResult.next,
2929
- state: {
2930
- discriminatorState: discriminatorResult.next.state,
2931
- discriminatorValue: value,
2932
- selectedBranch: {
2933
- kind: "branch",
2934
- key: value
3581
+ if (branchParseResult.success) {
3582
+ const mergedExec = mergeChildExec(discriminatorExec, branchParseResult.next.exec);
3583
+ return {
3584
+ success: true,
3585
+ next: {
3586
+ ...branchParseResult.next,
3587
+ state: {
3588
+ discriminatorState: discriminatorResult.next.state,
3589
+ discriminatorValue: value,
3590
+ selectedBranch: {
3591
+ kind: "branch",
3592
+ key: value
3593
+ },
3594
+ branchState: branchParseResult.next.state
2935
3595
  },
2936
- branchState: branchParseResult.next.state
2937
- }
2938
- },
2939
- consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
2940
- };
3596
+ ...mergedExec != null ? {
3597
+ exec: mergedExec,
3598
+ dependencyRegistry: mergedExec.dependencyRegistry
3599
+ } : {}
3600
+ },
3601
+ consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
3602
+ };
3603
+ }
2941
3604
  return {
2942
3605
  success: true,
2943
3606
  next: {
@@ -2950,7 +3613,11 @@ function conditional(discriminator, branches, defaultBranch, options) {
2950
3613
  key: value
2951
3614
  },
2952
3615
  branchState: branchParser.initialState
2953
- }
3616
+ },
3617
+ ...discriminatorExec != null ? {
3618
+ exec: discriminatorExec,
3619
+ dependencyRegistry: discriminatorExec.dependencyRegistry
3620
+ } : {}
2954
3621
  },
2955
3622
  consumed: discriminatorResult.consumed
2956
3623
  };
@@ -2958,23 +3625,26 @@ function conditional(discriminator, branches, defaultBranch, options) {
2958
3625
  }
2959
3626
  }
2960
3627
  if (defaultBranch !== void 0) {
2961
- const defaultResult = await defaultBranch.parse({
2962
- ...context,
2963
- state: state.branchState ?? defaultBranch.initialState,
2964
- usage: defaultBranch.usage
2965
- });
2966
- if (defaultResult.success && defaultResult.consumed.length > 0) return {
2967
- success: true,
2968
- next: {
2969
- ...defaultResult.next,
2970
- state: {
2971
- ...state,
2972
- selectedBranch: { kind: "default" },
2973
- branchState: defaultResult.next.state
2974
- }
2975
- },
2976
- consumed: defaultResult.consumed
2977
- };
3628
+ const defaultResult = await defaultBranch.parse(withChildContext(context, "_branch", state.branchState ?? defaultBranch.initialState, defaultBranch, defaultBranch.usage));
3629
+ if (defaultResult.success && defaultResult.consumed.length > 0) {
3630
+ const mergedExec = mergeChildExec(context.exec, defaultResult.next.exec);
3631
+ return {
3632
+ success: true,
3633
+ next: {
3634
+ ...defaultResult.next,
3635
+ state: {
3636
+ ...state,
3637
+ selectedBranch: { kind: "default" },
3638
+ branchState: defaultResult.next.state
3639
+ },
3640
+ ...mergedExec != null ? {
3641
+ exec: mergedExec,
3642
+ dependencyRegistry: mergedExec.dependencyRegistry
3643
+ } : {}
3644
+ },
3645
+ consumed: defaultResult.consumed
3646
+ };
3647
+ }
2978
3648
  }
2979
3649
  return {
2980
3650
  success: false,
@@ -2989,7 +3659,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
2989
3659
  if (state.selectedBranch === void 0) {
2990
3660
  if (syncDefaultBranch !== void 0) {
2991
3661
  const branchState = state.branchState ?? syncDefaultBranch.initialState;
2992
- const defaultResult = syncDefaultBranch.complete(branchState, exec);
3662
+ const defaultResult = unwrapCompleteResult(syncDefaultBranch.complete(branchState, withChildExecPath(exec, "_branch")));
2993
3663
  if (!defaultResult.success) return defaultResult;
2994
3664
  return {
2995
3665
  success: true,
@@ -3006,14 +3676,26 @@ function conditional(discriminator, branches, defaultBranch, options) {
3006
3676
  };
3007
3677
  }
3008
3678
  const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
3009
- const discriminatorCompleteResult = syncDiscriminator.complete(state.discriminatorState, exec);
3010
3679
  const combinedState = {
3011
3680
  _discriminator: state.discriminatorState,
3012
3681
  _branch: state.branchState
3013
3682
  };
3014
- const resolvedCombinedState = resolveDeferredParseStates(combinedState);
3015
- const resolvedBranchState = resolvedCombinedState._branch;
3016
- const branchResult = branchParser.complete(resolvedBranchState, exec);
3683
+ const runtime = createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
3684
+ collectExplicitSourceValues(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path), runtime);
3685
+ collectSourcesFromState(combinedState, runtime);
3686
+ const resolvedBranchState = resolveStateWithRuntime(state.branchState, runtime);
3687
+ const completionExec = {
3688
+ ...exec ?? {
3689
+ usage: branchParser.usage,
3690
+ path: [],
3691
+ trace: void 0
3692
+ },
3693
+ phase: "complete",
3694
+ dependencyRuntime: runtime,
3695
+ dependencyRegistry: runtime.registry
3696
+ };
3697
+ const discriminatorCompleteResult = state.selectedBranch.kind === "default" ? void 0 : syncDiscriminator.complete(state.discriminatorState, withChildExecPath(completionExec, "_discriminator"));
3698
+ const branchResult = unwrapCompleteResult(branchParser.complete(resolvedBranchState, withChildExecPath(completionExec, "_branch")));
3017
3699
  if (!branchResult.success) {
3018
3700
  if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
3019
3701
  success: false,
@@ -3023,9 +3705,10 @@ function conditional(discriminator, branches, defaultBranch, options) {
3023
3705
  }
3024
3706
  let discriminatorValue;
3025
3707
  if (state.selectedBranch.kind === "default") discriminatorValue = void 0;
3026
- else if (isDependencySourceState(discriminatorCompleteResult)) discriminatorValue = discriminatorCompleteResult.result.success ? discriminatorCompleteResult.result.value : state.selectedBranch.key;
3027
- else if (discriminatorCompleteResult.success) discriminatorValue = discriminatorCompleteResult.value;
3028
- else discriminatorValue = state.selectedBranch.key;
3708
+ else {
3709
+ const completedDiscriminator = unwrapCompleteResult(discriminatorCompleteResult);
3710
+ discriminatorValue = completedDiscriminator.success ? completedDiscriminator.value : state.selectedBranch.key;
3711
+ }
3029
3712
  return {
3030
3713
  success: true,
3031
3714
  value: [discriminatorValue, branchResult.value],
@@ -3039,7 +3722,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
3039
3722
  if (state.selectedBranch === void 0) {
3040
3723
  if (defaultBranch !== void 0) {
3041
3724
  const branchState = state.branchState ?? defaultBranch.initialState;
3042
- const defaultResult = await defaultBranch.complete(branchState, exec);
3725
+ const defaultResult = unwrapCompleteResult(await defaultBranch.complete(branchState, withChildExecPath(exec, "_branch")));
3043
3726
  if (!defaultResult.success) return defaultResult;
3044
3727
  return {
3045
3728
  success: true,
@@ -3056,14 +3739,26 @@ function conditional(discriminator, branches, defaultBranch, options) {
3056
3739
  };
3057
3740
  }
3058
3741
  const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
3059
- const discriminatorCompleteResult = await discriminator.complete(state.discriminatorState, exec);
3060
3742
  const combinedState = {
3061
3743
  _discriminator: state.discriminatorState,
3062
3744
  _branch: state.branchState
3063
3745
  };
3064
- const resolvedCombinedState = await resolveDeferredParseStatesAsync(combinedState);
3065
- const resolvedBranchState = resolvedCombinedState._branch;
3066
- const branchResult = await branchParser.complete(resolvedBranchState, exec);
3746
+ const runtime = createDependencyRuntimeContext(exec?.dependencyRegistry?.clone());
3747
+ await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, exec?.path), runtime);
3748
+ collectSourcesFromState(combinedState, runtime);
3749
+ const resolvedBranchState = await resolveStateWithRuntimeAsync(state.branchState, runtime);
3750
+ const completionExec = {
3751
+ ...exec ?? {
3752
+ usage: branchParser.usage,
3753
+ path: [],
3754
+ trace: void 0
3755
+ },
3756
+ phase: "complete",
3757
+ dependencyRuntime: runtime,
3758
+ dependencyRegistry: runtime.registry
3759
+ };
3760
+ const discriminatorCompleteResult = state.selectedBranch.kind === "default" ? void 0 : await discriminator.complete(state.discriminatorState, withChildExecPath(completionExec, "_discriminator"));
3761
+ const branchResult = unwrapCompleteResult(await branchParser.complete(resolvedBranchState, withChildExecPath(completionExec, "_branch")));
3067
3762
  if (!branchResult.success) {
3068
3763
  if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
3069
3764
  success: false,
@@ -3073,9 +3768,10 @@ function conditional(discriminator, branches, defaultBranch, options) {
3073
3768
  }
3074
3769
  let discriminatorValue;
3075
3770
  if (state.selectedBranch.kind === "default") discriminatorValue = void 0;
3076
- else if (isDependencySourceState(discriminatorCompleteResult)) discriminatorValue = discriminatorCompleteResult.result.success ? discriminatorCompleteResult.result.value : state.selectedBranch.key;
3077
- else if (discriminatorCompleteResult.success) discriminatorValue = discriminatorCompleteResult.value;
3078
- else discriminatorValue = state.selectedBranch.key;
3771
+ else {
3772
+ const completedDiscriminator = unwrapCompleteResult(discriminatorCompleteResult);
3773
+ discriminatorValue = completedDiscriminator.success ? completedDiscriminator.value : state.selectedBranch.key;
3774
+ }
3079
3775
  return {
3080
3776
  success: true,
3081
3777
  value: [discriminatorValue, branchResult.value],
@@ -3091,42 +3787,92 @@ function conditional(discriminator, branches, defaultBranch, options) {
3091
3787
  const syncBranches = branches;
3092
3788
  const syncDefaultBranch = defaultBranch;
3093
3789
  if (state.selectedBranch === void 0) {
3094
- yield* syncDiscriminator.suggest({
3095
- ...context,
3096
- state: state.discriminatorState
3097
- }, prefix);
3098
- if (syncDefaultBranch !== void 0) yield* syncDefaultBranch.suggest({
3790
+ const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
3791
+ collectExplicitSourceValues(buildRuntimeNodesFromPairs(syncDefaultBranch == null ? [["_discriminator", discriminator]] : [["_discriminator", discriminator], ["_branch", syncDefaultBranch]], {
3792
+ _discriminator: state.discriminatorState,
3793
+ _branch: state.branchState
3794
+ }, context.exec?.path), runtime);
3795
+ collectSourcesFromState({
3796
+ _discriminator: state.discriminatorState,
3797
+ _branch: state.branchState
3798
+ }, runtime);
3799
+ const suggestContext = {
3099
3800
  ...context,
3100
- state: state.branchState ?? syncDefaultBranch.initialState
3101
- }, prefix);
3801
+ dependencyRegistry: runtime.registry,
3802
+ ...context.exec != null ? { exec: {
3803
+ ...context.exec,
3804
+ dependencyRuntime: runtime,
3805
+ dependencyRegistry: runtime.registry
3806
+ } } : {}
3807
+ };
3808
+ yield* syncDiscriminator.suggest(withChildContext(suggestContext, "_discriminator", state.discriminatorState), prefix);
3809
+ if (syncDefaultBranch !== void 0) yield* syncDefaultBranch.suggest(withChildContext(suggestContext, "_branch", state.branchState ?? syncDefaultBranch.initialState), prefix);
3102
3810
  } else {
3103
3811
  const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
3104
- yield* branchParser.suggest({
3812
+ const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
3813
+ const combinedState = {
3814
+ _discriminator: state.discriminatorState,
3815
+ _branch: state.branchState
3816
+ };
3817
+ collectExplicitSourceValues(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, context.exec?.path), runtime);
3818
+ collectSourcesFromState(combinedState, runtime);
3819
+ const suggestContext = {
3105
3820
  ...context,
3106
- state: state.branchState
3107
- }, prefix);
3821
+ dependencyRegistry: runtime.registry,
3822
+ ...context.exec != null ? { exec: {
3823
+ ...context.exec,
3824
+ dependencyRuntime: runtime,
3825
+ dependencyRegistry: runtime.registry
3826
+ } } : {}
3827
+ };
3828
+ yield* branchParser.suggest(withChildContext(suggestContext, "_branch", state.branchState), prefix);
3108
3829
  }
3109
3830
  }
3110
3831
  async function* suggestAsync(context, prefix) {
3111
3832
  const state = context.state ?? initialState;
3112
3833
  if (state.selectedBranch === void 0) {
3113
- yield* discriminator.suggest({
3114
- ...context,
3115
- state: state.discriminatorState
3116
- }, prefix);
3117
- if (defaultBranch !== void 0) yield* defaultBranch.suggest({
3834
+ const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
3835
+ await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs(defaultBranch == null ? [["_discriminator", discriminator]] : [["_discriminator", discriminator], ["_branch", defaultBranch]], {
3836
+ _discriminator: state.discriminatorState,
3837
+ _branch: state.branchState
3838
+ }, context.exec?.path), runtime);
3839
+ collectSourcesFromState({
3840
+ _discriminator: state.discriminatorState,
3841
+ _branch: state.branchState
3842
+ }, runtime);
3843
+ const suggestContext = {
3118
3844
  ...context,
3119
- state: state.branchState ?? defaultBranch.initialState
3120
- }, prefix);
3845
+ dependencyRegistry: runtime.registry,
3846
+ ...context.exec != null ? { exec: {
3847
+ ...context.exec,
3848
+ dependencyRuntime: runtime,
3849
+ dependencyRegistry: runtime.registry
3850
+ } } : {}
3851
+ };
3852
+ yield* discriminator.suggest(withChildContext(suggestContext, "_discriminator", state.discriminatorState), prefix);
3853
+ if (defaultBranch !== void 0) yield* defaultBranch.suggest(withChildContext(suggestContext, "_branch", state.branchState ?? defaultBranch.initialState), prefix);
3121
3854
  } else {
3122
3855
  const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
3123
- yield* branchParser.suggest({
3856
+ const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
3857
+ const combinedState = {
3858
+ _discriminator: state.discriminatorState,
3859
+ _branch: state.branchState
3860
+ };
3861
+ await collectExplicitSourceValuesAsync(buildRuntimeNodesFromPairs([["_discriminator", discriminator], ["_branch", branchParser]], combinedState, context.exec?.path), runtime);
3862
+ collectSourcesFromState(combinedState, runtime);
3863
+ const suggestContext = {
3124
3864
  ...context,
3125
- state: state.branchState
3126
- }, prefix);
3865
+ dependencyRegistry: runtime.registry,
3866
+ ...context.exec != null ? { exec: {
3867
+ ...context.exec,
3868
+ dependencyRuntime: runtime,
3869
+ dependencyRegistry: runtime.registry
3870
+ } } : {}
3871
+ };
3872
+ yield* branchParser.suggest(withChildContext(suggestContext, "_branch", state.branchState), prefix);
3127
3873
  }
3128
3874
  }
3129
- return {
3875
+ const conditionalParser = {
3130
3876
  $mode: combinedMode,
3131
3877
  $valueType: [],
3132
3878
  $stateType: [],
@@ -3174,6 +3920,8 @@ function conditional(discriminator, branches, defaultBranch, options) {
3174
3920
  return { fragments };
3175
3921
  }
3176
3922
  };
3923
+ defineInheritedAnnotationParser(conditionalParser);
3924
+ return conditionalParser;
3177
3925
  }
3178
3926
 
3179
3927
  //#endregion