@optique/core 1.1.0-dev.2087 → 1.1.0-dev.2096

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.
@@ -319,6 +319,10 @@ function applyHiddenToUsageTerm(term, hidden) {
319
319
  terms: applyHiddenToUsage(term.terms, hidden),
320
320
  min: term.min
321
321
  };
322
+ if (term.type === "sequence") return {
323
+ type: "sequence",
324
+ terms: applyHiddenToUsage(term.terms, hidden)
325
+ };
322
326
  if (term.type === "exclusive") return {
323
327
  type: "exclusive",
324
328
  terms: term.terms.map((u) => applyHiddenToUsage(u, hidden))
@@ -374,7 +378,7 @@ function isOptionRequiringValue(usage, token) {
374
378
  if (!terms || !Array.isArray(terms)) return false;
375
379
  for (const term of terms) if (term.type === "option") {
376
380
  if (term.metavar && term.names.includes(token)) return true;
377
- } else if (term.type === "optional" || term.type === "multiple") {
381
+ } else if (term.type === "optional" || term.type === "multiple" || term.type === "sequence") {
378
382
  if (traverse(term.terms)) return true;
379
383
  } else if (term.type === "exclusive") {
380
384
  for (const exclusiveUsage of term.terms) if (traverse(exclusiveUsage)) return true;
@@ -1152,6 +1156,15 @@ function or(...args) {
1152
1156
  leadingNames: unionLeadingNames(parsers),
1153
1157
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
1154
1158
  initialState: void 0,
1159
+ canSkip(state, exec) {
1160
+ const activeState = normalizeExclusiveState(state);
1161
+ if (activeState != null) {
1162
+ const [index, result] = activeState;
1163
+ const parser = parsers[index];
1164
+ return result.success && parser?.canSkip?.(result.next.state, exec) === true;
1165
+ }
1166
+ return parsers.some((parser) => parser.canSkip?.(parser.initialState, exec) === true);
1167
+ },
1155
1168
  complete: createExclusiveComplete(parsers, options, noMatchContext, combinedMode),
1156
1169
  [extractPhase2SeedKey](state, exec) {
1157
1170
  return extractExclusivePhase2Seed(parsers, state, exec, combinedMode);
@@ -1992,6 +2005,13 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
1992
2005
  usage: applyHiddenToUsage(parserPairs.flatMap(([_, p]) => p.usage), options.hidden),
1993
2006
  leadingNames: sharedBufferLeadingNames(parserPairs.map(([_, p]) => p)),
1994
2007
  acceptingAnyToken: parserPairs.some(([_, p]) => p.acceptingAnyToken),
2008
+ canSkip(state, exec) {
2009
+ const getFieldState = createFieldStateGetter(state);
2010
+ return parserKeys.every((field) => {
2011
+ const parser = parsers[field];
2012
+ return parser.canSkip?.(getFieldState(field, parser), withChildExecPath(exec, field)) === true;
2013
+ });
2014
+ },
1995
2015
  get initialState() {
1996
2016
  return createInitialState();
1997
2017
  },
@@ -2284,6 +2304,369 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2284
2304
  defineInheritedAnnotationParser(objectParser);
2285
2305
  return objectParser;
2286
2306
  }
2307
+ function isParserLike(value) {
2308
+ return value != null && (typeof value === "object" || typeof value === "function") && "parse" in value && "$valueType" in value && "$stateType" in value;
2309
+ }
2310
+ function tokenMatchesLeadingName(token, candidates) {
2311
+ if (token == null) return false;
2312
+ for (const name of candidates.optionNames) if (token === name) return true;
2313
+ for (const name of candidates.joinedOptionNames) if (name.startsWith("/") && token.startsWith(`${name}:`) || (name.startsWith("--") || name.startsWith("-") && name.length > 2) && token.startsWith(`${name}=`)) return true;
2314
+ for (const name of candidates.commandNames) if (token === name) return true;
2315
+ return false;
2316
+ }
2317
+ function parserCanSkipAt(parser, state, exec, index) {
2318
+ return parser.canSkip?.(getWrappedChildState(void 0, state, parser), withChildExecPath(exec, index)) === true;
2319
+ }
2320
+ function collectLeadingJoinedOptionNames(terms, optionNames) {
2321
+ for (const term of terms) {
2322
+ if (term.type === "option") {
2323
+ if (term.metavar != null) for (const name of term.names) optionNames.add(name);
2324
+ return false;
2325
+ }
2326
+ if (term.type === "command" || term.type === "argument") return false;
2327
+ if (term.type === "optional") {
2328
+ collectLeadingJoinedOptionNames(term.terms, optionNames);
2329
+ continue;
2330
+ }
2331
+ if (term.type === "multiple") {
2332
+ collectLeadingJoinedOptionNames(term.terms, optionNames);
2333
+ if (term.min === 0) continue;
2334
+ return false;
2335
+ }
2336
+ if (term.type === "sequence") {
2337
+ if (collectLeadingJoinedOptionNames(term.terms, optionNames)) continue;
2338
+ return false;
2339
+ }
2340
+ if (term.type === "exclusive") {
2341
+ let allSkippable = true;
2342
+ for (const branch of term.terms) {
2343
+ const branchSkippable = collectLeadingJoinedOptionNames(branch, optionNames);
2344
+ allSkippable = allSkippable && branchSkippable;
2345
+ }
2346
+ if (allSkippable) continue;
2347
+ return false;
2348
+ }
2349
+ }
2350
+ return true;
2351
+ }
2352
+ function sequenceLeadingCandidates(parsers) {
2353
+ const optionNames = /* @__PURE__ */ new Set();
2354
+ const joinedOptionNames = /* @__PURE__ */ new Set();
2355
+ const commandNames = /* @__PURE__ */ new Set();
2356
+ let positionalBlocked = false;
2357
+ for (let i = 0; i < parsers.length; i++) {
2358
+ const parser = parsers[i];
2359
+ const parserOptions = /* @__PURE__ */ new Set();
2360
+ const parserJoinedOptions = /* @__PURE__ */ new Set();
2361
+ const parserCommands = /* @__PURE__ */ new Set();
2362
+ collectLeadingCandidates(parser.usage, parserOptions, parserCommands);
2363
+ collectLeadingJoinedOptionNames(parser.usage, parserJoinedOptions);
2364
+ for (const name of parserOptions) optionNames.add(name);
2365
+ for (const name of parserJoinedOptions) joinedOptionNames.add(name);
2366
+ if (!positionalBlocked) {
2367
+ for (const name of parserCommands) commandNames.add(name);
2368
+ for (const name of parser.leadingNames) if (!parserOptions.has(name)) commandNames.add(name);
2369
+ } else for (const name of parser.leadingNames) if (!parserOptions.has(name) && name.startsWith("-")) commandNames.add(name);
2370
+ if (parser.acceptingAnyToken) positionalBlocked = true;
2371
+ if (!parserCanSkipAt(parser, parser.initialState, void 0, i)) break;
2372
+ }
2373
+ return {
2374
+ optionNames: optionNames.size === 0 ? EMPTY_LEADING_NAMES : optionNames,
2375
+ joinedOptionNames: joinedOptionNames.size === 0 ? EMPTY_LEADING_NAMES : joinedOptionNames,
2376
+ commandNames: commandNames.size === 0 ? EMPTY_LEADING_NAMES : commandNames
2377
+ };
2378
+ }
2379
+ function sequenceLeadingNames(parsers) {
2380
+ const candidates = sequenceLeadingCandidates(parsers);
2381
+ const names = new Set([
2382
+ ...candidates.optionNames,
2383
+ ...candidates.joinedOptionNames,
2384
+ ...candidates.commandNames
2385
+ ]);
2386
+ return names.size === 0 ? EMPTY_LEADING_NAMES : names;
2387
+ }
2388
+ function sequenceAcceptingAnyToken(parsers) {
2389
+ for (let i = 0; i < parsers.length; i++) {
2390
+ const parser = parsers[i];
2391
+ if (parser.acceptingAnyToken) return true;
2392
+ if (!parserCanSkipAt(parser, parser.initialState, void 0, i)) break;
2393
+ }
2394
+ return false;
2395
+ }
2396
+ function sequencePriority(parsers) {
2397
+ let priority = 0;
2398
+ for (let i = 0; i < parsers.length; i++) {
2399
+ const parser = parsers[i];
2400
+ priority = Math.max(priority, parser.priority);
2401
+ if (!parserCanSkipAt(parser, parser.initialState, void 0, i)) break;
2402
+ }
2403
+ return priority;
2404
+ }
2405
+ function leadingCandidatesAfter(parsers, startIndex) {
2406
+ return sequenceLeadingCandidates(parsers.slice(startIndex));
2407
+ }
2408
+ function checkSequentialDuplicateOptionNames(parsers) {
2409
+ const active = /* @__PURE__ */ new Map();
2410
+ for (let i = 0; i < parsers.length; i++) {
2411
+ const parser = parsers[i];
2412
+ const optionNames = /* @__PURE__ */ new Set();
2413
+ collectLeadingCandidates(parser.usage, optionNames, /* @__PURE__ */ new Set(), true);
2414
+ const retainedOptionNames = collectRetainedLeadingCandidates(parser.usage).optionNames;
2415
+ for (const name of optionNames) {
2416
+ const sources = active.get(name);
2417
+ if (sources != null) throw new DuplicateOptionError(name, [...sources, String(i)]);
2418
+ }
2419
+ for (const name of optionNames) {
2420
+ const sources = active.get(name);
2421
+ active.set(name, sources == null ? [String(i)] : [...sources, String(i)]);
2422
+ }
2423
+ if (!parserCanSkipAt(parser, parser.initialState, void 0, i)) active.clear();
2424
+ for (const name of retainedOptionNames) {
2425
+ const sources = active.get(name);
2426
+ active.set(name, sources == null ? [String(i)] : [...sources, String(i)]);
2427
+ }
2428
+ }
2429
+ }
2430
+ function collectRetainedLeadingCandidates(terms) {
2431
+ const optionNames = /* @__PURE__ */ new Set();
2432
+ const joinedOptionNames = /* @__PURE__ */ new Set();
2433
+ collectRetainedLeadingCandidatesInto(terms, optionNames, joinedOptionNames);
2434
+ return {
2435
+ optionNames,
2436
+ joinedOptionNames,
2437
+ commandNames: EMPTY_LEADING_NAMES
2438
+ };
2439
+ }
2440
+ function collectRetainedLeadingCandidatesInto(terms, optionNames, joinedOptionNames) {
2441
+ for (const term of terms) {
2442
+ if (term.type === "optional") {
2443
+ collectLeadingOptionCandidates(term.terms, optionNames, joinedOptionNames);
2444
+ collectRetainedLeadingCandidatesInto(term.terms, optionNames, joinedOptionNames);
2445
+ continue;
2446
+ }
2447
+ if (term.type === "multiple") {
2448
+ collectLeadingOptionCandidates(term.terms, optionNames, joinedOptionNames);
2449
+ collectRetainedLeadingCandidatesInto(term.terms, optionNames, joinedOptionNames);
2450
+ continue;
2451
+ }
2452
+ if (term.type === "sequence") {
2453
+ collectRetainedLeadingCandidatesInto(term.terms, optionNames, joinedOptionNames);
2454
+ continue;
2455
+ }
2456
+ if (term.type === "exclusive") {
2457
+ let canSkipBranch = false;
2458
+ const branchOptionNames = [];
2459
+ const branchJoinedOptionNames = [];
2460
+ for (const branch of term.terms) {
2461
+ const branchOptions = /* @__PURE__ */ new Set();
2462
+ const branchJoinedOptions = /* @__PURE__ */ new Set();
2463
+ const branchCanSkip = collectLeadingCandidates(branch, branchOptions, /* @__PURE__ */ new Set(), true);
2464
+ collectLeadingJoinedOptionNames(branch, branchJoinedOptions);
2465
+ canSkipBranch = canSkipBranch || branchCanSkip;
2466
+ branchOptionNames.push(branchOptions);
2467
+ branchJoinedOptionNames.push(branchJoinedOptions);
2468
+ collectRetainedLeadingCandidatesInto(branch, optionNames, joinedOptionNames);
2469
+ }
2470
+ if (canSkipBranch) {
2471
+ for (const branchOptions of branchOptionNames) for (const name of branchOptions) optionNames.add(name);
2472
+ for (const branchJoinedOptions of branchJoinedOptionNames) for (const name of branchJoinedOptions) joinedOptionNames.add(name);
2473
+ }
2474
+ }
2475
+ }
2476
+ }
2477
+ function collectLeadingOptionCandidates(terms, optionNames, joinedOptionNames) {
2478
+ collectLeadingCandidates(terms, optionNames, /* @__PURE__ */ new Set(), true);
2479
+ collectLeadingJoinedOptionNames(terms, joinedOptionNames);
2480
+ }
2481
+ function collectRetainedLeadingCandidatesAtState(terms, state) {
2482
+ if (terms.length === 1 && terms[0].type === "optional" && Array.isArray(state)) return collectRetainedLeadingCandidates(terms[0].terms);
2483
+ return collectRetainedLeadingCandidates(terms);
2484
+ }
2485
+ function createSeqState(sourceState, index, states) {
2486
+ const seqState = {
2487
+ index,
2488
+ states: annotateFreshArray(sourceState, states)
2489
+ };
2490
+ return inheritAnnotations(sourceState, seqState);
2491
+ }
2492
+ function getSeqChildState(seqState, index, parser) {
2493
+ return getWrappedChildState(seqState, seqState.states[index], parser);
2494
+ }
2495
+ function updateSeqChildState(sourceState, index, childState, parser) {
2496
+ return annotateFreshArray(sourceState.states, sourceState.states.map((state, stateIndex) => stateIndex === index ? getWrappedChildState(sourceState.states, childState, parser) : state));
2497
+ }
2498
+ function shouldAdvanceSeqBeforeParse(parser, parserState, initialParserState, currentContext, index, parsers) {
2499
+ const token = currentContext.buffer[0];
2500
+ if (token !== "--") {
2501
+ const laterLeadingCandidates = leadingCandidatesAfter(parsers, index + 1);
2502
+ if (!tokenMatchesLeadingName(token, laterLeadingCandidates)) return false;
2503
+ }
2504
+ if (!parserCanSkipAt(parser, parserState, currentContext.exec, index)) return false;
2505
+ if (token === "--") return true;
2506
+ if (currentContext.state.states[index] === initialParserState) {
2507
+ const currentLeadingCandidates = sequenceLeadingCandidates([parser]);
2508
+ return !tokenMatchesLeadingName(token, currentLeadingCandidates);
2509
+ }
2510
+ return !tokenMatchesLeadingName(token, collectRetainedLeadingCandidatesAtState(parser.usage, currentContext.state.states[index]));
2511
+ }
2512
+ function advanceSeqContext(currentContext, nextIndex, consumedTerminator) {
2513
+ return {
2514
+ ...currentContext,
2515
+ buffer: consumedTerminator ? currentContext.buffer.slice(1) : currentContext.buffer,
2516
+ optionsTerminated: consumedTerminator ? true : currentContext.optionsTerminated,
2517
+ state: createSeqState(currentContext.state, nextIndex, currentContext.state.states)
2518
+ };
2519
+ }
2520
+ function updateSeqContextFromChildResult(currentContext, index, parser, result, nextIndex) {
2521
+ const states = updateSeqChildState(currentContext.state, index, result.next.state, parser);
2522
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2523
+ return {
2524
+ ...currentContext,
2525
+ buffer: result.next.buffer,
2526
+ optionsTerminated: result.next.optionsTerminated,
2527
+ state: createSeqState(currentContext.state, nextIndex, states),
2528
+ ...mergedExec != null ? {
2529
+ exec: mergedExec,
2530
+ dependencyRegistry: mergedExec.dependencyRegistry
2531
+ } : {}
2532
+ };
2533
+ }
2534
+ function advanceSeqSuggestContextSync(context, parsers, initialStates) {
2535
+ let currentContext = context;
2536
+ while (currentContext.state.index < parsers.length) {
2537
+ const index = currentContext.state.index;
2538
+ const parser = parsers[index];
2539
+ const parserState = getSeqChildState(currentContext.state, index, parser);
2540
+ if (currentContext.buffer.length < 1) break;
2541
+ if (shouldAdvanceSeqBeforeParse(parser, parserState, initialStates[index], currentContext, index, parsers)) {
2542
+ const consumedTerminator = currentContext.buffer[0] === "--";
2543
+ currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
2544
+ continue;
2545
+ }
2546
+ const result = parser.parse(withChildContext$1(currentContext, index, parserState, parser));
2547
+ if (!result.success) {
2548
+ if (result.consumed > 0) break;
2549
+ if (parserCanSkipAt(parser, parserState, currentContext.exec, index)) {
2550
+ currentContext = advanceSeqContext(currentContext, index + 1, false);
2551
+ continue;
2552
+ }
2553
+ break;
2554
+ }
2555
+ const nextIndex = result.consumed.length > 0 ? index : index + 1;
2556
+ currentContext = updateSeqContextFromChildResult(currentContext, index, parser, result, nextIndex);
2557
+ }
2558
+ return currentContext;
2559
+ }
2560
+ async function advanceSeqSuggestContextAsync(context, parsers, initialStates) {
2561
+ let currentContext = context;
2562
+ while (currentContext.state.index < parsers.length) {
2563
+ const index = currentContext.state.index;
2564
+ const parser = parsers[index];
2565
+ const parserState = getSeqChildState(currentContext.state, index, parser);
2566
+ if (currentContext.buffer.length < 1) break;
2567
+ if (shouldAdvanceSeqBeforeParse(parser, parserState, initialStates[index], currentContext, index, parsers)) {
2568
+ const consumedTerminator = currentContext.buffer[0] === "--";
2569
+ currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
2570
+ continue;
2571
+ }
2572
+ const result = await parser.parse(withChildContext$1(currentContext, index, parserState, parser));
2573
+ if (!result.success) {
2574
+ if (result.consumed > 0) break;
2575
+ if (parserCanSkipAt(parser, parserState, currentContext.exec, index)) {
2576
+ currentContext = advanceSeqContext(currentContext, index + 1, false);
2577
+ continue;
2578
+ }
2579
+ break;
2580
+ }
2581
+ const nextIndex = result.consumed.length > 0 ? index : index + 1;
2582
+ currentContext = updateSeqContextFromChildResult(currentContext, index, parser, result, nextIndex);
2583
+ }
2584
+ return currentContext;
2585
+ }
2586
+ function createSeqComplete(parsers, combinedMode) {
2587
+ const syncParsers = parsers;
2588
+ return (state, exec) => dispatchByMode(combinedMode, () => {
2589
+ const stateArray = annotateFreshArray(state, state.states);
2590
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2591
+ const childExec = {
2592
+ ...exec,
2593
+ dependencyRuntime: runtime
2594
+ };
2595
+ const pairs = buildIndexedParserPairs(syncParsers);
2596
+ const stateRecord = createAnnotatedArrayStateRecord(stateArray);
2597
+ const preCompleted = preCompleteAndRegisterDependencies(stateRecord, pairs, runtime.registry, childExec);
2598
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
2599
+ const phase3Exec = {
2600
+ ...childExec,
2601
+ preCompletedByParser: void 0
2602
+ };
2603
+ const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
2604
+ const result = [];
2605
+ const deferredKeys = /* @__PURE__ */ new Map();
2606
+ let hasDeferred = false;
2607
+ for (let i = 0; i < syncParsers.length; i++) {
2608
+ const elementParser = syncParsers[i];
2609
+ const preCompletedResult = preCompleted.get(String(i));
2610
+ const valueResult = preCompletedResult !== void 0 ? unwrapCompleteResult(preCompletedResult) : unwrapCompleteResult(elementParser.complete(prepareStateForCompletion(getWrappedChildState(stateArray, resolvedArray[i], elementParser), elementParser), withChildExecPath(phase3Exec, i)));
2611
+ if (!valueResult.success) return {
2612
+ success: false,
2613
+ error: valueResult.error
2614
+ };
2615
+ result[i] = valueResult.value;
2616
+ if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(i, valueResult.deferredKeys);
2617
+ else if (valueResult.value == null || typeof valueResult.value !== "object") deferredKeys.set(i, null);
2618
+ else hasDeferred = true;
2619
+ }
2620
+ return {
2621
+ success: true,
2622
+ value: result,
2623
+ ...deferredKeys.size > 0 || hasDeferred ? {
2624
+ deferred: true,
2625
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2626
+ } : {}
2627
+ };
2628
+ }, async () => {
2629
+ const stateArray = annotateFreshArray(state, state.states);
2630
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
2631
+ const childExec = {
2632
+ ...exec,
2633
+ dependencyRuntime: runtime
2634
+ };
2635
+ const pairs = buildIndexedParserPairs(parsers);
2636
+ const stateRecord = createAnnotatedArrayStateRecord(stateArray);
2637
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(stateRecord, pairs, runtime.registry, childExec);
2638
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
2639
+ const phase3Exec = {
2640
+ ...childExec,
2641
+ preCompletedByParser: void 0
2642
+ };
2643
+ const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
2644
+ const result = [];
2645
+ const deferredKeys = /* @__PURE__ */ new Map();
2646
+ let hasDeferred = false;
2647
+ for (let i = 0; i < parsers.length; i++) {
2648
+ const elementParser = parsers[i];
2649
+ const preCompletedResult = preCompleted.get(String(i));
2650
+ const valueResult = preCompletedResult !== void 0 ? unwrapCompleteResult(preCompletedResult) : unwrapCompleteResult(await elementParser.complete(prepareStateForCompletion(getWrappedChildState(stateArray, resolvedArray[i], elementParser), elementParser), withChildExecPath(phase3Exec, i)));
2651
+ if (!valueResult.success) return {
2652
+ success: false,
2653
+ error: valueResult.error
2654
+ };
2655
+ result[i] = valueResult.value;
2656
+ if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(i, valueResult.deferredKeys);
2657
+ else if (valueResult.value == null || typeof valueResult.value !== "object") deferredKeys.set(i, null);
2658
+ else hasDeferred = true;
2659
+ }
2660
+ return {
2661
+ success: true,
2662
+ value: result,
2663
+ ...deferredKeys.size > 0 || hasDeferred ? {
2664
+ deferred: true,
2665
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
2666
+ } : {}
2667
+ };
2668
+ });
2669
+ }
2287
2670
  function suggestTupleSync(context, prefix, parsers) {
2288
2671
  const suggestions = [];
2289
2672
  const advanced = advanceTupleSuggestContextSync(context, parsers);
@@ -2678,6 +3061,10 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2678
3061
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
2679
3062
  priority: parsers.length > 0 ? Math.max(...parsers.map((p) => p.priority)) : 0,
2680
3063
  initialState: parsers.map((parser) => parser.initialState),
3064
+ canSkip(state, exec) {
3065
+ const stateArray = state;
3066
+ return parsers.every((parser, index) => parser.canSkip?.(getWrappedChildState(stateArray, stateArray[index], parser), withChildExecPath(exec, index)) === true);
3067
+ },
2681
3068
  parse(context) {
2682
3069
  return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
2683
3070
  },
@@ -2915,6 +3302,334 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2915
3302
  defineInheritedAnnotationParser(tupleParser);
2916
3303
  return tupleParser;
2917
3304
  }
3305
+ function seq(...rawArgs) {
3306
+ const label = typeof rawArgs[0] === "string" ? rawArgs[0] : void 0;
3307
+ if (label != null) validateLabel(label);
3308
+ const args = label == null ? rawArgs : rawArgs.slice(1);
3309
+ const lastArg = args.at(-1);
3310
+ const hasOptions = lastArg != null && !isParserLike(lastArg);
3311
+ const options = hasOptions ? lastArg : {};
3312
+ const parsers = hasOptions ? args.slice(0, -1) : args;
3313
+ const combinedMode = parsers.some((p) => p.mode === "async") ? "async" : "sync";
3314
+ const syncParsers = parsers;
3315
+ if (!options.allowDuplicates) checkSequentialDuplicateOptionNames(parsers);
3316
+ const initialState = createSeqState(void 0, 0, parsers.map((parser) => parser.initialState));
3317
+ const withSeqConsumedDepth = (result, consumed) => ({
3318
+ ...result,
3319
+ consumed: consumed.length + result.consumed
3320
+ });
3321
+ const parseSync = (context) => {
3322
+ let currentContext = context;
3323
+ const allConsumed = [];
3324
+ while (currentContext.state.index < syncParsers.length) {
3325
+ const index = currentContext.state.index;
3326
+ const parser = syncParsers[index];
3327
+ const parserState = getSeqChildState(currentContext.state, index, parser);
3328
+ if (currentContext.buffer.length < 1) break;
3329
+ if (shouldAdvanceSeqBeforeParse(parser, parserState, initialState.states[index], currentContext, index, syncParsers)) {
3330
+ const consumedTerminator = currentContext.buffer[0] === "--";
3331
+ if (consumedTerminator) allConsumed.push("--");
3332
+ currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
3333
+ continue;
3334
+ }
3335
+ const result = parser.parse(withChildContext$1(currentContext, index, parserState, parser));
3336
+ if (!result.success) {
3337
+ if (result.consumed > 0) return withSeqConsumedDepth(result, allConsumed);
3338
+ if (!parserCanSkipAt(parser, parserState, currentContext.exec, index)) return withSeqConsumedDepth(result, allConsumed);
3339
+ currentContext = advanceSeqContext(currentContext, index + 1, false);
3340
+ continue;
3341
+ }
3342
+ const states = updateSeqChildState(currentContext.state, index, result.next.state, parser);
3343
+ const nextIndex = result.consumed.length > 0 ? index : index + 1;
3344
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3345
+ currentContext = {
3346
+ ...currentContext,
3347
+ buffer: result.next.buffer,
3348
+ optionsTerminated: result.next.optionsTerminated,
3349
+ state: createSeqState(currentContext.state, nextIndex, states),
3350
+ ...mergedExec != null ? {
3351
+ exec: mergedExec,
3352
+ dependencyRegistry: mergedExec.dependencyRegistry
3353
+ } : {}
3354
+ };
3355
+ allConsumed.push(...result.consumed);
3356
+ }
3357
+ return {
3358
+ success: true,
3359
+ next: currentContext,
3360
+ consumed: allConsumed
3361
+ };
3362
+ };
3363
+ const parseAsync = async (context) => {
3364
+ let currentContext = context;
3365
+ const allConsumed = [];
3366
+ while (currentContext.state.index < parsers.length) {
3367
+ const index = currentContext.state.index;
3368
+ const parser = parsers[index];
3369
+ const parserState = getSeqChildState(currentContext.state, index, parser);
3370
+ if (currentContext.buffer.length < 1) break;
3371
+ if (shouldAdvanceSeqBeforeParse(parser, parserState, initialState.states[index], currentContext, index, parsers)) {
3372
+ const consumedTerminator = currentContext.buffer[0] === "--";
3373
+ if (consumedTerminator) allConsumed.push("--");
3374
+ currentContext = advanceSeqContext(currentContext, index + 1, consumedTerminator);
3375
+ continue;
3376
+ }
3377
+ const result = await parser.parse(withChildContext$1(currentContext, index, parserState, parser));
3378
+ if (!result.success) {
3379
+ if (result.consumed > 0) return withSeqConsumedDepth(result, allConsumed);
3380
+ if (!parserCanSkipAt(parser, parserState, currentContext.exec, index)) return withSeqConsumedDepth(result, allConsumed);
3381
+ currentContext = advanceSeqContext(currentContext, index + 1, false);
3382
+ continue;
3383
+ }
3384
+ const states = updateSeqChildState(currentContext.state, index, result.next.state, parser);
3385
+ const nextIndex = result.consumed.length > 0 ? index : index + 1;
3386
+ const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3387
+ currentContext = {
3388
+ ...currentContext,
3389
+ buffer: result.next.buffer,
3390
+ optionsTerminated: result.next.optionsTerminated,
3391
+ state: createSeqState(currentContext.state, nextIndex, states),
3392
+ ...mergedExec != null ? {
3393
+ exec: mergedExec,
3394
+ dependencyRegistry: mergedExec.dependencyRegistry
3395
+ } : {}
3396
+ };
3397
+ allConsumed.push(...result.consumed);
3398
+ }
3399
+ return {
3400
+ success: true,
3401
+ next: currentContext,
3402
+ consumed: allConsumed
3403
+ };
3404
+ };
3405
+ const leadingNames = sequenceLeadingNames(parsers);
3406
+ const seqParser = {
3407
+ mode: combinedMode,
3408
+ $valueType: [],
3409
+ $stateType: [],
3410
+ [fieldParsersKey]: parsers.map((parser, index) => [String(index), parser]),
3411
+ usage: [{
3412
+ type: "sequence",
3413
+ terms: parsers.flatMap((parser) => parser.usage)
3414
+ }],
3415
+ leadingNames,
3416
+ acceptingAnyToken: sequenceAcceptingAnyToken(parsers),
3417
+ priority: sequencePriority(parsers),
3418
+ initialState,
3419
+ canSkip(state, exec) {
3420
+ for (let i = state.index; i < parsers.length; i++) {
3421
+ const parser = parsers[i];
3422
+ if (parser.canSkip?.(getSeqChildState(state, i, parser), withChildExecPath(exec, i)) !== true) return false;
3423
+ }
3424
+ return true;
3425
+ },
3426
+ parse(context) {
3427
+ return dispatchByMode(combinedMode, () => parseSync(context), () => parseAsync(context));
3428
+ },
3429
+ complete: void 0,
3430
+ [extractPhase2SeedKey](state, exec) {
3431
+ return dispatchByMode(combinedMode, () => {
3432
+ const stateArray = state.states;
3433
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
3434
+ const childExec = withDependencyRuntimeExec(seqParser.usage, exec, runtime);
3435
+ const pairs = buildIndexedParserPairs(syncParsers);
3436
+ const stateRecord = createAnnotatedArrayStateRecord(stateArray);
3437
+ const preCompleted = preCompleteAndRegisterDependencies(stateRecord, pairs, runtime.registry, childExec);
3438
+ collectExplicitSourceValues(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(syncParsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
3439
+ const phase3Exec = {
3440
+ ...childExec,
3441
+ preCompletedByParser: void 0
3442
+ };
3443
+ const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
3444
+ const result = [];
3445
+ const deferredKeys = /* @__PURE__ */ new Map();
3446
+ let hasDeferred = false;
3447
+ let hasAnySeed = false;
3448
+ for (let i = 0; i < syncParsers.length; i++) {
3449
+ const elementParser = syncParsers[i];
3450
+ const childExec$1 = withChildExecPath(phase3Exec, i);
3451
+ const preCompletedResult = preCompleted.get(String(i));
3452
+ const seed = preCompletedResult !== void 0 ? reusePreCompletedPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), preCompletedResult, childExec$1) : completeOrExtractPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), childExec$1);
3453
+ if (seed == null) continue;
3454
+ hasAnySeed = true;
3455
+ result[i] = seed.value;
3456
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(i, seed.deferredKeys);
3457
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(i, null);
3458
+ else hasDeferred = true;
3459
+ }
3460
+ if (!hasAnySeed) return null;
3461
+ return {
3462
+ value: result,
3463
+ ...deferredKeys.size > 0 || hasDeferred ? {
3464
+ deferred: true,
3465
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
3466
+ } : {}
3467
+ };
3468
+ }, async () => {
3469
+ const stateArray = state.states;
3470
+ const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
3471
+ const childExec = withDependencyRuntimeExec(seqParser.usage, exec, runtime);
3472
+ const pairs = buildIndexedParserPairs(parsers);
3473
+ const stateRecord = createAnnotatedArrayStateRecord(stateArray);
3474
+ const preCompleted = await preCompleteAndRegisterDependenciesAsync(stateRecord, pairs, runtime.registry, childExec);
3475
+ await collectExplicitSourceValuesAsync(filterPreCompletedRuntimeNodes(buildRuntimeNodesFromArray(parsers, stateArray, exec?.path), new Set(preCompleted.keys())), runtime);
3476
+ const phase3Exec = {
3477
+ ...childExec,
3478
+ preCompletedByParser: void 0
3479
+ };
3480
+ const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
3481
+ const result = [];
3482
+ const deferredKeys = /* @__PURE__ */ new Map();
3483
+ let hasDeferred = false;
3484
+ let hasAnySeed = false;
3485
+ for (let i = 0; i < parsers.length; i++) {
3486
+ const elementParser = parsers[i];
3487
+ const childExec$1 = withChildExecPath(phase3Exec, i);
3488
+ const preCompletedResult = preCompleted.get(String(i));
3489
+ const seed = preCompletedResult !== void 0 ? await reusePreCompletedPhase2SeedAsync(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), preCompletedResult, childExec$1) : await completeOrExtractPhase2Seed(elementParser, prepareStateForCompletion(resolvedArray[i], elementParser), childExec$1);
3490
+ if (seed == null) continue;
3491
+ hasAnySeed = true;
3492
+ result[i] = seed.value;
3493
+ if (seed.deferred) if (seed.deferredKeys) deferredKeys.set(i, seed.deferredKeys);
3494
+ else if (seed.value == null || typeof seed.value !== "object") deferredKeys.set(i, null);
3495
+ else hasDeferred = true;
3496
+ }
3497
+ if (!hasAnySeed) return null;
3498
+ return {
3499
+ value: result,
3500
+ ...deferredKeys.size > 0 || hasDeferred ? {
3501
+ deferred: true,
3502
+ ...deferredKeys.size > 0 ? { deferredKeys } : {}
3503
+ } : {}
3504
+ };
3505
+ });
3506
+ },
3507
+ suggest(context, prefix) {
3508
+ return dispatchIterableByMode(combinedMode, () => {
3509
+ const suggestions = [];
3510
+ const advancedContext = advanceSeqSuggestContextSync(context, syncParsers, initialState.states);
3511
+ const runtime = createDependencyRuntimeContext(advancedContext.dependencyRegistry?.clone());
3512
+ const state = advancedContext.state;
3513
+ const stateArray = state.states;
3514
+ const nodes = buildSuggestRuntimeNodesFromArray(syncParsers, stateArray, advancedContext.exec?.path);
3515
+ collectExplicitSourceValues(nodes, runtime);
3516
+ fillMissingSourceDefaults(nodes, runtime);
3517
+ collectSourcesFromState(stateArray, runtime);
3518
+ completeDependencySourceDefaults({
3519
+ ...advancedContext,
3520
+ state: createAnnotatedArrayStateRecord(stateArray)
3521
+ }, buildIndexedParserPairs(syncParsers), runtime.registry, advancedContext.exec);
3522
+ const contextWithRegistry = {
3523
+ ...advancedContext,
3524
+ dependencyRegistry: runtime.registry,
3525
+ ...advancedContext.exec != null ? { exec: {
3526
+ ...advancedContext.exec,
3527
+ dependencyRuntime: runtime,
3528
+ dependencyRegistry: runtime.registry
3529
+ } } : {}
3530
+ };
3531
+ for (let i = state.index; i < syncParsers.length; i++) {
3532
+ const parser = syncParsers[i];
3533
+ const parserState = getSeqChildState(state, i, parser);
3534
+ suggestions.push(...parser.suggest(withChildContext$1(contextWithRegistry, i, parserState, parser), prefix));
3535
+ if (parser.canSkip?.(parserState, withChildExecPath(contextWithRegistry.exec, i)) !== true) break;
3536
+ }
3537
+ return deduplicateSuggestions(suggestions);
3538
+ }, async function* () {
3539
+ const suggestions = [];
3540
+ const advancedContext = await advanceSeqSuggestContextAsync(context, parsers, initialState.states);
3541
+ const runtime = createDependencyRuntimeContext(advancedContext.dependencyRegistry?.clone());
3542
+ const state = advancedContext.state;
3543
+ const stateArray = state.states;
3544
+ const nodes = buildSuggestRuntimeNodesFromArray(parsers, stateArray, advancedContext.exec?.path);
3545
+ await collectExplicitSourceValuesAsync(nodes, runtime);
3546
+ await fillMissingSourceDefaultsAsync(nodes, runtime);
3547
+ collectSourcesFromState(stateArray, runtime);
3548
+ await completeDependencySourceDefaultsAsync({
3549
+ ...advancedContext,
3550
+ state: createAnnotatedArrayStateRecord(stateArray)
3551
+ }, buildIndexedParserPairs(parsers), runtime.registry, advancedContext.exec);
3552
+ const contextWithRegistry = {
3553
+ ...advancedContext,
3554
+ dependencyRegistry: runtime.registry,
3555
+ ...advancedContext.exec != null ? { exec: {
3556
+ ...advancedContext.exec,
3557
+ dependencyRuntime: runtime,
3558
+ dependencyRegistry: runtime.registry
3559
+ } } : {}
3560
+ };
3561
+ for (let i = state.index; i < parsers.length; i++) {
3562
+ const parser = parsers[i];
3563
+ const parserState = getSeqChildState(state, i, parser);
3564
+ const parserSuggestions = parser.suggest(withChildContext$1(contextWithRegistry, i, parserState, parser), prefix);
3565
+ if (parser.mode === "async") for await (const suggestion of parserSuggestions) suggestions.push(suggestion);
3566
+ else suggestions.push(...parserSuggestions);
3567
+ if (parser.canSkip?.(parserState, withChildExecPath(contextWithRegistry.exec, i)) !== true) break;
3568
+ }
3569
+ yield* deduplicateSuggestions(suggestions);
3570
+ });
3571
+ },
3572
+ getDocFragments(state, defaultValue) {
3573
+ const fragments = syncParsers.flatMap((parser, index) => {
3574
+ const indexState = state.kind === "unavailable" ? { kind: "unavailable" } : {
3575
+ kind: "available",
3576
+ state: state.state.states[index]
3577
+ };
3578
+ return parser.getDocFragments(indexState, defaultValue?.[index]).fragments;
3579
+ });
3580
+ const entries = fragments.filter((d) => d.type === "entry");
3581
+ const sections = [];
3582
+ for (const fragment of fragments) {
3583
+ if (fragment.type !== "section") continue;
3584
+ if (fragment.title == null) entries.push(...fragment.entries);
3585
+ else sections.push(fragment);
3586
+ }
3587
+ sections.push({
3588
+ title: label,
3589
+ entries
3590
+ });
3591
+ return { fragments: sections.map((s) => ({
3592
+ ...s,
3593
+ type: "section"
3594
+ })) };
3595
+ },
3596
+ [Symbol.for("Deno.customInspect")]() {
3597
+ const parsersStr = parsers.length === 1 ? "1 parser" : `${parsers.length} parsers`;
3598
+ return label == null ? `seq(${parsersStr})` : `seq(${JSON.stringify(label)}, ${parsersStr})`;
3599
+ }
3600
+ };
3601
+ Object.defineProperty(seqParser, "complete", {
3602
+ value: createSeqComplete(parsers, combinedMode),
3603
+ configurable: true,
3604
+ enumerable: true
3605
+ });
3606
+ const normalizers = [];
3607
+ for (let i = 0; i < parsers.length; i++) {
3608
+ const parser = parsers[i];
3609
+ if (typeof parser.normalizeValue === "function") normalizers.push([i, parser.normalizeValue.bind(parser)]);
3610
+ }
3611
+ if (normalizers.length > 0) Object.defineProperty(seqParser, "normalizeValue", {
3612
+ value(arr) {
3613
+ if (!Array.isArray(arr)) return arr;
3614
+ let changed = false;
3615
+ let result;
3616
+ for (const [index, normalize] of normalizers) if (index < arr.length && Object.hasOwn(arr, index)) try {
3617
+ const original = arr[index];
3618
+ const normalized = normalize(original);
3619
+ if (normalized !== original) {
3620
+ result ??= [...arr];
3621
+ result[index] = normalized;
3622
+ changed = true;
3623
+ }
3624
+ } catch {}
3625
+ return changed ? result : arr;
3626
+ },
3627
+ configurable: true,
3628
+ enumerable: false
3629
+ });
3630
+ defineInheritedAnnotationParser(seqParser);
3631
+ return seqParser;
3632
+ }
2918
3633
  function merge(...args) {
2919
3634
  const label = typeof args[0] === "string" ? args[0] : void 0;
2920
3635
  if (label != null) validateLabel(label);
@@ -2947,23 +3662,24 @@ function merge(...args) {
2947
3662
  if (parser.initialState === void 0) initialState[parserStateKey(i)] = void 0;
2948
3663
  else if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
2949
3664
  }
2950
- const extractParserState = (parser, context, index) => {
3665
+ const extractParserStateFromState = (parser, state, index) => {
2951
3666
  if (parser.initialState === void 0) {
2952
3667
  const key = parserStateKey(index);
2953
- if (context.state && typeof context.state === "object" && key in context.state) return context.state[key];
3668
+ if (state && typeof state === "object" && key in state) return state[key];
2954
3669
  return void 0;
2955
3670
  } else if (parser.initialState && typeof parser.initialState === "object") {
2956
3671
  const localStateKey = localObjectStateKey(index);
2957
- if (shouldPreserveLocalChildState(parser) && context.state && typeof context.state === "object" && localStateKey in context.state) return context.state[localStateKey];
2958
- if (context.state && typeof context.state === "object") {
3672
+ if (shouldPreserveLocalChildState(parser) && state && typeof state === "object" && localStateKey in state) return state[localStateKey];
3673
+ if (state && typeof state === "object") {
2959
3674
  const extractedState = {};
2960
- for (const field in parser.initialState) extractedState[field] = field in context.state ? context.state[field] : parser.initialState[field];
3675
+ for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
2961
3676
  return extractedState;
2962
3677
  }
2963
3678
  return parser.initialState;
2964
3679
  }
2965
3680
  return parser.initialState;
2966
3681
  };
3682
+ const extractParserState = (parser, context, index) => extractParserStateFromState(parser, context.state, index);
2967
3683
  const mergeResultState = (parser, context, parserState, result, index) => {
2968
3684
  if (parser.initialState === void 0) {
2969
3685
  const key = parserStateKey(index);
@@ -3088,6 +3804,12 @@ function merge(...args) {
3088
3804
  leadingNames: sharedBufferLeadingNames(parsers),
3089
3805
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
3090
3806
  initialState,
3807
+ canSkip(state, exec) {
3808
+ return parsers.every((parser, index) => {
3809
+ const parserState = extractParserStateFromState(parser, state, index);
3810
+ return parser.canSkip?.(getWrappedChildState(state, parserState, parser), withChildExecPath(exec, index)) === true;
3811
+ });
3812
+ },
3091
3813
  parse(context) {
3092
3814
  if (isAsync) return parseAsync(context);
3093
3815
  return parseSync(context);
@@ -4033,6 +4755,10 @@ function concat(...parsers) {
4033
4755
  leadingNames: sharedBufferLeadingNames(parsers),
4034
4756
  acceptingAnyToken: parsers.some((p) => p.acceptingAnyToken),
4035
4757
  initialState,
4758
+ canSkip(state, exec) {
4759
+ const stateArray = state;
4760
+ return parsers.every((parser, index) => parser.canSkip?.(getWrappedChildState(stateArray, stateArray[index], parser), withChildExecPath(exec, index)) === true);
4761
+ },
4036
4762
  parse(context) {
4037
4763
  if (isAsync) return parseAsync(context);
4038
4764
  return parseSync(context);
@@ -4181,6 +4907,7 @@ function group(label, parser, options = {}) {
4181
4907
  initialState: parser.initialState,
4182
4908
  ...fieldParsersKey in parser ? { [fieldParsersKey]: parser[fieldParsersKey] } : {},
4183
4909
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
4910
+ ...typeof parser.canSkip === "function" ? { canSkip: parser.canSkip.bind(parser) } : {},
4184
4911
  getSuggestRuntimeNodes(state, path) {
4185
4912
  return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{
4186
4913
  path,
@@ -4338,6 +5065,10 @@ function conditional(discriminator, branches, defaultBranch, options) {
4338
5065
  ...term,
4339
5066
  terms: appendLiteralToUsage(term.terms, literalValue)
4340
5067
  });
5068
+ else if (term.type === "sequence") result.push({
5069
+ ...term,
5070
+ terms: appendLiteralToUsage(term.terms, literalValue)
5071
+ });
4341
5072
  else if (term.type === "exclusive") result.push({
4342
5073
  ...term,
4343
5074
  terms: term.terms.map((t) => appendLiteralToUsage(t, literalValue))
@@ -5225,4 +5956,4 @@ function conditional(discriminator, branches, defaultBranch, options) {
5225
5956
  }
5226
5957
 
5227
5958
  //#endregion
5228
- export { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, tuple };
5959
+ export { DuplicateOptionError, concat, conditional, group, longestMatch, merge, object, or, seq, tuple };