@symbo.ls/router 3.14.10 → 3.14.12
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/CHANGELOG.md +15 -3
- package/dist/cjs/index.js +1 -1
- package/dist/esm/index.js +1 -1
- package/index.js +28 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
# @symbo.ls/router
|
|
2
2
|
|
|
3
|
+
## 3.14.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Auto-generated cross-repo patch release.
|
|
8
|
+
|
|
9
|
+
## 3.14.11
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Auto-generated cross-repo patch release.
|
|
14
|
+
|
|
3
15
|
## 3.14.10
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
6
18
|
|
|
7
|
-
- Manual patch bump triggered via workflow_dispatch (scope:
|
|
19
|
+
- Manual patch bump triggered via workflow_dispatch (scope: all).
|
|
8
20
|
No source change behind this bump — released to refresh dist or
|
|
9
21
|
coordinate a cross-package version line.
|
|
10
22
|
- Updated dependencies
|
|
11
|
-
- @symbo.ls/element@3.14.
|
|
12
|
-
- @symbo.ls/utils@3.14.
|
|
23
|
+
- @symbo.ls/element@3.14.18
|
|
24
|
+
- @symbo.ls/utils@3.14.16
|
|
13
25
|
|
|
14
26
|
## 3.14.9
|
|
15
27
|
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var R=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var Q=Object.prototype.hasOwnProperty;var D=(e,o)=>{for(var r in o)R(e,r,{get:o[r],enumerable:!0})},H=(e,o,r,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of G(o))!Q.call(e,t)&&t!==r&&R(e,t,{get:()=>o[t],enumerable:!(s=z(o,t))||s.enumerable});return e};var J=e=>H(R({},"__esModule",{value:!0}),e);var et={};D(et,{default:()=>tt,getActiveRoute:()=>q,lastLevel:()=>C,lastPathname:()=>w,matchRoute:()=>k,parseQuery:()=>B,parseRoutePattern:()=>A,router:()=>K,runGuards:()=>F});module.exports=J(et);var i=require("@symbo.ls/utils");const S=/^:(.+)/,j=/^\*$/,M=new Map,A=e=>{const o=M.get(e);if(o)return o;const r=e.replace(/^\//,"").split("/"),s=[];let t=!1;for(let c=0;c<r.length;c++){const n=r[c].match(S);n?s.push({index:c,name:n[1]}):j.test(r[c])&&(t=!0)}const a={segments:r,params:s,hasWildcard:t,pattern:e};return M.set(e,a),a},k=(e,o,r=0)=>{const t=e.replace(/^\//,"").split("/").filter(Boolean).slice(r),a="/"+(t[0]||"");if(!o)return{key:null,content:null,params:{},routePath:a};let c=null,n=-1,g={};for(const u in o){if(u==="/*")continue;const x=A(u),v=V(t,x);v>n&&(n=v,c=u,g=X(t,x))}return!c&&o["/*"]&&(c="/*"),{key:c,content:c?o[c]:null,params:g,routePath:a}},V=(e,o)=>{const{segments:r,hasWildcard:s}=o;if(!s&&r.length!==e.length&&r.length!==1&&r.length>e.length)return-1;let t=0;const a=Math.min(r.length,e.length);for(let c=0;c<a;c++)if(r[c]===e[c])t+=3;else if(S.test(r[c]))t+=1;else if(j.test(r[c]))t+=.5;else return-1;return t},X=(e,o)=>{const r={};for(const{index:s,name:t}of o.params)e[s]&&(r[t]=decodeURIComponent(e[s]));return r},B=e=>{if(!e||e==="?")return{};const o={};return new URLSearchParams(e).forEach((s,t)=>{o[t]!==void 0?(Array.isArray(o[t])||(o[t]=[o[t]]),o[t].push(s)):o[t]=s}),o},F=async(e,o)=>{if(!e||!e.length)return!0;for(const r of e){const s=await r(o);if(s===!1)return!1;if(typeof s=="string")return s}return!0},q=(e=0,o)=>{o||(o=typeof i.window<"u"?i.window.location.pathname:"/");const s=o.split("/")[e+1];if(s)return`/${s}`};let w,C=0;const Y=e=>!e||e==="srcdoc"||e==="about:srcdoc"?"/":e,Z={level:C,pushState:!0,initialRender:!1,scrollToTop:!0,scrollToNode:!1,scrollNode:i.document&&i.document.documentElement,scrollBody:!1,useFragment:!1,updateState:!0,scrollToOffset:0,contentElementKey:"content",scrollToOptions:{behavior:"smooth"},useParamsMatching:!0},K=async(e,o,r={},s={})=>{const t=o||void 0,a=t?.context?.window||i.window,c=t?.context?.document||i.document,n={...Z,...t.context.routerOptions,...s};C=n.lastLevel;const g=t.__ref;(n.contentElementKey!=="content"&&n.contentElementKey!==g.contentElementKey||!g.contentElementKey)&&(g.contentElementKey=n.contentElementKey||"content");const u=g.contentElementKey||n.contentElementKey||"content",x=a.location.origin!=="null"?a.location.origin:"http://localhost";e=Y(e);const v=typeof a.URL=="function"?a.URL:typeof globalThis<"u"&&globalThis.URL||URL,I=new v(x+e),{pathname:f,search:N,hash:y}=I,P=B(N),U=t.node,W=y&&y!==a.location.hash.slice(1),$=f!==w;w=f;let T,O,m,b;if(n.useParamsMatching){const l=k(f,t.routes,n.level);T=l.key,O=l.routePath,m=l.content,b=l.params}else{T=q(n.level,f),O=T;const l=t.routes;m=l?l[T||"/"]||l["/*"]:null,b={}}const E=n.scrollToNode?U:n.scrollNode;if(t.state?.root?.debugging){t.state.root.debugging=!1;return}if(!m){n.onNotFound?n.onNotFound({pathname:f,route:T,element:t}):n.silent||console.warn("[smbls/router] no content matched for path",f,"\u2014 available routes:",Object.keys(t.routes||{}));return}if(n.guards&&n.guards.length){const l={pathname:f,route:T,params:b,query:P,hash:y,element:t,state:r},d=await F(n.guards,l);if(d===!1)return;if(typeof d=="string")return K(d,o,r,{...s,guards:[]})}if(n.pushState)try{a.history.pushState(r,null,f+(N||"")+(y||""))}catch{}if($||!W){const l={route:T,routePath:O,hash:y,debugging:!1};Object.keys(b).length&&(l.params=b),Object.keys(P).length&&(l.query=P),n.updateState&&t.state.update(l,{preventContentUpdate:!0}),u&&n.removeOldElement&&t[u].remove();const d=t.__ref?.origin?.content,L={};if(d)for(const p in d){const h=d[p];p==="__ref"||p==="props"||p==="node"||p==="parent"||p==="key"||(typeof h=="string"||typeof h=="number"||typeof h=="boolean"||typeof h=="object"&&h!==null&&!h.node&&!h.__ref)&&(L[p]=h)}const _={...L,...typeof m=="object"?m:{extends:m}};n.useFragment&&(_.tag="fragment");try{t.set(_,{contentElementKey:u})}catch(p){console.error("[smbls/router] failed to render route content",f,p)}}if(n.scrollToTop&&E?.scrollTo&&E.scrollTo({...n.scrollToOptions||{},top:0,left:0}),n.scrollToNode&&m[u]?.node?.scrollTo&&m[u].node.scrollTo({...n.scrollToOptions||{},top:0,left:0}),y){const l=c.getElementById(y);if(l&&E?.scrollTo){const d=l.getBoundingClientRect().top+U.scrollTop-(n.scrollToOffset||0);E.scrollTo({...n.scrollToOptions||{},top:d,left:0})}}(0,i.triggerEventOn)("routeChanged",t,n)};var tt=K;
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{document as O,window as
|
|
1
|
+
import{document as O,window as R,triggerEventOn as F}from"@symbo.ls/utils";const U=/^:(.+)/,L=/^\*$/,_=new Map,q=e=>{const n=_.get(e);if(n)return n;const r=e.replace(/^\//,"").split("/"),s=[];let t=!1;for(let c=0;c<r.length;c++){const o=r[c].match(U);o?s.push({index:c,name:o[1]}):L.test(r[c])&&(t=!0)}const a={segments:r,params:s,hasWildcard:t,pattern:e};return _.set(e,a),a},I=(e,n,r=0)=>{const t=e.replace(/^\//,"").split("/").filter(Boolean).slice(r),a="/"+(t[0]||"");if(!n)return{key:null,content:null,params:{},routePath:a};let c=null,o=-1,h={};for(const i in n){if(i==="/*")continue;const b=q(i),x=W(t,b);x>o&&(o=x,c=i,h=$(t,b))}return!c&&n["/*"]&&(c="/*"),{key:c,content:c?n[c]:null,params:h,routePath:a}},W=(e,n)=>{const{segments:r,hasWildcard:s}=n;if(!s&&r.length!==e.length&&r.length!==1&&r.length>e.length)return-1;let t=0;const a=Math.min(r.length,e.length);for(let c=0;c<a;c++)if(r[c]===e[c])t+=3;else if(U.test(r[c]))t+=1;else if(L.test(r[c]))t+=.5;else return-1;return t},$=(e,n)=>{const r={};for(const{index:s,name:t}of n.params)e[s]&&(r[t]=decodeURIComponent(e[s]));return r},z=e=>{if(!e||e==="?")return{};const n={};return new URLSearchParams(e).forEach((s,t)=>{n[t]!==void 0?(Array.isArray(n[t])||(n[t]=[n[t]]),n[t].push(s)):n[t]=s}),n},G=async(e,n)=>{if(!e||!e.length)return!0;for(const r of e){const s=await r(n);if(s===!1)return!1;if(typeof s=="string")return s}return!0},Q=(e=0,n)=>{n||(n=typeof R<"u"?R.location.pathname:"/");const s=n.split("/")[e+1];if(s)return`/${s}`};let S,j=0;const D=e=>!e||e==="srcdoc"||e==="about:srcdoc"?"/":e,H={level:j,pushState:!0,initialRender:!1,scrollToTop:!0,scrollToNode:!1,scrollNode:O&&O.documentElement,scrollBody:!1,useFragment:!1,updateState:!0,scrollToOffset:0,contentElementKey:"content",scrollToOptions:{behavior:"smooth"},useParamsMatching:!0},M=async(e,n,r={},s={})=>{const t=n||void 0,a=t?.context?.window||R,c=t?.context?.document||O,o={...H,...t.context.routerOptions,...s};j=o.lastLevel;const h=t.__ref;(o.contentElementKey!=="content"&&o.contentElementKey!==h.contentElementKey||!h.contentElementKey)&&(h.contentElementKey=o.contentElementKey||"content");const i=h.contentElementKey||o.contentElementKey||"content",b=a.location.origin!=="null"?a.location.origin:"http://localhost";e=D(e);const x=typeof a.URL=="function"?a.URL:typeof globalThis<"u"&&globalThis.URL||URL,A=new x(b+e),{pathname:u,search:w,hash:g}=A,E=z(w),C=t.node,k=g&&g!==a.location.hash.slice(1),B=u!==S;S=u;let y,P,p,T;if(o.useParamsMatching){const l=I(u,t.routes,o.level);y=l.key,P=l.routePath,p=l.content,T=l.params}else{y=Q(o.level,u),P=y;const l=t.routes;p=l?l[y||"/"]||l["/*"]:null,T={}}const v=o.scrollToNode?C:o.scrollNode;if(t.state?.root?.debugging){t.state.root.debugging=!1;return}if(!p){o.onNotFound?o.onNotFound({pathname:u,route:y,element:t}):o.silent||console.warn("[smbls/router] no content matched for path",u,"\u2014 available routes:",Object.keys(t.routes||{}));return}if(o.guards&&o.guards.length){const l={pathname:u,route:y,params:T,query:E,hash:g,element:t,state:r},f=await G(o.guards,l);if(f===!1)return;if(typeof f=="string")return M(f,n,r,{...s,guards:[]})}if(o.pushState)try{a.history.pushState(r,null,u+(w||"")+(g||""))}catch{}if(B||!k){const l={route:y,routePath:P,hash:g,debugging:!1};Object.keys(T).length&&(l.params=T),Object.keys(E).length&&(l.query=E),o.updateState&&t.state.update(l,{preventContentUpdate:!0}),i&&o.removeOldElement&&t[i].remove();const f=t.__ref?.origin?.content,K={};if(f)for(const d in f){const m=f[d];d==="__ref"||d==="props"||d==="node"||d==="parent"||d==="key"||(typeof m=="string"||typeof m=="number"||typeof m=="boolean"||typeof m=="object"&&m!==null&&!m.node&&!m.__ref)&&(K[d]=m)}const N={...K,...typeof p=="object"?p:{extends:p}};o.useFragment&&(N.tag="fragment");try{t.set(N,{contentElementKey:i})}catch(d){console.error("[smbls/router] failed to render route content",u,d)}}if(o.scrollToTop&&v?.scrollTo&&v.scrollTo({...o.scrollToOptions||{},top:0,left:0}),o.scrollToNode&&p[i]?.node?.scrollTo&&p[i].node.scrollTo({...o.scrollToOptions||{},top:0,left:0}),g){const l=c.getElementById(g);if(l&&v?.scrollTo){const f=l.getBoundingClientRect().top+C.scrollTop-(o.scrollToOffset||0);v.scrollTo({...o.scrollToOptions||{},top:f,left:0})}}F("routeChanged",t,o)};var V=M;export{V as default,Q as getActiveRoute,j as lastLevel,S as lastPathname,I as matchRoute,z as parseQuery,q as parseRoutePattern,M as router,G as runGuards};
|
package/index.js
CHANGED
|
@@ -36,6 +36,19 @@ export const matchRoute = (pathname, routes, level = 0) => {
|
|
|
36
36
|
const relevantSegments = pathSegments.slice(level)
|
|
37
37
|
const routePath = '/' + (relevantSegments[0] || '')
|
|
38
38
|
|
|
39
|
+
// SMBLS-ROUTER-UNDEFINED-ROUTES-1: routes is transiently undefined
|
|
40
|
+
// during auth-state remount (the shell tears down + rebuilds the
|
|
41
|
+
// routed tree, and an in-flight router.update can fire after
|
|
42
|
+
// `element.routes` is cleared but before the new tree mounts).
|
|
43
|
+
// The pre-fix behavior threw `Cannot read properties of undefined
|
|
44
|
+
// (reading '/*')` as an uncaught promise rejection — see signin.js
|
|
45
|
+
// comment + ids 64177-64218+ on /silverbreeze-labs/dashboard.
|
|
46
|
+
// Guard so the router returns "no match" instead of crashing; the
|
|
47
|
+
// next render after the remount picks up the rebuilt routes.
|
|
48
|
+
if (!routes) {
|
|
49
|
+
return { key: null, content: null, params: {}, routePath }
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
let bestMatch = null
|
|
40
53
|
let bestScore = -1
|
|
41
54
|
let matchedParams = {}
|
|
@@ -184,7 +197,16 @@ export const router = async (path, el, state = {}, options = {}) => {
|
|
|
184
197
|
|
|
185
198
|
const origin = win.location.origin !== 'null' ? win.location.origin : 'http://localhost'
|
|
186
199
|
path = normalizePath(path)
|
|
187
|
-
|
|
200
|
+
// Runtime guard for the iframe-mount path: `prepareWindow` snapshots
|
|
201
|
+
// `win.URL` at create() time when the iframe Window is still valid,
|
|
202
|
+
// but by the time the router fires the iframe may have been detached
|
|
203
|
+
// (Window's intrinsics nulled out) and `win.URL` is no longer a
|
|
204
|
+
// constructor — throws `TypeError: f.URL is not a constructor`. Fall
|
|
205
|
+
// back to the realm-global URL when win's is unusable.
|
|
206
|
+
const URLCtor = typeof win.URL === 'function'
|
|
207
|
+
? win.URL
|
|
208
|
+
: (typeof globalThis !== 'undefined' && globalThis.URL) || URL
|
|
209
|
+
const urlObj = new URLCtor(origin + path)
|
|
188
210
|
const { pathname, search, hash } = urlObj
|
|
189
211
|
|
|
190
212
|
const query = parseQuery(search)
|
|
@@ -210,7 +232,11 @@ export const router = async (path, el, state = {}, options = {}) => {
|
|
|
210
232
|
} else {
|
|
211
233
|
route = getActiveRoute(opts.level, pathname)
|
|
212
234
|
routePath = route
|
|
213
|
-
|
|
235
|
+
// SMBLS-ROUTER-UNDEFINED-ROUTES-1: same transient-undefined guard
|
|
236
|
+
// as matchRoute above — without this the auth-state remount path
|
|
237
|
+
// throws an uncaught rejection here too.
|
|
238
|
+
const routes = element.routes
|
|
239
|
+
content = routes ? (routes[route || '/'] || routes['/*']) : null
|
|
214
240
|
params = {}
|
|
215
241
|
}
|
|
216
242
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/router",
|
|
3
|
-
"version": "3.14.
|
|
3
|
+
"version": "3.14.12",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"prepublishOnly": "npm run build"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@symbo.ls/element": "^3.14.
|
|
32
|
-
"@symbo.ls/utils": "^3.14.
|
|
31
|
+
"@symbo.ls/element": "^3.14.18",
|
|
32
|
+
"@symbo.ls/utils": "^3.14.16"
|
|
33
33
|
},
|
|
34
34
|
"gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
|
|
35
35
|
"devDependencies": {
|