@optique/core 1.0.0-dev.921 → 1.0.1

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.
Files changed (109) hide show
  1. package/dist/annotation-state.cjs +425 -0
  2. package/dist/annotation-state.d.cts +24 -0
  3. package/dist/annotation-state.d.ts +24 -0
  4. package/dist/annotation-state.js +414 -0
  5. package/dist/annotations.cjs +2 -248
  6. package/dist/annotations.d.cts +2 -137
  7. package/dist/annotations.d.ts +2 -137
  8. package/dist/annotations.js +2 -238
  9. package/dist/completion.cjs +611 -100
  10. package/dist/completion.d.cts +1 -1
  11. package/dist/completion.d.ts +1 -1
  12. package/dist/completion.js +611 -100
  13. package/dist/constructs.cjs +3338 -827
  14. package/dist/constructs.d.cts +48 -7
  15. package/dist/constructs.d.ts +48 -7
  16. package/dist/constructs.js +3338 -827
  17. package/dist/context.cjs +0 -23
  18. package/dist/context.d.cts +119 -53
  19. package/dist/context.d.ts +119 -53
  20. package/dist/context.js +0 -22
  21. package/dist/dependency-metadata.cjs +139 -0
  22. package/dist/dependency-metadata.d.cts +112 -0
  23. package/dist/dependency-metadata.d.ts +112 -0
  24. package/dist/dependency-metadata.js +138 -0
  25. package/dist/dependency-runtime.cjs +698 -0
  26. package/dist/dependency-runtime.d.cts +149 -0
  27. package/dist/dependency-runtime.d.ts +149 -0
  28. package/dist/dependency-runtime.js +687 -0
  29. package/dist/dependency.cjs +7 -928
  30. package/dist/dependency.d.cts +2 -794
  31. package/dist/dependency.d.ts +2 -794
  32. package/dist/dependency.js +2 -899
  33. package/dist/displaywidth.cjs +44 -0
  34. package/dist/displaywidth.js +43 -0
  35. package/dist/doc.cjs +285 -23
  36. package/dist/doc.d.cts +57 -2
  37. package/dist/doc.d.ts +57 -2
  38. package/dist/doc.js +283 -25
  39. package/dist/execution-context.cjs +56 -0
  40. package/dist/execution-context.js +53 -0
  41. package/dist/extension.cjs +87 -0
  42. package/dist/extension.d.cts +97 -0
  43. package/dist/extension.d.ts +97 -0
  44. package/dist/extension.js +76 -0
  45. package/dist/facade.cjs +718 -525
  46. package/dist/facade.d.cts +59 -15
  47. package/dist/facade.d.ts +59 -15
  48. package/dist/facade.js +718 -525
  49. package/dist/index.cjs +14 -29
  50. package/dist/index.d.cts +10 -10
  51. package/dist/index.d.ts +10 -10
  52. package/dist/index.js +7 -7
  53. package/dist/input-trace.cjs +56 -0
  54. package/dist/input-trace.d.cts +77 -0
  55. package/dist/input-trace.d.ts +77 -0
  56. package/dist/input-trace.js +55 -0
  57. package/dist/internal/annotations.cjs +316 -0
  58. package/dist/internal/annotations.d.cts +140 -0
  59. package/dist/internal/annotations.d.ts +140 -0
  60. package/dist/internal/annotations.js +306 -0
  61. package/dist/internal/dependency.cjs +984 -0
  62. package/dist/internal/dependency.d.cts +539 -0
  63. package/dist/internal/dependency.d.ts +539 -0
  64. package/dist/internal/dependency.js +964 -0
  65. package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
  66. package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
  67. package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
  68. package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
  69. package/dist/internal/parser.cjs +728 -0
  70. package/dist/internal/parser.d.cts +947 -0
  71. package/dist/internal/parser.d.ts +947 -0
  72. package/dist/internal/parser.js +711 -0
  73. package/dist/message.cjs +84 -26
  74. package/dist/message.d.cts +49 -9
  75. package/dist/message.d.ts +49 -9
  76. package/dist/message.js +84 -27
  77. package/dist/modifiers.cjs +1023 -240
  78. package/dist/modifiers.d.cts +42 -1
  79. package/dist/modifiers.d.ts +42 -1
  80. package/dist/modifiers.js +1023 -240
  81. package/dist/parser.cjs +11 -463
  82. package/dist/parser.d.cts +3 -537
  83. package/dist/parser.d.ts +3 -537
  84. package/dist/parser.js +2 -433
  85. package/dist/phase2-seed.cjs +59 -0
  86. package/dist/phase2-seed.js +56 -0
  87. package/dist/primitives.cjs +557 -208
  88. package/dist/primitives.d.cts +10 -14
  89. package/dist/primitives.d.ts +10 -14
  90. package/dist/primitives.js +557 -208
  91. package/dist/program.cjs +5 -1
  92. package/dist/program.d.cts +5 -3
  93. package/dist/program.d.ts +5 -3
  94. package/dist/program.js +6 -1
  95. package/dist/suggestion.cjs +22 -8
  96. package/dist/suggestion.js +22 -8
  97. package/dist/usage-internals.cjs +3 -2
  98. package/dist/usage-internals.js +4 -2
  99. package/dist/usage.cjs +195 -40
  100. package/dist/usage.d.cts +92 -11
  101. package/dist/usage.d.ts +92 -11
  102. package/dist/usage.js +194 -41
  103. package/dist/validate.cjs +170 -0
  104. package/dist/validate.js +164 -0
  105. package/dist/valueparser.cjs +1270 -187
  106. package/dist/valueparser.d.cts +320 -14
  107. package/dist/valueparser.d.ts +320 -14
  108. package/dist/valueparser.js +1269 -188
  109. package/package.json +9 -9
