@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.
package/dist/modifiers.js CHANGED
@@ -1,10 +1,84 @@
1
- import { annotateFreshArray, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
1
+ import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
2
2
  import { formatMessage, message, text } from "./message.js";
3
- import { createDependencySourceState, dependencyId, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, transformsDependencyValue, transformsDependencyValueMarker, wrappedDependencySourceMarker } from "./dependency.js";
4
3
  import { dispatchByMode, dispatchIterableByMode, mapModeValue } from "./mode-dispatch.js";
5
4
  import { composeDependencyMetadata } from "./dependency-metadata.js";
5
+ import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser } from "./parser.js";
6
6
 
7
7
  //#region src/modifiers.ts
8
+ function withChildExecPath(exec, segment) {
9
+ if (exec == null) return void 0;
10
+ return {
11
+ ...exec,
12
+ path: [...exec.path ?? [], segment]
13
+ };
14
+ }
15
+ function mergeChildExec(parent, child) {
16
+ if (parent == null) return child;
17
+ if (child == null) return parent;
18
+ return {
19
+ ...parent,
20
+ trace: child.trace ?? parent.trace,
21
+ dependencyRuntime: child.dependencyRuntime ?? parent.dependencyRuntime,
22
+ dependencyRegistry: child.dependencyRegistry ?? parent.dependencyRegistry,
23
+ preCompletedByParser: child.preCompletedByParser ?? parent.preCompletedByParser,
24
+ excludedSourceFields: child.excludedSourceFields ?? parent.excludedSourceFields
25
+ };
26
+ }
27
+ function withChildContext(context, segment, state) {
28
+ const exec = withChildExecPath(context.exec, segment);
29
+ const dependencyRegistry = context.dependencyRegistry ?? exec?.dependencyRegistry;
30
+ return {
31
+ ...context,
32
+ state,
33
+ ...exec != null ? {
34
+ exec: dependencyRegistry === exec.dependencyRegistry ? exec : {
35
+ ...exec,
36
+ dependencyRegistry
37
+ },
38
+ dependencyRegistry
39
+ } : {}
40
+ };
41
+ }
42
+ function isTerminalMultipleItemState(state) {
43
+ const unwrapped = unwrapMultipleItemState(state).value;
44
+ return unwrapped != null && typeof unwrapped === "object" && Object.hasOwn(unwrapped, "success") && typeof unwrapped.success === "boolean";
45
+ }
46
+ function isUnstartedMultipleItemState(state, originalState) {
47
+ const unwrappedState = unwrapMultipleItemState(state);
48
+ if (unwrappedState.value == null) return true;
49
+ if (originalState === void 0) return false;
50
+ const unwrappedOriginalState = unwrapMultipleItemState(originalState);
51
+ return unwrappedState.value === unwrappedOriginalState.value && (unwrappedState.viaBoundCliWrapper || unwrappedOriginalState.viaBoundCliWrapper || unwrappedOriginalState.value != null && typeof unwrappedOriginalState.value === "object");
52
+ }
53
+ function isBoundCliWrapperState(state) {
54
+ return state != null && typeof state === "object" && Object.hasOwn(state, "hasCliValue") && typeof state.hasCliValue === "boolean" && (Object.hasOwn(state, "cliState") || state.hasCliValue === false);
55
+ }
56
+ function unwrapMultipleItemState(state) {
57
+ let unwrapped = state;
58
+ let viaBoundCliWrapper = false;
59
+ while (true) {
60
+ if (isInjectedAnnotationWrapper(unwrapped)) {
61
+ unwrapped = unwrapInjectedAnnotationWrapper(unwrapped);
62
+ continue;
63
+ }
64
+ if (Array.isArray(unwrapped) && unwrapped.length === 1) {
65
+ unwrapped = unwrapped[0];
66
+ continue;
67
+ }
68
+ if (isBoundCliWrapperState(unwrapped)) {
69
+ viaBoundCliWrapper = true;
70
+ unwrapped = unwrapped.cliState;
71
+ continue;
72
+ }
73
+ return {
74
+ value: unwrapped,
75
+ viaBoundCliWrapper
76
+ };
77
+ }
78
+ }
79
+ function isPromiseLike(value) {
80
+ return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
81
+ }
8
82
  /**
9
83
  * Internal helper for optional-style parsing logic shared by optional()
10
84
  * and withDefault(). Handles the common pattern of:
@@ -75,16 +149,26 @@ function processOptionalStyleResult(result, innerState, context) {
75
149
  *
76
150
  * @internal
77
151
  */
78
- function adaptShouldDeferCompletion(innerCheck) {
152
+ function adaptShouldDeferCompletion(innerCheck, parser) {
79
153
  return (state, exec) => {
80
- if (Array.isArray(state)) {
81
- const inner = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
82
- return innerCheck(inner, exec);
83
- }
84
- if (state != null && typeof state === "object") return innerCheck(state, exec);
154
+ if (Array.isArray(state) || state != null && typeof state === "object") return innerCheck(normalizeOptionalLikeInnerState(state, parser.initialState, parser), exec);
85
155
  return false;
86
156
  };
87
157
  }
158
+ function isAnnotationOnlyObjectState(state) {
159
+ if (state == null || typeof state !== "object" || Array.isArray(state) || isInjectedAnnotationWrapper(state)) return false;
160
+ const keys = Reflect.ownKeys(state);
161
+ return getAnnotations(state) != null && keys.length === 1 && keys[0] === annotationKey;
162
+ }
163
+ function normalizeOptionalLikeInnerState(state, initialState, parser) {
164
+ if (Array.isArray(state)) return getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
165
+ if (isAnnotationOnlyObjectState(state)) {
166
+ if (parser != null && (parser.dependencyMetadata?.source != null || typeof parser.shouldDeferCompletion === "function")) return inheritAnnotations(state, initialState);
167
+ return initialState;
168
+ }
169
+ if (state != null && typeof state === "object") return state;
170
+ return initialState;
171
+ }
88
172
  /**
89
173
  * Creates a parser that makes another parser optional, allowing it to succeed
90
174
  * without consuming input if the wrapped parser fails to match.
@@ -100,25 +184,20 @@ function adaptShouldDeferCompletion(innerCheck) {
100
184
  function optional(parser) {
101
185
  const syncParser = parser;
102
186
  function* suggestSync(context, prefix) {
103
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
187
+ const innerState = normalizeOptionalLikeInnerState(context.state, syncParser.initialState, parser);
104
188
  yield* syncParser.suggest({
105
189
  ...context,
106
190
  state: innerState
107
191
  }, prefix);
108
192
  }
109
193
  async function* suggestAsync(context, prefix) {
110
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
194
+ const innerState = normalizeOptionalLikeInnerState(context.state, syncParser.initialState, parser);
111
195
  const suggestions = parser.suggest({
112
196
  ...context,
113
197
  state: innerState
114
198
  }, prefix);
115
199
  for await (const s of suggestions) yield s;
116
200
  }
117
- const innerHasWrappedDependency = isWrappedDependencySource(parser);
118
- const innerHasDirectDependency = isPendingDependencySourceState(syncParser.initialState);
119
- const wrappedDependencyMarker = innerHasWrappedDependency ? { [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker] } : innerHasDirectDependency ? { [wrappedDependencySourceMarker]: syncParser.initialState } : {};
120
- const hasWrappedDependencySource = wrappedDependencySourceMarker in wrappedDependencyMarker;
121
- const wrappedPendingState = hasWrappedDependencySource ? wrappedDependencyMarker[wrappedDependencySourceMarker] : void 0;
122
201
  const optionalParser = {
123
202
  $mode: parser.$mode,
124
203
  $valueType: [],
@@ -132,17 +211,29 @@ function optional(parser) {
132
211
  leadingNames: parser.leadingNames,
133
212
  acceptingAnyToken: false,
134
213
  initialState: void 0,
135
- ...wrappedDependencyMarker,
136
- ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser)) } : {},
214
+ ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
215
+ getSuggestRuntimeNodes(state, path) {
216
+ if (optionalParser.dependencyMetadata?.source != null) return [{
217
+ path,
218
+ parser: optionalParser,
219
+ state
220
+ }];
221
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
222
+ return parser.getSuggestRuntimeNodes?.(innerState, path) ?? (parser.dependencyMetadata?.source != null ? [{
223
+ path,
224
+ parser,
225
+ state: innerState
226
+ }] : []);
227
+ },
137
228
  parse(context) {
138
229
  return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
139
230
  },
140
231
  complete(state, exec) {
141
232
  if (!Array.isArray(state)) {
142
- if (innerHasWrappedDependency && wrappedPendingState) return dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState], exec), () => parser.complete([wrappedPendingState], exec));
143
233
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
144
234
  const innerComplete = () => {
145
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
235
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
236
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(innerState, exec), async () => await parser.complete(innerState, exec));
146
237
  return mapModeValue(parser.$mode, innerResult, (result) => result.success ? result : {
147
238
  success: true,
148
239
  value: void 0
@@ -150,20 +241,18 @@ function optional(parser) {
150
241
  };
151
242
  return innerComplete();
152
243
  }
244
+ const sourceMetadata = parser.dependencyMetadata?.source;
245
+ if (sourceMetadata?.preservesSourceValue !== false && sourceMetadata?.getMissingSourceValue != null) {
246
+ const delegatedState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
247
+ return dispatchByMode(parser.$mode, () => syncParser.complete(delegatedState, exec), async () => await parser.complete(delegatedState, exec));
248
+ }
153
249
  return {
154
250
  success: true,
155
251
  value: void 0
156
252
  };
157
253
  }
158
- if (Array.isArray(state) && state.length === 1 && isPendingDependencySourceState(state[0])) {
159
- if (innerHasWrappedDependency) return dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
160
- return {
161
- success: true,
162
- value: void 0
163
- };
164
- }
165
- const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
166
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
254
+ const innerElement = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
255
+ return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), async () => await parser.complete(innerElement, exec));
167
256
  },
168
257
  suggest(context, prefix) {
169
258
  return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -191,6 +280,8 @@ function optional(parser) {
191
280
  const composed = composeDependencyMetadata(parser.dependencyMetadata, "optional");
192
281
  if (composed != null) optionalParser.dependencyMetadata = composed;
193
282
  }
283
+ defineInheritedAnnotationParser(optionalParser);
284
+ defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
194
285
  return optionalParser;
195
286
  }
196
287
  /**
@@ -240,22 +331,20 @@ function withDefault(parser, defaultValue, options) {
240
331
  }
241
332
  };
242
333
  function* suggestSync(context, prefix) {
243
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
334
+ const innerState = normalizeOptionalLikeInnerState(context.state, syncParser.initialState, parser);
244
335
  yield* syncParser.suggest({
245
336
  ...context,
246
337
  state: innerState
247
338
  }, prefix);
248
339
  }
249
340
  async function* suggestAsync(context, prefix) {
250
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
341
+ const innerState = normalizeOptionalLikeInnerState(context.state, syncParser.initialState, parser);
251
342
  const suggestions = parser.suggest({
252
343
  ...context,
253
344
  state: innerState
254
345
  }, prefix);
255
346
  for await (const s of suggestions) yield s;
256
347
  }
257
- const innerInitialState = syncParser.initialState;
258
- const wrappedDependencyMarker = isPendingDependencySourceState(innerInitialState) ? { [wrappedDependencySourceMarker]: innerInitialState } : isWrappedDependencySource(parser) ? { [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker] } : {};
259
348
  const withDefaultParser = {
260
349
  $mode: parser.$mode,
261
350
  $valueType: [],
@@ -268,8 +357,20 @@ function withDefault(parser, defaultValue, options) {
268
357
  leadingNames: parser.leadingNames,
269
358
  acceptingAnyToken: false,
270
359
  initialState: void 0,
271
- ...wrappedDependencyMarker,
272
- ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser)) } : {},
360
+ ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
361
+ getSuggestRuntimeNodes(state, path) {
362
+ if (withDefaultParser.dependencyMetadata?.source != null) return [{
363
+ path,
364
+ parser: withDefaultParser,
365
+ state
366
+ }];
367
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
368
+ return parser.getSuggestRuntimeNodes?.(innerState, path) ?? (parser.dependencyMetadata?.source != null ? [{
369
+ path,
370
+ parser,
371
+ state: innerState
372
+ }] : []);
373
+ },
273
374
  parse(context) {
274
375
  return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
275
376
  },
@@ -282,51 +383,9 @@ function withDefault(parser, defaultValue, options) {
282
383
  return raw;
283
384
  }
284
385
  if (!Array.isArray(state)) {
285
- if (transformsDependencyValue(parser)) {
286
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(void 0, exec), () => parser.complete(void 0, exec));
287
- const handleInnerResult = (res) => {
288
- if (isDependencySourceState(res)) try {
289
- const value = evaluateDefault();
290
- return createDependencySourceState({
291
- success: true,
292
- value
293
- }, res[dependencyId]);
294
- } catch (error) {
295
- return {
296
- success: false,
297
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
298
- };
299
- }
300
- try {
301
- const value = evaluateDefault();
302
- return {
303
- success: true,
304
- value
305
- };
306
- } catch (error) {
307
- return {
308
- success: false,
309
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
310
- };
311
- }
312
- };
313
- return mapModeValue(parser.$mode, innerResult, handleInnerResult);
314
- }
315
- if (isWrappedDependencySource(parser)) try {
316
- const value = evaluateDefault();
317
- const pendingState = parser[wrappedDependencySourceMarker];
318
- return createDependencySourceState({
319
- success: true,
320
- value
321
- }, pendingState[dependencyId]);
322
- } catch (error) {
323
- return {
324
- success: false,
325
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
326
- };
327
- }
328
386
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
329
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
387
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
388
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(innerState, exec), async () => await parser.complete(innerState, exec));
330
389
  return innerResult;
331
390
  }
332
391
  try {
@@ -342,52 +401,8 @@ function withDefault(parser, defaultValue, options) {
342
401
  };
343
402
  }
344
403
  }
345
- if (isPendingDependencySourceState(state[0])) {
346
- if (transformsDependencyValue(parser)) {
347
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
348
- const handleInnerResult = (res) => {
349
- if (isDependencySourceState(res)) try {
350
- const value = evaluateDefault();
351
- return createDependencySourceState({
352
- success: true,
353
- value
354
- }, res[dependencyId]);
355
- } catch (error) {
356
- return {
357
- success: false,
358
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
359
- };
360
- }
361
- try {
362
- const value = evaluateDefault();
363
- return {
364
- success: true,
365
- value
366
- };
367
- } catch (error) {
368
- return {
369
- success: false,
370
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
371
- };
372
- }
373
- };
374
- return mapModeValue(parser.$mode, innerResult, handleInnerResult);
375
- }
376
- try {
377
- const value = evaluateDefault();
378
- return createDependencySourceState({
379
- success: true,
380
- value
381
- }, state[0][dependencyId]);
382
- } catch (error) {
383
- return {
384
- success: false,
385
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
386
- };
387
- }
388
- }
389
- const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
390
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
404
+ const innerElement = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
405
+ return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), async () => await parser.complete(innerElement, exec));
391
406
  },
392
407
  suggest(context, prefix) {
393
408
  return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -461,6 +476,8 @@ function withDefault(parser, defaultValue, options) {
461
476
  } });
462
477
  if (composed != null) withDefaultParser.dependencyMetadata = composed;
463
478
  }
479
+ defineInheritedAnnotationParser(withDefaultParser);
480
+ defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
464
481
  return withDefaultParser;
465
482
  }
466
483
  /**
@@ -561,15 +578,22 @@ function map(parser, transform) {
561
578
  };
562
579
  });
563
580
  };
564
- const dependencyMarkers = isWrappedDependencySource(parser) ? {
565
- [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker],
566
- [transformsDependencyValueMarker]: true
567
- } : {};
568
581
  const mappedParser = {
569
582
  ...parser,
570
583
  $valueType: [],
571
584
  complete,
572
- ...dependencyMarkers,
585
+ getSuggestRuntimeNodes(state, path) {
586
+ if (mappedParser.dependencyMetadata?.source != null) return [{
587
+ path,
588
+ parser: mappedParser,
589
+ state
590
+ }];
591
+ return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
592
+ path,
593
+ parser,
594
+ state
595
+ }] : []);
596
+ },
573
597
  getDocFragments(state, _defaultValue) {
574
598
  return parser.getDocFragments(state, void 0);
575
599
  }
@@ -616,7 +640,7 @@ function map(parser, transform) {
616
640
  ...composed.derived,
617
641
  replayParse: (rawInput, depValues) => {
618
642
  const result = innerReplay(rawInput, depValues);
619
- return result instanceof Promise ? result.then(applyMappedReplay) : applyMappedReplay(result);
643
+ return isPromiseLike(result) ? result.then(applyMappedReplay) : applyMappedReplay(result);
620
644
  }
621
645
  }
622
646
  };
@@ -646,7 +670,9 @@ function multiple(parser, options = {}) {
646
670
  const unwrapInjectedWrapper = unwrapInjectedAnnotationWrapper;
647
671
  const completeSyncWithUnwrappedFallback = (state, exec) => {
648
672
  try {
649
- return syncParser.complete(state, exec);
673
+ const result = syncParser.complete(state, exec);
674
+ if (!result.success && isInjectedAnnotationWrapper(state)) return syncParser.complete(unwrapInjectedWrapper(state), exec);
675
+ return result;
650
676
  } catch (error) {
651
677
  if (!isInjectedAnnotationWrapper(state)) throw error;
652
678
  return syncParser.complete(unwrapInjectedWrapper(state), exec);
@@ -670,7 +696,9 @@ function multiple(parser, options = {}) {
670
696
  };
671
697
  const completeAsyncWithUnwrappedFallback = async (state, exec) => {
672
698
  try {
673
- return await parser.complete(state, exec);
699
+ const result = await parser.complete(state, exec);
700
+ if (!result.success && isInjectedAnnotationWrapper(state)) return await parser.complete(unwrapInjectedWrapper(state), exec);
701
+ return result;
674
702
  } catch (error) {
675
703
  if (!isInjectedAnnotationWrapper(state)) throw error;
676
704
  return await parser.complete(unwrapInjectedWrapper(state), exec);
@@ -692,56 +720,133 @@ function multiple(parser, options = {}) {
692
720
  });
693
721
  }
694
722
  };
723
+ const getInnerSuggestRuntimeNodes = (state, path) => parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
724
+ path,
725
+ parser,
726
+ state
727
+ }] : []);
695
728
  const parseSync = (context) => {
696
- let added = context.state.length < 1;
697
- const currentItemStateWithAnnotations = context.state.at(-1) ?? inheritAnnotations(context.state, syncParser.initialState);
698
- let result = parseSyncWithUnwrappedFallback({
699
- ...context,
700
- state: currentItemStateWithAnnotations
701
- });
702
- if (!result.success) if (!added) {
729
+ const currentItemState = context.state.at(-1);
730
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
731
+ const canOpenFreshItem = context.state.length < max;
732
+ if (!canExtendCurrent && !canOpenFreshItem) return {
733
+ success: true,
734
+ next: context,
735
+ consumed: []
736
+ };
737
+ let added = !canExtendCurrent;
738
+ let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
739
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, syncParser.initialState);
740
+ let result = parseSyncWithUnwrappedFallback(withChildContext(context, itemIndex, currentItemStateWithAnnotations));
741
+ if (!result.success) if (!added && canOpenFreshItem && result.consumed === 0) {
703
742
  const nextInitialState = inheritAnnotations(context.state, syncParser.initialState);
704
- result = parseSyncWithUnwrappedFallback({
705
- ...context,
706
- state: nextInitialState
707
- });
743
+ itemIndex = context.state.length;
744
+ result = parseSyncWithUnwrappedFallback(withChildContext(context, itemIndex, nextInitialState));
708
745
  if (!result.success) return result;
709
746
  added = true;
710
747
  } else return result;
748
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
749
+ if (added && result.consumed.length === 0 && result.next.optionsTerminated === context.optionsTerminated && isUnstartedMultipleItemState(result.next.state, currentItemStateWithAnnotations)) return {
750
+ success: true,
751
+ next: {
752
+ ...result.next,
753
+ state: context.state,
754
+ ...mergedExec != null ? {
755
+ trace: mergedExec.trace,
756
+ exec: mergedExec,
757
+ dependencyRegistry: mergedExec.dependencyRegistry
758
+ } : {}
759
+ },
760
+ consumed: result.consumed
761
+ };
711
762
  const itemAnnotationSource = added ? context.state : currentItemStateWithAnnotations;
763
+ if (result.next.state === currentItemStateWithAnnotations && result.consumed.length > 0 && (!added || result.next.optionsTerminated !== context.optionsTerminated)) return {
764
+ success: true,
765
+ next: {
766
+ ...result.next,
767
+ state: context.state,
768
+ ...mergedExec != null ? {
769
+ trace: mergedExec.trace,
770
+ exec: mergedExec,
771
+ dependencyRegistry: mergedExec.dependencyRegistry
772
+ } : {}
773
+ },
774
+ consumed: result.consumed
775
+ };
712
776
  const nextItemState = inheritAnnotations(itemAnnotationSource, result.next.state);
713
777
  return {
714
778
  success: true,
715
779
  next: {
716
780
  ...result.next,
717
- state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState])
781
+ state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
782
+ ...mergedExec != null ? {
783
+ trace: mergedExec.trace,
784
+ exec: mergedExec,
785
+ dependencyRegistry: mergedExec.dependencyRegistry
786
+ } : {}
718
787
  },
719
788
  consumed: result.consumed
720
789
  };
721
790
  };
722
791
  const parseAsync = async (context) => {
723
- let added = context.state.length < 1;
724
- const currentItemStateWithAnnotations = context.state.at(-1) ?? inheritAnnotations(context.state, parser.initialState);
725
- let result = await parseAsyncWithUnwrappedFallback({
726
- ...context,
727
- state: currentItemStateWithAnnotations
728
- });
729
- if (!result.success) if (!added) {
792
+ const currentItemState = context.state.at(-1);
793
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
794
+ const canOpenFreshItem = context.state.length < max;
795
+ if (!canExtendCurrent && !canOpenFreshItem) return {
796
+ success: true,
797
+ next: context,
798
+ consumed: []
799
+ };
800
+ let added = !canExtendCurrent;
801
+ let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
802
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, parser.initialState);
803
+ let result = await parseAsyncWithUnwrappedFallback(withChildContext(context, itemIndex, currentItemStateWithAnnotations));
804
+ if (!result.success) if (!added && canOpenFreshItem && result.consumed === 0) {
730
805
  const nextInitialState = inheritAnnotations(context.state, parser.initialState);
731
- result = await parseAsyncWithUnwrappedFallback({
732
- ...context,
733
- state: nextInitialState
734
- });
806
+ itemIndex = context.state.length;
807
+ result = await parseAsyncWithUnwrappedFallback(withChildContext(context, itemIndex, nextInitialState));
735
808
  if (!result.success) return result;
736
809
  added = true;
737
810
  } else return result;
811
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
812
+ if (added && result.consumed.length === 0 && result.next.optionsTerminated === context.optionsTerminated && isUnstartedMultipleItemState(result.next.state, currentItemStateWithAnnotations)) return {
813
+ success: true,
814
+ next: {
815
+ ...result.next,
816
+ state: context.state,
817
+ ...mergedExec != null ? {
818
+ trace: mergedExec.trace,
819
+ exec: mergedExec,
820
+ dependencyRegistry: mergedExec.dependencyRegistry
821
+ } : {}
822
+ },
823
+ consumed: result.consumed
824
+ };
738
825
  const itemAnnotationSource = added ? context.state : currentItemStateWithAnnotations;
826
+ if (result.next.state === currentItemStateWithAnnotations && result.consumed.length > 0 && (!added || result.next.optionsTerminated !== context.optionsTerminated)) return {
827
+ success: true,
828
+ next: {
829
+ ...result.next,
830
+ state: context.state,
831
+ ...mergedExec != null ? {
832
+ trace: mergedExec.trace,
833
+ exec: mergedExec,
834
+ dependencyRegistry: mergedExec.dependencyRegistry
835
+ } : {}
836
+ },
837
+ consumed: result.consumed
838
+ };
739
839
  const nextItemState = inheritAnnotations(itemAnnotationSource, result.next.state);
740
840
  return {
741
841
  success: true,
742
842
  next: {
743
843
  ...result.next,
744
- state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState])
844
+ state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
845
+ ...mergedExec != null ? {
846
+ trace: mergedExec.trace,
847
+ exec: mergedExec,
848
+ dependencyRegistry: mergedExec.dependencyRegistry
849
+ } : {}
745
850
  },
746
851
  consumed: result.consumed
747
852
  };
@@ -759,6 +864,14 @@ function multiple(parser, options = {}) {
759
864
  leadingNames: parser.leadingNames,
760
865
  acceptingAnyToken: min > 0 && (parser.acceptingAnyToken ?? false),
761
866
  initialState: [],
867
+ getSuggestRuntimeNodes(state, path) {
868
+ const innerNodes = state.flatMap((item, i) => [...getInnerSuggestRuntimeNodes(item, [...path, i])]);
869
+ return resultParser.dependencyMetadata?.source != null ? [{
870
+ path,
871
+ parser: resultParser,
872
+ state
873
+ }, ...innerNodes] : innerNodes;
874
+ },
762
875
  parse(context) {
763
876
  return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
764
877
  },
@@ -768,7 +881,7 @@ function multiple(parser, options = {}) {
768
881
  const deferredIndices = /* @__PURE__ */ new Map();
769
882
  let hasDeferred = false;
770
883
  for (let i = 0; i < state.length; i++) {
771
- const valueResult = completeSyncWithUnwrappedFallback(state[i], exec);
884
+ const valueResult = completeSyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
772
885
  if (valueResult.success) {
773
886
  const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
774
887
  result.push(unwrappedValue);
@@ -782,12 +895,11 @@ function multiple(parser, options = {}) {
782
895
  }
783
896
  return validateMultipleResult(result, deferredIndices, hasDeferred);
784
897
  }, async () => {
785
- const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s, exec)));
786
898
  const values = [];
