@jsenv/navi 0.16.1 → 0.16.3
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 +88 -22
- package/dist/jsenv_navi.js.map +4 -4
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -7528,15 +7528,24 @@ const detectSignals = (routePattern) => {
|
|
|
7528
7528
|
const signalConnections = [];
|
|
7529
7529
|
let updatedPattern = routePattern;
|
|
7530
7530
|
|
|
7531
|
-
// Look for signals in
|
|
7532
|
-
//
|
|
7533
|
-
|
|
7531
|
+
// Look for signals in two formats:
|
|
7532
|
+
// 1. Expected format: :paramName={navi_state_signal:id} or ?paramName={navi_state_signal:id} or ¶mName={navi_state_signal:id}
|
|
7533
|
+
// 2. Typoe format (missing = sign): ¶mName{navi_state_signal:id}
|
|
7534
|
+
const signalParamRegex = /([?:&])(\w+)(=)?(\{navi_state_signal:[^}]+\})/g;
|
|
7534
7535
|
let match;
|
|
7535
7536
|
|
|
7536
7537
|
while ((match = signalParamRegex.exec(routePattern)) !== null) {
|
|
7537
|
-
const [fullMatch, prefix, paramName, signalString] = match;
|
|
7538
|
+
const [fullMatch, prefix, paramName, equalSign, signalString] = match;
|
|
7538
7539
|
|
|
7539
|
-
//
|
|
7540
|
+
// Emit warning if equal sign is missing
|
|
7541
|
+
if (!equalSign) {
|
|
7542
|
+
console.warn(
|
|
7543
|
+
`[detectSignals] Missing '=' sign in route pattern: "${prefix}${paramName}${signalString}". ` +
|
|
7544
|
+
`Consider using "${prefix}${paramName}=${signalString}" for better clarity.`,
|
|
7545
|
+
);
|
|
7546
|
+
}
|
|
7547
|
+
|
|
7548
|
+
// Extract the signal ID from the format: {navi_state_signal:id}
|
|
7540
7549
|
const signalIdMatch = signalString.match(/\{navi_state_signal:([^}]+)\}/);
|
|
7541
7550
|
if (!signalIdMatch) {
|
|
7542
7551
|
console.warn(
|
|
@@ -7553,13 +7562,10 @@ const detectSignals = (routePattern) => {
|
|
|
7553
7562
|
|
|
7554
7563
|
let replacement;
|
|
7555
7564
|
if (prefix === ":") {
|
|
7556
|
-
// Path parameter: :section=
|
|
7565
|
+
// Path parameter: :section={navi_state_signal:...} becomes :section
|
|
7557
7566
|
replacement = `${prefix}${paramName}`;
|
|
7558
|
-
} else if (prefix === "?") {
|
|
7559
|
-
//
|
|
7560
|
-
replacement = `${prefix}${paramName}`;
|
|
7561
|
-
} else if (prefix === "&") {
|
|
7562
|
-
// Additional search parameter: &lon=__jsenv_signal_1__ becomes &lon
|
|
7567
|
+
} else if (prefix === "?" || prefix === "&") {
|
|
7568
|
+
// Query parameter: ?city={navi_state_signal:...} or &lon{navi_state_signal:...} becomes ?city or &lon
|
|
7563
7569
|
replacement = `${prefix}${paramName}`;
|
|
7564
7570
|
}
|
|
7565
7571
|
updatedPattern = updatedPattern.replace(fullMatch, replacement);
|
|
@@ -7606,6 +7612,7 @@ const createRoutePattern = (pattern) => {
|
|
|
7606
7612
|
const result = matchUrl(parsedPattern, url, {
|
|
7607
7613
|
parameterDefaults,
|
|
7608
7614
|
baseUrl,
|
|
7615
|
+
connections,
|
|
7609
7616
|
});
|
|
7610
7617
|
|
|
7611
7618
|
return result;
|
|
@@ -7985,7 +7992,11 @@ const checkIfLiteralCanBeOptional = (literalValue, patternRegistry) => {
|
|
|
7985
7992
|
/**
|
|
7986
7993
|
* Match a URL against a parsed pattern
|
|
7987
7994
|
*/
|
|
7988
|
-
const matchUrl = (
|
|
7995
|
+
const matchUrl = (
|
|
7996
|
+
parsedPattern,
|
|
7997
|
+
url,
|
|
7998
|
+
{ parameterDefaults, baseUrl, connections = [] },
|
|
7999
|
+
) => {
|
|
7989
8000
|
// Parse the URL
|
|
7990
8001
|
const urlObj = new URL(url, baseUrl);
|
|
7991
8002
|
let pathname = urlObj.pathname;
|
|
@@ -8007,14 +8018,14 @@ const matchUrl = (parsedPattern, url, { parameterDefaults, baseUrl }) => {
|
|
|
8007
8018
|
// OR when URL exactly matches baseUrl (treating baseUrl as root)
|
|
8008
8019
|
if (parsedPattern.segments.length === 0) {
|
|
8009
8020
|
if (pathname === "/" || pathname === "") {
|
|
8010
|
-
return extractSearchParams(urlObj);
|
|
8021
|
+
return extractSearchParams(urlObj, connections);
|
|
8011
8022
|
}
|
|
8012
8023
|
|
|
8013
8024
|
// Special case: if URL exactly matches baseUrl, treat as root route
|
|
8014
8025
|
if (baseUrl) {
|
|
8015
8026
|
const baseUrlObj = new URL(baseUrl);
|
|
8016
8027
|
if (originalPathname === baseUrlObj.pathname) {
|
|
8017
|
-
return extractSearchParams(urlObj);
|
|
8028
|
+
return extractSearchParams(urlObj, connections);
|
|
8018
8029
|
}
|
|
8019
8030
|
}
|
|
8020
8031
|
|
|
@@ -8109,7 +8120,7 @@ const matchUrl = (parsedPattern, url, { parameterDefaults, baseUrl }) => {
|
|
|
8109
8120
|
// If pattern has trailing slash or wildcard, allow extra segments (no additional check needed)
|
|
8110
8121
|
|
|
8111
8122
|
// Add search parameters
|
|
8112
|
-
const searchParams = extractSearchParams(urlObj);
|
|
8123
|
+
const searchParams = extractSearchParams(urlObj, connections);
|
|
8113
8124
|
Object.assign(params, searchParams);
|
|
8114
8125
|
|
|
8115
8126
|
// Apply remaining parameter defaults for unmatched parameters
|
|
@@ -8125,10 +8136,29 @@ const matchUrl = (parsedPattern, url, { parameterDefaults, baseUrl }) => {
|
|
|
8125
8136
|
/**
|
|
8126
8137
|
* Extract search parameters from URL
|
|
8127
8138
|
*/
|
|
8128
|
-
const extractSearchParams = (urlObj) => {
|
|
8139
|
+
const extractSearchParams = (urlObj, connections = []) => {
|
|
8129
8140
|
const params = {};
|
|
8141
|
+
|
|
8142
|
+
// Create a map for quick signal type lookup
|
|
8143
|
+
const signalTypes = new Map();
|
|
8144
|
+
for (const connection of connections) {
|
|
8145
|
+
if (connection.options.type) {
|
|
8146
|
+
signalTypes.set(connection.paramName, connection.options.type);
|
|
8147
|
+
}
|
|
8148
|
+
}
|
|
8149
|
+
|
|
8130
8150
|
for (const [key, value] of urlObj.searchParams) {
|
|
8131
|
-
|
|
8151
|
+
const signalType = signalTypes.get(key);
|
|
8152
|
+
|
|
8153
|
+
// Cast value based on signal type
|
|
8154
|
+
if (signalType === "number" || signalType === "float") {
|
|
8155
|
+
const numberValue = Number(value);
|
|
8156
|
+
params[key] = isNaN(numberValue) ? value : numberValue;
|
|
8157
|
+
} else if (signalType === "boolean") {
|
|
8158
|
+
params[key] = value === "true" || value === "1";
|
|
8159
|
+
} else {
|
|
8160
|
+
params[key] = value;
|
|
8161
|
+
}
|
|
8132
8162
|
}
|
|
8133
8163
|
return params;
|
|
8134
8164
|
};
|
|
@@ -8784,12 +8814,48 @@ const registerRoute = (routePattern) => {
|
|
|
8784
8814
|
);
|
|
8785
8815
|
return null;
|
|
8786
8816
|
}
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8790
|
-
|
|
8791
|
-
|
|
8817
|
+
|
|
8818
|
+
// Find all matching routes and update their actions, then delegate to most specific
|
|
8819
|
+
const allMatchingRoutes = Array.from(routeSet).filter((r) => r.matching);
|
|
8820
|
+
|
|
8821
|
+
// Update action params on all matching routes
|
|
8822
|
+
for (const matchingRoute of allMatchingRoutes) {
|
|
8823
|
+
if (matchingRoute.action) {
|
|
8824
|
+
const matchingRoutePrivateProperties =
|
|
8825
|
+
getRoutePrivateProperties(matchingRoute);
|
|
8826
|
+
if (matchingRoutePrivateProperties) {
|
|
8827
|
+
const { routePattern: matchingRoutePattern } =
|
|
8828
|
+
matchingRoutePrivateProperties;
|
|
8829
|
+
const currentResolvedParams = matchingRoutePattern.resolveParams();
|
|
8830
|
+
const updatedActionParams = {
|
|
8831
|
+
...currentResolvedParams,
|
|
8832
|
+
...newParams,
|
|
8833
|
+
};
|
|
8834
|
+
matchingRoute.action.replaceParams(updatedActionParams);
|
|
8835
|
+
}
|
|
8836
|
+
}
|
|
8792
8837
|
}
|
|
8838
|
+
|
|
8839
|
+
// Find the most specific route (the one with the longest pattern path)
|
|
8840
|
+
let mostSpecificRoute = route;
|
|
8841
|
+
let maxSegments = route.pattern.split("/").filter((s) => s !== "").length;
|
|
8842
|
+
|
|
8843
|
+
for (const matchingRoute of allMatchingRoutes) {
|
|
8844
|
+
const segments = matchingRoute.pattern
|
|
8845
|
+
.split("/")
|
|
8846
|
+
.filter((s) => s !== "").length;
|
|
8847
|
+
if (segments > maxSegments) {
|
|
8848
|
+
maxSegments = segments;
|
|
8849
|
+
mostSpecificRoute = matchingRoute;
|
|
8850
|
+
}
|
|
8851
|
+
}
|
|
8852
|
+
|
|
8853
|
+
// If we found a more specific route, delegate to it; otherwise handle it ourselves
|
|
8854
|
+
if (mostSpecificRoute !== route) {
|
|
8855
|
+
return mostSpecificRoute.redirectTo(newParams);
|
|
8856
|
+
}
|
|
8857
|
+
|
|
8858
|
+
// This route is the most specific, handle the redirect ourselves
|
|
8793
8859
|
return route.redirectTo(newParams);
|
|
8794
8860
|
};
|
|
8795
8861
|
route.buildRelativeUrl = (params) => {
|