@optique/core 1.0.6 → 1.0.7
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/constructs.cjs +322 -14
- package/dist/constructs.js +323 -15
- package/dist/internal/parser.cjs +34 -0
- package/dist/internal/parser.d.cts +52 -0
- package/dist/internal/parser.d.ts +52 -0
- package/dist/internal/parser.js +33 -1
- package/dist/modifiers.cjs +53 -0
- package/dist/modifiers.js +54 -1
- package/package.json +1 -1
package/dist/constructs.cjs
CHANGED
|
@@ -77,8 +77,8 @@ function unionLeadingNames(parsers) {
|
|
|
77
77
|
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
78
78
|
* `object()`, `merge()`, `concat()`).
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
* round-robin parse loop). Once a
|
|
80
|
+
* Sources are processed in descending priority order (matching the
|
|
81
|
+
* round-robin parse loop). Once a source with `acceptingAnyToken` is
|
|
82
82
|
* encountered, no lower-priority children can match at position 0, so
|
|
83
83
|
* their names are excluded.
|
|
84
84
|
*/
|
|
@@ -1867,6 +1867,52 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1867
1867
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
1868
1868
|
const combinedMode = parserKeys.some((k) => parsers[k].mode === "async") ? "async" : "sync";
|
|
1869
1869
|
const getInitialError = (context) => createObjectLikeInitialError(context, noMatchContext, options.errors);
|
|
1870
|
+
const adaptFieldLaneResult = (context, field, parser, fieldState, result) => {
|
|
1871
|
+
if (!result.success) return result;
|
|
1872
|
+
if (result.consumed.length === 0 && result.next.state === fieldState) return {
|
|
1873
|
+
success: true,
|
|
1874
|
+
next: context,
|
|
1875
|
+
consumed: []
|
|
1876
|
+
};
|
|
1877
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, result.next.exec);
|
|
1878
|
+
const nextState = result.next.state === fieldState ? context.state : {
|
|
1879
|
+
...context.state,
|
|
1880
|
+
[field]: require_annotation_state.getWrappedChildState(context.state, result.next.state, parser)
|
|
1881
|
+
};
|
|
1882
|
+
return {
|
|
1883
|
+
success: true,
|
|
1884
|
+
next: {
|
|
1885
|
+
...context,
|
|
1886
|
+
buffer: result.next.buffer,
|
|
1887
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1888
|
+
state: nextState,
|
|
1889
|
+
...mergedExec != null ? {
|
|
1890
|
+
trace: mergedExec.trace,
|
|
1891
|
+
exec: mergedExec,
|
|
1892
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1893
|
+
} : {}
|
|
1894
|
+
},
|
|
1895
|
+
consumed: result.consumed
|
|
1896
|
+
};
|
|
1897
|
+
};
|
|
1898
|
+
const objectZeroConsumptionGroup = {};
|
|
1899
|
+
const objectParseLanes = parserPairs.map(([field, parser]) => ({
|
|
1900
|
+
priority: parser.priority,
|
|
1901
|
+
zeroConsumptionGroup: objectZeroConsumptionGroup,
|
|
1902
|
+
settlesZeroConsumption: false,
|
|
1903
|
+
leadingNames: parser.leadingNames,
|
|
1904
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
1905
|
+
parse(context) {
|
|
1906
|
+
const fieldState = createFieldStateGetter(context.state, getObjectParseChildState)(field, parser);
|
|
1907
|
+
return require_mode_dispatch.dispatchByMode(combinedMode, () => {
|
|
1908
|
+
const result = parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1909
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1910
|
+
}, async () => {
|
|
1911
|
+
const result = await parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1912
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
}));
|
|
1870
1916
|
const parseSync = (context) => {
|
|
1871
1917
|
let error = getInitialError(context);
|
|
1872
1918
|
let currentContext = context;
|
|
@@ -2360,6 +2406,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2360
2406
|
configurable: true,
|
|
2361
2407
|
enumerable: false
|
|
2362
2408
|
});
|
|
2409
|
+
require_parser.defineParseLanes(objectParser, objectParseLanes);
|
|
2363
2410
|
require_parser.defineInheritedAnnotationParser(objectParser);
|
|
2364
2411
|
return objectParser;
|
|
2365
2412
|
}
|
|
@@ -3027,17 +3074,17 @@ function merge(...args) {
|
|
|
3027
3074
|
if (parser.initialState === void 0) initialState[parserStateKey(i)] = void 0;
|
|
3028
3075
|
else if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
|
|
3029
3076
|
}
|
|
3030
|
-
const extractParserState = (parser,
|
|
3077
|
+
const extractParserState = (parser, state, index) => {
|
|
3031
3078
|
if (parser.initialState === void 0) {
|
|
3032
3079
|
const key = parserStateKey(index);
|
|
3033
|
-
if (
|
|
3080
|
+
if (state && typeof state === "object" && key in state) return state[key];
|
|
3034
3081
|
return void 0;
|
|
3035
3082
|
} else if (parser.initialState && typeof parser.initialState === "object") {
|
|
3036
3083
|
const localStateKey = localObjectStateKey(index);
|
|
3037
|
-
if (shouldPreserveLocalChildState(parser) &&
|
|
3038
|
-
if (
|
|
3084
|
+
if (shouldPreserveLocalChildState(parser) && state && typeof state === "object" && localStateKey in state) return state[localStateKey];
|
|
3085
|
+
if (state && typeof state === "object") {
|
|
3039
3086
|
const extractedState = {};
|
|
3040
|
-
for (const field in parser.initialState) extractedState[field] = field in
|
|
3087
|
+
for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
|
|
3041
3088
|
return extractedState;
|
|
3042
3089
|
}
|
|
3043
3090
|
return parser.initialState;
|
|
@@ -3067,12 +3114,145 @@ function merge(...args) {
|
|
|
3067
3114
|
[localObjectStateKey(index)]: result.next.state
|
|
3068
3115
|
};
|
|
3069
3116
|
};
|
|
3070
|
-
const
|
|
3117
|
+
const adaptMergeLaneResult = (parser, context, parserState, parsedState, result, index) => {
|
|
3118
|
+
if (!result.success) return result;
|
|
3119
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, result.next.exec);
|
|
3120
|
+
const newState = result.next.state === parsedState ? context.state : mergeResultState(parser, context, parserState, result, index);
|
|
3121
|
+
return {
|
|
3122
|
+
success: true,
|
|
3123
|
+
next: {
|
|
3124
|
+
...context,
|
|
3125
|
+
buffer: result.next.buffer,
|
|
3126
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3127
|
+
state: newState,
|
|
3128
|
+
...mergedExec != null ? {
|
|
3129
|
+
trace: mergedExec.trace,
|
|
3130
|
+
exec: mergedExec,
|
|
3131
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3132
|
+
} : {}
|
|
3133
|
+
},
|
|
3134
|
+
consumed: result.consumed
|
|
3135
|
+
};
|
|
3136
|
+
};
|
|
3137
|
+
const childrenInDeclarationOrder = sorted.map(([parser, originalIndex], sortedIndex) => ({
|
|
3138
|
+
parser,
|
|
3139
|
+
originalIndex,
|
|
3140
|
+
sortedIndex
|
|
3141
|
+
})).toSorted((a, b) => a.originalIndex - b.originalIndex);
|
|
3142
|
+
const mergeParseLanes = childrenInDeclarationOrder.flatMap(({ parser, sortedIndex }) => {
|
|
3143
|
+
const occurrenceConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3144
|
+
const occurrenceZeroConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3145
|
+
const scopeConsumptionGroup = (group$1) => {
|
|
3146
|
+
const existing = occurrenceConsumptionGroups.get(group$1);
|
|
3147
|
+
if (existing != null) return existing;
|
|
3148
|
+
const scoped = {};
|
|
3149
|
+
occurrenceConsumptionGroups.set(group$1, scoped);
|
|
3150
|
+
return scoped;
|
|
3151
|
+
};
|
|
3152
|
+
const childLanes = require_parser.getOwnParseLanes(parser);
|
|
3153
|
+
const lanes = childLanes ?? [{
|
|
3154
|
+
priority: parser.priority,
|
|
3155
|
+
leadingNames: parser.leadingNames,
|
|
3156
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
3157
|
+
parse(context) {
|
|
3158
|
+
return parser.parse(context);
|
|
3159
|
+
}
|
|
3160
|
+
}];
|
|
3161
|
+
return lanes.map((lane) => ({
|
|
3162
|
+
priority: lane.priority,
|
|
3163
|
+
zeroConsumptionGroup: (() => {
|
|
3164
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3165
|
+
const existing = occurrenceZeroConsumptionGroups.get(group$1);
|
|
3166
|
+
if (existing != null) return existing;
|
|
3167
|
+
const scoped = {};
|
|
3168
|
+
occurrenceZeroConsumptionGroups.set(group$1, scoped);
|
|
3169
|
+
return scoped;
|
|
3170
|
+
})(),
|
|
3171
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
3172
|
+
leadingNames: lane.leadingNames,
|
|
3173
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
3174
|
+
requiredConsumptionGroups: lane.requiredConsumptionGroups?.map((group$1) => ({
|
|
3175
|
+
id: scopeConsumptionGroup(group$1.id),
|
|
3176
|
+
...group$1.isActive == null ? {} : { isActive(state) {
|
|
3177
|
+
if (state == null || typeof state !== "object") return false;
|
|
3178
|
+
const parserState = extractParserState(parser, state, sortedIndex);
|
|
3179
|
+
return group$1.isActive?.(parserState) ?? true;
|
|
3180
|
+
} }
|
|
3181
|
+
})),
|
|
3182
|
+
parse(context) {
|
|
3183
|
+
const parserState = extractParserState(parser, context.state, sortedIndex);
|
|
3184
|
+
const childContext = withChildContext$1(context, sortedIndex, parserState, parser);
|
|
3185
|
+
return require_mode_dispatch.dispatchByMode(combinedMode, () => {
|
|
3186
|
+
const result = lane.parse(childContext);
|
|
3187
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3188
|
+
}, async () => {
|
|
3189
|
+
const result = await lane.parse(childContext);
|
|
3190
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3191
|
+
});
|
|
3192
|
+
}
|
|
3193
|
+
}));
|
|
3194
|
+
}).toSorted((a, b) => b.priority - a.priority);
|
|
3195
|
+
const settleZeroConsumptionLanes = (context, laneResults) => {
|
|
3196
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3197
|
+
for (const lane of mergeParseLanes) {
|
|
3198
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3199
|
+
const groupedLanes = groups.get(group$1);
|
|
3200
|
+
if (groupedLanes == null) groups.set(group$1, [lane]);
|
|
3201
|
+
else groupedLanes.push(lane);
|
|
3202
|
+
}
|
|
3203
|
+
const settledGroups = [];
|
|
3204
|
+
for (const groupedLanes of groups.values()) {
|
|
3205
|
+
const groupSucceeded = groupedLanes.every((lane) => {
|
|
3206
|
+
const result = laneResults.get(lane);
|
|
3207
|
+
return lane.settlesZeroConsumption !== false && result?.success === true && result.consumed.length === 0 && (lane.requiredConsumptionGroups?.length ?? 0) === 0;
|
|
3208
|
+
});
|
|
3209
|
+
if (!groupSucceeded) return null;
|
|
3210
|
+
settledGroups.push(groupedLanes);
|
|
3211
|
+
}
|
|
3212
|
+
let settledContext = context;
|
|
3213
|
+
for (const groupedLanes of settledGroups) for (const lane of groupedLanes) {
|
|
3214
|
+
const result = laneResults.get(lane);
|
|
3215
|
+
if (result?.success !== true) continue;
|
|
3216
|
+
const originalState = context.state;
|
|
3217
|
+
const resultState = result.next.state;
|
|
3218
|
+
const nextState = { ...settledContext.state };
|
|
3219
|
+
const stateKeys = new Set([...Reflect.ownKeys(originalState), ...Reflect.ownKeys(resultState)]);
|
|
3220
|
+
for (const key of stateKeys) {
|
|
3221
|
+
const originalHasKey = Object.hasOwn(originalState, key);
|
|
3222
|
+
const resultHasKey = Object.hasOwn(resultState, key);
|
|
3223
|
+
if (originalHasKey === resultHasKey && originalState[key] === resultState[key]) continue;
|
|
3224
|
+
if (resultHasKey) nextState[key] = resultState[key];
|
|
3225
|
+
else delete nextState[key];
|
|
3226
|
+
}
|
|
3227
|
+
const mergedExec = require_execution_context.mergeChildExec(settledContext.exec, result.next.exec);
|
|
3228
|
+
settledContext = {
|
|
3229
|
+
...settledContext,
|
|
3230
|
+
buffer: result.next.buffer,
|
|
3231
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3232
|
+
state: nextState,
|
|
3233
|
+
...mergedExec != null ? {
|
|
3234
|
+
trace: mergedExec.trace,
|
|
3235
|
+
exec: mergedExec,
|
|
3236
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3237
|
+
} : {}
|
|
3238
|
+
};
|
|
3239
|
+
}
|
|
3240
|
+
return {
|
|
3241
|
+
success: true,
|
|
3242
|
+
next: settledContext,
|
|
3243
|
+
consumed: []
|
|
3244
|
+
};
|
|
3245
|
+
};
|
|
3246
|
+
const canTryPositionalLaneAfterFailure = (lane, context) => {
|
|
3247
|
+
const token = context.buffer[0];
|
|
3248
|
+
return token != null && (context.optionsTerminated || !token.startsWith("-")) && (lane.acceptingAnyToken || lane.leadingNames.has(token));
|
|
3249
|
+
};
|
|
3250
|
+
const parseChildrenSync = (context) => {
|
|
3071
3251
|
let currentContext = context;
|
|
3072
3252
|
let zeroConsumedSuccess = null;
|
|
3073
3253
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
3074
3254
|
const parser = syncParsers[i];
|
|
3075
|
-
const parserState = extractParserState(parser, currentContext, i);
|
|
3255
|
+
const parserState = extractParserState(parser, currentContext.state, i);
|
|
3076
3256
|
const result = parser.parse(withChildContext$1(currentContext, i, parserState, parser));
|
|
3077
3257
|
if (result.success) {
|
|
3078
3258
|
const mergedExec = require_execution_context.mergeChildExec(currentContext.exec, result.next.exec);
|
|
@@ -3111,12 +3291,12 @@ function merge(...args) {
|
|
|
3111
3291
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3112
3292
|
};
|
|
3113
3293
|
};
|
|
3114
|
-
const
|
|
3294
|
+
const parseChildrenAsync = async (context) => {
|
|
3115
3295
|
let currentContext = context;
|
|
3116
3296
|
let zeroConsumedSuccess = null;
|
|
3117
3297
|
for (let i = 0; i < parsers.length; i++) {
|
|
3118
3298
|
const parser = parsers[i];
|
|
3119
|
-
const parserState = extractParserState(parser, currentContext, i);
|
|
3299
|
+
const parserState = extractParserState(parser, currentContext.state, i);
|
|
3120
3300
|
const resultOrPromise = parser.parse(withChildContext$1(currentContext, i, parserState, parser));
|
|
3121
3301
|
const result = await resultOrPromise;
|
|
3122
3302
|
if (result.success) {
|
|
@@ -3156,15 +3336,141 @@ function merge(...args) {
|
|
|
3156
3336
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3157
3337
|
};
|
|
3158
3338
|
};
|
|
3339
|
+
const parseSync = (context) => {
|
|
3340
|
+
let currentContext = context;
|
|
3341
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
3342
|
+
const allConsumed = [];
|
|
3343
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
3344
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
3345
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
3346
|
+
let attemptedLane = false;
|
|
3347
|
+
let madeProgress = true;
|
|
3348
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
3349
|
+
madeProgress = false;
|
|
3350
|
+
let consumingError = null;
|
|
3351
|
+
for (const lane of mergeParseLanes) {
|
|
3352
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
3353
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
3354
|
+
}
|
|
3355
|
+
attemptedLane = true;
|
|
3356
|
+
const result = lane.parse(currentContext);
|
|
3357
|
+
laneResults.set(lane, result);
|
|
3358
|
+
if (result.success && result.consumed.length > 0) {
|
|
3359
|
+
currentContext = result.next;
|
|
3360
|
+
allConsumed.push(...result.consumed);
|
|
3361
|
+
consumedLanes.add(lane);
|
|
3362
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
3363
|
+
madeProgress = true;
|
|
3364
|
+
break;
|
|
3365
|
+
}
|
|
3366
|
+
if (!result.success) {
|
|
3367
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
3368
|
+
priority: lane.priority,
|
|
3369
|
+
result
|
|
3370
|
+
};
|
|
3371
|
+
if (error.consumed < result.consumed) error = result;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
3375
|
+
}
|
|
3376
|
+
if (allConsumed.length === 0) {
|
|
3377
|
+
if (attemptedLane) {
|
|
3378
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
3379
|
+
return settled ?? {
|
|
3380
|
+
...error,
|
|
3381
|
+
success: false
|
|
3382
|
+
};
|
|
3383
|
+
}
|
|
3384
|
+
const fallback = parseChildrenSync(context);
|
|
3385
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
3386
|
+
...error,
|
|
3387
|
+
success: false
|
|
3388
|
+
};
|
|
3389
|
+
return fallback;
|
|
3390
|
+
}
|
|
3391
|
+
for (const lane of mergeParseLanes) {
|
|
3392
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
3393
|
+
const result = lane.parse(currentContext);
|
|
3394
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
3395
|
+
}
|
|
3396
|
+
return {
|
|
3397
|
+
success: true,
|
|
3398
|
+
next: currentContext,
|
|
3399
|
+
consumed: allConsumed
|
|
3400
|
+
};
|
|
3401
|
+
};
|
|
3402
|
+
const parseAsync = async (context) => {
|
|
3403
|
+
let currentContext = context;
|
|
3404
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
3405
|
+
const allConsumed = [];
|
|
3406
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
3407
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
3408
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
3409
|
+
let attemptedLane = false;
|
|
3410
|
+
let madeProgress = true;
|
|
3411
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
3412
|
+
madeProgress = false;
|
|
3413
|
+
let consumingError = null;
|
|
3414
|
+
for (const lane of mergeParseLanes) {
|
|
3415
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
3416
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
3417
|
+
}
|
|
3418
|
+
attemptedLane = true;
|
|
3419
|
+
const result = await lane.parse(currentContext);
|
|
3420
|
+
laneResults.set(lane, result);
|
|
3421
|
+
if (result.success && result.consumed.length > 0) {
|
|
3422
|
+
currentContext = result.next;
|
|
3423
|
+
allConsumed.push(...result.consumed);
|
|
3424
|
+
consumedLanes.add(lane);
|
|
3425
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
3426
|
+
madeProgress = true;
|
|
3427
|
+
break;
|
|
3428
|
+
}
|
|
3429
|
+
if (!result.success) {
|
|
3430
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
3431
|
+
priority: lane.priority,
|
|
3432
|
+
result
|
|
3433
|
+
};
|
|
3434
|
+
if (error.consumed < result.consumed) error = result;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
3438
|
+
}
|
|
3439
|
+
if (allConsumed.length === 0) {
|
|
3440
|
+
if (attemptedLane) {
|
|
3441
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
3442
|
+
return settled ?? {
|
|
3443
|
+
...error,
|
|
3444
|
+
success: false
|
|
3445
|
+
};
|
|
3446
|
+
}
|
|
3447
|
+
const fallback = await parseChildrenAsync(context);
|
|
3448
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
3449
|
+
...error,
|
|
3450
|
+
success: false
|
|
3451
|
+
};
|
|
3452
|
+
return fallback;
|
|
3453
|
+
}
|
|
3454
|
+
for (const lane of mergeParseLanes) {
|
|
3455
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
3456
|
+
const result = await lane.parse(currentContext);
|
|
3457
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
3458
|
+
}
|
|
3459
|
+
return {
|
|
3460
|
+
success: true,
|
|
3461
|
+
next: currentContext,
|
|
3462
|
+
consumed: allConsumed
|
|
3463
|
+
};
|
|
3464
|
+
};
|
|
3159
3465
|
const mergeParser = {
|
|
3160
3466
|
mode: combinedMode,
|
|
3161
3467
|
$valueType: [],
|
|
3162
3468
|
$stateType: [],
|
|
3163
3469
|
[fieldParsersKey]: mergedFieldParsers,
|
|
3164
|
-
priority: Math.max(...
|
|
3470
|
+
priority: Math.max(...mergeParseLanes.map((lane) => lane.priority)),
|
|
3165
3471
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
3166
|
-
leadingNames: sharedBufferLeadingNames(
|
|
3167
|
-
acceptingAnyToken:
|
|
3472
|
+
leadingNames: sharedBufferLeadingNames(mergeParseLanes),
|
|
3473
|
+
acceptingAnyToken: mergeParseLanes.some((lane) => lane.acceptingAnyToken),
|
|
3168
3474
|
initialState,
|
|
3169
3475
|
parse(context) {
|
|
3170
3476
|
if (isAsync) return parseAsync(context);
|
|
@@ -3633,6 +3939,7 @@ function merge(...args) {
|
|
|
3633
3939
|
};
|
|
3634
3940
|
}
|
|
3635
3941
|
};
|
|
3942
|
+
require_parser.defineParseLanes(mergeParser, mergeParseLanes);
|
|
3636
3943
|
require_parser.defineInheritedAnnotationParser(mergeParser);
|
|
3637
3944
|
return mergeParser;
|
|
3638
3945
|
}
|
|
@@ -4310,6 +4617,7 @@ function group(label, parser, options = {}) {
|
|
|
4310
4617
|
};
|
|
4311
4618
|
}
|
|
4312
4619
|
};
|
|
4620
|
+
require_parser.defineParseLanes(groupParser, require_parser.getOwnParseLanes(parser));
|
|
4313
4621
|
Object.defineProperty(groupParser, require_phase2_seed.extractPhase2SeedKey, {
|
|
4314
4622
|
value(state, exec) {
|
|
4315
4623
|
return require_phase2_seed.extractPhase2Seed(parser, state, exec);
|
package/dist/constructs.js
CHANGED
|
@@ -6,7 +6,7 @@ import { deduplicateDocFragments } from "./doc.js";
|
|
|
6
6
|
import { dispatchByMode, dispatchIterableByMode } from "./internal/mode-dispatch.js";
|
|
7
7
|
import { createDependencySourceState, dependencyId, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, wrappedDependencySourceMarker } from "./internal/dependency.js";
|
|
8
8
|
import { buildRuntimeNodesFromArray, buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectExplicitSourceValuesAsync, collectSourcesFromState, createDependencyRuntimeContext, fillMissingSourceDefaults, fillMissingSourceDefaultsAsync, resolveStateWithRuntime, resolveStateWithRuntimeAsync } from "./dependency-runtime.js";
|
|
9
|
-
import { defineInheritedAnnotationParser, getParserSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
9
|
+
import { defineInheritedAnnotationParser, defineParseLanes, getOwnParseLanes, getParserSuggestRuntimeNodes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
10
10
|
import { annotationViewTargets, getWrappedChildParseState, getWrappedChildState, reconcileObjectChildState, unwrapAnnotationView } from "./annotation-state.js";
|
|
11
11
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
12
12
|
import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
|
|
@@ -77,8 +77,8 @@ function unionLeadingNames(parsers) {
|
|
|
77
77
|
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
78
78
|
* `object()`, `merge()`, `concat()`).
|
|
79
79
|
*
|
|
80
|
-
*
|
|
81
|
-
* round-robin parse loop). Once a
|
|
80
|
+
* Sources are processed in descending priority order (matching the
|
|
81
|
+
* round-robin parse loop). Once a source with `acceptingAnyToken` is
|
|
82
82
|
* encountered, no lower-priority children can match at position 0, so
|
|
83
83
|
* their names are excluded.
|
|
84
84
|
*/
|
|
@@ -1867,6 +1867,52 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1867
1867
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
1868
1868
|
const combinedMode = parserKeys.some((k) => parsers[k].mode === "async") ? "async" : "sync";
|
|
1869
1869
|
const getInitialError = (context) => createObjectLikeInitialError(context, noMatchContext, options.errors);
|
|
1870
|
+
const adaptFieldLaneResult = (context, field, parser, fieldState, result) => {
|
|
1871
|
+
if (!result.success) return result;
|
|
1872
|
+
if (result.consumed.length === 0 && result.next.state === fieldState) return {
|
|
1873
|
+
success: true,
|
|
1874
|
+
next: context,
|
|
1875
|
+
consumed: []
|
|
1876
|
+
};
|
|
1877
|
+
const mergedExec = mergeChildExec(context.exec, result.next.exec);
|
|
1878
|
+
const nextState = result.next.state === fieldState ? context.state : {
|
|
1879
|
+
...context.state,
|
|
1880
|
+
[field]: getWrappedChildState(context.state, result.next.state, parser)
|
|
1881
|
+
};
|
|
1882
|
+
return {
|
|
1883
|
+
success: true,
|
|
1884
|
+
next: {
|
|
1885
|
+
...context,
|
|
1886
|
+
buffer: result.next.buffer,
|
|
1887
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1888
|
+
state: nextState,
|
|
1889
|
+
...mergedExec != null ? {
|
|
1890
|
+
trace: mergedExec.trace,
|
|
1891
|
+
exec: mergedExec,
|
|
1892
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1893
|
+
} : {}
|
|
1894
|
+
},
|
|
1895
|
+
consumed: result.consumed
|
|
1896
|
+
};
|
|
1897
|
+
};
|
|
1898
|
+
const objectZeroConsumptionGroup = {};
|
|
1899
|
+
const objectParseLanes = parserPairs.map(([field, parser]) => ({
|
|
1900
|
+
priority: parser.priority,
|
|
1901
|
+
zeroConsumptionGroup: objectZeroConsumptionGroup,
|
|
1902
|
+
settlesZeroConsumption: false,
|
|
1903
|
+
leadingNames: parser.leadingNames,
|
|
1904
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
1905
|
+
parse(context) {
|
|
1906
|
+
const fieldState = createFieldStateGetter(context.state, getObjectParseChildState)(field, parser);
|
|
1907
|
+
return dispatchByMode(combinedMode, () => {
|
|
1908
|
+
const result = parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1909
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1910
|
+
}, async () => {
|
|
1911
|
+
const result = await parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1912
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
}));
|
|
1870
1916
|
const parseSync = (context) => {
|
|
1871
1917
|
let error = getInitialError(context);
|
|
1872
1918
|
let currentContext = context;
|
|
@@ -2360,6 +2406,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2360
2406
|
configurable: true,
|
|
2361
2407
|
enumerable: false
|
|
2362
2408
|
});
|
|
2409
|
+
defineParseLanes(objectParser, objectParseLanes);
|
|
2363
2410
|
defineInheritedAnnotationParser(objectParser);
|
|
2364
2411
|
return objectParser;
|
|
2365
2412
|
}
|
|
@@ -3027,17 +3074,17 @@ function merge(...args) {
|
|
|
3027
3074
|
if (parser.initialState === void 0) initialState[parserStateKey(i)] = void 0;
|
|
3028
3075
|
else if (parser.initialState && typeof parser.initialState === "object") for (const field in parser.initialState) initialState[field] = parser.initialState[field];
|
|
3029
3076
|
}
|
|
3030
|
-
const extractParserState = (parser,
|
|
3077
|
+
const extractParserState = (parser, state, index) => {
|
|
3031
3078
|
if (parser.initialState === void 0) {
|
|
3032
3079
|
const key = parserStateKey(index);
|
|
3033
|
-
if (
|
|
3080
|
+
if (state && typeof state === "object" && key in state) return state[key];
|
|
3034
3081
|
return void 0;
|
|
3035
3082
|
} else if (parser.initialState && typeof parser.initialState === "object") {
|
|
3036
3083
|
const localStateKey = localObjectStateKey(index);
|
|
3037
|
-
if (shouldPreserveLocalChildState(parser) &&
|
|
3038
|
-
if (
|
|
3084
|
+
if (shouldPreserveLocalChildState(parser) && state && typeof state === "object" && localStateKey in state) return state[localStateKey];
|
|
3085
|
+
if (state && typeof state === "object") {
|
|
3039
3086
|
const extractedState = {};
|
|
3040
|
-
for (const field in parser.initialState) extractedState[field] = field in
|
|
3087
|
+
for (const field in parser.initialState) extractedState[field] = field in state ? state[field] : parser.initialState[field];
|
|
3041
3088
|
return extractedState;
|
|
3042
3089
|
}
|
|
3043
3090
|
return parser.initialState;
|
|
@@ -3067,12 +3114,145 @@ function merge(...args) {
|
|
|
3067
3114
|
[localObjectStateKey(index)]: result.next.state
|
|
3068
3115
|
};
|
|
3069
3116
|
};
|
|
3070
|
-
const
|
|
3117
|
+
const adaptMergeLaneResult = (parser, context, parserState, parsedState, result, index) => {
|
|
3118
|
+
if (!result.success) return result;
|
|
3119
|
+
const mergedExec = mergeChildExec(context.exec, result.next.exec);
|
|
3120
|
+
const newState = result.next.state === parsedState ? context.state : mergeResultState(parser, context, parserState, result, index);
|
|
3121
|
+
return {
|
|
3122
|
+
success: true,
|
|
3123
|
+
next: {
|
|
3124
|
+
...context,
|
|
3125
|
+
buffer: result.next.buffer,
|
|
3126
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3127
|
+
state: newState,
|
|
3128
|
+
...mergedExec != null ? {
|
|
3129
|
+
trace: mergedExec.trace,
|
|
3130
|
+
exec: mergedExec,
|
|
3131
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3132
|
+
} : {}
|
|
3133
|
+
},
|
|
3134
|
+
consumed: result.consumed
|
|
3135
|
+
};
|
|
3136
|
+
};
|
|
3137
|
+
const childrenInDeclarationOrder = sorted.map(([parser, originalIndex], sortedIndex) => ({
|
|
3138
|
+
parser,
|
|
3139
|
+
originalIndex,
|
|
3140
|
+
sortedIndex
|
|
3141
|
+
})).toSorted((a, b) => a.originalIndex - b.originalIndex);
|
|
3142
|
+
const mergeParseLanes = childrenInDeclarationOrder.flatMap(({ parser, sortedIndex }) => {
|
|
3143
|
+
const occurrenceConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3144
|
+
const occurrenceZeroConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3145
|
+
const scopeConsumptionGroup = (group$1) => {
|
|
3146
|
+
const existing = occurrenceConsumptionGroups.get(group$1);
|
|
3147
|
+
if (existing != null) return existing;
|
|
3148
|
+
const scoped = {};
|
|
3149
|
+
occurrenceConsumptionGroups.set(group$1, scoped);
|
|
3150
|
+
return scoped;
|
|
3151
|
+
};
|
|
3152
|
+
const childLanes = getOwnParseLanes(parser);
|
|
3153
|
+
const lanes = childLanes ?? [{
|
|
3154
|
+
priority: parser.priority,
|
|
3155
|
+
leadingNames: parser.leadingNames,
|
|
3156
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
3157
|
+
parse(context) {
|
|
3158
|
+
return parser.parse(context);
|
|
3159
|
+
}
|
|
3160
|
+
}];
|
|
3161
|
+
return lanes.map((lane) => ({
|
|
3162
|
+
priority: lane.priority,
|
|
3163
|
+
zeroConsumptionGroup: (() => {
|
|
3164
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3165
|
+
const existing = occurrenceZeroConsumptionGroups.get(group$1);
|
|
3166
|
+
if (existing != null) return existing;
|
|
3167
|
+
const scoped = {};
|
|
3168
|
+
occurrenceZeroConsumptionGroups.set(group$1, scoped);
|
|
3169
|
+
return scoped;
|
|
3170
|
+
})(),
|
|
3171
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
3172
|
+
leadingNames: lane.leadingNames,
|
|
3173
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
3174
|
+
requiredConsumptionGroups: lane.requiredConsumptionGroups?.map((group$1) => ({
|
|
3175
|
+
id: scopeConsumptionGroup(group$1.id),
|
|
3176
|
+
...group$1.isActive == null ? {} : { isActive(state) {
|
|
3177
|
+
if (state == null || typeof state !== "object") return false;
|
|
3178
|
+
const parserState = extractParserState(parser, state, sortedIndex);
|
|
3179
|
+
return group$1.isActive?.(parserState) ?? true;
|
|
3180
|
+
} }
|
|
3181
|
+
})),
|
|
3182
|
+
parse(context) {
|
|
3183
|
+
const parserState = extractParserState(parser, context.state, sortedIndex);
|
|
3184
|
+
const childContext = withChildContext$1(context, sortedIndex, parserState, parser);
|
|
3185
|
+
return dispatchByMode(combinedMode, () => {
|
|
3186
|
+
const result = lane.parse(childContext);
|
|
3187
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3188
|
+
}, async () => {
|
|
3189
|
+
const result = await lane.parse(childContext);
|
|
3190
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3191
|
+
});
|
|
3192
|
+
}
|
|
3193
|
+
}));
|
|
3194
|
+
}).toSorted((a, b) => b.priority - a.priority);
|
|
3195
|
+
const settleZeroConsumptionLanes = (context, laneResults) => {
|
|
3196
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3197
|
+
for (const lane of mergeParseLanes) {
|
|
3198
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3199
|
+
const groupedLanes = groups.get(group$1);
|
|
3200
|
+
if (groupedLanes == null) groups.set(group$1, [lane]);
|
|
3201
|
+
else groupedLanes.push(lane);
|
|
3202
|
+
}
|
|
3203
|
+
const settledGroups = [];
|
|
3204
|
+
for (const groupedLanes of groups.values()) {
|
|
3205
|
+
const groupSucceeded = groupedLanes.every((lane) => {
|
|
3206
|
+
const result = laneResults.get(lane);
|
|
3207
|
+
return lane.settlesZeroConsumption !== false && result?.success === true && result.consumed.length === 0 && (lane.requiredConsumptionGroups?.length ?? 0) === 0;
|
|
3208
|
+
});
|
|
3209
|
+
if (!groupSucceeded) return null;
|
|
3210
|
+
settledGroups.push(groupedLanes);
|
|
3211
|
+
}
|
|
3212
|
+
let settledContext = context;
|
|
3213
|
+
for (const groupedLanes of settledGroups) for (const lane of groupedLanes) {
|
|
3214
|
+
const result = laneResults.get(lane);
|
|
3215
|
+
if (result?.success !== true) continue;
|
|
3216
|
+
const originalState = context.state;
|
|
3217
|
+
const resultState = result.next.state;
|
|
3218
|
+
const nextState = { ...settledContext.state };
|
|
3219
|
+
const stateKeys = new Set([...Reflect.ownKeys(originalState), ...Reflect.ownKeys(resultState)]);
|
|
3220
|
+
for (const key of stateKeys) {
|
|
3221
|
+
const originalHasKey = Object.hasOwn(originalState, key);
|
|
3222
|
+
const resultHasKey = Object.hasOwn(resultState, key);
|
|
3223
|
+
if (originalHasKey === resultHasKey && originalState[key] === resultState[key]) continue;
|
|
3224
|
+
if (resultHasKey) nextState[key] = resultState[key];
|
|
3225
|
+
else delete nextState[key];
|
|
3226
|
+
}
|
|
3227
|
+
const mergedExec = mergeChildExec(settledContext.exec, result.next.exec);
|
|
3228
|
+
settledContext = {
|
|
3229
|
+
...settledContext,
|
|
3230
|
+
buffer: result.next.buffer,
|
|
3231
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3232
|
+
state: nextState,
|
|
3233
|
+
...mergedExec != null ? {
|
|
3234
|
+
trace: mergedExec.trace,
|
|
3235
|
+
exec: mergedExec,
|
|
3236
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3237
|
+
} : {}
|
|
3238
|
+
};
|
|
3239
|
+
}
|
|
3240
|
+
return {
|
|
3241
|
+
success: true,
|
|
3242
|
+
next: settledContext,
|
|
3243
|
+
consumed: []
|
|
3244
|
+
};
|
|
3245
|
+
};
|
|
3246
|
+
const canTryPositionalLaneAfterFailure = (lane, context) => {
|
|
3247
|
+
const token = context.buffer[0];
|
|
3248
|
+
return token != null && (context.optionsTerminated || !token.startsWith("-")) && (lane.acceptingAnyToken || lane.leadingNames.has(token));
|
|
3249
|
+
};
|
|
3250
|
+
const parseChildrenSync = (context) => {
|
|
3071
3251
|
let currentContext = context;
|
|
3072
3252
|
let zeroConsumedSuccess = null;
|
|
3073
3253
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
3074
3254
|
const parser = syncParsers[i];
|
|
3075
|
-
const parserState = extractParserState(parser, currentContext, i);
|
|
3255
|
+
const parserState = extractParserState(parser, currentContext.state, i);
|
|
3076
3256
|
const result = parser.parse(withChildContext$1(currentContext, i, parserState, parser));
|
|
3077
3257
|
if (result.success) {
|
|
3078
3258
|
const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
|
|
@@ -3111,12 +3291,12 @@ function merge(...args) {
|
|
|
3111
3291
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3112
3292
|
};
|
|
3113
3293
|
};
|
|
3114
|
-
const
|
|
3294
|
+
const parseChildrenAsync = async (context) => {
|
|
3115
3295
|
let currentContext = context;
|
|
3116
3296
|
let zeroConsumedSuccess = null;
|
|
3117
3297
|
for (let i = 0; i < parsers.length; i++) {
|
|
3118
3298
|
const parser = parsers[i];
|
|
3119
|
-
const parserState = extractParserState(parser, currentContext, i);
|
|
3299
|
+
const parserState = extractParserState(parser, currentContext.state, i);
|
|
3120
3300
|
const resultOrPromise = parser.parse(withChildContext$1(currentContext, i, parserState, parser));
|
|
3121
3301
|
const result = await resultOrPromise;
|
|
3122
3302
|
if (result.success) {
|
|
@@ -3156,15 +3336,141 @@ function merge(...args) {
|
|
|
3156
3336
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3157
3337
|
};
|
|
3158
3338
|
};
|
|
3339
|
+
const parseSync = (context) => {
|
|
3340
|
+
let currentContext = context;
|
|
3341
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
3342
|
+
const allConsumed = [];
|
|
3343
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
3344
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
3345
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
3346
|
+
let attemptedLane = false;
|
|
3347
|
+
let madeProgress = true;
|
|
3348
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
3349
|
+
madeProgress = false;
|
|
3350
|
+
let consumingError = null;
|
|
3351
|
+
for (const lane of mergeParseLanes) {
|
|
3352
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
3353
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
3354
|
+
}
|
|
3355
|
+
attemptedLane = true;
|
|
3356
|
+
const result = lane.parse(currentContext);
|
|
3357
|
+
laneResults.set(lane, result);
|
|
3358
|
+
if (result.success && result.consumed.length > 0) {
|
|
3359
|
+
currentContext = result.next;
|
|
3360
|
+
allConsumed.push(...result.consumed);
|
|
3361
|
+
consumedLanes.add(lane);
|
|
3362
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
3363
|
+
madeProgress = true;
|
|
3364
|
+
break;
|
|
3365
|
+
}
|
|
3366
|
+
if (!result.success) {
|
|
3367
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
3368
|
+
priority: lane.priority,
|
|
3369
|
+
result
|
|
3370
|
+
};
|
|
3371
|
+
if (error.consumed < result.consumed) error = result;
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
3375
|
+
}
|
|
3376
|
+
if (allConsumed.length === 0) {
|
|
3377
|
+
if (attemptedLane) {
|
|
3378
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
3379
|
+
return settled ?? {
|
|
3380
|
+
...error,
|
|
3381
|
+
success: false
|
|
3382
|
+
};
|
|
3383
|
+
}
|
|
3384
|
+
const fallback = parseChildrenSync(context);
|
|
3385
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
3386
|
+
...error,
|
|
3387
|
+
success: false
|
|
3388
|
+
};
|
|
3389
|
+
return fallback;
|
|
3390
|
+
}
|
|
3391
|
+
for (const lane of mergeParseLanes) {
|
|
3392
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
3393
|
+
const result = lane.parse(currentContext);
|
|
3394
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
3395
|
+
}
|
|
3396
|
+
return {
|
|
3397
|
+
success: true,
|
|
3398
|
+
next: currentContext,
|
|
3399
|
+
consumed: allConsumed
|
|
3400
|
+
};
|
|
3401
|
+
};
|
|
3402
|
+
const parseAsync = async (context) => {
|
|
3403
|
+
let currentContext = context;
|
|
3404
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
3405
|
+
const allConsumed = [];
|
|
3406
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
3407
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
3408
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
3409
|
+
let attemptedLane = false;
|
|
3410
|
+
let madeProgress = true;
|
|
3411
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
3412
|
+
madeProgress = false;
|
|
3413
|
+
let consumingError = null;
|
|
3414
|
+
for (const lane of mergeParseLanes) {
|
|
3415
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
3416
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
3417
|
+
}
|
|
3418
|
+
attemptedLane = true;
|
|
3419
|
+
const result = await lane.parse(currentContext);
|
|
3420
|
+
laneResults.set(lane, result);
|
|
3421
|
+
if (result.success && result.consumed.length > 0) {
|
|
3422
|
+
currentContext = result.next;
|
|
3423
|
+
allConsumed.push(...result.consumed);
|
|
3424
|
+
consumedLanes.add(lane);
|
|
3425
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
3426
|
+
madeProgress = true;
|
|
3427
|
+
break;
|
|
3428
|
+
}
|
|
3429
|
+
if (!result.success) {
|
|
3430
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
3431
|
+
priority: lane.priority,
|
|
3432
|
+
result
|
|
3433
|
+
};
|
|
3434
|
+
if (error.consumed < result.consumed) error = result;
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
3438
|
+
}
|
|
3439
|
+
if (allConsumed.length === 0) {
|
|
3440
|
+
if (attemptedLane) {
|
|
3441
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
3442
|
+
return settled ?? {
|
|
3443
|
+
...error,
|
|
3444
|
+
success: false
|
|
3445
|
+
};
|
|
3446
|
+
}
|
|
3447
|
+
const fallback = await parseChildrenAsync(context);
|
|
3448
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
3449
|
+
...error,
|
|
3450
|
+
success: false
|
|
3451
|
+
};
|
|
3452
|
+
return fallback;
|
|
3453
|
+
}
|
|
3454
|
+
for (const lane of mergeParseLanes) {
|
|
3455
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
3456
|
+
const result = await lane.parse(currentContext);
|
|
3457
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
3458
|
+
}
|
|
3459
|
+
return {
|
|
3460
|
+
success: true,
|
|
3461
|
+
next: currentContext,
|
|
3462
|
+
consumed: allConsumed
|
|
3463
|
+
};
|
|
3464
|
+
};
|
|
3159
3465
|
const mergeParser = {
|
|
3160
3466
|
mode: combinedMode,
|
|
3161
3467
|
$valueType: [],
|
|
3162
3468
|
$stateType: [],
|
|
3163
3469
|
[fieldParsersKey]: mergedFieldParsers,
|
|
3164
|
-
priority: Math.max(...
|
|
3470
|
+
priority: Math.max(...mergeParseLanes.map((lane) => lane.priority)),
|
|
3165
3471
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
3166
|
-
leadingNames: sharedBufferLeadingNames(
|
|
3167
|
-
acceptingAnyToken:
|
|
3472
|
+
leadingNames: sharedBufferLeadingNames(mergeParseLanes),
|
|
3473
|
+
acceptingAnyToken: mergeParseLanes.some((lane) => lane.acceptingAnyToken),
|
|
3168
3474
|
initialState,
|
|
3169
3475
|
parse(context) {
|
|
3170
3476
|
if (isAsync) return parseAsync(context);
|
|
@@ -3633,6 +3939,7 @@ function merge(...args) {
|
|
|
3633
3939
|
};
|
|
3634
3940
|
}
|
|
3635
3941
|
};
|
|
3942
|
+
defineParseLanes(mergeParser, mergeParseLanes);
|
|
3636
3943
|
defineInheritedAnnotationParser(mergeParser);
|
|
3637
3944
|
return mergeParser;
|
|
3638
3945
|
}
|
|
@@ -4310,6 +4617,7 @@ function group(label, parser, options = {}) {
|
|
|
4310
4617
|
};
|
|
4311
4618
|
}
|
|
4312
4619
|
};
|
|
4620
|
+
defineParseLanes(groupParser, getOwnParseLanes(parser));
|
|
4313
4621
|
Object.defineProperty(groupParser, extractPhase2SeedKey, {
|
|
4314
4622
|
value(state, exec) {
|
|
4315
4623
|
return extractPhase2Seed(parser, state, exec);
|
package/dist/internal/parser.cjs
CHANGED
|
@@ -8,6 +8,12 @@ const require_input_trace = require('../input-trace.cjs');
|
|
|
8
8
|
|
|
9
9
|
//#region src/internal/parser.ts
|
|
10
10
|
/**
|
|
11
|
+
* Internal symbol used by transparent combinators to expose independently
|
|
12
|
+
* competing parse operations to shared-buffer parents.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
const parseLanesKey = Symbol("parseLanes");
|
|
16
|
+
/**
|
|
11
17
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
12
18
|
* be treated as unmatched dependency-source states during completion-time
|
|
13
19
|
* Phase 1.
|
|
@@ -385,6 +391,32 @@ function composeWrappedSourceMetadata(dependencyMetadata, wrapSource) {
|
|
|
385
391
|
};
|
|
386
392
|
}
|
|
387
393
|
/**
|
|
394
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
395
|
+
* spreads used by custom parser wrappers.
|
|
396
|
+
*
|
|
397
|
+
* @internal
|
|
398
|
+
*/
|
|
399
|
+
function defineParseLanes(parser, lanes) {
|
|
400
|
+
if (lanes == null) return;
|
|
401
|
+
Object.defineProperty(parser, parseLanesKey, {
|
|
402
|
+
value: lanes,
|
|
403
|
+
configurable: true,
|
|
404
|
+
enumerable: false
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
409
|
+
*
|
|
410
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
411
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
412
|
+
*
|
|
413
|
+
* @internal
|
|
414
|
+
*/
|
|
415
|
+
function getOwnParseLanes(parser) {
|
|
416
|
+
if (!Object.hasOwn(parser, parseLanesKey)) return void 0;
|
|
417
|
+
return parser[parseLanesKey];
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
388
420
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
389
421
|
* reconstruction.
|
|
390
422
|
*
|
|
@@ -712,11 +744,13 @@ exports.annotationWrapperRequiresSourceBindingKey = annotationWrapperRequiresSou
|
|
|
712
744
|
exports.composeWrappedSourceMetadata = composeWrappedSourceMetadata;
|
|
713
745
|
exports.createParserContext = createParserContext;
|
|
714
746
|
exports.defineInheritedAnnotationParser = defineInheritedAnnotationParser;
|
|
747
|
+
exports.defineParseLanes = defineParseLanes;
|
|
715
748
|
exports.defineSourceBindingOnlyAnnotationCompletionParser = defineSourceBindingOnlyAnnotationCompletionParser;
|
|
716
749
|
exports.getDelegatingSuggestRuntimeNodes = getDelegatingSuggestRuntimeNodes;
|
|
717
750
|
exports.getDocPage = getDocPage;
|
|
718
751
|
exports.getDocPageAsync = getDocPageAsync;
|
|
719
752
|
exports.getDocPageSync = getDocPageSync;
|
|
753
|
+
exports.getOwnParseLanes = getOwnParseLanes;
|
|
720
754
|
exports.getParserSuggestRuntimeNodes = getParserSuggestRuntimeNodes;
|
|
721
755
|
exports.inheritParentAnnotationsKey = inheritParentAnnotationsKey;
|
|
722
756
|
exports.parse = parse;
|
|
@@ -42,6 +42,51 @@ type ModeValue<M extends Mode, T> = M extends "async" ? Promise<T> : T;
|
|
|
42
42
|
* @since 0.9.0
|
|
43
43
|
*/
|
|
44
44
|
type ModeIterable<M extends Mode, T> = M extends "async" ? AsyncIterable<T> : Iterable<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Internal symbol used by transparent combinators to expose independently
|
|
47
|
+
* competing parse operations to shared-buffer parents.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
declare const parseLanesKey: unique symbol;
|
|
51
|
+
/**
|
|
52
|
+
* An owner-consumption requirement for a parse lane.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
interface ParseLaneConsumptionGroup {
|
|
56
|
+
/** Identity shared by lanes belonging to the same owning parser. */
|
|
57
|
+
readonly id: object;
|
|
58
|
+
/** Whether the owning parser is active after a consuming lane succeeds. */
|
|
59
|
+
readonly isActive?: (state: unknown) => boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A state-preserving parse operation that competes at one exact priority.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
interface ParseLane<TState> {
|
|
66
|
+
/** The exact priority at which this lane competes. */
|
|
67
|
+
readonly priority: number;
|
|
68
|
+
/**
|
|
69
|
+
* Identity shared by lanes that must all succeed before their
|
|
70
|
+
* zero-consumption state updates can be committed.
|
|
71
|
+
*/
|
|
72
|
+
readonly zeroConsumptionGroup?: object;
|
|
73
|
+
/**
|
|
74
|
+
* Whether a zero-consumption success can settle the owning parser while
|
|
75
|
+
* input remains. Defaults to `true`.
|
|
76
|
+
*/
|
|
77
|
+
readonly settlesZeroConsumption?: boolean;
|
|
78
|
+
/** Fixed tokens reachable through this lane. */
|
|
79
|
+
readonly leadingNames: ReadonlySet<string>;
|
|
80
|
+
/** Whether this lane accepts any positional token. */
|
|
81
|
+
readonly acceptingAnyToken: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Groups in which a zero-consumption update is valid only after another
|
|
84
|
+
* lane in every group has consumed input during the same arbitration.
|
|
85
|
+
*/
|
|
86
|
+
readonly requiredConsumptionGroups?: readonly ParseLaneConsumptionGroup[];
|
|
87
|
+
/** Parses through the owning parser's state and execution context. */
|
|
88
|
+
parse(context: ParserContext<TState>): ParserResult<TState> | Promise<ParserResult<TState>>;
|
|
89
|
+
}
|
|
45
90
|
/**
|
|
46
91
|
* Combines multiple modes into a single mode.
|
|
47
92
|
* If any mode is `"async"`, the result is `"async"`; otherwise `"sync"`.
|
|
@@ -148,6 +193,13 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
148
193
|
* state when parsing starts.
|
|
149
194
|
*/
|
|
150
195
|
readonly initialState: TState;
|
|
196
|
+
/**
|
|
197
|
+
* Independently competing parse operations exposed by transparent
|
|
198
|
+
* combinators. Shared-buffer parents use these to arbitrate below an
|
|
199
|
+
* aggregate parser boundary without bypassing the owner's state adapters.
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
readonly [parseLanesKey]?: readonly ParseLane<TState>[];
|
|
151
203
|
/**
|
|
152
204
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
153
205
|
* be treated as unmatched dependency-source states during completion-time
|
|
@@ -42,6 +42,51 @@ type ModeValue<M extends Mode, T> = M extends "async" ? Promise<T> : T;
|
|
|
42
42
|
* @since 0.9.0
|
|
43
43
|
*/
|
|
44
44
|
type ModeIterable<M extends Mode, T> = M extends "async" ? AsyncIterable<T> : Iterable<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Internal symbol used by transparent combinators to expose independently
|
|
47
|
+
* competing parse operations to shared-buffer parents.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
declare const parseLanesKey: unique symbol;
|
|
51
|
+
/**
|
|
52
|
+
* An owner-consumption requirement for a parse lane.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
interface ParseLaneConsumptionGroup {
|
|
56
|
+
/** Identity shared by lanes belonging to the same owning parser. */
|
|
57
|
+
readonly id: object;
|
|
58
|
+
/** Whether the owning parser is active after a consuming lane succeeds. */
|
|
59
|
+
readonly isActive?: (state: unknown) => boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A state-preserving parse operation that competes at one exact priority.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
interface ParseLane<TState> {
|
|
66
|
+
/** The exact priority at which this lane competes. */
|
|
67
|
+
readonly priority: number;
|
|
68
|
+
/**
|
|
69
|
+
* Identity shared by lanes that must all succeed before their
|
|
70
|
+
* zero-consumption state updates can be committed.
|
|
71
|
+
*/
|
|
72
|
+
readonly zeroConsumptionGroup?: object;
|
|
73
|
+
/**
|
|
74
|
+
* Whether a zero-consumption success can settle the owning parser while
|
|
75
|
+
* input remains. Defaults to `true`.
|
|
76
|
+
*/
|
|
77
|
+
readonly settlesZeroConsumption?: boolean;
|
|
78
|
+
/** Fixed tokens reachable through this lane. */
|
|
79
|
+
readonly leadingNames: ReadonlySet<string>;
|
|
80
|
+
/** Whether this lane accepts any positional token. */
|
|
81
|
+
readonly acceptingAnyToken: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Groups in which a zero-consumption update is valid only after another
|
|
84
|
+
* lane in every group has consumed input during the same arbitration.
|
|
85
|
+
*/
|
|
86
|
+
readonly requiredConsumptionGroups?: readonly ParseLaneConsumptionGroup[];
|
|
87
|
+
/** Parses through the owning parser's state and execution context. */
|
|
88
|
+
parse(context: ParserContext<TState>): ParserResult<TState> | Promise<ParserResult<TState>>;
|
|
89
|
+
}
|
|
45
90
|
/**
|
|
46
91
|
* Combines multiple modes into a single mode.
|
|
47
92
|
* If any mode is `"async"`, the result is `"async"`; otherwise `"sync"`.
|
|
@@ -148,6 +193,13 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
148
193
|
* state when parsing starts.
|
|
149
194
|
*/
|
|
150
195
|
readonly initialState: TState;
|
|
196
|
+
/**
|
|
197
|
+
* Independently competing parse operations exposed by transparent
|
|
198
|
+
* combinators. Shared-buffer parents use these to arbitrate below an
|
|
199
|
+
* aggregate parser boundary without bypassing the owner's state adapters.
|
|
200
|
+
* @internal
|
|
201
|
+
*/
|
|
202
|
+
readonly [parseLanesKey]?: readonly ParseLane<TState>[];
|
|
151
203
|
/**
|
|
152
204
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
153
205
|
* be treated as unmatched dependency-source states during completion-time
|
package/dist/internal/parser.js
CHANGED
|
@@ -8,6 +8,12 @@ import { createInputTrace } from "../input-trace.js";
|
|
|
8
8
|
|
|
9
9
|
//#region src/internal/parser.ts
|
|
10
10
|
/**
|
|
11
|
+
* Internal symbol used by transparent combinators to expose independently
|
|
12
|
+
* competing parse operations to shared-buffer parents.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
const parseLanesKey = Symbol("parseLanes");
|
|
16
|
+
/**
|
|
11
17
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
12
18
|
* be treated as unmatched dependency-source states during completion-time
|
|
13
19
|
* Phase 1.
|
|
@@ -385,6 +391,32 @@ function composeWrappedSourceMetadata(dependencyMetadata, wrapSource) {
|
|
|
385
391
|
};
|
|
386
392
|
}
|
|
387
393
|
/**
|
|
394
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
395
|
+
* spreads used by custom parser wrappers.
|
|
396
|
+
*
|
|
397
|
+
* @internal
|
|
398
|
+
*/
|
|
399
|
+
function defineParseLanes(parser, lanes) {
|
|
400
|
+
if (lanes == null) return;
|
|
401
|
+
Object.defineProperty(parser, parseLanesKey, {
|
|
402
|
+
value: lanes,
|
|
403
|
+
configurable: true,
|
|
404
|
+
enumerable: false
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
409
|
+
*
|
|
410
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
411
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
412
|
+
*
|
|
413
|
+
* @internal
|
|
414
|
+
*/
|
|
415
|
+
function getOwnParseLanes(parser) {
|
|
416
|
+
if (!Object.hasOwn(parser, parseLanesKey)) return void 0;
|
|
417
|
+
return parser[parseLanesKey];
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
388
420
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
389
421
|
* reconstruction.
|
|
390
422
|
*
|
|
@@ -708,4 +740,4 @@ function buildDocPage(parser, context, args) {
|
|
|
708
740
|
}
|
|
709
741
|
|
|
710
742
|
//#endregion
|
|
711
|
-
export { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
|
743
|
+
export { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getOwnParseLanes, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
package/dist/modifiers.cjs
CHANGED
|
@@ -226,6 +226,44 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
226
226
|
};
|
|
227
227
|
return result;
|
|
228
228
|
}
|
|
229
|
+
function adaptOptionalStyleParseLanes(parser) {
|
|
230
|
+
const lanes = require_parser.getOwnParseLanes(parser);
|
|
231
|
+
if (lanes == null) return void 0;
|
|
232
|
+
const consumptionGroup = {};
|
|
233
|
+
return lanes.map((lane) => ({
|
|
234
|
+
priority: lane.priority,
|
|
235
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
236
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
237
|
+
leadingNames: lane.leadingNames,
|
|
238
|
+
acceptingAnyToken: false,
|
|
239
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups?.map((group) => ({
|
|
240
|
+
id: group.id,
|
|
241
|
+
...group.isActive == null ? {} : { isActive(state) {
|
|
242
|
+
const innerState = Array.isArray(state) ? state[0] : parser.initialState;
|
|
243
|
+
return group.isActive?.(innerState) ?? true;
|
|
244
|
+
} }
|
|
245
|
+
})) ?? [], {
|
|
246
|
+
id: consumptionGroup,
|
|
247
|
+
isActive(state) {
|
|
248
|
+
return Array.isArray(state);
|
|
249
|
+
}
|
|
250
|
+
}],
|
|
251
|
+
parse(context) {
|
|
252
|
+
const innerState = deriveOptionalInnerParseState(context.state, parser);
|
|
253
|
+
const innerContext = {
|
|
254
|
+
...context,
|
|
255
|
+
state: innerState
|
|
256
|
+
};
|
|
257
|
+
return require_mode_dispatch.dispatchByMode(parser.mode, () => {
|
|
258
|
+
const result = lane.parse(innerContext);
|
|
259
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
260
|
+
}, async () => {
|
|
261
|
+
const result = await lane.parse(innerContext);
|
|
262
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
229
267
|
/**
|
|
230
268
|
* Creates a `shouldDeferCompletion` adapter that unwraps the outer state
|
|
231
269
|
* shape (`[TState] | undefined`) used by {@link optional} and
|
|
@@ -410,6 +448,7 @@ function optional(parser) {
|
|
|
410
448
|
const composed = require_dependency_metadata.composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
411
449
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
412
450
|
}
|
|
451
|
+
require_parser.defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
413
452
|
require_parser.defineInheritedAnnotationParser(optionalParser);
|
|
414
453
|
require_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
415
454
|
return optionalParser;
|
|
@@ -639,6 +678,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
639
678
|
} });
|
|
640
679
|
if (composed != null) withDefaultParser.dependencyMetadata = composed;
|
|
641
680
|
}
|
|
681
|
+
require_parser.defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
642
682
|
require_parser.defineInheritedAnnotationParser(withDefaultParser);
|
|
643
683
|
require_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
644
684
|
return withDefaultParser;
|
|
@@ -778,6 +818,7 @@ function map(parser, transform) {
|
|
|
778
818
|
return parser.getDocFragments(state, void 0);
|
|
779
819
|
}
|
|
780
820
|
};
|
|
821
|
+
require_parser.defineParseLanes(mappedParser, require_parser.getOwnParseLanes(parser));
|
|
781
822
|
delete mappedParser.normalizeValue;
|
|
782
823
|
delete mappedParser.validateValue;
|
|
783
824
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
@@ -1484,6 +1525,7 @@ function multiple(parser, options = {}) {
|
|
|
1484
1525
|
*/
|
|
1485
1526
|
function nonEmpty(parser) {
|
|
1486
1527
|
const syncParser = parser;
|
|
1528
|
+
const consumptionGroup = {};
|
|
1487
1529
|
const processNonEmptyResult = (result) => {
|
|
1488
1530
|
if (!result.success) return result;
|
|
1489
1531
|
if (result.consumed.length === 0) return {
|
|
@@ -1531,6 +1573,17 @@ function nonEmpty(parser) {
|
|
|
1531
1573
|
return syncParser.getDocFragments(state, defaultValue);
|
|
1532
1574
|
}
|
|
1533
1575
|
};
|
|
1576
|
+
require_parser.defineParseLanes(nonEmptyParser, require_parser.getOwnParseLanes(parser)?.map((lane) => ({
|
|
1577
|
+
priority: lane.priority,
|
|
1578
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
1579
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
1580
|
+
leadingNames: lane.leadingNames,
|
|
1581
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
1582
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups ?? [], { id: consumptionGroup }],
|
|
1583
|
+
parse(context) {
|
|
1584
|
+
return lane.parse(context);
|
|
1585
|
+
}
|
|
1586
|
+
})));
|
|
1534
1587
|
if ("placeholder" in parser) Object.defineProperty(nonEmptyParser, "placeholder", {
|
|
1535
1588
|
get() {
|
|
1536
1589
|
return parser.placeholder;
|
package/dist/modifiers.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { annotateFreshArray, annotationKey, getAnnotations, inheritAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotationWrapper } from "./internal/annotations.js";
|
|
2
2
|
import { formatMessage, message, text } from "./message.js";
|
|
3
3
|
import { dispatchByMode, dispatchIterableByMode, mapModeValue, wrapForMode } from "./internal/mode-dispatch.js";
|
|
4
|
-
import { defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
4
|
+
import { defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getOwnParseLanes, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
|
|
5
5
|
import { getDelegatedAnnotationState, hasDelegatedAnnotationCarrier, isAnnotationWrappedInitialState, normalizeDelegatedAnnotationState, normalizeNestedDelegatedAnnotationState } from "./annotation-state.js";
|
|
6
6
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
7
7
|
import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
|
|
@@ -226,6 +226,44 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
226
226
|
};
|
|
227
227
|
return result;
|
|
228
228
|
}
|
|
229
|
+
function adaptOptionalStyleParseLanes(parser) {
|
|
230
|
+
const lanes = getOwnParseLanes(parser);
|
|
231
|
+
if (lanes == null) return void 0;
|
|
232
|
+
const consumptionGroup = {};
|
|
233
|
+
return lanes.map((lane) => ({
|
|
234
|
+
priority: lane.priority,
|
|
235
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
236
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
237
|
+
leadingNames: lane.leadingNames,
|
|
238
|
+
acceptingAnyToken: false,
|
|
239
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups?.map((group) => ({
|
|
240
|
+
id: group.id,
|
|
241
|
+
...group.isActive == null ? {} : { isActive(state) {
|
|
242
|
+
const innerState = Array.isArray(state) ? state[0] : parser.initialState;
|
|
243
|
+
return group.isActive?.(innerState) ?? true;
|
|
244
|
+
} }
|
|
245
|
+
})) ?? [], {
|
|
246
|
+
id: consumptionGroup,
|
|
247
|
+
isActive(state) {
|
|
248
|
+
return Array.isArray(state);
|
|
249
|
+
}
|
|
250
|
+
}],
|
|
251
|
+
parse(context) {
|
|
252
|
+
const innerState = deriveOptionalInnerParseState(context.state, parser);
|
|
253
|
+
const innerContext = {
|
|
254
|
+
...context,
|
|
255
|
+
state: innerState
|
|
256
|
+
};
|
|
257
|
+
return dispatchByMode(parser.mode, () => {
|
|
258
|
+
const result = lane.parse(innerContext);
|
|
259
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
260
|
+
}, async () => {
|
|
261
|
+
const result = await lane.parse(innerContext);
|
|
262
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
229
267
|
/**
|
|
230
268
|
* Creates a `shouldDeferCompletion` adapter that unwraps the outer state
|
|
231
269
|
* shape (`[TState] | undefined`) used by {@link optional} and
|
|
@@ -410,6 +448,7 @@ function optional(parser) {
|
|
|
410
448
|
const composed = composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
411
449
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
412
450
|
}
|
|
451
|
+
defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
413
452
|
defineInheritedAnnotationParser(optionalParser);
|
|
414
453
|
defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
415
454
|
return optionalParser;
|
|
@@ -639,6 +678,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
639
678
|
} });
|
|
640
679
|
if (composed != null) withDefaultParser.dependencyMetadata = composed;
|
|
641
680
|
}
|
|
681
|
+
defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
642
682
|
defineInheritedAnnotationParser(withDefaultParser);
|
|
643
683
|
defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
644
684
|
return withDefaultParser;
|
|
@@ -778,6 +818,7 @@ function map(parser, transform) {
|
|
|
778
818
|
return parser.getDocFragments(state, void 0);
|
|
779
819
|
}
|
|
780
820
|
};
|
|
821
|
+
defineParseLanes(mappedParser, getOwnParseLanes(parser));
|
|
781
822
|
delete mappedParser.normalizeValue;
|
|
782
823
|
delete mappedParser.validateValue;
|
|
783
824
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
@@ -1484,6 +1525,7 @@ function multiple(parser, options = {}) {
|
|
|
1484
1525
|
*/
|
|
1485
1526
|
function nonEmpty(parser) {
|
|
1486
1527
|
const syncParser = parser;
|
|
1528
|
+
const consumptionGroup = {};
|
|
1487
1529
|
const processNonEmptyResult = (result) => {
|
|
1488
1530
|
if (!result.success) return result;
|
|
1489
1531
|
if (result.consumed.length === 0) return {
|
|
@@ -1531,6 +1573,17 @@ function nonEmpty(parser) {
|
|
|
1531
1573
|
return syncParser.getDocFragments(state, defaultValue);
|
|
1532
1574
|
}
|
|
1533
1575
|
};
|
|
1576
|
+
defineParseLanes(nonEmptyParser, getOwnParseLanes(parser)?.map((lane) => ({
|
|
1577
|
+
priority: lane.priority,
|
|
1578
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
1579
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
1580
|
+
leadingNames: lane.leadingNames,
|
|
1581
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
1582
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups ?? [], { id: consumptionGroup }],
|
|
1583
|
+
parse(context) {
|
|
1584
|
+
return lane.parse(context);
|
|
1585
|
+
}
|
|
1586
|
+
})));
|
|
1534
1587
|
if ("placeholder" in parser) Object.defineProperty(nonEmptyParser, "placeholder", {
|
|
1535
1588
|
get() {
|
|
1536
1589
|
return parser.placeholder;
|