787
899
  const deferredIndices = /* @__PURE__ */ new Map();
788
900
  let hasDeferred = false;
789
- for (let i = 0; i < results.length; i++) {
790
- const valueResult = results[i];
901
+ for (let i = 0; i < state.length; i++) {
902
+ const valueResult = await completeAsyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
791
903
  if (valueResult.success) {
792
904
  const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
793
905
  values.push(unwrappedValue);
@@ -803,18 +915,33 @@ function multiple(parser, options = {}) {
803
915
  });
804
916
  },
805
917
  suggest(context, prefix) {
806
- const selectedValues = /* @__PURE__ */ new Set();
807
- const suggestInitialState = inheritAnnotations(context.state, parser.initialState);
918
+ const currentItemState = context.state.at(-1);
919
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
920
+ const canOpenNew = context.state.length < max;
921
+ if (!canExtendCurrent && !canOpenNew) return dispatchIterableByMode(parser.$mode, function* () {}, async function* () {});
922
+ const itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
923
+ const suggestInitialState = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, parser.initialState);
808
924
  const suggestFallbackState = unwrapInjectedWrapper(suggestInitialState);
809
925
  const hasSuggestFallbackState = suggestFallbackState !== suggestInitialState;
810
- for (const s of context.state) {
811
- const completed = completeSyncWithUnwrappedFallback(s);
812
- if (completed.success) {
813
- const valueStr = String(unwrapInjectedWrapper(completed.value));
814
- selectedValues.add(valueStr);
926
+ const collectSelectedValuesSync = () => {
927
+ const selectedValues = /* @__PURE__ */ new Set();
928
+ for (let i = 0; i < context.state.length; i++) {
929
+ const childContext = withChildContext(context, i, context.state[i]);
930
+ const completed = completeSyncWithUnwrappedFallback(childContext.state, childContext.exec);
931
+ if (completed.success) selectedValues.add(String(unwrapInjectedWrapper(completed.value)));
815
932
  }
816
- }
817
- const shouldInclude = (suggestion) => {
933
+ return selectedValues;
934
+ };
935
+ const collectSelectedValuesAsync = async () => {
936
+ const selectedValues = /* @__PURE__ */ new Set();
937
+ for (let i = 0; i < context.state.length; i++) {
938
+ const childContext = withChildContext(context, i, context.state[i]);
939
+ const completed = await completeAsyncWithUnwrappedFallback(childContext.state, childContext.exec);
940
+ if (completed.success) selectedValues.add(String(unwrapInjectedWrapper(completed.value)));
941
+ }
942
+ return selectedValues;
943
+ };
944
+ const shouldInclude = (selectedValues, suggestion) => {
818
945
  if (suggestion.kind === "literal") return !selectedValues.has(suggestion.text);
819
946
  return true;
820
947
  };
@@ -835,11 +962,12 @@ function multiple(parser, options = {}) {
835
962
  ]);
836
963
  };
837
964
  return dispatchIterableByMode(parser.$mode, function* () {
965
+ const selectedValues = collectSelectedValuesSync();
838
966
  const emitted = /* @__PURE__ */ new Set();
839
967
  const yieldUnique = function* (suggestions) {
840
968
  for (const s of suggestions) {
841
969
  const key = suggestionKey(s);
842
- if (shouldInclude(s) && !emitted.has(key)) {
970
+ if (shouldInclude(selectedValues, s) && !emitted.has(key)) {
843
971
  emitted.add(key);
844
972
  yield s;
845
973
  }
@@ -847,24 +975,19 @@ function multiple(parser, options = {}) {
847
975
  };
848
976
  let shouldTryFallback = false;
849
977
  try {
850
- yield* yieldUnique(syncParser.suggest({
851
- ...context,
852
- state: suggestInitialState
853
- }, prefix));
978
+ yield* yieldUnique(syncParser.suggest(withChildContext(context, itemIndex, suggestInitialState), prefix));
854
979
  } catch (error) {
855
980
  if (!hasSuggestFallbackState) throw error;
856
981
  shouldTryFallback = true;
857
982
  }
858
- if (shouldTryFallback) yield* yieldUnique(syncParser.suggest({
859
- ...context,
860
- state: suggestFallbackState
861
- }, prefix));
983
+ if (shouldTryFallback) yield* yieldUnique(syncParser.suggest(withChildContext(context, itemIndex, suggestFallbackState), prefix));
862
984
  }, async function* () {
985
+ const selectedValues = await collectSelectedValuesAsync();
863
986
  const emitted = /* @__PURE__ */ new Set();
864
987
  const yieldUnique = async function* (suggestions) {
865
988
  for await (const s of suggestions) {
866
989
  const key = suggestionKey(s);
867
- if (shouldInclude(s) && !emitted.has(key)) {
990
+ if (shouldInclude(selectedValues, s) && !emitted.has(key)) {
868
991
  emitted.add(key);
869
992
  yield s;
870
993
  }
@@ -872,18 +995,12 @@ function multiple(parser, options = {}) {
872
995
  };
873
996
  let shouldTryFallback = false;
874
997
  try {
875
- yield* yieldUnique(parser.suggest({
876
- ...context,
877
- state: suggestInitialState
878
- }, prefix));
998
+ yield* yieldUnique(parser.suggest(withChildContext(context, itemIndex, suggestInitialState), prefix));
879
999
  } catch (error) {
880
1000
  if (!hasSuggestFallbackState) throw error;
881
1001
  shouldTryFallback = true;
882
1002
  }
883
- if (shouldTryFallback) yield* yieldUnique(parser.suggest({
884
- ...context,
885
- state: suggestFallbackState
886
- }, prefix));
1003
+ if (shouldTryFallback) yield* yieldUnique(parser.suggest(withChildContext(context, itemIndex, suggestFallbackState), prefix));
887
1004
  });
888
1005
  },
889
1006
  getDocFragments(state, defaultValue) {
@@ -951,6 +1068,33 @@ function multiple(parser, options = {}) {
951
1068
  enumerable: false
952
1069
  });
953
1070
  }
1071
+ if (parser.dependencyMetadata?.source != null) {
1072
+ const innerSource = parser.dependencyMetadata.source;
1073
+ Object.defineProperty(resultParser, "dependencyMetadata", {
1074
+ value: {
1075
+ ...parser.dependencyMetadata,
1076
+ source: {
1077
+ ...innerSource,
1078
+ preservesSourceValue: false,
1079
+ extractSourceValue: (state) => {
1080
+ if (!Array.isArray(state)) return innerSource.extractSourceValue(state);
1081
+ const scan = (index) => {
1082
+ for (let i = index; i >= 0; i--) {
1083
+ const result = innerSource.extractSourceValue(state[i]);
1084
+ if (result == null) continue;
1085
+ if (isPromiseLike(result)) return Promise.resolve(result).then((resolved) => resolved ?? scan(i - 1));
1086
+ return result;
1087
+ }
1088
+ return void 0;
1089
+ };
1090
+ return scan(state.length - 1);
1091
+ }
1092
+ }
1093
+ },
1094
+ configurable: true,
1095
+ enumerable: false
1096
+ });
1097
+ }
954
1098
  return resultParser;
955
1099
  }
956
1100
  /**
@@ -1019,6 +1163,13 @@ function nonEmpty(parser) {
1019
1163
  acceptingAnyToken: parser.acceptingAnyToken,
1020
1164
  initialState: parser.initialState,
1021
1165
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
1166
+ getSuggestRuntimeNodes(state, path) {
1167
+ return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
1168
+ path,
1169
+ parser,
1170
+ state
1171
+ }] : []);
1172
+ },
1022
1173
  parse(context) {
1023
1174
  return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
1024
1175
  },