@optique/core 1.1.4 → 1.1.5
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 +315 -7
- package/dist/constructs.js +316 -8
- package/dist/internal/parser.cjs +35 -0
- package/dist/internal/parser.d.cts +69 -1
- package/dist/internal/parser.d.ts +69 -1
- package/dist/internal/parser.js +33 -1
- package/dist/modifiers.cjs +53 -0
- package/dist/modifiers.js +54 -1
- package/package.json +3 -3
package/dist/constructs.cjs
CHANGED
|
@@ -78,8 +78,8 @@ function unionLeadingNames(parsers) {
|
|
|
78
78
|
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
79
79
|
* `object()`, `merge()`, `concat()`).
|
|
80
80
|
*
|
|
81
|
-
*
|
|
82
|
-
* round-robin parse loop). Once a
|
|
81
|
+
* Sources are processed in descending priority order (matching the
|
|
82
|
+
* round-robin parse loop). Once a source with `acceptingAnyToken` is
|
|
83
83
|
* encountered, no lower-priority children can match at position 0, so
|
|
84
84
|
* their names are excluded.
|
|
85
85
|
*/
|
|
@@ -1948,6 +1948,52 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1948
1948
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
1949
1949
|
const combinedMode = parserKeys.some((k) => parsers[k].mode === "async") ? "async" : "sync";
|
|
1950
1950
|
const getInitialError = (context) => createObjectLikeInitialError(context, noMatchContext, options.errors);
|
|
1951
|
+
const adaptFieldLaneResult = (context, field, parser, fieldState, result) => {
|
|
1952
|
+
if (!result.success) return result;
|
|
1953
|
+
if (result.consumed.length === 0 && result.next.state === fieldState) return {
|
|
1954
|
+
success: true,
|
|
1955
|
+
next: context,
|
|
1956
|
+
consumed: []
|
|
1957
|
+
};
|
|
1958
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, result.next.exec);
|
|
1959
|
+
const nextState = result.next.state === fieldState ? context.state : {
|
|
1960
|
+
...context.state,
|
|
1961
|
+
[field]: require_annotation_state.getWrappedChildState(context.state, result.next.state, parser)
|
|
1962
|
+
};
|
|
1963
|
+
return {
|
|
1964
|
+
success: true,
|
|
1965
|
+
next: {
|
|
1966
|
+
...context,
|
|
1967
|
+
buffer: result.next.buffer,
|
|
1968
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1969
|
+
state: nextState,
|
|
1970
|
+
...mergedExec != null ? {
|
|
1971
|
+
trace: mergedExec.trace,
|
|
1972
|
+
exec: mergedExec,
|
|
1973
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1974
|
+
} : {}
|
|
1975
|
+
},
|
|
1976
|
+
consumed: result.consumed
|
|
1977
|
+
};
|
|
1978
|
+
};
|
|
1979
|
+
const objectZeroConsumptionGroup = {};
|
|
1980
|
+
const objectParseLanes = parserPairs.map(([field, parser]) => ({
|
|
1981
|
+
priority: parser.priority,
|
|
1982
|
+
zeroConsumptionGroup: objectZeroConsumptionGroup,
|
|
1983
|
+
settlesZeroConsumption: false,
|
|
1984
|
+
leadingNames: parser.leadingNames,
|
|
1985
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
1986
|
+
parse(context) {
|
|
1987
|
+
const fieldState = createFieldStateGetter(context.state, getObjectParseChildState)(field, parser);
|
|
1988
|
+
return require_mode_dispatch.dispatchByMode(combinedMode, () => {
|
|
1989
|
+
const result = parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1990
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1991
|
+
}, async () => {
|
|
1992
|
+
const result = await parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1993
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
}));
|
|
1951
1997
|
const parseSync = (context) => {
|
|
1952
1998
|
let error = getInitialError(context);
|
|
1953
1999
|
let currentContext = context;
|
|
@@ -2466,6 +2512,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2466
2512
|
configurable: true,
|
|
2467
2513
|
enumerable: false
|
|
2468
2514
|
});
|
|
2515
|
+
require_internal_parser.defineParseLanes(objectParser, objectParseLanes);
|
|
2469
2516
|
require_internal_parser.defineInheritedAnnotationParser(objectParser);
|
|
2470
2517
|
return objectParser;
|
|
2471
2518
|
}
|
|
@@ -3870,7 +3917,140 @@ function merge(...args) {
|
|
|
3870
3917
|
[localObjectStateKey(index)]: result.next.state
|
|
3871
3918
|
};
|
|
3872
3919
|
};
|
|
3873
|
-
const
|
|
3920
|
+
const adaptMergeLaneResult = (parser, context, parserState, parsedState, result, index) => {
|
|
3921
|
+
if (!result.success) return result;
|
|
3922
|
+
const mergedExec = require_execution_context.mergeChildExec(context.exec, result.next.exec);
|
|
3923
|
+
const newState = result.next.state === parsedState ? context.state : mergeResultState(parser, context, parserState, result, index);
|
|
3924
|
+
return {
|
|
3925
|
+
success: true,
|
|
3926
|
+
next: {
|
|
3927
|
+
...context,
|
|
3928
|
+
buffer: result.next.buffer,
|
|
3929
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3930
|
+
state: newState,
|
|
3931
|
+
...mergedExec != null ? {
|
|
3932
|
+
trace: mergedExec.trace,
|
|
3933
|
+
exec: mergedExec,
|
|
3934
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3935
|
+
} : {}
|
|
3936
|
+
},
|
|
3937
|
+
consumed: result.consumed
|
|
3938
|
+
};
|
|
3939
|
+
};
|
|
3940
|
+
const childrenInDeclarationOrder = sorted.map(([parser, originalIndex], sortedIndex) => ({
|
|
3941
|
+
parser,
|
|
3942
|
+
originalIndex,
|
|
3943
|
+
sortedIndex
|
|
3944
|
+
})).toSorted((a, b) => a.originalIndex - b.originalIndex);
|
|
3945
|
+
const mergeParseLanes = childrenInDeclarationOrder.flatMap(({ parser, sortedIndex }) => {
|
|
3946
|
+
const occurrenceConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3947
|
+
const occurrenceZeroConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3948
|
+
const scopeConsumptionGroup = (group$1) => {
|
|
3949
|
+
const existing = occurrenceConsumptionGroups.get(group$1);
|
|
3950
|
+
if (existing != null) return existing;
|
|
3951
|
+
const scoped = {};
|
|
3952
|
+
occurrenceConsumptionGroups.set(group$1, scoped);
|
|
3953
|
+
return scoped;
|
|
3954
|
+
};
|
|
3955
|
+
const childLanes = require_internal_parser.getOwnParseLanes(parser);
|
|
3956
|
+
const lanes = childLanes ?? [{
|
|
3957
|
+
priority: parser.priority,
|
|
3958
|
+
leadingNames: parser.leadingNames,
|
|
3959
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
3960
|
+
parse(context) {
|
|
3961
|
+
return parser.parse(context);
|
|
3962
|
+
}
|
|
3963
|
+
}];
|
|
3964
|
+
return lanes.map((lane) => ({
|
|
3965
|
+
priority: lane.priority,
|
|
3966
|
+
zeroConsumptionGroup: (() => {
|
|
3967
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3968
|
+
const existing = occurrenceZeroConsumptionGroups.get(group$1);
|
|
3969
|
+
if (existing != null) return existing;
|
|
3970
|
+
const scoped = {};
|
|
3971
|
+
occurrenceZeroConsumptionGroups.set(group$1, scoped);
|
|
3972
|
+
return scoped;
|
|
3973
|
+
})(),
|
|
3974
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
3975
|
+
leadingNames: lane.leadingNames,
|
|
3976
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
3977
|
+
requiredConsumptionGroups: lane.requiredConsumptionGroups?.map((group$1) => ({
|
|
3978
|
+
id: scopeConsumptionGroup(group$1.id),
|
|
3979
|
+
...group$1.isActive == null ? {} : { isActive(state) {
|
|
3980
|
+
if (state == null || typeof state !== "object") return false;
|
|
3981
|
+
const parserState = extractParserStateFromState(parser, state, sortedIndex);
|
|
3982
|
+
return group$1.isActive?.(parserState) ?? true;
|
|
3983
|
+
} }
|
|
3984
|
+
})),
|
|
3985
|
+
parse(context) {
|
|
3986
|
+
const parserState = extractParserState(parser, context, sortedIndex);
|
|
3987
|
+
const childContext = withChildContext$1(context, sortedIndex, parserState, parser);
|
|
3988
|
+
return require_mode_dispatch.dispatchByMode(combinedMode, () => {
|
|
3989
|
+
const result = lane.parse(childContext);
|
|
3990
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3991
|
+
}, async () => {
|
|
3992
|
+
const result = await lane.parse(childContext);
|
|
3993
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3994
|
+
});
|
|
3995
|
+
}
|
|
3996
|
+
}));
|
|
3997
|
+
}).toSorted((a, b) => b.priority - a.priority);
|
|
3998
|
+
const settleZeroConsumptionLanes = (context, laneResults) => {
|
|
3999
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4000
|
+
for (const lane of mergeParseLanes) {
|
|
4001
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
4002
|
+
const groupedLanes = groups.get(group$1);
|
|
4003
|
+
if (groupedLanes == null) groups.set(group$1, [lane]);
|
|
4004
|
+
else groupedLanes.push(lane);
|
|
4005
|
+
}
|
|
4006
|
+
const settledGroups = [];
|
|
4007
|
+
for (const groupedLanes of groups.values()) {
|
|
4008
|
+
const groupSucceeded = groupedLanes.every((lane) => {
|
|
4009
|
+
const result = laneResults.get(lane);
|
|
4010
|
+
return lane.settlesZeroConsumption !== false && result?.success === true && result.consumed.length === 0 && (lane.requiredConsumptionGroups?.length ?? 0) === 0;
|
|
4011
|
+
});
|
|
4012
|
+
if (!groupSucceeded) return null;
|
|
4013
|
+
settledGroups.push(groupedLanes);
|
|
4014
|
+
}
|
|
4015
|
+
let settledContext = context;
|
|
4016
|
+
for (const groupedLanes of settledGroups) for (const lane of groupedLanes) {
|
|
4017
|
+
const result = laneResults.get(lane);
|
|
4018
|
+
if (result?.success !== true) continue;
|
|
4019
|
+
const originalState = context.state;
|
|
4020
|
+
const resultState = result.next.state;
|
|
4021
|
+
const nextState = { ...settledContext.state };
|
|
4022
|
+
const stateKeys = new Set([...Reflect.ownKeys(originalState), ...Reflect.ownKeys(resultState)]);
|
|
4023
|
+
for (const key of stateKeys) {
|
|
4024
|
+
const originalHasKey = Object.hasOwn(originalState, key);
|
|
4025
|
+
const resultHasKey = Object.hasOwn(resultState, key);
|
|
4026
|
+
if (originalHasKey === resultHasKey && originalState[key] === resultState[key]) continue;
|
|
4027
|
+
if (resultHasKey) nextState[key] = resultState[key];
|
|
4028
|
+
else delete nextState[key];
|
|
4029
|
+
}
|
|
4030
|
+
const mergedExec = require_execution_context.mergeChildExec(settledContext.exec, result.next.exec);
|
|
4031
|
+
settledContext = {
|
|
4032
|
+
...settledContext,
|
|
4033
|
+
buffer: result.next.buffer,
|
|
4034
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
4035
|
+
state: nextState,
|
|
4036
|
+
...mergedExec != null ? {
|
|
4037
|
+
trace: mergedExec.trace,
|
|
4038
|
+
exec: mergedExec,
|
|
4039
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
4040
|
+
} : {}
|
|
4041
|
+
};
|
|
4042
|
+
}
|
|
4043
|
+
return {
|
|
4044
|
+
success: true,
|
|
4045
|
+
next: settledContext,
|
|
4046
|
+
consumed: []
|
|
4047
|
+
};
|
|
4048
|
+
};
|
|
4049
|
+
const canTryPositionalLaneAfterFailure = (lane, context) => {
|
|
4050
|
+
const token = context.buffer[0];
|
|
4051
|
+
return token != null && (context.optionsTerminated || !token.startsWith("-")) && (lane.acceptingAnyToken || lane.leadingNames.has(token));
|
|
4052
|
+
};
|
|
4053
|
+
const parseChildrenSync = (context) => {
|
|
3874
4054
|
let currentContext = context;
|
|
3875
4055
|
let zeroConsumedSuccess = null;
|
|
3876
4056
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
@@ -3914,7 +4094,7 @@ function merge(...args) {
|
|
|
3914
4094
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3915
4095
|
};
|
|
3916
4096
|
};
|
|
3917
|
-
const
|
|
4097
|
+
const parseChildrenAsync = async (context) => {
|
|
3918
4098
|
let currentContext = context;
|
|
3919
4099
|
let zeroConsumedSuccess = null;
|
|
3920
4100
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -3959,15 +4139,141 @@ function merge(...args) {
|
|
|
3959
4139
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3960
4140
|
};
|
|
3961
4141
|
};
|
|
4142
|
+
const parseSync = (context) => {
|
|
4143
|
+
let currentContext = context;
|
|
4144
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
4145
|
+
const allConsumed = [];
|
|
4146
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
4147
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
4148
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
4149
|
+
let attemptedLane = false;
|
|
4150
|
+
let madeProgress = true;
|
|
4151
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
4152
|
+
madeProgress = false;
|
|
4153
|
+
let consumingError = null;
|
|
4154
|
+
for (const lane of mergeParseLanes) {
|
|
4155
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
4156
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
4157
|
+
}
|
|
4158
|
+
attemptedLane = true;
|
|
4159
|
+
const result = lane.parse(currentContext);
|
|
4160
|
+
laneResults.set(lane, result);
|
|
4161
|
+
if (result.success && result.consumed.length > 0) {
|
|
4162
|
+
currentContext = result.next;
|
|
4163
|
+
allConsumed.push(...result.consumed);
|
|
4164
|
+
consumedLanes.add(lane);
|
|
4165
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
4166
|
+
madeProgress = true;
|
|
4167
|
+
break;
|
|
4168
|
+
}
|
|
4169
|
+
if (!result.success) {
|
|
4170
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
4171
|
+
priority: lane.priority,
|
|
4172
|
+
result
|
|
4173
|
+
};
|
|
4174
|
+
if (error.consumed < result.consumed) error = result;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
4178
|
+
}
|
|
4179
|
+
if (allConsumed.length === 0) {
|
|
4180
|
+
if (attemptedLane) {
|
|
4181
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
4182
|
+
return settled ?? {
|
|
4183
|
+
...error,
|
|
4184
|
+
success: false
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
const fallback = parseChildrenSync(context);
|
|
4188
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
4189
|
+
...error,
|
|
4190
|
+
success: false
|
|
4191
|
+
};
|
|
4192
|
+
return fallback;
|
|
4193
|
+
}
|
|
4194
|
+
for (const lane of mergeParseLanes) {
|
|
4195
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
4196
|
+
const result = lane.parse(currentContext);
|
|
4197
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
4198
|
+
}
|
|
4199
|
+
return {
|
|
4200
|
+
success: true,
|
|
4201
|
+
next: currentContext,
|
|
4202
|
+
consumed: allConsumed
|
|
4203
|
+
};
|
|
4204
|
+
};
|
|
4205
|
+
const parseAsync = async (context) => {
|
|
4206
|
+
let currentContext = context;
|
|
4207
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
4208
|
+
const allConsumed = [];
|
|
4209
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
4210
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
4211
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
4212
|
+
let attemptedLane = false;
|
|
4213
|
+
let madeProgress = true;
|
|
4214
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
4215
|
+
madeProgress = false;
|
|
4216
|
+
let consumingError = null;
|
|
4217
|
+
for (const lane of mergeParseLanes) {
|
|
4218
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
4219
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
4220
|
+
}
|
|
4221
|
+
attemptedLane = true;
|
|
4222
|
+
const result = await lane.parse(currentContext);
|
|
4223
|
+
laneResults.set(lane, result);
|
|
4224
|
+
if (result.success && result.consumed.length > 0) {
|
|
4225
|
+
currentContext = result.next;
|
|
4226
|
+
allConsumed.push(...result.consumed);
|
|
4227
|
+
consumedLanes.add(lane);
|
|
4228
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
4229
|
+
madeProgress = true;
|
|
4230
|
+
break;
|
|
4231
|
+
}
|
|
4232
|
+
if (!result.success) {
|
|
4233
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
4234
|
+
priority: lane.priority,
|
|
4235
|
+
result
|
|
4236
|
+
};
|
|
4237
|
+
if (error.consumed < result.consumed) error = result;
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
4241
|
+
}
|
|
4242
|
+
if (allConsumed.length === 0) {
|
|
4243
|
+
if (attemptedLane) {
|
|
4244
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
4245
|
+
return settled ?? {
|
|
4246
|
+
...error,
|
|
4247
|
+
success: false
|
|
4248
|
+
};
|
|
4249
|
+
}
|
|
4250
|
+
const fallback = await parseChildrenAsync(context);
|
|
4251
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
4252
|
+
...error,
|
|
4253
|
+
success: false
|
|
4254
|
+
};
|
|
4255
|
+
return fallback;
|
|
4256
|
+
}
|
|
4257
|
+
for (const lane of mergeParseLanes) {
|
|
4258
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
4259
|
+
const result = await lane.parse(currentContext);
|
|
4260
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
4261
|
+
}
|
|
4262
|
+
return {
|
|
4263
|
+
success: true,
|
|
4264
|
+
next: currentContext,
|
|
4265
|
+
consumed: allConsumed
|
|
4266
|
+
};
|
|
4267
|
+
};
|
|
3962
4268
|
const mergeParser = {
|
|
3963
4269
|
mode: combinedMode,
|
|
3964
4270
|
$valueType: [],
|
|
3965
4271
|
$stateType: [],
|
|
3966
4272
|
[fieldParsersKey]: mergedFieldParsers,
|
|
3967
|
-
priority: Math.max(...
|
|
4273
|
+
priority: Math.max(...mergeParseLanes.map((lane) => lane.priority)),
|
|
3968
4274
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
3969
|
-
leadingNames: sharedBufferLeadingNames(
|
|
3970
|
-
acceptingAnyToken:
|
|
4275
|
+
leadingNames: sharedBufferLeadingNames(mergeParseLanes),
|
|
4276
|
+
acceptingAnyToken: mergeParseLanes.some((lane) => lane.acceptingAnyToken),
|
|
3971
4277
|
initialState,
|
|
3972
4278
|
canSkip(state, exec) {
|
|
3973
4279
|
return parsers.every((parser, index) => {
|
|
@@ -4442,6 +4748,7 @@ function merge(...args) {
|
|
|
4442
4748
|
};
|
|
4443
4749
|
}
|
|
4444
4750
|
};
|
|
4751
|
+
require_internal_parser.defineParseLanes(mergeParser, mergeParseLanes);
|
|
4445
4752
|
require_internal_parser.defineInheritedAnnotationParser(mergeParser);
|
|
4446
4753
|
return mergeParser;
|
|
4447
4754
|
}
|
|
@@ -5124,6 +5431,7 @@ function group(label, parser, options = {}) {
|
|
|
5124
5431
|
};
|
|
5125
5432
|
}
|
|
5126
5433
|
};
|
|
5434
|
+
require_internal_parser.defineParseLanes(groupParser, require_internal_parser.getOwnParseLanes(parser));
|
|
5127
5435
|
Object.defineProperty(groupParser, require_phase2_seed.extractPhase2SeedKey, {
|
|
5128
5436
|
value(state, exec) {
|
|
5129
5437
|
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 { allowDuplicateLeadingCommandNamesKey } from "./internal/command-alias.js";
|
|
12
12
|
import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
|
|
@@ -78,8 +78,8 @@ function unionLeadingNames(parsers) {
|
|
|
78
78
|
* Computes `leadingNames` for shared-buffer compositions (`tuple()`,
|
|
79
79
|
* `object()`, `merge()`, `concat()`).
|
|
80
80
|
*
|
|
81
|
-
*
|
|
82
|
-
* round-robin parse loop). Once a
|
|
81
|
+
* Sources are processed in descending priority order (matching the
|
|
82
|
+
* round-robin parse loop). Once a source with `acceptingAnyToken` is
|
|
83
83
|
* encountered, no lower-priority children can match at position 0, so
|
|
84
84
|
* their names are excluded.
|
|
85
85
|
*/
|
|
@@ -1948,6 +1948,52 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1948
1948
|
const noMatchContext = analyzeNoMatchContext(parserKeys.map((k) => parsers[k]));
|
|
1949
1949
|
const combinedMode = parserKeys.some((k) => parsers[k].mode === "async") ? "async" : "sync";
|
|
1950
1950
|
const getInitialError = (context) => createObjectLikeInitialError(context, noMatchContext, options.errors);
|
|
1951
|
+
const adaptFieldLaneResult = (context, field, parser, fieldState, result) => {
|
|
1952
|
+
if (!result.success) return result;
|
|
1953
|
+
if (result.consumed.length === 0 && result.next.state === fieldState) return {
|
|
1954
|
+
success: true,
|
|
1955
|
+
next: context,
|
|
1956
|
+
consumed: []
|
|
1957
|
+
};
|
|
1958
|
+
const mergedExec = mergeChildExec(context.exec, result.next.exec);
|
|
1959
|
+
const nextState = result.next.state === fieldState ? context.state : {
|
|
1960
|
+
...context.state,
|
|
1961
|
+
[field]: getWrappedChildState(context.state, result.next.state, parser)
|
|
1962
|
+
};
|
|
1963
|
+
return {
|
|
1964
|
+
success: true,
|
|
1965
|
+
next: {
|
|
1966
|
+
...context,
|
|
1967
|
+
buffer: result.next.buffer,
|
|
1968
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
1969
|
+
state: nextState,
|
|
1970
|
+
...mergedExec != null ? {
|
|
1971
|
+
trace: mergedExec.trace,
|
|
1972
|
+
exec: mergedExec,
|
|
1973
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
1974
|
+
} : {}
|
|
1975
|
+
},
|
|
1976
|
+
consumed: result.consumed
|
|
1977
|
+
};
|
|
1978
|
+
};
|
|
1979
|
+
const objectZeroConsumptionGroup = {};
|
|
1980
|
+
const objectParseLanes = parserPairs.map(([field, parser]) => ({
|
|
1981
|
+
priority: parser.priority,
|
|
1982
|
+
zeroConsumptionGroup: objectZeroConsumptionGroup,
|
|
1983
|
+
settlesZeroConsumption: false,
|
|
1984
|
+
leadingNames: parser.leadingNames,
|
|
1985
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
1986
|
+
parse(context) {
|
|
1987
|
+
const fieldState = createFieldStateGetter(context.state, getObjectParseChildState)(field, parser);
|
|
1988
|
+
return dispatchByMode(combinedMode, () => {
|
|
1989
|
+
const result = parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1990
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1991
|
+
}, async () => {
|
|
1992
|
+
const result = await parser.parse(withChildContext$1(context, field, fieldState, parser));
|
|
1993
|
+
return adaptFieldLaneResult(context, field, parser, fieldState, result);
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1996
|
+
}));
|
|
1951
1997
|
const parseSync = (context) => {
|
|
1952
1998
|
let error = getInitialError(context);
|
|
1953
1999
|
let currentContext = context;
|
|
@@ -2466,6 +2512,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
2466
2512
|
configurable: true,
|
|
2467
2513
|
enumerable: false
|
|
2468
2514
|
});
|
|
2515
|
+
defineParseLanes(objectParser, objectParseLanes);
|
|
2469
2516
|
defineInheritedAnnotationParser(objectParser);
|
|
2470
2517
|
return objectParser;
|
|
2471
2518
|
}
|
|
@@ -3870,7 +3917,140 @@ function merge(...args) {
|
|
|
3870
3917
|
[localObjectStateKey(index)]: result.next.state
|
|
3871
3918
|
};
|
|
3872
3919
|
};
|
|
3873
|
-
const
|
|
3920
|
+
const adaptMergeLaneResult = (parser, context, parserState, parsedState, result, index) => {
|
|
3921
|
+
if (!result.success) return result;
|
|
3922
|
+
const mergedExec = mergeChildExec(context.exec, result.next.exec);
|
|
3923
|
+
const newState = result.next.state === parsedState ? context.state : mergeResultState(parser, context, parserState, result, index);
|
|
3924
|
+
return {
|
|
3925
|
+
success: true,
|
|
3926
|
+
next: {
|
|
3927
|
+
...context,
|
|
3928
|
+
buffer: result.next.buffer,
|
|
3929
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
3930
|
+
state: newState,
|
|
3931
|
+
...mergedExec != null ? {
|
|
3932
|
+
trace: mergedExec.trace,
|
|
3933
|
+
exec: mergedExec,
|
|
3934
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
3935
|
+
} : {}
|
|
3936
|
+
},
|
|
3937
|
+
consumed: result.consumed
|
|
3938
|
+
};
|
|
3939
|
+
};
|
|
3940
|
+
const childrenInDeclarationOrder = sorted.map(([parser, originalIndex], sortedIndex) => ({
|
|
3941
|
+
parser,
|
|
3942
|
+
originalIndex,
|
|
3943
|
+
sortedIndex
|
|
3944
|
+
})).toSorted((a, b) => a.originalIndex - b.originalIndex);
|
|
3945
|
+
const mergeParseLanes = childrenInDeclarationOrder.flatMap(({ parser, sortedIndex }) => {
|
|
3946
|
+
const occurrenceConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3947
|
+
const occurrenceZeroConsumptionGroups = /* @__PURE__ */ new WeakMap();
|
|
3948
|
+
const scopeConsumptionGroup = (group$1) => {
|
|
3949
|
+
const existing = occurrenceConsumptionGroups.get(group$1);
|
|
3950
|
+
if (existing != null) return existing;
|
|
3951
|
+
const scoped = {};
|
|
3952
|
+
occurrenceConsumptionGroups.set(group$1, scoped);
|
|
3953
|
+
return scoped;
|
|
3954
|
+
};
|
|
3955
|
+
const childLanes = getOwnParseLanes(parser);
|
|
3956
|
+
const lanes = childLanes ?? [{
|
|
3957
|
+
priority: parser.priority,
|
|
3958
|
+
leadingNames: parser.leadingNames,
|
|
3959
|
+
acceptingAnyToken: parser.acceptingAnyToken,
|
|
3960
|
+
parse(context) {
|
|
3961
|
+
return parser.parse(context);
|
|
3962
|
+
}
|
|
3963
|
+
}];
|
|
3964
|
+
return lanes.map((lane) => ({
|
|
3965
|
+
priority: lane.priority,
|
|
3966
|
+
zeroConsumptionGroup: (() => {
|
|
3967
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
3968
|
+
const existing = occurrenceZeroConsumptionGroups.get(group$1);
|
|
3969
|
+
if (existing != null) return existing;
|
|
3970
|
+
const scoped = {};
|
|
3971
|
+
occurrenceZeroConsumptionGroups.set(group$1, scoped);
|
|
3972
|
+
return scoped;
|
|
3973
|
+
})(),
|
|
3974
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
3975
|
+
leadingNames: lane.leadingNames,
|
|
3976
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
3977
|
+
requiredConsumptionGroups: lane.requiredConsumptionGroups?.map((group$1) => ({
|
|
3978
|
+
id: scopeConsumptionGroup(group$1.id),
|
|
3979
|
+
...group$1.isActive == null ? {} : { isActive(state) {
|
|
3980
|
+
if (state == null || typeof state !== "object") return false;
|
|
3981
|
+
const parserState = extractParserStateFromState(parser, state, sortedIndex);
|
|
3982
|
+
return group$1.isActive?.(parserState) ?? true;
|
|
3983
|
+
} }
|
|
3984
|
+
})),
|
|
3985
|
+
parse(context) {
|
|
3986
|
+
const parserState = extractParserState(parser, context, sortedIndex);
|
|
3987
|
+
const childContext = withChildContext$1(context, sortedIndex, parserState, parser);
|
|
3988
|
+
return dispatchByMode(combinedMode, () => {
|
|
3989
|
+
const result = lane.parse(childContext);
|
|
3990
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3991
|
+
}, async () => {
|
|
3992
|
+
const result = await lane.parse(childContext);
|
|
3993
|
+
return adaptMergeLaneResult(parser, context, parserState, childContext.state, result, sortedIndex);
|
|
3994
|
+
});
|
|
3995
|
+
}
|
|
3996
|
+
}));
|
|
3997
|
+
}).toSorted((a, b) => b.priority - a.priority);
|
|
3998
|
+
const settleZeroConsumptionLanes = (context, laneResults) => {
|
|
3999
|
+
const groups = /* @__PURE__ */ new Map();
|
|
4000
|
+
for (const lane of mergeParseLanes) {
|
|
4001
|
+
const group$1 = lane.zeroConsumptionGroup ?? lane;
|
|
4002
|
+
const groupedLanes = groups.get(group$1);
|
|
4003
|
+
if (groupedLanes == null) groups.set(group$1, [lane]);
|
|
4004
|
+
else groupedLanes.push(lane);
|
|
4005
|
+
}
|
|
4006
|
+
const settledGroups = [];
|
|
4007
|
+
for (const groupedLanes of groups.values()) {
|
|
4008
|
+
const groupSucceeded = groupedLanes.every((lane) => {
|
|
4009
|
+
const result = laneResults.get(lane);
|
|
4010
|
+
return lane.settlesZeroConsumption !== false && result?.success === true && result.consumed.length === 0 && (lane.requiredConsumptionGroups?.length ?? 0) === 0;
|
|
4011
|
+
});
|
|
4012
|
+
if (!groupSucceeded) return null;
|
|
4013
|
+
settledGroups.push(groupedLanes);
|
|
4014
|
+
}
|
|
4015
|
+
let settledContext = context;
|
|
4016
|
+
for (const groupedLanes of settledGroups) for (const lane of groupedLanes) {
|
|
4017
|
+
const result = laneResults.get(lane);
|
|
4018
|
+
if (result?.success !== true) continue;
|
|
4019
|
+
const originalState = context.state;
|
|
4020
|
+
const resultState = result.next.state;
|
|
4021
|
+
const nextState = { ...settledContext.state };
|
|
4022
|
+
const stateKeys = new Set([...Reflect.ownKeys(originalState), ...Reflect.ownKeys(resultState)]);
|
|
4023
|
+
for (const key of stateKeys) {
|
|
4024
|
+
const originalHasKey = Object.hasOwn(originalState, key);
|
|
4025
|
+
const resultHasKey = Object.hasOwn(resultState, key);
|
|
4026
|
+
if (originalHasKey === resultHasKey && originalState[key] === resultState[key]) continue;
|
|
4027
|
+
if (resultHasKey) nextState[key] = resultState[key];
|
|
4028
|
+
else delete nextState[key];
|
|
4029
|
+
}
|
|
4030
|
+
const mergedExec = mergeChildExec(settledContext.exec, result.next.exec);
|
|
4031
|
+
settledContext = {
|
|
4032
|
+
...settledContext,
|
|
4033
|
+
buffer: result.next.buffer,
|
|
4034
|
+
optionsTerminated: result.next.optionsTerminated,
|
|
4035
|
+
state: nextState,
|
|
4036
|
+
...mergedExec != null ? {
|
|
4037
|
+
trace: mergedExec.trace,
|
|
4038
|
+
exec: mergedExec,
|
|
4039
|
+
dependencyRegistry: mergedExec.dependencyRegistry
|
|
4040
|
+
} : {}
|
|
4041
|
+
};
|
|
4042
|
+
}
|
|
4043
|
+
return {
|
|
4044
|
+
success: true,
|
|
4045
|
+
next: settledContext,
|
|
4046
|
+
consumed: []
|
|
4047
|
+
};
|
|
4048
|
+
};
|
|
4049
|
+
const canTryPositionalLaneAfterFailure = (lane, context) => {
|
|
4050
|
+
const token = context.buffer[0];
|
|
4051
|
+
return token != null && (context.optionsTerminated || !token.startsWith("-")) && (lane.acceptingAnyToken || lane.leadingNames.has(token));
|
|
4052
|
+
};
|
|
4053
|
+
const parseChildrenSync = (context) => {
|
|
3874
4054
|
let currentContext = context;
|
|
3875
4055
|
let zeroConsumedSuccess = null;
|
|
3876
4056
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
@@ -3914,7 +4094,7 @@ function merge(...args) {
|
|
|
3914
4094
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3915
4095
|
};
|
|
3916
4096
|
};
|
|
3917
|
-
const
|
|
4097
|
+
const parseChildrenAsync = async (context) => {
|
|
3918
4098
|
let currentContext = context;
|
|
3919
4099
|
let zeroConsumedSuccess = null;
|
|
3920
4100
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -3959,15 +4139,141 @@ function merge(...args) {
|
|
|
3959
4139
|
...createObjectLikeInitialError(context, noMatchContext)
|
|
3960
4140
|
};
|
|
3961
4141
|
};
|
|
4142
|
+
const parseSync = (context) => {
|
|
4143
|
+
let currentContext = context;
|
|
4144
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
4145
|
+
const allConsumed = [];
|
|
4146
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
4147
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
4148
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
4149
|
+
let attemptedLane = false;
|
|
4150
|
+
let madeProgress = true;
|
|
4151
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
4152
|
+
madeProgress = false;
|
|
4153
|
+
let consumingError = null;
|
|
4154
|
+
for (const lane of mergeParseLanes) {
|
|
4155
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
4156
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
4157
|
+
}
|
|
4158
|
+
attemptedLane = true;
|
|
4159
|
+
const result = lane.parse(currentContext);
|
|
4160
|
+
laneResults.set(lane, result);
|
|
4161
|
+
if (result.success && result.consumed.length > 0) {
|
|
4162
|
+
currentContext = result.next;
|
|
4163
|
+
allConsumed.push(...result.consumed);
|
|
4164
|
+
consumedLanes.add(lane);
|
|
4165
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
4166
|
+
madeProgress = true;
|
|
4167
|
+
break;
|
|
4168
|
+
}
|
|
4169
|
+
if (!result.success) {
|
|
4170
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
4171
|
+
priority: lane.priority,
|
|
4172
|
+
result
|
|
4173
|
+
};
|
|
4174
|
+
if (error.consumed < result.consumed) error = result;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
4178
|
+
}
|
|
4179
|
+
if (allConsumed.length === 0) {
|
|
4180
|
+
if (attemptedLane) {
|
|
4181
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
4182
|
+
return settled ?? {
|
|
4183
|
+
...error,
|
|
4184
|
+
success: false
|
|
4185
|
+
};
|
|
4186
|
+
}
|
|
4187
|
+
const fallback = parseChildrenSync(context);
|
|
4188
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
4189
|
+
...error,
|
|
4190
|
+
success: false
|
|
4191
|
+
};
|
|
4192
|
+
return fallback;
|
|
4193
|
+
}
|
|
4194
|
+
for (const lane of mergeParseLanes) {
|
|
4195
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
4196
|
+
const result = lane.parse(currentContext);
|
|
4197
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
4198
|
+
}
|
|
4199
|
+
return {
|
|
4200
|
+
success: true,
|
|
4201
|
+
next: currentContext,
|
|
4202
|
+
consumed: allConsumed
|
|
4203
|
+
};
|
|
4204
|
+
};
|
|
4205
|
+
const parseAsync = async (context) => {
|
|
4206
|
+
let currentContext = context;
|
|
4207
|
+
let error = createObjectLikeInitialError(context, noMatchContext);
|
|
4208
|
+
const allConsumed = [];
|
|
4209
|
+
const consumedLanes = /* @__PURE__ */ new Set();
|
|
4210
|
+
const consumedGroups = /* @__PURE__ */ new Set();
|
|
4211
|
+
const laneResults = /* @__PURE__ */ new Map();
|
|
4212
|
+
let attemptedLane = false;
|
|
4213
|
+
let madeProgress = true;
|
|
4214
|
+
while (madeProgress && currentContext.buffer.length > 0) {
|
|
4215
|
+
madeProgress = false;
|
|
4216
|
+
let consumingError = null;
|
|
4217
|
+
for (const lane of mergeParseLanes) {
|
|
4218
|
+
if (consumingError != null && lane.priority < consumingError.priority) {
|
|
4219
|
+
if (!canTryPositionalLaneAfterFailure(lane, currentContext)) continue;
|
|
4220
|
+
}
|
|
4221
|
+
attemptedLane = true;
|
|
4222
|
+
const result = await lane.parse(currentContext);
|
|
4223
|
+
laneResults.set(lane, result);
|
|
4224
|
+
if (result.success && result.consumed.length > 0) {
|
|
4225
|
+
currentContext = result.next;
|
|
4226
|
+
allConsumed.push(...result.consumed);
|
|
4227
|
+
consumedLanes.add(lane);
|
|
4228
|
+
for (const group$1 of lane.requiredConsumptionGroups ?? []) if (group$1.isActive?.(result.next.state) !== false) consumedGroups.add(group$1.id);
|
|
4229
|
+
madeProgress = true;
|
|
4230
|
+
break;
|
|
4231
|
+
}
|
|
4232
|
+
if (!result.success) {
|
|
4233
|
+
if (result.consumed > 0 && consumingError == null) consumingError = {
|
|
4234
|
+
priority: lane.priority,
|
|
4235
|
+
result
|
|
4236
|
+
};
|
|
4237
|
+
if (error.consumed < result.consumed) error = result;
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
if (!madeProgress && consumingError != null && allConsumed.length === 0) return consumingError.result;
|
|
4241
|
+
}
|
|
4242
|
+
if (allConsumed.length === 0) {
|
|
4243
|
+
if (attemptedLane) {
|
|
4244
|
+
const settled = settleZeroConsumptionLanes(context, laneResults);
|
|
4245
|
+
return settled ?? {
|
|
4246
|
+
...error,
|
|
4247
|
+
success: false
|
|
4248
|
+
};
|
|
4249
|
+
}
|
|
4250
|
+
const fallback = await parseChildrenAsync(context);
|
|
4251
|
+
if (!fallback.success && fallback.consumed < error.consumed) return {
|
|
4252
|
+
...error,
|
|
4253
|
+
success: false
|
|
4254
|
+
};
|
|
4255
|
+
return fallback;
|
|
4256
|
+
}
|
|
4257
|
+
for (const lane of mergeParseLanes) {
|
|
4258
|
+
if (consumedLanes.has(lane) || lane.leadingNames.size > 0 || lane.acceptingAnyToken || lane.requiredConsumptionGroups?.some((group$1) => !consumedGroups.has(group$1.id)) === true) continue;
|
|
4259
|
+
const result = await lane.parse(currentContext);
|
|
4260
|
+
if (result.success && result.consumed.length === 0 && result.next.state !== currentContext.state) currentContext = result.next;
|
|
4261
|
+
}
|
|
4262
|
+
return {
|
|
4263
|
+
success: true,
|
|
4264
|
+
next: currentContext,
|
|
4265
|
+
consumed: allConsumed
|
|
4266
|
+
};
|
|
4267
|
+
};
|
|
3962
4268
|
const mergeParser = {
|
|
3963
4269
|
mode: combinedMode,
|
|
3964
4270
|
$valueType: [],
|
|
3965
4271
|
$stateType: [],
|
|
3966
4272
|
[fieldParsersKey]: mergedFieldParsers,
|
|
3967
|
-
priority: Math.max(...
|
|
4273
|
+
priority: Math.max(...mergeParseLanes.map((lane) => lane.priority)),
|
|
3968
4274
|
usage: applyHiddenToUsage(parsers.flatMap((p) => p.usage), options.hidden),
|
|
3969
|
-
leadingNames: sharedBufferLeadingNames(
|
|
3970
|
-
acceptingAnyToken:
|
|
4275
|
+
leadingNames: sharedBufferLeadingNames(mergeParseLanes),
|
|
4276
|
+
acceptingAnyToken: mergeParseLanes.some((lane) => lane.acceptingAnyToken),
|
|
3971
4277
|
initialState,
|
|
3972
4278
|
canSkip(state, exec) {
|
|
3973
4279
|
return parsers.every((parser, index) => {
|
|
@@ -4442,6 +4748,7 @@ function merge(...args) {
|
|
|
4442
4748
|
};
|
|
4443
4749
|
}
|
|
4444
4750
|
};
|
|
4751
|
+
defineParseLanes(mergeParser, mergeParseLanes);
|
|
4445
4752
|
defineInheritedAnnotationParser(mergeParser);
|
|
4446
4753
|
return mergeParser;
|
|
4447
4754
|
}
|
|
@@ -5124,6 +5431,7 @@ function group(label, parser, options = {}) {
|
|
|
5124
5431
|
};
|
|
5125
5432
|
}
|
|
5126
5433
|
};
|
|
5434
|
+
defineParseLanes(groupParser, getOwnParseLanes(parser));
|
|
5127
5435
|
Object.defineProperty(groupParser, extractPhase2SeedKey, {
|
|
5128
5436
|
value(state, exec) {
|
|
5129
5437
|
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.
|
|
@@ -387,6 +393,32 @@ function composeWrappedSourceMetadata(dependencyMetadata, wrapSource) {
|
|
|
387
393
|
};
|
|
388
394
|
}
|
|
389
395
|
/**
|
|
396
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
397
|
+
* spreads used by custom parser wrappers.
|
|
398
|
+
*
|
|
399
|
+
* @internal
|
|
400
|
+
*/
|
|
401
|
+
function defineParseLanes(parser, lanes) {
|
|
402
|
+
if (lanes == null) return;
|
|
403
|
+
Object.defineProperty(parser, parseLanesKey, {
|
|
404
|
+
value: lanes,
|
|
405
|
+
configurable: true,
|
|
406
|
+
enumerable: false
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
411
|
+
*
|
|
412
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
413
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
414
|
+
*
|
|
415
|
+
* @internal
|
|
416
|
+
*/
|
|
417
|
+
function getOwnParseLanes(parser) {
|
|
418
|
+
if (!Object.hasOwn(parser, parseLanesKey)) return void 0;
|
|
419
|
+
return parser[parseLanesKey];
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
390
422
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
391
423
|
* reconstruction.
|
|
392
424
|
*
|
|
@@ -797,15 +829,18 @@ exports.annotationWrapperRequiresSourceBindingKey = annotationWrapperRequiresSou
|
|
|
797
829
|
exports.composeWrappedSourceMetadata = composeWrappedSourceMetadata;
|
|
798
830
|
exports.createParserContext = createParserContext;
|
|
799
831
|
exports.defineInheritedAnnotationParser = defineInheritedAnnotationParser;
|
|
832
|
+
exports.defineParseLanes = defineParseLanes;
|
|
800
833
|
exports.defineSourceBindingOnlyAnnotationCompletionParser = defineSourceBindingOnlyAnnotationCompletionParser;
|
|
801
834
|
exports.getDelegatingSuggestRuntimeNodes = getDelegatingSuggestRuntimeNodes;
|
|
802
835
|
exports.getDocPage = getDocPage;
|
|
803
836
|
exports.getDocPageAsync = getDocPageAsync;
|
|
804
837
|
exports.getDocPageSync = getDocPageSync;
|
|
838
|
+
exports.getOwnParseLanes = getOwnParseLanes;
|
|
805
839
|
exports.getParserSuggestRuntimeNodes = getParserSuggestRuntimeNodes;
|
|
806
840
|
exports.inheritParentAnnotationsKey = inheritParentAnnotationsKey;
|
|
807
841
|
exports.parse = parse;
|
|
808
842
|
exports.parseAsync = parseAsync;
|
|
843
|
+
exports.parseLanesKey = parseLanesKey;
|
|
809
844
|
exports.parseSync = parseSync;
|
|
810
845
|
exports.suggest = suggest;
|
|
811
846
|
exports.suggestAsync = suggestAsync;
|
|
@@ -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"`.
|
|
@@ -162,6 +207,13 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
162
207
|
* state when parsing starts.
|
|
163
208
|
*/
|
|
164
209
|
readonly initialState: TState;
|
|
210
|
+
/**
|
|
211
|
+
* Independently competing parse operations exposed by transparent
|
|
212
|
+
* combinators. Shared-buffer parents use these to arbitrate below an
|
|
213
|
+
* aggregate parser boundary without bypassing the owner's state adapters.
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
readonly [parseLanesKey]?: readonly ParseLane<TState>[];
|
|
165
217
|
/**
|
|
166
218
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
167
219
|
* be treated as unmatched dependency-source states during completion-time
|
|
@@ -851,6 +903,22 @@ declare function getDelegatingSuggestRuntimeNodes<TInnerState>(innerParser: Pars
|
|
|
851
903
|
* @internal
|
|
852
904
|
*/
|
|
853
905
|
declare function composeWrappedSourceMetadata(dependencyMetadata: ParserDependencyMetadata | undefined, wrapSource: (source: NonNullable<ParserDependencyMetadata["source"]>) => NonNullable<ParserDependencyMetadata["source"]>): ParserDependencyMetadata | undefined;
|
|
906
|
+
/**
|
|
907
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
908
|
+
* spreads used by custom parser wrappers.
|
|
909
|
+
*
|
|
910
|
+
* @internal
|
|
911
|
+
*/
|
|
912
|
+
declare function defineParseLanes<TState>(parser: object, lanes: readonly ParseLane<TState>[] | undefined): void;
|
|
913
|
+
/**
|
|
914
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
915
|
+
*
|
|
916
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
917
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
918
|
+
*
|
|
919
|
+
* @internal
|
|
920
|
+
*/
|
|
921
|
+
declare function getOwnParseLanes<TState>(parser: object): readonly ParseLane<TState>[] | undefined;
|
|
854
922
|
/**
|
|
855
923
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
856
924
|
* reconstruction.
|
|
@@ -999,4 +1067,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, argsOrOpti
|
|
|
999
1067
|
declare function getDocPage(parser: Parser<"async", unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): Promise<DocPage | undefined>;
|
|
1000
1068
|
declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): ModeValue<M, DocPage | undefined>;
|
|
1001
1069
|
//#endregion
|
|
1002
|
-
export { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, Result, Suggestion, annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
|
1070
|
+
export { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, ParseLane, ParseLaneConsumptionGroup, type ParseOptions, Parser, ParserContext, ParserResult, Result, Suggestion, annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getOwnParseLanes, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseLanesKey, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
|
@@ -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"`.
|
|
@@ -162,6 +207,13 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
|
|
|
162
207
|
* state when parsing starts.
|
|
163
208
|
*/
|
|
164
209
|
readonly initialState: TState;
|
|
210
|
+
/**
|
|
211
|
+
* Independently competing parse operations exposed by transparent
|
|
212
|
+
* combinators. Shared-buffer parents use these to arbitrate below an
|
|
213
|
+
* aggregate parser boundary without bypassing the owner's state adapters.
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
readonly [parseLanesKey]?: readonly ParseLane<TState>[];
|
|
165
217
|
/**
|
|
166
218
|
* Internal marker for wrappers whose `{ hasCliValue: false }` states should
|
|
167
219
|
* be treated as unmatched dependency-source states during completion-time
|
|
@@ -851,6 +903,22 @@ declare function getDelegatingSuggestRuntimeNodes<TInnerState>(innerParser: Pars
|
|
|
851
903
|
* @internal
|
|
852
904
|
*/
|
|
853
905
|
declare function composeWrappedSourceMetadata(dependencyMetadata: ParserDependencyMetadata | undefined, wrapSource: (source: NonNullable<ParserDependencyMetadata["source"]>) => NonNullable<ParserDependencyMetadata["source"]>): ParserDependencyMetadata | undefined;
|
|
906
|
+
/**
|
|
907
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
908
|
+
* spreads used by custom parser wrappers.
|
|
909
|
+
*
|
|
910
|
+
* @internal
|
|
911
|
+
*/
|
|
912
|
+
declare function defineParseLanes<TState>(parser: object, lanes: readonly ParseLane<TState>[] | undefined): void;
|
|
913
|
+
/**
|
|
914
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
915
|
+
*
|
|
916
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
917
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
918
|
+
*
|
|
919
|
+
* @internal
|
|
920
|
+
*/
|
|
921
|
+
declare function getOwnParseLanes<TState>(parser: object): readonly ParseLane<TState>[] | undefined;
|
|
854
922
|
/**
|
|
855
923
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
856
924
|
* reconstruction.
|
|
@@ -999,4 +1067,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, argsOrOpti
|
|
|
999
1067
|
declare function getDocPage(parser: Parser<"async", unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): Promise<DocPage | undefined>;
|
|
1000
1068
|
declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): ModeValue<M, DocPage | undefined>;
|
|
1001
1069
|
//#endregion
|
|
1002
|
-
export { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, Result, Suggestion, annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
|
1070
|
+
export { CombineModes, DocState, ExecutionContext, ExecutionPhase, InferMode, InferValue, Mode, ModeIterable, ModeValue, ParseFrame, ParseLane, ParseLaneConsumptionGroup, type ParseOptions, Parser, ParserContext, ParserResult, Result, Suggestion, annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getOwnParseLanes, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseLanesKey, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
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.
|
|
@@ -387,6 +393,32 @@ function composeWrappedSourceMetadata(dependencyMetadata, wrapSource) {
|
|
|
387
393
|
};
|
|
388
394
|
}
|
|
389
395
|
/**
|
|
396
|
+
* Defines internal parse-lane metadata without exposing it through object
|
|
397
|
+
* spreads used by custom parser wrappers.
|
|
398
|
+
*
|
|
399
|
+
* @internal
|
|
400
|
+
*/
|
|
401
|
+
function defineParseLanes(parser, lanes) {
|
|
402
|
+
if (lanes == null) return;
|
|
403
|
+
Object.defineProperty(parser, parseLanesKey, {
|
|
404
|
+
value: lanes,
|
|
405
|
+
configurable: true,
|
|
406
|
+
enumerable: false
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Gets parse-lane metadata defined directly on a parser.
|
|
411
|
+
*
|
|
412
|
+
* Inherited metadata belongs to the parser's prototype and must not bypass an
|
|
413
|
+
* overriding `parse()` implementation on a custom wrapper.
|
|
414
|
+
*
|
|
415
|
+
* @internal
|
|
416
|
+
*/
|
|
417
|
+
function getOwnParseLanes(parser) {
|
|
418
|
+
if (!Object.hasOwn(parser, parseLanesKey)) return void 0;
|
|
419
|
+
return parser[parseLanesKey];
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
390
422
|
* Marks a parser as inheriting parent-state annotations through wrapper-state
|
|
391
423
|
* reconstruction.
|
|
392
424
|
*
|
|
@@ -793,4 +825,4 @@ function buildDocPage(parser, context, args, matchedCommandArgIndices) {
|
|
|
793
825
|
}
|
|
794
826
|
|
|
795
827
|
//#endregion
|
|
796
|
-
export { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
|
828
|
+
export { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, createParserContext, defineInheritedAnnotationParser, defineParseLanes, defineSourceBindingOnlyAnnotationCompletionParser, getDelegatingSuggestRuntimeNodes, getDocPage, getDocPageAsync, getDocPageSync, getOwnParseLanes, getParserSuggestRuntimeNodes, inheritParentAnnotationsKey, parse, parseAsync, parseLanesKey, parseSync, suggest, suggestAsync, suggestSync, unmatchedNonCliDependencySourceStateMarker };
|
package/dist/modifiers.cjs
CHANGED
|
@@ -231,6 +231,44 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
231
231
|
};
|
|
232
232
|
return result;
|
|
233
233
|
}
|
|
234
|
+
function adaptOptionalStyleParseLanes(parser) {
|
|
235
|
+
const lanes = require_internal_parser.getOwnParseLanes(parser);
|
|
236
|
+
if (lanes == null) return void 0;
|
|
237
|
+
const consumptionGroup = {};
|
|
238
|
+
return lanes.map((lane) => ({
|
|
239
|
+
priority: lane.priority,
|
|
240
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
241
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
242
|
+
leadingNames: lane.leadingNames,
|
|
243
|
+
acceptingAnyToken: false,
|
|
244
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups?.map((group) => ({
|
|
245
|
+
id: group.id,
|
|
246
|
+
...group.isActive == null ? {} : { isActive(state) {
|
|
247
|
+
const innerState = Array.isArray(state) ? state[0] : parser.initialState;
|
|
248
|
+
return group.isActive?.(innerState) ?? true;
|
|
249
|
+
} }
|
|
250
|
+
})) ?? [], {
|
|
251
|
+
id: consumptionGroup,
|
|
252
|
+
isActive(state) {
|
|
253
|
+
return Array.isArray(state);
|
|
254
|
+
}
|
|
255
|
+
}],
|
|
256
|
+
parse(context) {
|
|
257
|
+
const innerState = deriveOptionalInnerParseState(context.state, parser);
|
|
258
|
+
const innerContext = {
|
|
259
|
+
...context,
|
|
260
|
+
state: innerState
|
|
261
|
+
};
|
|
262
|
+
return require_mode_dispatch.dispatchByMode(parser.mode, () => {
|
|
263
|
+
const result = lane.parse(innerContext);
|
|
264
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
265
|
+
}, async () => {
|
|
266
|
+
const result = await lane.parse(innerContext);
|
|
267
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
234
272
|
/**
|
|
235
273
|
* Creates a `shouldDeferCompletion` adapter that unwraps the outer state
|
|
236
274
|
* shape (`[TState] | undefined`) used by {@link optional} and
|
|
@@ -420,6 +458,7 @@ function optional(parser) {
|
|
|
420
458
|
const composed = require_dependency_metadata.composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
421
459
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
422
460
|
}
|
|
461
|
+
require_internal_parser.defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
423
462
|
require_internal_parser.defineInheritedAnnotationParser(optionalParser);
|
|
424
463
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
425
464
|
return optionalParser;
|
|
@@ -654,6 +693,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
654
693
|
} });
|
|
655
694
|
if (composed != null) withDefaultParser.dependencyMetadata = composed;
|
|
656
695
|
}
|
|
696
|
+
require_internal_parser.defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
657
697
|
require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
|
|
658
698
|
require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
659
699
|
return withDefaultParser;
|
|
@@ -793,6 +833,7 @@ function map(parser, transform) {
|
|
|
793
833
|
return parser.getDocFragments(state, void 0);
|
|
794
834
|
}
|
|
795
835
|
};
|
|
836
|
+
require_internal_parser.defineParseLanes(mappedParser, require_internal_parser.getOwnParseLanes(parser));
|
|
796
837
|
delete mappedParser.normalizeValue;
|
|
797
838
|
delete mappedParser.validateValue;
|
|
798
839
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
@@ -1509,6 +1550,7 @@ function multiple(parser, options = {}) {
|
|
|
1509
1550
|
function nonEmpty(parser) {
|
|
1510
1551
|
const syncParser = parser;
|
|
1511
1552
|
const initialState = parser.initialState;
|
|
1553
|
+
const consumptionGroup = {};
|
|
1512
1554
|
const processNonEmptyResult = (result) => {
|
|
1513
1555
|
if (!result.success) return result;
|
|
1514
1556
|
if (result.consumed.length === 0) return {
|
|
@@ -1561,6 +1603,17 @@ function nonEmpty(parser) {
|
|
|
1561
1603
|
return syncParser.getDocFragments(state, defaultValue);
|
|
1562
1604
|
}
|
|
1563
1605
|
};
|
|
1606
|
+
require_internal_parser.defineParseLanes(nonEmptyParser, require_internal_parser.getOwnParseLanes(parser)?.map((lane) => ({
|
|
1607
|
+
priority: lane.priority,
|
|
1608
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
1609
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
1610
|
+
leadingNames: lane.leadingNames,
|
|
1611
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
1612
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups ?? [], { id: consumptionGroup }],
|
|
1613
|
+
parse(context) {
|
|
1614
|
+
return lane.parse(context);
|
|
1615
|
+
}
|
|
1616
|
+
})));
|
|
1564
1617
|
if ("placeholder" in parser) Object.defineProperty(nonEmptyParser, "placeholder", {
|
|
1565
1618
|
get() {
|
|
1566
1619
|
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";
|
|
@@ -231,6 +231,44 @@ function processOptionalStyleResult(result, innerState, context) {
|
|
|
231
231
|
};
|
|
232
232
|
return result;
|
|
233
233
|
}
|
|
234
|
+
function adaptOptionalStyleParseLanes(parser) {
|
|
235
|
+
const lanes = getOwnParseLanes(parser);
|
|
236
|
+
if (lanes == null) return void 0;
|
|
237
|
+
const consumptionGroup = {};
|
|
238
|
+
return lanes.map((lane) => ({
|
|
239
|
+
priority: lane.priority,
|
|
240
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
241
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
242
|
+
leadingNames: lane.leadingNames,
|
|
243
|
+
acceptingAnyToken: false,
|
|
244
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups?.map((group) => ({
|
|
245
|
+
id: group.id,
|
|
246
|
+
...group.isActive == null ? {} : { isActive(state) {
|
|
247
|
+
const innerState = Array.isArray(state) ? state[0] : parser.initialState;
|
|
248
|
+
return group.isActive?.(innerState) ?? true;
|
|
249
|
+
} }
|
|
250
|
+
})) ?? [], {
|
|
251
|
+
id: consumptionGroup,
|
|
252
|
+
isActive(state) {
|
|
253
|
+
return Array.isArray(state);
|
|
254
|
+
}
|
|
255
|
+
}],
|
|
256
|
+
parse(context) {
|
|
257
|
+
const innerState = deriveOptionalInnerParseState(context.state, parser);
|
|
258
|
+
const innerContext = {
|
|
259
|
+
...context,
|
|
260
|
+
state: innerState
|
|
261
|
+
};
|
|
262
|
+
return dispatchByMode(parser.mode, () => {
|
|
263
|
+
const result = lane.parse(innerContext);
|
|
264
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
265
|
+
}, async () => {
|
|
266
|
+
const result = await lane.parse(innerContext);
|
|
267
|
+
return processOptionalStyleResult(result, innerState, context);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
234
272
|
/**
|
|
235
273
|
* Creates a `shouldDeferCompletion` adapter that unwraps the outer state
|
|
236
274
|
* shape (`[TState] | undefined`) used by {@link optional} and
|
|
@@ -420,6 +458,7 @@ function optional(parser) {
|
|
|
420
458
|
const composed = composeDependencyMetadata(parser.dependencyMetadata, "optional");
|
|
421
459
|
if (composed != null) optionalParser.dependencyMetadata = composed;
|
|
422
460
|
}
|
|
461
|
+
defineParseLanes(optionalParser, adaptOptionalStyleParseLanes(parser));
|
|
423
462
|
defineInheritedAnnotationParser(optionalParser);
|
|
424
463
|
defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
|
|
425
464
|
return optionalParser;
|
|
@@ -654,6 +693,7 @@ function withDefault(parser, defaultValue, options) {
|
|
|
654
693
|
} });
|
|
655
694
|
if (composed != null) withDefaultParser.dependencyMetadata = composed;
|
|
656
695
|
}
|
|
696
|
+
defineParseLanes(withDefaultParser, adaptOptionalStyleParseLanes(parser));
|
|
657
697
|
defineInheritedAnnotationParser(withDefaultParser);
|
|
658
698
|
defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
|
|
659
699
|
return withDefaultParser;
|
|
@@ -793,6 +833,7 @@ function map(parser, transform) {
|
|
|
793
833
|
return parser.getDocFragments(state, void 0);
|
|
794
834
|
}
|
|
795
835
|
};
|
|
836
|
+
defineParseLanes(mappedParser, getOwnParseLanes(parser));
|
|
796
837
|
delete mappedParser.normalizeValue;
|
|
797
838
|
delete mappedParser.validateValue;
|
|
798
839
|
if ("placeholder" in parser) Object.defineProperty(mappedParser, "placeholder", {
|
|
@@ -1509,6 +1550,7 @@ function multiple(parser, options = {}) {
|
|
|
1509
1550
|
function nonEmpty(parser) {
|
|
1510
1551
|
const syncParser = parser;
|
|
1511
1552
|
const initialState = parser.initialState;
|
|
1553
|
+
const consumptionGroup = {};
|
|
1512
1554
|
const processNonEmptyResult = (result) => {
|
|
1513
1555
|
if (!result.success) return result;
|
|
1514
1556
|
if (result.consumed.length === 0) return {
|
|
@@ -1561,6 +1603,17 @@ function nonEmpty(parser) {
|
|
|
1561
1603
|
return syncParser.getDocFragments(state, defaultValue);
|
|
1562
1604
|
}
|
|
1563
1605
|
};
|
|
1606
|
+
defineParseLanes(nonEmptyParser, getOwnParseLanes(parser)?.map((lane) => ({
|
|
1607
|
+
priority: lane.priority,
|
|
1608
|
+
zeroConsumptionGroup: lane.zeroConsumptionGroup,
|
|
1609
|
+
settlesZeroConsumption: lane.settlesZeroConsumption,
|
|
1610
|
+
leadingNames: lane.leadingNames,
|
|
1611
|
+
acceptingAnyToken: lane.acceptingAnyToken,
|
|
1612
|
+
requiredConsumptionGroups: [...lane.requiredConsumptionGroups ?? [], { id: consumptionGroup }],
|
|
1613
|
+
parse(context) {
|
|
1614
|
+
return lane.parse(context);
|
|
1615
|
+
}
|
|
1616
|
+
})));
|
|
1564
1617
|
if ("placeholder" in parser) Object.defineProperty(nonEmptyParser, "placeholder", {
|
|
1565
1618
|
get() {
|
|
1566
1619
|
return parser.placeholder;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -196,11 +196,11 @@
|
|
|
196
196
|
},
|
|
197
197
|
"sideEffects": false,
|
|
198
198
|
"devDependencies": {
|
|
199
|
+
"@optique/env": "1.1.5",
|
|
199
200
|
"@types/node": "^24.0.0",
|
|
200
201
|
"fast-check": "^4.7.0",
|
|
201
202
|
"tsdown": "^0.13.0",
|
|
202
|
-
"typescript": "^5.8.3"
|
|
203
|
-
"@optique/env": "1.1.4"
|
|
203
|
+
"typescript": "^5.8.3"
|
|
204
204
|
},
|
|
205
205
|
"scripts": {
|
|
206
206
|
"build": "tsdown",
|