@optique/core 1.0.0-dev.1724 → 1.0.0-dev.1728

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.
@@ -872,27 +872,27 @@ function or(...args) {
872
872
  dependencyRegistry: replayExec.dependencyRegistry
873
873
  } : {}
874
874
  }, provisionalConsuming.index, checkResult.next.state, provisionalConsuming.parser));
875
- if (replayedResult.success) {
876
- const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
877
- return {
878
- success: true,
879
- provisional: true,
880
- next: {
881
- ...context,
882
- buffer: replayedResult.next.buffer,
883
- optionsTerminated: replayedResult.next.optionsTerminated,
884
- state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
885
- ...replayedResult,
886
- consumed: [...previouslyConsumed, ...replayedResult.consumed]
887
- }),
888
- ...mergedExec != null ? {
889
- exec: mergedExec,
890
- dependencyRegistry: mergedExec.dependencyRegistry
891
- } : {}
892
- },
893
- consumed: replayedResult.consumed
894
- };
895
- }
875
+ if (!replayedResult.success) return replayedResult;
876
+ const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
877
+ return {
878
+ success: true,
879
+ provisional: true,
880
+ next: {
881
+ ...context,
882
+ buffer: replayedResult.next.buffer,
883
+ optionsTerminated: replayedResult.next.optionsTerminated,
884
+ state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
885
+ ...replayedResult,
886
+ provisional: true,
887
+ consumed: [...previouslyConsumed, ...replayedResult.consumed]
888
+ }),
889
+ ...mergedExec != null ? {
890
+ exec: mergedExec,
891
+ dependencyRegistry: mergedExec.dependencyRegistry
892
+ } : {}
893
+ },
894
+ consumed: replayedResult.consumed
895
+ };
896
896
  }
897
897
  }
898
898
  }
@@ -1071,27 +1071,27 @@ function or(...args) {
1071
1071
  dependencyRegistry: replayExec.dependencyRegistry
1072
1072
  } : {}
1073
1073
  }, provisionalConsuming.index, checkResult.next.state, provisionalConsuming.parser));
1074
- if (replayedResult.success) {
1075
- const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
1076
- return {
1077
- success: true,
1078
- provisional: true,
1079
- next: {
1080
- ...context,
1081
- buffer: replayedResult.next.buffer,
1082
- optionsTerminated: replayedResult.next.optionsTerminated,
1083
- state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
1084
- ...replayedResult,
1085
- consumed: [...previouslyConsumed, ...replayedResult.consumed]
1086
- }),
1087
- ...mergedExec != null ? {
1088
- exec: mergedExec,
1089
- dependencyRegistry: mergedExec.dependencyRegistry
1090
- } : {}
1091
- },
1092
- consumed: replayedResult.consumed
1093
- };
1094
- }
1074
+ if (!replayedResult.success) return replayedResult;
1075
+ const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
1076
+ return {
1077
+ success: true,
1078
+ provisional: true,
1079
+ next: {
1080
+ ...context,
1081
+ buffer: replayedResult.next.buffer,
1082
+ optionsTerminated: replayedResult.next.optionsTerminated,
1083
+ state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
1084
+ ...replayedResult,
1085
+ provisional: true,
1086
+ consumed: [...previouslyConsumed, ...replayedResult.consumed]
1087
+ }),
1088
+ ...mergedExec != null ? {
1089
+ exec: mergedExec,
1090
+ dependencyRegistry: mergedExec.dependencyRegistry
1091
+ } : {}
1092
+ },
1093
+ consumed: replayedResult.consumed
1094
+ };
1095
1095
  }
1096
1096
  }
1097
1097
  }
@@ -4044,6 +4044,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
4044
4044
  const mergedExec = mergeChildExec(context.exec, branchResult.next.exec);
