@optique/core 1.0.0-dev.1854 → 1.0.0-dev.1858

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.
@@ -50,14 +50,20 @@ const protectedAnnotationStateViews = /* @__PURE__ */ new WeakMap();
50
50
  function throwReadonlyAnnotationMutation() {
51
51
  throw new TypeError("Cannot mutate read-only annotation data.");
52
52
  }
53
- function createAnnotationProtectionContext() {
54
- return { cache: /* @__PURE__ */ new WeakMap() };
53
+ function createAnnotationProtectionContext(rewrapProtectedViews = false) {
54
+ return {
55
+ cache: /* @__PURE__ */ new WeakMap(),
56
+ rewrapProtectedViews
57
+ };
55
58
  }
56
59
  function registerProtectedAnnotationView(context, target, view) {
57
60
  context.cache.set(target, view);
58
61
  protectedAnnotationTargets.set(view, target);
59
62
  return view;
60
63
  }
64
+ function cacheProtectedAnnotationViewAlias(context, alias, view) {
65
+ context.cache.set(alias, view);
66
+ }
61
67
  function isProtectedAnnotationView(value) {
62
68
  return value != null && typeof value === "object" && protectedAnnotationTargets.has(value);
63
69
  }
@@ -81,11 +87,11 @@ function defineProtectedDataProperty(context, target, key, descriptor) {
81
87
  set: () => throwReadonlyAnnotationMutation()
82
88
  });
83
89
  }
