@optique/core 1.0.0-dev.1901 → 1.0.0-dev.1903

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.
@@ -87,33 +87,36 @@ function normalizeDelegatedAnnotationState(state) {
87
87
  function hasDelegatedAnnotationCarrier(state) {
88
88
  return state != null && typeof state === "object" && (require_annotations.isInjectedAnnotationWrapper(state) || annotationViewTargets.has(state));
89
89
  }
90
- function isPendingNestedNormalizationAlias(originalValue, normalizedValue, seen) {
91
- if (originalValue == null || typeof originalValue !== "object") return false;
90
+ function getPendingNestedNormalizationEntry(originalValue, normalizedValue, seen) {
91
+ if (originalValue == null || typeof originalValue !== "object") return void 0;
92
92
  const entry = seen.get(originalValue);
93
- return entry != null && !entry.finalized && entry.clone === normalizedValue;
93
+ return entry != null && entry.clone === normalizedValue && (!entry.finalized || entry.preferCloneOnRead) ? entry : void 0;
94
94
  }
95
95
  function createPendingNestedNormalizationClone(source) {
96
96
  return Array.isArray(source) ? [] : Object.create(Object.getPrototypeOf(source));
97
97
  }
98
- function normalizeNestedDelegatedStructuredState(source, seen) {
98
+ function normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone) {
99
99
  const clone = createPendingNestedNormalizationClone(source);
100
100
  const entry = {
101
101
  clone,
102
102
  finalized: false,
103
- result: clone
103
+ result: clone,
104
+ preferCloneOnRead: false
104
105
  };
105
106
  seen.set(source, entry);
106
107
  const overrides = /* @__PURE__ */ new Map();
107
108
  let changed = false;
109
+ let hasPendingAliasOverride = false;
108
110
  for (const key of Reflect.ownKeys(source)) {
109
111
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
110
112
  if (descriptor == null || !("value" in descriptor)) continue;
111
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
113
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
112
114
  if (nextValue === descriptor.value) continue;
113
115
  overrides.set(key, nextValue);
114
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
116
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
117
+ else hasPendingAliasOverride = true;
115
118
  }
116
- if (!changed) {
119
+ if (!changed && !hasPendingAliasOverride) {
117
120
  entry.finalized = true;
118
121
  entry.result = source;
119
122
  return source;
@@ -129,35 +132,42 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
129
132
  }
130
133
  Object.defineProperties(clone, descriptors);
131
134
  entry.finalized = true;
132
- entry.result = clone;
133
- return clone;
135
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
136
+ entry.result = changed ? clone : source;
137
+ return changed || preferPendingClone ? clone : source;
134
138
  }
135
- function normalizeNestedDelegatedMapState(source, seen) {
139
+ function normalizeNestedDelegatedMapState(source, seen, preferPendingClone) {
136
140
  const clone = /* @__PURE__ */ new Map();
137
141
  const entry = {
138
142
  clone,
139
143
  finalized: false,
140
- result: clone
144
+ result: clone,
145
+ preferCloneOnRead: false
141
146
  };
142
147
  seen.set(source, entry);
143
148
  const normalizedEntries = [];
144
149
  const overrides = /* @__PURE__ */ new Map();
145
150
  let changed = false;
151
+ let hasPendingAliasOverride = false;
146
152
  for (const [key, value] of source) {
147
- const nextKey = normalizeNestedDelegatedAnnotationState(key, seen);
148
- const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
153
+ const nextKey = normalizeNestedDelegatedAnnotationState(key, seen, true);
154
+ const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
149
155
  normalizedEntries.push([nextKey, nextValue]);
150
- if (!isPendingNestedNormalizationAlias(key, nextKey, seen) && nextKey !== key || !isPendingNestedNormalizationAlias(value, nextValue, seen) && nextValue !== value) changed = true;
156
+ if (nextKey !== key) if (getPendingNestedNormalizationEntry(key, nextKey, seen) == null) changed = true;
157
+ else hasPendingAliasOverride = true;
158
+ if (nextValue !== value) if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
159
+ else hasPendingAliasOverride = true;
151
160
  }
152
161
  for (const key of Reflect.ownKeys(source)) {
153
162
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
154
163
  if (descriptor == null || !("value" in descriptor)) continue;
155
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
164
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
156
165
  if (nextValue === descriptor.value) continue;
157
166
  overrides.set(key, nextValue);
158
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
167
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
168
+ else hasPendingAliasOverride = true;
159
169
  }
160
- if (!changed) {
170
+ if (!changed && !hasPendingAliasOverride) {
161
171
  entry.finalized = true;
162
172
  entry.result = source;
163
173
  return source;
@@ -174,34 +184,40 @@ function normalizeNestedDelegatedMapState(source, seen) {
174
184
  }
175
185
  Object.defineProperties(clone, descriptors);
176
186
  entry.finalized = true;
177
- entry.result = clone;
178
- return clone;
187
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
188
+ entry.result = changed ? clone : source;
189
+ return changed || preferPendingClone ? clone : source;
179
190
  }
180
- function normalizeNestedDelegatedSetState(source, seen) {
191
+ function normalizeNestedDelegatedSetState(source, seen, preferPendingClone) {
181
192
  const clone = /* @__PURE__ */ new Set();
182
193
  const entry = {
183
194
  clone,
184
195
  finalized: false,
185
- result: clone
196
+ result: clone,
197
+ preferCloneOnRead: false
186
198
  };
187
199
  seen.set(source, entry);
188
200
  const normalizedValues = [];
189
201
  const overrides = /* @__PURE__ */ new Map();
190
202
  let changed = false;
203
+ let hasPendingAliasOverride = false;
191
204
  for (const value of source) {
192
- const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
205
+ const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
193
206
  normalizedValues.push(nextValue);
194
- if (nextValue !== value && !isPendingNestedNormalizationAlias(value, nextValue, seen)) changed = true;
207
+ if (nextValue === value) continue;
208
+ if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
209
+ else hasPendingAliasOverride = true;
195
210
  }
196
211
  for (const key of Reflect.ownKeys(source)) {
197
212
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
198
213
  if (descriptor == null || !("value" in descriptor)) continue;
199
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
214
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
200
215
  if (nextValue === descriptor.value) continue;
201
216
  overrides.set(key, nextValue);
202
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
217
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
218
+ else hasPendingAliasOverride = true;
203
219
  }
204
- if (!changed) {
220
+ if (!changed && !hasPendingAliasOverride) {
205
221
  entry.finalized = true;
206
222
  entry.result = source;
207
223
  return source;
@@ -218,8 +234,9 @@ function normalizeNestedDelegatedSetState(source, seen) {
218
234
  }
219
235
  Object.defineProperties(clone, descriptors);
220
236
  entry.finalized = true;
221
- entry.result = clone;
222
- return clone;
237
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
238
+ entry.result = changed ? clone : source;
239
+ return changed || preferPendingClone ? clone : source;
223
240
  }
224
241
  /**
225
242
  * Recursively removes delegated annotation carriers from plain-object, array,
@@ -237,18 +254,21 @@ function normalizeNestedDelegatedSetState(source, seen) {
237
254
  * normalized clone with delegated carriers removed.
238
255
  * @internal
239
256
  */
240
- function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
257
+ function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap(), preferPendingClone = false) {
241
258
  const normalized = normalizeDelegatedAnnotationState(value);
242
259
  if (normalized == null || typeof normalized !== "object") return normalized;
243
260
  const source = normalized;
244
261
  const existing = seen.get(source);
245
- if (existing != null) return existing.finalized ? existing.result : existing.clone;
246
- if (Array.isArray(source)) return normalizeNestedDelegatedStructuredState(source, seen);
247
- if (source instanceof Map) return normalizeNestedDelegatedMapState(source, seen);
248
- if (source instanceof Set) return normalizeNestedDelegatedSetState(source, seen);
262
+ if (existing != null) {
263
+ if (!existing.finalized) return existing.clone;
264
+ return preferPendingClone && existing.preferCloneOnRead ? existing.clone : existing.result;
265
+ }
266
+ if (Array.isArray(source)) return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
267
+ if (source instanceof Map) return normalizeNestedDelegatedMapState(source, seen, preferPendingClone);
268
+ if (source instanceof Set) return normalizeNestedDelegatedSetState(source, seen, preferPendingClone);
249
269
  const proto = Object.getPrototypeOf(source);
250
270
  if (proto !== Object.prototype && proto !== null) return normalized;
251
- return normalizeNestedDelegatedStructuredState(source, seen);
271
+ return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
252
272
  }
253
273
  /**
254
274
  * Creates a short-lived delegated state that exposes the parent's annotations
@@ -87,33 +87,36 @@ function normalizeDelegatedAnnotationState(state) {
87
87
  function hasDelegatedAnnotationCarrier(state) {
88
88
  return state != null && typeof state === "object" && (isInjectedAnnotationWrapper(state) || annotationViewTargets.has(state));
89
89
  }
90
- function isPendingNestedNormalizationAlias(originalValue, normalizedValue, seen) {
91
- if (originalValue == null || typeof originalValue !== "object") return false;
90
+ function getPendingNestedNormalizationEntry(originalValue, normalizedValue, seen) {
91
+ if (originalValue == null || typeof originalValue !== "object") return void 0;
92
92
  const entry = seen.get(originalValue);
93
- return entry != null && !entry.finalized && entry.clone === normalizedValue;
93
+ return entry != null && entry.clone === normalizedValue && (!entry.finalized || entry.preferCloneOnRead) ? entry : void 0;
94
94
  }
95
95
  function createPendingNestedNormalizationClone(source) {
96
96
  return Array.isArray(source) ? [] : Object.create(Object.getPrototypeOf(source));
97
97
  }
98
- function normalizeNestedDelegatedStructuredState(source, seen) {
98
+ function normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone) {
99
99
  const clone = createPendingNestedNormalizationClone(source);
100
100
  const entry = {
101
101
  clone,
102
102
  finalized: false,
103
- result: clone
103
+ result: clone,
104
+ preferCloneOnRead: false
104
105
  };
105
106
  seen.set(source, entry);
106
107
  const overrides = /* @__PURE__ */ new Map();
107
108
  let changed = false;
109
+ let hasPendingAliasOverride = false;
108
110
  for (const key of Reflect.ownKeys(source)) {
109
111
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
110
112
  if (descriptor == null || !("value" in descriptor)) continue;
111
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
113
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
112
114
  if (nextValue === descriptor.value) continue;
113
115
  overrides.set(key, nextValue);
114
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
116
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
117
+ else hasPendingAliasOverride = true;
115
118
  }
116
- if (!changed) {
119
+ if (!changed && !hasPendingAliasOverride) {
117
120
  entry.finalized = true;
118
121
  entry.result = source;
119
122
  return source;
@@ -129,35 +132,42 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
129
132
  }
130
133
  Object.defineProperties(clone, descriptors);
131
134
  entry.finalized = true;
132
- entry.result = clone;
133
- return clone;
135
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
136
+ entry.result = changed ? clone : source;
137
+ return changed || preferPendingClone ? clone : source;
134
138
  }
135
- function normalizeNestedDelegatedMapState(source, seen) {
139
+ function normalizeNestedDelegatedMapState(source, seen, preferPendingClone) {
136
140
  const clone = /* @__PURE__ */ new Map();
137
141
  const entry = {
138
142
  clone,
139
143
  finalized: false,
140
- result: clone
144
+ result: clone,
145
+ preferCloneOnRead: false
141
146
  };
142
147
  seen.set(source, entry);
143
148
  const normalizedEntries = [];
144
149
  const overrides = /* @__PURE__ */ new Map();
145
150
  let changed = false;
151
+ let hasPendingAliasOverride = false;
146
152
  for (const [key, value] of source) {
147
- const nextKey = normalizeNestedDelegatedAnnotationState(key, seen);
148
- const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
153
+ const nextKey = normalizeNestedDelegatedAnnotationState(key, seen, true);
154
+ const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
149
155
  normalizedEntries.push([nextKey, nextValue]);
150
- if (!isPendingNestedNormalizationAlias(key, nextKey, seen) && nextKey !== key || !isPendingNestedNormalizationAlias(value, nextValue, seen) && nextValue !== value) changed = true;
156
+ if (nextKey !== key) if (getPendingNestedNormalizationEntry(key, nextKey, seen) == null) changed = true;
157
+ else hasPendingAliasOverride = true;
158
+ if (nextValue !== value) if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
159
+ else hasPendingAliasOverride = true;
151
160
  }
152
161
  for (const key of Reflect.ownKeys(source)) {
153
162
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
154
163
  if (descriptor == null || !("value" in descriptor)) continue;
155
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
164
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
156
165
  if (nextValue === descriptor.value) continue;
157
166
  overrides.set(key, nextValue);
158
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
167
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
168
+ else hasPendingAliasOverride = true;
159
169
  }
160
- if (!changed) {
170
+ if (!changed && !hasPendingAliasOverride) {
161
171
  entry.finalized = true;
162
172
  entry.result = source;
163
173
  return source;
@@ -174,34 +184,40 @@ function normalizeNestedDelegatedMapState(source, seen) {
174
184
  }
175
185
  Object.defineProperties(clone, descriptors);
176
186
  entry.finalized = true;
177
- entry.result = clone;
178
- return clone;
187
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
188
+ entry.result = changed ? clone : source;
189
+ return changed || preferPendingClone ? clone : source;
179
190
  }
180
- function normalizeNestedDelegatedSetState(source, seen) {
191
+ function normalizeNestedDelegatedSetState(source, seen, preferPendingClone) {
181
192
  const clone = /* @__PURE__ */ new Set();
182
193
  const entry = {
183
194
  clone,
184
195
  finalized: false,
185
- result: clone
196
+ result: clone,
197
+ preferCloneOnRead: false
186
198
  };
187
199
  seen.set(source, entry);
188
200
  const normalizedValues = [];
189
201
  const overrides = /* @__PURE__ */ new Map();
190
202
  let changed = false;
203
+ let hasPendingAliasOverride = false;
191
204
  for (const value of source) {
192
- const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
205
+ const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
193
206
  normalizedValues.push(nextValue);
194
- if (nextValue !== value && !isPendingNestedNormalizationAlias(value, nextValue, seen)) changed = true;
207
+ if (nextValue === value) continue;
208
+ if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
209
+ else hasPendingAliasOverride = true;
195
210
  }
196
211
  for (const key of Reflect.ownKeys(source)) {
197
212
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
198
213
  if (descriptor == null || !("value" in descriptor)) continue;
199
- const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
214
+ const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
200
215
  if (nextValue === descriptor.value) continue;
201
216
  overrides.set(key, nextValue);
202
- if (!isPendingNestedNormalizationAlias(descriptor.value, nextValue, seen)) changed = true;
217
+ if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
218
+ else hasPendingAliasOverride = true;
203
219
  }
204
- if (!changed) {
220
+ if (!changed && !hasPendingAliasOverride) {
205
221
  entry.finalized = true;
206
222
  entry.result = source;
207
223
  return source;
@@ -218,8 +234,9 @@ function normalizeNestedDelegatedSetState(source, seen) {
218
234
  }
219
235
  Object.defineProperties(clone, descriptors);
220
236
  entry.finalized = true;
221
- entry.result = clone;
222
- return clone;
237
+ entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
238
+ entry.result = changed ? clone : source;
239
+ return changed || preferPendingClone ? clone : source;
223
240
  }
224
241
  /**
225
242
  * Recursively removes delegated annotation carriers from plain-object, array,
@@ -237,18 +254,21 @@ function normalizeNestedDelegatedSetState(source, seen) {
237
254
  * normalized clone with delegated carriers removed.
238
255
  * @internal
239
256
  */
240
- function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
257
+ function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap(), preferPendingClone = false) {
241
258
  const normalized = normalizeDelegatedAnnotationState(value);
242
259
  if (normalized == null || typeof normalized !== "object") return normalized;
243
260
  const source = normalized;
244
261
  const existing = seen.get(source);
245
- if (existing != null) return existing.finalized ? existing.result : existing.clone;
246
- if (Array.isArray(source)) return normalizeNestedDelegatedStructuredState(source, seen);
247
- if (source instanceof Map) return normalizeNestedDelegatedMapState(source, seen);
248
- if (source instanceof Set) return normalizeNestedDelegatedSetState(source, seen);
262
+ if (existing != null) {
263
+ if (!existing.finalized) return existing.clone;
264
+ return preferPendingClone && existing.preferCloneOnRead ? existing.clone : existing.result;
265
+ }
266
+ if (Array.isArray(source)) return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
267
+ if (source instanceof Map) return normalizeNestedDelegatedMapState(source, seen, preferPendingClone);
268
+ if (source instanceof Set) return normalizeNestedDelegatedSetState(source, seen, preferPendingClone);
249
269
  const proto = Object.getPrototypeOf(source);
250
270
  if (proto !== Object.prototype && proto !== null) return normalized;
251
- return normalizeNestedDelegatedStructuredState(source, seen);
271
+ return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
252
272
  }
253
273
  /**
254
274
  * Creates a short-lived delegated state that exposes the parent's annotations
@@ -82,91 +82,102 @@ function unwrapMultipleItemState(state) {
82
82
  function isPromiseLike(value) {
83
83
  return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
84
84
  }
85
- function normalizeOptionalLikeCompleteResult(result) {
86
- return result.success ? {
85
+ function normalizeOptionalLikeCompleteResult(result, shouldNormalize) {
86
+ return result.success && shouldNormalize ? {
87
87
  ...result,
88
88
  value: require_annotation_state.normalizeNestedDelegatedAnnotationState(result.value)
89
89
  } : result;
90
90
  }
91
91
  function completeOptionalLikeSync(parser, state, exec) {
92
92
  const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
93
- const shouldRetryFalseResult = require_annotation_state.isAnnotationWrappedInitialState(state);
94
- const run = (candidate) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec));
93
+ const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(state);
94
+ const run = (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec), shouldNormalize);
95
95
  try {
96
- const result = run(state);
97
- if (!result.success && shouldRetryFalseResult) return run(require_annotation_state.normalizeDelegatedAnnotationState(state));
96
+ const result = run(state, hasCarrier);
97
+ if (!result.success && shouldRetryFalseResult) return run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
98
98
  return result;
99
99
  } catch (error) {
100
100
  if (!hasCarrier) throw error;
101
- return run(require_annotation_state.normalizeDelegatedAnnotationState(state));
101
+ return run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
102
102
  }
103
103
  }
104
104
  async function completeOptionalLikeAsync(parser, state, exec) {
105
105
  const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
106
- const shouldRetryFalseResult = require_annotation_state.isAnnotationWrappedInitialState(state);
107
- const run = async (candidate) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec));
106
+ const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(state);
107
+ const run = async (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec), shouldNormalize);
108
108
  try {
109
- const result = await run(state);
110
- if (!result.success && shouldRetryFalseResult) return await run(require_annotation_state.normalizeDelegatedAnnotationState(state));
109
+ const result = await run(state, hasCarrier);
110
+ if (!result.success && shouldRetryFalseResult) return await run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
111
111
  return result;
112
112
  } catch (error) {
113
113
  if (!hasCarrier) throw error;
114
- return await run(require_annotation_state.normalizeDelegatedAnnotationState(state));
114
+ return await run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
115
115
  }
116
116
  }
117
- function normalizeOptionalLikePhase2Seed(seed) {
118
- return seed == null ? null : {
117
+ function normalizeOptionalLikePhase2Seed(seed, shouldNormalize) {
118
+ return seed == null ? null : shouldNormalize ? {
119
119
  ...seed,
120
120
  value: require_annotation_state.normalizeNestedDelegatedAnnotationState(seed.value)
121
- };
121
+ } : seed;
122
122
  }
123
123
  function extractOptionalLikePhase2Seed(parser, state, exec) {
124
124
  if (!Array.isArray(state) && !(state != null && typeof state === "object")) return require_mode_dispatch.wrapForMode(parser.$mode, null);
125
125
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
126
126
  const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(innerState);
127
+ const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(innerState);
127
128
  return require_mode_dispatch.dispatchByMode(parser.$mode, () => {
128
129
  try {
129
130
  const result = parser.complete(innerState, exec);
130
- if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
131
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), hasCarrier);
132
+ if (shouldRetryFalseResult) {
133
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
134
+ const fallbackResult = parser.complete(fallbackState, exec);
135
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(fallbackResult), false);
136
+ }
131
137
  const seed = require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
132
138
  if (seed == null && hasCarrier) {
133
139
  const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
134
- return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
140
+ return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
135
141
  }
136
- return normalizeOptionalLikePhase2Seed(seed);
142
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
137
143
  } catch (error) {
138
144
  if (!hasCarrier) throw error;
139
145
  const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
140
146
  const result = parser.complete(fallbackState, exec);
141
- if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
142
- return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
147
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), false);
148
+ return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
143
149
  }
144
150
  }, async () => {
145
151
  try {
146
152
  const result = await parser.complete(innerState, exec);
147
- if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
153
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), hasCarrier);
154
+ if (shouldRetryFalseResult) {
155
+ const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
156
+ const fallbackResult = await parser.complete(fallbackState, exec);
157
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(fallbackResult), false);
158
+ }
148
159
  const seed = await require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
149
160
  if (seed == null && hasCarrier) {
150
161
  const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
151
- return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
162
+ return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
152
163
  }
153
- return normalizeOptionalLikePhase2Seed(seed);
164
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
154
165
  } catch (error) {
155
166
  if (!hasCarrier) throw error;
156
167
  const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
157
168
  const result = await parser.complete(fallbackState, exec);
158
- if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result));
159
- return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
169
+ if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), false);
170
+ return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
160
171
  }
161
172
  });
162
173
  }
163
174
  /**
164
175
  * Computes the inner state to pass through to the wrapped parser inside
165
176
  * {@link optional} / {@link withDefault}. When the outer state is an
166
- * array, the inner state is `state[0]`. Otherwise including the
177
+ * array, the inner state is `state[0]`. Otherwise, including the
167
178
  * common case where `optional()` sits at top level and the outer state
168
179
  * is either `undefined` or an annotation wrapper from `parseOptionalLike`
169
- * / `parse({ annotations })` we use the wrapped parser's
180
+ * / `parse({ annotations })`, we use the wrapped parser's
170
181
  * `initialState`, propagating annotations from the outer state so that
171
182
  * source-binding wrappers under `optional()` / `withDefault()` (e.g.,
172
183
  * `bindEnv()` / `bindConfig()`) can resolve their fallbacks.
@@ -187,8 +198,8 @@ function deriveOptionalInnerParseState(outerState, parser) {
187
198
  * Internal helper for optional-style parsing logic shared by optional()
188
199
  * and withDefault(). Handles the common pattern of:
189
200
  * - Unwrapping optional state to inner parser state
190
- * - Detecting if inner parser actually matched (state changed or no consumption)
191
- * - Returning success with undefined state when inner parser fails without consuming
201
+ * - Detecting if the inner parser actually matched (state changed or no consumption)
202
+ * - Returning success with undefined state when the inner parser fails without consuming
192
203
  * @internal
193
204
  */
194
205
  function parseOptionalStyleSync(context, parser) {
@@ -249,7 +260,7 @@ function processOptionalStyleResult(result, innerState, context) {
249
260
  * {@link withDefault} before delegating to the inner parser's hook.
250
261
  *
251
262
  * When state is an array, the adapter unwraps `state[0]` and propagates
252
- * annotations from the outer array. Non-array objects (e.g., PromptBindState
263
+ * annotations from the outer array. Non-array objects (e.g. PromptBindState
253
264
  * from `prompt()`) are passed through directly. `undefined` returns `false`
254
265
  * without calling the inner hook.
255
266
  *
package/dist/modifiers.js CHANGED
@@ -82,91 +82,102 @@ function unwrapMultipleItemState(state) {
82
82
  function isPromiseLike(value) {
83
83
  return value != null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
84
84
  }
85
- function normalizeOptionalLikeCompleteResult(result) {
86
- return result.success ? {
85
+ function normalizeOptionalLikeCompleteResult(result, shouldNormalize) {
86
+ return result.success && shouldNormalize ? {
87
87
  ...result,
88
88
  value: normalizeNestedDelegatedAnnotationState(result.value)
89
89
  } : result;
90
90
  }
91
91
  function completeOptionalLikeSync(parser, state, exec) {
92
92
  const hasCarrier = hasDelegatedAnnotationCarrier(state);
93
- const shouldRetryFalseResult = isAnnotationWrappedInitialState(state);
94
- const run = (candidate) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec));
93
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(state);
94
+ const run = (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec), shouldNormalize);
95
95
  try {
96
- const result = run(state);
97
- if (!result.success && shouldRetryFalseResult) return run(normalizeDelegatedAnnotationState(state));
96
+ const result = run(state, hasCarrier);
97
+ if (!result.success && shouldRetryFalseResult) return run(normalizeDelegatedAnnotationState(state), false);
98
98
  return result;
99
99
  } catch (error) {
100
100
  if (!hasCarrier) throw error;
101
- return run(normalizeDelegatedAnnotationState(state));
101
+ return run(normalizeDelegatedAnnotationState(state), false);
102
102
  }
103
103
  }
104
104
  async function completeOptionalLikeAsync(parser, state, exec) {
105
105
  const hasCarrier = hasDelegatedAnnotationCarrier(state);
106
- const shouldRetryFalseResult = isAnnotationWrappedInitialState(state);
107
- const run = async (candidate) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec));
106
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(state);
107
+ const run = async (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec), shouldNormalize);
108
108
  try {
109
- const result = await run(state);
110
- if (!result.success && shouldRetryFalseResult) return await run(normalizeDelegatedAnnotationState(state));
109
+ const result = await run(state, hasCarrier);
110
+ if (!result.success && shouldRetryFalseResult) return await run(normalizeDelegatedAnnotationState(state), false);
111
111
  return result;
112
112
  } catch (error) {
113
113
  if (!hasCarrier) throw error;
114
- return await run(normalizeDelegatedAnnotationState(state));
114
+ return await run(normalizeDelegatedAnnotationState(state), false);
115
115
  }
116
116
  }
117
- function normalizeOptionalLikePhase2Seed(seed) {
118
- return seed == null ? null : {
117
+ function normalizeOptionalLikePhase2Seed(seed, shouldNormalize) {
118
+ return seed == null ? null : shouldNormalize ? {
119
119
  ...seed,
120
120
  value: normalizeNestedDelegatedAnnotationState(seed.value)
121
- };
121
+ } : seed;
122
122
  }
123
123
  function extractOptionalLikePhase2Seed(parser, state, exec) {
124
124
  if (!Array.isArray(state) && !(state != null && typeof state === "object")) return wrapForMode(parser.$mode, null);
125
125
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
126
126
  const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
127
+ const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(innerState);
127
128
  return dispatchByMode(parser.$mode, () => {
128
129
  try {
129
130
  const result = parser.complete(innerState, exec);
130
- if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
131
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), hasCarrier);
132
+ if (shouldRetryFalseResult) {
133
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
134
+ const fallbackResult = parser.complete(fallbackState, exec);
135
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(fallbackResult), false);
136
+ }
131
137
  const seed = extractPhase2Seed(parser, innerState, exec);
132
138
  if (seed == null && hasCarrier) {
133
139
  const fallbackState = normalizeDelegatedAnnotationState(innerState);
134
- return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
140
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
135
141
  }
136
- return normalizeOptionalLikePhase2Seed(seed);
142
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
137
143
  } catch (error) {
138
144
  if (!hasCarrier) throw error;
139
145
  const fallbackState = normalizeDelegatedAnnotationState(innerState);
140
146
  const result = parser.complete(fallbackState, exec);
141
- if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
142
- return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
147
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), false);
148
+ return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
143
149
  }
144
150
  }, async () => {
145
151
  try {
146
152
  const result = await parser.complete(innerState, exec);
147
- if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
153
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), hasCarrier);
154
+ if (shouldRetryFalseResult) {
155
+ const fallbackState = normalizeDelegatedAnnotationState(innerState);
156
+ const fallbackResult = await parser.complete(fallbackState, exec);
157
+ if (fallbackResult.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(fallbackResult), false);
158
+ }
148
159
  const seed = await extractPhase2Seed(parser, innerState, exec);
149
160
  if (seed == null && hasCarrier) {
150
161
  const fallbackState = normalizeDelegatedAnnotationState(innerState);
151
- return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec));
162
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec), false);
152
163
  }
153
- return normalizeOptionalLikePhase2Seed(seed);
164
+ return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
154
165
  } catch (error) {
155
166
  if (!hasCarrier) throw error;
156
167
  const fallbackState = normalizeDelegatedAnnotationState(innerState);
157
168
  const result = await parser.complete(fallbackState, exec);
158
- if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
159
- return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec));
169
+ if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), false);
170
+ return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec), false);
160
171
  }
