@optique/core 1.4.0-dev.2614 → 1.4.0-dev.2616

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.
@@ -8,10 +8,10 @@ const require_internal_dependency = require('./internal/dependency.cjs');
8
8
  const require_dependency_runtime = require('./dependency-runtime.cjs');
9
9
  const require_internal_parser = require('./internal/parser.cjs');
10
10
  const require_annotation_state = require('./annotation-state.cjs');
11
+ const require_execution_context = require('./execution-context.cjs');
11
12
  const require_usage_internals = require('./usage-internals.cjs');
12
13
  const require_short_option = require('./short-option.cjs');
13
14
  const require_command_alias = require('./internal/command-alias.cjs');
14
- const require_execution_context = require('./execution-context.cjs');
15
15
  const require_phase2_seed = require('./phase2-seed.cjs');
16
16
  const require_modifiers = require('./modifiers.cjs');
17
17
  const require_suggestion = require('./suggestion.cjs');
@@ -8,10 +8,10 @@ import { createDependencySourceState, dependencyId, isDependencySourceState, isP
8
8
  import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, completeEffectfulSourcesAsync, createDependencyRuntimeContext, effectfulSchedulingNodesKey, exclusiveSourceScopeKey, extractRawInputFromState, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, forkRuntimeForCommittedSubtree, getDefaultDependencySnapshot, guaranteedStaticSourceIdsKey, hasInactiveCompletion, isMatchedState, recordSourceScope, releaseUncollectedSourceValues, replaceCachedBarrierFailure, resolveDerivedSourceValues, resolveDerivedSourceValuesAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync, serializeSchedulingPath, sourceCollectionExpansionKey, staticSourceScopeKey } from "./dependency-runtime.js";
9
9
  import { defineInheritedAnnotationParser, defineParseLanes, getOwnParseLanes, getParserSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
10
10
  import { annotationViewTargets, getWrappedChildParseState, getWrappedChildState, reconcileObjectChildState, unwrapAnnotationView } from "./annotation-state.js";
11
+ import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
11
12
  import { collectLeadingCandidates } from "./usage-internals.js";
12
13
  import { adoptOptionScope, combinedOptionScope, conditionalOptionScope, forkOptionScope, restoreOptionScope, scopeParser, selectableOptionScope, withOptionScope, withParserOptionScope } from "./short-option.js";
13
14
  import { allowDuplicateLeadingCommandNamesKey } from "./internal/command-alias.js";
14
- import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
15
15
  import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
16
16
  import { fluent } from "./modifiers.js";
17
17
  import { DEFAULT_FIND_SIMILAR_OPTIONS, createErrorWithSuggestions, createSuggestionMessage, deduplicateSuggestions, expandCommandAliasSuggestions, findSimilar } from "./suggestion.js";
@@ -2,6 +2,7 @@ const require_internal_annotations = require('./internal/annotations.cjs');
2
2
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
3
3
  const require_internal_parser = require('./internal/parser.cjs');
4
4
  const require_annotation_state = require('./annotation-state.cjs');
5
+ const require_short_option = require('./short-option.cjs');
5
6
  const require_phase2_seed = require('./phase2-seed.cjs');
6
7
 
7
8
  //#region src/extension.ts
@@ -28,6 +29,19 @@ function defineTraits(parser, traits) {
28
29
  });
29
30
  }
30
31
  /**
32
+ * Preserves a wrapped parser's reachable option names in the same parse path.
33
+ * Call this when a transparent wrapper constructs a fresh parser object instead
34
+ * of copying the inner parser with object spread.
35
+ *
36
+ * @param parser The wrapper parser to annotate.
37
+ * @param innerParser The parser that handles the wrapper's CLI input.
38
+ * @throws {TypeError} If scope metadata cannot be defined on the wrapper.
39
+ * @since 1.4.0
40
+ */
41
+ function inheritOptionScope$1(parser, innerParser) {
42
+ require_short_option.inheritOptionScope(parser, innerParser);
43
+ }
44
+ /**
31
45
  * Reads the stable extension traits defined on a parser object.
32
46
  *
33
47
  * @param parser The parser object to inspect.
@@ -80,6 +94,7 @@ exports.dispatchByMode = require_mode_dispatch.dispatchByMode;
80
94
  exports.extractPhase2SeedKey = require_phase2_seed.extractPhase2SeedKey;
81
95
  exports.getTraits = getTraits;
82
96
  exports.inheritAnnotations = require_internal_annotations.inheritAnnotations;
97
+ exports.inheritOptionScope = inheritOptionScope$1;
83
98
  exports.injectAnnotations = require_internal_annotations.injectAnnotations;
84
99
  exports.isInjectedAnnotationState = require_internal_annotations.isInjectedAnnotationState;
85
100
  exports.mapModeValue = require_mode_dispatch.mapModeValue;
@@ -60,6 +60,17 @@ type ParserSourceMetadata<M extends Mode = Mode, TValue = unknown, TState = unkn
60
60
  * @since 1.0.0
61
61
  */
62
62
  declare function defineTraits(parser: object, traits: ParserTraits): void;
63
+ /**
64
+ * Preserves a wrapped parser's reachable option names in the same parse path.
65
+ * Call this when a transparent wrapper constructs a fresh parser object instead
66
+ * of copying the inner parser with object spread.
67
+ *
68
+ * @param parser The wrapper parser to annotate.
69
+ * @param innerParser The parser that handles the wrapper's CLI input.
70
+ * @throws {TypeError} If scope metadata cannot be defined on the wrapper.
71
+ * @since 1.4.0
72
+ */
73
+ declare function inheritOptionScope(parser: object, innerParser: Parser<Mode, unknown, unknown>): void;
63
74
  /**
64
75
  * Reads the stable extension traits defined on a parser object.
65
76
  *
@@ -95,4 +106,4 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
95
106
  */
96
107
  declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
97
108
  //#endregion
98
- export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
109
+ export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
@@ -60,6 +60,17 @@ type ParserSourceMetadata<M extends Mode = Mode, TValue = unknown, TState = unkn
60
60
  * @since 1.0.0
61
61
  */
62
62
  declare function defineTraits(parser: object, traits: ParserTraits): void;
63
+ /**
64
+ * Preserves a wrapped parser's reachable option names in the same parse path.
65
+ * Call this when a transparent wrapper constructs a fresh parser object instead
66
+ * of copying the inner parser with object spread.
67
+ *
68
+ * @param parser The wrapper parser to annotate.
69
+ * @param innerParser The parser that handles the wrapper's CLI input.
70
+ * @throws {TypeError} If scope metadata cannot be defined on the wrapper.
71
+ * @since 1.4.0
72
+ */
73
+ declare function inheritOptionScope(parser: object, innerParser: Parser<Mode, unknown, unknown>): void;
63
74
  /**
64
75
  * Reads the stable extension traits defined on a parser object.
65
76
  *
@@ -95,4 +106,4 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
95
106
  */
96
107
  declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
97
108
  //#endregion
98
- export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
109
+ export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
package/dist/extension.js CHANGED
@@ -2,6 +2,7 @@ import { inheritAnnotations, injectAnnotations, isInjectedAnnotationState, unwra
2
2
  import { dispatchByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
3
3
  import { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
4
4
  import { withAnnotationView } from "./annotation-state.js";
5
+ import { inheritOptionScope } from "./short-option.js";
5
6
  import { extractPhase2SeedKey } from "./phase2-seed.js";
6
7
 
7
8
  //#region src/extension.ts
@@ -28,6 +29,19 @@ function defineTraits(parser, traits) {
28
29
  });
29
30
  }
30
31
  /**
32
+ * Preserves a wrapped parser's reachable option names in the same parse path.
33
+ * Call this when a transparent wrapper constructs a fresh parser object instead
34
+ * of copying the inner parser with object spread.
35
+ *
36
+ * @param parser The wrapper parser to annotate.
37
+ * @param innerParser The parser that handles the wrapper's CLI input.
38
+ * @throws {TypeError} If scope metadata cannot be defined on the wrapper.
39
+ * @since 1.4.0
40
+ */
41
+ function inheritOptionScope$1(parser, innerParser) {
42
+ inheritOptionScope(parser, innerParser);
43
+ }
44
+ /**
31
45
  * Reads the stable extension traits defined on a parser object.
32
46
  *
33
47
  * @param parser The parser object to inspect.
@@ -74,4 +88,4 @@ function mapSourceMetadata(parser, mapSource) {
74
88
  }
75
89
 
76
90
  //#endregion
77
- export { defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
91
+ export { defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope$1 as inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
@@ -4,8 +4,8 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
4
4
  const require_dependency_runtime = require('./dependency-runtime.cjs');
5
5
  const require_internal_parser = require('./internal/parser.cjs');
6
6
  const require_annotation_state = require('./annotation-state.cjs');
7
- const require_short_option = require('./short-option.cjs');
8
7
  const require_execution_context = require('./execution-context.cjs');
8
+ const require_short_option = require('./short-option.cjs');
9
9
  const require_phase2_seed = require('./phase2-seed.cjs');
10
10
  const require_dependency_metadata = require('./dependency-metadata.cjs');
11
11
 
package/dist/modifiers.js CHANGED
@@ -4,8 +4,8 @@ import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } fro
4
4
  import { defineForwardedEffectfulSchedulingNodes } from "./dependency-runtime.js";
5
5
  import { defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getOwnParseLanes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
6
6
  import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
7
- import { combinedOptionScope, repeatedOptionScope, scopeParser } from "./short-option.js";
8
7
  import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
8
+ import { combinedOptionScope, repeatedOptionScope, scopeParser } from "./short-option.js";
9
9
  import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
10
10
  import { composeDependencyMetadata } from "./dependency-metadata.js";
11
11
 
@@ -6,10 +6,10 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
6
6
  const require_internal_dependency = require('./internal/dependency.cjs');
7
7
  const require_dependency_runtime = require('./dependency-runtime.cjs');
8
8
  const require_annotation_state = require('./annotation-state.cjs');
9
+ const require_execution_context = require('./execution-context.cjs');
9
10
  const require_usage_internals = require('./usage-internals.cjs');
10
11
  const require_short_option = require('./short-option.cjs');
11
12
  const require_command_alias = require('./internal/command-alias.cjs');
12
- const require_execution_context = require('./execution-context.cjs');
13
13
  const require_phase2_seed = require('./phase2-seed.cjs');
14
14
  const require_dependency_metadata = require('./dependency-metadata.cjs');
15
15
  const require_modifiers = require('./modifiers.cjs');
@@ -6,10 +6,10 @@ import { dispatchByMode, dispatchIterableByMode, wrapForMode } from "./internal/
6
6
  import { getDefaultValuesFunction, getDependencyIds, getSnapshottedDefaultDependencyValues, isDerivedValueParser, suggestWithDependency } from "./internal/dependency.js";
7
7
  import { effectfulSchedulingNodesKey, exclusiveSourceScopeKey, includeSourceFailureChain, recordDerivedRawInput, replayDerivedParser, replayDerivedParserAsync, sourceCollectionExpansionKey } from "./dependency-runtime.js";
8
8
  import { getWrappedChildParseState, getWrappedChildState, isAnnotationWrappedInitialState, normalizeInjectedAnnotationState } from "./annotation-state.js";
9
+ import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
9
10
  import { extractLeadingCommandNames } from "./usage-internals.js";
10
11
  import { attachedValuePrefix, combinedOptionScope, fullNameOwnsToken, prefixSuggestion, scopeParser, selectableOptionScope } from "./short-option.js";
11
12
  import { hiddenCommandAliasesKey } from "./internal/command-alias.js";
12
- import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
13
13
  import { completeOrExtractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
14
14
  import { extractDependencyMetadata } from "./dependency-metadata.js";
15
15
  import { fluent } from "./modifiers.js";
@@ -1,6 +1,7 @@
1
1
  const require_internal_annotations = require('./internal/annotations.cjs');
2
2
  const require_usage = require('./usage.cjs');
3
3
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
4
+ const require_execution_context = require('./execution-context.cjs');
4
5
  const require_usage_internals = require('./usage-internals.cjs');
5
6
 
6
7
  //#region src/short-option.ts
@@ -8,13 +9,22 @@ const optionScopeKey = Symbol("optionScope");
8
9
  const optionPathKey = Symbol("optionScopePath");
9
10
  const scopeSourceKey = Symbol("optionScopeSource");
10
11
  const scopeLocations = /* @__PURE__ */ new WeakMap();
11
- const boundScopes = /* @__PURE__ */ new WeakMap();
12
- function bindScope(source, path) {
12
+ const scopeBindings = /* @__PURE__ */ new WeakMap();
13
+ function getScopeBindings(selections) {
14
+ let bindings = scopeBindings.get(selections);
15
+ if (bindings == null) {
16
+ bindings = /* @__PURE__ */ new WeakMap();
17
+ scopeBindings.set(selections, bindings);
18
+ }
19
+ return bindings;
20
+ }
21
+ function bindScope(source, path, selections) {
22
+ const boundScopes = getScopeBindings(selections);
13
23
  let node = boundScopes.get(source);
14
24
  if (node == null) {
15
25
  node = {
16
26
  children: /* @__PURE__ */ new Map(),
17
- bound: (selections, arities, context) => source(selections, arities, context, [])
27
+ bound: (selections$1, arities, context) => source(selections$1, arities, context, [])
18
28
  };
19
29
  boundScopes.set(source, node);
20
30
  scopeLocations.set(node.bound, []);
@@ -25,7 +35,7 @@ function bindScope(source, path) {
25
35
  const occurrence = path.slice(0, i + 1);
26
36
  child = {
27
37
  children: /* @__PURE__ */ new Map(),
28
- bound: (selections, arities, context) => source(selections, arities, context, occurrence)
38
+ bound: (selections$1, arities, context) => source(selections$1, arities, context, occurrence)
29
39
  };
30
40
  node.children.set(path[i], child);
31
41
  scopeLocations.set(child.bound, occurrence);
@@ -58,6 +68,14 @@ function parserScope(parser) {
58
68
  }
59
69
  return source;
60
70
  }
71
+ /** Preserves dynamic option ownership through a transparent wrapper. @internal */
72
+ function inheritOptionScope(target, inner) {
73
+ Object.defineProperty(target, scopeSourceKey, {
74
+ value: parserScope(inner),
75
+ enumerable: true,
76
+ configurable: true
77
+ });
78
+ }
61
79
  /** Combines declarations without flattening conditional ownership. @internal */
62
80
  function combinedOptionScope(parsers, segments) {
63
81
  return (selections, arities, context, path = []) => new Set(parsers.flatMap((parser, index) => [...parserScope(parser)(selections, arities, context, segments == null ? path : [...path, segments[index]])]));
@@ -80,18 +98,23 @@ function repeatedOptionScope(parser) {
80
98
  }
81
99
  /** Tracks declarations after a command or discriminator routes input. @internal */
82
100
  function selectableOptionScope(initial) {
83
- const source = (selections, arities, context, path = []) => (selections.get(bindScope(source, path)) ?? initial)(selections, arities, context, path);
101
+ const source = (selections, arities, context, path = []) => (selections.get(bindScope(source, path, selections)) ?? initial)(selections, arities, context, path);
84
102
  return {
85
103
  source,
86
104
  select(context, selected) {
87
- context[optionScopeKey]?.selections.set(bindScope(source, scopePath(context)), selected);
105
+ const selections = context[optionScopeKey]?.selections;
106
+ if (selections == null) return;
107
+ selections.set(bindScope(source, scopePath(context), selections), selected);
88
108
  }
89
109
  };
90
110
  }
91
111
  /** Keeps selected conditional names distinct from sibling declarations. @internal */
92
112
  function conditionalOptionScope(discriminator, fallback, candidates = []) {
93
113
  const scope = selectableOptionScope((selections, arities, context, path) => {
94
- const canSkip = discriminator.canSkip?.(context == null ? discriminator.initialState : require_internal_annotations.inheritAnnotations(context.state, discriminator.initialState), context?.exec) === true;
114
+ const canSkip = discriminator.canSkip?.(context == null ? discriminator.initialState : require_internal_annotations.inheritAnnotations(context.state, discriminator.initialState), context?.exec == null ? void 0 : require_execution_context.withChildExecPath({
115
+ ...context.exec,
116
+ path: path ?? scopePath(context)
117
+ }, "_discriminator")) === true;
95
118
  return combinedOptionScope([
96
119
  discriminator,
97
120
  ...canSkip ? candidates : [],
@@ -130,23 +153,27 @@ function withOptionScope(context, names) {
130
153
  /** Adds a parser's owned declarations, retaining modifier metadata. @internal */
131
154
  function withParserOptionScope(context, parser, segment) {
132
155
  const inherited = context[optionScopeKey];
156
+ const selections = inherited?.selections ?? /* @__PURE__ */ new Map();
133
157
  return {
134
158
  ...context,
135
159
  [optionScopeKey]: {
136
160
  names: inherited?.names ?? /* @__PURE__ */ new Set(),
137
- sources: new Set([...inherited?.sources ?? [], bindScope(parserScope(parser), segment == null ? scopePath(context) : [...scopePath(context), segment])]),
138
- selections: inherited?.selections ?? /* @__PURE__ */ new Map()
161
+ sources: new Set([...inherited?.sources ?? [], bindScope(parserScope(parser), segment == null ? scopePath(context) : [...scopePath(context), segment], selections)]),
162
+ selections
139
163
  }
140
164
  };
141
165
  }
142
166
  /** Isolates route selections while probing a competing branch. @internal */
143
167
  function forkOptionScope(context) {
144
168
  const scoped = context[optionScopeKey];
145
- return scoped == null ? context : {
169
+ if (scoped == null) return context;
170
+ const selections = new Map(scoped.selections);
171
+ scopeBindings.set(selections, getScopeBindings(scoped.selections));
172
+ return {
146
173
  ...context,
147
174
  [optionScopeKey]: {
148
175
  ...scoped,
149
- selections: new Map(scoped.selections)
176
+ selections
150
177
  }
151
178
  };
152
179
  }
@@ -273,6 +300,7 @@ exports.combinedOptionScope = combinedOptionScope;
273
300
  exports.conditionalOptionScope = conditionalOptionScope;
274
301
  exports.forkOptionScope = forkOptionScope;
275
302
  exports.fullNameOwnsToken = fullNameOwnsToken;
303
+ exports.inheritOptionScope = inheritOptionScope;
276
304
  exports.prefixSuggestion = prefixSuggestion;
277
305
  exports.repeatedOptionScope = repeatedOptionScope;
278
306
  exports.restoreOptionScope = restoreOptionScope;
@@ -1,6 +1,7 @@
1
1
  import { inheritAnnotations } from "./internal/annotations.js";
2
2
  import { extractOptionNames } from "./usage.js";
3
3
  import { mapModeValue } from "./internal/mode-dispatch.js";
4
+ import { withChildExecPath } from "./execution-context.js";
4
5
  import { collectOptionNamesAtCurrentCommandDepth } from "./usage-internals.js";
5
6
 
6
7
  //#region src/short-option.ts
@@ -8,13 +9,22 @@ const optionScopeKey = Symbol("optionScope");
8
9
  const optionPathKey = Symbol("optionScopePath");
9
10
  const scopeSourceKey = Symbol("optionScopeSource");
10
11
  const scopeLocations = /* @__PURE__ */ new WeakMap();
11
- const boundScopes = /* @__PURE__ */ new WeakMap();
12
- function bindScope(source, path) {
12
+ const scopeBindings = /* @__PURE__ */ new WeakMap();
13
+ function getScopeBindings(selections) {
14
+ let bindings = scopeBindings.get(selections);
15
+ if (bindings == null) {
16
+ bindings = /* @__PURE__ */ new WeakMap();
17
+ scopeBindings.set(selections, bindings);
18
+ }
19
+ return bindings;
20
+ }
21
+ function bindScope(source, path, selections) {
22
+ const boundScopes = getScopeBindings(selections);
13
23
  let node = boundScopes.get(source);
14
24
  if (node == null) {
15
25
  node = {
16
26
  children: /* @__PURE__ */ new Map(),
17
- bound: (selections, arities, context) => source(selections, arities, context, [])
27
+ bound: (selections$1, arities, context) => source(selections$1, arities, context, [])
18
28
  };
19
29
  boundScopes.set(source, node);
20
30
  scopeLocations.set(node.bound, []);
@@ -25,7 +35,7 @@ function bindScope(source, path) {
25
35
  const occurrence = path.slice(0, i + 1);
26
36
  child = {
27
37
  children: /* @__PURE__ */ new Map(),
28
- bound: (selections, arities, context) => source(selections, arities, context, occurrence)
38
+ bound: (selections$1, arities, context) => source(selections$1, arities, context, occurrence)
29
39
  };
30
40
  node.children.set(path[i], child);
31
41
  scopeLocations.set(child.bound, occurrence);
@@ -58,6 +68,14 @@ function parserScope(parser) {
58
68
  }
59
69
  return source;
60
70
  }
71
+ /** Preserves dynamic option ownership through a transparent wrapper. @internal */
72
+ function inheritOptionScope(target, inner) {
73
+ Object.defineProperty(target, scopeSourceKey, {
74
+ value: parserScope(inner),
75
+ enumerable: true,
76
+ configurable: true
77
+ });
78
+ }
61
79
  /** Combines declarations without flattening conditional ownership. @internal */
62
80
  function combinedOptionScope(parsers, segments) {
63
81
  return (selections, arities, context, path = []) => new Set(parsers.flatMap((parser, index) => [...parserScope(parser)(selections, arities, context, segments == null ? path : [...path, segments[index]])]));
@@ -80,18 +98,23 @@ function repeatedOptionScope(parser) {
80
98
  }
81
99
  /** Tracks declarations after a command or discriminator routes input. @internal */
82
100
  function selectableOptionScope(initial) {
83
- const source = (selections, arities, context, path = []) => (selections.get(bindScope(source, path)) ?? initial)(selections, arities, context, path);
101
+ const source = (selections, arities, context, path = []) => (selections.get(bindScope(source, path, selections)) ?? initial)(selections, arities, context, path);
84
102
  return {
85
103
  source,
86
104
  select(context, selected) {
87
- context[optionScopeKey]?.selections.set(bindScope(source, scopePath(context)), selected);
105
+ const selections = context[optionScopeKey]?.selections;
106
+ if (selections == null) return;
107
+ selections.set(bindScope(source, scopePath(context), selections), selected);
88
108
  }
89
109
  };
90
110
  }
91
111
  /** Keeps selected conditional names distinct from sibling declarations. @internal */
92
112
  function conditionalOptionScope(discriminator, fallback, candidates = []) {
93
113
  const scope = selectableOptionScope((selections, arities, context, path) => {
94
- const canSkip = discriminator.canSkip?.(context == null ? discriminator.initialState : inheritAnnotations(context.state, discriminator.initialState), context?.exec) === true;
114
+ const canSkip = discriminator.canSkip?.(context == null ? discriminator.initialState : inheritAnnotations(context.state, discriminator.initialState), context?.exec == null ? void 0 : withChildExecPath({
115
+ ...context.exec,
116
+ path: path ?? scopePath(context)
117
+ }, "_discriminator")) === true;
95
118
  return combinedOptionScope([
96
119
  discriminator,
97
120
  ...canSkip ? candidates : [],
@@ -130,23 +153,27 @@ function withOptionScope(context, names) {
130
153
  /** Adds a parser's owned declarations, retaining modifier metadata. @internal */
131
154
  function withParserOptionScope(context, parser, segment) {
132
155
  const inherited = context[optionScopeKey];
156
+ const selections = inherited?.selections ?? /* @__PURE__ */ new Map();
133
157
  return {
134
158
  ...context,
135
159
  [optionScopeKey]: {
136
160
  names: inherited?.names ?? /* @__PURE__ */ new Set(),
137
- sources: new Set([...inherited?.sources ?? [], bindScope(parserScope(parser), segment == null ? scopePath(context) : [...scopePath(context), segment])]),
138
- selections: inherited?.selections ?? /* @__PURE__ */ new Map()
161
+ sources: new Set([...inherited?.sources ?? [], bindScope(parserScope(parser), segment == null ? scopePath(context) : [...scopePath(context), segment], selections)]),
162
+ selections
139
163
  }
140
164
  };
141
165
  }
142
166
  /** Isolates route selections while probing a competing branch. @internal */
143
167
  function forkOptionScope(context) {
144
168
  const scoped = context[optionScopeKey];
145
- return scoped == null ? context : {
169
+ if (scoped == null) return context;
170
+ const selections = new Map(scoped.selections);
171
+ scopeBindings.set(selections, getScopeBindings(scoped.selections));
172
+ return {
146
173
  ...context,
147
174
  [optionScopeKey]: {
148
175
  ...scoped,
149
- selections: new Map(scoped.selections)
176
+ selections
150
177
  }
151
178
  };
152
179
  }
@@ -267,4 +294,4 @@ function prefixSuggestion(head, suggestion) {
267
294
  }
268
295
 
269
296
  //#endregion
270
- export { adoptOptionScope, attachedValuePrefix, combinedOptionScope, conditionalOptionScope, forkOptionScope, fullNameOwnsToken, prefixSuggestion, repeatedOptionScope, restoreOptionScope, scopeParser, selectableOptionScope, withOptionScope, withOptionScopeChild, withParserOptionScope };
297
+ export { adoptOptionScope, attachedValuePrefix, combinedOptionScope, conditionalOptionScope, forkOptionScope, fullNameOwnsToken, inheritOptionScope, prefixSuggestion, repeatedOptionScope, restoreOptionScope, scopeParser, selectableOptionScope, withOptionScope, withOptionScopeChild, withParserOptionScope };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.4.0-dev.2614",
3
+ "version": "1.4.0-dev.2616",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",
@@ -237,7 +237,7 @@
237
237
  },
238
238
  "sideEffects": false,
239
239
  "devDependencies": {
240
- "@optique/env": "1.4.0-dev.2614+5915742e",
240
+ "@optique/env": "1.4.0-dev.2616+37c516eb",
241
241
  "@types/node": "^24.0.0",
242
242
  "fast-check": "^4.7.0",
243
243
  "tsdown": "^0.13.0",