4045
4045
  return {
4046
4046
  success: true,
4047
+ ...state.speculative || branchResult.provisional ? { provisional: true } : {},
4047
4048
  next: {
4048
4049
  ...branchResult.next,
4049
4050
  state: {
@@ -4449,6 +4450,10 @@ function conditional(discriminator, branches, defaultBranch, options) {
4449
4450
  };
4450
4451
  } else if (defaultBranch === void 0) return deferredDiscriminatorResult;
4451
4452
  }
4453
+ if (defaultBranch !== void 0 && (exec?.phase === "parse" || exec?.phase === "suggest")) return {
4454
+ success: true,
4455
+ value: [void 0, void 0]
4456
+ };
4452
4457
  if (defaultBranch !== void 0) {
4453
4458
  const branchState = getAnnotatedChildState(state, state.branchState ?? defaultBranch.initialState, defaultBranch);
4454
4459
  const defaultResult = unwrapCompleteResult(await defaultBranch.complete(branchState, withChildExecPath(exec, "_branch")));
@@ -1343,7 +1343,7 @@ interface ConditionalErrorOptions {
1343
1343
  * Receives both the discriminator value the parser actually
1344
1344
  * resolved to (`discriminatorValue`) and the speculative key the
1345
1345
  * branch tokens were committed to (`speculativeKey`).
1346
- * @since 0.10.1
1346
+ * @since 1.0.1
1347
1347
  */
1348
1348
  readonly branchMismatch?: (discriminatorValue: string, speculativeKey: string) => Message;
1349
1349
  }
@@ -1343,7 +1343,7 @@ interface ConditionalErrorOptions {
1343
1343
  * Receives both the discriminator value the parser actually
1344
1344
  * resolved to (`discriminatorValue`) and the speculative key the
1345
1345
  * branch tokens were committed to (`speculativeKey`).
1346
- * @since 0.10.1
1346
+ * @since 1.0.1
1347
1347
  */
1348
1348
  readonly branchMismatch?: (discriminatorValue: string, speculativeKey: string) => Message;
1349
1349
  }
@@ -872,27 +872,27 @@ function or(...args) {
872
872
  dependencyRegistry: replayExec.dependencyRegistry
873
873
  } : {}
874
874
  }, provisionalConsuming.index, checkResult.next.state, provisionalConsuming.parser));
875
- if (replayedResult.success) {
876
- const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
877
- return {
878
- success: true,
879
- provisional: true,
880
- next: {
881
- ...context,
882
- buffer: replayedResult.next.buffer,
883
- optionsTerminated: replayedResult.next.optionsTerminated,
884
- state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
885
- ...replayedResult,
886
- consumed: [...previouslyConsumed, ...replayedResult.consumed]
887
- }),
888
- ...mergedExec != null ? {
889
- exec: mergedExec,
890
- dependencyRegistry: mergedExec.dependencyRegistry
891
- } : {}
892
- },
893
- consumed: replayedResult.consumed
894
- };
895
- }
875
+ if (!replayedResult.success) return replayedResult;
876
+ const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
877
+ return {
878
+ success: true,
879
+ provisional: true,
880
+ next: {
881
+ ...context,
882
+ buffer: replayedResult.next.buffer,
883
+ optionsTerminated: replayedResult.next.optionsTerminated,
884
+ state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
885
+ ...replayedResult,
886
+ provisional: true,
887
+ consumed: [...previouslyConsumed, ...replayedResult.consumed]
888
+ }),
889
+ ...mergedExec != null ? {
890
+ exec: mergedExec,
891
+ dependencyRegistry: mergedExec.dependencyRegistry
892
+ } : {}
893
+ },
894
+ consumed: replayedResult.consumed
895
+ };
896
896
  }
897
897
  }
898
898
  }
@@ -1071,27 +1071,27 @@ function or(...args) {
1071
1071
  dependencyRegistry: replayExec.dependencyRegistry
1072
1072
  } : {}
1073
1073
  }, provisionalConsuming.index, checkResult.next.state, provisionalConsuming.parser));
1074
- if (replayedResult.success) {
1075
- const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
1076
- return {
1077
- success: true,
1078
- provisional: true,
1079
- next: {
1080
- ...context,
1081
- buffer: replayedResult.next.buffer,
1082
- optionsTerminated: replayedResult.next.optionsTerminated,
1083
- state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
1084
- ...replayedResult,
1085
- consumed: [...previouslyConsumed, ...replayedResult.consumed]
1086
- }),
1087
- ...mergedExec != null ? {
1088
- exec: mergedExec,
1089
- dependencyRegistry: mergedExec.dependencyRegistry
1090
- } : {}
1091
- },
1092
- consumed: replayedResult.consumed
1093
- };
1094
- }
1074
+ if (!replayedResult.success) return replayedResult;
1075
+ const mergedExec = mergeChildExec(replayExec, replayedResult.next.exec);
1076
+ return {
1077
+ success: true,
1078
+ provisional: true,
1079
+ next: {
1080
+ ...context,
1081
+ buffer: replayedResult.next.buffer,
1082
+ optionsTerminated: replayedResult.next.optionsTerminated,
1083
+ state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
1084
+ ...replayedResult,
1085
+ provisional: true,
1086
+ consumed: [...previouslyConsumed, ...replayedResult.consumed]
1087
+ }),
1088
+ ...mergedExec != null ? {
1089
+ exec: mergedExec,
1090
+ dependencyRegistry: mergedExec.dependencyRegistry
1091
+ } : {}
1092
+ },
1093
+ consumed: replayedResult.consumed
1094
+ };
1095
1095
  }