package/dist/modifiers.js CHANGED
@@ -1,20 +1,178 @@
1
- import { annotateFreshArray, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
1
+ import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./internal/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
- import { dispatchByMode, dispatchIterableByMode, mapModeValue } from "./mode-dispatch.js";
3
+ import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
4
+ import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
5
+ import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
6
+ import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
7
+ import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
8
+ import { composeDependencyMetadata } from "./dependency-metadata.js";
5
9
 
6
10
  //#region src/modifiers.ts
7
- const deferPromptUntilConfigResolvesKey = Symbol.for("@optique/config/deferPromptUntilResolved");
11
+ function isTerminalMultipleItemState(state) {
12
+ const unwrapped = unwrapMultipleItemState(state).value;
13
+ return unwrapped != null && typeof unwrapped === "object" && Object.hasOwn(unwrapped, "success") && typeof unwrapped.success === "boolean";
14
+ }
15
+ function isUnstartedMultipleItemState(state, originalState) {
16
+ const unwrappedState = unwrapMultipleItemState(state);
17
+ if (unwrappedState.value == null) return true;
18
+ if (originalState === void 0) return false;
19
+ const unwrappedOriginalState = unwrapMultipleItemState(originalState);
20
+ return unwrappedState.value === unwrappedOriginalState.value && (unwrappedState.viaBoundCliWrapper || unwrappedOriginalState.viaBoundCliWrapper || unwrappedOriginalState.value != null && typeof unwrappedOriginalState.value === "object");
21
+ }
22
+ function isBoundCliWrapperState(state) {
23
+ return state != null && typeof state === "object" && Object.hasOwn(state, "hasCliValue") && typeof state.hasCliValue === "boolean" && (Object.hasOwn(state, "cliState") || state.hasCliValue === false);
24
+ }
25
+ function unwrapMultipleItemState(state) {
26
+ let unwrapped = state;
27
+ let viaBoundCliWrapper = false;
28
+ while (true) {
29
+ if (isInjectedAnnotationWrapper(unwrapped)) {
30
+ unwrapped = unwrapInjectedAnnotationWrapper(unwrapped);
31
+ continue;
32
+ }
33
+ if (Array.isArray(unwrapped) && unwrapped.length === 1) {
34
+ unwrapped = unwrapped[0];
35
+ continue;
36
+ }
37
+ if (isBoundCliWrapperState(unwrapped)) {
38
+ viaBoundCliWrapper = true;
39
+ unwrapped = unwrapped.cliState;
40
+ continue;
41
+ }
42
+ return {
43
+ value: unwrapped,
44
+ viaBoundCliWrapper
45
+ };
46
+ }
47
+ }
48
+ function isPromiseLike(value) {
49
+ return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
50
+ }
51
+ function normalizeOptionalLikeCompleteResult(result, shouldNormalize) {
52
+ return result.success && shouldNormalize ? {
53
+ ...result,
54
+ value: normalizeNestedDelegatedAnnotationState(result.value)
55
+ } : result;
56
+ }
57
+ function shouldRetryOptionalLikeCompatibilityError(error, state) {
58
+ return error instanceof TypeError && state != null && typeof state === "object" && isInjectedAnnotationWrapper(state);
59
+ }
60
+ function completeOptionalLikeSync(parser, state, exec) {
61
+ const hasCarrier = hasDelegatedAnnotationCarrier(state);
62
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(state);
63
+ const run = (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec), shouldNormalize);
64
+ try {
65
+ const result = run(state, hasCarrier);
66
+ if (!result.success && shouldRetryFalseResult) return run(normalizeDelegatedAnnotationState(state), false);
67
+ return result;
68
+ } catch (error) {
69
+ if (!shouldRetryOptionalLikeCompatibilityError(error, state)) throw error;
70
+ return run(normalizeDelegatedAnnotationState(state), false);
71
+ }
72
+ }
73
+ async function completeOptionalLikeAsync(parser, state, exec) {
74
+ const hasCarrier = hasDelegatedAnnotationCarrier(state);
75
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(state);
76
+ const run = async (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec), shouldNormalize);
77
+ try {
78
+ const result = await run(state, hasCarrier);
79
+ if (!result.success && shouldRetryFalseResult) return await run(normalizeDelegatedAnnotationState(state), false);
80
+ return result;
81
+ } catch (error) {
82
+ if (!shouldRetryOptionalLikeCompatibilityError(error, state)) throw error;
83
+ return await run(normalizeDelegatedAnnotationState(state), false);
84
+ }
85
+ }
86
+ function normalizeOptionalLikePhase2Seed(seed, shouldNormalize) {
87
+ return seed == null ? null : shouldNormalize ? {
88
+ ...seed,
89
+ value: normalizeNestedDelegatedAnnotationState(seed.value)
90
+ } : seed;
91
+ }
92
+ function extractOptionalLikePhase2Seed(parser, state, exec) {
93
+ if (!Array.isArray(state) && !(state != null && typeof state === "object")) return wrapForMode(parser.mode, null);
94
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
95
+ const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
96
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(innerState);
97
+ return dispatchByMode(parser.mode, () => {
98
+ try {
99
+ const result = parser.complete(innerState, exec);
100
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), hasCarrier);
101
+ if (shouldRetryFalseResult) {
102
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
103
+ const fallbackResult = parser.complete(fallbackState, exec);
104
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(fallbackResult), false);
105
+ }
106
+ const seed = extractPhase2Seed(parser, innerState, exec);
107
+ if (seed == null && hasCarrier) {
108
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
109
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
110
+ }
111
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
112
+ } catch (error) {
113
+ if (!shouldRetryOptionalLikeCompatibilityError(error, innerState)) throw error;
114
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
115
+ const result = parser.complete(fallbackState, exec);
116
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), false);
117
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
118
+ }
119
+ }, async () => {
120
+ try {
121
+ const result = await parser.complete(innerState, exec);
122
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), hasCarrier);
123
+ if (shouldRetryFalseResult) {
124
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
125
+ const fallbackResult = await parser.complete(fallbackState, exec);
126
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(fallbackResult), false);
127
+ }
128
+ const seed = await extractPhase2Seed(parser, innerState, exec);
129
+ if (seed == null && hasCarrier) {
130
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
131
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec), false);
132
+ }
133
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
134
+ } catch (error) {
135
+ if (!shouldRetryOptionalLikeCompatibilityError(error, innerState)) throw error;
136
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
137
+ const result = await parser.complete(fallbackState, exec);
138
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), false);
139
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec), false);
140
+ }
141
+ });
142
+ }
143
+ /**
144
+ * Computes the inner state to pass through to the wrapped parser inside
145
+ * {@link optional} / {@link withDefault}. When the outer state is an
146
+ * array, the inner state is `state[0]`. Otherwise, including the
147
+ * common case where `optional()` sits at top level and the outer state
148
+ * is either `undefined` or an annotation wrapper from `parseOptionalLike`
149
+ * / `parse({ annotations })`, we use the wrapped parser's
150
+ * `initialState`, propagating annotations from the outer state so that
151
+ * source-binding wrappers under `optional()` / `withDefault()` (e.g.,
152
+ * `bindEnv()` / `bindConfig()`) can resolve their fallbacks.
153
+ *
154
+ * @internal
155
+ */
156
+ function deriveOptionalInnerParseState(outerState, parser) {
157
+ if (Array.isArray(outerState)) {
158
+ const innerState = outerState[0];
159
+ if (getAnnotations(outerState) != null && innerState != null && typeof innerState === "object") return getDelegatedAnnotationState(outerState, innerState);
160
+ return innerState;
161
+ }
162
+ const initial = parser.initialState;
163
+ if (initial != null && typeof initial !== "object") return initial;
164
+ return initial != null && typeof initial === "object" ? getDelegatedAnnotationState(outerState, initial) : inheritAnnotations(outerState, initial);
165
+ }
8
166
  /**
9
167
  * Internal helper for optional-style parsing logic shared by optional()
10
168
  * and withDefault(). Handles the common pattern of:
11
169
  * - Unwrapping optional state to inner parser state
12
- * - Detecting if inner parser actually matched (state changed or no consumption)
13
- * - Returning success with undefined state when inner parser fails without consuming
170
+ * - Detecting if the inner parser actually matched (state changed or no consumption)
171
+ * - Returning success with undefined state when the inner parser fails without consuming
14
172
  * @internal
15
173
  */
