@optique/core 0.9.0-dev.201 → 0.9.0-dev.204

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.
@@ -116,45 +116,79 @@ function generateNoMatchError(context) {
116
116
  * Creates a complete() method shared by or() and longestMatch().
117
117
  * @internal
118
118
  */
119
- function createExclusiveComplete(parsers, options, noMatchContext) {
119
+ function createExclusiveComplete(parsers, options, noMatchContext, isAsync) {
120
+ const syncParsers = parsers;
120
121
  return (state) => {
121
122
  if (state == null) return {
122
123
  success: false,
123
124
  error: getNoMatchError(options, noMatchContext)
124
125
  };
125
126
  const [i, result] = state;
126
- if (result.success) return parsers[i].complete(result.next.state);
127
- return {
127
+ if (!result.success) return {
128
128
  success: false,
129
129
  error: result.error
130
130
  };
131
+ if (isAsync) return (async () => {
132
+ const completeResult = await parsers[i].complete(result.next.state);
133
+ return completeResult;
134
+ })();
135
+ return syncParsers[i].complete(result.next.state);
131
136
  };
132
137
  }
133
138
  /**
134
139
  * Creates a suggest() method shared by or() and longestMatch().
135
140
  * @internal
136
141
  */
137
- function createExclusiveSuggest(parsers) {
142
+ function createExclusiveSuggest(parsers, isAsync) {
143
+ const syncParsers = parsers;
144
+ if (isAsync) return (context, prefix) => {
145
+ return async function* () {
146
+ const suggestions = [];
147
+ if (context.state == null) for (const parser of parsers) {
148
+ const parserSuggestions = parser.suggest({
149
+ ...context,
150
+ state: parser.initialState
151
+ }, prefix);
152
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
153
+ else suggestions.push(...parserSuggestions);
154
+ }
155
+ else {
156
+ const [index, parserResult] = context.state;
157
+ if (parserResult.success) {
158
+ const parser = parsers[index];
159
+ const parserSuggestions = parser.suggest({
160
+ ...context,
161
+ state: parserResult.next.state
162
+ }, prefix);
163
+ if (parser.$mode === "async") for await (const s of parserSuggestions) suggestions.push(s);
164
+ else suggestions.push(...parserSuggestions);
165
+ }
166
+ }
167
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
168
+ }();
169
+ };
138
170
  return (context, prefix) => {
139
- const suggestions = [];
140
- if (context.state == null) for (const parser of parsers) {
141
- const parserSuggestions = parser.suggest({
142
- ...context,
143
- state: parser.initialState
144
- }, prefix);
145
- suggestions.push(...parserSuggestions);
146
- }
147
- else {
148
- const [index, parserResult] = context.state;
149
- if (parserResult.success) {
150
- const parserSuggestions = parsers[index].suggest({
171
+ return function* () {
172
+ const suggestions = [];
173
+ if (context.state == null) for (const parser of syncParsers) {
174
+ const parserSuggestions = parser.suggest({
151
175
  ...context,
152
- state: parserResult.next.state
176
+ state: parser.initialState
153
177
  }, prefix);
154
178
  suggestions.push(...parserSuggestions);
155
179
  }
156
- }
157
- return require_suggestion.deduplicateSuggestions(suggestions);
180
+ else {
181
+ const [index, parserResult] = context.state;
182
+ if (parserResult.success) {
183
+ const parserSuggestions = syncParsers[index].suggest({
184
+ ...context,
185
+ state: parserResult.next.state
186
+ }, prefix);
187
+ suggestions.push(...parserSuggestions);
188
+ }
189
+ }
190
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
191
+ }();
158
192
  };
159
193
  }
160
194
  /**
@@ -190,7 +224,80 @@ function or(...args) {
190
224
  options = void 0;
191
225
  }
192
226
  const noMatchContext = analyzeNoMatchContext(parsers);
227
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
228
+ const isAsync = combinedMode === "async";
229
+ const syncParsers = parsers;
230
+ const getInitialError = (context) => ({
231
+ consumed: 0,
232
+ error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
233
+ });
234
+ const parseSync = (context) => {
235
+ let error = getInitialError(context);
236
+ const orderedParsers = syncParsers.map((p, i) => [p, i]);
237
+ orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
238
+ for (const [parser, i] of orderedParsers) {
239
+ const result = parser.parse({
240
+ ...context,
241
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
242
+ });
243
+ if (result.success && result.consumed.length > 0) {
244
+ if (context.state?.[0] !== i && context.state?.[1].success) return {
245
+ success: false,
246
+ consumed: context.buffer.length - result.next.buffer.length,
247
+ error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
248
+ };
249
+ return {
250
+ success: true,
251
+ next: {
252
+ ...context,
253
+ buffer: result.next.buffer,
254
+ optionsTerminated: result.next.optionsTerminated,
255
+ state: [i, result]
256
+ },
257
+ consumed: result.consumed
258
+ };
259
+ } else if (!result.success && error.consumed < result.consumed) error = result;
260
+ }
261
+ return {
262
+ ...error,
263
+ success: false
264
+ };
265
+ };
266
+ const parseAsync = async (context) => {
267
+ let error = getInitialError(context);
268
+ const orderedParsers = parsers.map((p, i) => [p, i]);
269
+ orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
270
+ for (const [parser, i] of orderedParsers) {
271
+ const resultOrPromise = parser.parse({
272
+ ...context,
273
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
274
+ });
275
+ const result = await resultOrPromise;
276
+ if (result.success && result.consumed.length > 0) {
277
+ if (context.state?.[0] !== i && context.state?.[1].success) return {
278
+ success: false,
279
+ consumed: context.buffer.length - result.next.buffer.length,
280
+ error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
281
+ };
282
+ return {
283
+ success: true,
284
+ next: {
285
+ ...context,
286
+ buffer: result.next.buffer,
287
+ optionsTerminated: result.next.optionsTerminated,
288
+ state: [i, result]
289
+ },
290
+ consumed: result.consumed
291
+ };
292
+ } else if (!result.success && error.consumed < result.consumed) error = result;
293
+ }
294
+ return {
295
+ ...error,
296
+ success: false
297
+ };
298
+ };
193
299
  return {
300
+ $mode: combinedMode,
194
301
  $valueType: [],
195
302
  $stateType: [],
196
303
  priority: Math.max(...parsers.map((p) => p.priority)),
@@ -199,43 +306,12 @@ function or(...args) {
199
306
  terms: parsers.map((p) => p.usage)
200
307
  }],
201
308
  initialState: void 0,
202
- complete: createExclusiveComplete(parsers, options, noMatchContext),
309
+ complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
203
310
  parse(context) {
204
- let error = {
205
- consumed: 0,
206
- error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
207
- };
208
- const orderedParsers = parsers.map((p, i) => [p, i]);
209
- orderedParsers.sort(([_, a], [__, b]) => context.state?.[0] === a ? -1 : context.state?.[0] === b ? 1 : a - b);
210
- for (const [parser, i] of orderedParsers) {
211
- const result = parser.parse({
212
- ...context,
213
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
214
- });
215
- if (result.success && result.consumed.length > 0) {
216
- if (context.state?.[0] !== i && context.state?.[1].success) return {
217
- success: false,
218
- consumed: context.buffer.length - result.next.buffer.length,
219
- error: require_message.message`${require_message.values(context.state[1].consumed)} and ${require_message.values(result.consumed)} cannot be used together.`
220
- };
221
- return {
222
- success: true,
223
- next: {
224
- ...context,
225
- buffer: result.next.buffer,
226
- optionsTerminated: result.next.optionsTerminated,
227
- state: [i, result]
228
- },
229
- consumed: result.consumed
230
- };
231
- } else if (!result.success && error.consumed < result.consumed) error = result;
232
- }
233
- return {
234
- ...error,
235
- success: false
236
- };
311
+ if (isAsync) return parseAsync(context);
312
+ return parseSync(context);
237
313
  },
238
- suggest: createExclusiveSuggest(parsers),
314
+ suggest: createExclusiveSuggest(parsers, isAsync),
239
315
  getDocFragments(state, _defaultValue) {
240
316
  let description;
241
317
  let fragments;
@@ -284,7 +360,82 @@ function longestMatch(...args) {
284
360
  options = void 0;
285
361
  }
286
362
  const noMatchContext = analyzeNoMatchContext(parsers);
363
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
364
+ const isAsync = combinedMode === "async";
365
+ const syncParsers = parsers;
366
+ const getInitialError = (context) => ({
367
+ consumed: 0,
368
+ error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
369
+ });
370
+ const parseSync = (context) => {
371
+ let bestMatch = null;
372
+ let error = getInitialError(context);
373
+ for (let i = 0; i < syncParsers.length; i++) {
374
+ const parser = syncParsers[i];
375
+ const result = parser.parse({
376
+ ...context,
377
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
378
+ });
379
+ if (result.success) {
380
+ const consumed = context.buffer.length - result.next.buffer.length;
381
+ if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
382
+ index: i,
383
+ result,
384
+ consumed
385
+ };
386
+ } else if (error.consumed < result.consumed) error = result;
387
+ }
388
+ if (bestMatch && bestMatch.result.success) return {
389
+ success: true,
390
+ next: {
391
+ ...context,
392
+ buffer: bestMatch.result.next.buffer,
393
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
394
+ state: [bestMatch.index, bestMatch.result]
395
+ },
396
+ consumed: bestMatch.result.consumed
397
+ };
398
+ return {
399
+ ...error,
400
+ success: false
401
+ };
402
+ };
403
+ const parseAsync = async (context) => {
404
+ let bestMatch = null;
405
+ let error = getInitialError(context);
406
+ for (let i = 0; i < parsers.length; i++) {
407
+ const parser = parsers[i];
408
+ const resultOrPromise = parser.parse({
409
+ ...context,
410
+ state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
411
+ });
412
+ const result = await resultOrPromise;
413
+ if (result.success) {
414
+ const consumed = context.buffer.length - result.next.buffer.length;
415
+ if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
416
+ index: i,
417
+ result,
418
+ consumed
419
+ };
420
+ } else if (error.consumed < result.consumed) error = result;
421
+ }
422
+ if (bestMatch && bestMatch.result.success) return {
423
+ success: true,
424
+ next: {
425
+ ...context,
426
+ buffer: bestMatch.result.next.buffer,
427
+ optionsTerminated: bestMatch.result.next.optionsTerminated,
428
+ state: [bestMatch.index, bestMatch.result]
429
+ },
430
+ consumed: bestMatch.result.consumed
431
+ };
432
+ return {
433
+ ...error,
434
+ success: false
435
+ };
436
+ };
287
437
  return {
438
+ $mode: combinedMode,
288
439
  $valueType: [],
289
440
  $stateType: [],
290
441
  priority: Math.max(...parsers.map((p) => p.priority)),
@@ -293,44 +444,12 @@ function longestMatch(...args) {
293
444
  terms: parsers.map((p) => p.usage)
294
445
  }],
295
446
  initialState: void 0,
296
- complete: createExclusiveComplete(parsers, options, noMatchContext),
447
+ complete: createExclusiveComplete(parsers, options, noMatchContext, isAsync),
297
448
  parse(context) {
298
- let bestMatch = null;
299
- let error = {
300
- consumed: 0,
301
- error: context.buffer.length < 1 ? getNoMatchError(options, noMatchContext) : createUnexpectedInputError(context.buffer[0], context.usage, options)
302
- };
303
- for (let i = 0; i < parsers.length; i++) {
304
- const parser = parsers[i];
305
- const result = parser.parse({
306
- ...context,
307
- state: context.state == null || context.state[0] !== i || !context.state[1].success ? parser.initialState : context.state[1].next.state
308
- });
309
- if (result.success) {
310
- const consumed = context.buffer.length - result.next.buffer.length;
311
- if (bestMatch === null || consumed > bestMatch.consumed) bestMatch = {
312
- index: i,
313
- result,
314
- consumed
315
- };
316
- } else if (error.consumed < result.consumed) error = result;
317
- }
318
- if (bestMatch && bestMatch.result.success) return {
319
- success: true,
320
- next: {
321
- ...context,
322
- buffer: bestMatch.result.next.buffer,
323
- optionsTerminated: bestMatch.result.next.optionsTerminated,
324
- state: [bestMatch.index, bestMatch.result]
325
- },
326
- consumed: bestMatch.result.consumed
327
- };
328
- return {
329
- ...error,
330
- success: false
331
- };
449
+ if (isAsync) return parseAsync(context);
450
+ return parseSync(context);
332
451
  },
333
- suggest: createExclusiveSuggest(parsers),
452
+ suggest: createExclusiveSuggest(parsers, isAsync),
334
453
  getDocFragments(state, _defaultValue) {
335
454
  let description;
336
455
  let footer;
@@ -356,6 +475,61 @@ function longestMatch(...args) {
356
475
  }
357
476
  };
358
477
  }
478
+ /**
479
+ * Internal sync helper for object suggest functionality.
480
+ * @internal
481
+ */
482
+ function* suggestObjectSync(context, prefix, parserPairs) {
483
+ if (context.buffer.length > 0) {
484
+ const lastToken = context.buffer[context.buffer.length - 1];
485
+ for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
486
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
487
+ yield* parser.suggest({
488
+ ...context,
489
+ state: fieldState
490
+ }, prefix);
491
+ return;
492
+ }
493
+ }
494
+ const suggestions = [];
495
+ for (const [field, parser] of parserPairs) {
496
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
497
+ const fieldSuggestions = parser.suggest({
498
+ ...context,
499
+ state: fieldState
500
+ }, prefix);
501
+ suggestions.push(...fieldSuggestions);
502
+ }
503
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
504
+ }
505
+ /**
506
+ * Internal async helper for object suggest functionality.
507
+ * @internal
508
+ */
509
+ async function* suggestObjectAsync(context, prefix, parserPairs) {
510
+ if (context.buffer.length > 0) {
511
+ const lastToken = context.buffer[context.buffer.length - 1];
512
+ for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
513
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
514
+ const suggestions$1 = parser.suggest({
515
+ ...context,
516
+ state: fieldState
517
+ }, prefix);
518
+ for await (const s of suggestions$1) yield s;
519
+ return;
520
+ }
521
+ }
522
+ const suggestions = [];
523
+ for (const [field, parser] of parserPairs) {
524
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
525
+ const fieldSuggestions = parser.suggest({
526
+ ...context,
527
+ state: fieldState
528
+ }, prefix);
529
+ for await (const s of fieldSuggestions) suggestions.push(s);
530
+ }
531
+ yield* require_suggestion.deduplicateSuggestions(suggestions);
532
+ }
359
533
  function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
360
534
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
361
535
  let parsers;
@@ -371,117 +545,185 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
371
545
  parserPairs.sort(([_, parserA], [__, parserB]) => parserB.priority - parserA.priority);
372
546
  if (!options.allowDuplicates) checkDuplicateOptionNames(parserPairs.map(([field, parser]) => [field, parser.usage]));
373
547
  const noMatchContext = analyzeNoMatchContext(Object.values(parsers));
374
- return {
375
- $valueType: [],
376
- $stateType: [],
377
- priority: Math.max(...Object.values(parsers).map((p) => p.priority)),
378
- usage: parserPairs.flatMap(([_, p]) => p.usage),
379
- initialState: Object.fromEntries(Object.entries(parsers).map(([key, parser]) => [key, parser.initialState])),
380
- parse(context) {
381
- let error = {
382
- consumed: 0,
383
- error: context.buffer.length > 0 ? (() => {
384
- const token = context.buffer[0];
385
- const customMessage = options.errors?.unexpectedInput;
386
- if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
387
- const baseError = require_message.message`Unexpected option or argument: ${token}.`;
388
- return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
389
- })() : (() => {
390
- const customEndOfInput = options.errors?.endOfInput;
391
- return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
392
- })()
393
- };
394
- let currentContext = context;
395
- let anySuccess = false;
396
- const allConsumed = [];
397
- let madeProgress = true;
398
- while (madeProgress && currentContext.buffer.length > 0) {
399
- madeProgress = false;
400
- for (const [field, parser] of parserPairs) {
401
- const result = parser.parse({
548
+ const combinedMode = Object.values(parsers).some((p) => p.$mode === "async") ? "async" : "sync";
549
+ const isAsync = combinedMode === "async";
550
+ const getInitialError = (context) => ({
551
+ consumed: 0,
552
+ error: context.buffer.length > 0 ? (() => {
553
+ const token = context.buffer[0];
554
+ const customMessage = options.errors?.unexpectedInput;
555
+ if (customMessage) return typeof customMessage === "function" ? customMessage(token) : customMessage;
556
+ const baseError = require_message.message`Unexpected option or argument: ${token}.`;
557
+ return require_suggestion.createErrorWithSuggestions(baseError, token, context.usage, "both", options.errors?.suggestions);
558
+ })() : (() => {
559
+ const customEndOfInput = options.errors?.endOfInput;
560
+ return customEndOfInput ? typeof customEndOfInput === "function" ? customEndOfInput(noMatchContext) : customEndOfInput : generateNoMatchError(noMatchContext);
561
+ })()
562
+ });
563
+ const parseSync = (context) => {
564
+ let error = getInitialError(context);
565
+ let currentContext = context;
566
+ let anySuccess = false;
567
+ const allConsumed = [];
568
+ let madeProgress = true;
569
+ while (madeProgress && currentContext.buffer.length > 0) {
570
+ madeProgress = false;
571
+ for (const [field, parser] of parserPairs) {
572
+ const result = parser.parse({
573
+ ...currentContext,
574
+ state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
575
+ });
576
+ if (result.success && result.consumed.length > 0) {
577
+ currentContext = {
402
578
  ...currentContext,
403
- state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
404
- });
405
- if (result.success && result.consumed.length > 0) {
406
- currentContext = {
407
- ...currentContext,
408
- buffer: result.next.buffer,
409
- optionsTerminated: result.next.optionsTerminated,
410
- state: {
411
- ...currentContext.state,
412
- [field]: result.next.state
413
- }
414
- };
415
- allConsumed.push(...result.consumed);
416
- anySuccess = true;
417
- madeProgress = true;
418
- break;
419
- } else if (!result.success && error.consumed < result.consumed) error = result;
579
+ buffer: result.next.buffer,
580
+ optionsTerminated: result.next.optionsTerminated,
581
+ state: {
582
+ ...currentContext.state,
583
+ [field]: result.next.state
584
+ }
585
+ };
586
+ allConsumed.push(...result.consumed);
587
+ anySuccess = true;
588
+ madeProgress = true;
589
+ break;
590
+ } else if (!result.success && error.consumed < result.consumed) error = result;
591
+ }
592
+ }
593
+ if (anySuccess) return {
594
+ success: true,
595
+ next: currentContext,
596
+ consumed: allConsumed
597
+ };
598
+ if (context.buffer.length === 0) {
599
+ let allCanComplete = true;
600
+ for (const [field, parser] of parserPairs) {
601
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
602
+ const completeResult = parser.complete(fieldState);
603
+ if (!completeResult.success) {
604
+ allCanComplete = false;
605
+ break;
420
606
  }
421
607
  }
422
- if (anySuccess) return {
608
+ if (allCanComplete) return {
423
609
  success: true,
424
- next: currentContext,
425
- consumed: allConsumed
610
+ next: context,
611
+ consumed: []
426
612
  };
427
- if (context.buffer.length === 0) {
428
- let allCanComplete = true;
429
- for (const [field, parser] of parserPairs) {
430
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
431
- const completeResult = parser.complete(fieldState);
432
- if (!completeResult.success) {
433
- allCanComplete = false;
434
- break;
435
- }
613
+ }
614
+ return {
615
+ ...error,
616
+ success: false
617
+ };
618
+ };
619
+ const parseAsync = async (context) => {
620
+ let error = getInitialError(context);
621
+ let currentContext = context;
622
+ let anySuccess = false;
623
+ const allConsumed = [];
624
+ let madeProgress = true;
625
+ while (madeProgress && currentContext.buffer.length > 0) {
626
+ madeProgress = false;
627
+ for (const [field, parser] of parserPairs) {
628
+ const resultOrPromise = parser.parse({
629
+ ...currentContext,
630
+ state: currentContext.state && typeof currentContext.state === "object" && field in currentContext.state ? currentContext.state[field] : parser.initialState
631
+ });
632
+ const result = await resultOrPromise;
633
+ if (result.success && result.consumed.length > 0) {
634
+ currentContext = {
635
+ ...currentContext,
636
+ buffer: result.next.buffer,
637
+ optionsTerminated: result.next.optionsTerminated,
638
+ state: {
639
+ ...currentContext.state,
640
+ [field]: result.next.state
641
+ }
642
+ };
643
+ allConsumed.push(...result.consumed);
644
+ anySuccess = true;
645
+ madeProgress = true;
646
+ break;
647
+ } else if (!result.success && error.consumed < result.consumed) error = result;
648
+ }
649
+ }
650
+ if (anySuccess) return {
651
+ success: true,
652
+ next: currentContext,
653
+ consumed: allConsumed
654
+ };
655
+ if (context.buffer.length === 0) {
656
+ let allCanComplete = true;
657
+ for (const [field, parser] of parserPairs) {
658
+ const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
659
+ const completeResult = await parser.complete(fieldState);
660
+ if (!completeResult.success) {
661
+ allCanComplete = false;
662
+ break;
436
663
  }
437
- if (allCanComplete) return {
438
- success: true,
439
- next: context,
440
- consumed: []
441
- };
442
664
  }
443
- return {
444
- ...error,
445
- success: false
665
+ if (allCanComplete) return {
666
+ success: true,
667
+ next: context,
668
+ consumed: []
446
669
  };
670
+ }
671
+ return {
672
+ ...error,
673
+ success: false
674
+ };
675
+ };
676
+ return {
677
+ $mode: combinedMode,
678
+ $valueType: [],
679
+ $stateType: [],
680
+ priority: Math.max(...Object.values(parsers).map((p) => p.priority)),
681
+ usage: parserPairs.flatMap(([_, p]) => p.usage),
682
+ initialState: Object.fromEntries(Object.entries(parsers).map(([key, parser]) => [key, parser.initialState])),
683
+ parse(context) {
684
+ if (isAsync) return parseAsync(context);
685
+ return parseSync(context);
447
686
  },
448
687
  complete(state) {
449
- const result = {};
450
- for (const field in state) {
451
- if (!(field in parsers)) continue;
452
- const valueResult = parsers[field].complete(state[field]);
453
- if (valueResult.success) result[field] = valueResult.value;
454
- else return {
455
- success: false,
456
- error: valueResult.error
688
+ if (!isAsync) {
689
+ const result = {};
690
+ const stateRecord = state;
691
+ for (const field in stateRecord) {
692
+ if (!(field in parsers)) continue;
693
+ const valueResult = parsers[field].complete(stateRecord[field]);
694
+ if (valueResult.success) result[field] = valueResult.value;
695
+ else return {
696
+ success: false,
697
+ error: valueResult.error
698
+ };
699
+ }
700
+ return {
701
+ success: true,
702
+ value: result
457
703
  };
458
704
  }
459
- return {
460
- success: true,
461
- value: result
462
- };
705
+ return (async () => {
706
+ const result = {};
707
+ const stateRecord = state;
708
+ for (const field in stateRecord) {
709
+ if (!(field in parsers)) continue;
710
+ const valueResult = await parsers[field].complete(stateRecord[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
720
+ };
721
+ })();
463
722
  },
464
723
  suggest(context, prefix) {
465
- const suggestions = [];
466
- if (context.buffer.length > 0) {
467
- const lastToken = context.buffer[context.buffer.length - 1];
468
- for (const [field, parser] of parserPairs) if (isOptionRequiringValue(parser.usage, lastToken)) {
469
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
470
- return Array.from(parser.suggest({
471
- ...context,
472
- state: fieldState
473
- }, prefix));
474
- }
475
- }
476
- for (const [field, parser] of parserPairs) {
477
- const fieldState = context.state && typeof context.state === "object" && field in context.state ? context.state[field] : parser.initialState;
478
- const fieldSuggestions = parser.suggest({
479
- ...context,
480
- state: fieldState
481
- }, prefix);
482
- suggestions.push(...fieldSuggestions);
483
- }
484
- return require_suggestion.deduplicateSuggestions(suggestions);
724
+ if (isAsync) return suggestObjectAsync(context, prefix, parserPairs);
725
+ const syncParserPairs = parserPairs;
726
+ return suggestObjectSync(context, prefix, syncParserPairs);
485
727
  },
486
728
  getDocFragments(state, defaultValue) {
487
729
  const fragments = parserPairs.flatMap(([field, p]) => {
@@ -510,6 +752,35 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
510
752
  }
511
753
  };
512
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
+ }
513
784
  function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
514
785
  const label = typeof labelOrParsers === "string" ? labelOrParsers : void 0;
515
786
  let parsers;
@@ -521,102 +792,187 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
521
792
  parsers = labelOrParsers;
522
793
  options = maybeParsersOrOptions ?? {};
523
794
  }
795
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
796
+ const isAsync = combinedMode === "async";
797
+ const syncParsers = parsers;
524
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
+ };
525
925
  return {
926
+ $mode: combinedMode,
526
927
  $valueType: [],
527
928
  $stateType: [],
528
929
  usage: parsers.toSorted((a, b) => b.priority - a.priority).flatMap((p) => p.usage),
529
930
  priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
530
931
  initialState: parsers.map((parser) => parser.initialState),
531
932
  parse(context) {
532
- let currentContext = context;
533
- const allConsumed = [];
534
- const matchedParsers = /* @__PURE__ */ new Set();
535
- while (matchedParsers.size < parsers.length) {
536
- let foundMatch = false;
537
- let error = {
538
- consumed: 0,
539
- error: require_message.message`No remaining parsers could match the input.`
540
- };
541
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
542
- for (const [parser, index] of remainingParsers) {
543
- const result = parser.parse({
544
- ...currentContext,
545
- state: currentContext.state[index]
546
- });
547
- if (result.success && result.consumed.length > 0) {
548
- currentContext = {
549
- ...currentContext,
550
- buffer: result.next.buffer,
551
- optionsTerminated: result.next.optionsTerminated,
552
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
553
- };
554
- allConsumed.push(...result.consumed);
555
- matchedParsers.add(index);
556
- foundMatch = true;
557
- break;
558
- } else if (!result.success && error.consumed < result.consumed) error = result;
559
- }
560
- if (!foundMatch) 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 < 1) {
566
- currentContext = {
567
- ...currentContext,
568
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
569
- };
570
- matchedParsers.add(index);
571
- foundMatch = true;
572
- break;
573
- } else if (!result.success && result.consumed < 1) {
574
- matchedParsers.add(index);
575
- foundMatch = true;
576
- break;
577
- }
578
- }
579
- if (!foundMatch) return {
580
- ...error,
581
- success: false
582
- };
583
- }
584
- return {
585
- success: true,
586
- next: currentContext,
587
- consumed: allConsumed
588
- };
933
+ if (isAsync) return parseAsync(context);
934
+ return parseSync(context);
589
935
  },
590
936
  complete(state) {
591
- const result = [];
592
- for (let i = 0; i < parsers.length; i++) {
593
- const valueResult = parsers[i].complete(state[i]);
594
- if (valueResult.success) result[i] = valueResult.value;
595
- else return {
596
- success: false,
597
- 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
598
951
  };
599
952
  }
600
- return {
601
- success: true,
602
- value: result
603
- };
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
+ })();
604
969
  },
605
970
  suggest(context, prefix) {
606
- const suggestions = [];
607
- for (let i = 0; i < parsers.length; i++) {
608
- const parser = parsers[i];
609
- const parserState = context.state && Array.isArray(context.state) ? context.state[i] : parser.initialState;
610
- const parserSuggestions = parser.suggest({
611
- ...context,
612
- state: parserState
613
- }, prefix);
614
- suggestions.push(...parserSuggestions);
615
- }
616
- return require_suggestion.deduplicateSuggestions(suggestions);
971
+ if (isAsync) return suggestTupleAsync(context, prefix, parsers);
972
+ return suggestTupleSync(context, prefix, syncParsers);
617
973
  },
618
974
  getDocFragments(state, defaultValue) {
619
- const fragments = parsers.flatMap((p, i) => {
975
+ const fragments = syncParsers.flatMap((p, i) => {
620
976
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
621
977
  kind: "available",
622
978
  state: state.state[i]
@@ -653,127 +1009,235 @@ function merge(...args) {
653
1009
  const startIndex = typeof args[0] === "string" ? 1 : 0;
654
1010
  const endIndex = lastArg && typeof lastArg === "object" && !("parse" in lastArg) && !("complete" in lastArg) ? args.length - 1 : args.length;
655
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;
656
1015
  const withIndex = rawParsers.map((p, i) => [p, i]);
657
1016
  const sorted = withIndex.toSorted(([a], [b]) => b.priority - a.priority);
658
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);
659
1021
  if (!options.allowDuplicates) checkDuplicateOptionNames(sorted.map(([parser, originalIndex]) => [String(originalIndex), parser.usage]));
660
1022
  const initialState = {};
661
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
+ };
662
1142
  return {
1143
+ $mode: combinedMode,
663
1144
  $valueType: [],
664
1145
  $stateType: [],
665
1146
  priority: Math.max(...parsers.map((p) => p.priority)),
666
1147
  usage: parsers.flatMap((p) => p.usage),
667
1148
  initialState,
668
1149
  parse(context) {
669
- let zeroConsumedSuccess = null;
670
- for (let i = 0; i < parsers.length; i++) {
671
- const parser = parsers[i];
672
- let parserState;
673
- if (parser.initialState === void 0) {
674
- const key = `__parser_${i}`;
675
- if (context.state && typeof context.state === "object" && key in context.state) parserState = context.state[key];
676
- else parserState = void 0;
677
- } else if (parser.initialState && typeof parser.initialState === "object") if (context.state && typeof context.state === "object") {
678
- const extractedState = {};
679
- for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
680
- parserState = extractedState;
681
- } else parserState = parser.initialState;
682
- else parserState = parser.initialState;
683
- const result = parser.parse({
684
- ...context,
685
- state: parserState
686
- });
687
- if (result.success) {
688
- let newState;
689
- if (parser.initialState === void 0) {
690
- const key = `__parser_${i}`;
691
- if (result.consumed.length > 0 || result.next.state !== void 0) newState = {
692
- ...context.state,
693
- [key]: result.next.state
694
- };
695
- else newState = { ...context.state };
696
- } else newState = {
697
- ...context.state,
698
- ...result.next.state
699
- };
700
- const newContext = {
701
- ...context,
702
- buffer: result.next.buffer,
703
- optionsTerminated: result.next.optionsTerminated,
704
- state: newState
705
- };
706
- if (result.consumed.length > 0) return {
707
- success: true,
708
- next: newContext,
709
- consumed: result.consumed
710
- };
711
- context = newContext;
712
- if (zeroConsumedSuccess === null) zeroConsumedSuccess = {
713
- context: newContext,
714
- consumed: []
715
- };
716
- else zeroConsumedSuccess.context = newContext;
717
- } else if (result.consumed < 1) continue;
718
- else return result;
719
- }
720
- if (zeroConsumedSuccess !== null) return {
721
- success: true,
722
- next: zeroConsumedSuccess.context,
723
- consumed: zeroConsumedSuccess.consumed
724
- };
725
- return {
726
- success: false,
727
- consumed: 0,
728
- error: require_message.message`No matching option or argument found.`
729
- };
1150
+ if (isAsync) return parseAsync(context);
1151
+ return parseSync(context);
730
1152
  },
731
1153
  complete(state) {
732
- const object$1 = {};
733
- for (let i = 0; i < parsers.length; i++) {
734
- const parser = parsers[i];
735
- let parserState;
1154
+ const extractCompleteState = (parser, index) => {
736
1155
  if (parser.initialState === void 0) {
737
- const key = `__parser_${i}`;
738
- if (state && typeof state === "object" && key in state) parserState = state[key];
739
- else parserState = void 0;
740
- } else if (parser.initialState && typeof parser.initialState === "object") if (state && typeof state === "object") {
741
- const extractedState = {};
742
- for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
743
- parserState = extractedState;
744
- } else parserState = parser.initialState;
745
- else parserState = parser.initialState;
746
- const result = parser.complete(parserState);
747
- if (!result.success) return result;
748
- for (const field in result.value) object$1[field] = result.value[field];
749
- }
750
- return {
751
- success: true,
752
- 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;
753
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
+ })();
754
1197
  },
755
1198
  suggest(context, prefix) {
756
- const suggestions = [];
757
- for (let i = 0; i < parsers.length; i++) {
758
- const parser = parsers[i];
759
- let parserState;
760
- if (parser.initialState === void 0) {
1199
+ const extractState = (p, i) => {
1200
+ if (p.initialState === void 0) {
761
1201
  const key = `__parser_${i}`;
762
- if (context.state && typeof context.state === "object" && key in context.state) parserState = context.state[key];
763
- else parserState = void 0;
764
- } else if (parser.initialState && typeof parser.initialState === "object") if (context.state && typeof context.state === "object") {
765
- const extractedState = {};
766
- for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
767
- parserState = extractedState;
768
- } else parserState = parser.initialState;
769
- else parserState = parser.initialState;
770
- const parserSuggestions = parser.suggest({
771
- ...context,
772
- state: parserState
773
- }, prefix);
774
- suggestions.push(...parserSuggestions);
775
- }
776
- 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
+ }();
777
1241
  },
778
1242
  getDocFragments(state, _defaultValue) {
779
1243
  const fragments = parsers.flatMap((p, i) => {
@@ -820,102 +1284,213 @@ function merge(...args) {
820
1284
  };
821
1285
  }
822
1286
  function concat(...parsers) {
1287
+ const combinedMode = parsers.some((p) => p.$mode === "async") ? "async" : "sync";
1288
+ const isAsync = combinedMode === "async";
1289
+ const syncParsers = parsers;
823
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
+ };
824
1447
  return {
1448
+ $mode: combinedMode,
825
1449
  $valueType: [],
826
1450
  $stateType: [],
827
1451
  priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
828
1452
  usage: parsers.flatMap((p) => p.usage),
829
1453
  initialState,
830
1454
  parse(context) {
831
- let currentContext = context;
832
- const allConsumed = [];
833
- const matchedParsers = /* @__PURE__ */ new Set();
834
- while (matchedParsers.size < parsers.length) {
835
- let foundMatch = false;
836
- let error = {
837
- consumed: 0,
838
- error: require_message.message`No remaining parsers could match the input.`
839
- };
840
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
841
- for (const [parser, index] of remainingParsers) {
842
- const result = parser.parse({
843
- ...currentContext,
844
- state: currentContext.state[index]
845
- });
846
- if (result.success && result.consumed.length > 0) {
847
- currentContext = {
848
- ...currentContext,
849
- buffer: result.next.buffer,
850
- optionsTerminated: result.next.optionsTerminated,
851
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
852
- };
853
- allConsumed.push(...result.consumed);
854
- matchedParsers.add(index);
855
- foundMatch = true;
856
- break;
857
- } else if (!result.success && error.consumed < result.consumed) error = result;
858
- }
859
- if (!foundMatch) 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 < 1) {
865
- currentContext = {
866
- ...currentContext,
867
- state: currentContext.state.map((s, idx) => idx === index ? result.next.state : s)
868
- };
869
- matchedParsers.add(index);
870
- foundMatch = true;
871
- break;
872
- } else if (!result.success && result.consumed < 1) {
873
- matchedParsers.add(index);
874
- foundMatch = true;
875
- break;
876
- }
877
- }
878
- if (!foundMatch) return {
879
- ...error,
880
- success: false
881
- };
882
- }
883
- return {
884
- success: true,
885
- next: currentContext,
886
- consumed: allConsumed
887
- };
1455
+ if (isAsync) return parseAsync(context);
1456
+ return parseSync(context);
888
1457
  },
889
1458
  complete(state) {
890
- const results = [];
891
- for (let i = 0; i < parsers.length; i++) {
892
- const parser = parsers[i];
893
- const parserState = state[i];
894
- const result = parser.complete(parserState);
895
- if (!result.success) return result;
896
- if (Array.isArray(result.value)) results.push(...result.value);
897
- else results.push(result.value);
898
- }
899
- return {
900
- success: true,
901
- value: results
902
- };
1459
+ if (isAsync) return completeAsync(state);
1460
+ return completeSync(state);
903
1461
  },
904
1462
  suggest(context, prefix) {
905
- const suggestions = [];
906
- for (let i = 0; i < parsers.length; i++) {
907
- const parser = parsers[i];
908
- const parserState = context.state && Array.isArray(context.state) ? context.state[i] : parser.initialState;
909
- const parserSuggestions = parser.suggest({
910
- ...context,
911
- state: parserState
912
- }, prefix);
913
- suggestions.push(...parserSuggestions);
914
- }
915
- 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
+ }();
916
1491
  },
917
1492
  getDocFragments(state, _defaultValue) {
918
- const fragments = parsers.flatMap((p, index) => {
1493
+ const fragments = syncParsers.flatMap((p, index) => {
919
1494
  const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
920
1495
  kind: "available",
921
1496
  state: state.state[index]
@@ -985,6 +1560,7 @@ function concat(...parsers) {
985
1560
  */
986
1561
  function group(label, parser) {
987
1562
  return {
1563
+ $mode: parser.$mode,
988
1564
  $valueType: parser.$valueType,
989
1565
  $stateType: parser.$stateType,
990
1566
  priority: parser.priority,
@@ -1050,6 +1626,8 @@ function group(label, parser) {
1050
1626
  function conditional(discriminator, branches, defaultBranch, options) {
1051
1627
  const branchParsers = Object.entries(branches);
1052
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";
1053
1631
  const maxPriority = Math.max(discriminator.priority, ...allBranchParsers.map((p) => p.priority));
1054
1632
  function appendLiteralToUsage(usage$1, literalValue) {
1055
1633
  const result = [];
@@ -1087,164 +1665,334 @@ function conditional(discriminator, branches, defaultBranch, options) {
1087
1665
  selectedBranch: void 0,
1088
1666
  branchState: void 0
1089
1667
  };
1090
- return {
1091
- $valueType: [],
1092
- $stateType: [],
1093
- priority: maxPriority,
1094
- usage,
1095
- initialState,
1096
- parse(context) {
1097
- const state = context.state ?? initialState;
1098
- if (state.selectedBranch !== void 0) {
1099
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1100
- const branchResult = branchParser.parse({
1101
- ...context,
1102
- state: state.branchState,
1103
- usage: branchParser.usage
1104
- });
1105
- if (branchResult.success) return {
1106
- success: true,
1107
- next: {
1108
- ...branchResult.next,
1109
- state: {
1110
- ...state,
1111
- branchState: branchResult.next.state
1112
- }
1113
- },
1114
- consumed: branchResult.consumed
1115
- };
1116
- return branchResult;
1117
- }
1118
- 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({
1119
1680
  ...context,
1120
- state: state.discriminatorState
1681
+ state: state.branchState,
1682
+ usage: branchParser.usage
1121
1683
  });
1122
- if (discriminatorResult.success && discriminatorResult.consumed.length > 0) {
1123
- const completionResult = discriminator.complete(discriminatorResult.next.state);
1124
- if (completionResult.success) {
1125
- const value = completionResult.value;
1126
- const branchParser = branches[value];
1127
- if (branchParser) {
1128
- const branchParseResult = branchParser.parse({
1129
- ...context,
1130
- buffer: discriminatorResult.next.buffer,
1131
- optionsTerminated: discriminatorResult.next.optionsTerminated,
1132
- state: branchParser.initialState,
1133
- usage: branchParser.usage
1134
- });
1135
- if (branchParseResult.success) return {
1136
- success: true,
1137
- next: {
1138
- ...branchParseResult.next,
1139
- state: {
1140
- discriminatorState: discriminatorResult.next.state,
1141
- discriminatorValue: value,
1142
- selectedBranch: {
1143
- kind: "branch",
1144
- key: value
1145
- },
1146
- branchState: branchParseResult.next.state
1147
- }
1148
- },
1149
- consumed: [...discriminatorResult.consumed, ...branchParseResult.consumed]
1150
- };
1151
- return {
1152
- success: true,
1153
- next: {
1154
- ...discriminatorResult.next,
1155
- state: {
1156
- discriminatorState: discriminatorResult.next.state,
1157
- discriminatorValue: value,
1158
- selectedBranch: {
1159
- kind: "branch",
1160
- key: value
1161
- },
1162
- branchState: branchParser.initialState
1163
- }
1164
- },
1165
- consumed: discriminatorResult.consumed
1166
- };
1684
+ if (branchResult.success) return {
1685
+ success: true,
1686
+ next: {
1687
+ ...branchResult.next,
1688
+ state: {
1689
+ ...state,
1690
+ branchState: branchResult.next.state
1167
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
+ };
1168
1746
  }
1169
1747
  }
1170
- if (defaultBranch !== void 0) {
1171
- const defaultResult = defaultBranch.parse({
1172
- ...context,
1173
- state: state.branchState ?? defaultBranch.initialState,
1174
- usage: defaultBranch.usage
1175
- });
1176
- if (defaultResult.success && defaultResult.consumed.length > 0) return {
1177
- success: true,
1178
- next: {
1179
- ...defaultResult.next,
1180
- state: {
1181
- ...state,
1182
- selectedBranch: { kind: "default" },
1183
- branchState: defaultResult.next.state
1184
- }
1185
- },
1186
- consumed: defaultResult.consumed
1187
- };
1188
- }
1189
- const noMatchContext = analyzeNoMatchContext([discriminator, ...allBranchParsers]);
1190
- const errorMessage = options?.errors?.noMatch ? typeof options.errors.noMatch === "function" ? options.errors.noMatch(noMatchContext) : options.errors.noMatch : generateNoMatchError(noMatchContext);
1191
- return {
1192
- success: false,
1193
- consumed: 0,
1194
- 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
1195
1766
  };
1196
- },
1197
- complete(state) {
1198
- if (state.selectedBranch === void 0) {
1199
- if (defaultBranch !== void 0) {
1200
- const branchState = state.branchState ?? defaultBranch.initialState;
1201
- const defaultResult = defaultBranch.complete(branchState);
1202
- 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
+ };
1203
1829
  return {
1204
1830
  success: true,
1205
- 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
1206
1844
  };
1207
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;
1208
1881
  return {
1209
- success: false,
1210
- error: require_message.message`Missing required discriminator option.`
1882
+ success: true,
1883
+ value: [void 0, defaultResult.value]
1211
1884
  };
1212
1885
  }
1213
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1214
- const branchResult = branchParser.complete(state.branchState);
1215
- if (!branchResult.success) {
1216
- if (state.discriminatorValue !== void 0 && options?.errors?.branchError) return {
1217
- success: false,
1218
- 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]
1219
1915
  };
1220
- return branchResult;
1221
1916
  }
1222
- const discriminatorValue = state.selectedBranch.kind === "default" ? void 0 : state.selectedBranch.key;
1223
1917
  return {
1224
- success: true,
1225
- value: [discriminatorValue, branchResult.value]
1918
+ success: false,
1919
+ error: require_message.message`Missing required discriminator option.`
1226
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);
1227
1992
  },
1228
1993
  suggest(context, prefix) {
1229
- const state = context.state ?? initialState;
1230
- const suggestions = [];
1231
- if (state.selectedBranch === void 0) {
1232
- suggestions.push(...discriminator.suggest({
1233
- ...context,
1234
- state: state.discriminatorState
1235
- }, prefix));
1236
- if (defaultBranch !== void 0) suggestions.push(...defaultBranch.suggest({
1237
- ...context,
1238
- state: state.branchState ?? defaultBranch.initialState
1239
- }, prefix));
1240
- } else {
1241
- const branchParser = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
1242
- suggestions.push(...branchParser.suggest({
1243
- ...context,
1244
- state: state.branchState
1245
- }, prefix));
1246
- }
1247
- return require_suggestion.deduplicateSuggestions(suggestions);
1994
+ if (isAsync) return suggestAsync(context, prefix);
1995
+ return suggestSync(context, prefix);
1248
1996
  },
1249
1997
  getDocFragments(_state, _defaultValue) {
1250
1998
  const fragments = [];