@optique/core 1.0.0-dev.1574 → 1.0.0-dev.1583

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.
@@ -75,12 +75,12 @@ function processOptionalStyleResult(result, innerState, context) {
75
75
  * @internal
76
76
  */
77
77
  function adaptShouldDeferCompletion(innerCheck) {
78
- return (state) => {
78
+ return (state, exec) => {
79
79
  if (Array.isArray(state)) {
80
80
  const inner = require_annotations.getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? require_annotations.inheritAnnotations(state, state[0]) : state[0];
81
- return innerCheck(inner);
81
+ return innerCheck(inner, exec);
82
82
  }
83
- if (state != null && typeof state === "object") return innerCheck(state);
83
+ if (state != null && typeof state === "object") return innerCheck(state, exec);
84
84
  return false;
85
85
  };
86
86
  }
@@ -136,12 +136,12 @@ function optional(parser) {
136
136
  parse(context) {
137
137
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
138
138
  },
139
- complete(state) {
139
+ complete(state, exec) {
140
140
  if (!Array.isArray(state)) {
141
- if (innerHasWrappedDependency && wrappedPendingState) return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState]), () => parser.complete([wrappedPendingState]));
141
+ if (innerHasWrappedDependency && wrappedPendingState) return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState], exec), () => parser.complete([wrappedPendingState], exec));
142
142
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
143
143
  const innerComplete = () => {
144
- const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
144
+ const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
145
145
  return require_mode_dispatch.mapModeValue(parser.$mode, innerResult, (result) => result.success ? result : {
146
146
  success: true,
147
147
  value: void 0
@@ -155,14 +155,14 @@ function optional(parser) {
155
155
  };
156
156
  }
157
157
  if (Array.isArray(state) && state.length === 1 && require_dependency.isPendingDependencySourceState(state[0])) {
158
- if (innerHasWrappedDependency) return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
158
+ if (innerHasWrappedDependency) return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
159
159
  return {
160
160
  success: true,
161
161
  value: void 0
162
162
  };
163
163
  }
164
164
  const innerElement = require_annotations.getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? require_annotations.inheritAnnotations(state, state[0]) : state[0];
165
- return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
165
+ return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
166
166
  },
167
167
  suggest(context, prefix) {
168
168
  return require_mode_dispatch.dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -268,7 +268,7 @@ function withDefault(parser, defaultValue, options) {
268
268
  parse(context) {
269
269
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
270
270
  },
271
- complete(state) {
271
+ complete(state, exec) {
272
272
  function evaluateDefault() {
273
273
  const raw = typeof defaultValue === "function" ? defaultValue() : defaultValue;
274
274
  if (typeof parser.normalizeValue === "function") try {
@@ -278,7 +278,7 @@ function withDefault(parser, defaultValue, options) {
278
278
  }
279
279
  if (!Array.isArray(state)) {
280
280
  if (require_dependency.transformsDependencyValue(parser)) {
281
- const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(void 0), () => parser.complete(void 0));
281
+ const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(void 0, exec), () => parser.complete(void 0, exec));
282
282
  const handleInnerResult = (res) => {
283
283
  if (require_dependency.isDependencySourceState(res)) try {
284
284
  const value = evaluateDefault();
@@ -321,7 +321,7 @@ function withDefault(parser, defaultValue, options) {
321
321
  };
322
322
  }
323
323
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
324
- const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
324
+ const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
325
325
  return innerResult;
326
326
  }
327
327
  try {
@@ -339,7 +339,7 @@ function withDefault(parser, defaultValue, options) {
339
339
  }
340
340
  if (require_dependency.isPendingDependencySourceState(state[0])) {
341
341
  if (require_dependency.transformsDependencyValue(parser)) {
342
- const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
342
+ const innerResult = require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
343
343
  const handleInnerResult = (res) => {
344
344
  if (require_dependency.isDependencySourceState(res)) try {
345
345
  const value = evaluateDefault();
@@ -382,7 +382,7 @@ function withDefault(parser, defaultValue, options) {
382
382
  }
383
383
  }
384
384
  const innerElement = require_annotations.getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? require_annotations.inheritAnnotations(state, state[0]) : state[0];
385
- return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
385
+ return require_mode_dispatch.dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
386
386
  },
387
387
  suggest(context, prefix) {
388
388
  return require_mode_dispatch.dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -512,8 +512,8 @@ function withDefault(parser, defaultValue, options) {
512
512
  * ```
513
513
  */
514
514
  function map(parser, transform) {
515
- const complete = (state) => {
516
- return require_mode_dispatch.mapModeValue(parser.$mode, parser.complete(state), (result) => {
515
+ const complete = (state, exec) => {
516
+ return require_mode_dispatch.mapModeValue(parser.$mode, parser.complete(state, exec), (result) => {
517
517
  if (!result.success) return result;
518
518
  if (result.deferred) try {
519
519
  return {
@@ -580,12 +580,12 @@ function multiple(parser, options = {}) {
580
580
  const syncParser = parser;
581
581
  const { min = 0, max = Infinity } = options;
582
582
  const unwrapInjectedWrapper = require_annotations.unwrapInjectedAnnotationWrapper;
583
- const completeSyncWithUnwrappedFallback = (state) => {
583
+ const completeSyncWithUnwrappedFallback = (state, exec) => {
584
584
  try {
585
- return syncParser.complete(state);
585
+ return syncParser.complete(state, exec);
586
586
  } catch (error) {
587
587
  if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
588
- return syncParser.complete(unwrapInjectedWrapper(state));
588
+ return syncParser.complete(unwrapInjectedWrapper(state), exec);
589
589
  }
590
590
  };
591
591
  const parseSyncWithUnwrappedFallback = (context) => {
@@ -604,12 +604,12 @@ function multiple(parser, options = {}) {
604
604
  });
605
605
  }
606
606
  };
607
- const completeAsyncWithUnwrappedFallback = async (state) => {
607
+ const completeAsyncWithUnwrappedFallback = async (state, exec) => {
608
608
  try {
609
- return await parser.complete(state);
609
+ return await parser.complete(state, exec);
610
610
  } catch (error) {
611
611
  if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
612
- return await parser.complete(unwrapInjectedWrapper(state));
612
+ return await parser.complete(unwrapInjectedWrapper(state), exec);
613
613
  }
614
614
  };
615
615
  const parseAsyncWithUnwrappedFallback = async (context) => {
@@ -698,13 +698,13 @@ function multiple(parser, options = {}) {
698
698
  parse(context) {
699
699
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
700
700
  },
701
- complete(state) {
701
+ complete(state, exec) {
702
702
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => {
703
703
  const result = [];
704
704
  const deferredIndices = /* @__PURE__ */ new Map();
705
705
  let hasDeferred = false;
706
706
  for (let i = 0; i < state.length; i++) {
707
- const valueResult = completeSyncWithUnwrappedFallback(state[i]);
707
+ const valueResult = completeSyncWithUnwrappedFallback(state[i], exec);
708
708
  if (valueResult.success) {
709
709
  const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
710
710
  result.push(unwrappedValue);
@@ -718,7 +718,7 @@ function multiple(parser, options = {}) {
718
718
  }
719
719
  return validateMultipleResult(result, deferredIndices, hasDeferred);
720
720
  }, async () => {
721
- const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s)));
721
+ const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s, exec)));
722
722
  const values = [];
723
723
  const deferredIndices = /* @__PURE__ */ new Map();
724
724
  let hasDeferred = false;
@@ -958,8 +958,8 @@ function nonEmpty(parser) {
958
958
  parse(context) {
959
959
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
960
960
  },
961
- complete(state) {
962
- return parser.complete(state);
961
+ complete(state, exec) {
962
+ return parser.complete(state, exec);
963
963
  },
964
964
  suggest(context, prefix) {
965
965
  return parser.suggest(context, prefix);
package/dist/modifiers.js CHANGED
@@ -75,12 +75,12 @@ function processOptionalStyleResult(result, innerState, context) {
75
75
  * @internal
76
76
  */
77
77
  function adaptShouldDeferCompletion(innerCheck) {
78
- return (state) => {
78
+ return (state, exec) => {
79
79
  if (Array.isArray(state)) {
80
80
  const inner = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
81
- return innerCheck(inner);
81
+ return innerCheck(inner, exec);
82
82
  }
83
- if (state != null && typeof state === "object") return innerCheck(state);
83
+ if (state != null && typeof state === "object") return innerCheck(state, exec);
84
84
  return false;
85
85
  };
86
86
  }
@@ -136,12 +136,12 @@ function optional(parser) {
136
136
  parse(context) {
137
137
  return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
138
138
  },
139
- complete(state) {
139
+ complete(state, exec) {
140
140
  if (!Array.isArray(state)) {
141
- if (innerHasWrappedDependency && wrappedPendingState) return dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState]), () => parser.complete([wrappedPendingState]));
141
+ if (innerHasWrappedDependency && wrappedPendingState) return dispatchByMode(parser.$mode, () => syncParser.complete([wrappedPendingState], exec), () => parser.complete([wrappedPendingState], exec));
142
142
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
143
143
  const innerComplete = () => {
144
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
144
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
145
145
  return mapModeValue(parser.$mode, innerResult, (result) => result.success ? result : {
146
146
  success: true,
147
147
  value: void 0
@@ -155,14 +155,14 @@ function optional(parser) {
155
155
  };
156
156
  }
157
157
  if (Array.isArray(state) && state.length === 1 && isPendingDependencySourceState(state[0])) {
158
- if (innerHasWrappedDependency) return dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
158
+ if (innerHasWrappedDependency) return dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
159
159
  return {
160
160
  success: true,
161
161
  value: void 0
162
162
  };
163
163
  }
164
164
  const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
165
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
165
+ return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
166
166
  },
167
167
  suggest(context, prefix) {
168
168
  return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -268,7 +268,7 @@ function withDefault(parser, defaultValue, options) {
268
268
  parse(context) {
269
269
  return dispatchByMode(parser.$mode, () => parseOptionalStyleSync(context, syncParser), () => parseOptionalStyleAsync(context, parser));
270
270
  },
271
- complete(state) {
271
+ complete(state, exec) {
272
272
  function evaluateDefault() {
273
273
  const raw = typeof defaultValue === "function" ? defaultValue() : defaultValue;
274
274
  if (typeof parser.normalizeValue === "function") try {
@@ -278,7 +278,7 @@ function withDefault(parser, defaultValue, options) {
278
278
  }
279
279
  if (!Array.isArray(state)) {
280
280
  if (transformsDependencyValue(parser)) {
281
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(void 0), () => parser.complete(void 0));
281
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(void 0, exec), () => parser.complete(void 0, exec));
282
282
  const handleInnerResult = (res) => {
283
283
  if (isDependencySourceState(res)) try {
284
284
  const value = evaluateDefault();
@@ -321,7 +321,7 @@ function withDefault(parser, defaultValue, options) {
321
321
  };
322
322
  }
323
323
  if (typeof parser.shouldDeferCompletion === "function" && state != null && typeof state === "object") {
324
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
324
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
325
325
  return innerResult;
326
326
  }
327
327
  try {
@@ -339,7 +339,7 @@ function withDefault(parser, defaultValue, options) {
339
339
  }
340
340
  if (isPendingDependencySourceState(state[0])) {
341
341
  if (transformsDependencyValue(parser)) {
342
- const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state), () => parser.complete(state));
342
+ const innerResult = dispatchByMode(parser.$mode, () => syncParser.complete(state, exec), () => parser.complete(state, exec));
343
343
  const handleInnerResult = (res) => {
344
344
  if (isDependencySourceState(res)) try {
345
345
  const value = evaluateDefault();
@@ -382,7 +382,7 @@ function withDefault(parser, defaultValue, options) {
382
382
  }
383
383
  }
384
384
  const innerElement = getAnnotations(state) != null && state[0] != null && typeof state[0] === "object" ? inheritAnnotations(state, state[0]) : state[0];
385
- return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement), () => parser.complete(innerElement));
385
+ return dispatchByMode(parser.$mode, () => syncParser.complete(innerElement, exec), () => parser.complete(innerElement, exec));
386
386
  },
387
387
  suggest(context, prefix) {
388
388
  return dispatchIterableByMode(parser.$mode, () => suggestSync(context, prefix), () => suggestAsync(context, prefix));
@@ -512,8 +512,8 @@ function withDefault(parser, defaultValue, options) {
512
512
  * ```
513
513
  */
514
514
  function map(parser, transform) {
515
- const complete = (state) => {
516
- return mapModeValue(parser.$mode, parser.complete(state), (result) => {
515
+ const complete = (state, exec) => {
516
+ return mapModeValue(parser.$mode, parser.complete(state, exec), (result) => {
517
517
  if (!result.success) return result;
518
518
  if (result.deferred) try {
519
519
  return {
@@ -580,12 +580,12 @@ function multiple(parser, options = {}) {
580
580
  const syncParser = parser;
581
581
  const { min = 0, max = Infinity } = options;
582
582
  const unwrapInjectedWrapper = unwrapInjectedAnnotationWrapper;
583
- const completeSyncWithUnwrappedFallback = (state) => {
583
+ const completeSyncWithUnwrappedFallback = (state, exec) => {
584
584
  try {
585
- return syncParser.complete(state);
585
+ return syncParser.complete(state, exec);
586
586
  } catch (error) {
587
587
  if (!isInjectedAnnotationWrapper(state)) throw error;
588
- return syncParser.complete(unwrapInjectedWrapper(state));
588
+ return syncParser.complete(unwrapInjectedWrapper(state), exec);
589
589
  }
590
590
  };
591
591
  const parseSyncWithUnwrappedFallback = (context) => {
@@ -604,12 +604,12 @@ function multiple(parser, options = {}) {
604
604
  });
605
605
  }
606
606
  };
607
- const completeAsyncWithUnwrappedFallback = async (state) => {
607
+ const completeAsyncWithUnwrappedFallback = async (state, exec) => {
608
608
  try {
609
- return await parser.complete(state);
609
+ return await parser.complete(state, exec);
610
610
  } catch (error) {
611
611
  if (!isInjectedAnnotationWrapper(state)) throw error;
612
- return await parser.complete(unwrapInjectedWrapper(state));
612
+ return await parser.complete(unwrapInjectedWrapper(state), exec);
613
613
  }
614
614
  };
615
615
  const parseAsyncWithUnwrappedFallback = async (context) => {
@@ -698,13 +698,13 @@ function multiple(parser, options = {}) {
698
698
  parse(context) {
699
699
  return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
700
700
  },
701
- complete(state) {
701
+ complete(state, exec) {
702
702
  return dispatchByMode(parser.$mode, () => {
703
703
  const result = [];
704
704
  const deferredIndices = /* @__PURE__ */ new Map();
705
705
  let hasDeferred = false;
706
706
  for (let i = 0; i < state.length; i++) {
707
- const valueResult = completeSyncWithUnwrappedFallback(state[i]);
707
+ const valueResult = completeSyncWithUnwrappedFallback(state[i], exec);
708
708
  if (valueResult.success) {
709
709
  const unwrappedValue = unwrapInjectedWrapper(valueResult.value);
710
710
  result.push(unwrappedValue);
@@ -718,7 +718,7 @@ function multiple(parser, options = {}) {
718
718
  }
719
719
  return validateMultipleResult(result, deferredIndices, hasDeferred);
720
720
  }, async () => {
721
- const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s)));
721
+ const results = await Promise.all(state.map((s) => completeAsyncWithUnwrappedFallback(s, exec)));
722
722
  const values = [];
723
723
  const deferredIndices = /* @__PURE__ */ new Map();
724
724
  let hasDeferred = false;
@@ -958,8 +958,8 @@ function nonEmpty(parser) {
958
958
  parse(context) {
959
959
  return dispatchByMode(parser.$mode, () => parseSync(context), () => parseAsync(context));
960
960
  },
961
- complete(state) {
962
- return parser.complete(state);
961
+ complete(state, exec) {
962
+ return parser.complete(state, exec);
963
963
  },
964
964
  suggest(context, prefix) {
965
965
  return parser.suggest(context, prefix);
package/dist/parser.cjs CHANGED
@@ -8,6 +8,28 @@ const require_modifiers = require('./modifiers.cjs');
8
8
  const require_primitives = require('./primitives.cjs');
9
9
 
10
10
  //#region src/parser.ts
11
+ /**
12
+ * Creates a {@link ParserContext} from a {@link ParseFrame} and an
13
+ * {@link ExecutionContext}. The returned object provides both structured
14
+ * access (`frame`, `exec`) and flat access (`buffer`, `state`, etc.)
15
+ * for backward compatibility.
16
+ *
17
+ * @template TState The type of the state used during parsing.
18
+ * @param frame Parser-local frame data.
19
+ * @param exec Shared execution context.
20
+ * @returns A {@link ParserContext} instance.
21
+ * @since 1.0.0
22
+ */
23
+ function createParserContext(frame, exec) {
24
+ return {
25
+ exec,
26
+ buffer: frame.buffer,
27
+ state: frame.state,
28
+ optionsTerminated: frame.optionsTerminated,
29
+ usage: exec.usage,
30
+ dependencyRegistry: exec.dependencyRegistry
31
+ };
32
+ }
11
33
  function injectAnnotationsIntoState(state, options) {
12
34
  const annotations = options?.annotations;
13
35
  if (annotations == null) return state;
@@ -38,12 +60,16 @@ function injectAnnotationsIntoState(state, options) {
38
60
  function parseSync(parser, args, options) {
39
61
  const initialState = injectAnnotationsIntoState(parser.initialState, options);
40
62
  const shouldUnwrapAnnotatedValue = options?.annotations != null || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
41
- let context = {
63
+ const exec = {
64
+ usage: parser.usage,
65
+ phase: "parse",
66
+ path: []
67
+ };
68
+ let context = createParserContext({
42
69
  buffer: args,
43
- optionsTerminated: false,
44
70
  state: initialState,
45
- usage: parser.usage
46
- };
71
+ optionsTerminated: false
72
+ }, exec);
47
73
  do {
48
74
  const result = parser.parse(context);
49
75
  if (!result.success) return {
@@ -57,7 +83,11 @@ function parseSync(parser, args, options) {
57
83
  error: require_message.message`Unexpected option or argument: ${context.buffer[0]}.`
58
84
  };
59
85
  } while (context.buffer.length > 0);
60
- const endResult = parser.complete(context.state);
86
+ const completeExec = {
87
+ ...exec,
88
+ phase: "complete"
89
+ };
90
+ const endResult = parser.complete(context.state, completeExec);
61
91
  return endResult.success ? {
62
92
  success: true,
63
93
  value: shouldUnwrapAnnotatedValue ? require_annotations.unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value,
@@ -97,12 +127,16 @@ function isBufferUnchanged(previous, current) {
97
127
  async function parseAsync(parser, args, options) {
98
128
  const initialState = injectAnnotationsIntoState(parser.initialState, options);
99
129
  const shouldUnwrapAnnotatedValue = options?.annotations != null || require_annotations.isInjectedAnnotationWrapper(parser.initialState);
100
- let context = {
130
+ const exec = {
131
+ usage: parser.usage,
132
+ phase: "parse",
133
+ path: []
134
+ };
135
+ let context = createParserContext({
101
136
  buffer: args,
102
- optionsTerminated: false,
103
137
  state: initialState,
104
- usage: parser.usage
105
- };
138
+ optionsTerminated: false
139
+ }, exec);
106
140
  do {
107
141
  const result = await parser.parse(context);
108
142
  if (!result.success) return {
@@ -116,7 +150,11 @@ async function parseAsync(parser, args, options) {
116
150
  error: require_message.message`Unexpected option or argument: ${context.buffer[0]}.`
117
151
  };
118
152
  } while (context.buffer.length > 0);
119
- const endResult = await parser.complete(context.state);
153
+ const completeExec = {
154
+ ...exec,
155
+ phase: "complete"
156
+ };
157
+ const endResult = await parser.complete(context.state, completeExec);
120
158
  return endResult.success ? {
121
159
  success: true,
122
160
  value: shouldUnwrapAnnotatedValue ? require_annotations.unwrapInjectedAnnotationWrapper(endResult.value) : endResult.value,
@@ -192,12 +230,15 @@ function suggestSync(parser, args, options) {
192
230
  const allButLast = args.slice(0, -1);
193
231
  const prefix = args[args.length - 1];
194
232
  const initialState = injectAnnotationsIntoState(parser.initialState, options);
195
- let context = {
233
+ let context = createParserContext({
196
234
  buffer: allButLast,
197
- optionsTerminated: false,
198
235
  state: initialState,
199
- usage: parser.usage
200
- };
236
+ optionsTerminated: false
237
+ }, {
238
+ usage: parser.usage,
239
+ phase: "suggest",
240
+ path: []
241
+ });
201
242
  while (context.buffer.length > 0) {
202
243
  const result = parser.parse(context);
203
244
  if (!result.success) return Array.from(parser.suggest(context, prefix));
@@ -231,12 +272,15 @@ async function suggestAsync(parser, args, options) {
231
272
  const allButLast = args.slice(0, -1);
232
273
  const prefix = args[args.length - 1];
233
274
  const initialState = injectAnnotationsIntoState(parser.initialState, options);
234
- let context = {
275
+ let context = createParserContext({
235
276
  buffer: allButLast,
236
- optionsTerminated: false,
237
277
  state: initialState,
238
- usage: parser.usage
239
- };
278
+ optionsTerminated: false
279
+ }, {
280
+ usage: parser.usage,
281
+ phase: "suggest",
282
+ path: []
283
+ });
240
284
  while (context.buffer.length > 0) {
241
285
  const result = await parser.parse(context);
242
286
  if (!result.success) {
@@ -493,6 +537,7 @@ exports.command = require_primitives.command;
493
537
  exports.concat = require_constructs.concat;
494
538
  exports.conditional = require_constructs.conditional;
495
539
  exports.constant = require_primitives.constant;
540
+ exports.createParserContext = createParserContext;
496
541
  exports.fail = require_primitives.fail;
497
542
  exports.flag = require_primitives.flag;
498
543
  exports.getDocPage = getDocPage;
package/dist/parser.d.cts CHANGED
@@ -164,13 +164,17 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
164
164
  * message.
165
165
  * @param state The current state of the parser, which may contain accumulated
166
166
  * data or context needed to produce the final value.
167
+ * @param exec Optional shared execution context. When provided, gives the
168
+ * parser access to cross-cutting runtime data such as the current
169
+ * execution phase and dependency registry.
167
170
  * @returns A result object indicating success or failure of
168
171
  * the transformation. If successful, it should contain
169
172
  * the parsed value of type {@link TValue}. If not applicable,
170
173
  * it should return an error message.
171
174
  * In async mode, returns a Promise that resolves to the result.
175
+ * @since 1.0.0 Added optional `exec` parameter.
172
176
  */
173
- complete(state: TState): ModeValue<M, ValueParserResult<TValue>>;
177
+ complete(state: TState, exec?: ExecutionContext): ModeValue<M, ValueParserResult<TValue>>;
174
178
  /**
175
179
  * Generates next-step suggestions based on the current context
176
180
  * and an optional prefix. This can be used to provide shell completion
@@ -221,10 +225,12 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
221
225
  * source) has resolved.
222
226
  *
223
227
  * @param state The current parser state.
228
+ * @param exec Optional shared execution context.
224
229
  * @returns `true` if completion should be deferred.
225
230
  * @since 1.0.0
231
+ * @since 1.0.0 Added optional `exec` parameter.
226
232
  */
227
- shouldDeferCompletion?(state: TState): boolean;
233
+ shouldDeferCompletion?(state: TState, exec?: ExecutionContext): boolean;
228
234
  /**
229
235
  * Normalizes a parsed value according to the underlying value parser's
230
236
  * configuration. When present, {@link withDefault} calls this method
@@ -246,11 +252,82 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
246
252
  */
247
253
  normalizeValue?(value: TValue): TValue;
248
254
  }
255
+ /**
256
+ * Parser-local frame data containing the input buffer and parser state.
257
+ * This represents the per-parser progress during parsing, separated from
258
+ * cross-cutting execution context.
259
+ * @template TState The type of the state used during parsing.
260
+ * @since 1.0.0
261
+ */
262
+ interface ParseFrame<TState> {
263
+ /**
264
+ * The array of input strings that the parser is currently processing.
265
+ */
266
+ readonly buffer: readonly string[];
267
+ /**
268
+ * The current state of the parser, which is used to track
269
+ * the progress of parsing and any accumulated data.
270
+ */
271
+ readonly state: TState;
272
+ /**
273
+ * A flag indicating whether no more options should be parsed and instead
274
+ * the remaining input should be treated as positional arguments.
275
+ */
276
+ readonly optionsTerminated: boolean;
277
+ }
278
+ /**
279
+ * The phase of the execution pipeline.
280
+ * @since 1.0.0
281
+ */
282
+ type ExecutionPhase = "parse" | "precomplete" | "resolve" | "complete" | "suggest";
283
+ /**
284
+ * Shared execution context carrying cross-cutting runtime data.
285
+ * This includes information that is shared across all parsers in a parse
286
+ * tree, such as usage information, dependency registries, and the current
287
+ * execution phase.
288
+ * @since 1.0.0
289
+ */
290
+ interface ExecutionContext {
291
+ /**
292
+ * Usage information for the entire parser tree.
293
+ */
294
+ readonly usage: Usage;
295
+ /**
296
+ * The current phase of the execution pipeline.
297
+ */
298
+ readonly phase: ExecutionPhase;
299
+ /**
300
+ * The path from the root to the current parser in the parse tree.
301
+ * Used by constructs to track the current position during dependency
302
+ * resolution and completion.
303
+ */
304
+ readonly path: readonly PropertyKey[];
305
+ /**
306
+ * A registry containing resolved dependency values from DependencySource
307
+ * parsers.
308
+ * @since 0.10.0
309
+ */
310
+ readonly dependencyRegistry?: DependencyRegistryLike;
311
+ }
249
312
  /**
250
313
  * The context of the parser, which includes the input buffer and the state.
314
+ *
315
+ * `ParserContext` provides structured access to shared execution context
316
+ * via {@link exec}, and flat access to all fields for backward
317
+ * compatibility.
318
+ *
251
319
  * @template TState The type of the state used during parsing.
252
320
  */
253
321
  interface ParserContext<TState> {
322
+ /**
323
+ * Shared execution context (usage, phase, path, dependencyRegistry).
324
+ *
325
+ * Present when the context was created via {@link createParserContext}.
326
+ * Later runtime work will make this field required.
327
+ *
328
+ * @since 1.0.0
329
+ */
330
+ readonly exec?: ExecutionContext;
254
331
  /**
255
332
  * The array of input strings that the parser is currently processing.
256
333
  */
@@ -284,6 +361,19 @@ interface ParserContext<TState> {
284
361
  */
285
362
  readonly dependencyRegistry?: DependencyRegistryLike;
286
363
  }
364
+ /**
365
+ * Creates a {@link ParserContext} from a {@link ParseFrame} and an
366
+ * {@link ExecutionContext}. The returned object provides both structured
367
+ * access (`frame`, `exec`) and flat access (`buffer`, `state`, etc.)
368
+ * for backward compatibility.
369
+ *
370
+ * @template TState The type of the state used during parsing.
371
+ * @param frame Parser-local frame data.
372
+ * @param exec Shared execution context.
373
+ * @returns A {@link ParserContext} instance.
374
+ * @since 1.0.0
375
+ */
376
+ declare function createParserContext<TState>(frame: ParseFrame<TState>, exec: ExecutionContext): ParserContext<TState>;
287
377
  /**
288
378
  * Represents a suggestion for command-line completion or guidance.
289
379
  * @since 0.6.0
@@ -648,4 +738,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, argsOrOpti
648
738
  declare function getDocPage(parser: Parser<"async", unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): Promise<DocPage | undefined>;
649
739
  declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): ModeValue<M, DocPage | undefined>;
650
740
  //#endregion
651
- export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
741
+ export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, ExecutionContext, ExecutionPhase, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, createParserContext, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };