@optique/core 1.0.0-dev.1891 → 1.0.0-dev.1893

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.
@@ -88,6 +88,70 @@ function hasDelegatedAnnotationCarrier(state) {
88
88
  return state != null && typeof state === "object" && (require_annotations.isInjectedAnnotationWrapper(state) || annotationViewTargets.has(state));
89
89
  }
90
90
  /**
91
+ * Recursively removes delegated annotation carriers from plain-object and array
92
+ * structures.
93
+ *
94
+ * Nested plain objects and arrays are shallow-cloned only when a delegated
95
+ * carrier is found below them. Non-plain objects are unwrapped at the top
96
+ * level and then preserved as-is to avoid mutating or reconstructing class
97
+ * instances.
98
+ *
99
+ * @param value The candidate value to normalize.
100
+ * @param seen Tracks already-normalized objects so cyclic values keep their
101
+ * shape.
102
+ * @returns The original value when no delegated carriers are present, or a
103
+ * normalized clone with delegated carriers removed.
104
+ * @internal
105
+ */
106
+ function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
107
+ const normalized = normalizeDelegatedAnnotationState(value);
108
+ if (normalized == null || typeof normalized !== "object") return normalized;
109
+ const source = normalized;
110
+ if (seen.has(source)) return seen.get(source);
111
+ if (Array.isArray(source)) {
112
+ let changed$1 = false;
113
+ const clone$1 = [...source];
114
+ seen.set(source, clone$1);
115
+ for (let i = 0; i < source.length; i++) {
116
+ const nextValue = normalizeNestedDelegatedAnnotationState(source[i], seen);
117
+ if (nextValue !== source[i]) {
118
+ clone$1[i] = nextValue;
119
+ changed$1 = true;
120
+ }
121
+ }
122
+ if (!changed$1) {
123
+ seen.set(source, source);
124
+ return source;
125
+ }
126
+ return clone$1;
127
+ }
128
+ const proto = Object.getPrototypeOf(source);
129
+ if (proto !== Object.prototype && proto !== null) return normalized;
130
+ const descriptors = Object.getOwnPropertyDescriptors(source);
131
+ let changed = false;
132
+ const clone = Object.create(proto);
133
+ seen.set(source, clone);
134
+ for (const key of Reflect.ownKeys(descriptors)) {
135
+ const descriptor = descriptors[key];
136
+ if (descriptor != null && "value" in descriptor) {
137
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
138
+ if (nextValue !== descriptor.value) {
139
+ descriptors[key] = {
140
+ ...descriptor,
141
+ value: nextValue
142
+ };
143
+ changed = true;
144
+ }
145
+ }
146
+ }
147
+ if (!changed) {
148
+ seen.set(source, source);
149
+ return source;
150
+ }
151
+ Object.defineProperties(clone, descriptors);
152
+ return clone;
153
+ }
154
+ /**
91
155
  * Creates a short-lived delegated state that exposes the parent's annotations
92
156
  * regardless of the child state's runtime shape.
93
157
  *
@@ -105,7 +169,7 @@ function getDelegatedAnnotationState(parentState, childState) {
105
169
  const annotations = require_annotations.getAnnotations(parentState);
106
170
  if (annotations === void 0 || require_annotations.getAnnotations(childState) === annotations) return childState;
107
171
  if (childState == null || typeof childState !== "object") return require_annotations.injectAnnotations(childState, annotations);
108
- if (require_annotations.isInjectedAnnotationWrapper(childState)) return require_annotations.injectAnnotations(childState, annotations);
172
+ if (require_annotations.isInjectedAnnotationWrapper(childState)) return require_annotations.injectAnnotations(normalizeInjectedAnnotationState(childState), annotations);
109
173
  if (isNonPlainDelegatedObject(childState)) return withAnnotationView(childState, annotations);
110
174
  return require_annotations.inheritAnnotations(parentState, childState);
111
175
  }
@@ -201,5 +265,6 @@ exports.hasDelegatedAnnotationCarrier = hasDelegatedAnnotationCarrier;
201
265
  exports.isAnnotationWrappedInitialState = isAnnotationWrappedInitialState;
202
266
  exports.normalizeDelegatedAnnotationState = normalizeDelegatedAnnotationState;
203
267
  exports.normalizeInjectedAnnotationState = normalizeInjectedAnnotationState;
268
+ exports.normalizeNestedDelegatedAnnotationState = normalizeNestedDelegatedAnnotationState;
204
269
  exports.reconcileObjectChildState = reconcileObjectChildState;
205
270
  exports.unwrapAnnotationView = unwrapAnnotationView;
@@ -88,6 +88,70 @@ function hasDelegatedAnnotationCarrier(state) {
88
88
  return state != null && typeof state === "object" && (isInjectedAnnotationWrapper(state) || annotationViewTargets.has(state));
89
89
  }
90
90
  /**
91
+ * Recursively removes delegated annotation carriers from plain-object and array
92
+ * structures.
93
+ *
94
+ * Nested plain objects and arrays are shallow-cloned only when a delegated
95
+ * carrier is found below them. Non-plain objects are unwrapped at the top
96
+ * level and then preserved as-is to avoid mutating or reconstructing class
97
+ * instances.
98
+ *
99
+ * @param value The candidate value to normalize.
100
+ * @param seen Tracks already-normalized objects so cyclic values keep their
101
+ * shape.
102
+ * @returns The original value when no delegated carriers are present, or a
103
+ * normalized clone with delegated carriers removed.
104
+ * @internal
105
+ */
106
+ function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
107
+ const normalized = normalizeDelegatedAnnotationState(value);
108
+ if (normalized == null || typeof normalized !== "object") return normalized;
109
+ const source = normalized;
110
+ if (seen.has(source)) return seen.get(source);
111
+ if (Array.isArray(source)) {
112
+ let changed$1 = false;
113
+ const clone$1 = [...source];
114
+ seen.set(source, clone$1);
115
+ for (let i = 0; i < source.length; i++) {
116
+ const nextValue = normalizeNestedDelegatedAnnotationState(source[i], seen);
117
+ if (nextValue !== source[i]) {
118
+ clone$1[i] = nextValue;
119
+ changed$1 = true;
120
+ }
121
+ }
122
+ if (!changed$1) {
123
+ seen.set(source, source);
124
+ return source;
125
+ }
126
+ return clone$1;
127
+ }
128
+ const proto = Object.getPrototypeOf(source);
129
+ if (proto !== Object.prototype && proto !== null) return normalized;
130
+ const descriptors = Object.getOwnPropertyDescriptors(source);
131
+ let changed = false;
132
+ const clone = Object.create(proto);
133
+ seen.set(source, clone);
134
+ for (const key of Reflect.ownKeys(descriptors)) {
135
+ const descriptor = descriptors[key];
136
+ if (descriptor != null && "value" in descriptor) {
137
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
138
+ if (nextValue !== descriptor.value) {
139
+ descriptors[key] = {
140
+ ...descriptor,
141
+ value: nextValue
142
+ };
143
+ changed = true;
144
+ }
145
+ }
146
+ }
147
+ if (!changed) {
148
+ seen.set(source, source);
149
+ return source;
150
+ }
151
+ Object.defineProperties(clone, descriptors);
152
+ return clone;
153
+ }
154
+ /**
91
155
  * Creates a short-lived delegated state that exposes the parent's annotations
92
156
  * regardless of the child state's runtime shape.
93
157
  *
@@ -105,7 +169,7 @@ function getDelegatedAnnotationState(parentState, childState) {
105
169
  const annotations = getAnnotations(parentState);
106
170
  if (annotations === void 0 || getAnnotations(childState) === annotations) return childState;
107
171
  if (childState == null || typeof childState !== "object") return injectAnnotations(childState, annotations);
108
- if (isInjectedAnnotationWrapper(childState)) return injectAnnotations(childState, annotations);
172
+ if (isInjectedAnnotationWrapper(childState)) return injectAnnotations(normalizeInjectedAnnotationState(childState), annotations);
109
173
  if (isNonPlainDelegatedObject(childState)) return withAnnotationView(childState, annotations);
110
174
  return inheritAnnotations(parentState, childState);
111
175
  }
@@ -193,4 +257,4 @@ function reconcileObjectChildState(parentState, childState) {
193
257
  }
194
258
 
195
259
  //#endregion
196
- export { annotationViewTargets, getDelegatedAnnotationState, getWrappedChildParseState, getWrappedChildState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeInjectedAnnotationState, reconcileObjectChildState, unwrapAnnotationView };
260
+ export { annotationViewTargets, getDelegatedAnnotationState, getWrappedChildParseState, getWrappedChildState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeInjectedAnnotationState, normalizeNestedDelegatedAnnotationState, reconcileObjectChildState, unwrapAnnotationView };
@@ -85,58 +85,72 @@ function isPromiseLike(value) {
85
85
  function normalizeOptionalLikeCompleteResult(result) {
86
86
  return result.success ? {
87
87
  ...result,
88
- value: require_annotation_state.normalizeDelegatedAnnotationState(result.value)
88
+ value: require_annotation_state.normalizeNestedDelegatedAnnotationState(result.value)
89
89
  } : result;
90
90
  }
91
91
  function completeOptionalLikeSync(parser, state, exec) {
92
- const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(state);
92
+ const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
93
93
  try {
94
- const result = parser.complete(state, exec);
95
- if (!result.success && require_annotation_state.hasDelegatedAnnotationCarrier(state)) return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
96
- return normalizeOptionalLikeCompleteResult(result);
94
+ return normalizeOptionalLikeCompleteResult(parser.complete(state, exec));
97
95
  } catch (error) {
98
- if (!require_annotation_state.hasDelegatedAnnotationCarrier(state)) throw error;
96
+ if (!hasCarrier) throw error;
97
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(state);
99
98
  return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
100
99
  }
101
100
  }
102
101
  async function completeOptionalLikeAsync(parser, state, exec) {
103
- const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(state);
102
+ const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
104
103
  try {
105
- const result = await parser.complete(state, exec);
106
- if (!result.success && require_annotation_state.hasDelegatedAnnotationCarrier(state)) return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
107
- return normalizeOptionalLikeCompleteResult(result);
104
+ return normalizeOptionalLikeCompleteResult(await parser.complete(state, exec));
108
105
  } catch (error) {
109
- if (!require_annotation_state.hasDelegatedAnnotationCarrier(state)) throw error;
106
+ if (!hasCarrier) throw error;
107
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(state);
110
108
  return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
111
109
  }
112
110
  }
113
111
  function normalizeOptionalLikePhase2Seed(seed) {
114
112
  return seed == null ? null : {
115
113
  ...seed,
116
- value: require_annotation_state.normalizeDelegatedAnnotationState(seed.value)
114
+ value: require_annotation_state.normalizeNestedDelegatedAnnotationState(seed.value)
117
115
  };
118
116
  }
119
117
  function extractOptionalLikePhase2Seed(parser, state, exec) {
120
118
  if (!Array.isArray(state) && !(state != null && typeof state === "object")) return require_mode_dispatch.wrapForMode(parser.$mode, null);
121
119
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
122
- const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
120
+ const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(innerState);
123
121
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => {
124
122
  try {
125
- const seed = require_phase2_seed.completeOrExtractPhase2Seed(parser, innerState, exec);
126
- if (seed == null && require_annotation_state.hasDelegatedAnnotationCarrier(innerState)) return normalizeOptionalLikePhase2Seed(require_phase2_seed.completeOrExtractPhase2Seed(parser, fallbackState, exec));
123
+ const result = parser.complete(innerState, exec);
124
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
125
+ const seed = require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
126
+ if (seed == null && hasCarrier) {
127
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
128
+ return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
129
+ }
127
130
  return normalizeOptionalLikePhase2Seed(seed);
128
131
  } catch (error) {
129
- if (!require_annotation_state.hasDelegatedAnnotationCarrier(innerState)) throw error;
130
- return normalizeOptionalLikePhase2Seed(require_phase2_seed.completeOrExtractPhase2Seed(parser, fallbackState, exec));
132
+ if (!hasCarrier) throw error;
133
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
134
+ const result = parser.complete(fallbackState, exec);
135
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
136
+ return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
131
137
  }
132
138
  }, async () => {
133
139
  try {
134
- const seed = await require_phase2_seed.completeOrExtractPhase2Seed(parser, innerState, exec);
135
- if (seed == null && require_annotation_state.hasDelegatedAnnotationCarrier(innerState)) return normalizeOptionalLikePhase2Seed(await require_phase2_seed.completeOrExtractPhase2Seed(parser, fallbackState, exec));
140
+ const result = await parser.complete(innerState, exec);
141
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
142
+ const seed = await require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
143
+ if (seed == null && hasCarrier) {
144
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
145
+ return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
146
+ }
136
147
  return normalizeOptionalLikePhase2Seed(seed);
137
148
  } catch (error) {
138
- if (!require_annotation_state.hasDelegatedAnnotationCarrier(innerState)) throw error;
139
- return normalizeOptionalLikePhase2Seed(await require_phase2_seed.completeOrExtractPhase2Seed(parser, fallbackState, exec));
149
+ if (!hasCarrier) throw error;
150
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
151
+ const result = await parser.complete(fallbackState, exec);
152
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
153
+ return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
140
154
  }
141
155
  });
142
156
  }
package/dist/modifiers.js CHANGED
@@ -2,9 +2,9 @@ import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations,
2
2
  import { formatMessage, message, text } from "./message.js";
3
3
  import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./mode-dispatch.js";
4
4
  import { composeDependencyMetadata } from "./dependency-metadata.js";
5
- import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey } from "./phase2-seed.js";
5
+ import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
6
6
  import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, unmatchedNonCliDependencySourceStateMarker } from "./parser.js";
7
- import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, normalizeDelegatedAnnotationState } from "./annotation-state.js";
7
+ import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
8
8
 
9
9
  //#region src/modifiers.ts
10
10
  function withChildExecPath(exec, segment) {
@@ -85,58 +85,72 @@ function isPromiseLike(value) {
85
85
  function normalizeOptionalLikeCompleteResult(result) {
86
86
  return result.success ? {
87
87
  ...result,
88
- value: normalizeDelegatedAnnotationState(result.value)
88
+ value: normalizeNestedDelegatedAnnotationState(result.value)
89
89
  } : result;
90
90
  }
91
91
  function completeOptionalLikeSync(parser, state, exec) {
92
- const fallbackState = normalizeDelegatedAnnotationState(state);
92
+ const hasCarrier = hasDelegatedAnnotationCarrier(state);
93
93
  try {
94
- const result = parser.complete(state, exec);
95
- if (!result.success && hasDelegatedAnnotationCarrier(state)) return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
96
- return normalizeOptionalLikeCompleteResult(result);
94
+ return normalizeOptionalLikeCompleteResult(parser.complete(state, exec));
97
95
  } catch (error) {
98
- if (!hasDelegatedAnnotationCarrier(state)) throw error;
96
+ if (!hasCarrier) throw error;
97
+ const fallbackState = normalizeDelegatedAnnotationState(state);
99
98
  return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
100
99
  }
101
100
  }
102
101
  async function completeOptionalLikeAsync(parser, state, exec) {
103
- const fallbackState = normalizeDelegatedAnnotationState(state);
102
+ const hasCarrier = hasDelegatedAnnotationCarrier(state);
104
103
  try {
105
- const result = await parser.complete(state, exec);
106
- if (!result.success && hasDelegatedAnnotationCarrier(state)) return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
107
- return normalizeOptionalLikeCompleteResult(result);
104
+ return normalizeOptionalLikeCompleteResult(await parser.complete(state, exec));
108
105
  } catch (error) {
109
- if (!hasDelegatedAnnotationCarrier(state)) throw error;
106
+ if (!hasCarrier) throw error;
107
+ const fallbackState = normalizeDelegatedAnnotationState(state);
110
108
  return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
111
109
  }
112
110
  }
113
111
  function normalizeOptionalLikePhase2Seed(seed) {
114
112
  return seed == null ? null : {
115
113
  ...seed,
116
- value: normalizeDelegatedAnnotationState(seed.value)
114
+ value: normalizeNestedDelegatedAnnotationState(seed.value)
117
115
  };
118
116
  }
119
117
  function extractOptionalLikePhase2Seed(parser, state, exec) {
120
118
  if (!Array.isArray(state) && !(state != null && typeof state === "object")) return wrapForMode(parser.$mode, null);
121
119
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
122
- const fallbackState = normalizeDelegatedAnnotationState(innerState);
120
+ const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
123
121
  return dispatchByMode(parser.$mode, () => {
124
122
  try {
125
- const seed = completeOrExtractPhase2Seed(parser, innerState, exec);
126
- if (seed == null && hasDelegatedAnnotationCarrier(innerState)) return normalizeOptionalLikePhase2Seed(completeOrExtractPhase2Seed(parser, fallbackState, exec));
123
+ const result = parser.complete(innerState, exec);
124
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
125
+ const seed = extractPhase2Seed(parser, innerState, exec);
126
+ if (seed == null && hasCarrier) {
127
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
128
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
129
+ }
127
130
  return normalizeOptionalLikePhase2Seed(seed);
128
131
  } catch (error) {
129
- if (!hasDelegatedAnnotationCarrier(innerState)) throw error;
130
- return normalizeOptionalLikePhase2Seed(completeOrExtractPhase2Seed(parser, fallbackState, exec));
132
+ if (!hasCarrier) throw error;
133
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
134
+ const result = parser.complete(fallbackState, exec);
135
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
136
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
131
137
  }
132
138
  }, async () => {
133
139
  try {
134
- const seed = await completeOrExtractPhase2Seed(parser, innerState, exec);
135
- if (seed == null && hasDelegatedAnnotationCarrier(innerState)) return normalizeOptionalLikePhase2Seed(await completeOrExtractPhase2Seed(parser, fallbackState, exec));
140
+ const result = await parser.complete(innerState, exec);
141
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
142
+ const seed = await extractPhase2Seed(parser, innerState, exec);
143
+ if (seed == null && hasCarrier) {
144
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
145
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec));
146
+ }
136
147
  return normalizeOptionalLikePhase2Seed(seed);
137
148
  } catch (error) {
138
- if (!hasDelegatedAnnotationCarrier(innerState)) throw error;
139
- return normalizeOptionalLikePhase2Seed(await completeOrExtractPhase2Seed(parser, fallbackState, exec));
149
+ if (!hasCarrier) throw error;
150
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
151
+ const result = await parser.complete(fallbackState, exec);
152
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
153
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec));
140
154
  }
141
155
  });
142
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1891+f32e7ae2",
3
+ "version": "1.0.0-dev.1893+e1c35f1a",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",