@optique/core 1.0.0-dev.1901 → 1.0.0-dev.1970
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 +115 -60
- package/dist/annotation-state.d.cts +24 -0
- package/dist/annotation-state.d.ts +24 -0
- package/dist/annotation-state.js +114 -60
- package/dist/annotations.cjs +2 -267
- package/dist/annotations.d.cts +2 -152
- package/dist/annotations.d.ts +2 -152
- package/dist/annotations.js +2 -256
- package/dist/completion.d.cts +1 -1
- package/dist/completion.d.ts +1 -1
- package/dist/constructs.cjs +206 -238
- package/dist/constructs.d.cts +1 -1
- package/dist/constructs.d.ts +1 -1
- package/dist/constructs.js +96 -128
- package/dist/context.d.cts +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/dependency-metadata.cjs +1 -1
- package/dist/dependency-metadata.d.cts +1 -1
- package/dist/dependency-metadata.d.ts +1 -1
- package/dist/dependency-metadata.js +1 -1
- package/dist/dependency-runtime.cjs +2 -2
- package/dist/dependency-runtime.js +2 -2
- package/dist/dependency.cjs +7 -1111
- package/dist/dependency.d.cts +2 -838
- package/dist/dependency.d.ts +2 -838
- package/dist/dependency.js +2 -1078
- package/dist/execution-context.cjs +56 -0
- package/dist/execution-context.js +53 -0
- package/dist/extension.cjs +87 -0
- package/dist/extension.d.cts +97 -0
- package/dist/extension.d.ts +97 -0
- package/dist/extension.js +76 -0
- package/dist/facade.cjs +19 -19
- package/dist/facade.d.cts +1 -1
- package/dist/facade.d.ts +1 -1
- package/dist/facade.js +19 -19
- package/dist/index.cjs +4 -41
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +5 -5
- package/dist/internal/annotations.cjs +316 -0
- package/dist/internal/annotations.d.cts +140 -0
- package/dist/internal/annotations.d.ts +140 -0
- package/dist/internal/annotations.js +306 -0
- package/dist/internal/dependency.cjs +984 -0
- package/dist/internal/dependency.d.cts +539 -0
- package/dist/internal/dependency.d.ts +539 -0
- package/dist/internal/dependency.js +964 -0
- package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
- package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
- package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
- package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
- package/dist/internal/parser.cjs +728 -0
- package/dist/internal/parser.d.cts +947 -0
- package/dist/internal/parser.d.ts +947 -0
- package/dist/internal/parser.js +711 -0
- package/dist/modifiers.cjs +108 -125
- package/dist/modifiers.d.cts +1 -1
- package/dist/modifiers.d.ts +1 -1
- package/dist/modifiers.js +92 -109
- package/dist/parser.cjs +11 -743
- package/dist/parser.d.cts +3 -991
- package/dist/parser.d.ts +3 -991
- package/dist/parser.js +2 -704
- package/dist/phase2-seed.cjs +4 -4
- package/dist/phase2-seed.js +4 -4
- package/dist/primitives.cjs +39 -74
- package/dist/primitives.d.cts +1 -1
- package/dist/primitives.d.ts +1 -1
- package/dist/primitives.js +26 -61
- package/dist/program.d.cts +1 -1
- package/dist/program.d.ts +1 -1
- package/dist/valueparser.cjs +23 -23
- package/dist/valueparser.d.cts +3 -3
- package/dist/valueparser.d.ts +3 -3
- package/dist/valueparser.js +23 -23
- package/package.json +9 -9
package/dist/annotation-state.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { annotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./annotations.js";
|
|
2
|
-
import { inheritParentAnnotationsKey } from "./parser.js";
|
|
1
|
+
import { annotationKey, getAnnotations, inheritAnnotations, injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./internal/annotations.js";
|
|
2
|
+
import { inheritParentAnnotationsKey } from "./internal/parser.js";
|
|
3
3
|
|
|
4
4
|
//#region src/annotation-state.ts
|
|
5
5
|
/**
|
|
@@ -11,6 +11,7 @@ import { inheritParentAnnotationsKey } from "./parser.js";
|
|
|
11
11
|
* @internal
|
|
12
12
|
*/
|
|
13
13
|
const annotationViewTargets = /* @__PURE__ */ new WeakMap();
|
|
14
|
+
const delegatedAnnotationCloneTargets = /* @__PURE__ */ new WeakMap();
|
|
14
15
|
/**
|
|
15
16
|
* Unwraps an annotation-view proxy to its original target object.
|
|
16
17
|
*
|
|
@@ -23,14 +24,18 @@ function unwrapAnnotationView(value) {
|
|
|
23
24
|
if (value == null || typeof value !== "object") return value;
|
|
24
25
|
return annotationViewTargets.get(value) ?? value;
|
|
25
26
|
}
|
|
27
|
+
function unwrapDelegatedAnnotationClone(value) {
|
|
28
|
+
if (value == null || typeof value !== "object") return value;
|
|
29
|
+
return delegatedAnnotationCloneTargets.get(value) ?? value;
|
|
30
|
+
}
|
|
26
31
|
/**
|
|
27
|
-
* Creates
|
|
32
|
+
* Creates an annotation-aware proxy without changing the target shape.
|
|
28
33
|
*
|
|
29
34
|
* @param state The object state to expose through an annotation-aware view.
|
|
30
35
|
* @param annotations The annotations to surface through the proxy.
|
|
31
36
|
* @returns A proxy over the unwrapped target object that reports the supplied
|
|
32
37
|
* annotations while preserving the target's structural behavior.
|
|
33
|
-
* @
|
|
38
|
+
* @since 1.0.0
|
|
34
39
|
*/
|
|
35
40
|
function withAnnotationView(state, annotations) {
|
|
36
41
|
const target = unwrapAnnotationView(state);
|
|
@@ -59,61 +64,90 @@ function normalizeInjectedAnnotationState(state) {
|
|
|
59
64
|
return unwrapInjectedAnnotationWrapper(state);
|
|
60
65
|
}
|
|
61
66
|
function isNonPlainDelegatedObject(state) {
|
|
62
|
-
if (Array.isArray(state) || state instanceof Date || state instanceof Map || state instanceof Set || state instanceof RegExp) return false;
|
|
63
67
|
const proto = Object.getPrototypeOf(state);
|
|
68
|
+
if (proto === Array.prototype || proto === Date.prototype || proto === Map.prototype || proto === Set.prototype || proto === RegExp.prototype) return false;
|
|
64
69
|
return proto !== Object.prototype && proto !== null;
|
|
65
70
|
}
|
|
71
|
+
function inheritDelegatedAnnotations(parentState, childState) {
|
|
72
|
+
const target = normalizeDelegatedAnnotationState(childState);
|
|
73
|
+
const delegatedState = inheritAnnotations(parentState, target);
|
|
74
|
+
if (delegatedState !== target) delegatedAnnotationCloneTargets.set(delegatedState, target);
|
|
75
|
+
return delegatedState;
|
|
76
|
+
}
|
|
66
77
|
/**
|
|
67
78
|
* Removes Optique's internal annotation carriers from a delegated state.
|
|
68
79
|
*
|
|
69
|
-
* This unwraps
|
|
70
|
-
* proxies used for
|
|
80
|
+
* This unwraps primitive-state annotation wrappers, tracked delegated clones,
|
|
81
|
+
* and annotation-view proxies used for object states.
|
|
71
82
|
*
|
|
72
83
|
* @param state The delegated state to normalize.
|
|
73
84
|
* @returns The original underlying state value.
|
|
74
85
|
* @internal
|
|
75
86
|
*/
|
|
76
87
|
function normalizeDelegatedAnnotationState(state) {
|
|
77
|
-
return normalizeInjectedAnnotationState(unwrapAnnotationView(state));
|
|
88
|
+
return normalizeInjectedAnnotationState(unwrapDelegatedAnnotationClone(unwrapAnnotationView(state)));
|
|
78
89
|
}
|
|
79
90
|
/**
|
|
80
91
|
* Returns whether the given state uses an internal delegated annotation carrier.
|
|
81
92
|
*
|
|
82
93
|
* @param state The candidate state to inspect.
|
|
83
|
-
* @returns `true` when the state is an injected primitive wrapper
|
|
84
|
-
* annotation-view proxy.
|
|
94
|
+
* @returns `true` when the state is an injected primitive wrapper, a tracked
|
|
95
|
+
* delegated clone, or an annotation-view proxy.
|
|
85
96
|
* @internal
|
|
86
97
|
*/
|
|
87
98
|
function hasDelegatedAnnotationCarrier(state) {
|
|
88
|
-
return state != null && typeof state === "object" && (isInjectedAnnotationWrapper(state) || annotationViewTargets.has(state));
|
|
99
|
+
return state != null && typeof state === "object" && (isInjectedAnnotationWrapper(state) || delegatedAnnotationCloneTargets.has(state) || annotationViewTargets.has(state));
|
|
100
|
+
}
|
|
101
|
+
function getOrCreateNestedNormalizationClone(entry) {
|
|
102
|
+
entry.clone ??= entry.createClone();
|
|
103
|
+
return entry.clone;
|
|
89
104
|
}
|
|
90
|
-
function
|
|
91
|
-
if (originalValue == null || typeof originalValue !== "object") return
|
|
105
|
+
function getPendingNestedNormalizationEntry(originalValue, normalizedValue, seen) {
|
|
106
|
+
if (originalValue == null || typeof originalValue !== "object") return void 0;
|
|
92
107
|
const entry = seen.get(originalValue);
|
|
93
|
-
return entry != null &&
|
|
108
|
+
return entry != null && entry.clone != null && entry.clone === normalizedValue && (!entry.finalized || entry.preferCloneOnRead) ? entry : void 0;
|
|
94
109
|
}
|
|
95
110
|
function createPendingNestedNormalizationClone(source) {
|
|
96
|
-
|
|
111
|
+
if (!Array.isArray(source)) return Object.create(Object.getPrototypeOf(source));
|
|
112
|
+
if (Object.getPrototypeOf(source) === Array.prototype) return [];
|
|
113
|
+
try {
|
|
114
|
+
return source.slice(0, 0);
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function createPendingNestedNormalizationCollectionClone(source) {
|
|
120
|
+
const proto = Object.getPrototypeOf(source);
|
|
121
|
+
if (source instanceof Map && proto === Map.prototype) return /* @__PURE__ */ new Map();
|
|
122
|
+
if (source instanceof Set && proto === Set.prototype) return /* @__PURE__ */ new Set();
|
|
123
|
+
const Constructor = source.constructor;
|
|
124
|
+
if (typeof Constructor === "function") try {
|
|
125
|
+
return new Constructor();
|
|
126
|
+
} catch {}
|
|
127
|
+
return source instanceof Map ? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Set();
|
|
97
128
|
}
|
|
98
|
-
function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
99
|
-
const clone = createPendingNestedNormalizationClone(source);
|
|
129
|
+
function normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone) {
|
|
100
130
|
const entry = {
|
|
101
|
-
clone,
|
|
131
|
+
clone: void 0,
|
|
132
|
+
createClone: () => createPendingNestedNormalizationClone(source),
|
|
102
133
|
finalized: false,
|
|
103
|
-
result:
|
|
134
|
+
result: source,
|
|
135
|
+
preferCloneOnRead: false
|
|
104
136
|
};
|
|
105
137
|
seen.set(source, entry);
|
|
106
138
|
const overrides = /* @__PURE__ */ new Map();
|
|
107
139
|
let changed = false;
|
|
140
|
+
let hasPendingAliasOverride = false;
|
|
108
141
|
for (const key of Reflect.ownKeys(source)) {
|
|
109
142
|
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
110
143
|
if (descriptor == null || !("value" in descriptor)) continue;
|
|
111
|
-
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
|
|
144
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
112
145
|
if (nextValue === descriptor.value) continue;
|
|
113
146
|
overrides.set(key, nextValue);
|
|
114
|
-
if (
|
|
147
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
148
|
+
else hasPendingAliasOverride = true;
|
|
115
149
|
}
|
|
116
|
-
if (!changed) {
|
|
150
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
117
151
|
entry.finalized = true;
|
|
118
152
|
entry.result = source;
|
|
119
153
|
return source;
|
|
@@ -127,41 +161,50 @@ function normalizeNestedDelegatedStructuredState(source, seen) {
|
|
|
127
161
|
value: nextValue
|
|
128
162
|
};
|
|
129
163
|
}
|
|
164
|
+
const clone = getOrCreateNestedNormalizationClone(entry);
|
|
130
165
|
Object.defineProperties(clone, descriptors);
|
|
131
166
|
entry.finalized = true;
|
|
132
|
-
entry.
|
|
133
|
-
|
|
167
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
168
|
+
entry.result = changed ? clone : source;
|
|
169
|
+
return changed || preferPendingClone ? clone : source;
|
|
134
170
|
}
|
|
135
|
-
function normalizeNestedDelegatedMapState(source, seen) {
|
|
136
|
-
const clone = /* @__PURE__ */ new Map();
|
|
171
|
+
function normalizeNestedDelegatedMapState(source, seen, preferPendingClone) {
|
|
137
172
|
const entry = {
|
|
138
|
-
clone,
|
|
173
|
+
clone: void 0,
|
|
174
|
+
createClone: () => createPendingNestedNormalizationCollectionClone(source),
|
|
139
175
|
finalized: false,
|
|
140
|
-
result:
|
|
176
|
+
result: source,
|
|
177
|
+
preferCloneOnRead: false
|
|
141
178
|
};
|
|
142
179
|
seen.set(source, entry);
|
|
143
180
|
const normalizedEntries = [];
|
|
144
181
|
const overrides = /* @__PURE__ */ new Map();
|
|
145
182
|
let changed = false;
|
|
183
|
+
let hasPendingAliasOverride = false;
|
|
146
184
|
for (const [key, value] of source) {
|
|
147
|
-
const nextKey = normalizeNestedDelegatedAnnotationState(key, seen);
|
|
148
|
-
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
|
|
185
|
+
const nextKey = normalizeNestedDelegatedAnnotationState(key, seen, true);
|
|
186
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
149
187
|
normalizedEntries.push([nextKey, nextValue]);
|
|
150
|
-
if (
|
|
188
|
+
if (nextKey !== key) if (getPendingNestedNormalizationEntry(key, nextKey, seen) == null) changed = true;
|
|
189
|
+
else hasPendingAliasOverride = true;
|
|
190
|
+
if (nextValue !== value) if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
|
|
191
|
+
else hasPendingAliasOverride = true;
|
|
151
192
|
}
|
|
152
193
|
for (const key of Reflect.ownKeys(source)) {
|
|
153
194
|
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
154
195
|
if (descriptor == null || !("value" in descriptor)) continue;
|
|
155
|
-
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
|
|
196
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
156
197
|
if (nextValue === descriptor.value) continue;
|
|
157
198
|
overrides.set(key, nextValue);
|
|
158
|
-
if (
|
|
199
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
200
|
+
else hasPendingAliasOverride = true;
|
|
159
201
|
}
|
|
160
|
-
if (!changed) {
|
|
202
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
161
203
|
entry.finalized = true;
|
|
162
204
|
entry.result = source;
|
|
163
205
|
return source;
|
|
164
206
|
}
|
|
207
|
+
const clone = getOrCreateNestedNormalizationClone(entry);
|
|
165
208
|
for (const [key, value] of normalizedEntries) clone.set(key, value);
|
|
166
209
|
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
167
210
|
for (const [key, nextValue] of overrides) {
|
|
@@ -174,38 +217,45 @@ function normalizeNestedDelegatedMapState(source, seen) {
|
|
|
174
217
|
}
|
|
175
218
|
Object.defineProperties(clone, descriptors);
|
|
176
219
|
entry.finalized = true;
|
|
177
|
-
entry.
|
|
178
|
-
|
|
220
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
221
|
+
entry.result = changed ? clone : source;
|
|
222
|
+
return changed || preferPendingClone ? clone : source;
|
|
179
223
|
}
|
|
180
|
-
function normalizeNestedDelegatedSetState(source, seen) {
|
|
181
|
-
const clone = /* @__PURE__ */ new Set();
|
|
224
|
+
function normalizeNestedDelegatedSetState(source, seen, preferPendingClone) {
|
|
182
225
|
const entry = {
|
|
183
|
-
clone,
|
|
226
|
+
clone: void 0,
|
|
227
|
+
createClone: () => createPendingNestedNormalizationCollectionClone(source),
|
|
184
228
|
finalized: false,
|
|
185
|
-
result:
|
|
229
|
+
result: source,
|
|
230
|
+
preferCloneOnRead: false
|
|
186
231
|
};
|
|
187
232
|
seen.set(source, entry);
|
|
188
233
|
const normalizedValues = [];
|
|
189
234
|
const overrides = /* @__PURE__ */ new Map();
|
|
190
235
|
let changed = false;
|
|
236
|
+
let hasPendingAliasOverride = false;
|
|
191
237
|
for (const value of source) {
|
|
192
|
-
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen);
|
|
238
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(value, seen, true);
|
|
193
239
|
normalizedValues.push(nextValue);
|
|
194
|
-
if (nextValue
|
|
240
|
+
if (nextValue === value) continue;
|
|
241
|
+
if (getPendingNestedNormalizationEntry(value, nextValue, seen) == null) changed = true;
|
|
242
|
+
else hasPendingAliasOverride = true;
|
|
195
243
|
}
|
|
196
244
|
for (const key of Reflect.ownKeys(source)) {
|
|
197
245
|
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
198
246
|
if (descriptor == null || !("value" in descriptor)) continue;
|
|
199
|
-
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen);
|
|
247
|
+
const nextValue = normalizeNestedDelegatedAnnotationState(descriptor.value, seen, true);
|
|
200
248
|
if (nextValue === descriptor.value) continue;
|
|
201
249
|
overrides.set(key, nextValue);
|
|
202
|
-
if (
|
|
250
|
+
if (getPendingNestedNormalizationEntry(descriptor.value, nextValue, seen) == null) changed = true;
|
|
251
|
+
else hasPendingAliasOverride = true;
|
|
203
252
|
}
|
|
204
|
-
if (!changed) {
|
|
253
|
+
if (!changed && !hasPendingAliasOverride) {
|
|
205
254
|
entry.finalized = true;
|
|
206
255
|
entry.result = source;
|
|
207
256
|
return source;
|
|
208
257
|
}
|
|
258
|
+
const clone = getOrCreateNestedNormalizationClone(entry);
|
|
209
259
|
for (const value of normalizedValues) clone.add(value);
|
|
210
260
|
const descriptors = Object.getOwnPropertyDescriptors(source);
|
|
211
261
|
for (const [key, nextValue] of overrides) {
|
|
@@ -218,8 +268,9 @@ function normalizeNestedDelegatedSetState(source, seen) {
|
|
|
218
268
|
}
|
|
219
269
|
Object.defineProperties(clone, descriptors);
|
|
220
270
|
entry.finalized = true;
|
|
221
|
-
entry.
|
|
222
|
-
|
|
271
|
+
entry.preferCloneOnRead = !changed && hasPendingAliasOverride;
|
|
272
|
+
entry.result = changed ? clone : source;
|
|
273
|
+
return changed || preferPendingClone ? clone : source;
|
|
223
274
|
}
|
|
224
275
|
/**
|
|
225
276
|
* Recursively removes delegated annotation carriers from plain-object, array,
|
|
@@ -237,27 +288,30 @@ function normalizeNestedDelegatedSetState(source, seen) {
|
|
|
237
288
|
* normalized clone with delegated carriers removed.
|
|
238
289
|
* @internal
|
|
239
290
|
*/
|
|
240
|
-
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap()) {
|
|
291
|
+
function normalizeNestedDelegatedAnnotationState(value, seen = /* @__PURE__ */ new WeakMap(), preferPendingClone = false) {
|
|
241
292
|
const normalized = normalizeDelegatedAnnotationState(value);
|
|
242
293
|
if (normalized == null || typeof normalized !== "object") return normalized;
|
|
243
294
|
const source = normalized;
|
|
244
295
|
const existing = seen.get(source);
|
|
245
|
-
if (existing != null)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
296
|
+
if (existing != null) {
|
|
297
|
+
if (!existing.finalized) return getOrCreateNestedNormalizationClone(existing);
|
|
298
|
+
return preferPendingClone && existing.preferCloneOnRead ? getOrCreateNestedNormalizationClone(existing) : existing.result;
|
|
299
|
+
}
|
|
300
|
+
if (Array.isArray(source)) return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
|
|
301
|
+
if (source instanceof Map) return normalizeNestedDelegatedMapState(source, seen, preferPendingClone);
|
|
302
|
+
if (source instanceof Set) return normalizeNestedDelegatedSetState(source, seen, preferPendingClone);
|
|
249
303
|
const proto = Object.getPrototypeOf(source);
|
|
250
304
|
if (proto !== Object.prototype && proto !== null) return normalized;
|
|
251
|
-
return normalizeNestedDelegatedStructuredState(source, seen);
|
|
305
|
+
return normalizeNestedDelegatedStructuredState(source, seen, preferPendingClone);
|
|
252
306
|
}
|
|
253
307
|
/**
|
|
254
308
|
* Creates a short-lived delegated state that exposes the parent's annotations
|
|
255
309
|
* regardless of the child state's runtime shape.
|
|
256
310
|
*
|
|
257
|
-
* Primitive and nullish states use `injectAnnotations()`,
|
|
258
|
-
*
|
|
259
|
-
* annotation-view proxy so class invariants such as private
|
|
260
|
-
* intact.
|
|
311
|
+
* Primitive and nullish states use `injectAnnotations()`, clone-based object
|
|
312
|
+
* delegation is tracked so it can be normalized back out later, and non-plain
|
|
313
|
+
* objects use an annotation-view proxy so class invariants such as private
|
|
314
|
+
* fields remain intact.
|
|
261
315
|
*
|
|
262
316
|
* @param parentState The state carrying the annotations to delegate.
|
|
263
317
|
* @param childState The child state that should observe those annotations.
|
|
@@ -268,10 +322,10 @@ function getDelegatedAnnotationState(parentState, childState) {
|
|
|
268
322
|
const annotations = getAnnotations(parentState);
|
|
269
323
|
if (annotations === void 0) return childState;
|
|
270
324
|
if (isInjectedAnnotationWrapper(childState)) return injectAnnotations(normalizeInjectedAnnotationState(childState), annotations);
|
|
271
|
-
if (getAnnotations(childState) === annotations) return childState;
|
|
272
325
|
if (childState == null || typeof childState !== "object") return injectAnnotations(childState, annotations);
|
|
326
|
+
if (getAnnotations(childState) === annotations && (delegatedAnnotationCloneTargets.has(childState) || annotationViewTargets.has(childState))) return childState;
|
|
273
327
|
if (isNonPlainDelegatedObject(childState)) return withAnnotationView(childState, annotations);
|
|
274
|
-
return
|
|
328
|
+
return inheritDelegatedAnnotations(parentState, childState);
|
|
275
329
|
}
|
|
276
330
|
/**
|
|
277
331
|
* Returns whether a state is still at the initial sentinel after normalizing
|
|
@@ -357,4 +411,4 @@ function reconcileObjectChildState(parentState, childState) {
|
|
|
357
411
|
}
|
|
358
412
|
|
|
359
413
|
//#endregion
|
|
360
|
-
export { annotationViewTargets, getDelegatedAnnotationState, getWrappedChildParseState, getWrappedChildState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeInjectedAnnotationState, normalizeNestedDelegatedAnnotationState, reconcileObjectChildState, unwrapAnnotationView };
|
|
414
|
+
export { annotationViewTargets, getDelegatedAnnotationState, getWrappedChildParseState, getWrappedChildState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeInjectedAnnotationState, normalizeNestedDelegatedAnnotationState, reconcileObjectChildState, unwrapAnnotationView, withAnnotationView };
|
package/dist/annotations.cjs
CHANGED
|
@@ -1,268 +1,3 @@
|
|
|
1
|
+
const require_annotations = require('./internal/annotations.cjs');
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Runtime context extension system for Optique parsers.
|
|
5
|
-
*
|
|
6
|
-
* This module provides the annotations system that allows external runtime data
|
|
7
|
-
* to be passed to parsers during the parsing session. This enables use cases like
|
|
8
|
-
* config file fallbacks, environment-based validation, and shared context.
|
|
9
|
-
*
|
|
10
|
-
* @module
|
|
11
|
-
* @since 0.10.0
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Annotation key symbol for storing data in parser state.
|
|
15
|
-
* @since 0.10.0
|
|
16
|
-
*/
|
|
17
|
-
const annotationKey = Symbol.for("@optique/core/parser/annotation");
|
|
18
|
-
/**
|
|
19
|
-
* Internal marker attached during the first pass of `runWith()` so wrappers
|
|
20
|
-
* with side effects can defer work until two-pass contexts have resolved.
|
|
21
|
-
*
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
const firstPassAnnotationKey = Symbol.for("@optique/core/parser/firstPass");
|
|
25
|
-
/**
|
|
26
|
-
* Internal key for preserving primitive parser state values when annotations
|
|
27
|
-
* are injected into non-object states.
|
|
28
|
-
* @internal
|
|
29
|
-
*/
|
|
30
|
-
const annotationStateValueKey = Symbol.for("@optique/core/parser/annotationStateValue");
|
|
31
|
-
/**
|
|
32
|
-
* Internal marker key that indicates annotation wrapping was injected by
|
|
33
|
-
* Optique internals for non-object states.
|
|
34
|
-
* @internal
|
|
35
|
-
*/
|
|
36
|
-
const annotationWrapperKey = Symbol.for("@optique/core/parser/annotationWrapper");
|
|
37
|
-
/**
|
|
38
|
-
* Internal symbol keys that define Optique's primitive-state annotation
|
|
39
|
-
* wrapper shape.
|
|
40
|
-
* @internal
|
|
41
|
-
*/
|
|
42
|
-
const annotationWrapperKeys = new Set([
|
|
43
|
-
annotationKey,
|
|
44
|
-
annotationStateValueKey,
|
|
45
|
-
annotationWrapperKey
|
|
46
|
-
]);
|
|
47
|
-
const injectedAnnotationWrappers = /* @__PURE__ */ new WeakSet();
|
|
48
|
-
/**
|
|
49
|
-
* Extracts annotations from parser state.
|
|
50
|
-
*
|
|
51
|
-
* @param state Parser state that may contain annotations
|
|
52
|
-
* @returns Annotations object or undefined if no annotations are present
|
|
53
|
-
* @since 0.10.0
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```typescript
|
|
57
|
-
* const annotations = getAnnotations(state);
|
|
58
|
-
* const myData = annotations?.[myDataKey];
|
|
59
|
-
* ```
|
|
60
|
-
*/
|
|
61
|
-
function getAnnotations(state) {
|
|
62
|
-
if (state == null || typeof state !== "object") return void 0;
|
|
63
|
-
const stateObj = state;
|
|
64
|
-
const annotations = stateObj[annotationKey];
|
|
65
|
-
if (annotations != null && typeof annotations === "object") return annotations;
|
|
66
|
-
return void 0;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Reattaches annotations to a freshly created array state.
|
|
70
|
-
*
|
|
71
|
-
* Array spread copies elements but drops symbol properties, so parsers that
|
|
72
|
-
* rebuild array states need to copy annotations back explicitly.
|
|
73
|
-
*
|
|
74
|
-
* @param source The original state that may carry annotations.
|
|
75
|
-
* @param target The freshly created array state.
|
|
76
|
-
* @returns The target array, with annotations copied when available.
|
|
77
|
-
* @internal
|
|
78
|
-
*/
|
|
79
|
-
function annotateFreshArray(source, target) {
|
|
80
|
-
const annotations = getAnnotations(source);
|
|
81
|
-
if (annotations === void 0) return target;
|
|
82
|
-
const annotated = target;
|
|
83
|
-
annotated[annotationKey] = annotations;
|
|
84
|
-
return annotated;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Propagates annotations from one parser state to another.
|
|
88
|
-
*
|
|
89
|
-
* This is mainly used by parsers that rebuild array states with spread syntax.
|
|
90
|
-
* Array spread copies elements but drops custom symbol properties, so we need
|
|
91
|
-
* to reattach annotations explicitly when present.
|
|
92
|
-
*
|
|
93
|
-
* @param source The original state that may carry annotations.
|
|
94
|
-
* @param target The new state to receive annotations.
|
|
95
|
-
* @returns The target state, with annotations copied when available.
|
|
96
|
-
* @internal
|
|
97
|
-
*/
|
|
98
|
-
function inheritAnnotations(source, target) {
|
|
99
|
-
const annotations = getAnnotations(source);
|
|
100
|
-
if (annotations === void 0) return target;
|
|
101
|
-
if (target == null || typeof target !== "object") return injectAnnotations(target, annotations);
|
|
102
|
-
if (isInjectedAnnotationWrapper(target)) return injectAnnotations(target, annotations);
|
|
103
|
-
if (Array.isArray(target)) {
|
|
104
|
-
const cloned$1 = [...target];
|
|
105
|
-
cloned$1[annotationKey] = annotations;
|
|
106
|
-
return cloned$1;
|
|
107
|
-
}
|
|
108
|
-
if (target instanceof Date) {
|
|
109
|
-
const cloned$1 = new Date(target.getTime());
|
|
110
|
-
cloned$1[annotationKey] = annotations;
|
|
111
|
-
return cloned$1;
|
|
112
|
-
}
|
|
113
|
-
if (target instanceof Map) {
|
|
114
|
-
const cloned$1 = new Map(target);
|
|
115
|
-
cloned$1[annotationKey] = annotations;
|
|
116
|
-
return cloned$1;
|
|
117
|
-
}
|
|
118
|
-
if (target instanceof Set) {
|
|
119
|
-
const cloned$1 = new Set(target);
|
|
120
|
-
cloned$1[annotationKey] = annotations;
|
|
121
|
-
return cloned$1;
|
|
122
|
-
}
|
|
123
|
-
if (target instanceof RegExp) {
|
|
124
|
-
const cloned$1 = new RegExp(target);
|
|
125
|
-
cloned$1[annotationKey] = annotations;
|
|
126
|
-
return cloned$1;
|
|
127
|
-
}
|
|
128
|
-
if (Object.getPrototypeOf(target) !== Object.prototype && Object.getPrototypeOf(target) !== null) return target;
|
|
129
|
-
const cloned = Object.create(Object.getPrototypeOf(target), Object.getOwnPropertyDescriptors(target));
|
|
130
|
-
cloned[annotationKey] = annotations;
|
|
131
|
-
return cloned;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Returns whether an annotations record carries at least one own symbol key.
|
|
135
|
-
*
|
|
136
|
-
* An annotations object with no own symbol keys is treated as a no-op by the
|
|
137
|
-
* injection pipeline: it should behave identically to omitting the
|
|
138
|
-
* `annotations` option entirely. `null` and `undefined` are accepted for
|
|
139
|
-
* call-site convenience and always return `false`.
|
|
140
|
-
*
|
|
141
|
-
* @param annotations The annotations record to check.
|
|
142
|
-
* @returns `true` when the record has at least one own symbol key.
|
|
143
|
-
* @internal
|
|
144
|
-
*/
|
|
145
|
-
function hasMeaningfulAnnotations(annotations) {
|
|
146
|
-
return annotations != null && Object.getOwnPropertySymbols(annotations).length > 0;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Injects annotations into parser state while preserving state shape.
|
|
150
|
-
*
|
|
151
|
-
* - Primitive, null, and undefined states are wrapped with internal metadata.
|
|
152
|
-
* - Array states are cloned and annotated without mutating the original.
|
|
153
|
-
* - Plain object states are shallow-cloned with annotations attached.
|
|
154
|
-
* - Built-in object states (Date/Map/Set/RegExp) are cloned by constructor.
|
|
155
|
-
* - Other non-plain object states are cloned via prototype/descriptors.
|
|
156
|
-
* - If the `annotations` record has no own symbol keys, the state is
|
|
157
|
-
* returned unchanged; an empty annotations object is a no-op.
|
|
158
|
-
*
|
|
159
|
-
* @param state The parser state to annotate.
|
|
160
|
-
* @param annotations The annotations to inject.
|
|
161
|
-
* @returns Annotated state.
|
|
162
|
-
* @internal
|
|
163
|
-
*/
|
|
164
|
-
function injectAnnotations(state, annotations) {
|
|
165
|
-
if (!hasMeaningfulAnnotations(annotations)) return state;
|
|
166
|
-
if (state == null || typeof state !== "object") {
|
|
167
|
-
const wrapper = {};
|
|
168
|
-
Object.defineProperties(wrapper, {
|
|
169
|
-
[annotationKey]: {
|
|
170
|
-
value: annotations,
|
|
171
|
-
enumerable: true,
|
|
172
|
-
writable: true,
|
|
173
|
-
configurable: true
|
|
174
|
-
},
|
|
175
|
-
[annotationStateValueKey]: {
|
|
176
|
-
value: state,
|
|
177
|
-
enumerable: false,
|
|
178
|
-
writable: true,
|
|
179
|
-
configurable: true
|
|
180
|
-
},
|
|
181
|
-
[annotationWrapperKey]: {
|
|
182
|
-
value: true,
|
|
183
|
-
enumerable: false,
|
|
184
|
-
writable: true,
|
|
185
|
-
configurable: true
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
injectedAnnotationWrappers.add(wrapper);
|
|
189
|
-
return wrapper;
|
|
190
|
-
}
|
|
191
|
-
if (Array.isArray(state)) {
|
|
192
|
-
const cloned$1 = [...state];
|
|
193
|
-
cloned$1[annotationKey] = annotations;
|
|
194
|
-
return cloned$1;
|
|
195
|
-
}
|
|
196
|
-
if (isInjectedAnnotationWrapper(state)) {
|
|
197
|
-
state[annotationKey] = annotations;
|
|
198
|
-
return state;
|
|
199
|
-
}
|
|
200
|
-
if (state instanceof Date) {
|
|
201
|
-
const cloned$1 = new Date(state.getTime());
|
|
202
|
-
cloned$1[annotationKey] = annotations;
|
|
203
|
-
return cloned$1;
|
|
204
|
-
}
|
|
205
|
-
if (state instanceof Map) {
|
|
206
|
-
const cloned$1 = new Map(state);
|
|
207
|
-
cloned$1[annotationKey] = annotations;
|
|
208
|
-
return cloned$1;
|
|
209
|
-
}
|
|
210
|
-
if (state instanceof Set) {
|
|
211
|
-
const cloned$1 = new Set(state);
|
|
212
|
-
cloned$1[annotationKey] = annotations;
|
|
213
|
-
return cloned$1;
|
|
214
|
-
}
|
|
215
|
-
if (state instanceof RegExp) {
|
|
216
|
-
const cloned$1 = new RegExp(state);
|
|
217
|
-
cloned$1[annotationKey] = annotations;
|
|
218
|
-
return cloned$1;
|
|
219
|
-
}
|
|
220
|
-
const proto = Object.getPrototypeOf(state);
|
|
221
|
-
if (proto === Object.prototype || proto === null) return {
|
|
222
|
-
...state,
|
|
223
|
-
[annotationKey]: annotations
|
|
224
|
-
};
|
|
225
|
-
const cloned = Object.create(proto, Object.getOwnPropertyDescriptors(state));
|
|
226
|
-
cloned[annotationKey] = annotations;
|
|
227
|
-
return cloned;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Unwraps a primitive-state annotation wrapper injected by Optique internals.
|
|
231
|
-
*
|
|
232
|
-
* @param value Value to potentially unwrap.
|
|
233
|
-
* @returns The unwrapped primitive value when the input is an injected wrapper;
|
|
234
|
-
* otherwise the original value.
|
|
235
|
-
* @internal
|
|
236
|
-
*/
|
|
237
|
-
function unwrapInjectedAnnotationWrapper(value) {
|
|
238
|
-
if (value == null || typeof value !== "object") return value;
|
|
239
|
-
const valueRecord = value;
|
|
240
|
-
if (valueRecord[annotationWrapperKey] !== true) return value;
|
|
241
|
-
const ownKeys = Reflect.ownKeys(valueRecord);
|
|
242
|
-
if (ownKeys.length === 3 && ownKeys.every((key) => annotationWrapperKeys.has(key)) && isInjectedAnnotationWrapper(value)) return valueRecord[annotationStateValueKey];
|
|
243
|
-
return value;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Returns whether the given value is an internal primitive-state annotation
|
|
247
|
-
* wrapper that was injected by Optique.
|
|
248
|
-
*
|
|
249
|
-
* @param value Value to check.
|
|
250
|
-
* @returns `true` if the value is an injected internal wrapper.
|
|
251
|
-
* @internal
|
|
252
|
-
*/
|
|
253
|
-
function isInjectedAnnotationWrapper(value) {
|
|
254
|
-
return value != null && typeof value === "object" && injectedAnnotationWrappers.has(value);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
//#endregion
|
|
258
|
-
exports.annotateFreshArray = annotateFreshArray;
|
|
259
|
-
exports.annotationKey = annotationKey;
|
|
260
|
-
exports.annotationStateValueKey = annotationStateValueKey;
|
|
261
|
-
exports.annotationWrapperKey = annotationWrapperKey;
|
|
262
|
-
exports.firstPassAnnotationKey = firstPassAnnotationKey;
|
|
263
|
-
exports.getAnnotations = getAnnotations;
|
|
264
|
-
exports.hasMeaningfulAnnotations = hasMeaningfulAnnotations;
|
|
265
|
-
exports.inheritAnnotations = inheritAnnotations;
|
|
266
|
-
exports.injectAnnotations = injectAnnotations;
|
|
267
|
-
exports.isInjectedAnnotationWrapper = isInjectedAnnotationWrapper;
|
|
268
|
-
exports.unwrapInjectedAnnotationWrapper = unwrapInjectedAnnotationWrapper;
|
|
3
|
+
exports.getAnnotations = require_annotations.getAnnotations;
|