16
174
  function parseOptionalStyleSync(context, parser) {
17
- const innerState = Array.isArray(context.state) ? context.state[0] : parser.initialState;
175
+ const innerState = deriveOptionalInnerParseState(context.state, parser);
18
176
  const result = parser.parse({
19
177
  ...context,
20
178
  state: innerState
@@ -26,7 +184,7 @@ function parseOptionalStyleSync(context, parser) {
26
184
  * @internal
27
185
  */
28
186
  async function parseOptionalStyleAsync(context, parser) {
29
- const innerState = Array.isArray(context.state) ? context.state[0] : parser.initialState;
187
+ const innerState = deriveOptionalInnerParseState(context.state, parser);
30
188
  const result = await parser.parse({
31
189
  ...context,
32
190
  state: innerState
@@ -37,10 +195,14 @@ async function parseOptionalStyleAsync(context, parser) {
37
195
  * Internal helper to process optional-style parse results.
38
196
  * @internal
39
197
  */
198
+ function hasOptionalLikeParseStateChanged(previousState, nextState) {
199
+ return previousState !== nextState && normalizeDelegatedAnnotationState(previousState) !== normalizeDelegatedAnnotationState(nextState);
200
+ }
40
201
  function processOptionalStyleResult(result, innerState, context) {
41
202
  if (result.success) {
42
- if (result.next.state !== innerState || result.consumed.length === 0) return {
203
+ if (hasOptionalLikeParseStateChanged(innerState, result.next.state) || result.consumed.length === 0) return {
43
204
  success: true,
205
+ ...result.provisional ? { provisional: true } : {},
44
206
  next: {
45
207
  ...result.next,
46
208
  state: [result.next.state]
@@ -49,6 +211,7 @@ function processOptionalStyleResult(result, innerState, context) {
49
211
  };
50
212
  return {
51
213
  success: true,
214
+ ...result.provisional ? { provisional: true } : {},
52
215
  next: {
53
216
  ...result.next,
54
217
  state: context.state
@@ -64,6 +227,57 @@ function processOptionalStyleResult(result, innerState, context) {
64
227
  return result;
65
228
  }
66
229
  /**
230
+ * Creates a `shouldDeferCompletion` adapter that unwraps the outer state
231
+ * shape (`[TState] | undefined`) used by {@link optional} and
232
+ * {@link withDefault} before delegating to the inner parser's hook.
233
+ *
234
+ * When state is an array, the adapter unwraps `state[0]` and propagates
235
+ * annotations from the outer array. Non-array objects (e.g. PromptBindState
236
+ * from `prompt()`) are passed through directly. `undefined` returns `false`
237
+ * without calling the inner hook.
238
+ *
239
+ * @internal
240
+ */
241
+ function adaptShouldDeferCompletion(innerCheck, parser) {
242
+ return (state, exec) => {
243
+ if (Array.isArray(state) || state != null && typeof state === "object") {
244
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
245
+ const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
246
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(innerState);
247
+ try {
248
+ const result = innerCheck(innerState, exec);
249
+ if (!result && shouldRetryFalseResult) return innerCheck(normalizeDelegatedAnnotationState(innerState), exec);
250
+ return result;
251
+ } catch (error) {
252
+ if (!shouldRetryOptionalLikeCompatibilityError(error, innerState)) throw error;
253
+ return innerCheck(normalizeDelegatedAnnotationState(innerState), exec);
254
+ }
255
+ }
256
+ return false;
257
+ };
258
+ }
259
+ function isAnnotationOnlyObjectState(state) {
260
+ if (state == null || typeof state !== "object" || Array.isArray(state) || isInjectedAnnotationWrapper(state)) return false;
261
+ const keys = Reflect.ownKeys(state);
262
+ return getAnnotations(state) != null && keys.length === 1 && keys[0] === annotationKey;
263
+ }
264
+ function normalizeOptionalLikeInnerState(state, initialState, parser) {
265
+ if (Array.isArray(state)) return getDelegatedAnnotationState(state, state[0]);
266
+ if (isAnnotationOnlyObjectState(state)) {
267
+ if (parser != null && (parser.dependencyMetadata?.source != null || typeof parser.shouldDeferCompletion === "function")) return getDelegatedAnnotationState(state, initialState);
268
+ return initialState;
269
+ }
270
+ if (state != null && typeof state === "object") return state;
271
+ return initialState;
272
+ }
273
+ function normalizeOptionalLikeSuggestState(state, initialState, parser) {
274
+ if (Array.isArray(state)) {
275
+ const innerState = state[0];
276
+ return innerState != null && typeof innerState === "object" ? getDelegatedAnnotationState(state, innerState) : innerState;
277
+ }
278
+ return normalizeOptionalLikeInnerState(state, initialState, parser);
279
+ }
280
+ /**
67
281
  * Creates a parser that makes another parser optional, allowing it to succeed
68
282
  * without consuming input if the wrapped parser fails to match.
69
283
  * If the wrapped parser succeeds, this returns its value.
@@ -78,72 +292,86 @@ function processOptionalStyleResult(result, innerState, context) {
78
292
  function optional(parser) {
79
293
  const syncParser = parser;
80
294
  function* suggestSync(context, prefix) {
81
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
295
+ const innerState = normalizeOptionalLikeSuggestState(context.state, syncParser.initialState, parser);
82
296
  yield* syncParser.suggest({
83
297
  ...context,
84
298
  state: innerState
85
299
  }, prefix);
86
300
  }
87
301
  async function* suggestAsync(context, prefix) {
88
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
302
+ const innerState = normalizeOptionalLikeSuggestState(context.state, syncParser.initialState, parser);
89
303
  const suggestions = parser.suggest({
90
304
  ...context,
91
305
  state: innerState
92
306
  }, prefix);
93
307
  for await (const s of suggestions) yield s;
94
308
  }
95
- const innerHasWrappedDependency = isWrappedDependencySource(parser);
96
- const innerHasDirectDependency = isPendingDependencySourceState(syncParser.initialState);
97
- const wrappedDependencyMarker = innerHasWrappedDependency ? { [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker] } : innerHasDirectDependency ? { [wrappedDependencySourceMarker]: syncParser.initialState } : {};
98
- const hasWrappedDependencySource = wrappedDependencySourceMarker in wrappedDependencyMarker;
99
- const wrappedPendingState = hasWrappedDependencySource ? wrappedDependencyMarker[wrappedDependencySourceMarker] : void 0;
100
- const deferPromptHook = Reflect.get(parser, deferPromptUntilConfigResolvesKey);
101
- const deferPromptMarker = typeof deferPromptHook === "function" ? { [deferPromptUntilConfigResolvesKey]: deferPromptHook } : {};
102
- return {
103
- $mode: parser.$mode,
309
+ const optionalParser = {
310
+ mode: parser.mode,
104
311
  $valueType: [],
105
312
  $stateType: [],
313
+ ...parser[unmatchedNonCliDependencySourceStateMarker] === true ? { [unmatchedNonCliDependencySourceStateMarker]: true } : {},
314
+ placeholder: void 0,
106
315
  priority: parser.priority,
107
316
  usage: [{
108
317
  type: "optional",
109
318
  terms: parser.usage
110
319
  }],
320
+ leadingNames: parser.leadingNames,
321
+ acceptingAnyToken: false,
111
322
  initialState: void 0,
112
- ...wrappedDependencyMarker,
113
- ...deferPromptMarker,
323
+ ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
324
+ getSuggestRuntimeNodes(state, path) {
325
+ if (optionalParser.dependencyMetadata?.source != null) return [{
326
+ path,
327
+ parser: optionalParser,
328
+ state
329
+ }];
330
+ const innerState = normalizeOptionalLikeSuggestState(state, parser.initialState, parser);
331
+ return parser.getSuggestRuntimeNodes?.(innerState, path) ?? (parser.dependencyMetadata?.source != null ? [{
332
+ path,
333
+ parser,
334
+ state: innerState
335
+ }] : []);
336
+ },
337
+ [extractPhase2SeedKey](state, exec) {
338
+ return extractOptionalLikePhase2Seed(parser, state, exec);
339
+ },
114
340
  parse(context) {
115
- return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
341
+ return dispatchByMode(parser.mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
116
342
  },
117
- complete(state) {
343
+ complete(state, exec) {
118
344
  if (!Array.isArray(state)) {
119
- if (innerHasWrappedDependency && wrappedPendingState) return dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState]), () => parser.complete([wrappedPendingState]));
120
- if (typeof deferPromptHook === "function" && state != null && typeof state === "object") {
121
- const innerComplete = () => {
122
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
123
- return mapModeValue(parser.$mode, innerResult, (result) => result.success ? result : {
124
- success: true,
125
- value: void 0
126
- });
127
- };
128
- return innerComplete();
129
- }
130
- return {
131
- success: true,
132
- value: void 0
345
+ const delegateToInner = (resolvedInnerState) => {
346
+ const innerResult = dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, resolvedInnerState, exec), async () => await completeOptionalLikeAsync(parser, resolvedInnerState, exec));
347
+ return mapModeValue(parser.mode, innerResult, (result) => result.success ? result : {
348
+ success: true,
349
+ value: void 0
350
+ });
133
351
  };
134
- }
135
- if (Array.isArray(state) && state.length === 1 && isPendingDependencySourceState(state[0])) {
136
- if (innerHasWrappedDependency) return dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
352
+ if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
353
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
354
+ return delegateToInner(innerState);
355
+ }
356
+ const sourceMetadata = parser.dependencyMetadata?.source;
357
+ if (sourceMetadata?.preservesSourceValue !== false && sourceMetadata?.getMissingSourceValue != null) {
358
+ const delegatedState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
359
+ return dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, delegatedState, exec), async () => await completeOptionalLikeAsync(parser, delegatedState, exec));
360
+ }
361
+ if (parser[unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
362
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
363
+ return delegateToInner(innerState);
364
+ }
137
365
  return {
138
366
  success: true,
139
367
  value: void 0
140
368
  };
141
369
  }
142
- const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
143
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
370
+ const innerElement = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
371
+ return dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerElement, exec), async () => await completeOptionalLikeAsync(parser, innerElement, exec));
144
372
  },
145
373
  suggest(context, prefix) {
146
- return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
374
+ return dispatchIterableByMode(parser.mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
147
375
  },
148
376
  getDocFragments(state, defaultValue) {
149
377
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
@@ -153,6 +381,38 @@ function optional(parser) {
153
381
  return syncParser.getDocFragments(innerState, defaultValue);
154
382
  }
155
383
  };
384
+ if (typeof parser.normalizeValue === "function") {
385
+ const innerNormalize = parser.normalizeValue.bind(parser);
386
+ Object.defineProperty(optionalParser, "normalizeValue", {
387
+ value(v) {
388
+ if (v == null) return v;
389
+ return innerNormalize(v);
390
+ },
391
+ configurable: true,
392
+ enumerable: false
393
+ });
394
+ }
395
+ if (typeof parser.validateValue === "function") {
396
+ const innerValidate = parser.validateValue.bind(parser);
397
+ Object.defineProperty(optionalParser, "validateValue", {
398
+ value(v) {
399
+ if (v === void 0) return wrapForMode(parser.mode, {
400
+ success: true,
401
+ value: v
402
+ });
403
+ return innerValidate(v);
404
+ },
405
+ configurable: true,
406
+ enumerable: false
407
+ });
408
+ }
409
+ if (parser.dependencyMetadata != null) {
410
+ const composed = composeDependencyMetadata(parser.dependencyMetadata, "optional");
411
+ if (composed != null) optionalParser.dependencyMetadata = composed;
412
+ }
413
+ defineInheritedAnnotationParser(optionalParser);
414
+ defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
415
+ return optionalParser;
156
416
  }
157
417
  /**
158
418
  * Error type for structured error messages in {@link withDefault} default value callbacks.
@@ -201,122 +461,76 @@ function withDefault(parser, defaultValue, options) {
201
461
  }
202
462
  };
203
463
  function* suggestSync(context, prefix) {
204
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
464
+ const innerState = normalizeOptionalLikeSuggestState(context.state, syncParser.initialState, parser);
205
465
  yield* syncParser.suggest({
206
466
  ...context,
207
467
  state: innerState
208
468
  }, prefix);
209
469
  }
210
470
  async function* suggestAsync(context, prefix) {
211
- const innerState = Array.isArray(context.state) ? context.state[0] : syncParser.initialState;
471
+ const innerState = normalizeOptionalLikeSuggestState(context.state, syncParser.initialState, parser);
212
472
  const suggestions = parser.suggest({
213
473
  ...context,
214
474
  state: innerState
215
475
  }, prefix);
216
476
  for await (const s of suggestions) yield s;
217
477
  }
218
- const innerInitialState = syncParser.initialState;
219
- const wrappedDependencyMarker = isPendingDependencySourceState(innerInitialState) ? { [wrappedDependencySourceMarker]: innerInitialState } : isWrappedDependencySource(parser) ? { [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker] } : {};
220
- const deferPromptHookDefault = Reflect.get(parser, deferPromptUntilConfigResolvesKey);
221
- const deferPromptMarkerDefault = typeof deferPromptHookDefault === "function" ? { [deferPromptUntilConfigResolvesKey]: deferPromptHookDefault } : {};
222
- return {
223
- $mode: parser.$mode,
478
+ const withDefaultParser = {
479
+ mode: parser.mode,
224
480
  $valueType: [],
225
481
  $stateType: [],
482
+ ...parser[unmatchedNonCliDependencySourceStateMarker] === true ? { [unmatchedNonCliDependencySourceStateMarker]: true } : {},
226
483
  priority: parser.priority,
227
484
  usage: [{
228
485
  type: "optional",
229
486
  terms: parser.usage
230
487
  }],
488
+ leadingNames: parser.leadingNames,
489
+ acceptingAnyToken: false,
231
490
  initialState: void 0,
232
- ...wrappedDependencyMarker,
233
- ...deferPromptMarkerDefault,
491
+ ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
492
+ getSuggestRuntimeNodes(state, path) {
493
+ if (withDefaultParser.dependencyMetadata?.source != null) return [{
494
+ path,
495
+ parser: withDefaultParser,
496
+ state
497
+ }];
498
+ const innerState = normalizeOptionalLikeSuggestState(state, parser.initialState, parser);
499
+ return parser.getSuggestRuntimeNodes?.(innerState, path) ?? (parser.dependencyMetadata?.source != null ? [{
500
+ path,
501
+ parser,
502
+ state: innerState
503
+ }] : []);
504
+ },
505
+ [extractPhase2SeedKey](state, exec) {
506
+ return extractOptionalLikePhase2Seed(parser, state, exec);
507
+ },
234
508
  parse(context) {
235
- return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
509
+ return dispatchByMode(parser.mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
236
510
  },
237
- complete(state) {
511
+ complete(state, exec) {
512
+ function evaluateDefault() {
513
+ const raw = typeof defaultValue === "function" ? defaultValue() : defaultValue;
514
+ if (typeof parser.normalizeValue === "function") try {
515
+ return parser.normalizeValue(raw);
516
+ } catch {}
517
+ return raw;
518
+ }
238
519
  if (!Array.isArray(state)) {
239
- if (transformsDependencyValue(parser)) {
240
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(void 0), () => parser.complete(void 0));
241
- const handleInnerResult = (res) => {
242
- if (isDependencySourceState(res)) try {
243
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
244
- return createDependencySourceState({
245
- success: true,
246
- value
247
- }, res[dependencyId]);
248
- } catch (error) {
249
- return {
250
- success: false,
251
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
252
- };
253
- }
254
- try {
255
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
256
- return {
257
- success: true,
258
- value
259
- };
260
- } catch (error) {
261
- return {
262
- success: false,
263
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
264
- };
265
- }
266
- };
267
- return mapModeValue(parser.$mode, innerResult, handleInnerResult);
268
- }
269
- if (isWrappedDependencySource(parser)) try {
270
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
271
- const pendingState = parser[wrappedDependencySourceMarker];
272
- return createDependencySourceState({
273
- success: true,
274
- value
275
- }, pendingState[dependencyId]);
276
- } catch (error) {
277
- return {
278
- success: false,
279
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
280
- };
281
- }
282
- if (typeof deferPromptHookDefault === "function" && state != null && typeof state === "object") {
283
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
520
+ if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
521
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
522
+ const innerResult = dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerState, exec), async () => await completeOptionalLikeAsync(parser, innerState, exec));
284
523
  return innerResult;
285
524
  }
286
- try {
287
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
288
- return {
289
- success: true,
290
- value
291
- };
292
- } catch (error) {
293
- return {
294
- success: false,
295
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
296
- };
297
- }
298
- }
299
- if (isPendingDependencySourceState(state[0])) {
300
- if (transformsDependencyValue(parser)) {
301
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
302
- const handleInnerResult = (res) => {
303
- if (isDependencySourceState(res)) try {
304
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
305
- return createDependencySourceState({
306
- success: true,
307
- value
308
- }, res[dependencyId]);
309
- } catch (error) {
310
- return {
311
- success: false,
312
- error: error instanceof WithDefaultError ? error.errorMessage : message`${text(String(error))}`
313
- };
314
- }
525
+ if (parser[unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
526
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
527
+ const innerResult = dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerState, exec), async () => await completeOptionalLikeAsync(parser, innerState, exec));
528
+ const handleInnerResult = (result) => {
529
+ if (result.success && result.value !== void 0) return result;
315
530
  try {
316
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
317
531
  return {
318
532
  success: true,
319
- value
533
+ value: evaluateDefault()
320
534
  };
321
535
  } catch (error) {
322
536
  return {
@@ -325,14 +539,14 @@ function withDefault(parser, defaultValue, options) {
325
539
  };
326
540
  }
327
541
  };
328
- return mapModeValue(parser.$mode, innerResult, handleInnerResult);
542
+ return mapModeValue(parser.mode, innerResult, handleInnerResult);
329
543
  }
330
544
  try {
331
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
332
- return createDependencySourceState({
545
+ const value = evaluateDefault();
546
+ return {
333
547
  success: true,
334
548
  value
335
- }, state[0][dependencyId]);
549
+ };
336
550
  } catch (error) {
337
551
  return {
338
552
  success: false,
@@ -340,18 +554,22 @@ function withDefault(parser, defaultValue, options) {
340
554
  };
341
555
  }
342
556
  }
343
- const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
344
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
557
+ const innerElement = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
558
+ return dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerElement, exec), async () => await completeOptionalLikeAsync(parser, innerElement, exec));
345
559
  },
346
560
  suggest(context, prefix) {
347
- return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
561
+ return dispatchIterableByMode(parser.mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
348
562
  },
349
563
  getDocFragments(state, upperDefaultValue) {
350
564
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : state.state === void 0 ? { kind: "unavailable" } : {
351
565
  kind: "available",
352
566
  state: state.state[0]
353
567
  };
354
- const fragments = syncParser.getDocFragments(innerState, getDocDefaultValue(upperDefaultValue));
568
+ let docDefault = getDocDefaultValue(upperDefaultValue);
569
+ if (docDefault != null && typeof parser.normalizeValue === "function") try {
570
+ docDefault = parser.normalizeValue(docDefault);
571
+ } catch {}
572
+ const fragments = syncParser.getDocFragments(innerState, docDefault);
355
573
  if (options?.message) {
356
574
  const modifiedFragments = fragments.fragments.map((fragment) => {
357
575
  if (fragment.type === "entry") return {
@@ -368,6 +586,62 @@ function withDefault(parser, defaultValue, options) {
368
586
  return fragments;
369
587
  }
370
588
  };
589
+ if ("placeholder" in parser) Object.defineProperty(withDefaultParser, "placeholder", {
590
+ get() {
591
+ return parser.placeholder;
592
+ },
593
+ configurable: true,
594
+ enumerable: false
595
+ });
596
+ if (typeof parser.normalizeValue === "function") {
597
+ const innerNormalize = parser.normalizeValue.bind(parser);
598
+ Object.defineProperty(withDefaultParser, "normalizeValue", {
599
+ value(v) {
600
+ try {
601
+ return innerNormalize(v);
602
+ } catch {
603
+ return v;
604
+ }
605
+ },
606
+ configurable: true,
607
+ enumerable: false
608
+ });
609
+ }
610
+ if (typeof parser.validateValue === "function") {
611
+ const innerValidate = parser.validateValue.bind(parser);
612
+ Object.defineProperty(withDefaultParser, "validateValue", {
613
+ value(v) {
614
+ return innerValidate(v);
615
+ },
616
+ configurable: true,
617
+ enumerable: false
618
+ });
619
+ }
620
+ if (parser.dependencyMetadata != null) {
621
+ const composed = composeDependencyMetadata(parser.dependencyMetadata, "withDefault", { defaultValue: () => {
622
+ let v;
623
+ try {
624
+ v = typeof defaultValue === "function" ? defaultValue() : defaultValue;
625
+ } catch (e) {
626
+ const error = e instanceof WithDefaultError ? e.errorMessage : message`${e instanceof Error ? e.message : String(e)}`;
627
+ return {
628
+ success: false,
629
+ error
630
+ };
631
+ }
632
+ if (typeof parser.normalizeValue === "function") try {
633
+ v = parser.normalizeValue(v);
634
+ } catch {}
635
+ return {
636
+ success: true,
637
+ value: v
638
+ };
639
+ } });
640
+ if (composed != null) withDefaultParser.dependencyMetadata = composed;
641
+ }
642
+ defineInheritedAnnotationParser(withDefaultParser);
643
+ defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
644
+ return withDefaultParser;
371
645
  }
372
646
  /**
373
647
  * Creates a parser that transforms the result value of another parser using
@@ -388,6 +662,47 @@ function withDefault(parser, defaultValue, options) {
388
662
  * @param transform A function that transforms the parsed value from type T to type U.
389
663
  * @returns A {@link Parser} that produces the transformed value of type U
390
664
  * while preserving the original parser's state type and parsing behavior.
665
+ * @throws Any exception thrown by `transform` when completing a non-deferred
666
+ * value. Errors from deferred placeholder transforms are caught and the
667
+ * mapped result falls back to `undefined` with `deferred: true`.
668
+ *
669
+ * ### Deferred prompt interaction
670
+ *
671
+ * During two-phase parsing, `map()` propagates the `deferred` flag from
672
+ * inner results but intentionally drops per-field `deferredKeys`. The
673
+ * inner key set describes the *input* shape, but `transform` produces an
674
+ * arbitrary *output* shape where keys may be renamed, dropped, or reused
675
+ * with different semantics. For `object()` results that are *not*
676
+ * wrapped in `map()`, per-field deferred stripping works normally.
677
+ *
678
+ * Because the `deferred` flag is propagated conservatively, mapped scalar
679
+ * results are treated as missing (`undefined`) during phase-two context
680
+ * collection — even when `transform` only used non-deferred fields.
681
+ * For example, `map(object({ apiKey: prompt(...), mode: option(...) }),
682
+ * v => v.mode)` makes phase-two contexts see `undefined` instead of the
683
+ * real `mode` value. This is the intentional trade-off: the alternative
684
+ * (not propagating `deferred`) would leak placeholder values into context
685
+ * resolution when `transform` *does* use deferred fields. The final
686
+ * parse always produces the correct result regardless.
687
+ *
688
+ * If the transform throws on a deferred placeholder value, the mapped
689
+ * result falls back to `undefined` with `deferred: true`, so the first
690
+ * pass does not abort.
691
+ *
692
+ * ### Transform purity
693
+ *
694
+ * The `transform` function must not mutate its input. Object and array
695
+ * values may be shared placeholder references during deferred prompt
696
+ * resolution, and in-place mutations would corrupt the placeholder for
697
+ * subsequent parses. Always return a new value:
698
+ *
699
+ * ```typescript
700
+ * // ✅ Correct — creates a new object
701
+ * map(parser, v => ({ ...v, host: "override" }))
702
+ *
703
+ * // ❌ Wrong — mutates the input in place
704
+ * map(parser, v => { v.host = "override"; return v; })
705
+ * ```
391
706
  *
392
707
  * @example
393
708
  * ```typescript
@@ -404,25 +719,116 @@ function withDefault(parser, defaultValue, options) {
404
719
  * ```
405
720
  */
406
721
  function map(parser, transform) {
407
- const complete = (state) => {
408
- return mapModeValue(parser.$mode, parser.complete(state), (result) => result.success ? {
409
- success: true,
410
- value: transform(result.value)
411
- } : result);
722
+ const complete = (state, exec) => {
723
+ return mapModeValue(parser.mode, parser.complete(state, exec), (result) => {
724
+ if (!result.success) return result;
725
+ if (result.deferred) try {
726
+ return {
727
+ success: true,
728
+ value: transform(result.value),
729
+ deferred: true
730
+ };
731
+ } catch {
732
+ return {
733
+ success: true,
734
+ value: void 0,
735
+ deferred: true
736
+ };
737
+ }
738
+ return {
739
+ success: true,
740
+ value: transform(result.value)
741
+ };
742
+ });
412
743
  };
413
- const dependencyMarkers = isWrappedDependencySource(parser) ? {
414
- [wrappedDependencySourceMarker]: parser[wrappedDependencySourceMarker],
415
- [transformsDependencyValueMarker]: true
416
- } : {};
417
- return {
744
+ const mappedParser = {
418
745
  ...parser,
419
746
  $valueType: [],
420
747
  complete,
421
- ...dependencyMarkers,
748
+ [extractPhase2SeedKey](state, exec) {
749
+ return mapModeValue(parser.mode, completeOrExtractPhase2Seed(parser, state, exec), (seed) => {
750
+ if (seed == null) return null;
751
+ if (seed.deferred) try {
752
+ return {
753
+ value: transform(seed.value),
754
+ deferred: true
755
+ };
756
+ } catch {
757
+ return {
758
+ value: void 0,
759
+ deferred: true
760
+ };
761
+ }
762
+ return { value: transform(seed.value) };
763
+ });
764
+ },
765
+ getSuggestRuntimeNodes(state, path) {
766
+ if (mappedParser.dependencyMetadata?.source != null) return [{
767
+ path,
768
+ parser: mappedParser,
769
+ state
770
+ }];
771
+ return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
772
+ path,
773
+ parser,
774
+ state
775
+ }] : []);
776
+ },
422
777
  getDocFragments(state, _defaultValue) {
423
778
  return parser.getDocFragments(state, void 0);
424
779
  }
425
780
  };
781
+ delete mappedParser.normalizeValue;
782
+ delete mappedParser.validateValue;
783
+ if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
784
+ get() {
785
+ try {
786
+ return transform(parser.placeholder);
787
+ } catch {
788
+ return void 0;
789
+ }
790
+ },
791
+ configurable: true,
792
+ enumerable: false
793
+ });
794
+ if (parser.dependencyMetadata != null) {
795
+ let composed = composeDependencyMetadata(parser.dependencyMetadata, "map");
796
+ if (composed?.derived != null) {
797
+ const innerReplay = composed.derived.replayParse;
798
+ const applyMappedReplay = (r) => {
799
+ if (!r.success) return r;
800
+ if (r.deferred) try {
801
+ return {
802
+ success: true,
803
+ value: transform(r.value),
804
+ deferred: true
805
+ };
806
+ } catch {
807
+ return {
808
+ success: true,
809
+ value: void 0,
810
+ deferred: true
811
+ };
812
+ }
813
+ return {
814
+ success: true,
815
+ value: transform(r.value)
816
+ };
817
+ };
818
+ composed = {
819
+ ...composed,
820
+ derived: {
821
+ ...composed.derived,
822
+ replayParse: (rawInput, depValues) => {
823
+ const result = innerReplay(rawInput, depValues);
824
+ return isPromiseLike(result) ? result.then(applyMappedReplay) : applyMappedReplay(result);
825
+ }
826
+ }
827
+ };
828
+ }
829
+ if (composed != null) mappedParser.dependencyMetadata = composed;
830
+ }
831
+ return mappedParser;
426
832
  }
427
833
  /**
428
834
  * Creates a parser that allows multiple occurrences of a given parser.
@@ -443,12 +849,14 @@ function multiple(parser, options = {}) {
443
849
  const syncParser = parser;
444
850
  const { min = 0, max = Infinity } = options;
445
851
  const unwrapInjectedWrapper = unwrapInjectedAnnotationWrapper;
446
- const completeSyncWithUnwrappedFallback = (state) => {
852
+ const completeSyncWithUnwrappedFallback = (state, exec) => {
447
853
  try {
448
- return syncParser.complete(state);
854
+ const result = syncParser.complete(state, exec);
855
+ if (!result.success && isInjectedAnnotationWrapper(state)) return syncParser.complete(unwrapInjectedWrapper(state), exec);
856
+ return result;
449
857
  } catch (error) {
450
858
  if (!isInjectedAnnotationWrapper(state)) throw error;
451
- return syncParser.complete(unwrapInjectedWrapper(state));
859
+ return syncParser.complete(unwrapInjectedWrapper(state), exec);
452
860
  }
453
861
  };
454
862
  const parseSyncWithUnwrappedFallback = (context) => {
@@ -467,12 +875,14 @@ function multiple(parser, options = {}) {
467
875
  });
468
876
  }
469
877
  };
470
- const completeAsyncWithUnwrappedFallback = async (state) => {
878
+ const completeAsyncWithUnwrappedFallback = async (state, exec) => {
471
879
  try {
472
- return await parser.complete(state);
880
+ const result = await parser.complete(state, exec);
881
+ if (!result.success && isInjectedAnnotationWrapper(state)) return await parser.complete(unwrapInjectedWrapper(state), exec);
882
+ return result;
473
883
  } catch (error) {
474
884
  if (!isInjectedAnnotationWrapper(state)) throw error;
475
- return await parser.complete(unwrapInjectedWrapper(state));
885
+ return await parser.complete(unwrapInjectedWrapper(state), exec);
476
886
  }
477
887
  };
478
888
  const parseAsyncWithUnwrappedFallback = async (context) => {
@@ -491,62 +901,193 @@ function multiple(parser, options = {}) {
491
901
  });
492
902
  }
493
903
  };
904
+ const extractPhase2SeedSyncWithUnwrappedFallback = (state, exec) => {
905
+ try {
906
+ const seed = completeOrExtractPhase2Seed(syncParser, state, exec);
907
+ if (seed == null && isInjectedAnnotationWrapper(state)) return completeOrExtractPhase2Seed(syncParser, unwrapInjectedWrapper(state), exec);
908
+ return seed;
909
+ } catch (error) {
910
+ if (!isInjectedAnnotationWrapper(state)) throw error;
911
+ return completeOrExtractPhase2Seed(syncParser, unwrapInjectedWrapper(state), exec);
912
+ }
913
+ };
914
+ const extractPhase2SeedAsyncWithUnwrappedFallback = async (state, exec) => {
915
+ try {
916
+ const seed = await completeOrExtractPhase2Seed(parser, state, exec);
917
+ if (seed == null && isInjectedAnnotationWrapper(state)) return await completeOrExtractPhase2Seed(parser, unwrapInjectedWrapper(state), exec);
918
+ return seed;
919
+ } catch (error) {
920
+ if (!isInjectedAnnotationWrapper(state)) throw error;
921
+ return await completeOrExtractPhase2Seed(parser, unwrapInjectedWrapper(state), exec);
922
+ }
923
+ };
924
+ const getInnerSuggestRuntimeNodes = (state, path) => parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
925
+ path,
926
+ parser,
927
+ state
928
+ }] : []);
494
929
  const parseSync = (context) => {
495
- let added = context.state.length < 1;
496
- const currentItemStateWithAnnotations = context.state.at(-1) ?? inheritAnnotations(context.state, syncParser.initialState);
497
- let result = parseSyncWithUnwrappedFallback({
498
- ...context,
499
- state: currentItemStateWithAnnotations
500
- });
501
- if (!result.success) if (!added) {
502
- const nextInitialState = inheritAnnotations(context.state, syncParser.initialState);
503
- result = parseSyncWithUnwrappedFallback({
504
- ...context,
505
- state: nextInitialState
506
- });
507
- if (!result.success) return result;
508
- added = true;
509
- } else return result;
930
+ const currentItemState = context.state.at(-1);
931
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
932
+ const canOpenFreshItem = context.state.length < max;
933
+ if (!canExtendCurrent && !canOpenFreshItem) return {
934
+ success: true,
935
+ next: context,
936
+ consumed: []
937
+ };
938
+ let added = !canExtendCurrent;
939
+ let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
940
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, syncParser.initialState);
941
+ let result = parseSyncWithUnwrappedFallback(withChildContext(context, itemIndex, currentItemStateWithAnnotations));
942
+ if (!result.success) {
943
+ if (result.consumed !== 0) return result;
944
+ if (!added && canOpenFreshItem) {
945
+ const nextInitialState = inheritAnnotations(context.state, syncParser.initialState);
946
+ itemIndex = context.state.length;
947
+ result = parseSyncWithUnwrappedFallback(withChildContext(context, itemIndex, nextInitialState));
948
+ if (!result.success) {
949
+ if (min === 0 && context.buffer.length === 0 && result.consumed === 0) return {
950
+ success: true,
951
+ next: context,
952
+ consumed: []
953
+ };
954
+ return result;
955
+ }
956
+ added = true;
957
+ } else if (min === 0 && context.buffer.length === 0) return {
958
+ success: true,
959
+ next: context,
960
+ consumed: []
961
+ };
962
+ else return result;
963
+ }
964
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
965
+ if (added && result.consumed.length === 0 && result.next.optionsTerminated === context.optionsTerminated && isUnstartedMultipleItemState(result.next.state, currentItemStateWithAnnotations)) return {
966
+ success: true,
967
+ next: {
968
+ ...result.next,
969
+ state: context.state,
970
+ ...mergedExec != null ? {
971
+ trace: mergedExec.trace,
972
+ exec: mergedExec,
973
+ dependencyRegistry: mergedExec.dependencyRegistry
974
+ } : {}
975
+ },
976
+ consumed: result.consumed
977
+ };
510
978
  const itemAnnotationSource = added ? context.state : currentItemStateWithAnnotations;
979
+ if (result.next.state === currentItemStateWithAnnotations && result.consumed.length > 0 && (!added || result.next.optionsTerminated !== context.optionsTerminated)) return {
980
+ success: true,
981
+ ...result.provisional ? { provisional: true } : {},
982
+ next: {
983
+ ...result.next,
984
+ state: context.state,
985
+ ...mergedExec != null ? {
986
+ trace: mergedExec.trace,
987
+ exec: mergedExec,
988
+ dependencyRegistry: mergedExec.dependencyRegistry
989
+ } : {}
990
+ },
991
+ consumed: result.consumed
992
+ };
511
993
  const nextItemState = inheritAnnotations(itemAnnotationSource, result.next.state);
512
994
  return {
513
995
  success: true,
996
+ ...result.provisional ? { provisional: true } : {},
514
997
  next: {
515
998
  ...result.next,
516
- state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState])
999
+ state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1000
+ ...mergedExec != null ? {
1001
+ trace: mergedExec.trace,
1002
+ exec: mergedExec,
1003
+ dependencyRegistry: mergedExec.dependencyRegistry
1004
+ } : {}
517
1005
  },
518
1006
  consumed: result.consumed
519
1007
  };
520
1008
  };
521
1009
  const parseAsync = async (context) => {
522
- let added = context.state.length < 1;
523
- const currentItemStateWithAnnotations = context.state.at(-1) ?? inheritAnnotations(context.state, parser.initialState);
524
- let result = await parseAsyncWithUnwrappedFallback({
525
- ...context,
526
- state: currentItemStateWithAnnotations
527
- });
528
- if (!result.success) if (!added) {
529
- const nextInitialState = inheritAnnotations(context.state, parser.initialState);
530
- result = await parseAsyncWithUnwrappedFallback({
531
- ...context,
532
- state: nextInitialState
533
- });
534
- if (!result.success) return result;
535
- added = true;
536
- } else return result;
1010
+ const currentItemState = context.state.at(-1);
1011
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1012
+ const canOpenFreshItem = context.state.length < max;
1013
+ if (!canExtendCurrent && !canOpenFreshItem) return {
1014
+ success: true,
1015
+ next: context,
1016
+ consumed: []
1017
+ };
1018
+ let added = !canExtendCurrent;
1019
+ let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
1020
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, parser.initialState);
1021
+ let result = await parseAsyncWithUnwrappedFallback(withChildContext(context, itemIndex, currentItemStateWithAnnotations));
1022
+ if (!result.success) {
1023
+ if (result.consumed !== 0) return result;
1024
+ if (!added && canOpenFreshItem) {
1025
+ const nextInitialState = inheritAnnotations(context.state, parser.initialState);
1026
+ itemIndex = context.state.length;
1027
+ result = await parseAsyncWithUnwrappedFallback(withChildContext(context, itemIndex, nextInitialState));
1028
+ if (!result.success) {
1029
+ if (min === 0 && context.buffer.length === 0 && result.consumed === 0) return {
1030
+ success: true,
1031
+ next: context,
1032
+ consumed: []
1033
+ };
1034
+ return result;
1035
+ }
1036
+ added = true;
1037
+ } else if (min === 0 && context.buffer.length === 0) return {
1038
+ success: true,
1039
+ next: context,
1040
+ consumed: []
1041
+ };
1042
+ else return result;
1043
+ }
1044
+ const mergedExec = mergeChildExec(context.exec, result.next.exec);
1045
+ if (added && result.consumed.length === 0 && result.next.optionsTerminated === context.optionsTerminated && isUnstartedMultipleItemState(result.next.state, currentItemStateWithAnnotations)) return {
1046
+ success: true,
1047
+ next: {
1048
+ ...result.next,
1049
+ state: context.state,
1050
+ ...mergedExec != null ? {
1051
+ trace: mergedExec.trace,
1052
+ exec: mergedExec,
1053
+ dependencyRegistry: mergedExec.dependencyRegistry
1054
+ } : {}
1055
+ },
1056
+ consumed: result.consumed
1057
+ };
537
1058
  const itemAnnotationSource = added ? context.state : currentItemStateWithAnnotations;
1059
+ if (result.next.state === currentItemStateWithAnnotations && result.consumed.length > 0 && (!added || result.next.optionsTerminated !== context.optionsTerminated)) return {
1060
+ success: true,
1061
+ ...result.provisional ? { provisional: true } : {},
1062
+ next: {
1063
+ ...result.next,
1064
+ state: context.state,
1065
+ ...mergedExec != null ? {
1066
+ trace: mergedExec.trace,
1067
+ exec: mergedExec,
1068
+ dependencyRegistry: mergedExec.dependencyRegistry
1069
+ } : {}
1070
+ },
1071
+ consumed: result.consumed
1072
+ };
538
1073
  const nextItemState = inheritAnnotations(itemAnnotationSource, result.next.state);
539
1074
  return {
540
1075
  success: true,
1076
+ ...result.provisional ? { provisional: true } : {},
541
1077
  next: {
542
1078
  ...result.next,
543
- state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState])
1079
+ state: annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1080
+ ...mergedExec != null ? {
1081
+ trace: mergedExec.trace,
1082
+ exec: mergedExec,
1083
+ dependencyRegistry: mergedExec.dependencyRegistry
1084
+ } : {}
544
1085
  },
545
1086
  consumed: result.consumed
546
1087
  };
547
1088
  };
548
1089
  const resultParser = {
549
- $mode: parser.$mode,
1090
+ mode: parser.mode,
550
1091
  $valueType: [],
551
1092
  $stateType: [],
552
1093
  priority: parser.priority,
@@ -555,46 +1096,134 @@ function multiple(parser, options = {}) {
555
1096
  terms: parser.usage,
556
1097
  min
557
1098
  }],
1099
+ leadingNames: parser.leadingNames,
1100
+ acceptingAnyToken: min > 0 && (parser.acceptingAnyToken ?? false),
558
1101
  initialState: [],
1102
+ getSuggestRuntimeNodes(state, path) {
1103
+ const innerNodes = state.flatMap((item, i) => [...getInnerSuggestRuntimeNodes(item, [...path, i])]);
1104
+ return resultParser.dependencyMetadata?.source != null ? [{
1105
+ path,
1106
+ parser: resultParser,
1107
+ state
1108
+ }, ...innerNodes] : innerNodes;
1109
+ },
559
1110
  parse(context) {
560
- return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
1111
+ return dispatchByMode(parser.mode, () => parseSync(context), () => parseAsync(context));
561
1112
  },
562
- complete(state) {
563
- return dispatchByMode(parser.$mode, () => {
1113
+ complete(state, exec) {
1114
+ return dispatchByMode(parser.mode, () => {
564
1115
  const result = [];
565
- for (const s of state) {
566
- const valueResult = completeSyncWithUnwrappedFallback(s);
567
- if (valueResult.success) result.push(unwrapInjectedWrapper(valueResult.value));
568
- else return {
1116
+ const deferredIndices = /* @__PURE__ */ new Map();
1117
+ let hasDeferred = false;
1118
+ for (let i = 0; i < state.length; i++) {
1119
+ const valueResult = completeSyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
1120
+ if (valueResult.success) {
1121
+ const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
1122
+ result.push(unwrappedValue);
1123
+ if (valueResult.deferred) if (valueResult.deferredKeys) deferredIndices.set(i, valueResult.deferredKeys);
1124
+ else if (unwrappedValue == null || typeof unwrappedValue !== "object") deferredIndices.set(i, null);
1125
+ else hasDeferred = true;
1126
+ } else return {
569
1127
  success: false,
570
1128
  error: valueResult.error
571
1129
  };
572
1130
  }
573
- return validateMultipleResult(result);
1131
+ return validateMultipleResult(result, deferredIndices, hasDeferred);
574
1132
  }, async () => {
575
- const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s)));
576
1133
  const values = [];
577
- for (const valueResult of results) if (valueResult.success) values.push(unwrapInjectedWrapper(valueResult.value));
578
- else return {
579
- success: false,
580
- error: valueResult.error
1134
+ const deferredIndices = /* @__PURE__ */ new Map();
1135
+ let hasDeferred = false;
1136
+ for (let i = 0; i < state.length; i++) {
1137
+ const valueResult = await completeAsyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
1138
+ if (valueResult.success) {
1139
+ const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
1140
+ values.push(unwrappedValue);
1141
+ if (valueResult.deferred) if (valueResult.deferredKeys) deferredIndices.set(i, valueResult.deferredKeys);
1142
+ else if (unwrappedValue == null || typeof unwrappedValue !== "object") deferredIndices.set(i, null);
1143
+ else hasDeferred = true;
1144
+ } else return {
1145
+ success: false,
1146
+ error: valueResult.error
1147
+ };
1148
+ }
1149
+ return validateMultipleResult(values, deferredIndices, hasDeferred);
1150
+ });
1151
+ },
1152
+ [extractPhase2SeedKey](state, exec) {
1153
+ return dispatchByMode(parser.mode, () => {
1154
+ const values = [];
1155
+ const deferredIndices = /* @__PURE__ */ new Map();
1156
+ let hasDeferred = false;
1157
+ let hasAnySeed = false;
1158
+ for (let i = 0; i < state.length; i++) {
1159
+ const seed = extractPhase2SeedSyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
1160
+ if (seed == null) continue;
1161
+ hasAnySeed = true;
1162
+ values[i] = seed.value;
1163
+ if (seed.deferred) if (seed.deferredKeys) deferredIndices.set(i, seed.deferredKeys);
1164
+ else if (seed.value == null || typeof seed.value !== "object") deferredIndices.set(i, null);
1165
+ else hasDeferred = true;
1166
+ }
1167
+ if (!hasAnySeed) return null;
1168
+ return {
1169
+ value: values,
1170
+ ...deferredIndices.size > 0 || hasDeferred ? {
1171
+ deferred: true,
1172
+ ...deferredIndices.size > 0 ? { deferredKeys: deferredIndices } : {}
1173
+ } : {}
1174
+ };
1175
+ }, async () => {
1176
+ const values = [];
1177
+ const deferredIndices = /* @__PURE__ */ new Map();
1178
+ let hasDeferred = false;
1179
+ let hasAnySeed = false;
1180
+ for (let i = 0; i < state.length; i++) {
1181
+ const seed = await extractPhase2SeedAsyncWithUnwrappedFallback(state[i], withChildExecPath(exec, i));
1182
+ if (seed == null) continue;
1183
+ hasAnySeed = true;
1184
+ values[i] = seed.value;
1185
+ if (seed.deferred) if (seed.deferredKeys) deferredIndices.set(i, seed.deferredKeys);
1186
+ else if (seed.value == null || typeof seed.value !== "object") deferredIndices.set(i, null);
1187
+ else hasDeferred = true;
1188
+ }
1189
+ if (!hasAnySeed) return null;
1190
+ return {
1191
+ value: values,
1192
+ ...deferredIndices.size > 0 || hasDeferred ? {
1193
+ deferred: true,
1194
+ ...deferredIndices.size > 0 ? { deferredKeys: deferredIndices } : {}
1195
+ } : {}
581
1196
  };
582
- return validateMultipleResult(values);
583
1197
  });
584
1198
  },
585
1199
  suggest(context, prefix) {
586
- const selectedValues = /* @__PURE__ */ new Set();
587
- const suggestInitialState = inheritAnnotations(context.state, parser.initialState);
1200
+ const currentItemState = context.state.at(-1);
1201
+ const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1202
+ const canOpenNew = context.state.length < max;
1203
+ if (!canExtendCurrent && !canOpenNew) return dispatchIterableByMode(parser.mode, function* () {}, async function* () {});
1204
+ const itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
1205
+ const suggestInitialState = canExtendCurrent ? currentItemState : inheritAnnotations(context.state, parser.initialState);
588
1206
  const suggestFallbackState = unwrapInjectedWrapper(suggestInitialState);
589
1207
  const hasSuggestFallbackState = suggestFallbackState !== suggestInitialState;
590
- for (const s of context.state) {
591
- const completed = completeSyncWithUnwrappedFallback(s);
592
- if (completed.success) {
593
- const valueStr = String(unwrapInjectedWrapper(completed.value));
594
- selectedValues.add(valueStr);
1208
+ const collectSelectedValuesSync = () => {
1209
+ const selectedValues = /* @__PURE__ */ new Set();
1210
+ for (let i = 0; i < context.state.length; i++) {
1211
+ const childContext = withChildContext(context, i, context.state[i]);
1212
+ const completed = completeSyncWithUnwrappedFallback(childContext.state, childContext.exec);
1213
+ if (completed.success) selectedValues.add(String(unwrapInjectedWrapper(completed.value)));
595
1214
  }
596
- }
597
- const shouldInclude = (suggestion) => {
1215
+ return selectedValues;
1216
+ };
1217
+ const collectSelectedValuesAsync = async () => {
1218
+ const selectedValues = /* @__PURE__ */ new Set();
1219
+ for (let i = 0; i < context.state.length; i++) {
1220
+ const childContext = withChildContext(context, i, context.state[i]);
1221
+ const completed = await completeAsyncWithUnwrappedFallback(childContext.state, childContext.exec);
1222
+ if (completed.success) selectedValues.add(String(unwrapInjectedWrapper(completed.value)));
1223
+ }
1224
+ return selectedValues;
1225
+ };
1226
+ const shouldInclude = (selectedValues, suggestion) => {
598
1227
  if (suggestion.kind === "literal") return !selectedValues.has(suggestion.text);
599
1228
  return true;
600
1229
  };
@@ -610,16 +1239,17 @@ function multiple(parser, options = {}) {
610
1239
  suggestion.type,
611
1240
  suggestion.pattern ?? "",
612
1241
  suggestion.includeHidden === true,
613
- suggestion.extensions == null ? "" : suggestion.extensions.join("\0"),
1242
+ suggestion.extensions == null ? "" : suggestion.extensions.toSorted().join("\0"),
614
1243
  description
615
1244
  ]);
616
1245
  };
617
- return dispatchIterableByMode(parser.$mode, function* () {
1246
+ return dispatchIterableByMode(parser.mode, function* () {
1247
+ const selectedValues = collectSelectedValuesSync();
618
1248
  const emitted = /* @__PURE__ */ new Set();
619
1249
  const yieldUnique = function* (suggestions) {
620
1250
  for (const s of suggestions) {
621
1251
  const key = suggestionKey(s);
622
- if (shouldInclude(s) && !emitted.has(key)) {
1252
+ if (shouldInclude(selectedValues, s) && !emitted.has(key)) {
623
1253
  emitted.add(key);
624
1254
  yield s;
625
1255
  }
@@ -627,24 +1257,19 @@ function multiple(parser, options = {}) {
627
1257
  };
628
1258
  let shouldTryFallback = false;
629
1259
  try {
630
- yield* yieldUnique(syncParser.suggest({
631
- ...context,
632
- state: suggestInitialState
633
- }, prefix));
1260
+ yield* yieldUnique(syncParser.suggest(withChildContext(context, itemIndex, suggestInitialState), prefix));
634
1261
  } catch (error) {
635
1262
  if (!hasSuggestFallbackState) throw error;
636
1263
  shouldTryFallback = true;
637
1264
  }
638
- if (shouldTryFallback) yield* yieldUnique(syncParser.suggest({
639
- ...context,
640
- state: suggestFallbackState
641
- }, prefix));
1265
+ if (shouldTryFallback) yield* yieldUnique(syncParser.suggest(withChildContext(context, itemIndex, suggestFallbackState), prefix));
642
1266
  }, async function* () {
1267
+ const selectedValues = await collectSelectedValuesAsync();
643
1268
  const emitted = /* @__PURE__ */ new Set();
644
1269
  const yieldUnique = async function* (suggestions) {
645
1270
  for await (const s of suggestions) {
646
1271
  const key = suggestionKey(s);
647
- if (shouldInclude(s) && !emitted.has(key)) {
1272
+ if (shouldInclude(selectedValues, s) && !emitted.has(key)) {
648
1273
  emitted.add(key);
649
1274
  yield s;
650
1275
  }
@@ -652,18 +1277,12 @@ function multiple(parser, options = {}) {
652
1277
  };
653
1278
  let shouldTryFallback = false;
654
1279
  try {
655
- yield* yieldUnique(parser.suggest({
656
- ...context,
657
- state: suggestInitialState
658
- }, prefix));
1280
+ yield* yieldUnique(parser.suggest(withChildContext(context, itemIndex, suggestInitialState), prefix));
659
1281
  } catch (error) {
660
1282
  if (!hasSuggestFallbackState) throw error;
661
1283
  shouldTryFallback = true;
662
1284
  }
663
- if (shouldTryFallback) yield* yieldUnique(parser.suggest({
664
- ...context,
665
- state: suggestFallbackState
666
- }, prefix));
1285
+ if (shouldTryFallback) yield* yieldUnique(parser.suggest(withChildContext(context, itemIndex, suggestFallbackState), prefix));
667
1286
  });
668
1287
  },
669
1288
  getDocFragments(state, defaultValue) {
@@ -676,7 +1295,7 @@ function multiple(parser, options = {}) {
676
1295
  return syncParser.getDocFragments(innerState, defaultValue != null && defaultValue.length > 0 ? defaultValue[0] : void 0);
677
1296
  }
678
1297
  };
679
- function validateMultipleResult(result) {
1298
+ function validateMultipleResult(result, deferredIndices, hasDeferred = false) {
680
1299
  if (result.length < min) {
681
1300
  const customMessage = options.errors?.tooFew;
682
1301
  return {
@@ -690,10 +1309,139 @@ function multiple(parser, options = {}) {
690
1309
  error: customMessage ? typeof customMessage === "function" ? customMessage(max, result.length) : customMessage : message`Expected at most ${text(max.toLocaleString("en"))} values, but got ${text(result.length.toLocaleString("en"))}.`
691
1310
  };
692
1311
  }
1312
+ const isDeferred = deferredIndices.size > 0 || hasDeferred;
693
1313
  return {
694
1314
  success: true,
695
- value: result
1315
+ value: result,
1316
+ ...isDeferred ? {
1317
+ deferred: true,
1318
+ ...deferredIndices.size > 0 ? { deferredKeys: deferredIndices } : {}
1319
+ } : {}
1320
+ };
1321
+ }
1322
+ Object.defineProperty(resultParser, "placeholder", {
1323
+ get() {
1324
+ try {
1325
+ if (min > 0 && "placeholder" in parser) return Array.from({ length: min }, () => parser.placeholder);
1326
+ } catch {}
1327
+ return [];
1328
+ },
1329
+ configurable: true,
1330
+ enumerable: false
1331
+ });
1332
+ if (typeof parser.normalizeValue === "function") {
1333
+ const innerNormalize = parser.normalizeValue.bind(parser);
1334
+ Object.defineProperty(resultParser, "normalizeValue", {
1335
+ value(values) {
1336
+ if (!Array.isArray(values)) return values;
1337
+ let changed = false;
1338
+ const result = values.map((v) => {
1339
+ try {
1340
+ const n = innerNormalize(v);
1341
+ if (n !== v) changed = true;
1342
+ return n;
1343
+ } catch {
1344
+ return v;
1345
+ }
1346
+ });
1347
+ return changed ? result : values;
1348
+ },
1349
+ configurable: true,
1350
+ enumerable: false
1351
+ });
1352
+ }
1353
+ {
1354
+ const innerValidate = typeof parser.validateValue === "function" ? parser.validateValue.bind(parser) : void 0;
1355
+ const validateArity = (values) => {
1356
+ if (values.length < min) {
1357
+ const customMessage = options.errors?.tooFew;
1358
+ return {
1359
+ success: false,
1360
+ error: customMessage ? typeof customMessage === "function" ? customMessage(min, values.length) : customMessage : message`Expected at least ${text(min.toLocaleString("en"))} values, but got only ${text(values.length.toLocaleString("en"))}.`
1361
+ };
1362
+ }
1363
+ if (values.length > max) {
1364
+ const customMessage = options.errors?.tooMany;
1365
+ return {
1366
+ success: false,
1367
+ error: customMessage ? typeof customMessage === "function" ? customMessage(max, values.length) : customMessage : message`Expected at most ${text(max.toLocaleString("en"))} values, but got ${text(values.length.toLocaleString("en"))}.`
1368
+ };
1369
+ }
1370
+ return {
1371
+ success: true,
1372
+ value: values
1373
+ };
696
1374
  };
1375
+ Object.defineProperty(resultParser, "validateValue", {
1376
+ value(values) {
1377
+ if (!Array.isArray(values)) {
1378
+ const actualType = values === null ? "null" : typeof values;
1379
+ return wrapForMode(parser.mode, {
1380
+ success: false,
1381
+ error: message`Expected an array of values, but received ${actualType}.`
1382
+ });
1383
+ }
1384
+ const arity = validateArity(values);
1385
+ if (!arity.success) return wrapForMode(parser.mode, arity);
1386
+ if (innerValidate == null) return wrapForMode(parser.mode, arity);
1387
+ return dispatchByMode(parser.mode, () => {
1388
+ let changed = false;
1389
+ const normalized = [];
1390
+ for (const v of values) {
1391
+ const r = innerValidate(v);
1392
+ if (!r.success) return r;
1393
+ normalized.push(r.value);
1394
+ if (r.value !== v) changed = true;
1395
+ }
1396
+ return {
1397
+ success: true,
1398
+ value: changed ? normalized : values
1399
+ };
1400
+ }, async () => {
1401
+ let changed = false;
1402
+ const normalized = [];
1403
+ for (const v of values) {
1404
+ const r = await innerValidate(v);
1405
+ if (!r.success) return r;
1406
+ normalized.push(r.value);
1407
+ if (r.value !== v) changed = true;
1408
+ }
1409
+ return {
1410
+ success: true,
1411
+ value: changed ? normalized : values
1412
+ };
1413
+ });
1414
+ },
1415
+ configurable: true,
1416
+ enumerable: false
1417
+ });
1418
+ }
1419
+ if (parser.dependencyMetadata?.source != null) {
1420
+ const innerSource = parser.dependencyMetadata.source;
1421
+ Object.defineProperty(resultParser, "dependencyMetadata", {
1422
+ value: {
1423
+ ...parser.dependencyMetadata,
1424
+ source: {
1425
+ ...innerSource,
1426
+ preservesSourceValue: false,
1427
+ extractSourceValue: (state) => {
1428
+ if (!Array.isArray(state)) return innerSource.extractSourceValue(state);
1429
+ const scan = (index) => {
1430
+ for (let i = index; i >= 0; i--) {
1431
+ const result = innerSource.extractSourceValue(state[i]);
1432
+ if (result == null) continue;
1433
+ if (isPromiseLike(result)) return Promise.resolve(result).then((resolved) => resolved ?? scan(i - 1));
1434
+ return result;
1435
+ }
1436
+ return void 0;
1437
+ };
1438
+ return scan(state.length - 1);
1439
+ }
1440
+ }
1441
+ },
1442
+ configurable: true,
1443
+ enumerable: false
1444
+ });
697
1445
  }
698
1446
  return resultParser;
699
1447
  }
@@ -753,18 +1501,28 @@ function nonEmpty(parser) {
753
1501
  const result = await parser.parse(context);
754
1502
  return processNonEmptyResult(result);
755
1503
  };
756
- return {
757
- $mode: parser.$mode,
1504
+ const nonEmptyParser = {
1505
+ mode: parser.mode,
758
1506
  $valueType: parser.$valueType,
759
1507
  $stateType: parser.$stateType,
760
1508
  priority: parser.priority,
761
1509
  usage: parser.usage,
1510
+ leadingNames: parser.leadingNames,
1511
+ acceptingAnyToken: parser.acceptingAnyToken,
762
1512
  initialState: parser.initialState,
1513
+ ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
1514
+ getSuggestRuntimeNodes(state, path) {
1515
+ return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
1516
+ path,
1517
+ parser,
1518
+ state
1519
+ }] : []);
1520
+ },
763
1521
  parse(context) {
764
- return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
1522
+ return dispatchByMode(parser.mode, () => parseSync(context), () => parseAsync(context));
765
1523
  },
766
- complete(state) {
767
- return parser.complete(state);
1524
+ complete(state, exec) {
1525
+ return parser.complete(state, exec);
768
1526
  },
769
1527
  suggest(context, prefix) {
770
1528
  return parser.suggest(context, prefix);
@@ -773,6 +1531,31 @@ function nonEmpty(parser) {
773
1531
  return syncParser.getDocFragments(state, defaultValue);
774
1532
  }
775
1533
  };
1534
+ if ("placeholder" in parser) Object.defineProperty(nonEmptyParser, "placeholder", {
1535
+ get() {
1536
+ return parser.placeholder;
1537
+ },
1538
+ configurable: true,
1539
+ enumerable: false
1540
+ });
1541
+ Object.defineProperty(nonEmptyParser, extractPhase2SeedKey, {
1542
+ value(state, exec) {
1543
+ return extractPhase2Seed(parser, state, exec);
1544
+ },
1545
+ configurable: true,
1546
+ enumerable: false
1547
+ });
1548
+ if (typeof parser.normalizeValue === "function") Object.defineProperty(nonEmptyParser, "normalizeValue", {
1549
+ value: parser.normalizeValue.bind(parser),
1550
+ configurable: true,
1551
+ enumerable: false
1552
+ });
1553
+ if (typeof parser.validateValue === "function") Object.defineProperty(nonEmptyParser, "validateValue", {
1554
+ value: parser.validateValue.bind(parser),
1555
+ configurable: true,
1556
+ enumerable: false
1557
+ });
1558
+ return nonEmptyParser;
776
1559
  }
777
1560
 
778
1561
  //#endregion