84
- function copyRegExpMetadata(source, target, transformValue) {
90
+ function copyOwnProperties(source, target, transformValue, excludedKeys) {
85
91
  const sourcePrototype = Object.getPrototypeOf(source);
86
92
  if (Object.getPrototypeOf(target) !== sourcePrototype) Object.setPrototypeOf(target, sourcePrototype);
87
93
  for (const key of Reflect.ownKeys(source)) {
88
- if (key === "lastIndex") continue;
94
+ if (excludedKeys?.has(key) === true) continue;
89
95
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
90
96
  if (descriptor == null) continue;
91
97
  if ("value" in descriptor && transformValue != null) {
@@ -97,6 +103,10 @@ function copyRegExpMetadata(source, target, transformValue) {
97
103
  }
98
104
  Object.defineProperty(target, key, descriptor);
99
105
  }
106
+ }
107
+ const regExpExcludedKeys = new Set(["lastIndex"]);
108
+ function copyRegExpMetadata(source, target, transformValue) {
109
+ copyOwnProperties(source, target, transformValue, regExpExcludedKeys);
100
110
  target.lastIndex = source.lastIndex;
101
111
  }
102
112
  function cloneRegExpShape(source) {
@@ -106,7 +116,8 @@ function cloneRegExpShape(source) {
106
116
  }
107
117
  function createProtectedObjectView(target, context) {
108
118
  if (Array.isArray(target)) {
109
- const view$1 = new Array(target.length);
119
+ const view$1 = Object.setPrototypeOf([], Object.getPrototypeOf(target));
120
+ view$1.length = target.length;
110
121
  registerProtectedAnnotationView(context, target, view$1);
111
122
  for (const key of Reflect.ownKeys(target)) {
112
123
  if (key === "length") continue;
@@ -145,26 +156,27 @@ function createProtectedObjectView(target, context) {
145
156
  }
146
157
  function createProtectedMapView(target, context) {
147
158
  const methodCache = /* @__PURE__ */ new Map();
148
- const view = new Proxy(target, {
149
- get(target$1, key) {
150
- if (key === "size") return target$1.size;
159
+ const cloned = new Map(target);
160
+ const view = new Proxy(cloned, {
161
+ get(clonedTarget, key) {
162
+ if (key === "size") return clonedTarget.size;
151
163
  if (key === "set" || key === "delete" || key === "clear") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
152
- if (key === "get") return cacheProtectedMethod(methodCache, key, () => (lookup) => protectAnnotationValue(target$1.get(unwrapProtectedAnnotationTarget(lookup)), context));
153
- if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => target$1.has(unwrapProtectedAnnotationTarget(lookup)));
154
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1, mapKey) => {
164
+ if (key === "get") return cacheProtectedMethod(methodCache, key, () => (lookup) => protectAnnotationValue(clonedTarget.get(unwrapProtectedAnnotationTarget(lookup)), context));
165
+ if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => clonedTarget.has(unwrapProtectedAnnotationTarget(lookup)));
166
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1, mapKey) => {
155
167
  callback.call(thisArg, protectAnnotationValue(value$1, context), protectAnnotationValue(mapKey, context), view);
156
168
  }));
157
169
  if (key === "keys") return cacheProtectedMethod(methodCache, key, () => function* () {
158
- for (const value$1 of target$1.keys()) yield protectAnnotationValue(value$1, context);
170
+ for (const value$1 of clonedTarget.keys()) yield protectAnnotationValue(value$1, context);
159
171
  });
160
172
  if (key === "values") return cacheProtectedMethod(methodCache, key, () => function* () {
161
- for (const value$1 of target$1.values()) yield protectAnnotationValue(value$1, context);
173
+ for (const value$1 of clonedTarget.values()) yield protectAnnotationValue(value$1, context);
162
174
  });
163
175
  if (key === "entries" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
164
- for (const [entryKey, entryValue] of target$1.entries()) yield [protectAnnotationValue(entryKey, context), protectAnnotationValue(entryValue, context)];
176
+ for (const [entryKey, entryValue] of clonedTarget.entries()) yield [protectAnnotationValue(entryKey, context), protectAnnotationValue(entryValue, context)];
165
177
  });
166
- const value = Reflect.get(target$1, key, target$1);
167
- return typeof value === "function" ? value.bind(target$1) : value;
178
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
179
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
168
180
  },
169
181
  set() {
170
182
  throwReadonlyAnnotationMutation();
@@ -182,30 +194,34 @@ function createProtectedMapView(target, context) {
182
194
  throwReadonlyAnnotationMutation();
183
195
  }
184
196
  });
185
- return registerProtectedAnnotationView(context, target, view);
197
+ registerProtectedAnnotationView(context, target, view);
198
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
199
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
200
+ return view;
186
201
  }
187
202
  function createProtectedSetView(target, context) {
188
203
  const methodCache = /* @__PURE__ */ new Map();
189
- const view = new Proxy(target, {
190
- get(target$1, key) {
191
- if (key === "size") return target$1.size;
204
+ const cloned = new Set(target);
205
+ const view = new Proxy(cloned, {
206
+ get(clonedTarget, key) {
207
+ if (key === "size") return clonedTarget.size;
192
208
  if (key === "add" || key === "delete" || key === "clear") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
193
- if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => target$1.has(unwrapProtectedAnnotationTarget(lookup)));
194
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1) => {
209
+ if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => clonedTarget.has(unwrapProtectedAnnotationTarget(lookup)));
210
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1) => {
195
211
  const protectedValue = protectAnnotationValue(value$1, context);
196
212
  callback.call(thisArg, protectedValue, protectedValue, view);
197
213
  }));
198
214
  if (key === "keys" || key === "values" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
199
- for (const value$1 of target$1.values()) yield protectAnnotationValue(value$1, context);
215
+ for (const value$1 of clonedTarget.values()) yield protectAnnotationValue(value$1, context);
200
216
  });
201
217
  if (key === "entries") return cacheProtectedMethod(methodCache, key, () => function* () {
202
- for (const value$1 of target$1.values()) {
218
+ for (const value$1 of clonedTarget.values()) {
203
219
  const protectedValue = protectAnnotationValue(value$1, context);
204
220
  yield [protectedValue, protectedValue];
205
221
  }
206
222
  });
207
- const value = Reflect.get(target$1, key, target$1);
208
- return typeof value === "function" ? value.bind(target$1) : value;
223
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
224
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
209
225
  },
210
226
  set() {
211
227
  throwReadonlyAnnotationMutation();
@@ -223,15 +239,19 @@ function createProtectedSetView(target, context) {
223
239
  throwReadonlyAnnotationMutation();
224
240
  }
225
241
  });
226
- return registerProtectedAnnotationView(context, target, view);
242
+ registerProtectedAnnotationView(context, target, view);
243
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
244
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
245
+ return view;
227
246
  }
228
247
  function createProtectedDateView(target, context) {
229
248
  const methodCache = /* @__PURE__ */ new Map();
230
- const view = new Proxy(target, {
231
- get(target$1, key) {
232
- const value = Reflect.get(target$1, key, target$1);
249
+ const cloned = new Date(target.getTime());
250
+ const view = new Proxy(cloned, {
251
+ get(clonedTarget, key) {
252
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
233
253
  if (typeof key === "string" && key.startsWith("set")) return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
234
- return typeof value === "function" ? value.bind(target$1) : value;
254
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
235
255
  },
236
256
  set() {
237
257
  throwReadonlyAnnotationMutation();
@@ -249,7 +269,10 @@ function createProtectedDateView(target, context) {
249
269
  throwReadonlyAnnotationMutation();
250
270
  }
251
271
  });
252
- return registerProtectedAnnotationView(context, target, view);
272
+ registerProtectedAnnotationView(context, target, view);
273
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
274
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
275
+ return view;
253
276
  }
254
277
  function createProtectedRegExpView(target, context) {
255
278
  const methodCache = /* @__PURE__ */ new Map();
@@ -279,26 +302,28 @@ function createProtectedRegExpView(target, context) {
279
302
  }
280
303
  });
281
304
  registerProtectedAnnotationView(context, target, view);
305
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
282
306
  copyRegExpMetadata(target, cloned, (value) => protectAnnotationValue(value, context));
283
307
  return view;
284
308
  }
285
309
  function createProtectedURLSearchParamsView(target, context) {
286
310
  const methodCache = /* @__PURE__ */ new Map();
287
- const view = new Proxy(target, {
288
- get(target$1, key) {
311
+ const cloned = new URLSearchParams(target);
312
+ const view = new Proxy(cloned, {
313
+ get(clonedTarget, key) {
289
314
  if (key === "append" || key === "delete" || key === "set" || key === "sort") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
290
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1, name) => {
315
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1, name) => {
291
316
  callback.call(thisArg, value$1, name, view);
292
317
  }));
293
318
  if (key === "keys" || key === "values") return cacheProtectedMethod(methodCache, key, () => function* () {
294
- const iterator = key === "keys" ? target$1.keys() : target$1.values();
319
+ const iterator = key === "keys" ? clonedTarget.keys() : clonedTarget.values();
295
320
  for (const value$1 of iterator) yield value$1;
296
321
  });
297
322
  if (key === "entries" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
298
- for (const entry of target$1.entries()) yield entry;
323
+ for (const entry of clonedTarget.entries()) yield entry;
299
324
  });
300
- const value = Reflect.get(target$1, key, target$1);
301
- return typeof value === "function" ? value.bind(target$1) : value;
325
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
326
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
302
327
  },
303
328
  set() {
304
329
  throwReadonlyAnnotationMutation();
@@ -316,14 +341,18 @@ function createProtectedURLSearchParamsView(target, context) {
316
341
  throwReadonlyAnnotationMutation();
317
342
  }
318
343
  });
319
- return registerProtectedAnnotationView(context, target, view);
344
+ registerProtectedAnnotationView(context, target, view);
345
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
346
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
347
+ return view;
320
348
  }
321
349
  function createProtectedURLView(target, context) {
322
- const view = new Proxy(target, {
323
- get(target$1, key) {
324
- if (key === "searchParams") return protectAnnotationValue(target$1.searchParams, context);
325
- const value = Reflect.get(target$1, key, target$1);
326
- return typeof value === "function" ? value.bind(target$1) : value;
350
+ const cloned = new URL(target.href);
351
+ const view = new Proxy(cloned, {
352
+ get(clonedTarget, key) {
353
+ if (key === "searchParams") return protectAnnotationValue(clonedTarget.searchParams, context);
354
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
355
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
327
356
  },
328
357
  set() {
329
358
  throwReadonlyAnnotationMutation();
@@ -341,12 +370,16 @@ function createProtectedURLView(target, context) {
341
370
  throwReadonlyAnnotationMutation();
342
371
  }
343
372
  });
344
- return registerProtectedAnnotationView(context, target, view);
373
+ registerProtectedAnnotationView(context, target, view);
374
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
375
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
376
+ return view;
345
377
  }
346
378
  function protectAnnotationValue(value, context) {
347
379
  if (value == null || typeof value !== "object") return value;
348
- const target = value;
349
- if (isProtectedAnnotationView(value)) return value;
380
+ const isProtectedView = isProtectedAnnotationView(value);
381
+ if (isProtectedView && !context.rewrapProtectedViews) return value;
382
+ const target = isProtectedView ? unwrapProtectedAnnotationTarget(value) : value;
350
383
  const cached = context.cache.get(target);
351
384
  if (cached !== void 0) return cached;
352
385
  if (target instanceof Map) return createProtectedMapView(target, context);
@@ -361,6 +394,85 @@ function protectAnnotationValue(value, context) {
361
394
  return value;
362
395
  }
363
396
  /**
397
+ * Normalizes annotation input for a fresh parse run.
398
+ *
399
+ * When callers feed a protected annotation view returned by `getAnnotations()`
400
+ * back into a new parse entrypoint, Optique unwraps it to the caller-owned
401
+ * record first so the new run gets its own protected views.
402
+ *
403
+ * @param annotations The caller-supplied annotations input.
404
+ * @returns The raw annotation record to inject for the new run.
405
+ * @internal
406
+ */
407
+ function normalizeRunAnnotationInput(annotations) {
408
+ return isProtectedAnnotationView(annotations) ? unwrapProtectedAnnotationTarget(annotations) : annotations;
409
+ }
410
+ function injectAnnotationsWithContext(state, annotations, context) {
411
+ const protectedAnnotations = protectAnnotationValue(annotations, context);
412
+ if (state == null || typeof state !== "object") {
413
+ const wrapper = {};
414
+ Object.defineProperties(wrapper, {
415
+ [annotationKey]: {
416
+ value: protectedAnnotations,
417
+ enumerable: true,
418
+ writable: true,
419
+ configurable: true
420
+ },
421
+ [annotationStateValueKey]: {
422
+ value: state,
423
+ enumerable: false,
424
+ writable: true,
425
+ configurable: true
426
+ },
427
+ [annotationWrapperKey]: {
428
+ value: true,
429
+ enumerable: false,
430
+ writable: true,
431
+ configurable: true
432
+ }
433
+ });
434
+ injectedAnnotationWrappers.add(wrapper);
435
+ return wrapper;
436
+ }
437
+ if (Array.isArray(state)) {
438
+ const cloned$1 = [...state];
439
+ cloned$1[annotationKey] = protectedAnnotations;
440
+ return cloned$1;
441
+ }
442
+ if (isInjectedAnnotationWrapper(state)) {
443
+ state[annotationKey] = protectedAnnotations;
444
+ return state;
445
+ }
446
+ if (state instanceof Date) {
447
+ const cloned$1 = new Date(state.getTime());
448
+ cloned$1[annotationKey] = protectedAnnotations;
449
+ return cloned$1;
450
+ }
451
+ if (state instanceof Map) {
452
+ const cloned$1 = new Map(state);
453
+ cloned$1[annotationKey] = protectedAnnotations;
454
+ return cloned$1;
455
+ }
456
+ if (state instanceof Set) {
457
+ const cloned$1 = new Set(state);
458
+ cloned$1[annotationKey] = protectedAnnotations;
459
+ return cloned$1;
460
+ }
461
+ if (state instanceof RegExp) {
462
+ const cloned$1 = cloneRegExpShape(state);
463
+ cloned$1[annotationKey] = protectedAnnotations;
464
+ return cloned$1;
465
+ }
466
+ const proto = Object.getPrototypeOf(state);
467
+ if (proto === Object.prototype || proto === null) return {
468
+ ...state,
469
+ [annotationKey]: protectedAnnotations
470
+ };
471
+ const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
472
+ cloned[annotationKey] = protectedAnnotations;
473
+ return cloned;
474
+ }
475
+ /**
364
476
  * Extracts annotations from parser state.
365
477
  *
366
478
  * @param state Parser state that may contain annotations
@@ -491,69 +603,22 @@ function hasMeaningfulAnnotations(annotations) {
491
603
  */
492
604
  function injectAnnotations(state, annotations) {
493
605
  if (!hasMeaningfulAnnotations(annotations)) return state;
494
- const protectedAnnotations = protectAnnotationValue(annotations, createAnnotationProtectionContext());
495
- if (state == null || typeof state !== "object") {
496
- const wrapper = {};
497
- Object.defineProperties(wrapper, {
498
- [annotationKey]: {
499
- value: protectedAnnotations,
500
- enumerable: true,
501
- writable: true,
502
- configurable: true
503
- },
504
- [annotationStateValueKey]: {
505
- value: state,
506
- enumerable: false,
507
- writable: true,
508
- configurable: true
509
- },
510
- [annotationWrapperKey]: {
511
- value: true,
512
- enumerable: false,
513
- writable: true,
514
- configurable: true
515
- }
516
- });
517
- injectedAnnotationWrappers.add(wrapper);
518
- return wrapper;
519
- }
520
- if (Array.isArray(state)) {
521
- const cloned$1 = [...state];
522
- cloned$1[annotationKey] = protectedAnnotations;
523
- return cloned$1;
524
- }
525
- if (isInjectedAnnotationWrapper(state)) {
526
- state[annotationKey] = protectedAnnotations;
527
- return state;
528
- }
529
- if (state instanceof Date) {
530
- const cloned$1 = new Date(state.getTime());
531
- cloned$1[annotationKey] = protectedAnnotations;
532
- return cloned$1;
533
- }
534
- if (state instanceof Map) {
535
- const cloned$1 = new Map(state);
536
- cloned$1[annotationKey] = protectedAnnotations;
537
- return cloned$1;
538
- }
539
- if (state instanceof Set) {
540
- const cloned$1 = new Set(state);
541
- cloned$1[annotationKey] = protectedAnnotations;
542
- return cloned$1;
543
- }
544
- if (state instanceof RegExp) {
545
- const cloned$1 = cloneRegExpShape(state);
546
- cloned$1[annotationKey] = protectedAnnotations;
547
- return cloned$1;
548
- }
549
- const proto = Object.getPrototypeOf(state);
550
- if (proto === Object.prototype || proto === null) return {
551
- ...state,
552
- [annotationKey]: protectedAnnotations
553
- };
554
- const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
555
- cloned[annotationKey] = protectedAnnotations;
556
- return cloned;
606
+ return injectAnnotationsWithContext(state, annotations, createAnnotationProtectionContext());
607
+ }
608
+ /**
609
+ * Injects annotations for a fresh parse run.
610
+ *
611
+ * This path re-wraps protected views from previous runs so stateful container
612
+ * internals remain isolated across parse entrypoints.
613
+ *
614
+ * @param state The parser state to annotate.
615
+ * @param annotations The annotations to inject.
616
+ * @returns Annotated state for the fresh run.
617
+ * @internal
618
+ */
619
+ function injectFreshRunAnnotations(state, annotations) {
620
+ if (!hasMeaningfulAnnotations(annotations)) return state;
621
+ return injectAnnotationsWithContext(state, normalizeRunAnnotationInput(annotations), createAnnotationProtectionContext(true));
557
622
  }
558
623
  /**
559
624
  * Unwraps a primitive-state annotation wrapper injected by Optique internals.
@@ -593,5 +658,7 @@ exports.getAnnotations = getAnnotations;
593
658
  exports.hasMeaningfulAnnotations = hasMeaningfulAnnotations;
594
659
  exports.inheritAnnotations = inheritAnnotations;
595
660
  exports.injectAnnotations = injectAnnotations;
661
+ exports.injectFreshRunAnnotations = injectFreshRunAnnotations;
596
662
  exports.isInjectedAnnotationWrapper = isInjectedAnnotationWrapper;
663
+ exports.normalizeRunAnnotationInput = normalizeRunAnnotationInput;
597
664
  exports.unwrapInjectedAnnotationWrapper = unwrapInjectedAnnotationWrapper;
@@ -64,6 +64,18 @@ type Annotations = Record<symbol, unknown>;
64
64
  */
65
65
  type ReadonlyAnnotations = Readonly<Annotations>;
66
66
  type AnnotationInput = Annotations | ReadonlyAnnotations;
67
+ /**
68
+ * Normalizes annotation input for a fresh parse run.
69
+ *
70
+ * When callers feed a protected annotation view returned by `getAnnotations()`
71
+ * back into a new parse entrypoint, Optique unwraps it to the caller-owned
72
+ * record first so the new run gets its own protected views.
73
+ *
74
+ * @param annotations The caller-supplied annotations input.
75
+ * @returns The raw annotation record to inject for the new run.
76
+ * @internal
77
+ */
78
+ declare function normalizeRunAnnotationInput(annotations: AnnotationInput): AnnotationInput;
67
79
  /**
68
80
  * Options for parse functions.
69
81
  * @since 0.10.0
@@ -150,6 +162,18 @@ declare function hasMeaningfulAnnotations(annotations: AnnotationInput | null |
150
162
  * @internal
151
163
  */
152
164
  declare function injectAnnotations<TState>(state: TState, annotations: AnnotationInput): TState;
165
+ /**
166
+ * Injects annotations for a fresh parse run.
167
+ *
168
+ * This path re-wraps protected views from previous runs so stateful container
169
+ * internals remain isolated across parse entrypoints.
170
+ *
171
+ * @param state The parser state to annotate.
172
+ * @param annotations The annotations to inject.
173
+ * @returns Annotated state for the fresh run.
174
+ * @internal
175
+ */
176
+ declare function injectFreshRunAnnotations<TState>(state: TState, annotations: AnnotationInput): TState;
153
177
  /**
154
178
  * Unwraps a primitive-state annotation wrapper injected by Optique internals.
155
179
  *
@@ -169,4 +193,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
169
193
  */
170
194
  declare function isInjectedAnnotationWrapper(value: unknown): boolean;
171
195
  //#endregion
172
- export { Annotations, ParseOptions, ReadonlyAnnotations, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
196
+ export { Annotations, ParseOptions, ReadonlyAnnotations, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, injectFreshRunAnnotations, isInjectedAnnotationWrapper, normalizeRunAnnotationInput, unwrapInjectedAnnotationWrapper };
@@ -64,6 +64,18 @@ type Annotations = Record<symbol, unknown>;
64
64
  */
65
65
  type ReadonlyAnnotations = Readonly<Annotations>;
66
66
  type AnnotationInput = Annotations | ReadonlyAnnotations;
67
+ /**
68
+ * Normalizes annotation input for a fresh parse run.
69
+ *
70
+ * When callers feed a protected annotation view returned by `getAnnotations()`
71
+ * back into a new parse entrypoint, Optique unwraps it to the caller-owned
72
+ * record first so the new run gets its own protected views.
73
+ *
74
+ * @param annotations The caller-supplied annotations input.
75
+ * @returns The raw annotation record to inject for the new run.
76
+ * @internal
77
+ */
78
+ declare function normalizeRunAnnotationInput(annotations: AnnotationInput): AnnotationInput;
67
79
  /**
68
80
  * Options for parse functions.
69
81
  * @since 0.10.0
@@ -150,6 +162,18 @@ declare function hasMeaningfulAnnotations(annotations: AnnotationInput | null |
150
162
  * @internal
151
163
  */
152
164
  declare function injectAnnotations<TState>(state: TState, annotations: AnnotationInput): TState;
165
+ /**
166
+ * Injects annotations for a fresh parse run.
167
+ *
168
+ * This path re-wraps protected views from previous runs so stateful container
169
+ * internals remain isolated across parse entrypoints.
170
+ *
171
+ * @param state The parser state to annotate.
172
+ * @param annotations The annotations to inject.
173
+ * @returns Annotated state for the fresh run.
174
+ * @internal
175
+ */
176
+ declare function injectFreshRunAnnotations<TState>(state: TState, annotations: AnnotationInput): TState;
153
177
  /**
154
178
  * Unwraps a primitive-state annotation wrapper injected by Optique internals.
155
179
  *
@@ -169,4 +193,4 @@ declare function unwrapInjectedAnnotationWrapper<T>(value: T): T;
169
193
  */
170
194
  declare function isInjectedAnnotationWrapper(value: unknown): boolean;
171
195
  //#endregion
172
- export { Annotations, ParseOptions, ReadonlyAnnotations, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
196
+ export { Annotations, ParseOptions, ReadonlyAnnotations, annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, injectFreshRunAnnotations, isInjectedAnnotationWrapper, normalizeRunAnnotationInput, unwrapInjectedAnnotationWrapper };
@@ -49,14 +49,20 @@ const protectedAnnotationStateViews = /* @__PURE__ */ new WeakMap();
49
49
  function throwReadonlyAnnotationMutation() {
50
50
  throw new TypeError("Cannot mutate read-only annotation data.");
51
51
  }
52
- function createAnnotationProtectionContext() {
53
- return { cache: /* @__PURE__ */ new WeakMap() };
52
+ function createAnnotationProtectionContext(rewrapProtectedViews = false) {
53
+ return {
54
+ cache: /* @__PURE__ */ new WeakMap(),
55
+ rewrapProtectedViews
56
+ };
54
57
  }
55
58
  function registerProtectedAnnotationView(context, target, view) {
56
59
  context.cache.set(target, view);
57
60
  protectedAnnotationTargets.set(view, target);
58
61
  return view;
59
62
  }
63
+ function cacheProtectedAnnotationViewAlias(context, alias, view) {
64
+ context.cache.set(alias, view);
65
+ }
60
66
  function isProtectedAnnotationView(value) {
61
67
  return value != null && typeof value === "object" && protectedAnnotationTargets.has(value);
62
68
  }
@@ -80,11 +86,11 @@ function defineProtectedDataProperty(context, target, key, descriptor) {
80
86
  set: () => throwReadonlyAnnotationMutation()
81
87
  });
82
88
  }
83
- function copyRegExpMetadata(source, target, transformValue) {
89
+ function copyOwnProperties(source, target, transformValue, excludedKeys) {
84
90
  const sourcePrototype = Object.getPrototypeOf(source);
85
91
  if (Object.getPrototypeOf(target) !== sourcePrototype) Object.setPrototypeOf(target, sourcePrototype);
86
92
  for (const key of Reflect.ownKeys(source)) {
87
- if (key === "lastIndex") continue;
93
+ if (excludedKeys?.has(key) === true) continue;
88
94
  const descriptor = Object.getOwnPropertyDescriptor(source, key);
89
95
  if (descriptor == null) continue;
90
96
  if ("value" in descriptor && transformValue != null) {
@@ -96,6 +102,10 @@ function copyRegExpMetadata(source, target, transformValue) {
96
102
  }
97
103
  Object.defineProperty(target, key, descriptor);
98
104
  }
105
+ }
106
+ const regExpExcludedKeys = new Set(["lastIndex"]);
107
+ function copyRegExpMetadata(source, target, transformValue) {
108
+ copyOwnProperties(source, target, transformValue, regExpExcludedKeys);
99
109
  target.lastIndex = source.lastIndex;
100
110
  }
101
111
  function cloneRegExpShape(source) {
@@ -105,7 +115,8 @@ function cloneRegExpShape(source) {
105
115
  }
106
116
  function createProtectedObjectView(target, context) {
107
117
  if (Array.isArray(target)) {
108
- const view$1 = new Array(target.length);
118
+ const view$1 = Object.setPrototypeOf([], Object.getPrototypeOf(target));
119
+ view$1.length = target.length;
109
120
  registerProtectedAnnotationView(context, target, view$1);
110
121
  for (const key of Reflect.ownKeys(target)) {
111
122
  if (key === "length") continue;
@@ -144,26 +155,27 @@ function createProtectedObjectView(target, context) {
144
155
  }
145
156
  function createProtectedMapView(target, context) {
146
157
  const methodCache = /* @__PURE__ */ new Map();
147
- const view = new Proxy(target, {
148
- get(target$1, key) {
149
- if (key === "size") return target$1.size;
158
+ const cloned = new Map(target);
159
+ const view = new Proxy(cloned, {
160
+ get(clonedTarget, key) {
161
+ if (key === "size") return clonedTarget.size;
150
162
  if (key === "set" || key === "delete" || key === "clear") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
151
- if (key === "get") return cacheProtectedMethod(methodCache, key, () => (lookup) => protectAnnotationValue(target$1.get(unwrapProtectedAnnotationTarget(lookup)), context));
152
- if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => target$1.has(unwrapProtectedAnnotationTarget(lookup)));
153
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1, mapKey) => {
163
+ if (key === "get") return cacheProtectedMethod(methodCache, key, () => (lookup) => protectAnnotationValue(clonedTarget.get(unwrapProtectedAnnotationTarget(lookup)), context));
164
+ if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => clonedTarget.has(unwrapProtectedAnnotationTarget(lookup)));
165
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1, mapKey) => {
154
166
  callback.call(thisArg, protectAnnotationValue(value$1, context), protectAnnotationValue(mapKey, context), view);
155
167
  }));
156
168
  if (key === "keys") return cacheProtectedMethod(methodCache, key, () => function* () {
157
- for (const value$1 of target$1.keys()) yield protectAnnotationValue(value$1, context);
169
+ for (const value$1 of clonedTarget.keys()) yield protectAnnotationValue(value$1, context);
158
170
  });
159
171
  if (key === "values") return cacheProtectedMethod(methodCache, key, () => function* () {
160
- for (const value$1 of target$1.values()) yield protectAnnotationValue(value$1, context);
172
+ for (const value$1 of clonedTarget.values()) yield protectAnnotationValue(value$1, context);
161
173
  });
162
174
  if (key === "entries" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
163
- for (const [entryKey, entryValue] of target$1.entries()) yield [protectAnnotationValue(entryKey, context), protectAnnotationValue(entryValue, context)];
175
+ for (const [entryKey, entryValue] of clonedTarget.entries()) yield [protectAnnotationValue(entryKey, context), protectAnnotationValue(entryValue, context)];
164
176
  });
165
- const value = Reflect.get(target$1, key, target$1);
166
- return typeof value === "function" ? value.bind(target$1) : value;
177
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
178
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
167
179
  },
168
180
  set() {
169
181
  throwReadonlyAnnotationMutation();
@@ -181,30 +193,34 @@ function createProtectedMapView(target, context) {
181
193
  throwReadonlyAnnotationMutation();
182
194
  }
183
195
  });
184
- return registerProtectedAnnotationView(context, target, view);
196
+ registerProtectedAnnotationView(context, target, view);
197
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
198
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
199
+ return view;
185
200
  }
186
201
  function createProtectedSetView(target, context) {
187
202
  const methodCache = /* @__PURE__ */ new Map();
188
- const view = new Proxy(target, {
189
- get(target$1, key) {
190
- if (key === "size") return target$1.size;
203
+ const cloned = new Set(target);
204
+ const view = new Proxy(cloned, {
205
+ get(clonedTarget, key) {
206
+ if (key === "size") return clonedTarget.size;
191
207
  if (key === "add" || key === "delete" || key === "clear") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
192
- if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => target$1.has(unwrapProtectedAnnotationTarget(lookup)));
193
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1) => {
208
+ if (key === "has") return cacheProtectedMethod(methodCache, key, () => (lookup) => clonedTarget.has(unwrapProtectedAnnotationTarget(lookup)));
209
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1) => {
194
210
  const protectedValue = protectAnnotationValue(value$1, context);
195
211
  callback.call(thisArg, protectedValue, protectedValue, view);
196
212
  }));
197
213
  if (key === "keys" || key === "values" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
198
- for (const value$1 of target$1.values()) yield protectAnnotationValue(value$1, context);
214
+ for (const value$1 of clonedTarget.values()) yield protectAnnotationValue(value$1, context);
199
215
  });
200
216
  if (key === "entries") return cacheProtectedMethod(methodCache, key, () => function* () {
201
- for (const value$1 of target$1.values()) {
217
+ for (const value$1 of clonedTarget.values()) {
202
218
  const protectedValue = protectAnnotationValue(value$1, context);
203
219
  yield [protectedValue, protectedValue];
204
220
  }
205
221
  });
206
- const value = Reflect.get(target$1, key, target$1);
207
- return typeof value === "function" ? value.bind(target$1) : value;
222
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
223
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
208
224
  },
209
225
  set() {
210
226
  throwReadonlyAnnotationMutation();
@@ -222,15 +238,19 @@ function createProtectedSetView(target, context) {
222
238
  throwReadonlyAnnotationMutation();
223
239
  }
224
240
  });
225
- return registerProtectedAnnotationView(context, target, view);
241
+ registerProtectedAnnotationView(context, target, view);
242
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
243
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
244
+ return view;
226
245
  }
227
246
  function createProtectedDateView(target, context) {
228
247
  const methodCache = /* @__PURE__ */ new Map();
229
- const view = new Proxy(target, {
230
- get(target$1, key) {
231
- const value = Reflect.get(target$1, key, target$1);
248
+ const cloned = new Date(target.getTime());
249
+ const view = new Proxy(cloned, {
250
+ get(clonedTarget, key) {
251
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
232
252
  if (typeof key === "string" && key.startsWith("set")) return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
233
- return typeof value === "function" ? value.bind(target$1) : value;
253
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
234
254
  },
235
255
  set() {
236
256
  throwReadonlyAnnotationMutation();
@@ -248,7 +268,10 @@ function createProtectedDateView(target, context) {
248
268
  throwReadonlyAnnotationMutation();
249
269
  }
250
270
  });
251
- return registerProtectedAnnotationView(context, target, view);
271
+ registerProtectedAnnotationView(context, target, view);
272
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
273
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
274
+ return view;
252
275
  }
253
276
  function createProtectedRegExpView(target, context) {
254
277
  const methodCache = /* @__PURE__ */ new Map();
@@ -278,26 +301,28 @@ function createProtectedRegExpView(target, context) {
278
301
  }
279
302
  });
280
303
  registerProtectedAnnotationView(context, target, view);
304
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
281
305
  copyRegExpMetadata(target, cloned, (value) => protectAnnotationValue(value, context));
282
306
  return view;
283
307
  }
284
308
  function createProtectedURLSearchParamsView(target, context) {
285
309
  const methodCache = /* @__PURE__ */ new Map();
286
- const view = new Proxy(target, {
287
- get(target$1, key) {
310
+ const cloned = new URLSearchParams(target);
311
+ const view = new Proxy(cloned, {
312
+ get(clonedTarget, key) {
288
313
  if (key === "append" || key === "delete" || key === "set" || key === "sort") return cacheProtectedMethod(methodCache, key, () => (..._args) => throwReadonlyAnnotationMutation());
289
- if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => target$1.forEach((value$1, name) => {
314
+ if (key === "forEach") return cacheProtectedMethod(methodCache, key, () => (callback, thisArg) => clonedTarget.forEach((value$1, name) => {
290
315
  callback.call(thisArg, value$1, name, view);
291
316
  }));
292
317
  if (key === "keys" || key === "values") return cacheProtectedMethod(methodCache, key, () => function* () {
293
- const iterator = key === "keys" ? target$1.keys() : target$1.values();
318
+ const iterator = key === "keys" ? clonedTarget.keys() : clonedTarget.values();
294
319
  for (const value$1 of iterator) yield value$1;
295
320
  });
296
321
  if (key === "entries" || key === Symbol.iterator) return cacheProtectedMethod(methodCache, key, () => function* () {
297
- for (const entry of target$1.entries()) yield entry;
322
+ for (const entry of clonedTarget.entries()) yield entry;
298
323
  });
299
- const value = Reflect.get(target$1, key, target$1);
300
- return typeof value === "function" ? value.bind(target$1) : value;
324
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
325
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
301
326
  },
302
327
  set() {
303
328
  throwReadonlyAnnotationMutation();
@@ -315,14 +340,18 @@ function createProtectedURLSearchParamsView(target, context) {
315
340
  throwReadonlyAnnotationMutation();
316
341
  }
317
342
  });
318
- return registerProtectedAnnotationView(context, target, view);
343
+ registerProtectedAnnotationView(context, target, view);
344
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
345
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
346
+ return view;
319
347
  }
320
348
  function createProtectedURLView(target, context) {
321
- const view = new Proxy(target, {
322
- get(target$1, key) {
323
- if (key === "searchParams") return protectAnnotationValue(target$1.searchParams, context);
324
- const value = Reflect.get(target$1, key, target$1);
325
- return typeof value === "function" ? value.bind(target$1) : value;
349
+ const cloned = new URL(target.href);
350
+ const view = new Proxy(cloned, {
351
+ get(clonedTarget, key) {
352
+ if (key === "searchParams") return protectAnnotationValue(clonedTarget.searchParams, context);
353
+ const value = Reflect.get(clonedTarget, key, clonedTarget);
354
+ return typeof value === "function" ? value.bind(clonedTarget) : protectAnnotationValue(value, context);
326
355
  },
327
356
  set() {
328
357
  throwReadonlyAnnotationMutation();
@@ -340,12 +369,16 @@ function createProtectedURLView(target, context) {
340
369
  throwReadonlyAnnotationMutation();
341
370
  }
342
371
  });
343
- return registerProtectedAnnotationView(context, target, view);
372
+ registerProtectedAnnotationView(context, target, view);
373
+ cacheProtectedAnnotationViewAlias(context, cloned, view);
374
+ copyOwnProperties(target, cloned, (value) => protectAnnotationValue(value, context));
375
+ return view;
344
376
  }
345
377
  function protectAnnotationValue(value, context) {
346
378
  if (value == null || typeof value !== "object") return value;
347
- const target = value;
348
- if (isProtectedAnnotationView(value)) return value;
379
+ const isProtectedView = isProtectedAnnotationView(value);
380
+ if (isProtectedView && !context.rewrapProtectedViews) return value;
381
+ const target = isProtectedView ? unwrapProtectedAnnotationTarget(value) : value;
349
382
  const cached = context.cache.get(target);
350
383
  if (cached !== void 0) return cached;
351
384
  if (target instanceof Map) return createProtectedMapView(target, context);
@@ -360,6 +393,85 @@ function protectAnnotationValue(value, context) {
360
393
  return value;
361
394
  }
362
395
  /**
396
+ * Normalizes annotation input for a fresh parse run.
397
+ *
398
+ * When callers feed a protected annotation view returned by `getAnnotations()`
399
+ * back into a new parse entrypoint, Optique unwraps it to the caller-owned
400
+ * record first so the new run gets its own protected views.
401
+ *
402
+ * @param annotations The caller-supplied annotations input.
403
+ * @returns The raw annotation record to inject for the new run.
404
+ * @internal
405
+ */
406
+ function normalizeRunAnnotationInput(annotations) {
407
+ return isProtectedAnnotationView(annotations) ? unwrapProtectedAnnotationTarget(annotations) : annotations;
408
+ }
409
+ function injectAnnotationsWithContext(state, annotations, context) {
410
+ const protectedAnnotations = protectAnnotationValue(annotations, context);
411
+ if (state == null || typeof state !== "object") {
412
+ const wrapper = {};
413
+ Object.defineProperties(wrapper, {
414
+ [annotationKey]: {
415
+ value: protectedAnnotations,
416
+ enumerable: true,
417
+ writable: true,
418
+ configurable: true
419
+ },
420
+ [annotationStateValueKey]: {
421
+ value: state,
422
+ enumerable: false,
423
+ writable: true,
424
+ configurable: true
425
+ },
426
+ [annotationWrapperKey]: {
427
+ value: true,
428
+ enumerable: false,
429
+ writable: true,
430
+ configurable: true
431
+ }
432
+ });
433
+ injectedAnnotationWrappers.add(wrapper);
434
+ return wrapper;
435
+ }
436
+ if (Array.isArray(state)) {
437
+ const cloned$1 = [...state];
438
+ cloned$1[annotationKey] = protectedAnnotations;
439
+ return cloned$1;
440
+ }
441
+ if (isInjectedAnnotationWrapper(state)) {
442
+ state[annotationKey] = protectedAnnotations;
443
+ return state;
444
+ }
445
+ if (state instanceof Date) {
446
+ const cloned$1 = new Date(state.getTime());
447
+ cloned$1[annotationKey] = protectedAnnotations;
448
+ return cloned$1;
449
+ }
450
+ if (state instanceof Map) {
451
+ const cloned$1 = new Map(state);
452
+ cloned$1[annotationKey] = protectedAnnotations;
453
+ return cloned$1;
454
+ }
455
+ if (state instanceof Set) {
456
+ const cloned$1 = new Set(state);
457
+ cloned$1[annotationKey] = protectedAnnotations;
458
+ return cloned$1;
459
+ }
460
+ if (state instanceof RegExp) {
461
+ const cloned$1 = cloneRegExpShape(state);
462
+ cloned$1[annotationKey] = protectedAnnotations;
463
+ return cloned$1;
464
+ }
465
+ const proto = Object.getPrototypeOf(state);
466
+ if (proto === Object.prototype || proto === null) return {
467
+ ...state,
468
+ [annotationKey]: protectedAnnotations
469
+ };
470
+ const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
471
+ cloned[annotationKey] = protectedAnnotations;
472
+ return cloned;
473
+ }
474
+ /**
363
475
  * Extracts annotations from parser state.
364
476
  *
365
477
  * @param state Parser state that may contain annotations
@@ -490,69 +602,22 @@ function hasMeaningfulAnnotations(annotations) {
490
602
  */
491
603
  function injectAnnotations(state, annotations) {
492
604
  if (!hasMeaningfulAnnotations(annotations)) return state;
493
- const protectedAnnotations = protectAnnotationValue(annotations, createAnnotationProtectionContext());
494
- if (state == null || typeof state !== "object") {
495
- const wrapper = {};
496
- Object.defineProperties(wrapper, {
497
- [annotationKey]: {
498
- value: protectedAnnotations,
499
- enumerable: true,
500
- writable: true,
501
- configurable: true
502
- },
503
- [annotationStateValueKey]: {
504
- value: state,
505
- enumerable: false,
506
- writable: true,
507
- configurable: true
508
- },
509
- [annotationWrapperKey]: {
510
- value: true,
511
- enumerable: false,
512
- writable: true,
513
- configurable: true
514
- }
515
- });
516
- injectedAnnotationWrappers.add(wrapper);
517
- return wrapper;
518
- }
519
- if (Array.isArray(state)) {
520
- const cloned$1 = [...state];
521
- cloned$1[annotationKey] = protectedAnnotations;
522
- return cloned$1;
523
- }
524
- if (isInjectedAnnotationWrapper(state)) {
525
- state[annotationKey] = protectedAnnotations;
526
- return state;
527
- }
528
- if (state instanceof Date) {
529
- const cloned$1 = new Date(state.getTime());
530
- cloned$1[annotationKey] = protectedAnnotations;
531
- return cloned$1;
532
- }
533
- if (state instanceof Map) {
534
- const cloned$1 = new Map(state);
535
- cloned$1[annotationKey] = protectedAnnotations;
536
- return cloned$1;
537
- }
538
- if (state instanceof Set) {
539
- const cloned$1 = new Set(state);
540
- cloned$1[annotationKey] = protectedAnnotations;
541
- return cloned$1;
542
- }
543
- if (state instanceof RegExp) {
544
- const cloned$1 = cloneRegExpShape(state);
545
- cloned$1[annotationKey] = protectedAnnotations;
546
- return cloned$1;
547
- }
548
- const proto = Object.getPrototypeOf(state);
549
- if (proto === Object.prototype || proto === null) return {
550
- ...state,
551
- [annotationKey]: protectedAnnotations
552
- };
553
- const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
554
- cloned[annotationKey] = protectedAnnotations;
555
- return cloned;
605
+ return injectAnnotationsWithContext(state, annotations, createAnnotationProtectionContext());
606
+ }
607
+ /**
608
+ * Injects annotations for a fresh parse run.
609
+ *
610
+ * This path re-wraps protected views from previous runs so stateful container
611
+ * internals remain isolated across parse entrypoints.
612
+ *
613
+ * @param state The parser state to annotate.
614
+ * @param annotations The annotations to inject.
615
+ * @returns Annotated state for the fresh run.
616
+ * @internal
617
+ */
618
+ function injectFreshRunAnnotations(state, annotations) {
619
+ if (!hasMeaningfulAnnotations(annotations)) return state;
620
+ return injectAnnotationsWithContext(state, normalizeRunAnnotationInput(annotations), createAnnotationProtectionContext(true));
556
621
  }
557
622
  /**
558
623
  * Unwraps a primitive-state annotation wrapper injected by Optique internals.
@@ -583,4 +648,4 @@ function isInjectedAnnotationWrapper(value) {
583
648
  }
584
649
 
585
650
  //#endregion
586
- export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper };
651
+ export { annotateFreshArray, annotationKey, annotationStateValueKey, annotationWrapperKey, firstPassAnnotationKey, getAnnotations, hasMeaningfulAnnotations, inheritAnnotations, injectAnnotations, injectFreshRunAnnotations, isInjectedAnnotationWrapper, normalizeRunAnnotationInput, unwrapInjectedAnnotationWrapper };
package/dist/parser.cjs CHANGED
@@ -69,7 +69,7 @@ function createParserContext(frame, exec) {
69
69
  function injectAnnotationsIntoState(state, options) {
70
70
  const annotations = options?.annotations;
71
71
  if (!require_annotations.hasMeaningfulAnnotations(annotations)) return state;
72
- return require_annotations.injectAnnotations(state, annotations);
72
+ return require_annotations.injectFreshRunAnnotations(state, annotations);
73
73
  }
74
74
  /**
75
75
  * Parses an array of command-line arguments using the provided combined parser.
package/dist/parser.js CHANGED
@@ -1,4 +1,4 @@
1
- import { hasMeaningfulAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
1
+ import { hasMeaningfulAnnotations, injectFreshRunAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
2
2
  import { cloneMessage, message } from "./message.js";
3
3
  import { cloneUsage, normalizeUsage } from "./usage.js";
4
4
  import { cloneDocEntry, isDocEntryHidden } from "./doc.js";
@@ -69,7 +69,7 @@ function createParserContext(frame, exec) {
69
69
  function injectAnnotationsIntoState(state, options) {
70
70
  const annotations = options?.annotations;
71
71
  if (!hasMeaningfulAnnotations(annotations)) return state;
72
- return injectAnnotations(state, annotations);
72
+ return injectFreshRunAnnotations(state, annotations);
73
73
  }
74
74
  /**
75
75
  * Parses an array of command-line arguments using the provided combined parser.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/core",
3
- "version": "1.0.0-dev.1854+f15dcfec",
3
+ "version": "1.0.0-dev.1858+fbabb36b",
4
4
  "description": "Type-safe combinatorial command-line interface parser",
5
5
  "keywords": [
6
6
  "CLI",