@jsenv/navi 0.16.12 → 0.16.13
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/jsenv_navi.js +326 -27
- package/dist/jsenv_navi.js.map +3 -3
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -804,9 +804,9 @@ const weakEffect = (values, callback) => {
|
|
|
804
804
|
|
|
805
805
|
const SYMBOL_OBJECT_SIGNAL = Symbol.for("navi_object_signal");
|
|
806
806
|
|
|
807
|
-
let DEBUG$
|
|
807
|
+
let DEBUG$3 = false;
|
|
808
808
|
const enableDebugActions = () => {
|
|
809
|
-
DEBUG$
|
|
809
|
+
DEBUG$3 = true;
|
|
810
810
|
};
|
|
811
811
|
|
|
812
812
|
let dispatchActions = (params) => {
|
|
@@ -870,7 +870,7 @@ const prerunProtectionRegistry = (() => {
|
|
|
870
870
|
if (protection) {
|
|
871
871
|
clearTimeout(protection.timeoutId);
|
|
872
872
|
protectedActionMap.delete(action);
|
|
873
|
-
if (DEBUG$
|
|
873
|
+
if (DEBUG$3) {
|
|
874
874
|
const elapsed = Date.now() - protection.timestamp;
|
|
875
875
|
console.debug(`"${action}": GC protection removed after ${elapsed}ms`);
|
|
876
876
|
}
|
|
@@ -888,7 +888,7 @@ const prerunProtectionRegistry = (() => {
|
|
|
888
888
|
const timestamp = Date.now();
|
|
889
889
|
const timeoutId = setTimeout(() => {
|
|
890
890
|
unprotect(action);
|
|
891
|
-
if (DEBUG$
|
|
891
|
+
if (DEBUG$3) {
|
|
892
892
|
console.debug(
|
|
893
893
|
`"${action}": prerun protection expired after ${PROTECTION_DURATION}ms`,
|
|
894
894
|
);
|
|
@@ -897,7 +897,7 @@ const prerunProtectionRegistry = (() => {
|
|
|
897
897
|
|
|
898
898
|
protectedActionMap.set(action, { timeoutId, timestamp });
|
|
899
899
|
|
|
900
|
-
if (DEBUG$
|
|
900
|
+
if (DEBUG$3) {
|
|
901
901
|
console.debug(
|
|
902
902
|
`"${action}": protected from GC for ${PROTECTION_DURATION}ms`,
|
|
903
903
|
);
|
|
@@ -1008,7 +1008,7 @@ const updateActions = ({
|
|
|
1008
1008
|
|
|
1009
1009
|
const { runningSet, settledSet } = getActivationInfo();
|
|
1010
1010
|
|
|
1011
|
-
if (DEBUG$
|
|
1011
|
+
if (DEBUG$3) {
|
|
1012
1012
|
let argSource = `reason: \`${reason}\``;
|
|
1013
1013
|
if (isReplace) {
|
|
1014
1014
|
argSource += `, isReplace: true`;
|
|
@@ -1132,7 +1132,7 @@ ${lines.join("\n")}`,
|
|
|
1132
1132
|
}
|
|
1133
1133
|
}
|
|
1134
1134
|
}
|
|
1135
|
-
if (DEBUG$
|
|
1135
|
+
if (DEBUG$3) {
|
|
1136
1136
|
const lines = [
|
|
1137
1137
|
...(willResetSet.size
|
|
1138
1138
|
? [formatActionSet(willResetSet, "- will reset:")]
|
|
@@ -1228,7 +1228,7 @@ ${lines.join("\n")}`);
|
|
|
1228
1228
|
actionToPromotePrivateProperties.isPrerunSignal.value = false;
|
|
1229
1229
|
}
|
|
1230
1230
|
}
|
|
1231
|
-
if (DEBUG$
|
|
1231
|
+
if (DEBUG$3) {
|
|
1232
1232
|
console.groupEnd();
|
|
1233
1233
|
}
|
|
1234
1234
|
|
|
@@ -1339,7 +1339,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1339
1339
|
if (!actionAbort) {
|
|
1340
1340
|
return false;
|
|
1341
1341
|
}
|
|
1342
|
-
if (DEBUG$
|
|
1342
|
+
if (DEBUG$3) {
|
|
1343
1343
|
console.log(`"${action}": aborting (reason: ${reason})`);
|
|
1344
1344
|
}
|
|
1345
1345
|
actionAbort(reason);
|
|
@@ -1611,7 +1611,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1611
1611
|
if (isPrerun && (globalAbortSignal.aborted || abortSignal.aborted)) {
|
|
1612
1612
|
prerunProtectionRegistry.unprotect(action);
|
|
1613
1613
|
}
|
|
1614
|
-
if (DEBUG$
|
|
1614
|
+
if (DEBUG$3) {
|
|
1615
1615
|
console.log(`"${action}": aborted (reason: ${abortReason})`);
|
|
1616
1616
|
}
|
|
1617
1617
|
};
|
|
@@ -1684,7 +1684,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1684
1684
|
onComplete?.(computedDataSignal.peek(), action);
|
|
1685
1685
|
completeSideEffect?.(action);
|
|
1686
1686
|
});
|
|
1687
|
-
if (DEBUG$
|
|
1687
|
+
if (DEBUG$3) {
|
|
1688
1688
|
console.log(`"${action}": completed`);
|
|
1689
1689
|
}
|
|
1690
1690
|
return computedDataSignal.peek();
|
|
@@ -1711,7 +1711,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1711
1711
|
"never supposed to happen, abort error should be handled by the abort signal",
|
|
1712
1712
|
);
|
|
1713
1713
|
}
|
|
1714
|
-
if (DEBUG$
|
|
1714
|
+
if (DEBUG$3) {
|
|
1715
1715
|
console.log(
|
|
1716
1716
|
`"${action}": failed (error: ${e}, handled by ui: ${ui.hasRenderers})`,
|
|
1717
1717
|
);
|
|
@@ -1781,7 +1781,7 @@ const createAction = (callback, rootOptions = {}) => {
|
|
|
1781
1781
|
|
|
1782
1782
|
const performStop = ({ reason }) => {
|
|
1783
1783
|
abort(reason);
|
|
1784
|
-
if (DEBUG$
|
|
1784
|
+
if (DEBUG$3) {
|
|
1785
1785
|
console.log(`"${action}": stopping (reason: ${reason})`);
|
|
1786
1786
|
}
|
|
1787
1787
|
|
|
@@ -7608,6 +7608,9 @@ const buildQueryString = (params) => {
|
|
|
7608
7608
|
return searchParamPairs.join("&");
|
|
7609
7609
|
};
|
|
7610
7610
|
|
|
7611
|
+
const DEBUG$2 =
|
|
7612
|
+
typeof process === "object" ? process.env.DEBUG === "true" : false;
|
|
7613
|
+
|
|
7611
7614
|
// Base URL management
|
|
7612
7615
|
let baseFileUrl;
|
|
7613
7616
|
let baseUrl;
|
|
@@ -7713,6 +7716,11 @@ const createRoutePattern = (pattern) => {
|
|
|
7713
7716
|
|
|
7714
7717
|
const parsedPattern = parsePattern(cleanPattern, parameterDefaults);
|
|
7715
7718
|
|
|
7719
|
+
if (DEBUG$2) {
|
|
7720
|
+
console.debug(`[CustomPattern] Created pattern:`, parsedPattern);
|
|
7721
|
+
console.debug(`[CustomPattern] Signal connections:`, connections);
|
|
7722
|
+
}
|
|
7723
|
+
|
|
7716
7724
|
const applyOn = (url) => {
|
|
7717
7725
|
const result = matchUrl(parsedPattern, url, {
|
|
7718
7726
|
parameterDefaults,
|
|
@@ -7720,6 +7728,13 @@ const createRoutePattern = (pattern) => {
|
|
|
7720
7728
|
connections,
|
|
7721
7729
|
});
|
|
7722
7730
|
|
|
7731
|
+
if (DEBUG$2) {
|
|
7732
|
+
console.debug(
|
|
7733
|
+
`[CustomPattern] Matching "${url}" against "${cleanPattern}":`,
|
|
7734
|
+
result,
|
|
7735
|
+
);
|
|
7736
|
+
}
|
|
7737
|
+
|
|
7723
7738
|
return result;
|
|
7724
7739
|
};
|
|
7725
7740
|
|
|
@@ -7806,6 +7821,13 @@ const createRoutePattern = (pattern) => {
|
|
|
7806
7821
|
const childParams = {};
|
|
7807
7822
|
let isCompatible = true;
|
|
7808
7823
|
|
|
7824
|
+
if (DEBUG$2) {
|
|
7825
|
+
console.debug(
|
|
7826
|
+
`[${pattern}] Checking compatibility with child: ${childPatternObj.originalPattern}`,
|
|
7827
|
+
);
|
|
7828
|
+
console.debug(`[${pattern}] Params passed to buildUrl:`, params);
|
|
7829
|
+
}
|
|
7830
|
+
|
|
7809
7831
|
// CRITICAL: Check if parent route can reach all child route's literal segments
|
|
7810
7832
|
// A route can only optimize to a descendant if there's a viable path through parameters
|
|
7811
7833
|
// to reach all the descendant's literal segments (e.g., "/" cannot reach "/admin"
|
|
@@ -7831,6 +7853,12 @@ const createRoutePattern = (pattern) => {
|
|
|
7831
7853
|
// Same literal - no problem
|
|
7832
7854
|
continue;
|
|
7833
7855
|
}
|
|
7856
|
+
// Different literal - incompatible
|
|
7857
|
+
if (DEBUG$2) {
|
|
7858
|
+
console.debug(
|
|
7859
|
+
`[${pattern}] INCOMPATIBLE with ${childPatternObj.originalPattern}: conflicting literal "${parentSegmentAtPosition.value}" vs "${literalValue}" at position ${childPosition}`,
|
|
7860
|
+
);
|
|
7861
|
+
}
|
|
7834
7862
|
return { isCompatible: false, childParams: {} };
|
|
7835
7863
|
}
|
|
7836
7864
|
if (parentSegmentAtPosition.type === "param") {
|
|
@@ -7842,6 +7870,11 @@ const createRoutePattern = (pattern) => {
|
|
|
7842
7870
|
// Parent doesn't have a segment at this position - child extends beyond parent
|
|
7843
7871
|
// Check if any available parameter can produce this literal value
|
|
7844
7872
|
else if (!canReachLiteralValue(literalValue, params)) {
|
|
7873
|
+
if (DEBUG$2) {
|
|
7874
|
+
console.debug(
|
|
7875
|
+
`[${pattern}] INCOMPATIBLE with ${childPatternObj.originalPattern}: cannot reach literal segment "${literalValue}" at position ${childPosition} - no viable parameter path`,
|
|
7876
|
+
);
|
|
7877
|
+
}
|
|
7845
7878
|
return { isCompatible: false, childParams: {} };
|
|
7846
7879
|
}
|
|
7847
7880
|
}
|
|
@@ -7862,8 +7895,19 @@ const createRoutePattern = (pattern) => {
|
|
|
7862
7895
|
childPatternObj.pattern,
|
|
7863
7896
|
);
|
|
7864
7897
|
|
|
7898
|
+
if (DEBUG$2) {
|
|
7899
|
+
console.debug(
|
|
7900
|
+
`[${pattern}] Processing param '${item.paramName}' (userProvided: ${item.isUserProvided}, value: ${item.isUserProvided ? item.userValue : item.signal?.value}) for child ${childPatternObj.originalPattern}: compatible=${result.isCompatible}, shouldInclude=${result.shouldInclude}`,
|
|
7901
|
+
);
|
|
7902
|
+
}
|
|
7903
|
+
|
|
7865
7904
|
if (!result.isCompatible) {
|
|
7866
7905
|
isCompatible = false;
|
|
7906
|
+
if (DEBUG$2) {
|
|
7907
|
+
console.debug(
|
|
7908
|
+
`[${pattern}] Child ${childPatternObj.originalPattern} INCOMPATIBLE due to param '${item.paramName}'`,
|
|
7909
|
+
);
|
|
7910
|
+
}
|
|
7867
7911
|
break;
|
|
7868
7912
|
}
|
|
7869
7913
|
|
|
@@ -7872,6 +7916,12 @@ const createRoutePattern = (pattern) => {
|
|
|
7872
7916
|
}
|
|
7873
7917
|
}
|
|
7874
7918
|
|
|
7919
|
+
if (DEBUG$2) {
|
|
7920
|
+
console.debug(
|
|
7921
|
+
`[${pattern}] Final compatibility result for ${childPatternObj.originalPattern}: ${isCompatible}`,
|
|
7922
|
+
);
|
|
7923
|
+
}
|
|
7924
|
+
|
|
7875
7925
|
return { isCompatible, childParams };
|
|
7876
7926
|
};
|
|
7877
7927
|
|
|
@@ -7999,6 +8049,13 @@ const createRoutePattern = (pattern) => {
|
|
|
7999
8049
|
);
|
|
8000
8050
|
|
|
8001
8051
|
if (signalMatchesThisChildLiteral) {
|
|
8052
|
+
// This child route's literal matches the sibling's signal value
|
|
8053
|
+
// User passed undefined to override that signal - don't use this child route
|
|
8054
|
+
if (DEBUG$2) {
|
|
8055
|
+
console.debug(
|
|
8056
|
+
`[${pattern}] Blocking child route ${childPatternObj.originalPattern} because ${paramName}:undefined overrides sibling signal value "${signalValue}"`,
|
|
8057
|
+
);
|
|
8058
|
+
}
|
|
8002
8059
|
return false;
|
|
8003
8060
|
}
|
|
8004
8061
|
}
|
|
@@ -8060,6 +8117,12 @@ const createRoutePattern = (pattern) => {
|
|
|
8060
8117
|
const shouldUse =
|
|
8061
8118
|
hasActiveParams || (hasProvidedParams && canBuildChildCompletely);
|
|
8062
8119
|
|
|
8120
|
+
if (DEBUG$2 && shouldUse) {
|
|
8121
|
+
console.debug(
|
|
8122
|
+
`[${pattern}] Will use child route ${childPatternObj.originalPattern}`,
|
|
8123
|
+
);
|
|
8124
|
+
}
|
|
8125
|
+
|
|
8063
8126
|
return shouldUse;
|
|
8064
8127
|
};
|
|
8065
8128
|
|
|
@@ -8221,6 +8284,9 @@ const createRoutePattern = (pattern) => {
|
|
|
8221
8284
|
};
|
|
8222
8285
|
|
|
8223
8286
|
const buildMostPreciseUrl = (params = {}) => {
|
|
8287
|
+
if (DEBUG$2) {
|
|
8288
|
+
console.debug(`[${pattern}] buildMostPreciseUrl called`);
|
|
8289
|
+
}
|
|
8224
8290
|
|
|
8225
8291
|
// Step 1: Resolve and clean parameters
|
|
8226
8292
|
const resolvedParams = resolveParams(params);
|
|
@@ -8229,6 +8295,13 @@ const createRoutePattern = (pattern) => {
|
|
|
8229
8295
|
const relationships = patternRelationships.get(pattern);
|
|
8230
8296
|
const parentPattern = relationships?.parent;
|
|
8231
8297
|
|
|
8298
|
+
if (DEBUG$2 && parentPattern) {
|
|
8299
|
+
console.debug(
|
|
8300
|
+
`[${pattern}] Available ancestor:`,
|
|
8301
|
+
parentPattern.originalPattern,
|
|
8302
|
+
);
|
|
8303
|
+
}
|
|
8304
|
+
|
|
8232
8305
|
let bestAncestorUrl = null;
|
|
8233
8306
|
if (parentPattern) {
|
|
8234
8307
|
// Skip root route - never use as optimization target
|
|
@@ -8238,6 +8311,12 @@ const createRoutePattern = (pattern) => {
|
|
|
8238
8311
|
parentPattern,
|
|
8239
8312
|
resolvedParams,
|
|
8240
8313
|
);
|
|
8314
|
+
if (DEBUG$2) {
|
|
8315
|
+
console.debug(
|
|
8316
|
+
`[${pattern}] Highest ancestor from ${parentPattern.originalPattern}:`,
|
|
8317
|
+
highestAncestorUrl,
|
|
8318
|
+
);
|
|
8319
|
+
}
|
|
8241
8320
|
|
|
8242
8321
|
if (highestAncestorUrl) {
|
|
8243
8322
|
bestAncestorUrl = highestAncestorUrl;
|
|
@@ -8246,6 +8325,9 @@ const createRoutePattern = (pattern) => {
|
|
|
8246
8325
|
}
|
|
8247
8326
|
|
|
8248
8327
|
if (bestAncestorUrl) {
|
|
8328
|
+
if (DEBUG$2) {
|
|
8329
|
+
console.debug(`[${pattern}] Using ancestor optimization`);
|
|
8330
|
+
}
|
|
8249
8331
|
return bestAncestorUrl;
|
|
8250
8332
|
}
|
|
8251
8333
|
|
|
@@ -8271,8 +8353,14 @@ const createRoutePattern = (pattern) => {
|
|
|
8271
8353
|
}
|
|
8272
8354
|
|
|
8273
8355
|
if (bestDescendantUrl) {
|
|
8356
|
+
if (DEBUG$2) {
|
|
8357
|
+
console.debug(`[${pattern}] Using descendant optimization`);
|
|
8358
|
+
}
|
|
8274
8359
|
return bestDescendantUrl;
|
|
8275
8360
|
}
|
|
8361
|
+
if (DEBUG$2) {
|
|
8362
|
+
console.debug(`[${pattern}] No suitable child route found`);
|
|
8363
|
+
}
|
|
8276
8364
|
|
|
8277
8365
|
// Step 5: Inherit parameters from parent routes
|
|
8278
8366
|
inheritParentParameters(finalParams, relationships);
|
|
@@ -8360,17 +8448,6 @@ const createRoutePattern = (pattern) => {
|
|
|
8360
8448
|
* Helper: Try to use an ancestor route (only immediate parent for parameter optimization)
|
|
8361
8449
|
*/
|
|
8362
8450
|
const tryUseAncestor = (ancestorPatternObj, resolvedParams) => {
|
|
8363
|
-
// For routes with parameters, only allow optimization if all resolved parameters have default values
|
|
8364
|
-
const hasNonDefaultParameters = connections.some((connection) => {
|
|
8365
|
-
const resolvedValue = resolvedParams[connection.paramName];
|
|
8366
|
-
const defaultValue = connection.options.defaultValue;
|
|
8367
|
-
return resolvedValue !== defaultValue;
|
|
8368
|
-
});
|
|
8369
|
-
|
|
8370
|
-
if (hasNonDefaultParameters) {
|
|
8371
|
-
return null;
|
|
8372
|
-
}
|
|
8373
|
-
|
|
8374
8451
|
// Check if this ancestor is the immediate parent (for parameter optimization safety)
|
|
8375
8452
|
const relationships = patternRelationships.get(pattern);
|
|
8376
8453
|
const immediateParent = relationships?.parent;
|
|
@@ -8379,6 +8456,35 @@ const createRoutePattern = (pattern) => {
|
|
|
8379
8456
|
immediateParent &&
|
|
8380
8457
|
immediateParent.originalPattern === ancestorPatternObj.originalPattern
|
|
8381
8458
|
) {
|
|
8459
|
+
// This is the immediate parent - check if we can optimize
|
|
8460
|
+
if (DEBUG$2) {
|
|
8461
|
+
console.debug(
|
|
8462
|
+
`[${pattern}] tryUseAncestor: Trying immediate parent ${ancestorPatternObj.originalPattern}`,
|
|
8463
|
+
);
|
|
8464
|
+
}
|
|
8465
|
+
|
|
8466
|
+
// For immediate parent optimization with parameters, only allow if:
|
|
8467
|
+
// 1. All path/route parameters have default values, OR
|
|
8468
|
+
// 2. The source route has only query parameters that are non-default
|
|
8469
|
+
const hasNonDefaultPathParams = connections.some((connection) => {
|
|
8470
|
+
const resolvedValue = resolvedParams[connection.paramName];
|
|
8471
|
+
const defaultValue = connection.options.defaultValue;
|
|
8472
|
+
// Check if this is a query parameter (not in the pattern path)
|
|
8473
|
+
const isQueryParam = parsedPattern.queryParams.some(
|
|
8474
|
+
(qp) => qp.name === connection.paramName,
|
|
8475
|
+
);
|
|
8476
|
+
// Allow non-default query parameters, but not path parameters
|
|
8477
|
+
return !isQueryParam && resolvedValue !== defaultValue;
|
|
8478
|
+
});
|
|
8479
|
+
|
|
8480
|
+
if (hasNonDefaultPathParams) {
|
|
8481
|
+
if (DEBUG$2) {
|
|
8482
|
+
console.debug(
|
|
8483
|
+
`[${pattern}] tryUseAncestor: Has non-default path parameters, skipping`,
|
|
8484
|
+
);
|
|
8485
|
+
}
|
|
8486
|
+
return null;
|
|
8487
|
+
}
|
|
8382
8488
|
|
|
8383
8489
|
const result = tryDirectOptimization(
|
|
8384
8490
|
parsedPattern,
|
|
@@ -8386,14 +8492,42 @@ const createRoutePattern = (pattern) => {
|
|
|
8386
8492
|
ancestorPatternObj,
|
|
8387
8493
|
resolvedParams,
|
|
8388
8494
|
);
|
|
8495
|
+
if (DEBUG$2) {
|
|
8496
|
+
console.debug(
|
|
8497
|
+
`[${pattern}] tryUseAncestor: tryDirectOptimization result:`,
|
|
8498
|
+
result,
|
|
8499
|
+
);
|
|
8500
|
+
}
|
|
8389
8501
|
return result;
|
|
8390
8502
|
}
|
|
8503
|
+
|
|
8504
|
+
// For non-immediate parents, only allow optimization if all resolved parameters have default values
|
|
8505
|
+
const hasNonDefaultParameters = connections.some((connection) => {
|
|
8506
|
+
const resolvedValue = resolvedParams[connection.paramName];
|
|
8507
|
+
const defaultValue = connection.options.defaultValue;
|
|
8508
|
+
return resolvedValue !== defaultValue;
|
|
8509
|
+
});
|
|
8510
|
+
|
|
8511
|
+
if (hasNonDefaultParameters) {
|
|
8512
|
+
if (DEBUG$2) {
|
|
8513
|
+
console.debug(
|
|
8514
|
+
`[${pattern}] tryUseAncestor: Non-immediate parent with non-default parameters, skipping`,
|
|
8515
|
+
);
|
|
8516
|
+
}
|
|
8517
|
+
return null;
|
|
8518
|
+
}
|
|
8519
|
+
|
|
8391
8520
|
// This is not the immediate parent - only allow literal-only optimization
|
|
8392
8521
|
const hasParameters =
|
|
8393
8522
|
connections.length > 0 ||
|
|
8394
8523
|
parsedPattern.segments.some((seg) => seg.type === "param");
|
|
8395
8524
|
|
|
8396
8525
|
if (hasParameters) {
|
|
8526
|
+
if (DEBUG$2) {
|
|
8527
|
+
console.debug(
|
|
8528
|
+
`[${pattern}] tryUseAncestor: Non-immediate parent with parameters, skipping`,
|
|
8529
|
+
);
|
|
8530
|
+
}
|
|
8397
8531
|
return null;
|
|
8398
8532
|
}
|
|
8399
8533
|
|
|
@@ -8403,15 +8537,33 @@ const createRoutePattern = (pattern) => {
|
|
|
8403
8537
|
ancestorPatternObj.pattern.segments.some((seg) => seg.type === "param");
|
|
8404
8538
|
|
|
8405
8539
|
if (ancestorHasParameters) {
|
|
8540
|
+
if (DEBUG$2) {
|
|
8541
|
+
console.debug(
|
|
8542
|
+
`[${pattern}] tryUseAncestor: Literal route cannot optimize to parametric ancestor ${ancestorPatternObj.originalPattern}`,
|
|
8543
|
+
);
|
|
8544
|
+
}
|
|
8406
8545
|
return null;
|
|
8407
8546
|
}
|
|
8408
8547
|
|
|
8548
|
+
// Both are pure literal routes - can optimize
|
|
8549
|
+
if (DEBUG$2) {
|
|
8550
|
+
console.debug(
|
|
8551
|
+
`[${pattern}] tryUseAncestor: Trying literal-to-literal optimization to ${ancestorPatternObj.originalPattern}`,
|
|
8552
|
+
);
|
|
8553
|
+
}
|
|
8554
|
+
|
|
8409
8555
|
const result = tryDirectOptimization(
|
|
8410
8556
|
parsedPattern,
|
|
8411
8557
|
connections,
|
|
8412
8558
|
ancestorPatternObj,
|
|
8413
8559
|
resolvedParams,
|
|
8414
8560
|
);
|
|
8561
|
+
if (DEBUG$2) {
|
|
8562
|
+
console.debug(
|
|
8563
|
+
`[${pattern}] tryUseAncestor: tryDirectOptimization result:`,
|
|
8564
|
+
result,
|
|
8565
|
+
);
|
|
8566
|
+
}
|
|
8415
8567
|
return result;
|
|
8416
8568
|
};
|
|
8417
8569
|
|
|
@@ -8436,14 +8588,37 @@ const createRoutePattern = (pattern) => {
|
|
|
8436
8588
|
(seg) => seg.type === "param",
|
|
8437
8589
|
);
|
|
8438
8590
|
|
|
8591
|
+
if (DEBUG$2) {
|
|
8592
|
+
console.debug(
|
|
8593
|
+
`[${pattern}] tryDirectOptimization: sourceLiterals:`,
|
|
8594
|
+
sourceLiterals,
|
|
8595
|
+
);
|
|
8596
|
+
console.debug(
|
|
8597
|
+
`[${pattern}] tryDirectOptimization: targetLiterals:`,
|
|
8598
|
+
targetLiterals,
|
|
8599
|
+
);
|
|
8600
|
+
console.debug(
|
|
8601
|
+
`[${pattern}] tryDirectOptimization: targetParams:`,
|
|
8602
|
+
targetParams,
|
|
8603
|
+
);
|
|
8604
|
+
}
|
|
8605
|
+
|
|
8439
8606
|
// Source must extend target's literal path
|
|
8440
8607
|
if (sourceLiterals.length <= targetLiterals.length) {
|
|
8608
|
+
if (DEBUG$2) {
|
|
8609
|
+
console.debug(`[${pattern}] tryDirectOptimization: Source too short`);
|
|
8610
|
+
}
|
|
8441
8611
|
return null;
|
|
8442
8612
|
}
|
|
8443
8613
|
|
|
8444
8614
|
// Source must start with same literals as target
|
|
8445
8615
|
for (let i = 0; i < targetLiterals.length; i++) {
|
|
8446
8616
|
if (sourceLiterals[i] !== targetLiterals[i]) {
|
|
8617
|
+
if (DEBUG$2) {
|
|
8618
|
+
console.debug(
|
|
8619
|
+
`[${pattern}] tryDirectOptimization: Literal mismatch at ${i}`,
|
|
8620
|
+
);
|
|
8621
|
+
}
|
|
8447
8622
|
return null;
|
|
8448
8623
|
}
|
|
8449
8624
|
}
|
|
@@ -8459,6 +8634,11 @@ const createRoutePattern = (pattern) => {
|
|
|
8459
8634
|
targetAncestor.connections.length === 0;
|
|
8460
8635
|
|
|
8461
8636
|
if (sourceHasOnlyLiterals && targetHasOnlyLiterals) {
|
|
8637
|
+
if (DEBUG$2) {
|
|
8638
|
+
console.debug(
|
|
8639
|
+
`[${pattern}] tryDirectOptimization: Both are pure literal-only routes, allowing optimization`,
|
|
8640
|
+
);
|
|
8641
|
+
}
|
|
8462
8642
|
return buildUrlFromPattern(
|
|
8463
8643
|
targetAncestor.pattern,
|
|
8464
8644
|
{},
|
|
@@ -8469,6 +8649,11 @@ const createRoutePattern = (pattern) => {
|
|
|
8469
8649
|
// For parametric optimization: remaining segments must match target's parameter defaults
|
|
8470
8650
|
const extraSegments = sourceLiterals.slice(targetLiterals.length);
|
|
8471
8651
|
if (extraSegments.length !== targetParams.length) {
|
|
8652
|
+
if (DEBUG$2) {
|
|
8653
|
+
console.debug(
|
|
8654
|
+
`[${pattern}] tryDirectOptimization: Extra segments ${extraSegments.length} != target params ${targetParams.length}`,
|
|
8655
|
+
);
|
|
8656
|
+
}
|
|
8472
8657
|
return null;
|
|
8473
8658
|
}
|
|
8474
8659
|
|
|
@@ -8479,29 +8664,84 @@ const createRoutePattern = (pattern) => {
|
|
|
8479
8664
|
(conn) => conn.paramName === param.name,
|
|
8480
8665
|
);
|
|
8481
8666
|
if (!connection || connection.options.defaultValue !== segment) {
|
|
8667
|
+
if (DEBUG$2) {
|
|
8668
|
+
console.debug(
|
|
8669
|
+
`[${pattern}] tryDirectOptimization: Parameter default mismatch for ${param.name}`,
|
|
8670
|
+
);
|
|
8671
|
+
}
|
|
8482
8672
|
return null;
|
|
8483
8673
|
}
|
|
8484
8674
|
}
|
|
8485
8675
|
|
|
8676
|
+
if (DEBUG$2) {
|
|
8677
|
+
console.debug(
|
|
8678
|
+
`[${pattern}] tryDirectOptimization: SUCCESS! Returning ancestor URL`,
|
|
8679
|
+
);
|
|
8680
|
+
console.debug(
|
|
8681
|
+
`[${pattern}] tryDirectOptimization: resolvedParams:`,
|
|
8682
|
+
resolvedParams,
|
|
8683
|
+
);
|
|
8684
|
+
}
|
|
8685
|
+
|
|
8486
8686
|
// Build ancestor URL with inherited parameters that don't conflict with optimization
|
|
8487
8687
|
const ancestorParams = {};
|
|
8488
8688
|
|
|
8489
8689
|
// First, add extra parameters from the original resolvedParams
|
|
8490
|
-
// These are parameters that don't correspond to any pattern segments
|
|
8690
|
+
// These are parameters that don't correspond to any pattern segments or query params
|
|
8491
8691
|
const sourcePatternParamNames = new Set(
|
|
8492
8692
|
sourceConnections.map((conn) => conn.paramName),
|
|
8493
8693
|
);
|
|
8694
|
+
const sourceQueryParamNames = new Set(
|
|
8695
|
+
sourcePattern.queryParams.map((qp) => qp.name),
|
|
8696
|
+
);
|
|
8494
8697
|
const targetPatternParamNames = new Set(
|
|
8495
8698
|
targetAncestor.connections.map((conn) => conn.paramName),
|
|
8496
8699
|
);
|
|
8700
|
+
const targetQueryParamNames = new Set(
|
|
8701
|
+
targetAncestor.pattern.queryParams.map((qp) => qp.name),
|
|
8702
|
+
);
|
|
8497
8703
|
|
|
8498
8704
|
for (const [paramName, value] of Object.entries(resolvedParams)) {
|
|
8499
|
-
|
|
8500
|
-
|
|
8705
|
+
if (DEBUG$2) {
|
|
8706
|
+
console.debug(
|
|
8707
|
+
`[${pattern}] tryDirectOptimization: Considering param ${paramName}=${value}`,
|
|
8708
|
+
);
|
|
8709
|
+
}
|
|
8710
|
+
// Include parameters that target pattern specifically needs
|
|
8711
|
+
if (targetQueryParamNames.has(paramName)) {
|
|
8712
|
+
ancestorParams[paramName] = value;
|
|
8713
|
+
if (DEBUG$2) {
|
|
8714
|
+
console.debug(
|
|
8715
|
+
`[${pattern}] tryDirectOptimization: Added target param ${paramName}=${value}`,
|
|
8716
|
+
);
|
|
8717
|
+
}
|
|
8718
|
+
}
|
|
8719
|
+
// Include source query parameters (these should be inherited during ancestor optimization)
|
|
8720
|
+
else if (sourceQueryParamNames.has(paramName)) {
|
|
8721
|
+
// Only include if the value is not the default value
|
|
8722
|
+
const connection = sourceConnections.find(
|
|
8723
|
+
(conn) => conn.paramName === paramName,
|
|
8724
|
+
);
|
|
8725
|
+
if (connection && connection.options.defaultValue !== value) {
|
|
8726
|
+
ancestorParams[paramName] = value;
|
|
8727
|
+
if (DEBUG$2) {
|
|
8728
|
+
console.debug(
|
|
8729
|
+
`[${pattern}] tryDirectOptimization: Added source param ${paramName}=${value}`,
|
|
8730
|
+
);
|
|
8731
|
+
}
|
|
8732
|
+
}
|
|
8733
|
+
}
|
|
8734
|
+
// Include extra parameters that are not part of either pattern (true extra parameters)
|
|
8735
|
+
else if (
|
|
8501
8736
|
!sourcePatternParamNames.has(paramName) &&
|
|
8502
8737
|
!targetPatternParamNames.has(paramName)
|
|
8503
8738
|
) {
|
|
8504
8739
|
ancestorParams[paramName] = value;
|
|
8740
|
+
if (DEBUG$2) {
|
|
8741
|
+
console.debug(
|
|
8742
|
+
`[${pattern}] tryDirectOptimization: Added extra param ${paramName}=${value}`,
|
|
8743
|
+
);
|
|
8744
|
+
}
|
|
8505
8745
|
}
|
|
8506
8746
|
}
|
|
8507
8747
|
|
|
@@ -8992,6 +9232,11 @@ const buildHierarchicalQueryParams = (
|
|
|
8992
9232
|
currentParent = parentRelationships?.parent;
|
|
8993
9233
|
}
|
|
8994
9234
|
|
|
9235
|
+
// DEBUG: Log what we found
|
|
9236
|
+
if (DEBUG$2) {
|
|
9237
|
+
console.debug(`Building params for ${originalPattern}`);
|
|
9238
|
+
}
|
|
9239
|
+
|
|
8995
9240
|
// Step 1: Add query parameters from ancestor patterns (oldest to newest)
|
|
8996
9241
|
// This ensures ancestor parameters come first in their declaration order
|
|
8997
9242
|
// ancestorPatterns is in correct order: root ancestor first, then immediate parent
|
|
@@ -9006,6 +9251,12 @@ const buildHierarchicalQueryParams = (
|
|
|
9006
9251
|
) {
|
|
9007
9252
|
queryParams[paramName] = params[paramName];
|
|
9008
9253
|
processedParams.add(paramName);
|
|
9254
|
+
|
|
9255
|
+
if (DEBUG$2) {
|
|
9256
|
+
console.debug(
|
|
9257
|
+
`Added ancestor param: ${paramName}=${params[paramName]}`,
|
|
9258
|
+
);
|
|
9259
|
+
}
|
|
9009
9260
|
}
|
|
9010
9261
|
}
|
|
9011
9262
|
}
|
|
@@ -9013,12 +9264,24 @@ const buildHierarchicalQueryParams = (
|
|
|
9013
9264
|
|
|
9014
9265
|
// Step 2: Add query parameters from current pattern
|
|
9015
9266
|
if (parsedPattern.queryParams) {
|
|
9267
|
+
if (DEBUG$2) {
|
|
9268
|
+
console.debug(
|
|
9269
|
+
`Processing current pattern query params:`,
|
|
9270
|
+
parsedPattern.queryParams.map((q) => q.name),
|
|
9271
|
+
);
|
|
9272
|
+
}
|
|
9016
9273
|
|
|
9017
9274
|
for (const queryParam of parsedPattern.queryParams) {
|
|
9018
9275
|
const paramName = queryParam.name;
|
|
9019
9276
|
if (params[paramName] !== undefined && !processedParams.has(paramName)) {
|
|
9020
9277
|
queryParams[paramName] = params[paramName];
|
|
9021
9278
|
processedParams.add(paramName);
|
|
9279
|
+
|
|
9280
|
+
if (DEBUG$2) {
|
|
9281
|
+
console.debug(
|
|
9282
|
+
`Added current param: ${paramName}=${params[paramName]}`,
|
|
9283
|
+
);
|
|
9284
|
+
}
|
|
9022
9285
|
}
|
|
9023
9286
|
}
|
|
9024
9287
|
}
|
|
@@ -9317,6 +9580,10 @@ const setupPatterns = (patternDefinitions) => {
|
|
|
9317
9580
|
originalPattern: currentPattern,
|
|
9318
9581
|
});
|
|
9319
9582
|
}
|
|
9583
|
+
|
|
9584
|
+
if (DEBUG$2) {
|
|
9585
|
+
console.debug("Pattern registry updated");
|
|
9586
|
+
}
|
|
9320
9587
|
};
|
|
9321
9588
|
|
|
9322
9589
|
/**
|
|
@@ -9325,20 +9592,52 @@ const setupPatterns = (patternDefinitions) => {
|
|
|
9325
9592
|
const calculatePatternDepth = (patternString) => {
|
|
9326
9593
|
const relationships = patternRelationships.get(patternString);
|
|
9327
9594
|
if (!relationships) {
|
|
9595
|
+
if (DEBUG$2) {
|
|
9596
|
+
console.debug(
|
|
9597
|
+
`[calculatePatternDepth] No relationships found for ${patternString}`,
|
|
9598
|
+
);
|
|
9599
|
+
}
|
|
9328
9600
|
return 0;
|
|
9329
9601
|
}
|
|
9330
9602
|
|
|
9603
|
+
if (DEBUG$2) {
|
|
9604
|
+
console.debug(
|
|
9605
|
+
`[calculatePatternDepth] Calculating depth for ${patternString}`,
|
|
9606
|
+
);
|
|
9607
|
+
console.debug(
|
|
9608
|
+
`[calculatePatternDepth] Parent pattern:`,
|
|
9609
|
+
relationships.parent?.originalPattern,
|
|
9610
|
+
);
|
|
9611
|
+
}
|
|
9612
|
+
|
|
9331
9613
|
// If no parent, depth is 0 (root pattern)
|
|
9332
9614
|
if (!relationships.parent) {
|
|
9615
|
+
if (DEBUG$2) {
|
|
9616
|
+
console.debug(
|
|
9617
|
+
`[calculatePatternDepth] Final depth for ${patternString}: 0 (no parent)`,
|
|
9618
|
+
);
|
|
9619
|
+
}
|
|
9333
9620
|
return 0;
|
|
9334
9621
|
}
|
|
9335
9622
|
|
|
9623
|
+
if (DEBUG$2) {
|
|
9624
|
+
console.debug(
|
|
9625
|
+
`[calculatePatternDepth] Parent: ${relationships.parent.originalPattern}`,
|
|
9626
|
+
);
|
|
9627
|
+
}
|
|
9628
|
+
|
|
9336
9629
|
// Recursively calculate depth: 1 + parent's depth
|
|
9337
9630
|
const parentDepth = calculatePatternDepth(
|
|
9338
9631
|
relationships.parent.originalPattern,
|
|
9339
9632
|
);
|
|
9340
9633
|
const depth = parentDepth + 1;
|
|
9341
9634
|
|
|
9635
|
+
if (DEBUG$2) {
|
|
9636
|
+
console.debug(
|
|
9637
|
+
`[calculatePatternDepth] Final depth for ${patternString}: ${depth} (parent: ${relationships.parent.originalPattern} with depth ${parentDepth})`,
|
|
9638
|
+
);
|
|
9639
|
+
}
|
|
9640
|
+
|
|
9342
9641
|
return depth;
|
|
9343
9642
|
};
|
|
9344
9643
|
|