161
172
  });
162
173
  }
163
174
  /**
164
175
  * Computes the inner state to pass through to the wrapped parser inside
165
176
  * {@link optional} / {@link withDefault}. When the outer state is an
166
- * array, the inner state is `state[0]`. Otherwise including the
177
+ * array, the inner state is `state[0]`. Otherwise, including the
167
178
  * common case where `optional()` sits at top level and the outer state
168
179
  * is either `undefined` or an annotation wrapper from `parseOptionalLike`
169
- * / `parse({ annotations })` we use the wrapped parser's
180
+ * / `parse({ annotations })`, we use the wrapped parser's
170
181
  * `initialState`, propagating annotations from the outer state so that
171
182
  * source-binding wrappers under `optional()` / `withDefault()` (e.g.,
172
183
  * `bindEnv()` / `bindConfig()`) can resolve their fallbacks.
@@ -187,8 +198,8 @@ function deriveOptionalInnerParseState(outerState, parser) {
187
198
  * Internal helper for optional-style parsing logic shared by optional()
188
199
  * and withDefault(). Handles the common pattern of:
189
200
  * - Unwrapping optional state to inner parser state
190
- * - Detecting if inner parser actually matched (state changed or no consumption)
191
- * - Returning success with undefined state when inner parser fails without consuming
201
+ * - Detecting if the inner parser actually matched (state changed or no consumption)
202
+ * - Returning success with undefined state when the inner parser fails without consuming
192
203
  * @internal
193
204
  */
194
205
  function parseOptionalStyleSync(context, parser) {
@@ -249,7 +260,7 @@ function processOptionalStyleResult(result, innerState, context) {
249
260
  * {@link withDefault} before delegating to the inner parser's hook.
250
261
  *
251
262
  * When state is an array, the adapter unwraps `state[0]` and propagates
252
- * annotations from the outer array. Non-array objects (e.g., PromptBindState
263
+ * annotations from the outer array. Non-array objects (e.g. PromptBindState
253
264
  * from `prompt()`) are passed through directly. `undefined` returns `false`
254
265
  * without calling the inner hook.
255
266
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1901+a2ce4da0",
3
+ "version": "1.0.0-dev.1903+af120cc5",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",