@optique/core 1.0.0-dev.1899 → 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.
- package/dist/annotation-state.cjs +131 -20
- package/dist/annotation-state.js +131 -20
- package/dist/modifiers.cjs +49 -28
- package/dist/modifiers.js +50 -29
- package/package.json +1 -1
|
@@ -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
|
|
91
|
-
if (originalValue == null || typeof originalValue !== "object") return
|
|
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
|
|
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 (
|
|
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,17 +132,120 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
|
129
132
|
}
|
|
130
133
|
Object.defineProperties(clone, descriptors);
|
|
131
134
|
entry.finalized = true;
|
|
132
|
-
entry.
|
|
133
|
-
|
|
135
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
136
|
+
entry.result = changed ? clone : source;
|
|
137
|
+
return changed || preferPendingClone ? clone : source;
|
|
138
|
+
}
|
|
139
|
+
function normalizeNestedDelegatedMapState(source, seen, preferPendingClone) {
|
|
140
|
+
const clone = /* @__PURE__ */ new Map();
|
|
141
|
+
const entry = {
|
|
142
|
+
clone,
|
|
143
|
+
finalized: false,
|
|
144
|
+
result: clone,
|
|
145
|
+
preferCloneOnRead: false
|
|
146
|
+
};
|
|
147
|
+
seen.set(source, entry);
|
|
148
|
+
const normalizedEntries = [];
|
|
149
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
150
|
+
let changed = false;
|
|
151
|
+
let hasPendingAliasOverride = false;
|
|
152
|
+
for (const [key, value] of source) {
|
|
153
|
+
const nextKey = normalizeNestedDelegatedAnnotationState(key, seen, true);
|
|
154
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
155
|
+
normalizedEntries.push([nextKey, nextValue]);
|
|
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;
|
|
160
|
+
}
|
|
161
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
162
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
163
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
164
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
165
|
+
if (nextValue === descriptor.value) continue;
|
|
166
|
+
overrides.set(key, nextValue);
|
|
167
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
168
|
+
else hasPendingAliasOverride = true;
|
|
169
|
+
}
|
|
170
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
171
|
+
entry.finalized = true;
|
|
172
|
+
entry.result = source;
|
|
173
|
+
return source;
|
|
174
|
+
}
|
|
175
|
+
for (const [key, value] of normalizedEntries) clone.set(key, value);
|
|
176
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
177
|
+
for (const [key, nextValue] of overrides) {
|
|
178
|
+
const descriptor = descriptors[key];
|
|
179
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
180
|
+
descriptors[key] = {
|
|
181
|
+
...descriptor,
|
|
182
|
+
value: nextValue
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
Object.defineProperties(clone, descriptors);
|
|
186
|
+
entry.finalized = true;
|
|
187
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
188
|
+
entry.result = changed ? clone : source;
|
|
189
|
+
return changed || preferPendingClone ? clone : source;
|
|
190
|
+
}
|
|
191
|
+
function normalizeNestedDelegatedSetState(source, seen, preferPendingClone) {
|
|
192
|
+
const clone = /* @__PURE__ */ new Set();
|
|
193
|
+
const entry = {
|
|
194
|
+
clone,
|
|
195
|
+
finalized: false,
|
|
196
|
+
result: clone,
|
|
197
|
+
preferCloneOnRead: false
|
|
198
|
+
};
|
|
199
|
+
seen.set(source, entry);
|
|
200
|
+
const normalizedValues = [];
|
|
201
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
202
|
+
let changed = false;
|
|
203
|
+
let hasPendingAliasOverride = false;
|
|
204
|
+
for (const value of source) {
|
|
205
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
206
|
+
normalizedValues.push(nextValue);
|
|
207
|
+
if (nextValue === value) continue;
|
|
208
|
+
if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
|
|
209
|
+
else hasPendingAliasOverride = true;
|
|
210
|
+
}
|
|
211
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
212
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
213
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
214
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
215
|
+
if (nextValue === descriptor.value) continue;
|
|
216
|
+
overrides.set(key, nextValue);
|
|
217
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
218
|
+
else hasPendingAliasOverride = true;
|
|
219
|
+
}
|
|
220
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
221
|
+
entry.finalized = true;
|
|
222
|
+
entry.result = source;
|
|
223
|
+
return source;
|
|
224
|
+
}
|
|
225
|
+
for (const value of normalizedValues) clone.add(value);
|
|
226
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
227
|
+
for (const [key, nextValue] of overrides) {
|
|
228
|
+
const descriptor = descriptors[key];
|
|
229
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
230
|
+
descriptors[key] = {
|
|
231
|
+
...descriptor,
|
|
232
|
+
value: nextValue
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
Object.defineProperties(clone, descriptors);
|
|
236
|
+
entry.finalized = true;
|
|
237
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
238
|
+
entry.result = changed ? clone : source;
|
|
239
|
+
return changed || preferPendingClone ? clone : source;
|
|
134
240
|
}
|
|
135
241
|
/**
|
|
136
|
-
* Recursively removes delegated annotation carriers from plain-object
|
|
137
|
-
* structures.
|
|
242
|
+
* Recursively removes delegated annotation carriers from plain-object, array,
|
|
243
|
+
* and built-in collection structures.
|
|
138
244
|
*
|
|
139
|
-
* Nested plain objects and
|
|
140
|
-
* carrier is found below them.
|
|
141
|
-
* level and then preserved as-is to avoid mutating or reconstructing
|
|
142
|
-
* instances.
|
|
245
|
+
* Nested plain objects, arrays, Maps, and Sets are shallow-cloned only when a
|
|
246
|
+
* delegated carrier is found below them. Other non-plain objects are unwrapped
|
|
247
|
+
* at the top level and then preserved as-is to avoid mutating or reconstructing
|
|
248
|
+
* class instances.
|
|
143
249
|
*
|
|
144
250
|
* @param value The candidate value to normalize.
|
|
145
251
|
* @param seen Tracks already-normalized objects so cyclic values keep their
|
|
@@ -148,16 +254,21 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
|
148
254
|
* normalized clone with delegated carriers removed.
|
|
149
255
|
* @internal
|
|
150
256
|
*/
|
|
151
|
-
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
257
|
+
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap(), preferPendingClone = false) {
|
|
152
258
|
const normalized = normalizeDelegatedAnnotationState(value);
|
|
153
259
|
if (normalized == null || typeof normalized !== "object") return normalized;
|
|
154
260
|
const source = normalized;
|
|
155
261
|
const existing = seen.get(source);
|
|
156
|
-
if (existing != null)
|
|
157
|
-
|
|
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);
|
|
158
269
|
const proto = Object.getPrototypeOf(source);
|
|
159
270
|
if (proto !== Object.prototype && proto !== null) return normalized;
|
|
160
|
-
return normalizeNestedDelegatedStructuredState(source, seen);
|
|
271
|
+
return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
|
|
161
272
|
}
|
|
162
273
|
/**
|
|
163
274
|
* Creates a short-lived delegated state that exposes the parent's annotations
|
package/dist/annotation-state.js
CHANGED
|
@@ -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
|
|
91
|
-
if (originalValue == null || typeof originalValue !== "object") return
|
|
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
|
|
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 (
|
|
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,17 +132,120 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
|
129
132
|
}
|
|
130
133
|
Object.defineProperties(clone, descriptors);
|
|
131
134
|
entry.finalized = true;
|
|
132
|
-
entry.
|
|
133
|
-
|
|
135
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
136
|
+
entry.result = changed ? clone : source;
|
|
137
|
+
return changed || preferPendingClone ? clone : source;
|
|
138
|
+
}
|
|
139
|
+
function normalizeNestedDelegatedMapState(source, seen, preferPendingClone) {
|
|
140
|
+
const clone = /* @__PURE__ */ new Map();
|
|
141
|
+
const entry = {
|
|
142
|
+
clone,
|
|
143
|
+
finalized: false,
|
|
144
|
+
result: clone,
|
|
145
|
+
preferCloneOnRead: false
|
|
146
|
+
};
|
|
147
|
+
seen.set(source, entry);
|
|
148
|
+
const normalizedEntries = [];
|
|
149
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
150
|
+
let changed = false;
|
|
151
|
+
let hasPendingAliasOverride = false;
|
|
152
|
+
for (const [key, value] of source) {
|
|
153
|
+
const nextKey = normalizeNestedDelegatedAnnotationState(key, seen, true);
|
|
154
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
155
|
+
normalizedEntries.push([nextKey, nextValue]);
|
|
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;
|
|
160
|
+
}
|
|
161
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
162
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
163
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
164
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
165
|
+
if (nextValue === descriptor.value) continue;
|
|
166
|
+
overrides.set(key, nextValue);
|
|
167
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
168
|
+
else hasPendingAliasOverride = true;
|
|
169
|
+
}
|
|
170
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
171
|
+
entry.finalized = true;
|
|
172
|
+
entry.result = source;
|
|
173
|
+
return source;
|
|
174
|
+
}
|
|
175
|
+
for (const [key, value] of normalizedEntries) clone.set(key, value);
|
|
176
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
177
|
+
for (const [key, nextValue] of overrides) {
|
|
178
|
+
const descriptor = descriptors[key];
|
|
179
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
180
|
+
descriptors[key] = {
|
|
181
|
+
...descriptor,
|
|
182
|
+
value: nextValue
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
Object.defineProperties(clone, descriptors);
|
|
186
|
+
entry.finalized = true;
|
|
187
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
188
|
+
entry.result = changed ? clone : source;
|
|
189
|
+
return changed || preferPendingClone ? clone : source;
|
|
190
|
+
}
|
|
191
|
+
function normalizeNestedDelegatedSetState(source, seen, preferPendingClone) {
|
|
192
|
+
const clone = /* @__PURE__ */ new Set();
|
|
193
|
+
const entry = {
|
|
194
|
+
clone,
|
|
195
|
+
finalized: false,
|
|
196
|
+
result: clone,
|
|
197
|
+
preferCloneOnRead: false
|
|
198
|
+
};
|
|
199
|
+
seen.set(source, entry);
|
|
200
|
+
const normalizedValues = [];
|
|
201
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
202
|
+
let changed = false;
|
|
203
|
+
let hasPendingAliasOverride = false;
|
|
204
|
+
for (const value of source) {
|
|
205
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
206
|
+
normalizedValues.push(nextValue);
|
|
207
|
+
if (nextValue === value) continue;
|
|
208
|
+
if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
|
|
209
|
+
else hasPendingAliasOverride = true;
|
|
210
|
+
}
|
|
211
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
212
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
213
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
214
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
215
|
+
if (nextValue === descriptor.value) continue;
|
|
216
|
+
overrides.set(key, nextValue);
|
|
217
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
218
|
+
else hasPendingAliasOverride = true;
|
|
219
|
+
}
|
|
220
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
221
|
+
entry.finalized = true;
|
|
222
|
+
entry.result = source;
|
|
223
|
+
return source;
|
|
224
|
+
}
|
|
225
|
+
for (const value of normalizedValues) clone.add(value);
|
|
226
|
+
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
227
|
+
for (const [key, nextValue] of overrides) {
|
|
228
|
+
const descriptor = descriptors[key];
|
|
229
|
+
if (descriptor == null || !("value" in descriptor)) continue;
|
|
230
|
+
descriptors[key] = {
|
|
231
|
+
...descriptor,
|
|
232
|
+
value: nextValue
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
Object.defineProperties(clone, descriptors);
|
|
236
|
+
entry.finalized = true;
|
|
237
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
238
|
+
entry.result = changed ? clone : source;
|
|
239
|
+
return changed || preferPendingClone ? clone : source;
|
|
134
240
|
}
|
|
135
241
|
/**
|
|
136
|
-
* Recursively removes delegated annotation carriers from plain-object
|
|
137
|
-
* structures.
|
|
242
|
+
* Recursively removes delegated annotation carriers from plain-object, array,
|
|
243
|
+
* and built-in collection structures.
|
|
138
244
|
*
|
|
139
|
-
* Nested plain objects and
|
|
140
|
-
* carrier is found below them.
|
|
141
|
-
* level and then preserved as-is to avoid mutating or reconstructing
|
|
142
|
-
* instances.
|
|
245
|
+
* Nested plain objects, arrays, Maps, and Sets are shallow-cloned only when a
|
|
246
|
+
* delegated carrier is found below them. Other non-plain objects are unwrapped
|
|
247
|
+
* at the top level and then preserved as-is to avoid mutating or reconstructing
|
|
248
|
+
* class instances.
|
|
143
249
|
*
|
|
144
250
|
* @param value The candidate value to normalize.
|
|
145
251
|
* @param seen Tracks already-normalized objects so cyclic values keep their
|
|
@@ -148,16 +254,21 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
|
148
254
|
* normalized clone with delegated carriers removed.
|
|
149
255
|
* @internal
|
|
150
256
|
*/
|
|
151
|
-
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
257
|
+
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap(), preferPendingClone = false) {
|
|
152
258
|
const normalized = normalizeDelegatedAnnotationState(value);
|
|
153
259
|
if (normalized == null || typeof normalized !== "object") return normalized;
|
|
154
260
|
const source = normalized;
|
|
155
261
|
const existing = seen.get(source);
|
|
156
|
-
if (existing != null)
|
|
157
|
-
|
|
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);
|
|
158
269
|
const proto = Object.getPrototypeOf(source);
|
|
159
270
|
if (proto !== Object.prototype && proto !== null) return normalized;
|
|
160
|
-
return normalizeNestedDelegatedStructuredState(source, seen);
|
|
271
|
+
return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
|
|
161
272
|
}
|
|
162
273
|
/**
|
|
163
274
|
* Creates a short-lived delegated state that exposes the parent's annotations
|
package/dist/modifiers.cjs
CHANGED
|
@@ -82,85 +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 = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(state);
|
|
94
|
+
const run = (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec), shouldNormalize);
|
|
93
95
|
try {
|
|
94
|
-
|
|
96
|
+
const result = run(state, hasCarrier);
|
|
97
|
+
if (!result.success && shouldRetryFalseResult) return run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
|
|
98
|
+
return result;
|
|
95
99
|
} catch (error) {
|
|
96
100
|
if (!hasCarrier) throw error;
|
|
97
|
-
|
|
98
|
-
return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
|
|
101
|
+
return run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
async function completeOptionalLikeAsync(parser, state, exec) {
|
|
102
105
|
const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
|
|
106
|
+
const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(state);
|
|
107
|
+
const run = async (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec), shouldNormalize);
|
|
103
108
|
try {
|
|
104
|
-
|
|
109
|
+
const result = await run(state, hasCarrier);
|
|
110
|
+
if (!result.success && shouldRetryFalseResult) return await run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
|
|
111
|
+
return result;
|
|
105
112
|
} catch (error) {
|
|
106
113
|
if (!hasCarrier) throw error;
|
|
107
|
-
|
|
108
|
-
return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
|
|
114
|
+
return await run(require_annotation_state.normalizeDelegatedAnnotationState(state), false);
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
|
-
function normalizeOptionalLikePhase2Seed(seed) {
|
|
112
|
-
return seed == null ? null : {
|
|
117
|
+
function normalizeOptionalLikePhase2Seed(seed, shouldNormalize) {
|
|
118
|
+
return seed == null ? null : shouldNormalize ? {
|
|
113
119
|
...seed,
|
|
114
120
|
value: require_annotation_state.normalizeNestedDelegatedAnnotationState(seed.value)
|
|
115
|
-
};
|
|
121
|
+
} : seed;
|
|
116
122
|
}
|
|
117
123
|
function extractOptionalLikePhase2Seed(parser, state, exec) {
|
|
118
124
|
if (!Array.isArray(state) && !(state != null && typeof state === "object")) return require_mode_dispatch.wrapForMode(parser.$mode, null);
|
|
119
125
|
const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
|
|
120
126
|
const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(innerState);
|
|
127
|
+
const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(innerState);
|
|
121
128
|
return require_mode_dispatch.dispatchByMode(parser.$mode, () => {
|
|
122
129
|
try {
|
|
123
130
|
const result = parser.complete(innerState, exec);
|
|
124
|
-
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
|
+
}
|
|
125
137
|
const seed = require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
|
|
126
138
|
if (seed == null && hasCarrier) {
|
|
127
139
|
const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
|
|
128
|
-
return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
|
|
140
|
+
return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
|
|
129
141
|
}
|
|
130
|
-
return normalizeOptionalLikePhase2Seed(seed);
|
|
142
|
+
return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
|
|
131
143
|
} catch (error) {
|
|
132
144
|
if (!hasCarrier) throw error;
|
|
133
145
|
const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
|
|
134
146
|
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));
|
|
147
|
+
if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), false);
|
|
148
|
+
return normalizeOptionalLikePhase2Seed(require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
|
|
137
149
|
}
|
|
138
150
|
}, async () => {
|
|
139
151
|
try {
|
|
140
152
|
const result = await parser.complete(innerState, exec);
|
|
141
|
-
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
|
+
}
|
|
142
159
|
const seed = await require_phase2_seed.extractPhase2Seed(parser, innerState, exec);
|
|
143
160
|
if (seed == null && hasCarrier) {
|
|
144
161
|
const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
|
|
145
|
-
return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec));
|
|
162
|
+
return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
|
|
146
163
|
}
|
|
147
|
-
return normalizeOptionalLikePhase2Seed(seed);
|
|
164
|
+
return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
|
|
148
165
|
} catch (error) {
|
|
149
166
|
if (!hasCarrier) throw error;
|
|
150
167
|
const fallbackState = require_annotation_state.normalizeDelegatedAnnotationState(innerState);
|
|
151
168
|
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));
|
|
169
|
+
if (result.success) return normalizeOptionalLikePhase2Seed(require_phase2_seed.phase2SeedFromValueResult(result), false);
|
|
170
|
+
return normalizeOptionalLikePhase2Seed(await require_phase2_seed.extractPhase2Seed(parser, fallbackState, exec), false);
|
|
154
171
|
}
|
|
155
172
|
});
|
|
156
173
|
}
|
|
157
174
|
/**
|
|
158
175
|
* Computes the inner state to pass through to the wrapped parser inside
|
|
159
176
|
* {@link optional} / {@link withDefault}. When the outer state is an
|
|
160
|
-
* array, the inner state is `state[0]`. Otherwise
|
|
177
|
+
* array, the inner state is `state[0]`. Otherwise, including the
|
|
161
178
|
* common case where `optional()` sits at top level and the outer state
|
|
162
179
|
* is either `undefined` or an annotation wrapper from `parseOptionalLike`
|
|
163
|
-
* / `parse({ annotations })
|
|
180
|
+
* / `parse({ annotations })`, we use the wrapped parser's
|
|
164
181
|
* `initialState`, propagating annotations from the outer state so that
|
|
165
182
|
* source-binding wrappers under `optional()` / `withDefault()` (e.g.,
|
|
166
183
|
* `bindEnv()` / `bindConfig()`) can resolve their fallbacks.
|
|
@@ -181,8 +198,8 @@ function deriveOptionalInnerParseState(outerState, parser) {
|
|
|
181
198
|
* Internal helper for optional-style parsing logic shared by optional()
|
|
182
199
|
* and withDefault(). Handles the common pattern of:
|
|
183
200
|
* - Unwrapping optional state to inner parser state
|
|
184
|
-
* - Detecting if inner parser actually matched (state changed or no consumption)
|
|
185
|
-
* - 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
|
|
186
203
|
* @internal
|
|
187
204
|
*/
|
|
188
205
|
function parseOptionalStyleSync(context, parser) {
|
|
@@ -243,7 +260,7 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
243
260
|
* {@link withDefault} before delegating to the inner parser's hook.
|
|
244
261
|
*
|
|
245
262
|
* When state is an array, the adapter unwraps `state[0]` and propagates
|
|
246
|
-
* annotations from the outer array. Non-array objects (e.g
|
|
263
|
+
* annotations from the outer array. Non-array objects (e.g. PromptBindState
|
|
247
264
|
* from `prompt()`) are passed through directly. `undefined` returns `false`
|
|
248
265
|
* without calling the inner hook.
|
|
249
266
|
*
|
|
@@ -253,10 +270,14 @@ function adaptShouldDeferCompletion(innerCheck, parser) {
|
|
|
253
270
|
return (state, exec) => {
|
|
254
271
|
if (Array.isArray(state) || state != null && typeof state === "object") {
|
|
255
272
|
const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
|
|
273
|
+
const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(innerState);
|
|
274
|
+
const shouldRetryFalseResult = hasCarrier && require_annotation_state.isAnnotationWrappedInitialState(innerState);
|
|
256
275
|
try {
|
|
257
|
-
|
|
276
|
+
const result = innerCheck(innerState, exec);
|
|
277
|
+
if (!result && shouldRetryFalseResult) return innerCheck(require_annotation_state.normalizeDelegatedAnnotationState(innerState), exec);
|
|
278
|
+
return result;
|
|
258
279
|
} catch (error) {
|
|
259
|
-
if (!
|
|
280
|
+
if (!hasCarrier) throw error;
|
|
260
281
|
return innerCheck(require_annotation_state.normalizeDelegatedAnnotationState(innerState), exec);
|
|
261
282
|
}
|
|
262
283
|
}
|
package/dist/modifiers.js
CHANGED
|
@@ -4,7 +4,7 @@ import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } fro
|
|
|
4
4
|
import { composeDependencyMetadata } from "./dependency-metadata.js";
|
|
5
5
|
import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
|
|
6
6
|
import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, unmatchedNonCliDependencySourceStateMarker } from "./parser.js";
|
|
7
|
-
import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
|
|
7
|
+
import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
|
|
8
8
|
|
|
9
9
|
//#region src/modifiers.ts
|
|
10
10
|
function withChildExecPath(exec, segment) {
|
|
@@ -82,85 +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 = hasCarrier && isAnnotationWrappedInitialState(state);
|
|
94
|
+
const run = (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(parser.complete(candidate, exec), shouldNormalize);
|
|
93
95
|
try {
|
|
94
|
-
|
|
96
|
+
const result = run(state, hasCarrier);
|
|
97
|
+
if (!result.success && shouldRetryFalseResult) return run(normalizeDelegatedAnnotationState(state), false);
|
|
98
|
+
return result;
|
|
95
99
|
} catch (error) {
|
|
96
100
|
if (!hasCarrier) throw error;
|
|
97
|
-
|
|
98
|
-
return normalizeOptionalLikeCompleteResult(parser.complete(fallbackState, exec));
|
|
101
|
+
return run(normalizeDelegatedAnnotationState(state), false);
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
async function completeOptionalLikeAsync(parser, state, exec) {
|
|
102
105
|
const hasCarrier = hasDelegatedAnnotationCarrier(state);
|
|
106
|
+
const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(state);
|
|
107
|
+
const run = async (candidate, shouldNormalize) => normalizeOptionalLikeCompleteResult(await parser.complete(candidate, exec), shouldNormalize);
|
|
103
108
|
try {
|
|
104
|
-
|
|
109
|
+
const result = await run(state, hasCarrier);
|
|
110
|
+
if (!result.success && shouldRetryFalseResult) return await run(normalizeDelegatedAnnotationState(state), false);
|
|
111
|
+
return result;
|
|
105
112
|
} catch (error) {
|
|
106
113
|
if (!hasCarrier) throw error;
|
|
107
|
-
|
|
108
|
-
return normalizeOptionalLikeCompleteResult(await parser.complete(fallbackState, exec));
|
|
114
|
+
return await run(normalizeDelegatedAnnotationState(state), false);
|
|
109
115
|
}
|
|
110
116
|
}
|
|
111
|
-
function normalizeOptionalLikePhase2Seed(seed) {
|
|
112
|
-
return seed == null ? null : {
|
|
117
|
+
function normalizeOptionalLikePhase2Seed(seed, shouldNormalize) {
|
|
118
|
+
return seed == null ? null : shouldNormalize ? {
|
|
113
119
|
...seed,
|
|
114
120
|
value: normalizeNestedDelegatedAnnotationState(seed.value)
|
|
115
|
-
};
|
|
121
|
+
} : seed;
|
|
116
122
|
}
|
|
117
123
|
function extractOptionalLikePhase2Seed(parser, state, exec) {
|
|
118
124
|
if (!Array.isArray(state) && !(state != null && typeof state === "object")) return wrapForMode(parser.$mode, null);
|
|
119
125
|
const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
|
|
120
126
|
const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
|
|
127
|
+
const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(innerState);
|
|
121
128
|
return dispatchByMode(parser.$mode, () => {
|
|
122
129
|
try {
|
|
123
130
|
const result = parser.complete(innerState, exec);
|
|
124
|
-
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
|
+
}
|
|
125
137
|
const seed = extractPhase2Seed(parser, innerState, exec);
|
|
126
138
|
if (seed == null && hasCarrier) {
|
|
127
139
|
const fallbackState = normalizeDelegatedAnnotationState(innerState);
|
|
128
|
-
return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
|
|
140
|
+
return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
|
|
129
141
|
}
|
|
130
|
-
return normalizeOptionalLikePhase2Seed(seed);
|
|
142
|
+
return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
|
|
131
143
|
} catch (error) {
|
|
132
144
|
if (!hasCarrier) throw error;
|
|
133
145
|
const fallbackState = normalizeDelegatedAnnotationState(innerState);
|
|
134
146
|
const result = parser.complete(fallbackState, exec);
|
|
135
|
-
if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
|
|
136
|
-
return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec));
|
|
147
|
+
if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result), false);
|
|
148
|
+
return normalizeOptionalLikePhase2Seed(extractPhase2Seed(parser, fallbackState, exec), false);
|
|
137
149
|
}
|
|
138
150
|
}, async () => {
|
|
139
151
|
try {
|
|
140
152
|
const result = await parser.complete(innerState, exec);
|
|
141
|
-
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
|
+
}
|
|
142
159
|
const seed = await extractPhase2Seed(parser, innerState, exec);
|
|
143
160
|
if (seed == null && hasCarrier) {
|
|
144
161
|
const fallbackState = normalizeDelegatedAnnotationState(innerState);
|
|
145
|
-
return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec));
|
|
162
|
+
return normalizeOptionalLikePhase2Seed(await extractPhase2Seed(parser, fallbackState, exec), false);
|
|
146
163
|
}
|
|
147
|
-
return normalizeOptionalLikePhase2Seed(seed);
|
|
164
|
+
return normalizeOptionalLikePhase2Seed(seed, hasCarrier);
|
|
148
165
|
} catch (error) {
|
|
149
166
|
if (!hasCarrier) throw error;
|
|
150
167
|
const fallbackState = normalizeDelegatedAnnotationState(innerState);
|
|
151
168
|
const result = await parser.complete(fallbackState, exec);
|
|
152
|
-
if (result.success) return normalizeOptionalLikePhase2Seed(phase2SeedFromValueResult(result));
|
|
153
|
-
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);
|
|
154
171
|
}
|
|
155
172
|
});
|
|
156
173
|
}
|
|
157
174
|
/**
|
|
158
175
|
* Computes the inner state to pass through to the wrapped parser inside
|
|
159
176
|
* {@link optional} / {@link withDefault}. When the outer state is an
|
|
160
|
-
* array, the inner state is `state[0]`. Otherwise
|
|
177
|
+
* array, the inner state is `state[0]`. Otherwise, including the
|
|
161
178
|
* common case where `optional()` sits at top level and the outer state
|
|
162
179
|
* is either `undefined` or an annotation wrapper from `parseOptionalLike`
|
|
163
|
-
* / `parse({ annotations })
|
|
180
|
+
* / `parse({ annotations })`, we use the wrapped parser's
|
|
164
181
|
* `initialState`, propagating annotations from the outer state so that
|
|
165
182
|
* source-binding wrappers under `optional()` / `withDefault()` (e.g.,
|
|
166
183
|
* `bindEnv()` / `bindConfig()`) can resolve their fallbacks.
|
|
@@ -181,8 +198,8 @@ function deriveOptionalInnerParseState(outerState, parser) {
|
|
|
181
198
|
* Internal helper for optional-style parsing logic shared by optional()
|
|
182
199
|
* and withDefault(). Handles the common pattern of:
|
|
183
200
|
* - Unwrapping optional state to inner parser state
|
|
184
|
-
* - Detecting if inner parser actually matched (state changed or no consumption)
|
|
185
|
-
* - 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
|
|
186
203
|
* @internal
|
|
187
204
|
*/
|
|
188
205
|
function parseOptionalStyleSync(context, parser) {
|
|
@@ -243,7 +260,7 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
243
260
|
* {@link withDefault} before delegating to the inner parser's hook.
|
|
244
261
|
*
|
|
245
262
|
* When state is an array, the adapter unwraps `state[0]` and propagates
|
|
246
|
-
* annotations from the outer array. Non-array objects (e.g
|
|
263
|
+
* annotations from the outer array. Non-array objects (e.g. PromptBindState
|
|
247
264
|
* from `prompt()`) are passed through directly. `undefined` returns `false`
|
|
248
265
|
* without calling the inner hook.
|
|
249
266
|
*
|
|
@@ -253,10 +270,14 @@ function adaptShouldDeferCompletion(innerCheck, parser) {
|
|
|
253
270
|
return (state, exec) => {
|
|
254
271
|
if (Array.isArray(state) || state != null && typeof state === "object") {
|
|
255
272
|
const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
|
|
273
|
+
const hasCarrier = hasDelegatedAnnotationCarrier(innerState);
|
|
274
|
+
const shouldRetryFalseResult = hasCarrier && isAnnotationWrappedInitialState(innerState);
|
|
256
275
|
try {
|
|
257
|
-
|
|
276
|
+
const result = innerCheck(innerState, exec);
|
|
277
|
+
if (!result && shouldRetryFalseResult) return innerCheck(normalizeDelegatedAnnotationState(innerState), exec);
|
|
278
|
+
return result;
|
|
258
279
|
} catch (error) {
|
|
259
|
-
if (!
|
|
280
|
+
if (!hasCarrier) throw error;
|
|
260
281
|
return innerCheck(normalizeDelegatedAnnotationState(innerState), exec);
|
|
261
282
|
}
|
|
262
283
|
}
|