@jsenv/navi 0.16.19 → 0.16.21
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 +112 -97
- package/dist/jsenv_navi.js.map +4 -4
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -9465,7 +9465,13 @@ const extractSearchParams = (urlObj, connections = []) => {
|
|
|
9465
9465
|
const numberValue = Number(value);
|
|
9466
9466
|
params[key] = isNaN(numberValue) ? value : numberValue;
|
|
9467
9467
|
} else if (signalType === "boolean") {
|
|
9468
|
-
|
|
9468
|
+
// Handle boolean query parameters:
|
|
9469
|
+
// ?walk=true → true
|
|
9470
|
+
// ?walk=1 → true
|
|
9471
|
+
// ?walk → true (parameter present without value)
|
|
9472
|
+
// ?walk=false → false
|
|
9473
|
+
// ?walk=0 → false
|
|
9474
|
+
params[key] = value === "true" || value === "1" || value === "";
|
|
9469
9475
|
} else {
|
|
9470
9476
|
params[key] = value;
|
|
9471
9477
|
}
|
|
@@ -10039,6 +10045,110 @@ const updateRoutes = (
|
|
|
10039
10045
|
matchingRouteSet.add(route);
|
|
10040
10046
|
}
|
|
10041
10047
|
}
|
|
10048
|
+
|
|
10049
|
+
// URL -> Signal synchronization (moved from individual route effects to eliminate circular dependency)
|
|
10050
|
+
for (const {
|
|
10051
|
+
route,
|
|
10052
|
+
routePrivateProperties,
|
|
10053
|
+
newMatching,
|
|
10054
|
+
} of routeMatchInfoSet) {
|
|
10055
|
+
const { routePattern } = routePrivateProperties;
|
|
10056
|
+
const { connections } = routePattern;
|
|
10057
|
+
|
|
10058
|
+
for (const {
|
|
10059
|
+
signal: stateSignal,
|
|
10060
|
+
paramName,
|
|
10061
|
+
options = {},
|
|
10062
|
+
} of connections) {
|
|
10063
|
+
const { debug } = options;
|
|
10064
|
+
const params = routePrivateProperties.rawParamsSignal.value;
|
|
10065
|
+
const urlParamValue = params[paramName];
|
|
10066
|
+
|
|
10067
|
+
if (newMatching) {
|
|
10068
|
+
// When route matches, sync signal with URL parameter value
|
|
10069
|
+
// This ensures URL is the source of truth
|
|
10070
|
+
if (debug) {
|
|
10071
|
+
console.debug(
|
|
10072
|
+
`[route] Route matching: setting ${paramName} signal to URL value: ${urlParamValue}`,
|
|
10073
|
+
);
|
|
10074
|
+
}
|
|
10075
|
+
stateSignal.value = urlParamValue;
|
|
10076
|
+
} else {
|
|
10077
|
+
// When route doesn't match, check if we're navigating to a parent route
|
|
10078
|
+
let parentRouteMatching = false;
|
|
10079
|
+
for (const otherRoute of routeSet) {
|
|
10080
|
+
if (otherRoute === route || !otherRoute.matching) {
|
|
10081
|
+
continue;
|
|
10082
|
+
}
|
|
10083
|
+
const otherRouteProperties = getRoutePrivateProperties(otherRoute);
|
|
10084
|
+
const otherPatternObj = otherRouteProperties.routePattern;
|
|
10085
|
+
|
|
10086
|
+
// Check if the other route pattern is a parent of this route pattern
|
|
10087
|
+
// Using the built relationships in the pattern objects
|
|
10088
|
+
let currentParent = routePattern.parent;
|
|
10089
|
+
let foundParent = false;
|
|
10090
|
+
while (currentParent) {
|
|
10091
|
+
if (currentParent === otherPatternObj) {
|
|
10092
|
+
foundParent = true;
|
|
10093
|
+
break;
|
|
10094
|
+
}
|
|
10095
|
+
currentParent = currentParent.parent;
|
|
10096
|
+
}
|
|
10097
|
+
|
|
10098
|
+
if (!foundParent) {
|
|
10099
|
+
continue;
|
|
10100
|
+
}
|
|
10101
|
+
|
|
10102
|
+
// Found a parent route that's matching, but check if there's a more specific
|
|
10103
|
+
// sibling route also matching (indicating sibling navigation, not parent navigation)
|
|
10104
|
+
let hasMatchingSibling = false;
|
|
10105
|
+
for (const siblingCandidateRoute of routeSet) {
|
|
10106
|
+
if (
|
|
10107
|
+
siblingCandidateRoute === route ||
|
|
10108
|
+
siblingCandidateRoute === otherRoute ||
|
|
10109
|
+
!siblingCandidateRoute.matching
|
|
10110
|
+
) {
|
|
10111
|
+
continue;
|
|
10112
|
+
}
|
|
10113
|
+
|
|
10114
|
+
const siblingProperties = getRoutePrivateProperties(
|
|
10115
|
+
siblingCandidateRoute,
|
|
10116
|
+
);
|
|
10117
|
+
const siblingPatternObj = siblingProperties.routePattern;
|
|
10118
|
+
|
|
10119
|
+
// Check if this is a sibling (shares the same parent)
|
|
10120
|
+
if (siblingPatternObj.parent === currentParent) {
|
|
10121
|
+
hasMatchingSibling = true;
|
|
10122
|
+
break;
|
|
10123
|
+
}
|
|
10124
|
+
}
|
|
10125
|
+
|
|
10126
|
+
// Only treat as parent navigation if no sibling is matching
|
|
10127
|
+
if (!hasMatchingSibling) {
|
|
10128
|
+
parentRouteMatching = true;
|
|
10129
|
+
break; // Found the parent route, no need to check other routes
|
|
10130
|
+
}
|
|
10131
|
+
}
|
|
10132
|
+
|
|
10133
|
+
if (parentRouteMatching) {
|
|
10134
|
+
// We're navigating to a parent route - clear this signal to reflect the hierarchy
|
|
10135
|
+
const defaultValue = routePattern.parameterDefaults?.get(paramName);
|
|
10136
|
+
if (debug) {
|
|
10137
|
+
console.debug(
|
|
10138
|
+
`[route] Parent route ${parentRouteMatching} matching: clearing ${paramName} signal to default: ${defaultValue}`,
|
|
10139
|
+
);
|
|
10140
|
+
}
|
|
10141
|
+
stateSignal.value = defaultValue;
|
|
10142
|
+
} else if (debug) {
|
|
10143
|
+
// We're navigating to a different route family - preserve signal for future URL building
|
|
10144
|
+
// Keep current signal value unchanged
|
|
10145
|
+
console.debug(
|
|
10146
|
+
`[route] Different route family: preserving ${paramName} signal value: ${stateSignal.value}`,
|
|
10147
|
+
);
|
|
10148
|
+
}
|
|
10149
|
+
}
|
|
10150
|
+
}
|
|
10151
|
+
}
|
|
10042
10152
|
});
|
|
10043
10153
|
|
|
10044
10154
|
// must be after paramsSignal.value update to ensure the proxy target is set
|
|
@@ -10230,102 +10340,7 @@ const registerRoute = (routePattern) => {
|
|
|
10230
10340
|
);
|
|
10231
10341
|
}
|
|
10232
10342
|
|
|
10233
|
-
// URL -> Signal synchronization
|
|
10234
|
-
effect(() => {
|
|
10235
|
-
const matching = matchingSignal.value;
|
|
10236
|
-
const params = rawParamsSignal.value;
|
|
10237
|
-
const urlParamValue = params[paramName];
|
|
10238
|
-
|
|
10239
|
-
if (debug) {
|
|
10240
|
-
console.debug(
|
|
10241
|
-
`[route] URL->Signal effect triggered for ${paramName}: matching=${matching}, urlParamValue=${urlParamValue}, currentSignalValue=${stateSignal.value}`,
|
|
10242
|
-
);
|
|
10243
|
-
}
|
|
10244
|
-
|
|
10245
|
-
if (matching) {
|
|
10246
|
-
// When route matches, sync signal with URL parameter value
|
|
10247
|
-
// This ensures URL is the source of truth
|
|
10248
|
-
if (debug) {
|
|
10249
|
-
console.debug(
|
|
10250
|
-
`[route] Route matching: setting ${paramName} signal to URL value: ${urlParamValue}`,
|
|
10251
|
-
);
|
|
10252
|
-
}
|
|
10253
|
-
stateSignal.value = urlParamValue;
|
|
10254
|
-
} else {
|
|
10255
|
-
// When route doesn't match, check if we're navigating to a parent route
|
|
10256
|
-
let parentRouteMatching = false;
|
|
10257
|
-
for (const otherRoute of routeSet) {
|
|
10258
|
-
if (otherRoute === route || !otherRoute.matching) {
|
|
10259
|
-
continue;
|
|
10260
|
-
}
|
|
10261
|
-
const otherRouteProperties = getRoutePrivateProperties(otherRoute);
|
|
10262
|
-
const otherPatternObj = otherRouteProperties.routePattern;
|
|
10263
|
-
|
|
10264
|
-
// Check if the other route pattern is a parent of this route pattern
|
|
10265
|
-
// Using the built relationships in the pattern objects
|
|
10266
|
-
let currentParent = routePattern.parent;
|
|
10267
|
-
let foundParent = false;
|
|
10268
|
-
while (currentParent) {
|
|
10269
|
-
if (currentParent === otherPatternObj) {
|
|
10270
|
-
foundParent = true;
|
|
10271
|
-
break;
|
|
10272
|
-
}
|
|
10273
|
-
currentParent = currentParent.parent;
|
|
10274
|
-
}
|
|
10275
|
-
|
|
10276
|
-
if (!foundParent) {
|
|
10277
|
-
continue;
|
|
10278
|
-
}
|
|
10279
|
-
|
|
10280
|
-
// Found a parent route that's matching, but check if there's a more specific
|
|
10281
|
-
// sibling route also matching (indicating sibling navigation, not parent navigation)
|
|
10282
|
-
let hasMatchingSibling = false;
|
|
10283
|
-
for (const siblingCandidateRoute of routeSet) {
|
|
10284
|
-
if (
|
|
10285
|
-
siblingCandidateRoute === route ||
|
|
10286
|
-
siblingCandidateRoute === otherRoute ||
|
|
10287
|
-
!siblingCandidateRoute.matching
|
|
10288
|
-
) {
|
|
10289
|
-
continue;
|
|
10290
|
-
}
|
|
10291
|
-
|
|
10292
|
-
const siblingProperties = getRoutePrivateProperties(
|
|
10293
|
-
siblingCandidateRoute,
|
|
10294
|
-
);
|
|
10295
|
-
const siblingPatternObj = siblingProperties.routePattern;
|
|
10296
|
-
|
|
10297
|
-
// Check if this is a sibling (shares the same parent)
|
|
10298
|
-
if (siblingPatternObj.parent === currentParent) {
|
|
10299
|
-
hasMatchingSibling = true;
|
|
10300
|
-
break;
|
|
10301
|
-
}
|
|
10302
|
-
}
|
|
10303
|
-
|
|
10304
|
-
// Only treat as parent navigation if no sibling is matching
|
|
10305
|
-
if (!hasMatchingSibling) {
|
|
10306
|
-
parentRouteMatching = true;
|
|
10307
|
-
break; // Found the parent route, no need to check other routes
|
|
10308
|
-
}
|
|
10309
|
-
}
|
|
10310
|
-
|
|
10311
|
-
if (parentRouteMatching) {
|
|
10312
|
-
// We're navigating to a parent route - clear this signal to reflect the hierarchy
|
|
10313
|
-
const defaultValue = routePattern.parameterDefaults?.get(paramName);
|
|
10314
|
-
if (debug) {
|
|
10315
|
-
console.debug(
|
|
10316
|
-
`[route] Parent route ${parentRouteMatching} matching: clearing ${paramName} signal to default: ${defaultValue}`,
|
|
10317
|
-
);
|
|
10318
|
-
}
|
|
10319
|
-
stateSignal.value = defaultValue;
|
|
10320
|
-
} else if (debug) {
|
|
10321
|
-
// We're navigating to a different route family - preserve signal for future URL building
|
|
10322
|
-
// Keep current signal value unchanged
|
|
10323
|
-
console.debug(
|
|
10324
|
-
`[route] Different route family: preserving ${paramName} signal value: ${stateSignal.value}`,
|
|
10325
|
-
);
|
|
10326
|
-
}
|
|
10327
|
-
}
|
|
10328
|
-
});
|
|
10343
|
+
// URL -> Signal synchronization now handled in updateRoutes() to eliminate circular dependency
|
|
10329
10344
|
|
|
10330
10345
|
// Signal -> URL synchronization
|
|
10331
10346
|
effect(() => {
|