1096
1096
  }
1097
1097
  }
@@ -4044,6 +4044,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
4044
4044
  const mergedExec = mergeChildExec(context.exec, branchResult.next.exec);
4045
4045
  return {
4046
4046
  success: true,
4047
+ ...state.speculative || branchResult.provisional ? { provisional: true } : {},
4047
4048
  next: {
4048
4049
  ...branchResult.next,
4049
4050
  state: {
@@ -4449,6 +4450,10 @@ function conditional(discriminator, branches, defaultBranch, options) {
4449
4450
  };
4450
4451
  } else if (defaultBranch === void 0) return deferredDiscriminatorResult;
4451
4452
  }
4453
+ if (defaultBranch !== void 0 && (exec?.phase === "parse" || exec?.phase === "suggest")) return {
4454
+ success: true,
4455
+ value: [void 0, void 0]
4456
+ };
4452
4457
  if (defaultBranch !== void 0) {
4453
4458
  const branchState = getAnnotatedChildState(state, state.branchState ?? defaultBranch.initialState, defaultBranch);
4454
4459
  const defaultResult = unwrapCompleteResult(await defaultBranch.complete(branchState, withChildExecPath(exec, "_branch")));
package/dist/parser.d.cts CHANGED
@@ -559,11 +559,23 @@ type ParserResult<TState> = {
559
559
  */
560
560
  readonly consumed: readonly string[];
561
561
  /**
562
- * When `true`, indicates that this success is tentative: the parser
563
- * matched something (e.g., a zero-consuming discriminator resolved to
564
- * a branch key) but the selected sub-parser has not consumed any input
565
- * yet. Outer combinators like {@link or} should not treat provisional
566
- * successes as definitive zero-consumed fallback candidates.
562
+ * When `true`, indicates that this success is tentative or
563
+ * speculative: the parser matched something but the match has not
564
+ * been confirmed yet. This covers two cases:
565
+ *
566
+ * - A zero-consuming discriminator resolved to a branch key, but
567
+ * the selected sub-parser has not consumed any input yet.
568
+ * - A {@link conditional} parser speculatively committed to a
569
+ * named branch that consumed tokens, before the discriminator
570
+ * has had a chance to confirm the choice. In this case the
571
+ * marker stays set across subsequent parse calls until
572
+ * `complete()` verifies the speculative selection.
573
+ *
574
+ * Outer combinators like {@link or} and {@link longestMatch} should
575
+ * not treat provisional successes as definitive — a definitive
576
+ * branch must be allowed to take priority, and a definitive
577
+ * zero-consuming fallback must not be displaced by a provisional
578
+ * consuming hit.
567
579
  *
568
580
  * @since 1.0.0
569
581
  */
package/dist/parser.d.ts CHANGED
@@ -559,11 +559,23 @@ type ParserResult<TState> = {
559
559
  */
560
560
  readonly consumed: readonly string[];
561
561
  /**
562
- * When `true`, indicates that this success is tentative: the parser
563
- * matched something (e.g., a zero-consuming discriminator resolved to
564
- * a branch key) but the selected sub-parser has not consumed any input
565
- * yet. Outer combinators like {@link or} should not treat provisional
566
- * successes as definitive zero-consumed fallback candidates.
562
+ * When `true`, indicates that this success is tentative or
563
+ * speculative: the parser matched something but the match has not
564
+ * been confirmed yet. This covers two cases:
565
+ *
566
+ * - A zero-consuming discriminator resolved to a branch key, but
567
+ * the selected sub-parser has not consumed any input yet.
568
+ * - A {@link conditional} parser speculatively committed to a
569
+ * named branch that consumed tokens, before the discriminator
570
+ * has had a chance to confirm the choice. In this case the
571
+ * marker stays set across subsequent parse calls until
572
+ * `complete()` verifies the speculative selection.
573
+ *
574
+ * Outer combinators like {@link or} and {@link longestMatch} should
575
+ * not treat provisional successes as definitive — a definitive
576
+ * branch must be allowed to take priority, and a definitive
577
+ * zero-consuming fallback must not be displaced by a provisional
578
+ * consuming hit.
567
579
  *
568
580
  * @since 1.0.0
569
581
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1724+3460ea70",
3
+ "version": "1.0.0-dev.1728+5206d2c9",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",