@optique/core 0.9.0-dev.211 → 0.9.0-dev.215

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.
@@ -117,45 +117,79 @@ function generateNoMatchError(context) {
117
117
  * Creates a complete() method shared by or() and longestMatch().
118
118
  * @internal
119
119
  */
120
- function createExclusiveComplete(parsers, options, noMatchContext) {
120
+ function createExclusiveComplete(parsers, options, noMatchContext, isAsync) {
121
+ const syncParsers = parsers;
121
122
  return (state) => {
122
123
  if (state == null) return {
123
124
  success: false,
124
125
  error: getNoMatchError(options, noMatchContext)
125
126
  };
126
127
  const [i, result] = state;
127
- if (result.success) return parsers[i].complete(result.next.state);
128
- return {
128
+ if (!result.success) return {
129
129
  success: false,
130
130
  error: result.error
131
131
  };
132
+ if (isAsync) return (async () => {
133
+ const completeResult = await parsers[i].complete(result.next.state);
134
+ return completeResult;
135
+ })();
136
+ return syncParsers[i].complete(result.next.state);
132
137
  };
133
138
  }
134
139
  /**
135
140
  * Creates a suggest() method shared by or() and longestMatch().
136
141
  * @internal
137
142
  */
138
- function createExclusiveSuggest(parsers) {
143
+ function createExclusiveSuggest(parsers, isAsync) {
144
+ const syncParsers = parsers;
145
+ if (isAsync) return (context, prefix) => {
146
+ return async function* () {
147
+ const suggestions = [];
148
+ if (context.state == null) for (const parser of parsers) {
149
+ const parserSuggestions = parser.suggest({
150
+ ...context,
151
+ state: parser.initialState
152
+ }, prefix);
153
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
154
+ else suggestions.push(...parserSuggestions);
155
+ }
156
+ else {
157
+ const [index, parserResult] = context.state;
158
+ if (parserResult.success) {
159
+ const parser = parsers[index];
160
+ const parserSuggestions = parser.suggest({
161
+ ...context,
162
+ state: parserResult.next.state
163
+ }, prefix);
164
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
165
+ else suggestions.push(...parserSuggestions);
166
+ }
167
+ }
168
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
169
+ }();
170
+ };
139
171
  return (context, prefix) => {
140
- const suggestions = [];
141
- if (context.state == null) for (const parser of parsers) {
142
- const parserSuggestions = parser.suggest({
143
- ...context,
144
- state: parser.initialState
145
- }, prefix);
146
- suggestions.push(...parserSuggestions);
147
- }
148
- else {
149
- const [index, parserResult] = context.state;
150
- if (parserResult.success) {
151
- const parserSuggestions = parsers[index].suggest({
172
+ return function* () {
173
+ const suggestions = [];
174
+ if (context.state == null) for (const parser of syncParsers) {
175
+ const parserSuggestions = parser.suggest({
152
176
  ...context,
153
- state: parserResult.next.state
177
+ state: parser.initialState
154
178
  }, prefix);
155
179
  suggestions.push(...parserSuggestions);
156
180
  }
157
- }
158
- return require_suggestion.deduplicateSuggestions(suggestions);
181
+ else {
182
+ const [index, parserResult] = context.state;
183
+ if (parserResult.success) {
184
+ const parserSuggestions = syncParsers[index].suggest({
185
+ ...context,
186
+ state: parserResult.next.state
187
+ }, prefix);
188
+ suggestions.push(...parserSuggestions);
189
+ }
190
+ }
191
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
192
+ }();
159
193
  };
160
194
  }
161
195
  /**
@@ -191,7 +225,80 @@ function or(...args) {
191
225
  options = void 0;
192
226
  }
193
227
  const noMatchContext = analyzeNoMatchContext(parsers);
228
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
229
+ const isAsync = combinedMode === "async";
230
+ const syncParsers = parsers;
231
+ const getInitialError = (context) => ({
232
+ consumed: 0,
233
+ error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
234
+ });
235
+ const parseSync = (context) => {
236
+ let error = getInitialError(context);
237
+ const orderedParsers = syncParsers.map((p, i) => [p, i]);
238
+ orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
239
+ for (const [parser, i] of orderedParsers) {
240
+ const result = parser.parse({
241
+ ...context,
242
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
243
+ });
244
+ if (result.success && result.consumed.length > 0) {
245
+ if (context.state?.[0] !== i && context.state?.[1].success) return {
246
+ success: false,
247
+ consumed: context.buffer.length - result.next.buffer.length,
248
+ error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
249
+ };
250
+ return {
251
+ success: true,
252
+ next: {
253
+ ...context,
254
+ buffer: result.next.buffer,
255
+ optionsTerminated: result.next.optionsTerminated,
256
+ state: [i, result]
257
+ },
258
+ consumed: result.consumed
259
+ };
260
+ } else if (!result.success && error.consumed < result.consumed) error = result;
261
+ }
262
+ return {
263
+ ...error,
264
+ success: false
265
+ };
266
+ };
267
+ const parseAsync = async (context) => {
268
+ let error = getInitialError(context);
269
+ const orderedParsers = parsers.map((p, i) => [p, i]);
270
+ orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
271
+ for (const [parser, i] of orderedParsers) {
272
+ const resultOrPromise = parser.parse({
273
+ ...context,
274
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
275
+ });
276
+ const result = await resultOrPromise;
277
+ if (result.success && result.consumed.length > 0) {
278
+ if (context.state?.[0] !== i && context.state?.[1].success) return {
279
+ success: false,
280
+ consumed: context.buffer.length - result.next.buffer.length,
281
+ error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
282
+ };
283
+ return {
284
+ success: true,
285
+ next: {
286
+ ...context,
287
+ buffer: result.next.buffer,
288
+ optionsTerminated: result.next.optionsTerminated,
289
+ state: [i, result]
290
+ },
291
+ consumed: result.consumed
292
+ };
293
+ } else if (!result.success && error.consumed < result.consumed) error = result;
294
+ }
295
+ return {
296
+ ...error,
297
+ success: false
298
+ };
299
+ };
194
300
  return {
301
+ $mode: combinedMode,
195
302
  $valueType: [],
196
303
  $stateType: [],
197
304
  priority: Math.max(...parsers.map((p) => p.priority)),
@@ -200,43 +307,12 @@ function or(...args) {
200
307
  terms: parsers.map((p) => p.usage)
201
308
  }],
202
309
  initialState: void 0,
203
- complete: createExclusiveComplete(parsers, options, noMatchContext),
310
+ complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
204
311
  parse(context) {
205
- let error = {
206
- consumed: 0,
207
- error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
208
- };
209
- const orderedParsers = parsers.map((p, i) => [p, i]);
210
- orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
211
- for (const [parser, i] of orderedParsers) {
212
- const result = parser.parse({
213
- ...context,
214
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
215
- });
216
- if (result.success && result.consumed.length > 0) {
217
- if (context.state?.[0] !== i && context.state?.[1].success) return {
218
- success: false,
219
- consumed: context.buffer.length - result.next.buffer.length,
220
- error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
221
- };
222
- return {
223
- success: true,
224
- next: {
225
- ...context,
226
- buffer: result.next.buffer,
227
- optionsTerminated: result.next.optionsTerminated,
228
- state: [i, result]
229
- },
230
- consumed: result.consumed
231
- };
232
- } else if (!result.success && error.consumed < result.consumed) error = result;
233
- }
234
- return {
235
- ...error,
236
- success: false
237
- };
312
+ if (isAsync) return parseAsync(context);
313
+ return parseSync(context);
238
314
  },
239
- suggest: createExclusiveSuggest(parsers),
315
+ suggest: createExclusiveSuggest(parsers, isAsync),
240
316
  getDocFragments(state, _defaultValue) {
241
317
  let description;
242
318
  let fragments;
@@ -285,7 +361,82 @@ function longestMatch(...args) {
285
361
  options = void 0;
286
362
  }
287
363
  const noMatchContext = analyzeNoMatchContext(parsers);
364
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
365
+ const isAsync = combinedMode === "async";
366
+ const syncParsers = parsers;
367
+ const getInitialError = (context) => ({
368
+ consumed: 0,
369
+ error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
370
+ });
371
+ const parseSync = (context) => {
372
+ let bestMatch = null;
373
+ let error = getInitialError(context);
374
+ for (let i = 0; i < syncParsers.length; i++) {
375
+ const parser = syncParsers[i];
376
+ const result = parser.parse({
377
+ ...context,
378
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
379
+ });
380
+ if (result.success) {
381
+ const consumed = context.buffer.length - result.next.buffer.length;
382
+ if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
383
+ index: i,
384
+ result,
385
+ consumed
386
+ };
387
+ } else if (error.consumed < result.consumed) error = result;
388
+ }
389
+ if (bestMatch && bestMatch.result.success) return {
390
+ success: true,
391
+ next: {
392
+ ...context,
393
+ buffer: bestMatch.result.next.buffer,
394
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
395
+ state: [bestMatch.index, bestMatch.result]
396
+ },
397
+ consumed: bestMatch.result.consumed
398
+ };
399
+ return {
400
+ ...error,
401
+ success: false
402
+ };
403
+ };
404
+ const parseAsync = async (context) => {
405
+ let bestMatch = null;
406
+ let error = getInitialError(context);
407
+ for (let i = 0; i < parsers.length; i++) {
408
+ const parser = parsers[i];
409
+ const resultOrPromise = parser.parse({
410
+ ...context,
411
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
412
+ });
413
+ const result = await resultOrPromise;
414
+ if (result.success) {
415
+ const consumed = context.buffer.length - result.next.buffer.length;
416
+ if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
417
+ index: i,
418
+ result,
419
+ consumed
420
+ };
421
+ } else if (error.consumed < result.consumed) error = result;
422
+ }
423
+ if (bestMatch && bestMatch.result.success) return {
424
+ success: true,
425
+ next: {
426
+ ...context,
427
+ buffer: bestMatch.result.next.buffer,
428
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
429
+ state: [bestMatch.index, bestMatch.result]
430
+ },
431
+ consumed: bestMatch.result.consumed
432
+ };
433
+ return {
434
+ ...error,
435
+ success: false
436
+ };
437
+ };
288
438
  return {
439
+ $mode: combinedMode,
289
440
  $valueType: [],
290
441
  $stateType: [],
291
442
  priority: Math.max(...parsers.map((p) => p.priority)),
@@ -294,44 +445,12 @@ function longestMatch(...args) {
294
445
  terms: parsers.map((p) => p.usage)
295
446
  }],
296
447
  initialState: void 0,
297
- complete: createExclusiveComplete(parsers, options, noMatchContext),
448
+ complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
298
449
  parse(context) {
299
- let bestMatch = null;
300
- let error = {
301
- consumed: 0,
302
- error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
303
- };
304
- for (let i = 0; i < parsers.length; i++) {
305
- const parser = parsers[i];
306
- const result = parser.parse({
307
- ...context,
308
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
309
- });
310
- if (result.success) {
311
- const consumed = context.buffer.length - result.next.buffer.length;
312
- if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
313
- index: i,
314
- result,
315
- consumed
316
- };
317
- } else if (error.consumed < result.consumed) error = result;
318
- }
319
- if (bestMatch && bestMatch.result.success) return {
320
- success: true,
321
- next: {
322
- ...context,
323
- buffer: bestMatch.result.next.buffer,
324
- optionsTerminated: bestMatch.result.next.optionsTerminated,
325
- state: [bestMatch.index, bestMatch.result]
326
- },
327
- consumed: bestMatch.result.consumed
328
- };
329
- return {
330
- ...error,
331
- success: false
332
- };
450
+ if (isAsync) return parseAsync(context);
451
+ return parseSync(context);
333
452
  },
334
- suggest: createExclusiveSuggest(parsers),
453
+ suggest: createExclusiveSuggest(parsers, isAsync),
335
454
  getDocFragments(state, _defaultValue) {
336
455
  let description;
337
456
  let footer;
@@ -357,6 +476,61 @@ function longestMatch(...args) {
357
476
  }
358
477
  };
359
478
  }
479
+ /**
480
+ * Internal sync helper for object suggest functionality.
481
+ * @internal
482
+ */
483
+ function* suggestObjectSync(context, prefix, parserPairs) {
484
+ if (context.buffer.length > 0) {
485
+ const lastToken = context.buffer[context.buffer.length - 1];
486
+ for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
487
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
488
+ yield* parser.suggest({
489
+ ...context,
490
+ state: fieldState
491
+ }, prefix);
492
+ return;
493
+ }
494
+ }
495
+ const suggestions = [];
496
+ for (const [field, parser] of parserPairs) {
497
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
498
+ const fieldSuggestions = parser.suggest({
499
+ ...context,
500
+ state: fieldState
501
+ }, prefix);
502
+ suggestions.push(...fieldSuggestions);
503
+ }
504
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
505
+ }
506
+ /**
507
+ * Internal async helper for object suggest functionality.
508
+ * @internal
509
+ */
510
+ async function* suggestObjectAsync(context, prefix, parserPairs) {
511
+ if (context.buffer.length > 0) {
512
+ const lastToken = context.buffer[context.buffer.length - 1];
513
+ for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
514
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
515
+ const suggestions$1 = parser.suggest({
516
+ ...context,
517
+ state: fieldState
518
+ }, prefix);
519
+ for await (const s of suggestions$1) yield s;
520
+ return;
521
+ }
522
+ }
523
+ const suggestions = [];
524
+ for (const [field, parser] of parserPairs) {
525
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
526
+ const fieldSuggestions = parser.suggest({
527
+ ...context,
528
+ state: fieldState
529
+ }, prefix);
530
+ for await (const s of fieldSuggestions) suggestions.push(s);
531
+ }
532
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
533
+ }
360
534
  function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
361
535
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
362
536
  let parsers;
@@ -375,131 +549,181 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
375
549
  for (const key of parserKeys) initialState[key] = parsers[key].initialState;
376
550
  if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
377
551
  const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
378
- return {
379
- $valueType: [],
380
- $stateType: [],
381
- priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
382
- usage: parserPairs.flatMap(([_, p]) => p.usage),
383
- initialState,
384
- parse(context) {
385
- if (!options.allowDuplicates) {
386
- const optionNameSources = /* @__PURE__ */ new Map();
387
- for (const [field, parser] of parserPairs) {
388
- const names = require_usage.extractOptionNames(parser.usage);
389
- for (const name of names) {
390
- if (!optionNameSources.has(name)) optionNameSources.set(name, []);
391
- optionNameSources.get(name).push(field);
392
- }
552
+ const combinedMode = parserKeys.some((k) => parsers[k].$mode === "async") ? "async" : "sync";
553
+ const isAsync = combinedMode === "async";
554
+ const getInitialError = (context) => ({
555
+ consumed: 0,
556
+ error: context.buffer.length > 0 ? (() => {
557
+ const token = context.buffer[0];
558
+ const customMessage = options.errors?.unexpectedInput;
559
+ if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
560
+ const baseError = require_message.message`Unexpected option or argument: ${token}.`;
561
+ return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
562
+ })() : (() => {
563
+ const customEndOfInput = options.errors?.endOfInput;
564
+ return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
565
+ })()
566
+ });
567
+ const parseSync = (context) => {
568
+ let error = getInitialError(context);
569
+ let currentContext = context;
570
+ let anySuccess = false;
571
+ const allConsumed = [];
572
+ let madeProgress = true;
573
+ while (madeProgress && currentContext.buffer.length > 0) {
574
+ madeProgress = false;
575
+ for (const [field, parser] of parserPairs) {
576
+ const result = parser.parse({
577
+ ...currentContext,
578
+ state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
579
+ });
580
+ if (result.success && result.consumed.length > 0) {
581
+ currentContext = {
582
+ ...currentContext,
583
+ buffer: result.next.buffer,
584
+ optionsTerminated: result.next.optionsTerminated,
585
+ state: {
586
+ ...currentContext.state,
587
+ [field]: result.next.state
588
+ }
589
+ };
590
+ allConsumed.push(...result.consumed);
591
+ anySuccess = true;
592
+ madeProgress = true;
593
+ break;
594
+ } else if (!result.success && error.consumed < result.consumed) error = result;
595
+ }
596
+ }
597
+ if (anySuccess) return {
598
+ success: true,
599
+ next: currentContext,
600
+ consumed: allConsumed
601
+ };
602
+ if (context.buffer.length === 0) {
603
+ let allCanComplete = true;
604
+ for (const [field, parser] of parserPairs) {
605
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
606
+ const completeResult = parser.complete(fieldState);
607
+ if (!completeResult.success) {
608
+ allCanComplete = false;
609
+ break;
393
610
  }
394
- for (const [name, sources] of optionNameSources) if (sources.length > 1) return {
395
- success: false,
396
- consumed: 0,
397
- error: require_message.message`Duplicate option name ${require_message.optionName(name)} found in fields: ${require_message.values(sources.map((s) => typeof s === "symbol" ? s.description ?? s.toString() : s))}. Each option name must be unique within a parser combinator.`
398
- };
399
611
  }
400
- let error = {
401
- consumed: 0,
402
- error: context.buffer.length > 0 ? (() => {
403
- const token = context.buffer[0];
404
- const customMessage = options.errors?.unexpectedInput;
405
- if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
406
- const baseError = require_message.message`Unexpected option or argument: ${token}.`;
407
- return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
408
- })() : (() => {
409
- const customEndOfInput = options.errors?.endOfInput;
410
- return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
411
- })()
612
+ if (allCanComplete) return {
613
+ success: true,
614
+ next: context,
615
+ consumed: []
412
616
  };
413
- let currentContext = context;
414
- let anySuccess = false;
415
- const allConsumed = [];
416
- let madeProgress = true;
417
- while (madeProgress && currentContext.buffer.length > 0) {
418
- madeProgress = false;
419
- for (const [field, parser] of parserPairs) {
420
- const result = parser.parse({
617
+ }
618
+ return {
619
+ ...error,
620
+ success: false
621
+ };
622
+ };
623
+ const parseAsync = async (context) => {
624
+ let error = getInitialError(context);
625
+ let currentContext = context;
626
+ let anySuccess = false;
627
+ const allConsumed = [];
628
+ let madeProgress = true;
629
+ while (madeProgress && currentContext.buffer.length > 0) {
630
+ madeProgress = false;
631
+ for (const [field, parser] of parserPairs) {
632
+ const resultOrPromise = parser.parse({
633
+ ...currentContext,
634
+ state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
635
+ });
636
+ const result = await resultOrPromise;
637
+ if (result.success && result.consumed.length > 0) {
638
+ currentContext = {
421
639
  ...currentContext,
422
- state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
423
- });
424
- if (result.success && result.consumed.length > 0) {
425
- currentContext = {
426
- ...currentContext,
427
- buffer: result.next.buffer,
428
- optionsTerminated: result.next.optionsTerminated,
429
- state: {
430
- ...currentContext.state,
431
- [field]: result.next.state
432
- }
433
- };
434
- allConsumed.push(...result.consumed);
435
- anySuccess = true;
436
- madeProgress = true;
437
- break;
438
- } else if (!result.success && error.consumed < result.consumed) error = result;
640
+ buffer: result.next.buffer,
641
+ optionsTerminated: result.next.optionsTerminated,
642
+ state: {
643
+ ...currentContext.state,
644
+ [field]: result.next.state
645
+ }
646
+ };
647
+ allConsumed.push(...result.consumed);
648
+ anySuccess = true;
649
+ madeProgress = true;
650
+ break;
651
+ } else if (!result.success && error.consumed < result.consumed) error = result;
652
+ }
653
+ }
654
+ if (anySuccess) return {
655
+ success: true,
656
+ next: currentContext,
657
+ consumed: allConsumed
658
+ };
659
+ if (context.buffer.length === 0) {
660
+ let allCanComplete = true;
661
+ for (const [field, parser] of parserPairs) {
662
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
663
+ const completeResult = await parser.complete(fieldState);
664
+ if (!completeResult.success) {
665
+ allCanComplete = false;
666
+ break;
439
667
  }
440
668
  }
441
- if (anySuccess) return {
669
+ if (allCanComplete) return {
442
670
  success: true,
443
- next: currentContext,
444
- consumed: allConsumed
671
+ next: context,
672
+ consumed: []
445
673
  };
446
- if (context.buffer.length === 0) {
447
- let allCanComplete = true;
448
- for (const [field, parser] of parserPairs) {
449
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
450
- const completeResult = parser.complete(fieldState);
451
- if (!completeResult.success) {
452
- allCanComplete = false;
453
- break;
454
- }
674
+ }
675
+ return {
676
+ ...error,
677
+ success: false
678
+ };
679
+ };
680
+ return {
681
+ $mode: combinedMode,
682
+ $valueType: [],
683
+ $stateType: [],
684
+ priority: Math.max(...parserKeys.map((k) => parsers[k].priority)),
685
+ usage: parserPairs.flatMap(([_, p]) => p.usage),
686
+ initialState,
687
+ parse(context) {
688
+ if (isAsync) return parseAsync(context);
689
+ return parseSync(context);
690
+ },
691
+ complete(state) {
692
+ if (!isAsync) {
693
+ const result = {};
694
+ for (const field of parserKeys) {
695
+ const valueResult = parsers[field].complete(state[field]);
696
+ if (valueResult.success) result[field] = valueResult.value;
697
+ else return {
698
+ success: false,
699
+ error: valueResult.error
700
+ };
455
701
  }
456
- if (allCanComplete) return {
702
+ return {
457
703
  success: true,
458
- next: context,
459
- consumed: []
704
+ value: result
460
705
  };
461
706
  }
462
- return {
463
- ...error,
464
- success: false
465
- };
466
- },
467
- complete(state) {
468
- const result = {};
469
- for (const field of parserKeys) {
470
- const valueResult = parsers[field].complete(state[field]);
471
- if (valueResult.success) result[field] = valueResult.value;
472
- else return {
473
- success: false,
474
- error: valueResult.error
707
+ return (async () => {
708
+ const result = {};
709
+ for (const field of parserKeys) {
710
+ const valueResult = await parsers[field].complete(state[field]);
711
+ if (valueResult.success) result[field] = valueResult.value;
712
+ else return {
713
+ success: false,
714
+ error: valueResult.error
715
+ };
716
+ }
717
+ return {
718
+ success: true,
719
+ value: result
475
720
  };
476
- }
477
- return {
478
- success: true,
479
- value: result
480
- };
721
+ })();
481
722
  },
482
723
  suggest(context, prefix) {
483
- const suggestions = [];
484
- if (context.buffer.length > 0) {
485
- const lastToken = context.buffer[context.buffer.length - 1];
486
- for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
487
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
488
- return Array.from(parser.suggest({
489
- ...context,
490
- state: fieldState
491
- }, prefix));
492
- }
493
- }
494
- for (const [field, parser] of parserPairs) {
495
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
496
- const fieldSuggestions = parser.suggest({
497
- ...context,
498
- state: fieldState
499
- }, prefix);
500
- suggestions.push(...fieldSuggestions);
501
- }
502
- return require_suggestion.deduplicateSuggestions(suggestions);
724
+ if (isAsync) return suggestObjectAsync(context, prefix, parserPairs);
725
+ const syncParserPairs = parserPairs;
726
+ return suggestObjectSync(context, prefix, syncParserPairs);
503
727
  },
504
728
  getDocFragments(state, defaultValue) {
505
729
  const fragments = parserPairs.flatMap(([field, p]) => {
@@ -528,6 +752,35 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
528
752
  }
529
753
  };
530
754
  }
755
+ function suggestTupleSync(context, prefix, parsers) {
756
+ const suggestions = [];
757
+ const stateArray = context.state;
758
+ for (let i = 0; i < parsers.length; i++) {
759
+ const parser = parsers[i];
760
+ const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
761
+ const parserSuggestions = parser.suggest({
762
+ ...context,
763
+ state: parserState
764
+ }, prefix);
765
+ suggestions.push(...parserSuggestions);
766
+ }
767
+ return require_suggestion.deduplicateSuggestions(suggestions);
768
+ }
769
+ async function* suggestTupleAsync(context, prefix, parsers) {
770
+ const suggestions = [];
771
+ const stateArray = context.state;
772
+ for (let i = 0; i < parsers.length; i++) {
773
+ const parser = parsers[i];
774
+ const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
775
+ const parserSuggestions = parser.suggest({
776
+ ...context,
777
+ state: parserState
778
+ }, prefix);
779
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
780
+ else suggestions.push(...parserSuggestions);
781
+ }
782
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
783
+ }
531
784
  function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
532
785
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
533
786
  let parsers;
@@ -539,102 +792,187 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
539
792
  parsers = labelOrParsers;
540
793
  options = maybeParsersOrOptions ?? {};
541
794
  }
795
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
796
+ const isAsync = combinedMode === "async";
797
+ const syncParsers = parsers;
542
798
  if (!options.allowDuplicates) checkDuplicateOptionNames(parsers.map((parser, index) => [String(index), parser.usage]));
799
+ const parseSync = (context) => {
800
+ let currentContext = context;
801
+ const allConsumed = [];
802
+ const matchedParsers = /* @__PURE__ */ new Set();
803
+ while (matchedParsers.size < syncParsers.length) {
804
+ let foundMatch = false;
805
+ let error = {
806
+ consumed: 0,
807
+ error: require_message.message`No remaining parsers could match the input.`
808
+ };
809
+ const stateArray = currentContext.state;
810
+ const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
811
+ for (const [parser, index] of remainingParsers) {
812
+ const result = parser.parse({
813
+ ...currentContext,
814
+ state: stateArray[index]
815
+ });
816
+ if (result.success && result.consumed.length > 0) {
817
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
818
+ currentContext = {
819
+ ...currentContext,
820
+ buffer: result.next.buffer,
821
+ optionsTerminated: result.next.optionsTerminated,
822
+ state: newStateArray
823
+ };
824
+ allConsumed.push(...result.consumed);
825
+ matchedParsers.add(index);
826
+ foundMatch = true;
827
+ break;
828
+ } else if (!result.success && error.consumed < result.consumed) error = result;
829
+ }
830
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
831
+ const result = parser.parse({
832
+ ...currentContext,
833
+ state: stateArray[index]
834
+ });
835
+ if (result.success && result.consumed.length < 1) {
836
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
837
+ currentContext = {
838
+ ...currentContext,
839
+ state: newStateArray
840
+ };
841
+ matchedParsers.add(index);
842
+ foundMatch = true;
843
+ break;
844
+ } else if (!result.success && result.consumed < 1) {
845
+ matchedParsers.add(index);
846
+ foundMatch = true;
847
+ break;
848
+ }
849
+ }
850
+ if (!foundMatch) return {
851
+ ...error,
852
+ success: false
853
+ };
854
+ }
855
+ return {
856
+ success: true,
857
+ next: currentContext,
858
+ consumed: allConsumed
859
+ };
860
+ };
861
+ const parseAsync = async (context) => {
862
+ let currentContext = context;
863
+ const allConsumed = [];
864
+ const matchedParsers = /* @__PURE__ */ new Set();
865
+ while (matchedParsers.size < parsers.length) {
866
+ let foundMatch = false;
867
+ let error = {
868
+ consumed: 0,
869
+ error: require_message.message`No remaining parsers could match the input.`
870
+ };
871
+ const stateArray = currentContext.state;
872
+ const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
873
+ for (const [parser, index] of remainingParsers) {
874
+ const resultOrPromise = parser.parse({
875
+ ...currentContext,
876
+ state: stateArray[index]
877
+ });
878
+ const result = await resultOrPromise;
879
+ if (result.success && result.consumed.length > 0) {
880
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
881
+ currentContext = {
882
+ ...currentContext,
883
+ buffer: result.next.buffer,
884
+ optionsTerminated: result.next.optionsTerminated,
885
+ state: newStateArray
886
+ };
887
+ allConsumed.push(...result.consumed);
888
+ matchedParsers.add(index);
889
+ foundMatch = true;
890
+ break;
891
+ } else if (!result.success && error.consumed < result.consumed) error = result;
892
+ }
893
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
894
+ const resultOrPromise = parser.parse({
895
+ ...currentContext,
896
+ state: stateArray[index]
897
+ });
898
+ const result = await resultOrPromise;
899
+ if (result.success && result.consumed.length < 1) {
900
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
901
+ currentContext = {
902
+ ...currentContext,
903
+ state: newStateArray
904
+ };
905
+ matchedParsers.add(index);
906
+ foundMatch = true;
907
+ break;
908
+ } else if (!result.success && result.consumed < 1) {
909
+ matchedParsers.add(index);
910
+ foundMatch = true;
911
+ break;
912
+ }
913
+ }
914
+ if (!foundMatch) return {
915
+ ...error,
916
+ success: false
917
+ };
918
+ }
919
+ return {
920
+ success: true,
921
+ next: currentContext,
922
+ consumed: allConsumed
923
+ };
924
+ };
543
925
  return {
926
+ $mode: combinedMode,
544
927
  $valueType: [],
545
928
  $stateType: [],
546
929
  usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
547
930
  priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
548
931
  initialState: parsers.map((parser) => parser.initialState),
549
932
  parse(context) {
550
- let currentContext = context;
551
- const allConsumed = [];
552
- const matchedParsers = /* @__PURE__ */ new Set();
553
- while (matchedParsers.size < parsers.length) {
554
- let foundMatch = false;
555
- let error = {
556
- consumed: 0,
557
- error: require_message.message`No remaining parsers could match the input.`
558
- };
559
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
560
- for (const [parser, index] of remainingParsers) {
561
- const result = parser.parse({
562
- ...currentContext,
563
- state: currentContext.state[index]
564
- });
565
- if (result.success && result.consumed.length > 0) {
566
- currentContext = {
567
- ...currentContext,
568
- buffer: result.next.buffer,
569
- optionsTerminated: result.next.optionsTerminated,
570
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
571
- };
572
- allConsumed.push(...result.consumed);
573
- matchedParsers.add(index);
574
- foundMatch = true;
575
- break;
576
- } else if (!result.success && error.consumed < result.consumed) error = result;
577
- }
578
- if (!foundMatch) for (const [parser, index] of remainingParsers) {
579
- const result = parser.parse({
580
- ...currentContext,
581
- state: currentContext.state[index]
582
- });
583
- if (result.success && result.consumed.length < 1) {
584
- currentContext = {
585
- ...currentContext,
586
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
587
- };
588
- matchedParsers.add(index);
589
- foundMatch = true;
590
- break;
591
- } else if (!result.success && result.consumed < 1) {
592
- matchedParsers.add(index);
593
- foundMatch = true;
594
- break;
595
- }
596
- }
597
- if (!foundMatch) return {
598
- ...error,
599
- success: false
600
- };
601
- }
602
- return {
603
- success: true,
604
- next: currentContext,
605
- consumed: allConsumed
606
- };
933
+ if (isAsync) return parseAsync(context);
934
+ return parseSync(context);
607
935
  },
608
936
  complete(state) {
609
- const result = [];
610
- for (let i = 0; i < parsers.length; i++) {
611
- const valueResult = parsers[i].complete(state[i]);
612
- if (valueResult.success) result[i] = valueResult.value;
613
- else return {
614
- success: false,
615
- error: valueResult.error
937
+ if (!isAsync) {
938
+ const result = [];
939
+ const stateArray = state;
940
+ for (let i = 0; i < syncParsers.length; i++) {
941
+ const valueResult = syncParsers[i].complete(stateArray[i]);
942
+ if (valueResult.success) result[i] = valueResult.value;
943
+ else return {
944
+ success: false,
945
+ error: valueResult.error
946
+ };
947
+ }
948
+ return {
949
+ success: true,
950
+ value: result
616
951
  };
617
952
  }
618
- return {
619
- success: true,
620
- value: result
621
- };
953
+ return (async () => {
954
+ const result = [];
955
+ const stateArray = state;
956
+ for (let i = 0; i < parsers.length; i++) {
957
+ const valueResult = await parsers[i].complete(stateArray[i]);
958
+ if (valueResult.success) result[i] = valueResult.value;
959
+ else return {
960
+ success: false,
961
+ error: valueResult.error
962
+ };
963
+ }
964
+ return {
965
+ success: true,
966
+ value: result
967
+ };
968
+ })();
622
969
  },
623
970
  suggest(context, prefix) {
624
- const suggestions = [];
625
- for (let i = 0; i < parsers.length; i++) {
626
- const parser = parsers[i];
627
- const parserState = context.state && Array.isArray(context.state) ? context.state[i] : parser.initialState;
628
- const parserSuggestions = parser.suggest({
629
- ...context,
630
- state: parserState
631
- }, prefix);
632
- suggestions.push(...parserSuggestions);
633
- }
634
- return require_suggestion.deduplicateSuggestions(suggestions);
971
+ if (isAsync) return suggestTupleAsync(context, prefix, parsers);
972
+ return suggestTupleSync(context, prefix, syncParsers);
635
973
  },
636
974
  getDocFragments(state, defaultValue) {
637
- const fragments = parsers.flatMap((p, i) => {
975
+ const fragments = syncParsers.flatMap((p, i) => {
638
976
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
639
977
  kind: "available",
640
978
  state: state.state[i]
@@ -671,127 +1009,235 @@ function merge(...args) {
671
1009
  const startIndex = typeof args[0] === "string" ? 1 : 0;
672
1010
  const endIndex = lastArg && typeof lastArg === "object" && !("parse" in lastArg) && !("complete" in lastArg) ? args.length - 1 : args.length;
673
1011
  const rawParsers = args.slice(startIndex, endIndex);
1012
+ const combinedMode = rawParsers.some((p) => p.$mode === "async") ? "async" : "sync";
1013
+ const isAsync = combinedMode === "async";
1014
+ const syncRawParsers = rawParsers;
674
1015
  const withIndex = rawParsers.map((p, i) => [p, i]);
675
1016
  const sorted = withIndex.toSorted(([a], [b]) => b.priority - a.priority);
676
1017
  const parsers = sorted.map(([p]) => p);
1018
+ const syncWithIndex = syncRawParsers.map((p, i) => [p, i]);
1019
+ const syncSorted = syncWithIndex.toSorted(([a], [b]) => b.priority - a.priority);
1020
+ const syncParsers = syncSorted.map(([p]) => p);
677
1021
  if (!options.allowDuplicates) checkDuplicateOptionNames(sorted.map(([parser, originalIndex]) => [String(originalIndex), parser.usage]));
678
1022
  const initialState = {};
679
1023
  for (const parser of parsers) if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
1024
+ const extractParserState = (parser, context, index) => {
1025
+ if (parser.initialState === void 0) {
1026
+ const key = `__parser_${index}`;
1027
+ if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
1028
+ return void 0;
1029
+ } else if (parser.initialState && typeof parser.initialState === "object") {
1030
+ if (context.state && typeof context.state === "object") {
1031
+ const extractedState = {};
1032
+ for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
1033
+ return extractedState;
1034
+ }
1035
+ return parser.initialState;
1036
+ }
1037
+ return parser.initialState;
1038
+ };
1039
+ const mergeResultState = (parser, context, result, index) => {
1040
+ if (parser.initialState === void 0) {
1041
+ const key = `__parser_${index}`;
1042
+ if (result.success) {
1043
+ if (result.consumed.length > 0 || result.next.state !== void 0) return {
1044
+ ...context.state,
1045
+ [key]: result.next.state
1046
+ };
1047
+ }
1048
+ return { ...context.state };
1049
+ }
1050
+ return result.success ? {
1051
+ ...context.state,
1052
+ ...result.next.state
1053
+ } : { ...context.state };
1054
+ };
1055
+ const parseSync = (context) => {
1056
+ let currentContext = context;
1057
+ let zeroConsumedSuccess = null;
1058
+ for (let i = 0; i < syncParsers.length; i++) {
1059
+ const parser = syncParsers[i];
1060
+ const parserState = extractParserState(parser, currentContext, i);
1061
+ const result = parser.parse({
1062
+ ...currentContext,
1063
+ state: parserState
1064
+ });
1065
+ if (result.success) {
1066
+ const newState = mergeResultState(parser, currentContext, result, i);
1067
+ const newContext = {
1068
+ ...currentContext,
1069
+ buffer: result.next.buffer,
1070
+ optionsTerminated: result.next.optionsTerminated,
1071
+ state: newState
1072
+ };
1073
+ if (result.consumed.length > 0) return {
1074
+ success: true,
1075
+ next: newContext,
1076
+ consumed: result.consumed
1077
+ };
1078
+ currentContext = newContext;
1079
+ if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
1080
+ context: newContext,
1081
+ consumed: []
1082
+ };
1083
+ else zeroConsumedSuccess.context = newContext;
1084
+ } else if (result.consumed < 1) continue;
1085
+ else return result;
1086
+ }
1087
+ if (zeroConsumedSuccess !== null) return {
1088
+ success: true,
1089
+ next: zeroConsumedSuccess.context,
1090
+ consumed: zeroConsumedSuccess.consumed
1091
+ };
1092
+ return {
1093
+ success: false,
1094
+ consumed: 0,
1095
+ error: require_message.message`No matching option or argument found.`
1096
+ };
1097
+ };
1098
+ const parseAsync = async (context) => {
1099
+ let currentContext = context;
1100
+ let zeroConsumedSuccess = null;
1101
+ for (let i = 0; i < parsers.length; i++) {
1102
+ const parser = parsers[i];
1103
+ const parserState = extractParserState(parser, currentContext, i);
1104
+ const resultOrPromise = parser.parse({
1105
+ ...currentContext,
1106
+ state: parserState
1107
+ });
1108
+ const result = await resultOrPromise;
1109
+ if (result.success) {
1110
+ const newState = mergeResultState(parser, currentContext, result, i);
1111
+ const newContext = {
1112
+ ...currentContext,
1113
+ buffer: result.next.buffer,
1114
+ optionsTerminated: result.next.optionsTerminated,
1115
+ state: newState
1116
+ };
1117
+ if (result.consumed.length > 0) return {
1118
+ success: true,
1119
+ next: newContext,
1120
+ consumed: result.consumed
1121
+ };
1122
+ currentContext = newContext;
1123
+ if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
1124
+ context: newContext,
1125
+ consumed: []
1126
+ };
1127
+ else zeroConsumedSuccess.context = newContext;
1128
+ } else if (result.consumed < 1) continue;
1129
+ else return result;
1130
+ }
1131
+ if (zeroConsumedSuccess !== null) return {
1132
+ success: true,
1133
+ next: zeroConsumedSuccess.context,
1134
+ consumed: zeroConsumedSuccess.consumed
1135
+ };
1136
+ return {
1137
+ success: false,
1138
+ consumed: 0,
1139
+ error: require_message.message`No matching option or argument found.`
1140
+ };
1141
+ };
680
1142
  return {
1143
+ $mode: combinedMode,
681
1144
  $valueType: [],
682
1145
  $stateType: [],
683
1146
  priority: Math.max(...parsers.map((p) => p.priority)),
684
1147
  usage: parsers.flatMap((p) => p.usage),
685
1148
  initialState,
686
1149
  parse(context) {
687
- let zeroConsumedSuccess = null;
688
- for (let i = 0; i < parsers.length; i++) {
689
- const parser = parsers[i];
690
- let parserState;
691
- if (parser.initialState === void 0) {
692
- const key = `__parser_${i}`;
693
- if (context.state && typeof context.state === "object" && key in context.state) parserState = context.state[key];
694
- else parserState = void 0;
695
- } else if (parser.initialState && typeof parser.initialState === "object") if (context.state && typeof context.state === "object") {
696
- const extractedState = {};
697
- for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
698
- parserState = extractedState;
699
- } else parserState = parser.initialState;
700
- else parserState = parser.initialState;
701
- const result = parser.parse({
702
- ...context,
703
- state: parserState
704
- });
705
- if (result.success) {
706
- let newState;
707
- if (parser.initialState === void 0) {
708
- const key = `__parser_${i}`;
709
- if (result.consumed.length > 0 || result.next.state !== void 0) newState = {
710
- ...context.state,
711
- [key]: result.next.state
712
- };
713
- else newState = { ...context.state };
714
- } else newState = {
715
- ...context.state,
716
- ...result.next.state
717
- };
718
- const newContext = {
719
- ...context,
720
- buffer: result.next.buffer,
721
- optionsTerminated: result.next.optionsTerminated,
722
- state: newState
723
- };
724
- if (result.consumed.length > 0) return {
725
- success: true,
726
- next: newContext,
727
- consumed: result.consumed
728
- };
729
- context = newContext;
730
- if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
731
- context: newContext,
732
- consumed: []
733
- };
734
- else zeroConsumedSuccess.context = newContext;
735
- } else if (result.consumed < 1) continue;
736
- else return result;
737
- }
738
- if (zeroConsumedSuccess !== null) return {
739
- success: true,
740
- next: zeroConsumedSuccess.context,
741
- consumed: zeroConsumedSuccess.consumed
742
- };
743
- return {
744
- success: false,
745
- consumed: 0,
746
- error: require_message.message`No matching option or argument found.`
747
- };
1150
+ if (isAsync) return parseAsync(context);
1151
+ return parseSync(context);
748
1152
  },
749
1153
  complete(state) {
750
- const object$1 = {};
751
- for (let i = 0; i < parsers.length; i++) {
752
- const parser = parsers[i];
753
- let parserState;
1154
+ const extractCompleteState = (parser, index) => {
754
1155
  if (parser.initialState === void 0) {
755
- const key = `__parser_${i}`;
756
- if (state && typeof state === "object" && key in state) parserState = state[key];
757
- else parserState = void 0;
758
- } else if (parser.initialState && typeof parser.initialState === "object") if (state && typeof state === "object") {
759
- const extractedState = {};
760
- for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
761
- parserState = extractedState;
762
- } else parserState = parser.initialState;
763
- else parserState = parser.initialState;
764
- const result = parser.complete(parserState);
765
- if (!result.success) return result;
766
- for (const field in result.value) object$1[field] = result.value[field];
767
- }
768
- return {
769
- success: true,
770
- value: object$1
1156
+ const key = `__parser_${index}`;
1157
+ if (state && typeof state === "object" && key in state) return state[key];
1158
+ return void 0;
1159
+ } else if (parser.initialState && typeof parser.initialState === "object") {
1160
+ if (state && typeof state === "object") {
1161
+ const extractedState = {};
1162
+ for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
1163
+ return extractedState;
1164
+ }
1165
+ return parser.initialState;
1166
+ }
1167
+ return parser.initialState;
771
1168
  };
1169
+ if (!isAsync) {
1170
+ const object$1 = {};
1171
+ for (let i = 0; i < syncParsers.length; i++) {
1172
+ const parser = syncParsers[i];
1173
+ const parserState = extractCompleteState(parser, i);
1174
+ const result = parser.complete(parserState);
1175
+ if (!result.success) return result;
1176
+ for (const field in result.value) object$1[field] = result.value[field];
1177
+ }
1178
+ return {
1179
+ success: true,
1180
+ value: object$1
1181
+ };
1182
+ }
1183
+ return (async () => {
1184
+ const object$1 = {};
1185
+ for (let i = 0; i < parsers.length; i++) {
1186
+ const parser = parsers[i];
1187
+ const parserState = extractCompleteState(parser, i);
1188
+ const result = await parser.complete(parserState);
1189
+ if (!result.success) return result;
1190
+ for (const field in result.value) object$1[field] = result.value[field];
1191
+ }
1192
+ return {
1193
+ success: true,
1194
+ value: object$1
1195
+ };
1196
+ })();
772
1197
  },
773
1198
  suggest(context, prefix) {
774
- const suggestions = [];
775
- for (let i = 0; i < parsers.length; i++) {
776
- const parser = parsers[i];
777
- let parserState;
778
- if (parser.initialState === void 0) {
1199
+ const extractState = (p, i) => {
1200
+ if (p.initialState === void 0) {
779
1201
  const key = `__parser_${i}`;
780
- if (context.state && typeof context.state === "object" && key in context.state) parserState = context.state[key];
781
- else parserState = void 0;
782
- } else if (parser.initialState && typeof parser.initialState === "object") if (context.state && typeof context.state === "object") {
783
- const extractedState = {};
784
- for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
785
- parserState = extractedState;
786
- } else parserState = parser.initialState;
787
- else parserState = parser.initialState;
788
- const parserSuggestions = parser.suggest({
789
- ...context,
790
- state: parserState
791
- }, prefix);
792
- suggestions.push(...parserSuggestions);
793
- }
794
- return require_suggestion.deduplicateSuggestions(suggestions);
1202
+ if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
1203
+ return void 0;
1204
+ } else if (p.initialState && typeof p.initialState === "object") {
1205
+ if (context.state && typeof context.state === "object") {
1206
+ const extractedState = {};
1207
+ for (const field in p.initialState) extractedState[field] = field in context.state ? context.state[field] : p.initialState[field];
1208
+ return extractedState;
1209
+ }
1210
+ return p.initialState;
1211
+ }
1212
+ return p.initialState;
1213
+ };
1214
+ if (isAsync) return async function* () {
1215
+ const suggestions = [];
1216
+ for (let i = 0; i < parsers.length; i++) {
1217
+ const parser = parsers[i];
1218
+ const parserState = extractState(parser, i);
1219
+ const parserSuggestions = parser.suggest({
1220
+ ...context,
1221
+ state: parserState
1222
+ }, prefix);
1223
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
1224
+ else suggestions.push(...parserSuggestions);
1225
+ }
1226
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
1227
+ }();
1228
+ return function* () {
1229
+ const suggestions = [];
1230
+ for (let i = 0; i < syncParsers.length; i++) {
1231
+ const parser = syncParsers[i];
1232
+ const parserState = extractState(parser, i);
1233
+ const parserSuggestions = parser.suggest({
1234
+ ...context,
1235
+ state: parserState
1236
+ }, prefix);
1237
+ suggestions.push(...parserSuggestions);
1238
+ }
1239
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
1240
+ }();
795
1241
  },
796
1242
  getDocFragments(state, _defaultValue) {
797
1243
  const fragments = parsers.flatMap((p, i) => {
@@ -838,102 +1284,213 @@ function merge(...args) {
838
1284
  };
839
1285
  }
840
1286
  function concat(...parsers) {
1287
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
1288
+ const isAsync = combinedMode === "async";
1289
+ const syncParsers = parsers;
841
1290
  const initialState = parsers.map((parser) => parser.initialState);
1291
+ const parseSync = (context) => {
1292
+ let currentContext = context;
1293
+ const allConsumed = [];
1294
+ const matchedParsers = /* @__PURE__ */ new Set();
1295
+ while (matchedParsers.size < syncParsers.length) {
1296
+ let foundMatch = false;
1297
+ let error = {
1298
+ consumed: 0,
1299
+ error: require_message.message`No remaining parsers could match the input.`
1300
+ };
1301
+ const stateArray = currentContext.state;
1302
+ const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1303
+ for (const [parser, index] of remainingParsers) {
1304
+ const result = parser.parse({
1305
+ ...currentContext,
1306
+ state: stateArray[index]
1307
+ });
1308
+ if (result.success && result.consumed.length > 0) {
1309
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1310
+ currentContext = {
1311
+ ...currentContext,
1312
+ buffer: result.next.buffer,
1313
+ optionsTerminated: result.next.optionsTerminated,
1314
+ state: newStateArray
1315
+ };
1316
+ allConsumed.push(...result.consumed);
1317
+ matchedParsers.add(index);
1318
+ foundMatch = true;
1319
+ break;
1320
+ } else if (!result.success && error.consumed < result.consumed) error = result;
1321
+ }
1322
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
1323
+ const result = parser.parse({
1324
+ ...currentContext,
1325
+ state: stateArray[index]
1326
+ });
1327
+ if (result.success && result.consumed.length < 1) {
1328
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1329
+ currentContext = {
1330
+ ...currentContext,
1331
+ state: newStateArray
1332
+ };
1333
+ matchedParsers.add(index);
1334
+ foundMatch = true;
1335
+ break;
1336
+ } else if (!result.success && result.consumed < 1) {
1337
+ matchedParsers.add(index);
1338
+ foundMatch = true;
1339
+ break;
1340
+ }
1341
+ }
1342
+ if (!foundMatch) return {
1343
+ ...error,
1344
+ success: false
1345
+ };
1346
+ }
1347
+ return {
1348
+ success: true,
1349
+ next: currentContext,
1350
+ consumed: allConsumed
1351
+ };
1352
+ };
1353
+ const parseAsync = async (context) => {
1354
+ let currentContext = context;
1355
+ const allConsumed = [];
1356
+ const matchedParsers = /* @__PURE__ */ new Set();
1357
+ while (matchedParsers.size < parsers.length) {
1358
+ let foundMatch = false;
1359
+ let error = {
1360
+ consumed: 0,
1361
+ error: require_message.message`No remaining parsers could match the input.`
1362
+ };
1363
+ const stateArray = currentContext.state;
1364
+ const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
1365
+ for (const [parser, index] of remainingParsers) {
1366
+ const result = await parser.parse({
1367
+ ...currentContext,
1368
+ state: stateArray[index]
1369
+ });
1370
+ if (result.success && result.consumed.length > 0) {
1371
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1372
+ currentContext = {
1373
+ ...currentContext,
1374
+ buffer: result.next.buffer,
1375
+ optionsTerminated: result.next.optionsTerminated,
1376
+ state: newStateArray
1377
+ };
1378
+ allConsumed.push(...result.consumed);
1379
+ matchedParsers.add(index);
1380
+ foundMatch = true;
1381
+ break;
1382
+ } else if (!result.success && error.consumed < result.consumed) error = result;
1383
+ }
1384
+ if (!foundMatch) for (const [parser, index] of remainingParsers) {
1385
+ const result = await parser.parse({
1386
+ ...currentContext,
1387
+ state: stateArray[index]
1388
+ });
1389
+ if (result.success && result.consumed.length < 1) {
1390
+ const newStateArray = stateArray.map((s, idx) => idx === index ? result.next.state : s);
1391
+ currentContext = {
1392
+ ...currentContext,
1393
+ state: newStateArray
1394
+ };
1395
+ matchedParsers.add(index);
1396
+ foundMatch = true;
1397
+ break;
1398
+ } else if (!result.success && result.consumed < 1) {
1399
+ matchedParsers.add(index);
1400
+ foundMatch = true;
1401
+ break;
1402
+ }
1403
+ }
1404
+ if (!foundMatch) return {
1405
+ ...error,
1406
+ success: false
1407
+ };
1408
+ }
1409
+ return {
1410
+ success: true,
1411
+ next: currentContext,
1412
+ consumed: allConsumed
1413
+ };
1414
+ };
1415
+ const completeSync = (state) => {
1416
+ const results = [];
1417
+ const stateArray = state;
1418
+ for (let i = 0; i < syncParsers.length; i++) {
1419
+ const parser = syncParsers[i];
1420
+ const parserState = stateArray[i];
1421
+ const result = parser.complete(parserState);
1422
+ if (!result.success) return result;
1423
+ if (Array.isArray(result.value)) results.push(...result.value);
1424
+ else results.push(result.value);
1425
+ }
1426
+ return {
1427
+ success: true,
1428
+ value: results
1429
+ };
1430
+ };
1431
+ const completeAsync = async (state) => {
1432
+ const results = [];
1433
+ const stateArray = state;
1434
+ for (let i = 0; i < parsers.length; i++) {
1435
+ const parser = parsers[i];
1436
+ const parserState = stateArray[i];
1437
+ const result = await parser.complete(parserState);
1438
+ if (!result.success) return result;
1439
+ if (Array.isArray(result.value)) results.push(...result.value);
1440
+ else results.push(result.value);
1441
+ }
1442
+ return {
1443
+ success: true,
1444
+ value: results
1445
+ };
1446
+ };
842
1447
  return {
1448
+ $mode: combinedMode,
843
1449
  $valueType: [],
844
1450
  $stateType: [],
845
1451
  priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
846
1452
  usage: parsers.flatMap((p) => p.usage),
847
1453
  initialState,
848
1454
  parse(context) {
849
- let currentContext = context;
850
- const allConsumed = [];
851
- const matchedParsers = /* @__PURE__ */ new Set();
852
- while (matchedParsers.size < parsers.length) {
853
- let foundMatch = false;
854
- let error = {
855
- consumed: 0,
856
- error: require_message.message`No remaining parsers could match the input.`
857
- };
858
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
859
- for (const [parser, index] of remainingParsers) {
860
- const result = parser.parse({
861
- ...currentContext,
862
- state: currentContext.state[index]
863
- });
864
- if (result.success && result.consumed.length > 0) {
865
- currentContext = {
866
- ...currentContext,
867
- buffer: result.next.buffer,
868
- optionsTerminated: result.next.optionsTerminated,
869
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
870
- };
871
- allConsumed.push(...result.consumed);
872
- matchedParsers.add(index);
873
- foundMatch = true;
874
- break;
875
- } else if (!result.success && error.consumed < result.consumed) error = result;
876
- }
877
- if (!foundMatch) for (const [parser, index] of remainingParsers) {
878
- const result = parser.parse({
879
- ...currentContext,
880
- state: currentContext.state[index]
881
- });
882
- if (result.success && result.consumed.length < 1) {
883
- currentContext = {
884
- ...currentContext,
885
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
886
- };
887
- matchedParsers.add(index);
888
- foundMatch = true;
889
- break;
890
- } else if (!result.success && result.consumed < 1) {
891
- matchedParsers.add(index);
892
- foundMatch = true;
893
- break;
894
- }
895
- }
896
- if (!foundMatch) return {
897
- ...error,
898
- success: false
899
- };
900
- }
901
- return {
902
- success: true,
903
- next: currentContext,
904
- consumed: allConsumed
905
- };
1455
+ if (isAsync) return parseAsync(context);
1456
+ return parseSync(context);
906
1457
  },
907
1458
  complete(state) {
908
- const results = [];
909
- for (let i = 0; i < parsers.length; i++) {
910
- const parser = parsers[i];
911
- const parserState = state[i];
912
- const result = parser.complete(parserState);
913
- if (!result.success) return result;
914
- if (Array.isArray(result.value)) results.push(...result.value);
915
- else results.push(result.value);
916
- }
917
- return {
918
- success: true,
919
- value: results
920
- };
1459
+ if (isAsync) return completeAsync(state);
1460
+ return completeSync(state);
921
1461
  },
922
1462
  suggest(context, prefix) {
923
- const suggestions = [];
924
- for (let i = 0; i < parsers.length; i++) {
925
- const parser = parsers[i];
926
- const parserState = context.state && Array.isArray(context.state) ? context.state[i] : parser.initialState;
927
- const parserSuggestions = parser.suggest({
928
- ...context,
929
- state: parserState
930
- }, prefix);
931
- suggestions.push(...parserSuggestions);
932
- }
933
- return require_suggestion.deduplicateSuggestions(suggestions);
1463
+ const stateArray = context.state;
1464
+ if (isAsync) return async function* () {
1465
+ const suggestions = [];
1466
+ for (let i = 0; i < parsers.length; i++) {
1467
+ const parser = parsers[i];
1468
+ const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
1469
+ const parserSuggestions = parser.suggest({
1470
+ ...context,
1471
+ state: parserState
1472
+ }, prefix);
1473
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
1474
+ else suggestions.push(...parserSuggestions);
1475
+ }
1476
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
1477
+ }();
1478
+ return function* () {
1479
+ const suggestions = [];
1480
+ for (let i = 0; i < syncParsers.length; i++) {
1481
+ const parser = syncParsers[i];
1482
+ const parserState = stateArray && Array.isArray(stateArray) ? stateArray[i] : parser.initialState;
1483
+ const parserSuggestions = parser.suggest({
1484
+ ...context,
1485
+ state: parserState
1486
+ }, prefix);
1487
+ suggestions.push(...parserSuggestions);
1488
+ }
1489
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
1490
+ }();
934
1491
  },
935
1492
  getDocFragments(state, _defaultValue) {
936
- const fragments = parsers.flatMap((p, index) => {
1493
+ const fragments = syncParsers.flatMap((p, index) => {
937
1494
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
938
1495
  kind: "available",
939
1496
  state: state.state[index]
@@ -1003,6 +1560,7 @@ function concat(...parsers) {
1003
1560
  */
1004
1561
  function group(label, parser) {
1005
1562
  return {
1563
+ $mode: parser.$mode,
1006
1564
  $valueType: parser.$valueType,
1007
1565
  $stateType: parser.$stateType,
1008
1566
  priority: parser.priority,
@@ -1068,6 +1626,8 @@ function group(label, parser) {
1068
1626
  function conditional(discriminator, branches, defaultBranch, options) {
1069
1627
  const branchParsers = Object.entries(branches);
1070
1628
  const allBranchParsers = defaultBranch ? [...branchParsers.map(([_, p]) => p), defaultBranch] : branchParsers.map(([_, p]) => p);
1629
+ const combinedMode = discriminator.$mode === "async" || allBranchParsers.some((p) => p.$mode === "async") ? "async" : "sync";
1630
+ const isAsync = combinedMode === "async";
1071
1631
  const maxPriority = Math.max(discriminator.priority, ...allBranchParsers.map((p) => p.priority));
1072
1632
  function appendLiteralToUsage(usage$1, literalValue) {
1073
1633
  const result = [];
@@ -1105,164 +1665,334 @@ function conditional(discriminator, branches, defaultBranch, options) {
1105
1665
  selectedBranch: void 0,
1106
1666
  branchState: void 0
1107
1667
  };
1108
- return {
1109
- $valueType: [],
1110
- $stateType: [],
1111
- priority: maxPriority,
1112
- usage,
1113
- initialState,
1114
- parse(context) {
1115
- const state = context.state ?? initialState;
1116
- if (state.selectedBranch !== void 0) {
1117
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1118
- const branchResult = branchParser.parse({
1119
- ...context,
1120
- state: state.branchState,
1121
- usage: branchParser.usage
1122
- });
1123
- if (branchResult.success) return {
1124
- success: true,
1125
- next: {
1126
- ...branchResult.next,
1127
- state: {
1128
- ...state,
1129
- branchState: branchResult.next.state
1130
- }
1131
- },
1132
- consumed: branchResult.consumed
1133
- };
1134
- return branchResult;
1135
- }
1136
- const discriminatorResult = discriminator.parse({
1668
+ const getNoMatchError$1 = () => {
1669
+ const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
1670
+ return options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
1671
+ };
1672
+ const parseSync = (context) => {
1673
+ const state = context.state ?? initialState;
1674
+ const syncDiscriminator = discriminator;
1675
+ const syncBranches = branches;
1676
+ const syncDefaultBranch = defaultBranch;
1677
+ if (state.selectedBranch !== void 0) {
1678
+ const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
1679
+ const branchResult = branchParser.parse({
1137
1680
  ...context,
1138
- state: state.discriminatorState
1681
+ state: state.branchState,
1682
+ usage: branchParser.usage
1139
1683
  });
1140
- if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
1141
- const completionResult = discriminator.complete(discriminatorResult.next.state);
1142
- if (completionResult.success) {
1143
- const value = completionResult.value;
1144
- const branchParser = branches[value];
1145
- if (branchParser) {
1146
- const branchParseResult = branchParser.parse({
1147
- ...context,
1148
- buffer: discriminatorResult.next.buffer,
1149
- optionsTerminated: discriminatorResult.next.optionsTerminated,
1150
- state: branchParser.initialState,
1151
- usage: branchParser.usage
1152
- });
1153
- if (branchParseResult.success) return {
1154
- success: true,
1155
- next: {
1156
- ...branchParseResult.next,
1157
- state: {
1158
- discriminatorState: discriminatorResult.next.state,
1159
- discriminatorValue: value,
1160
- selectedBranch: {
1161
- kind: "branch",
1162
- key: value
1163
- },
1164
- branchState: branchParseResult.next.state
1165
- }
1166
- },
1167
- consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
1168
- };
1169
- return {
1170
- success: true,
1171
- next: {
1172
- ...discriminatorResult.next,
1173
- state: {
1174
- discriminatorState: discriminatorResult.next.state,
1175
- discriminatorValue: value,
1176
- selectedBranch: {
1177
- kind: "branch",
1178
- key: value
1179
- },
1180
- branchState: branchParser.initialState
1181
- }
1182
- },
1183
- consumed: discriminatorResult.consumed
1184
- };
1684
+ if (branchResult.success) return {
1685
+ success: true,
1686
+ next: {
1687
+ ...branchResult.next,
1688
+ state: {
1689
+ ...state,
1690
+ branchState: branchResult.next.state
1185
1691
  }
1692
+ },
1693
+ consumed: branchResult.consumed
1694
+ };
1695
+ return branchResult;
1696
+ }
1697
+ const discriminatorResult = syncDiscriminator.parse({
1698
+ ...context,
1699
+ state: state.discriminatorState
1700
+ });
1701
+ if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
1702
+ const completionResult = syncDiscriminator.complete(discriminatorResult.next.state);
1703
+ if (completionResult.success) {
1704
+ const value = completionResult.value;
1705
+ const branchParser = syncBranches[value];
1706
+ if (branchParser) {
1707
+ const branchParseResult = branchParser.parse({
1708
+ ...context,
1709
+ buffer: discriminatorResult.next.buffer,
1710
+ optionsTerminated: discriminatorResult.next.optionsTerminated,
1711
+ state: branchParser.initialState,
1712
+ usage: branchParser.usage
1713
+ });
1714
+ if (branchParseResult.success) return {
1715
+ success: true,
1716
+ next: {
1717
+ ...branchParseResult.next,
1718
+ state: {
1719
+ discriminatorState: discriminatorResult.next.state,
1720
+ discriminatorValue: value,
1721
+ selectedBranch: {
1722
+ kind: "branch",
1723
+ key: value
1724
+ },
1725
+ branchState: branchParseResult.next.state
1726
+ }
1727
+ },
1728
+ consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
1729
+ };
1730
+ return {
1731
+ success: true,
1732
+ next: {
1733
+ ...discriminatorResult.next,
1734
+ state: {
1735
+ discriminatorState: discriminatorResult.next.state,
1736
+ discriminatorValue: value,
1737
+ selectedBranch: {
1738
+ kind: "branch",
1739
+ key: value
1740
+ },
1741
+ branchState: branchParser.initialState
1742
+ }
1743
+ },
1744
+ consumed: discriminatorResult.consumed
1745
+ };
1186
1746
  }
1187
1747
  }
1188
- if (defaultBranch !== void 0) {
1189
- const defaultResult = defaultBranch.parse({
1190
- ...context,
1191
- state: state.branchState ?? defaultBranch.initialState,
1192
- usage: defaultBranch.usage
1193
- });
1194
- if (defaultResult.success && defaultResult.consumed.length > 0) return {
1195
- success: true,
1196
- next: {
1197
- ...defaultResult.next,
1198
- state: {
1199
- ...state,
1200
- selectedBranch: { kind: "default" },
1201
- branchState: defaultResult.next.state
1202
- }
1203
- },
1204
- consumed: defaultResult.consumed
1205
- };
1206
- }
1207
- const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
1208
- const errorMessage = options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
1209
- return {
1210
- success: false,
1211
- consumed: 0,
1212
- error: errorMessage
1748
+ }
1749
+ if (syncDefaultBranch !== void 0) {
1750
+ const defaultResult = syncDefaultBranch.parse({
1751
+ ...context,
1752
+ state: state.branchState ?? syncDefaultBranch.initialState,
1753
+ usage: syncDefaultBranch.usage
1754
+ });
1755
+ if (defaultResult.success && defaultResult.consumed.length > 0) return {
1756
+ success: true,
1757
+ next: {
1758
+ ...defaultResult.next,
1759
+ state: {
1760
+ ...state,
1761
+ selectedBranch: { kind: "default" },
1762
+ branchState: defaultResult.next.state
1763
+ }
1764
+ },
1765
+ consumed: defaultResult.consumed
1213
1766
  };
1214
- },
1215
- complete(state) {
1216
- if (state.selectedBranch === void 0) {
1217
- if (defaultBranch !== void 0) {
1218
- const branchState = state.branchState ?? defaultBranch.initialState;
1219
- const defaultResult = defaultBranch.complete(branchState);
1220
- if (!defaultResult.success) return defaultResult;
1767
+ }
1768
+ return {
1769
+ success: false,
1770
+ consumed: 0,
1771
+ error: getNoMatchError$1()
1772
+ };
1773
+ };
1774
+ const parseAsync = async (context) => {
1775
+ const state = context.state ?? initialState;
1776
+ if (state.selectedBranch !== void 0) {
1777
+ const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1778
+ const branchResult = await branchParser.parse({
1779
+ ...context,
1780
+ state: state.branchState,
1781
+ usage: branchParser.usage
1782
+ });
1783
+ if (branchResult.success) return {
1784
+ success: true,
1785
+ next: {
1786
+ ...branchResult.next,
1787
+ state: {
1788
+ ...state,
1789
+ branchState: branchResult.next.state
1790
+ }
1791
+ },
1792
+ consumed: branchResult.consumed
1793
+ };
1794
+ return branchResult;
1795
+ }
1796
+ const discriminatorResult = await discriminator.parse({
1797
+ ...context,
1798
+ state: state.discriminatorState
1799
+ });
1800
+ if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
1801
+ const completionResult = await discriminator.complete(discriminatorResult.next.state);
1802
+ if (completionResult.success) {
1803
+ const value = completionResult.value;
1804
+ const branchParser = branches[value];
1805
+ if (branchParser) {
1806
+ const branchParseResult = await branchParser.parse({
1807
+ ...context,
1808
+ buffer: discriminatorResult.next.buffer,
1809
+ optionsTerminated: discriminatorResult.next.optionsTerminated,
1810
+ state: branchParser.initialState,
1811
+ usage: branchParser.usage
1812
+ });
1813
+ if (branchParseResult.success) return {
1814
+ success: true,
1815
+ next: {
1816
+ ...branchParseResult.next,
1817
+ state: {
1818
+ discriminatorState: discriminatorResult.next.state,
1819
+ discriminatorValue: value,
1820
+ selectedBranch: {
1821
+ kind: "branch",
1822
+ key: value
1823
+ },
1824
+ branchState: branchParseResult.next.state
1825
+ }
1826
+ },
1827
+ consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
1828
+ };
1221
1829
  return {
1222
1830
  success: true,
1223
- value: [void 0, defaultResult.value]
1831
+ next: {
1832
+ ...discriminatorResult.next,
1833
+ state: {
1834
+ discriminatorState: discriminatorResult.next.state,
1835
+ discriminatorValue: value,
1836
+ selectedBranch: {
1837
+ kind: "branch",
1838
+ key: value
1839
+ },
1840
+ branchState: branchParser.initialState
1841
+ }
1842
+ },
1843
+ consumed: discriminatorResult.consumed
1224
1844
  };
1225
1845
  }
1846
+ }
1847
+ }
1848
+ if (defaultBranch !== void 0) {
1849
+ const defaultResult = await defaultBranch.parse({
1850
+ ...context,
1851
+ state: state.branchState ?? defaultBranch.initialState,
1852
+ usage: defaultBranch.usage
1853
+ });
1854
+ if (defaultResult.success && defaultResult.consumed.length > 0) return {
1855
+ success: true,
1856
+ next: {
1857
+ ...defaultResult.next,
1858
+ state: {
1859
+ ...state,
1860
+ selectedBranch: { kind: "default" },
1861
+ branchState: defaultResult.next.state
1862
+ }
1863
+ },
1864
+ consumed: defaultResult.consumed
1865
+ };
1866
+ }
1867
+ return {
1868
+ success: false,
1869
+ consumed: 0,
1870
+ error: getNoMatchError$1()
1871
+ };
1872
+ };
1873
+ const completeSync = (state) => {
1874
+ const syncDefaultBranch = defaultBranch;
1875
+ const syncBranches = branches;
1876
+ if (state.selectedBranch === void 0) {
1877
+ if (syncDefaultBranch !== void 0) {
1878
+ const branchState = state.branchState ?? syncDefaultBranch.initialState;
1879
+ const defaultResult = syncDefaultBranch.complete(branchState);
1880
+ if (!defaultResult.success) return defaultResult;
1226
1881
  return {
1227
- success: false,
1228
- error: require_message.message`Missing required discriminator option.`
1882
+ success: true,
1883
+ value: [void 0, defaultResult.value]
1229
1884
  };
1230
1885
  }
1231
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1232
- const branchResult = branchParser.complete(state.branchState);
1233
- if (!branchResult.success) {
1234
- if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
1235
- success: false,
1236
- error: options.errors.branchError(state.discriminatorValue, branchResult.error)
1886
+ return {
1887
+ success: false,
1888
+ error: require_message.message`Missing required discriminator option.`
1889
+ };
1890
+ }
1891
+ const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
1892
+ const branchResult = branchParser.complete(state.branchState);
1893
+ if (!branchResult.success) {
1894
+ if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
1895
+ success: false,
1896
+ error: options.errors.branchError(state.discriminatorValue, branchResult.error)
1897
+ };
1898
+ return branchResult;
1899
+ }
1900
+ const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
1901
+ return {
1902
+ success: true,
1903
+ value: [discriminatorValue, branchResult.value]
1904
+ };
1905
+ };
1906
+ const completeAsync = async (state) => {
1907
+ if (state.selectedBranch === void 0) {
1908
+ if (defaultBranch !== void 0) {
1909
+ const branchState = state.branchState ?? defaultBranch.initialState;
1910
+ const defaultResult = await defaultBranch.complete(branchState);
1911
+ if (!defaultResult.success) return defaultResult;
1912
+ return {
1913
+ success: true,
1914
+ value: [void 0, defaultResult.value]
1237
1915
  };
1238
- return branchResult;
1239
1916
  }
1240
- const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
1241
1917
  return {
1242
- success: true,
1243
- value: [discriminatorValue, branchResult.value]
1918
+ success: false,
1919
+ error: require_message.message`Missing required discriminator option.`
1244
1920
  };
1921
+ }
1922
+ const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1923
+ const branchResult = await branchParser.complete(state.branchState);
1924
+ if (!branchResult.success) {
1925
+ if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
1926
+ success: false,
1927
+ error: options.errors.branchError(state.discriminatorValue, branchResult.error)
1928
+ };
1929
+ return branchResult;
1930
+ }
1931
+ const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
1932
+ return {
1933
+ success: true,
1934
+ value: [discriminatorValue, branchResult.value]
1935
+ };
1936
+ };
1937
+ function* suggestSync(context, prefix) {
1938
+ const state = context.state ?? initialState;
1939
+ const syncDiscriminator = discriminator;
1940
+ const syncBranches = branches;
1941
+ const syncDefaultBranch = defaultBranch;
1942
+ if (state.selectedBranch === void 0) {
1943
+ yield* syncDiscriminator.suggest({
1944
+ ...context,
1945
+ state: state.discriminatorState
1946
+ }, prefix);
1947
+ if (syncDefaultBranch !== void 0) yield* syncDefaultBranch.suggest({
1948
+ ...context,
1949
+ state: state.branchState ?? syncDefaultBranch.initialState
1950
+ }, prefix);
1951
+ } else {
1952
+ const branchParser = state.selectedBranch.kind === "default" ? syncDefaultBranch : syncBranches[state.selectedBranch.key];
1953
+ yield* branchParser.suggest({
1954
+ ...context,
1955
+ state: state.branchState
1956
+ }, prefix);
1957
+ }
1958
+ }
1959
+ async function* suggestAsync(context, prefix) {
1960
+ const state = context.state ?? initialState;
1961
+ if (state.selectedBranch === void 0) {
1962
+ yield* discriminator.suggest({
1963
+ ...context,
1964
+ state: state.discriminatorState
1965
+ }, prefix);
1966
+ if (defaultBranch !== void 0) yield* defaultBranch.suggest({
1967
+ ...context,
1968
+ state: state.branchState ?? defaultBranch.initialState
1969
+ }, prefix);
1970
+ } else {
1971
+ const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1972
+ yield* branchParser.suggest({
1973
+ ...context,
1974
+ state: state.branchState
1975
+ }, prefix);
1976
+ }
1977
+ }
1978
+ return {
1979
+ $mode: combinedMode,
1980
+ $valueType: [],
1981
+ $stateType: [],
1982
+ priority: maxPriority,
1983
+ usage,
1984
+ initialState,
1985
+ parse(context) {
1986
+ if (isAsync) return parseAsync(context);
1987
+ return parseSync(context);
1988
+ },
1989
+ complete(state) {
1990
+ if (isAsync) return completeAsync(state);
1991
+ return completeSync(state);
1245
1992
  },
1246
1993
  suggest(context, prefix) {
1247
- const state = context.state ?? initialState;
1248
- const suggestions = [];
1249
- if (state.selectedBranch === void 0) {
1250
- suggestions.push(...discriminator.suggest({
1251
- ...context,
1252
- state: state.discriminatorState
1253
- }, prefix));
1254
- if (defaultBranch !== void 0) suggestions.push(...defaultBranch.suggest({
1255
- ...context,
1256
- state: state.branchState ?? defaultBranch.initialState
1257
- }, prefix));
1258
- } else {
1259
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1260
- suggestions.push(...branchParser.suggest({
1261
- ...context,
1262
- state: state.branchState
1263
- }, prefix));
1264
- }
1265
- return require_suggestion.deduplicateSuggestions(suggestions);
1994
+ if (isAsync) return suggestAsync(context, prefix);
1995
+ return suggestSync(context, prefix);
1266
1996
  },
1267
1997
  getDocFragments(_state, _defaultValue) {
1268
1998
  const fragments = [];