@optique/core 1.0.0-dev.1602 → 1.0.0-dev.1611
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 +273 -225
- package/dist/constructs.js +273 -225
- package/dist/dependency-runtime.cjs +328 -0
- package/dist/dependency-runtime.js +323 -0
- package/dist/parser.d.cts +19 -0
- package/dist/parser.d.ts +19 -0
- package/package.json +1 -1
package/dist/constructs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getAnnotations, inheritAnnotations, injectAnnotations } from "./annotations.js";
|
|
2
2
|
import { message, optionName, text, values } from "./message.js";
|
|
3
3
|
import { DependencyRegistry, createDependencySourceState, dependencyId, isDeferredParseState, isDependencySourceState, isPendingDependencySourceState, isWrappedDependencySource, parseWithDependency, wrappedDependencySourceMarker } from "./dependency.js";
|
|
4
|
+
import { buildRuntimeNodesFromPairs, collectExplicitSourceValues, collectSourcesFromState, createDependencyRuntimeContext, resolveStateWithRuntime, resolveStateWithRuntimeAsync } from "./dependency-runtime.js";
|
|
4
5
|
import { dispatchByMode, dispatchIterableByMode } from "./mode-dispatch.js";
|
|
5
6
|
import { validateLabel } from "./validate.js";
|
|
6
7
|
import { extractArgumentMetavars, extractCommandNames, extractOptionNames, isDocHidden, mergeHidden } from "./usage.js";
|
|
@@ -55,6 +56,34 @@ const inheritParentAnnotationsKey = Symbol.for("@optique/core/inheritParentAnnot
|
|
|
55
56
|
*/
|
|
56
57
|
const fieldParsersKey = Symbol("fieldParsers");
|
|
57
58
|
/**
|
|
59
|
+
* Extracts the actual {@link ValueParserResult} from a `complete()` return
|
|
60
|
+
* value, which may be a plain result or a `DependencySourceState` wrapper
|
|
61
|
+
* from the old protocol. This bridge helper allows the new runtime path
|
|
62
|
+
* to consume results from parsers that still return `DependencySourceState`.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
function unwrapCompleteResult(result) {
|
|
66
|
+
if (isDependencySourceState(result)) return result.result;
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Prepares a field state for completion by wrapping `undefined` state
|
|
71
|
+
* with the parser's initial pending dependency state when needed.
|
|
72
|
+
*
|
|
73
|
+
* In the old protocol, when a parser has a `PendingDependencySourceState`
|
|
74
|
+
* as its initial state and the field state is `undefined` (option not
|
|
75
|
+
* provided), the construct wraps it as `[initialState]` so that
|
|
76
|
+
* `withDefault().complete()` can detect the pending dependency and
|
|
77
|
+
* return a `DependencySourceState` with the default value.
|
|
78
|
+
* @internal
|
|
79
|
+
*/
|
|
80
|
+
function prepareStateForCompletion(fieldState, parser) {
|
|
81
|
+
if (fieldState !== void 0) return fieldState;
|
|
82
|
+
if (isPendingDependencySourceState(parser.initialState)) return [parser.initialState];
|
|
83
|
+
if (isWrappedDependencySource(parser)) return [parser[wrappedDependencySourceMarker]];
|
|
84
|
+
return fieldState;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
58
87
|
* Returns the field state with parent annotations inherited, respecting
|
|
59
88
|
* the parser's {@link inheritParentAnnotationsKey} flag. This is the
|
|
60
89
|
* same logic as {@link createFieldStateGetter} inside `object()` but
|
|
@@ -689,12 +718,14 @@ function longestMatch(...args) {
|
|
|
689
718
|
* @internal
|
|
690
719
|
*/
|
|
691
720
|
function* suggestObjectSync(context, prefix, parserPairs) {
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
721
|
+
const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
|
|
722
|
+
const nodes = buildRuntimeNodesFromPairs(parserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
|
|
723
|
+
collectExplicitSourceValues(nodes, runtime);
|
|
724
|
+
if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
|
|
725
|
+
completeDependencySourceDefaults(context, parserPairs, runtime.registry, context.exec);
|
|
695
726
|
const contextWithRegistry = {
|
|
696
727
|
...context,
|
|
697
|
-
dependencyRegistry: registry
|
|
728
|
+
dependencyRegistry: runtime.registry
|
|
698
729
|
};
|
|
699
730
|
if (context.buffer.length > 0) {
|
|
700
731
|
const lastToken = context.buffer[context.buffer.length - 1];
|
|
@@ -723,12 +754,14 @@ function* suggestObjectSync(context, prefix, parserPairs) {
|
|
|
723
754
|
* @internal
|
|
724
755
|
*/
|
|
725
756
|
async function* suggestObjectAsync(context, prefix, parserPairs) {
|
|
726
|
-
const
|
|
727
|
-
|
|
728
|
-
|
|
757
|
+
const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
|
|
758
|
+
const nodes = buildRuntimeNodesFromPairs(parserPairs, context.state && typeof context.state === "object" ? context.state : {}, context.exec?.path);
|
|
759
|
+
collectExplicitSourceValues(nodes, runtime);
|
|
760
|
+
if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
|
|
761
|
+
await completeDependencySourceDefaultsAsync(context, parserPairs, runtime.registry, context.exec);
|
|
729
762
|
const contextWithRegistry = {
|
|
730
763
|
...context,
|
|
731
|
-
dependencyRegistry: registry
|
|
764
|
+
dependencyRegistry: runtime.registry
|
|
732
765
|
};
|
|
733
766
|
if (context.buffer.length > 0) {
|
|
734
767
|
const lastToken = context.buffer[context.buffer.length - 1];
|
|
@@ -846,6 +879,31 @@ async function completeDependencySourceDefaultsAsync(context, parserPairs, regis
|
|
|
846
879
|
* mappings from its child `object()` (or nested `merge()`) parsers.
|
|
847
880
|
* @internal
|
|
848
881
|
*/
|
|
882
|
+
/**
|
|
883
|
+
* Removes entries for duplicate field names from a pre-completed results
|
|
884
|
+
* map. When a child construct's field-parser pairs contain the same field
|
|
885
|
+
* name more than once (e.g., inner merges with overlapping output keys),
|
|
886
|
+
* the flat map collapses branch-specific results. This function strips
|
|
887
|
+
* only the ambiguous entries, preserving cached results for unique fields.
|
|
888
|
+
*
|
|
889
|
+
* Returns `undefined` if the filtered map is empty (no cacheable fields).
|
|
890
|
+
*
|
|
891
|
+
* @see https://github.com/dahlia/optique/issues/762
|
|
892
|
+
* @internal
|
|
893
|
+
*/
|
|
894
|
+
function filterDuplicateKeys(preCompleted, pairs) {
|
|
895
|
+
const counts = /* @__PURE__ */ new Map();
|
|
896
|
+
for (const [field] of pairs) counts.set(field, (counts.get(field) ?? 0) + 1);
|
|
897
|
+
let hasDuplicates = false;
|
|
898
|
+
for (const count of counts.values()) if (count > 1) {
|
|
899
|
+
hasDuplicates = true;
|
|
900
|
+
break;
|
|
901
|
+
}
|
|
902
|
+
if (!hasDuplicates) return preCompleted;
|
|
903
|
+
const filtered = /* @__PURE__ */ new Map();
|
|
904
|
+
for (const [field, value] of preCompleted) if ((counts.get(field) ?? 0) <= 1) filtered.set(field, value);
|
|
905
|
+
return filtered.size > 0 ? filtered : void 0;
|
|
906
|
+
}
|
|
849
907
|
function collectChildFieldParsers(parsers) {
|
|
850
908
|
const pairs = [];
|
|
851
909
|
for (const parser of parsers) if (fieldParsersKey in parser) pairs.push(...parser[fieldParsersKey]);
|
|
@@ -858,45 +916,85 @@ function collectChildFieldParsers(parsers) {
|
|
|
858
916
|
* PendingDependencySourceState in arrays and wrappedDependencySourceMarker.
|
|
859
917
|
*
|
|
860
918
|
* The original state is NOT modified; only the registry is populated.
|
|
919
|
+
*
|
|
920
|
+
* Used by the new dependency runtime path as an old-protocol bridge:
|
|
921
|
+
* not all wrappers (e.g., `bindConfig`, `bindEnv`) compose
|
|
922
|
+
* `dependencyMetadata` yet, so metadata-based source collection alone
|
|
923
|
+
* cannot register all dependency values. This function fills the gap
|
|
924
|
+
* by inspecting old-protocol markers on the parsers.
|
|
861
925
|
* @internal
|
|
862
926
|
*/
|
|
863
927
|
function preCompleteAndRegisterDependencies(state, fieldParserPairs, registry, exec) {
|
|
928
|
+
const preCompleted = /* @__PURE__ */ new Map();
|
|
929
|
+
const parentResults = exec?.preCompletedByParser;
|
|
864
930
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
931
|
+
const cached = parentResults?.get(field);
|
|
932
|
+
if (cached !== void 0) {
|
|
933
|
+
preCompleted.set(field, cached);
|
|
934
|
+
registerCompletedDependency(cached, registry);
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
865
937
|
const fieldState = state[field];
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
938
|
+
if (Array.isArray(fieldState) && fieldState.length === 1 && isPendingDependencySourceState(fieldState[0])) {
|
|
939
|
+
const completed = fieldParser.complete(fieldState, exec);
|
|
940
|
+
preCompleted.set(field, completed);
|
|
941
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
942
|
+
} else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
|
|
943
|
+
const completed = fieldParser.complete([fieldParser.initialState], exec);
|
|
944
|
+
preCompleted.set(field, completed);
|
|
945
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
946
|
+
} else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
|
|
870
947
|
const pendingState = fieldParser[wrappedDependencySourceMarker];
|
|
871
|
-
completed = fieldParser.complete([pendingState], exec);
|
|
948
|
+
const completed = fieldParser.complete([pendingState], exec);
|
|
949
|
+
preCompleted.set(field, completed);
|
|
950
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
872
951
|
} else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
|
|
873
952
|
const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
|
|
874
|
-
completed = fieldParser.complete(annotatedFieldState, exec);
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
953
|
+
const completed = fieldParser.complete(annotatedFieldState, exec);
|
|
954
|
+
preCompleted.set(field, completed);
|
|
955
|
+
const depState = wrapAsDependencySourceState(completed, fieldParser);
|
|
956
|
+
if (depState) registerCompletedDependency(depState, registry);
|
|
957
|
+
}
|
|
878
958
|
}
|
|
959
|
+
return preCompleted;
|
|
879
960
|
}
|
|
880
961
|
/**
|
|
881
962
|
* Async version of {@link preCompleteAndRegisterDependencies}.
|
|
882
963
|
* @internal
|
|
883
964
|
*/
|
|
884
965
|
async function preCompleteAndRegisterDependenciesAsync(state, fieldParserPairs, registry, exec) {
|
|
966
|
+
const preCompleted = /* @__PURE__ */ new Map();
|
|
967
|
+
const parentResults = exec?.preCompletedByParser;
|
|
885
968
|
for (const [field, fieldParser] of fieldParserPairs) {
|
|
969
|
+
const cached = parentResults?.get(field);
|
|
970
|
+
if (cached !== void 0) {
|
|
971
|
+
preCompleted.set(field, cached);
|
|
972
|
+
registerCompletedDependency(cached, registry);
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
886
975
|
const fieldState = state[field];
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
976
|
+
if (Array.isArray(fieldState) && fieldState.length === 1 && isPendingDependencySourceState(fieldState[0])) {
|
|
977
|
+
const completed = await fieldParser.complete(fieldState, exec);
|
|
978
|
+
preCompleted.set(field, completed);
|
|
979
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
980
|
+
} else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
|
|
981
|
+
const completed = await fieldParser.complete([fieldParser.initialState], exec);
|
|
982
|
+
preCompleted.set(field, completed);
|
|
983
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
984
|
+
} else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
|
|
891
985
|
const pendingState = fieldParser[wrappedDependencySourceMarker];
|
|
892
|
-
completed = await fieldParser.complete([pendingState], exec);
|
|
986
|
+
const completed = await fieldParser.complete([pendingState], exec);
|
|
987
|
+
preCompleted.set(field, completed);
|
|
988
|
+
if (isDependencySourceState(completed)) registerCompletedDependency(completed, registry);
|
|
893
989
|
} else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
|
|
894
990
|
const annotatedFieldState = getAnnotatedFieldState(state, field, fieldParser);
|
|
895
|
-
completed = await fieldParser.complete(annotatedFieldState, exec);
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
991
|
+
const completed = await fieldParser.complete(annotatedFieldState, exec);
|
|
992
|
+
preCompleted.set(field, completed);
|
|
993
|
+
const depState = wrapAsDependencySourceState(completed, fieldParser);
|
|
994
|
+
if (depState) registerCompletedDependency(depState, registry);
|
|
995
|
+
}
|
|
899
996
|
}
|
|
997
|
+
return preCompleted;
|
|
900
998
|
}
|
|
901
999
|
/**
|
|
902
1000
|
* Recursively collects dependency values from DependencySourceState objects
|
|
@@ -1240,62 +1338,38 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1240
1338
|
},
|
|
1241
1339
|
complete(state, exec) {
|
|
1242
1340
|
return dispatchByMode(combinedMode, () => {
|
|
1243
|
-
const
|
|
1244
|
-
const
|
|
1341
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
1342
|
+
const childExec = {
|
|
1343
|
+
...exec,
|
|
1344
|
+
dependencyRuntime: runtime
|
|
1345
|
+
};
|
|
1346
|
+
const typedParserPairs = parserPairs;
|
|
1347
|
+
const preCompleted = preCompleteAndRegisterDependencies(state, typedParserPairs, runtime.registry, childExec);
|
|
1348
|
+
const phase3Exec = {
|
|
1349
|
+
...childExec,
|
|
1350
|
+
preCompletedByParser: void 0
|
|
1351
|
+
};
|
|
1245
1352
|
const getFieldState = createFieldStateGetter(state);
|
|
1353
|
+
const annotatedState = {};
|
|
1246
1354
|
for (const field of parserKeys) {
|
|
1247
1355
|
const fieldKey = field;
|
|
1248
|
-
const fieldState = state[fieldKey];
|
|
1249
1356
|
const fieldParser = parsers[field];
|
|
1250
|
-
|
|
1251
|
-
const completed = fieldParser.complete(fieldState, exec);
|
|
1252
|
-
preCompletedState[fieldKey] = completed;
|
|
1253
|
-
preCompletedKeys.add(fieldKey);
|
|
1254
|
-
} else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
|
|
1255
|
-
const completed = fieldParser.complete([fieldParser.initialState], exec);
|
|
1256
|
-
preCompletedState[fieldKey] = completed;
|
|
1257
|
-
preCompletedKeys.add(fieldKey);
|
|
1258
|
-
} else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
|
|
1259
|
-
const pendingState = fieldParser[wrappedDependencySourceMarker];
|
|
1260
|
-
const completed = fieldParser.complete([pendingState], exec);
|
|
1261
|
-
if (isDependencySourceState(completed)) {
|
|
1262
|
-
preCompletedState[fieldKey] = completed;
|
|
1263
|
-
preCompletedKeys.add(fieldKey);
|
|
1264
|
-
} else preCompletedState[fieldKey] = fieldState;
|
|
1265
|
-
} else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
|
|
1266
|
-
const annotatedFieldState = getFieldState(field, fieldParser);
|
|
1267
|
-
const completed = fieldParser.complete(annotatedFieldState, exec);
|
|
1268
|
-
const depState = wrapAsDependencySourceState(completed, fieldParser);
|
|
1269
|
-
if (depState) {
|
|
1270
|
-
preCompletedState[fieldKey] = depState;
|
|
1271
|
-
preCompletedKeys.add(fieldKey);
|
|
1272
|
-
} else preCompletedState[fieldKey] = annotatedFieldState;
|
|
1273
|
-
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1357
|
+
annotatedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1274
1358
|
}
|
|
1275
|
-
const
|
|
1359
|
+
const resolvedFieldStates = resolveStateWithRuntime(annotatedState, runtime);
|
|
1276
1360
|
const result = {};
|
|
1277
1361
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
1278
1362
|
let hasDeferred = false;
|
|
1279
|
-
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1280
1363
|
for (const field of parserKeys) {
|
|
1281
1364
|
const fieldKey = field;
|
|
1282
|
-
const fieldResolvedState = resolvedState[fieldKey];
|
|
1283
1365
|
const fieldParser = parsers[field];
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
else hasDeferred = true;
|
|
1291
|
-
} else return {
|
|
1292
|
-
success: false,
|
|
1293
|
-
error: depResult.error
|
|
1294
|
-
};
|
|
1295
|
-
continue;
|
|
1366
|
+
let valueResult;
|
|
1367
|
+
const preCompletedResult = preCompleted.get(fieldKey);
|
|
1368
|
+
if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
|
|
1369
|
+
else {
|
|
1370
|
+
const fieldState = resolvedFieldStates[fieldKey];
|
|
1371
|
+
valueResult = unwrapCompleteResult(fieldParser.complete(fieldState, phase3Exec));
|
|
1296
1372
|
}
|
|
1297
|
-
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1298
|
-
const valueResult = fieldParser.complete(completionState, exec);
|
|
1299
1373
|
if (valueResult.success) {
|
|
1300
1374
|
result[fieldKey] = valueResult.value;
|
|
1301
1375
|
if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(fieldKey, valueResult.deferredKeys);
|
|
@@ -1316,62 +1390,38 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1316
1390
|
} : {}
|
|
1317
1391
|
};
|
|
1318
1392
|
}, async () => {
|
|
1319
|
-
const
|
|
1320
|
-
const
|
|
1393
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
1394
|
+
const childExec = {
|
|
1395
|
+
...exec,
|
|
1396
|
+
dependencyRuntime: runtime
|
|
1397
|
+
};
|
|
1398
|
+
const asyncParserPairs = parserPairs;
|
|
1399
|
+
const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, asyncParserPairs, runtime.registry, childExec);
|
|
1400
|
+
const phase3Exec = {
|
|
1401
|
+
...childExec,
|
|
1402
|
+
preCompletedByParser: void 0
|
|
1403
|
+
};
|
|
1321
1404
|
const getFieldState = createFieldStateGetter(state);
|
|
1405
|
+
const annotatedState = {};
|
|
1322
1406
|
for (const field of parserKeys) {
|
|
1323
1407
|
const fieldKey = field;
|
|
1324
|
-
const fieldState = state[fieldKey];
|
|
1325
1408
|
const fieldParser = parsers[field];
|
|
1326
|
-
|
|
1327
|
-
const completed = await fieldParser.complete(fieldState, exec);
|
|
1328
|
-
preCompletedState[fieldKey] = completed;
|
|
1329
|
-
preCompletedKeys.add(fieldKey);
|
|
1330
|
-
} else if (fieldState === void 0 && isPendingDependencySourceState(fieldParser.initialState)) {
|
|
1331
|
-
const completed = await fieldParser.complete([fieldParser.initialState], exec);
|
|
1332
|
-
preCompletedState[fieldKey] = completed;
|
|
1333
|
-
preCompletedKeys.add(fieldKey);
|
|
1334
|
-
} else if (fieldState === void 0 && isWrappedDependencySource(fieldParser)) {
|
|
1335
|
-
const pendingState = fieldParser[wrappedDependencySourceMarker];
|
|
1336
|
-
const completed = await fieldParser.complete([pendingState], exec);
|
|
1337
|
-
if (isDependencySourceState(completed)) {
|
|
1338
|
-
preCompletedState[fieldKey] = completed;
|
|
1339
|
-
preCompletedKeys.add(fieldKey);
|
|
1340
|
-
} else preCompletedState[fieldKey] = fieldState;
|
|
1341
|
-
} else if (fieldState != null && !Array.isArray(fieldState) && !isDependencySourceState(fieldState) && (isWrappedDependencySource(fieldParser) || isPendingDependencySourceState(fieldParser.initialState))) {
|
|
1342
|
-
const annotatedFieldState = getFieldState(field, fieldParser);
|
|
1343
|
-
const completed = await fieldParser.complete(annotatedFieldState, exec);
|
|
1344
|
-
const depState = wrapAsDependencySourceState(completed, fieldParser);
|
|
1345
|
-
if (depState) {
|
|
1346
|
-
preCompletedState[fieldKey] = depState;
|
|
1347
|
-
preCompletedKeys.add(fieldKey);
|
|
1348
|
-
} else preCompletedState[fieldKey] = annotatedFieldState;
|
|
1349
|
-
} else preCompletedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1409
|
+
annotatedState[fieldKey] = getFieldState(field, fieldParser);
|
|
1350
1410
|
}
|
|
1351
|
-
const
|
|
1411
|
+
const resolvedFieldStates = await resolveStateWithRuntimeAsync(annotatedState, runtime);
|
|
1352
1412
|
const result = {};
|
|
1353
1413
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
1354
1414
|
let hasDeferred = false;
|
|
1355
|
-
const getCompletionFieldState = createFieldStateGetter(state);
|
|
1356
1415
|
for (const field of parserKeys) {
|
|
1357
1416
|
const fieldKey = field;
|
|
1358
|
-
const fieldResolvedState = resolvedState[fieldKey];
|
|
1359
1417
|
const fieldParser = parsers[field];
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
else hasDeferred = true;
|
|
1367
|
-
} else return {
|
|
1368
|
-
success: false,
|
|
1369
|
-
error: depResult.error
|
|
1370
|
-
};
|
|
1371
|
-
continue;
|
|
1418
|
+
let valueResult;
|
|
1419
|
+
const preCompletedResult = preCompleted.get(fieldKey);
|
|
1420
|
+
if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
|
|
1421
|
+
else {
|
|
1422
|
+
const fieldState = resolvedFieldStates[fieldKey];
|
|
1423
|
+
valueResult = unwrapCompleteResult(await fieldParser.complete(fieldState, phase3Exec));
|
|
1372
1424
|
}
|
|
1373
|
-
const completionState = fieldResolvedState === void 0 ? getCompletionFieldState(field, fieldParser) : fieldResolvedState;
|
|
1374
|
-
const valueResult = await fieldParser.complete(completionState, exec);
|
|
1375
1425
|
if (valueResult.success) {
|
|
1376
1426
|
result[fieldKey] = valueResult.value;
|
|
1377
1427
|
if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(fieldKey, valueResult.deferredKeys);
|
|
@@ -1635,48 +1685,31 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1635
1685
|
complete(state, exec) {
|
|
1636
1686
|
return dispatchByMode(combinedMode, () => {
|
|
1637
1687
|
const stateArray = state;
|
|
1638
|
-
const
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
preCompletedState[i] = completed;
|
|
1652
|
-
} else preCompletedState[i] = elementState;
|
|
1653
|
-
}
|
|
1654
|
-
const resolvedState = resolveDeferredParseStates(preCompletedState);
|
|
1655
|
-
const resolvedArray = resolvedState;
|
|
1688
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
1689
|
+
const childExec = {
|
|
1690
|
+
...exec,
|
|
1691
|
+
dependencyRuntime: runtime
|
|
1692
|
+
};
|
|
1693
|
+
const tuplePairs = syncParsers.map((p, i) => [String(i), p]);
|
|
1694
|
+
const tupleState = Object.fromEntries(stateArray.map((s, i) => [String(i), s]));
|
|
1695
|
+
const preCompleted = preCompleteAndRegisterDependencies(tupleState, tuplePairs, runtime.registry, childExec);
|
|
1696
|
+
const phase3Exec = {
|
|
1697
|
+
...childExec,
|
|
1698
|
+
preCompletedByParser: void 0
|
|
1699
|
+
};
|
|
1700
|
+
const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
|
|
1656
1701
|
const result = [];
|
|
1657
1702
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
1658
1703
|
let hasDeferred = false;
|
|
1659
1704
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
1660
|
-
const elementResolvedState = resolvedArray[i];
|
|
1661
1705
|
const elementParser = syncParsers[i];
|
|
1662
|
-
|
|
1663
|
-
const
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
if (depResult.success) {
|
|
1669
|
-
result[i] = depResult.value;
|
|
1670
|
-
if (depResult.deferred) if (depResult.deferredKeys) deferredKeys.set(i, depResult.deferredKeys);
|
|
1671
|
-
else if (depResult.value == null || typeof depResult.value !== "object") deferredKeys.set(i, null);
|
|
1672
|
-
else hasDeferred = true;
|
|
1673
|
-
} else return {
|
|
1674
|
-
success: false,
|
|
1675
|
-
error: depResult.error
|
|
1676
|
-
};
|
|
1677
|
-
continue;
|
|
1706
|
+
let valueResult;
|
|
1707
|
+
const preCompletedResult = preCompleted.get(String(i));
|
|
1708
|
+
if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
|
|
1709
|
+
else {
|
|
1710
|
+
const elementState = prepareStateForCompletion(resolvedArray[i], elementParser);
|
|
1711
|
+
valueResult = unwrapCompleteResult(elementParser.complete(elementState, phase3Exec));
|
|
1678
1712
|
}
|
|
1679
|
-
const valueResult = elementParser.complete(elementResolvedState, exec);
|
|
1680
1713
|
if (valueResult.success) {
|
|
1681
1714
|
result[i] = valueResult.value;
|
|
1682
1715
|
if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(i, valueResult.deferredKeys);
|
|
@@ -1698,48 +1731,31 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
|
|
|
1698
1731
|
};
|
|
1699
1732
|
}, async () => {
|
|
1700
1733
|
const stateArray = state;
|
|
1701
|
-
const
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
preCompletedState[i] = completed;
|
|
1715
|
-
} else preCompletedState[i] = elementState;
|
|
1716
|
-
}
|
|
1717
|
-
const resolvedState = await resolveDeferredParseStatesAsync(preCompletedState);
|
|
1718
|
-
const resolvedArray = resolvedState;
|
|
1734
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
1735
|
+
const childExec = {
|
|
1736
|
+
...exec,
|
|
1737
|
+
dependencyRuntime: runtime
|
|
1738
|
+
};
|
|
1739
|
+
const tuplePairs = parsers.map((p, i) => [String(i), p]);
|
|
1740
|
+
const tupleState = Object.fromEntries(stateArray.map((s, i) => [String(i), s]));
|
|
1741
|
+
const preCompleted = await preCompleteAndRegisterDependenciesAsync(tupleState, tuplePairs, runtime.registry, childExec);
|
|
1742
|
+
const phase3Exec = {
|
|
1743
|
+
...childExec,
|
|
1744
|
+
preCompletedByParser: void 0
|
|
1745
|
+
};
|
|
1746
|
+
const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
|
|
1719
1747
|
const result = [];
|
|
1720
1748
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
1721
1749
|
let hasDeferred = false;
|
|
1722
1750
|
for (let i = 0; i < parsers.length; i++) {
|
|
1723
|
-
const elementResolvedState = resolvedArray[i];
|
|
1724
1751
|
const elementParser = parsers[i];
|
|
1725
|
-
|
|
1726
|
-
const
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
if (depResult.success) {
|
|
1732
|
-
result[i] = depResult.value;
|
|
1733
|
-
if (depResult.deferred) if (depResult.deferredKeys) deferredKeys.set(i, depResult.deferredKeys);
|
|
1734
|
-
else if (depResult.value == null || typeof depResult.value !== "object") deferredKeys.set(i, null);
|
|
1735
|
-
else hasDeferred = true;
|
|
1736
|
-
} else return {
|
|
1737
|
-
success: false,
|
|
1738
|
-
error: depResult.error
|
|
1739
|
-
};
|
|
1740
|
-
continue;
|
|
1752
|
+
let valueResult;
|
|
1753
|
+
const preCompletedResult = preCompleted.get(String(i));
|
|
1754
|
+
if (preCompletedResult !== void 0) valueResult = unwrapCompleteResult(preCompletedResult);
|
|
1755
|
+
else {
|
|
1756
|
+
const elementState = prepareStateForCompletion(resolvedArray[i], elementParser);
|
|
1757
|
+
valueResult = unwrapCompleteResult(await elementParser.complete(elementState, phase3Exec));
|
|
1741
1758
|
}
|
|
1742
|
-
const valueResult = await elementParser.complete(elementResolvedState, exec);
|
|
1743
1759
|
if (valueResult.success) {
|
|
1744
1760
|
result[i] = valueResult.value;
|
|
1745
1761
|
if (valueResult.deferred) if (valueResult.deferredKeys) deferredKeys.set(i, valueResult.deferredKeys);
|
|
@@ -1999,20 +2015,35 @@ function merge(...args) {
|
|
|
1999
2015
|
return parser.initialState;
|
|
2000
2016
|
};
|
|
2001
2017
|
if (!isAsync) {
|
|
2002
|
-
const
|
|
2003
|
-
const
|
|
2004
|
-
|
|
2005
|
-
|
|
2018
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
2019
|
+
const childExec = {
|
|
2020
|
+
...exec,
|
|
2021
|
+
dependencyRuntime: runtime
|
|
2022
|
+
};
|
|
2023
|
+
const perChildCache = syncParsers.map((parser) => {
|
|
2024
|
+
if (fieldParsersKey in parser) {
|
|
2025
|
+
const pairs = parser[fieldParsersKey];
|
|
2026
|
+
const preCompleted = preCompleteAndRegisterDependencies(state, pairs, runtime.registry, childExec);
|
|
2027
|
+
return filterDuplicateKeys(preCompleted, pairs);
|
|
2028
|
+
}
|
|
2029
|
+
return void 0;
|
|
2030
|
+
});
|
|
2031
|
+
const resolvedState = resolveStateWithRuntime(state, runtime);
|
|
2006
2032
|
const object$1 = {};
|
|
2007
2033
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
2008
2034
|
let hasDeferred = false;
|
|
2009
2035
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
2010
2036
|
const parser = syncParsers[i];
|
|
2011
2037
|
const parserState = extractCompleteState(parser, resolvedState, i);
|
|
2012
|
-
const
|
|
2038
|
+
const cache = perChildCache[i];
|
|
2039
|
+
const result = unwrapCompleteResult(parser.complete(parserState, {
|
|
2040
|
+
...childExec,
|
|
2041
|
+
preCompletedByParser: cache
|
|
2042
|
+
}));
|
|
2013
2043
|
if (!result.success) return result;
|
|
2014
|
-
|
|
2015
|
-
|
|
2044
|
+
const resultValue = result.value;
|
|
2045
|
+
for (const field in resultValue) {
|
|
2046
|
+
object$1[field] = resultValue[field];
|
|
2016
2047
|
if (deferredKeys.has(field) && !(result.deferred && result.deferredKeys?.has(field))) deferredKeys.delete(field);
|
|
2017
2048
|
}
|
|
2018
2049
|
if (result.deferred && result.deferredKeys) for (const [key, value] of result.deferredKeys) deferredKeys.set(key, value);
|
|
@@ -2029,20 +2060,33 @@ function merge(...args) {
|
|
|
2029
2060
|
};
|
|
2030
2061
|
}
|
|
2031
2062
|
return (async () => {
|
|
2032
|
-
const
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2063
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
2064
|
+
const childExec = {
|
|
2065
|
+
...exec,
|
|
2066
|
+
dependencyRuntime: runtime
|
|
2067
|
+
};
|
|
2068
|
+
const perChildCache = [];
|
|
2069
|
+
for (const parser of parsers) if (fieldParsersKey in parser) {
|
|
2070
|
+
const pairs = parser[fieldParsersKey];
|
|
2071
|
+
const preCompleted = await preCompleteAndRegisterDependenciesAsync(state, pairs, runtime.registry, childExec);
|
|
2072
|
+
perChildCache.push(filterDuplicateKeys(preCompleted, pairs));
|
|
2073
|
+
} else perChildCache.push(void 0);
|
|
2074
|
+
const resolvedState = await resolveStateWithRuntimeAsync(state, runtime);
|
|
2036
2075
|
const object$1 = {};
|
|
2037
2076
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
2038
2077
|
let hasDeferred = false;
|
|
2039
2078
|
for (let i = 0; i < parsers.length; i++) {
|
|
2040
2079
|
const parser = parsers[i];
|
|
2041
2080
|
const parserState = extractCompleteState(parser, resolvedState, i);
|
|
2042
|
-
const
|
|
2081
|
+
const asyncCache = perChildCache[i];
|
|
2082
|
+
const result = unwrapCompleteResult(await parser.complete(parserState, {
|
|
2083
|
+
...childExec,
|
|
2084
|
+
preCompletedByParser: asyncCache
|
|
2085
|
+
}));
|
|
2043
2086
|
if (!result.success) return result;
|
|
2044
|
-
|
|
2045
|
-
|
|
2087
|
+
const resultValue = result.value;
|
|
2088
|
+
for (const field in resultValue) {
|
|
2089
|
+
object$1[field] = resultValue[field];
|
|
2046
2090
|
if (deferredKeys.has(field) && !(result.deferred && result.deferredKeys?.has(field))) deferredKeys.delete(field);
|
|
2047
2091
|
}
|
|
2048
2092
|
if (result.deferred && result.deferredKeys) for (const [key, value] of result.deferredKeys) deferredKeys.set(key, value);
|
|
@@ -2077,15 +2121,13 @@ function merge(...args) {
|
|
|
2077
2121
|
return p.initialState;
|
|
2078
2122
|
};
|
|
2079
2123
|
if (isAsync) return async function* () {
|
|
2080
|
-
const
|
|
2124
|
+
const runtime$1 = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
|
|
2081
2125
|
const childFieldPairs$1 = collectChildFieldParsers(parsers);
|
|
2082
|
-
if (context.state && typeof context.state === "object")
|
|
2083
|
-
|
|
2084
|
-
collectDependencies(context.state, registry$1);
|
|
2085
|
-
} else await completeDependencySourceDefaultsAsync(context, childFieldPairs$1, registry$1, context.exec);
|
|
2126
|
+
if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime$1);
|
|
2127
|
+
await completeDependencySourceDefaultsAsync(context, childFieldPairs$1, runtime$1.registry, context.exec);
|
|
2086
2128
|
const contextWithRegistry$1 = {
|
|
2087
2129
|
...context,
|
|
2088
|
-
dependencyRegistry:
|
|
2130
|
+
dependencyRegistry: runtime$1.registry
|
|
2089
2131
|
};
|
|
2090
2132
|
const suggestions = [];
|
|
2091
2133
|
for (let i = 0; i < parsers.length; i++) {
|
|
@@ -2100,15 +2142,13 @@ function merge(...args) {
|
|
|
2100
2142
|
}
|
|
2101
2143
|
yield* deduplicateSuggestions(suggestions);
|
|
2102
2144
|
}();
|
|
2103
|
-
const
|
|
2145
|
+
const runtime = createDependencyRuntimeContext(context.dependencyRegistry?.clone());
|
|
2104
2146
|
const childFieldPairs = collectChildFieldParsers(syncParsers);
|
|
2105
|
-
if (context.state && typeof context.state === "object")
|
|
2106
|
-
|
|
2107
|
-
collectDependencies(context.state, registry);
|
|
2108
|
-
} else completeDependencySourceDefaults(context, childFieldPairs, registry, context.exec);
|
|
2147
|
+
if (context.state && typeof context.state === "object") collectSourcesFromState(context.state, runtime);
|
|
2148
|
+
completeDependencySourceDefaults(context, childFieldPairs, runtime.registry, context.exec);
|
|
2109
2149
|
const contextWithRegistry = {
|
|
2110
2150
|
...context,
|
|
2111
|
-
dependencyRegistry: registry
|
|
2151
|
+
dependencyRegistry: runtime.registry
|
|
2112
2152
|
};
|
|
2113
2153
|
return function* () {
|
|
2114
2154
|
const suggestions = [];
|
|
@@ -2195,12 +2235,12 @@ function merge(...args) {
|
|
|
2195
2235
|
*/
|
|
2196
2236
|
function buildSuggestRegistry(preParsedContext) {
|
|
2197
2237
|
const stateArray = preParsedContext.state;
|
|
2198
|
-
const
|
|
2199
|
-
if (stateArray && Array.isArray(stateArray))
|
|
2238
|
+
const runtime = createDependencyRuntimeContext(preParsedContext.dependencyRegistry?.clone());
|
|
2239
|
+
if (stateArray && Array.isArray(stateArray)) collectSourcesFromState(stateArray, runtime);
|
|
2200
2240
|
return {
|
|
2201
2241
|
context: {
|
|
2202
2242
|
...preParsedContext,
|
|
2203
|
-
dependencyRegistry: registry
|
|
2243
|
+
dependencyRegistry: runtime.registry
|
|
2204
2244
|
},
|
|
2205
2245
|
stateArray
|
|
2206
2246
|
};
|
|
@@ -2432,16 +2472,20 @@ function concat(...parsers) {
|
|
|
2432
2472
|
};
|
|
2433
2473
|
const completeSync = (state, exec) => {
|
|
2434
2474
|
const stateArray = state;
|
|
2435
|
-
const
|
|
2436
|
-
|
|
2437
|
-
|
|
2475
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
2476
|
+
const childExec = {
|
|
2477
|
+
...exec,
|
|
2478
|
+
dependencyRuntime: runtime,
|
|
2479
|
+
preCompletedByParser: void 0
|
|
2480
|
+
};
|
|
2481
|
+
const resolvedArray = resolveStateWithRuntime(stateArray, runtime);
|
|
2438
2482
|
const results = [];
|
|
2439
2483
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
2440
2484
|
let hasDeferred = false;
|
|
2441
2485
|
for (let i = 0; i < syncParsers.length; i++) {
|
|
2442
2486
|
const parser = syncParsers[i];
|
|
2443
|
-
const parserState =
|
|
2444
|
-
const result = parser.complete(parserState,
|
|
2487
|
+
const parserState = prepareStateForCompletion(resolvedArray[i], parser);
|
|
2488
|
+
const result = unwrapCompleteResult(parser.complete(parserState, childExec));
|
|
2445
2489
|
if (!result.success) return result;
|
|
2446
2490
|
const baseIndex = results.length;
|
|
2447
2491
|
if (Array.isArray(result.value)) {
|
|
@@ -2471,16 +2515,20 @@ function concat(...parsers) {
|
|
|
2471
2515
|
};
|
|
2472
2516
|
const completeAsync = async (state, exec) => {
|
|
2473
2517
|
const stateArray = state;
|
|
2474
|
-
const
|
|
2475
|
-
|
|
2476
|
-
|
|
2518
|
+
const runtime = exec?.dependencyRuntime ?? createDependencyRuntimeContext(exec?.dependencyRegistry);
|
|
2519
|
+
const childExec = {
|
|
2520
|
+
...exec,
|
|
2521
|
+
dependencyRuntime: runtime,
|
|
2522
|
+
preCompletedByParser: void 0
|
|
2523
|
+
};
|
|
2524
|
+
const resolvedArray = await resolveStateWithRuntimeAsync(stateArray, runtime);
|
|
2477
2525
|
const results = [];
|
|
2478
2526
|
const deferredKeys = /* @__PURE__ */ new Map();
|
|
2479
2527
|
let hasDeferred = false;
|
|
2480
2528
|
for (let i = 0; i < parsers.length; i++) {
|
|
2481
2529
|
const parser = parsers[i];
|
|
2482
|
-
const parserState =
|
|
2483
|
-
const result = await parser.complete(parserState,
|
|
2530
|
+
const parserState = prepareStateForCompletion(resolvedArray[i], parser);
|
|
2531
|
+
const result = unwrapCompleteResult(await parser.complete(parserState, childExec));
|
|
2484
2532
|
if (!result.success) return result;
|
|
2485
2533
|
const baseIndex = results.length;
|
|
2486
2534
|
if (Array.isArray(result.value)) {
|