@vielzeug/wayfinder 3.0.0 → 26.10.0

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.
Files changed (71) hide show
  1. package/dist/_dev.cjs +1 -1
  2. package/dist/_dev.cjs.map +1 -1
  3. package/dist/_dev.js +1 -6
  4. package/dist/_dev.js.map +1 -1
  5. package/dist/_navigation.cjs +1 -1
  6. package/dist/_navigation.cjs.map +1 -1
  7. package/dist/_navigation.js +1 -20
  8. package/dist/_navigation.js.map +1 -1
  9. package/dist/compile.cjs +1 -1
  10. package/dist/compile.cjs.map +1 -1
  11. package/dist/compile.js +1 -46
  12. package/dist/compile.js.map +1 -1
  13. package/dist/context.cjs +1 -1
  14. package/dist/context.cjs.map +1 -1
  15. package/dist/context.js +1 -59
  16. package/dist/context.js.map +1 -1
  17. package/dist/errors.cjs +1 -1
  18. package/dist/errors.cjs.map +1 -1
  19. package/dist/errors.d.ts +4 -1
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +1 -17
  22. package/dist/errors.js.map +1 -1
  23. package/dist/guards.cjs +1 -1
  24. package/dist/guards.cjs.map +1 -1
  25. package/dist/guards.js +1 -9
  26. package/dist/guards.js.map +1 -1
  27. package/dist/history.cjs +1 -1
  28. package/dist/history.cjs.map +1 -1
  29. package/dist/history.d.ts +11 -0
  30. package/dist/history.d.ts.map +1 -1
  31. package/dist/history.js +1 -67
  32. package/dist/history.js.map +1 -1
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.d.ts +6 -2
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -5
  37. package/dist/middleware.cjs +1 -1
  38. package/dist/middleware.cjs.map +1 -1
  39. package/dist/middleware.js +1 -9
  40. package/dist/middleware.js.map +1 -1
  41. package/dist/path.cjs +1 -1
  42. package/dist/path.cjs.map +1 -1
  43. package/dist/path.js +1 -132
  44. package/dist/path.js.map +1 -1
  45. package/dist/phase-mirror.cjs +2 -0
  46. package/dist/phase-mirror.cjs.map +1 -0
  47. package/dist/phase-mirror.d.ts +51 -0
  48. package/dist/phase-mirror.d.ts.map +1 -0
  49. package/dist/phase-mirror.js +2 -0
  50. package/dist/phase-mirror.js.map +1 -0
  51. package/dist/route-signals.cjs +2 -0
  52. package/dist/route-signals.cjs.map +1 -0
  53. package/dist/route-signals.d.ts +23 -0
  54. package/dist/route-signals.d.ts.map +1 -0
  55. package/dist/route-signals.js +2 -0
  56. package/dist/route-signals.js.map +1 -0
  57. package/dist/router.cjs +1 -1
  58. package/dist/router.cjs.map +1 -1
  59. package/dist/router.d.ts +7 -1
  60. package/dist/router.d.ts.map +1 -1
  61. package/dist/router.js +1 -475
  62. package/dist/router.js.map +1 -1
  63. package/dist/types.d.ts +7 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/dist/wayfinder.cjs +1 -1
  66. package/dist/wayfinder.cjs.map +1 -1
  67. package/dist/wayfinder.iife.js +1 -1
  68. package/dist/wayfinder.iife.js.map +1 -1
  69. package/dist/wayfinder.js +1 -1
  70. package/dist/wayfinder.js.map +1 -1
  71. package/package.json +8 -5
package/dist/_dev.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function e(e){}function t(e,...t){}exports.error=t,exports.warn=e;
1
+ function warn(e){}function error(e,...t){}exports.error=error,exports.warn=warn;
2
2
  //# sourceMappingURL=_dev.cjs.map
package/dist/_dev.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __WAYFINDER_PROD__?: boolean }).__WAYFINDER_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/wayfinder] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/wayfinder] ${msg}`, ...args);\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC,CAGA,SAAgB,EAAM,EAAa,GAAG,EAAuB,CAE7D"}
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __WAYFINDER_PROD__?: boolean }).__WAYFINDER_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/wayfinder] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/wayfinder] ${msg}`, ...args);\n}\n"],"mappings":"AAGA,SAAgB,KAAK,EAAmB,CAExC,CAGA,SAAgB,MAAM,EAAa,GAAG,EAAuB,CAE7D"}
package/dist/_dev.js CHANGED
@@ -1,7 +1,2 @@
1
- //#region src/_dev.ts
2
- function e(e) {}
3
- function t(e, ...t) {}
4
- //#endregion
5
- export { t as error, e as warn };
6
-
1
+ function warn(e){}function error(e,...t){}export{error,warn};
7
2
  //# sourceMappingURL=_dev.js.map
package/dist/_dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __WAYFINDER_PROD__?: boolean }).__WAYFINDER_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/wayfinder] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/wayfinder] ${msg}`, ...args);\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC;AAGA,SAAgB,EAAM,GAAa,GAAG,GAAuB,CAE7D"}
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __WAYFINDER_PROD__?: boolean }).__WAYFINDER_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/wayfinder] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/wayfinder] ${msg}`, ...args);\n}\n"],"mappings":"AAGA,SAAgB,KAAK,EAAmB,CAExC,CAGA,SAAgB,MAAM,EAAa,GAAG,EAAuB,CAE7D"}
@@ -1,2 +1,2 @@
1
- function e(){let e;return{begin(){e?.abort();let t=new AbortController;return e=t,{isCurrent:()=>e===t&&!t.signal.aborted,signal:t.signal}},invalidate(t){e?.abort(t),e=void 0}}}exports.createNavigationCoordinator=e;
1
+ function createNavigationCoordinator(){let e;return{begin(){e?.abort();let t=new AbortController;return e=t,{isCurrent:()=>e===t&&!t.signal.aborted,signal:t.signal}},invalidate(t){e?.abort(t),e=void 0}}}exports.createNavigationCoordinator=createNavigationCoordinator;
2
2
  //# sourceMappingURL=_navigation.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"_navigation.cjs","names":[],"sources":["../src/_navigation.ts"],"sourcesContent":["export type NavigationAttempt = {\n isCurrent(): boolean;\n readonly signal: AbortSignal;\n};\n\n/** Coordinates navigation ownership so stale work cannot commit router state. */\nexport function createNavigationCoordinator() {\n let active: AbortController | undefined;\n\n return {\n begin(): NavigationAttempt {\n active?.abort();\n\n const controller = new AbortController();\n\n active = controller;\n\n return {\n isCurrent: () => active === controller && !controller.signal.aborted,\n signal: controller.signal,\n };\n },\n\n invalidate(reason?: unknown): void {\n active?.abort(reason);\n active = undefined;\n },\n };\n}\n"],"mappings":"AAMA,SAAgB,GAA8B,CAC5C,IAAI,EAEJ,MAAO,CACL,OAA2B,CACzB,GAAQ,MAAM,EAEd,IAAM,EAAa,IAAI,gBAIvB,MAFA,GAAS,EAEF,CACL,cAAiB,IAAW,GAAc,CAAC,EAAW,OAAO,QAC7D,OAAQ,EAAW,MACrB,CACF,EAEA,WAAW,EAAwB,CACjC,GAAQ,MAAM,CAAM,EACpB,EAAS,IAAA,EACX,CACF,CACF"}
1
+ {"version":3,"file":"_navigation.cjs","names":[],"sources":["../src/_navigation.ts"],"sourcesContent":["export type NavigationAttempt = {\n isCurrent(): boolean;\n readonly signal: AbortSignal;\n};\n\n/** Coordinates navigation ownership so stale work cannot commit router state. */\nexport function createNavigationCoordinator() {\n let active: AbortController | undefined;\n\n return {\n begin(): NavigationAttempt {\n active?.abort();\n\n const controller = new AbortController();\n\n active = controller;\n\n return {\n isCurrent: () => active === controller && !controller.signal.aborted,\n signal: controller.signal,\n };\n },\n\n invalidate(reason?: unknown): void {\n active?.abort(reason);\n active = undefined;\n },\n };\n}\n"],"mappings":"AAMA,SAAgB,6BAA8B,CAC5C,IAAI,EAEJ,MAAO,CACL,OAA2B,CACzB,GAAQ,MAAM,EAEd,IAAM,EAAa,IAAI,gBAIvB,MAFA,GAAS,EAEF,CACL,cAAiB,IAAW,GAAc,CAAC,EAAW,OAAO,QAC7D,OAAQ,EAAW,MACrB,CACF,EAEA,WAAW,EAAwB,CACjC,GAAQ,MAAM,CAAM,EACpB,EAAS,IAAA,EACX,CACF,CACF"}
@@ -1,21 +1,2 @@
1
- //#region src/_navigation.ts
2
- function e() {
3
- let e;
4
- return {
5
- begin() {
6
- e?.abort();
7
- let t = new AbortController();
8
- return e = t, {
9
- isCurrent: () => e === t && !t.signal.aborted,
10
- signal: t.signal
11
- };
12
- },
13
- invalidate(t) {
14
- e?.abort(t), e = void 0;
15
- }
16
- };
17
- }
18
- //#endregion
19
- export { e as createNavigationCoordinator };
20
-
1
+ function createNavigationCoordinator(){let e;return{begin(){e?.abort();let t=new AbortController;return e=t,{isCurrent:()=>e===t&&!t.signal.aborted,signal:t.signal}},invalidate(t){e?.abort(t),e=void 0}}}export{createNavigationCoordinator};
21
2
  //# sourceMappingURL=_navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_navigation.js","names":[],"sources":["../src/_navigation.ts"],"sourcesContent":["export type NavigationAttempt = {\n isCurrent(): boolean;\n readonly signal: AbortSignal;\n};\n\n/** Coordinates navigation ownership so stale work cannot commit router state. */\nexport function createNavigationCoordinator() {\n let active: AbortController | undefined;\n\n return {\n begin(): NavigationAttempt {\n active?.abort();\n\n const controller = new AbortController();\n\n active = controller;\n\n return {\n isCurrent: () => active === controller && !controller.signal.aborted,\n signal: controller.signal,\n };\n },\n\n invalidate(reason?: unknown): void {\n active?.abort(reason);\n active = undefined;\n },\n };\n}\n"],"mappings":";AAMA,SAAgB,IAA8B;CAC5C,IAAI;CAEJ,OAAO;EACL,QAA2B;GACzB,GAAQ,MAAM;GAEd,IAAM,IAAa,IAAI,gBAAgB;GAIvC,OAFA,IAAS,GAEF;IACL,iBAAiB,MAAW,KAAc,CAAC,EAAW,OAAO;IAC7D,QAAQ,EAAW;GACrB;EACF;EAEA,WAAW,GAAwB;GAEjC,AADA,GAAQ,MAAM,CAAM,GACpB,IAAS,KAAA;EACX;CACF;AACF"}
1
+ {"version":3,"file":"_navigation.js","names":[],"sources":["../src/_navigation.ts"],"sourcesContent":["export type NavigationAttempt = {\n isCurrent(): boolean;\n readonly signal: AbortSignal;\n};\n\n/** Coordinates navigation ownership so stale work cannot commit router state. */\nexport function createNavigationCoordinator() {\n let active: AbortController | undefined;\n\n return {\n begin(): NavigationAttempt {\n active?.abort();\n\n const controller = new AbortController();\n\n active = controller;\n\n return {\n isCurrent: () => active === controller && !controller.signal.aborted,\n signal: controller.signal,\n };\n },\n\n invalidate(reason?: unknown): void {\n active?.abort(reason);\n active = undefined;\n },\n };\n}\n"],"mappings":"AAMA,SAAgB,6BAA8B,CAC5C,IAAI,EAEJ,MAAO,CACL,OAA2B,CACzB,GAAQ,MAAM,EAEd,IAAM,EAAa,IAAI,gBAIvB,MAFA,GAAS,EAEF,CACL,cAAiB,IAAW,GAAc,CAAC,EAAW,OAAO,QAC7D,OAAQ,EAAW,MACrB,CACF,EAEA,WAAW,EAAwB,CACjC,GAAQ,MAAM,CAAM,EACpB,EAAS,IAAA,EACX,CACF,CACF"}
package/dist/compile.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs");require("./_dev.cjs");const t=require("./path.cjs");function n(n){let r=[],i=(n,a,o,s,c)=>{if(a.index&&a.path!==void 0)throw new e.WayfinderRouteError(`Route "${n}" cannot define both index and path`);if(!a.index&&a.path===void 0)throw new e.WayfinderRouteError(`Route "${n}" must define path or set index: true`);let l=a.index?o:t.normalizePath(a.path?t.joinPaths(o,a.path):o),u=[...s,{dataFn:a.data,name:n,onError:a.onError}],d=[...c,...a.middleware??[]];if(a.children)for(let[e,t]of Object.entries(a.children))i(`${n}.${e}`,t,l,u,d);if(a.redirect!==void 0||!a.children||a.data!==void 0){let e=u[u.length-1];r.push({branchDefs:u,coerceSearch:a.coerceSearch,leaf:e,matcher:t.compilePathMatcher(l),ownMiddleware:d,path:l,redirect:a.redirect})}};for(let[e,t]of Object.entries(n.routes))i(e,t,`/`,[],[]);let a=new Set;for(let t of r){if(a.has(t.leaf.name))throw new e.WayfinderRouteError(`Duplicate route name: "${t.leaf.name}". A top-level route key must not coincide with a nested route's dot-notation name.`);a.add(t.leaf.name)}let o=!1;for(let e of r){let t=e.path===`/*`||e.path.endsWith(`/*`)||e.path.includes(`:`)&&e.path.endsWith(`*`);o&&!t&&`${e.leaf.name}${e.path}`,t&&(o=!0)}return{records:r,routesByName:new Map(r.map(e=>[e.leaf.name,e]))}}exports.compileRoutes=n;
1
+ const e=require("./errors.cjs"),t=require("./path.cjs");require("./_dev.cjs");function compileRoutes(n){let r=[],compile=(n,i,a,o,s)=>{if(i.index&&i.path!==void 0)throw new e.WayfinderConfigError(`Route "${n}" cannot define both index and path`);if(!i.index&&i.path===void 0)throw new e.WayfinderConfigError(`Route "${n}" must define path or set index: true`);let c=i.index?a:t.normalizePath(i.path?t.joinPaths(a,i.path):a),l=[...o,{dataFn:i.data,name:n,onError:i.onError}],u=[...s,...i.middleware??[]];if(i.children)for(let[e,t]of Object.entries(i.children))compile(`${n}.${e}`,t,c,l,u);if(i.redirect!==void 0||!i.children||i.data!==void 0){let e=l[l.length-1];r.push({branchDefs:l,coerceSearch:i.coerceSearch,leaf:e,matcher:t.compilePathMatcher(c),ownMiddleware:u,path:c,redirect:i.redirect})}};for(let[e,t]of Object.entries(n.routes))compile(e,t,`/`,[],[]);let i=new Set;for(let t of r){if(i.has(t.leaf.name))throw new e.WayfinderConfigError(`Duplicate route name: "${t.leaf.name}". A top-level route key must not coincide with a nested route's dot-notation name.`);i.add(t.leaf.name)}let a=!1;for(let e of r){let t=e.path===`/*`||e.path.endsWith(`/*`)||e.path.includes(`:`)&&e.path.endsWith(`*`);a&&!t&&`${e.leaf.name}${e.path}`,t&&(a=!0)}return{records:r,routesByName:new Map(r.map(e=>[e.leaf.name,e]))}}exports.compileRoutes=compileRoutes;
2
2
  //# sourceMappingURL=compile.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"compile.cjs","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\nimport type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nexport type CompiledRoutes = {\n records: readonly RouteRecord[];\n routesByName: ReadonlyMap<string, RouteRecord>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable>(options: RouterOptions<TRoutes>): CompiledRoutes {\n const records: RouteRecord[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef[],\n ancestorMiddleware: RouteRecord['ownMiddleware'],\n ): void => {\n if (route.index && route.path !== undefined) {\n throw new WayfinderRouteError(`Route \"${name}\" cannot define both index and path`);\n }\n\n if (!route.index && route.path === undefined) {\n throw new WayfinderRouteError(`Route \"${name}\" must define path or set index: true`);\n }\n\n const ownPath = route.index\n ? ancestorPath\n : normalizePath(route.path ? joinPaths(ancestorPath, route.path) : ancestorPath);\n\n const branchDefs: RouteBranchDef[] = [\n ...ancestorBranchDefs,\n {\n dataFn: route.data,\n name,\n onError: route.onError as RouteBranchDef['onError'],\n },\n ];\n\n const ownMiddleware: Middleware[] = [\n ...ancestorMiddleware,\n ...((route.middleware ?? []) as unknown as Middleware[]),\n ];\n\n if (route.children) {\n for (const [childName, childRoute] of Object.entries(route.children)) {\n compile(`${name}.${childName}`, childRoute, ownPath, branchDefs, ownMiddleware);\n }\n }\n\n // Emit a record for leaf routes (no children) and routes with data or redirect.\n // A bare parent-only route (children but no data/redirect) is not emitted as a leaf.\n if (route.redirect !== undefined || !route.children || route.data !== undefined) {\n const leaf = branchDefs[branchDefs.length - 1]!;\n\n records.push({\n branchDefs,\n coerceSearch: route.coerceSearch,\n leaf,\n matcher: compilePathMatcher(ownPath),\n ownMiddleware,\n path: ownPath,\n redirect: route.redirect,\n });\n }\n };\n\n for (const [name, route] of Object.entries(options.routes)) {\n compile(name, route, '/', [], []);\n }\n\n // Validate duplicate names.\n const namesSeen = new Set<string>();\n\n for (const record of records) {\n if (namesSeen.has(record.leaf.name)) {\n throw new WayfinderRouteError(\n `Duplicate route name: \"${record.leaf.name}\". A top-level route key must not coincide with a nested route's dot-notation name.`,\n );\n }\n\n namesSeen.add(record.leaf.name);\n }\n\n // Warn when a catch-all or wildcard-param route precedes more specific routes.\n // Routes match in array order (object key order), so a wildcard placed too early silently shadows later routes.\n let wildcardSeen = false;\n\n for (const record of records) {\n const isCatchAll =\n record.path === '/*' || record.path.endsWith('/*') || (record.path.includes(':') && record.path.endsWith('*'));\n\n if (wildcardSeen && !isCatchAll) {\n warn(\n `Route \"${record.leaf.name}\" (${record.path}) is defined after a wildcard/catch-all route and will never match. Move specific routes before wildcards.`,\n );\n }\n\n if (isCatchAll) wildcardSeen = true;\n }\n\n return {\n records,\n routesByName: new Map(records.map((r) => [r.leaf.name, r])),\n };\n}\n"],"mappings":"oFAUA,SAAgB,EAA0C,EAAiD,CACzG,IAAM,EAAyB,CAAC,EAE1B,GACJ,EACA,EACA,EACA,EACA,IACS,CACT,GAAI,EAAM,OAAS,EAAM,OAAS,IAAA,GAChC,MAAM,IAAI,EAAA,oBAAoB,UAAU,EAAK,oCAAoC,EAGnF,GAAI,CAAC,EAAM,OAAS,EAAM,OAAS,IAAA,GACjC,MAAM,IAAI,EAAA,oBAAoB,UAAU,EAAK,sCAAsC,EAGrF,IAAM,EAAU,EAAM,MAClB,EACA,EAAA,cAAc,EAAM,KAAO,EAAA,UAAU,EAAc,EAAM,IAAI,EAAI,CAAY,EAE3E,EAA+B,CACnC,GAAG,EACH,CACE,OAAQ,EAAM,KACd,OACA,QAAS,EAAM,OACjB,CACF,EAEM,EAA8B,CAClC,GAAG,EACH,GAAK,EAAM,YAAc,CAAC,CAC5B,EAEA,GAAI,EAAM,SACR,IAAK,GAAM,CAAC,EAAW,KAAe,OAAO,QAAQ,EAAM,QAAQ,EACjE,EAAQ,GAAG,EAAK,GAAG,IAAa,EAAY,EAAS,EAAY,CAAa,EAMlF,GAAI,EAAM,WAAa,IAAA,IAAa,CAAC,EAAM,UAAY,EAAM,OAAS,IAAA,GAAW,CAC/E,IAAM,EAAO,EAAW,EAAW,OAAS,GAE5C,EAAQ,KAAK,CACX,aACA,aAAc,EAAM,aACpB,OACA,QAAS,EAAA,mBAAmB,CAAO,EACnC,gBACA,KAAM,EACN,SAAU,EAAM,QAClB,CAAC,CACH,CACF,EAEA,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAQ,MAAM,EACvD,EAAQ,EAAM,EAAO,IAAK,CAAC,EAAG,CAAC,CAAC,EAIlC,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,KAAU,EAAS,CAC5B,GAAI,EAAU,IAAI,EAAO,KAAK,IAAI,EAChC,MAAM,IAAI,EAAA,oBACR,0BAA0B,EAAO,KAAK,KAAK,oFAC7C,EAGF,EAAU,IAAI,EAAO,KAAK,IAAI,CAChC,CAIA,IAAI,EAAe,GAEnB,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EACJ,EAAO,OAAS,MAAQ,EAAO,KAAK,SAAS,IAAI,GAAM,EAAO,KAAK,SAAS,GAAG,GAAK,EAAO,KAAK,SAAS,GAAG,EAE1G,GAAgB,CAAC,GAEjB,GAAU,EAAO,KAAK,KAAtB,EAAgC,EAAO,KAAvC,EAIA,IAAY,EAAe,GACjC,CAEA,MAAO,CACL,UACA,aAAc,IAAI,IAAI,EAAQ,IAAK,GAAM,CAAC,EAAE,KAAK,KAAM,CAAC,CAAC,CAAC,CAC5D,CACF"}
1
+ {"version":3,"file":"compile.cjs","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { WayfinderConfigError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\nimport type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nexport type CompiledRoutes = {\n records: readonly RouteRecord[];\n routesByName: ReadonlyMap<string, RouteRecord>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable>(options: RouterOptions<TRoutes>): CompiledRoutes {\n const records: RouteRecord[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef[],\n ancestorMiddleware: RouteRecord['ownMiddleware'],\n ): void => {\n if (route.index && route.path !== undefined) {\n throw new WayfinderConfigError(`Route \"${name}\" cannot define both index and path`);\n }\n\n if (!route.index && route.path === undefined) {\n throw new WayfinderConfigError(`Route \"${name}\" must define path or set index: true`);\n }\n\n const ownPath = route.index\n ? ancestorPath\n : normalizePath(route.path ? joinPaths(ancestorPath, route.path) : ancestorPath);\n\n const branchDefs: RouteBranchDef[] = [\n ...ancestorBranchDefs,\n {\n dataFn: route.data,\n name,\n onError: route.onError as RouteBranchDef['onError'],\n },\n ];\n\n const ownMiddleware: Middleware[] = [\n ...ancestorMiddleware,\n ...((route.middleware ?? []) as unknown as Middleware[]),\n ];\n\n if (route.children) {\n for (const [childName, childRoute] of Object.entries(route.children)) {\n compile(`${name}.${childName}`, childRoute, ownPath, branchDefs, ownMiddleware);\n }\n }\n\n // Emit a record for leaf routes (no children) and routes with data or redirect.\n // A bare parent-only route (children but no data/redirect) is not emitted as a leaf.\n if (route.redirect !== undefined || !route.children || route.data !== undefined) {\n const leaf = branchDefs[branchDefs.length - 1]!;\n\n records.push({\n branchDefs,\n coerceSearch: route.coerceSearch,\n leaf,\n matcher: compilePathMatcher(ownPath),\n ownMiddleware,\n path: ownPath,\n redirect: route.redirect,\n });\n }\n };\n\n for (const [name, route] of Object.entries(options.routes)) {\n compile(name, route, '/', [], []);\n }\n\n // Validate duplicate names.\n const namesSeen = new Set<string>();\n\n for (const record of records) {\n if (namesSeen.has(record.leaf.name)) {\n throw new WayfinderConfigError(\n `Duplicate route name: \"${record.leaf.name}\". A top-level route key must not coincide with a nested route's dot-notation name.`,\n );\n }\n\n namesSeen.add(record.leaf.name);\n }\n\n // Warn when a catch-all or wildcard-param route precedes more specific routes.\n // Routes match in array order (object key order), so a wildcard placed too early silently shadows later routes.\n let wildcardSeen = false;\n\n for (const record of records) {\n const isCatchAll =\n record.path === '/*' || record.path.endsWith('/*') || (record.path.includes(':') && record.path.endsWith('*'));\n\n if (wildcardSeen && !isCatchAll) {\n warn(\n `Route \"${record.leaf.name}\" (${record.path}) is defined after a wildcard/catch-all route and will never match. Move specific routes before wildcards.`,\n );\n }\n\n if (isCatchAll) wildcardSeen = true;\n }\n\n return {\n records,\n routesByName: new Map(records.map((r) => [r.leaf.name, r])),\n };\n}\n"],"mappings":"8EAUA,SAAgB,cAA0C,EAAiD,CACzG,IAAM,EAAyB,CAAC,EAE1B,SACJ,EACA,EACA,EACA,EACA,IACS,CACT,GAAI,EAAM,OAAS,EAAM,OAAS,IAAA,GAChC,MAAM,IAAI,EAAA,qBAAqB,UAAU,EAAK,oCAAoC,EAGpF,GAAI,CAAC,EAAM,OAAS,EAAM,OAAS,IAAA,GACjC,MAAM,IAAI,EAAA,qBAAqB,UAAU,EAAK,sCAAsC,EAGtF,IAAM,EAAU,EAAM,MAClB,EACA,EAAA,cAAc,EAAM,KAAO,EAAA,UAAU,EAAc,EAAM,IAAI,EAAI,CAAY,EAE3E,EAA+B,CACnC,GAAG,EACH,CACE,OAAQ,EAAM,KACd,OACA,QAAS,EAAM,OACjB,CACF,EAEM,EAA8B,CAClC,GAAG,EACH,GAAK,EAAM,YAAc,CAAC,CAC5B,EAEA,GAAI,EAAM,SACR,IAAK,GAAM,CAAC,EAAW,KAAe,OAAO,QAAQ,EAAM,QAAQ,EACjE,QAAQ,GAAG,EAAK,GAAG,IAAa,EAAY,EAAS,EAAY,CAAa,EAMlF,GAAI,EAAM,WAAa,IAAA,IAAa,CAAC,EAAM,UAAY,EAAM,OAAS,IAAA,GAAW,CAC/E,IAAM,EAAO,EAAW,EAAW,OAAS,GAE5C,EAAQ,KAAK,CACX,aACA,aAAc,EAAM,aACpB,OACA,QAAS,EAAA,mBAAmB,CAAO,EACnC,gBACA,KAAM,EACN,SAAU,EAAM,QAClB,CAAC,CACH,CACF,EAEA,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAQ,MAAM,EACvD,QAAQ,EAAM,EAAO,IAAK,CAAC,EAAG,CAAC,CAAC,EAIlC,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,KAAU,EAAS,CAC5B,GAAI,EAAU,IAAI,EAAO,KAAK,IAAI,EAChC,MAAM,IAAI,EAAA,qBACR,0BAA0B,EAAO,KAAK,KAAK,oFAC7C,EAGF,EAAU,IAAI,EAAO,KAAK,IAAI,CAChC,CAIA,IAAI,EAAe,GAEnB,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EACJ,EAAO,OAAS,MAAQ,EAAO,KAAK,SAAS,IAAI,GAAM,EAAO,KAAK,SAAS,GAAG,GAAK,EAAO,KAAK,SAAS,GAAG,EAE1G,GAAgB,CAAC,GAEjB,GAAU,EAAO,KAAK,KAAtB,EAAgC,EAAO,KAAvC,EAIA,IAAY,EAAe,GACjC,CAEA,MAAO,CACL,UACA,aAAc,IAAI,IAAI,EAAQ,IAAK,GAAM,CAAC,EAAE,KAAK,KAAM,CAAC,CAAC,CAAC,CAC5D,CACF"}
package/dist/compile.js CHANGED
@@ -1,47 +1,2 @@
1
- import { WayfinderRouteError as e } from "./errors.js";
2
- import "./_dev.js";
3
- import { compilePathMatcher as t, joinPaths as n, normalizePath as r } from "./path.js";
4
- //#region src/compile.ts
5
- function i(i) {
6
- let a = [], o = (i, s, c, l, u) => {
7
- if (s.index && s.path !== void 0) throw new e(`Route "${i}" cannot define both index and path`);
8
- if (!s.index && s.path === void 0) throw new e(`Route "${i}" must define path or set index: true`);
9
- let d = s.index ? c : r(s.path ? n(c, s.path) : c), f = [...l, {
10
- dataFn: s.data,
11
- name: i,
12
- onError: s.onError
13
- }], p = [...u, ...s.middleware ?? []];
14
- if (s.children) for (let [e, t] of Object.entries(s.children)) o(`${i}.${e}`, t, d, f, p);
15
- if (s.redirect !== void 0 || !s.children || s.data !== void 0) {
16
- let e = f[f.length - 1];
17
- a.push({
18
- branchDefs: f,
19
- coerceSearch: s.coerceSearch,
20
- leaf: e,
21
- matcher: t(d),
22
- ownMiddleware: p,
23
- path: d,
24
- redirect: s.redirect
25
- });
26
- }
27
- };
28
- for (let [e, t] of Object.entries(i.routes)) o(e, t, "/", [], []);
29
- let s = /* @__PURE__ */ new Set();
30
- for (let t of a) {
31
- if (s.has(t.leaf.name)) throw new e(`Duplicate route name: "${t.leaf.name}". A top-level route key must not coincide with a nested route's dot-notation name.`);
32
- s.add(t.leaf.name);
33
- }
34
- let c = !1;
35
- for (let e of a) {
36
- let t = e.path === "/*" || e.path.endsWith("/*") || e.path.includes(":") && e.path.endsWith("*");
37
- c && !t && `${e.leaf.name}${e.path}`, t && (c = !0);
38
- }
39
- return {
40
- records: a,
41
- routesByName: new Map(a.map((e) => [e.leaf.name, e]))
42
- };
43
- }
44
- //#endregion
45
- export { i as compileRoutes };
46
-
1
+ import{WayfinderConfigError as e}from"./errors.js";import{compilePathMatcher as t,joinPaths as n,normalizePath as r}from"./path.js";import"./_dev.js";function compileRoutes(i){let a=[],compile=(i,o,s,c,l)=>{if(o.index&&o.path!==void 0)throw new e(`Route "${i}" cannot define both index and path`);if(!o.index&&o.path===void 0)throw new e(`Route "${i}" must define path or set index: true`);let u=o.index?s:r(o.path?n(s,o.path):s),d=[...c,{dataFn:o.data,name:i,onError:o.onError}],f=[...l,...o.middleware??[]];if(o.children)for(let[e,t]of Object.entries(o.children))compile(`${i}.${e}`,t,u,d,f);if(o.redirect!==void 0||!o.children||o.data!==void 0){let e=d[d.length-1];a.push({branchDefs:d,coerceSearch:o.coerceSearch,leaf:e,matcher:t(u),ownMiddleware:f,path:u,redirect:o.redirect})}};for(let[e,t]of Object.entries(i.routes))compile(e,t,`/`,[],[]);let o=new Set;for(let t of a){if(o.has(t.leaf.name))throw new e(`Duplicate route name: "${t.leaf.name}". A top-level route key must not coincide with a nested route's dot-notation name.`);o.add(t.leaf.name)}let s=!1;for(let e of a){let t=e.path===`/*`||e.path.endsWith(`/*`)||e.path.includes(`:`)&&e.path.endsWith(`*`);s&&!t&&`${e.leaf.name}${e.path}`,t&&(s=!0)}return{records:a,routesByName:new Map(a.map(e=>[e.leaf.name,e]))}}export{compileRoutes};
47
2
  //# sourceMappingURL=compile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compile.js","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\nimport type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nexport type CompiledRoutes = {\n records: readonly RouteRecord[];\n routesByName: ReadonlyMap<string, RouteRecord>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable>(options: RouterOptions<TRoutes>): CompiledRoutes {\n const records: RouteRecord[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef[],\n ancestorMiddleware: RouteRecord['ownMiddleware'],\n ): void => {\n if (route.index && route.path !== undefined) {\n throw new WayfinderRouteError(`Route \"${name}\" cannot define both index and path`);\n }\n\n if (!route.index && route.path === undefined) {\n throw new WayfinderRouteError(`Route \"${name}\" must define path or set index: true`);\n }\n\n const ownPath = route.index\n ? ancestorPath\n : normalizePath(route.path ? joinPaths(ancestorPath, route.path) : ancestorPath);\n\n const branchDefs: RouteBranchDef[] = [\n ...ancestorBranchDefs,\n {\n dataFn: route.data,\n name,\n onError: route.onError as RouteBranchDef['onError'],\n },\n ];\n\n const ownMiddleware: Middleware[] = [\n ...ancestorMiddleware,\n ...((route.middleware ?? []) as unknown as Middleware[]),\n ];\n\n if (route.children) {\n for (const [childName, childRoute] of Object.entries(route.children)) {\n compile(`${name}.${childName}`, childRoute, ownPath, branchDefs, ownMiddleware);\n }\n }\n\n // Emit a record for leaf routes (no children) and routes with data or redirect.\n // A bare parent-only route (children but no data/redirect) is not emitted as a leaf.\n if (route.redirect !== undefined || !route.children || route.data !== undefined) {\n const leaf = branchDefs[branchDefs.length - 1]!;\n\n records.push({\n branchDefs,\n coerceSearch: route.coerceSearch,\n leaf,\n matcher: compilePathMatcher(ownPath),\n ownMiddleware,\n path: ownPath,\n redirect: route.redirect,\n });\n }\n };\n\n for (const [name, route] of Object.entries(options.routes)) {\n compile(name, route, '/', [], []);\n }\n\n // Validate duplicate names.\n const namesSeen = new Set<string>();\n\n for (const record of records) {\n if (namesSeen.has(record.leaf.name)) {\n throw new WayfinderRouteError(\n `Duplicate route name: \"${record.leaf.name}\". A top-level route key must not coincide with a nested route's dot-notation name.`,\n );\n }\n\n namesSeen.add(record.leaf.name);\n }\n\n // Warn when a catch-all or wildcard-param route precedes more specific routes.\n // Routes match in array order (object key order), so a wildcard placed too early silently shadows later routes.\n let wildcardSeen = false;\n\n for (const record of records) {\n const isCatchAll =\n record.path === '/*' || record.path.endsWith('/*') || (record.path.includes(':') && record.path.endsWith('*'));\n\n if (wildcardSeen && !isCatchAll) {\n warn(\n `Route \"${record.leaf.name}\" (${record.path}) is defined after a wildcard/catch-all route and will never match. Move specific routes before wildcards.`,\n );\n }\n\n if (isCatchAll) wildcardSeen = true;\n }\n\n return {\n records,\n routesByName: new Map(records.map((r) => [r.leaf.name, r])),\n };\n}\n"],"mappings":";;;;AAUA,SAAgB,EAA0C,GAAiD;CACzG,IAAM,IAAyB,CAAC,GAE1B,KACJ,GACA,GACA,GACA,GACA,MACS;EACT,IAAI,EAAM,SAAS,EAAM,SAAS,KAAA,GAChC,MAAM,IAAI,EAAoB,UAAU,EAAK,oCAAoC;EAGnF,IAAI,CAAC,EAAM,SAAS,EAAM,SAAS,KAAA,GACjC,MAAM,IAAI,EAAoB,UAAU,EAAK,sCAAsC;EAGrF,IAAM,IAAU,EAAM,QAClB,IACA,EAAc,EAAM,OAAO,EAAU,GAAc,EAAM,IAAI,IAAI,CAAY,GAE3E,IAA+B,CACnC,GAAG,GACH;GACE,QAAQ,EAAM;GACd;GACA,SAAS,EAAM;EACjB,CACF,GAEM,IAA8B,CAClC,GAAG,GACH,GAAK,EAAM,cAAc,CAAC,CAC5B;EAEA,IAAI,EAAM,UACR,KAAK,IAAM,CAAC,GAAW,MAAe,OAAO,QAAQ,EAAM,QAAQ,GACjE,EAAQ,GAAG,EAAK,GAAG,KAAa,GAAY,GAAS,GAAY,CAAa;EAMlF,IAAI,EAAM,aAAa,KAAA,KAAa,CAAC,EAAM,YAAY,EAAM,SAAS,KAAA,GAAW;GAC/E,IAAM,IAAO,EAAW,EAAW,SAAS;GAE5C,EAAQ,KAAK;IACX;IACA,cAAc,EAAM;IACpB;IACA,SAAS,EAAmB,CAAO;IACnC;IACA,MAAM;IACN,UAAU,EAAM;GAClB,CAAC;EACH;CACF;CAEA,KAAK,IAAM,CAAC,GAAM,MAAU,OAAO,QAAQ,EAAQ,MAAM,GACvD,EAAQ,GAAM,GAAO,KAAK,CAAC,GAAG,CAAC,CAAC;CAIlC,IAAM,oBAAY,IAAI,IAAY;CAElC,KAAK,IAAM,KAAU,GAAS;EAC5B,IAAI,EAAU,IAAI,EAAO,KAAK,IAAI,GAChC,MAAM,IAAI,EACR,0BAA0B,EAAO,KAAK,KAAK,oFAC7C;EAGF,EAAU,IAAI,EAAO,KAAK,IAAI;CAChC;CAIA,IAAI,IAAe;CAEnB,KAAK,IAAM,KAAU,GAAS;EAC5B,IAAM,IACJ,EAAO,SAAS,QAAQ,EAAO,KAAK,SAAS,IAAI,KAAM,EAAO,KAAK,SAAS,GAAG,KAAK,EAAO,KAAK,SAAS,GAAG;EAQ9G,AANI,KAAgB,CAAC,KAEjB,GAAU,EAAO,KAAK,KAAtB,EAAgC,EAAO,KAAvC,GAIA,MAAY,IAAe;CACjC;CAEA,OAAO;EACL;EACA,cAAc,IAAI,IAAI,EAAQ,KAAK,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC;CAC5D;AACF"}
1
+ {"version":3,"file":"compile.js","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import { warn } from './_dev';\nimport { WayfinderConfigError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\nimport type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nexport type CompiledRoutes = {\n records: readonly RouteRecord[];\n routesByName: ReadonlyMap<string, RouteRecord>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable>(options: RouterOptions<TRoutes>): CompiledRoutes {\n const records: RouteRecord[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef[],\n ancestorMiddleware: RouteRecord['ownMiddleware'],\n ): void => {\n if (route.index && route.path !== undefined) {\n throw new WayfinderConfigError(`Route \"${name}\" cannot define both index and path`);\n }\n\n if (!route.index && route.path === undefined) {\n throw new WayfinderConfigError(`Route \"${name}\" must define path or set index: true`);\n }\n\n const ownPath = route.index\n ? ancestorPath\n : normalizePath(route.path ? joinPaths(ancestorPath, route.path) : ancestorPath);\n\n const branchDefs: RouteBranchDef[] = [\n ...ancestorBranchDefs,\n {\n dataFn: route.data,\n name,\n onError: route.onError as RouteBranchDef['onError'],\n },\n ];\n\n const ownMiddleware: Middleware[] = [\n ...ancestorMiddleware,\n ...((route.middleware ?? []) as unknown as Middleware[]),\n ];\n\n if (route.children) {\n for (const [childName, childRoute] of Object.entries(route.children)) {\n compile(`${name}.${childName}`, childRoute, ownPath, branchDefs, ownMiddleware);\n }\n }\n\n // Emit a record for leaf routes (no children) and routes with data or redirect.\n // A bare parent-only route (children but no data/redirect) is not emitted as a leaf.\n if (route.redirect !== undefined || !route.children || route.data !== undefined) {\n const leaf = branchDefs[branchDefs.length - 1]!;\n\n records.push({\n branchDefs,\n coerceSearch: route.coerceSearch,\n leaf,\n matcher: compilePathMatcher(ownPath),\n ownMiddleware,\n path: ownPath,\n redirect: route.redirect,\n });\n }\n };\n\n for (const [name, route] of Object.entries(options.routes)) {\n compile(name, route, '/', [], []);\n }\n\n // Validate duplicate names.\n const namesSeen = new Set<string>();\n\n for (const record of records) {\n if (namesSeen.has(record.leaf.name)) {\n throw new WayfinderConfigError(\n `Duplicate route name: \"${record.leaf.name}\". A top-level route key must not coincide with a nested route's dot-notation name.`,\n );\n }\n\n namesSeen.add(record.leaf.name);\n }\n\n // Warn when a catch-all or wildcard-param route precedes more specific routes.\n // Routes match in array order (object key order), so a wildcard placed too early silently shadows later routes.\n let wildcardSeen = false;\n\n for (const record of records) {\n const isCatchAll =\n record.path === '/*' || record.path.endsWith('/*') || (record.path.includes(':') && record.path.endsWith('*'));\n\n if (wildcardSeen && !isCatchAll) {\n warn(\n `Route \"${record.leaf.name}\" (${record.path}) is defined after a wildcard/catch-all route and will never match. Move specific routes before wildcards.`,\n );\n }\n\n if (isCatchAll) wildcardSeen = true;\n }\n\n return {\n records,\n routesByName: new Map(records.map((r) => [r.leaf.name, r])),\n };\n}\n"],"mappings":"sJAUA,SAAgB,cAA0C,EAAiD,CACzG,IAAM,EAAyB,CAAC,EAE1B,SACJ,EACA,EACA,EACA,EACA,IACS,CACT,GAAI,EAAM,OAAS,EAAM,OAAS,IAAA,GAChC,MAAM,IAAI,EAAqB,UAAU,EAAK,oCAAoC,EAGpF,GAAI,CAAC,EAAM,OAAS,EAAM,OAAS,IAAA,GACjC,MAAM,IAAI,EAAqB,UAAU,EAAK,sCAAsC,EAGtF,IAAM,EAAU,EAAM,MAClB,EACA,EAAc,EAAM,KAAO,EAAU,EAAc,EAAM,IAAI,EAAI,CAAY,EAE3E,EAA+B,CACnC,GAAG,EACH,CACE,OAAQ,EAAM,KACd,OACA,QAAS,EAAM,OACjB,CACF,EAEM,EAA8B,CAClC,GAAG,EACH,GAAK,EAAM,YAAc,CAAC,CAC5B,EAEA,GAAI,EAAM,SACR,IAAK,GAAM,CAAC,EAAW,KAAe,OAAO,QAAQ,EAAM,QAAQ,EACjE,QAAQ,GAAG,EAAK,GAAG,IAAa,EAAY,EAAS,EAAY,CAAa,EAMlF,GAAI,EAAM,WAAa,IAAA,IAAa,CAAC,EAAM,UAAY,EAAM,OAAS,IAAA,GAAW,CAC/E,IAAM,EAAO,EAAW,EAAW,OAAS,GAE5C,EAAQ,KAAK,CACX,aACA,aAAc,EAAM,aACpB,OACA,QAAS,EAAmB,CAAO,EACnC,gBACA,KAAM,EACN,SAAU,EAAM,QAClB,CAAC,CACH,CACF,EAEA,IAAK,GAAM,CAAC,EAAM,KAAU,OAAO,QAAQ,EAAQ,MAAM,EACvD,QAAQ,EAAM,EAAO,IAAK,CAAC,EAAG,CAAC,CAAC,EAIlC,IAAM,EAAY,IAAI,IAEtB,IAAK,IAAM,KAAU,EAAS,CAC5B,GAAI,EAAU,IAAI,EAAO,KAAK,IAAI,EAChC,MAAM,IAAI,EACR,0BAA0B,EAAO,KAAK,KAAK,oFAC7C,EAGF,EAAU,IAAI,EAAO,KAAK,IAAI,CAChC,CAIA,IAAI,EAAe,GAEnB,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EACJ,EAAO,OAAS,MAAQ,EAAO,KAAK,SAAS,IAAI,GAAM,EAAO,KAAK,SAAS,GAAG,GAAK,EAAO,KAAK,SAAS,GAAG,EAE1G,GAAgB,CAAC,GAEjB,GAAU,EAAO,KAAK,KAAtB,EAAgC,EAAO,KAAvC,EAIA,IAAY,EAAe,GACjC,CAEA,MAAO,CACL,UACA,aAAc,IAAI,IAAI,EAAQ,IAAK,GAAM,CAAC,EAAE,KAAK,KAAM,CAAC,CAAC,CAAC,CAC5D,CACF"}
package/dist/context.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./errors.cjs");require("./_dev.cjs");function t(e){return{error:e.error,location:e.location,matches:e.matches,status:e.status}}function n(e,t,n,r){return e.map((e,i)=>({data:r[i],name:e.name,params:{...t},pathname:n}))}function r(e,t,n,r,i){return{hash:e.hash,historyState:e.historyState,locals:{},matches:r,navigate:i,params:n,pathname:e.pathname,query:t}}async function i(t,n,r,i){let a=!1;async function o(s){if(s<n.length){let r=!1;try{await n[s]?.(t,async()=>{if(r)throw new e.WayfinderApiError(`next() called multiple times`);r=!0,await o(s+1)})}catch(e){throw i?.(e)??e}return}a=!0,await r()}return await o(0),a}function a(e,t,n){if(n){n(e,t);return}}exports.buildMatchBranch=n,exports.createRouteContext=r,exports.createRouteState=t,exports.executeMiddlewarePipeline=i,exports.reportError=a;
1
+ const e=require("./errors.cjs");require("./_dev.cjs");function createRouteState(e){return{error:e.error,location:e.location,matches:e.matches,status:e.status}}function buildMatchBranch(e,t,n,r){return e.map((e,i)=>({data:r[i],name:e.name,params:{...t},pathname:n}))}function createRouteContext(e,t,n,r,i){return{hash:e.hash,historyState:e.historyState,locals:{},matches:r,navigate:i,params:n,pathname:e.pathname,query:t}}async function executeMiddlewarePipeline(t,n,r,i){let a=!1;async function dispatch(o){if(o<n.length){let r=!1;try{await n[o]?.(t,async()=>{if(r)throw new e.WayfinderApiError(`next() called multiple times`);r=!0,await dispatch(o+1)})}catch(e){throw i?.(e)??e}return}a=!0,await r()}return await dispatch(0),a}function reportError(e,t,n){if(n){n(e,t);return}}exports.buildMatchBranch=buildMatchBranch,exports.createRouteContext=createRouteContext,exports.createRouteState=createRouteState,exports.executeMiddlewarePipeline=executeMiddlewarePipeline,exports.reportError=reportError;
2
2
  //# sourceMappingURL=context.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.cjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\nimport type {\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatch,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch;\n status: NavigationStatus;\n}): RouteState {\n return {\n error: input.error,\n location: input.location,\n matches: input.matches,\n status: input.status,\n };\n}\n\n/**\n * Build a RouteMatchBranch from compiled defs and data results.\n */\nexport function buildMatchBranch(\n branchDefs: readonly RouteBranchDef[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n): RouteMatchBranch {\n return branchDefs.map(\n (def, i): RouteMatch => ({\n data: dataResults[i],\n name: def.name,\n params: { ...params },\n pathname,\n }),\n );\n}\n\n// ─── Context factory ──────────────────────────────────────────────────────────\n\nexport function createRouteContext<TRoutes extends RouteTable>(\n location: RouteLocation,\n resolvedQuery: ResolvedQueryParams,\n params: RouteParams,\n matches: RouteMatchBranch,\n navigate: RouteContext<RouteParams, TRoutes>['navigate'],\n): RouteContext<RouteParams, TRoutes> {\n return {\n hash: location.hash,\n historyState: location.historyState,\n locals: {},\n matches,\n navigate,\n params,\n pathname: location.pathname,\n query: resolvedQuery,\n };\n}\n\n// ─── Middleware pipeline ──────────────────────────────────────────────────────\n\nexport async function executeMiddlewarePipeline<TRoutes extends RouteTable>(\n context: RouteContext<RouteParams, TRoutes>,\n middleware: readonly Middleware<TRoutes>[],\n terminal: () => Promise<void>,\n wrapMiddlewareError?: (error: unknown) => unknown,\n): Promise<boolean> {\n let terminalRan = false;\n\n async function dispatch(index: number): Promise<void> {\n if (index < middleware.length) {\n let called = false;\n\n try {\n await middleware[index]?.(context, async () => {\n if (called) throw new WayfinderApiError('next() called multiple times');\n\n called = true;\n await dispatch(index + 1);\n });\n } catch (error) {\n throw wrapMiddlewareError?.(error) ?? error;\n }\n\n return;\n }\n\n terminalRan = true;\n await terminal();\n }\n\n await dispatch(0);\n\n return terminalRan;\n}\n\n// ─── Error reporting ──────────────────────────────────────────────────────────\n\nexport function reportError(\n error: unknown,\n context: RouterErrorContext,\n onError?: (e: unknown, ctx: RouterErrorContext) => void,\n): void {\n if (onError) {\n onError(error, context);\n\n return;\n }\n\n logError('Unhandled router error. Provide an onError callback to handle errors explicitly:', error);\n}\n"],"mappings":"sDAoBA,SAAgB,EAAiB,EAKlB,CACb,MAAO,CACL,MAAO,EAAM,MACb,SAAU,EAAM,SAChB,QAAS,EAAM,QACf,OAAQ,EAAM,MAChB,CACF,CAKA,SAAgB,EACd,EACA,EACA,EACA,EACkB,CAClB,OAAO,EAAW,KACf,EAAK,KAAmB,CACvB,KAAM,EAAY,GAClB,KAAM,EAAI,KACV,OAAQ,CAAE,GAAG,CAAO,EACpB,UACF,EACF,CACF,CAIA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACoC,CACpC,MAAO,CACL,KAAM,EAAS,KACf,aAAc,EAAS,aACvB,OAAQ,CAAC,EACT,UACA,WACA,SACA,SAAU,EAAS,SACnB,MAAO,CACT,CACF,CAIA,eAAsB,EACpB,EACA,EACA,EACA,EACkB,CAClB,IAAI,EAAc,GAElB,eAAe,EAAS,EAA8B,CACpD,GAAI,EAAQ,EAAW,OAAQ,CAC7B,IAAI,EAAS,GAEb,GAAI,CACF,MAAM,EAAW,EAAM,GAAG,EAAS,SAAY,CAC7C,GAAI,EAAQ,MAAM,IAAI,EAAA,kBAAkB,8BAA8B,EAEtE,EAAS,GACT,MAAM,EAAS,EAAQ,CAAC,CAC1B,CAAC,CACH,OAAS,EAAO,CACd,MAAM,IAAsB,CAAK,GAAK,CACxC,CAEA,MACF,CAEA,EAAc,GACd,MAAM,EAAS,CACjB,CAIA,OAFA,MAAM,EAAS,CAAC,EAET,CACT,CAIA,SAAgB,EACd,EACA,EACA,EACM,CACN,GAAI,EAAS,CACX,EAAQ,EAAO,CAAO,EAEtB,MACF,CAGF"}
1
+ {"version":3,"file":"context.cjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\nimport type {\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatch,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch;\n status: NavigationStatus;\n}): RouteState {\n return {\n error: input.error,\n location: input.location,\n matches: input.matches,\n status: input.status,\n };\n}\n\n/**\n * Build a RouteMatchBranch from compiled defs and data results.\n */\nexport function buildMatchBranch(\n branchDefs: readonly RouteBranchDef[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n): RouteMatchBranch {\n return branchDefs.map(\n (def, i): RouteMatch => ({\n data: dataResults[i],\n name: def.name,\n params: { ...params },\n pathname,\n }),\n );\n}\n\n// ─── Context factory ──────────────────────────────────────────────────────────\n\nexport function createRouteContext<TRoutes extends RouteTable>(\n location: RouteLocation,\n resolvedQuery: ResolvedQueryParams,\n params: RouteParams,\n matches: RouteMatchBranch,\n navigate: RouteContext<RouteParams, TRoutes>['navigate'],\n): RouteContext<RouteParams, TRoutes> {\n return {\n hash: location.hash,\n historyState: location.historyState,\n locals: {},\n matches,\n navigate,\n params,\n pathname: location.pathname,\n query: resolvedQuery,\n };\n}\n\n// ─── Middleware pipeline ──────────────────────────────────────────────────────\n\nexport async function executeMiddlewarePipeline<TRoutes extends RouteTable>(\n context: RouteContext<RouteParams, TRoutes>,\n middleware: readonly Middleware<TRoutes>[],\n terminal: () => Promise<void>,\n wrapMiddlewareError?: (error: unknown) => unknown,\n): Promise<boolean> {\n let terminalRan = false;\n\n async function dispatch(index: number): Promise<void> {\n if (index < middleware.length) {\n let called = false;\n\n try {\n await middleware[index]?.(context, async () => {\n if (called) throw new WayfinderApiError('next() called multiple times');\n\n called = true;\n await dispatch(index + 1);\n });\n } catch (error) {\n throw wrapMiddlewareError?.(error) ?? error;\n }\n\n return;\n }\n\n terminalRan = true;\n await terminal();\n }\n\n await dispatch(0);\n\n return terminalRan;\n}\n\n// ─── Error reporting ──────────────────────────────────────────────────────────\n\nexport function reportError(\n error: unknown,\n context: RouterErrorContext,\n onError?: (e: unknown, ctx: RouterErrorContext) => void,\n): void {\n if (onError) {\n onError(error, context);\n\n return;\n }\n\n logError('Unhandled router error. Provide an onError callback to handle errors explicitly:', error);\n}\n"],"mappings":"sDAoBA,SAAgB,iBAAiB,EAKlB,CACb,MAAO,CACL,MAAO,EAAM,MACb,SAAU,EAAM,SAChB,QAAS,EAAM,QACf,OAAQ,EAAM,MAChB,CACF,CAKA,SAAgB,iBACd,EACA,EACA,EACA,EACkB,CAClB,OAAO,EAAW,KACf,EAAK,KAAmB,CACvB,KAAM,EAAY,GAClB,KAAM,EAAI,KACV,OAAQ,CAAE,GAAG,CAAO,EACpB,UACF,EACF,CACF,CAIA,SAAgB,mBACd,EACA,EACA,EACA,EACA,EACoC,CACpC,MAAO,CACL,KAAM,EAAS,KACf,aAAc,EAAS,aACvB,OAAQ,CAAC,EACT,UACA,WACA,SACA,SAAU,EAAS,SACnB,MAAO,CACT,CACF,CAIA,eAAsB,0BACpB,EACA,EACA,EACA,EACkB,CAClB,IAAI,EAAc,GAElB,eAAe,SAAS,EAA8B,CACpD,GAAI,EAAQ,EAAW,OAAQ,CAC7B,IAAI,EAAS,GAEb,GAAI,CACF,MAAM,EAAW,EAAM,GAAG,EAAS,SAAY,CAC7C,GAAI,EAAQ,MAAM,IAAI,EAAA,kBAAkB,8BAA8B,EAEtE,EAAS,GACT,MAAM,SAAS,EAAQ,CAAC,CAC1B,CAAC,CACH,OAAS,EAAO,CACd,MAAM,IAAsB,CAAK,GAAK,CACxC,CAEA,MACF,CAEA,EAAc,GACd,MAAM,EAAS,CACjB,CAIA,OAFA,MAAM,SAAS,CAAC,EAET,CACT,CAIA,SAAgB,YACd,EACA,EACA,EACM,CACN,GAAI,EAAS,CACX,EAAQ,EAAO,CAAO,EAEtB,MACF,CAGF"}
package/dist/context.js CHANGED
@@ -1,60 +1,2 @@
1
- import { WayfinderApiError as e } from "./errors.js";
2
- import "./_dev.js";
3
- //#region src/context.ts
4
- function t(e) {
5
- return {
6
- error: e.error,
7
- location: e.location,
8
- matches: e.matches,
9
- status: e.status
10
- };
11
- }
12
- function n(e, t, n, r) {
13
- return e.map((e, i) => ({
14
- data: r[i],
15
- name: e.name,
16
- params: { ...t },
17
- pathname: n
18
- }));
19
- }
20
- function r(e, t, n, r, i) {
21
- return {
22
- hash: e.hash,
23
- historyState: e.historyState,
24
- locals: {},
25
- matches: r,
26
- navigate: i,
27
- params: n,
28
- pathname: e.pathname,
29
- query: t
30
- };
31
- }
32
- async function i(t, n, r, i) {
33
- let a = !1;
34
- async function o(s) {
35
- if (s < n.length) {
36
- let r = !1;
37
- try {
38
- await n[s]?.(t, async () => {
39
- if (r) throw new e("next() called multiple times");
40
- r = !0, await o(s + 1);
41
- });
42
- } catch (e) {
43
- throw i?.(e) ?? e;
44
- }
45
- return;
46
- }
47
- a = !0, await r();
48
- }
49
- return await o(0), a;
50
- }
51
- function a(e, t, n) {
52
- if (n) {
53
- n(e, t);
54
- return;
55
- }
56
- }
57
- //#endregion
58
- export { n as buildMatchBranch, r as createRouteContext, t as createRouteState, i as executeMiddlewarePipeline, a as reportError };
59
-
1
+ import{WayfinderApiError as e}from"./errors.js";import"./_dev.js";function createRouteState(e){return{error:e.error,location:e.location,matches:e.matches,status:e.status}}function buildMatchBranch(e,t,n,r){return e.map((e,i)=>({data:r[i],name:e.name,params:{...t},pathname:n}))}function createRouteContext(e,t,n,r,i){return{hash:e.hash,historyState:e.historyState,locals:{},matches:r,navigate:i,params:n,pathname:e.pathname,query:t}}async function executeMiddlewarePipeline(t,n,r,i){let a=!1;async function dispatch(o){if(o<n.length){let r=!1;try{await n[o]?.(t,async()=>{if(r)throw new e(`next() called multiple times`);r=!0,await dispatch(o+1)})}catch(e){throw i?.(e)??e}return}a=!0,await r()}return await dispatch(0),a}function reportError(e,t,n){if(n){n(e,t);return}}export{buildMatchBranch,createRouteContext,createRouteState,executeMiddlewarePipeline,reportError};
60
2
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\nimport type {\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatch,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch;\n status: NavigationStatus;\n}): RouteState {\n return {\n error: input.error,\n location: input.location,\n matches: input.matches,\n status: input.status,\n };\n}\n\n/**\n * Build a RouteMatchBranch from compiled defs and data results.\n */\nexport function buildMatchBranch(\n branchDefs: readonly RouteBranchDef[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n): RouteMatchBranch {\n return branchDefs.map(\n (def, i): RouteMatch => ({\n data: dataResults[i],\n name: def.name,\n params: { ...params },\n pathname,\n }),\n );\n}\n\n// ─── Context factory ──────────────────────────────────────────────────────────\n\nexport function createRouteContext<TRoutes extends RouteTable>(\n location: RouteLocation,\n resolvedQuery: ResolvedQueryParams,\n params: RouteParams,\n matches: RouteMatchBranch,\n navigate: RouteContext<RouteParams, TRoutes>['navigate'],\n): RouteContext<RouteParams, TRoutes> {\n return {\n hash: location.hash,\n historyState: location.historyState,\n locals: {},\n matches,\n navigate,\n params,\n pathname: location.pathname,\n query: resolvedQuery,\n };\n}\n\n// ─── Middleware pipeline ──────────────────────────────────────────────────────\n\nexport async function executeMiddlewarePipeline<TRoutes extends RouteTable>(\n context: RouteContext<RouteParams, TRoutes>,\n middleware: readonly Middleware<TRoutes>[],\n terminal: () => Promise<void>,\n wrapMiddlewareError?: (error: unknown) => unknown,\n): Promise<boolean> {\n let terminalRan = false;\n\n async function dispatch(index: number): Promise<void> {\n if (index < middleware.length) {\n let called = false;\n\n try {\n await middleware[index]?.(context, async () => {\n if (called) throw new WayfinderApiError('next() called multiple times');\n\n called = true;\n await dispatch(index + 1);\n });\n } catch (error) {\n throw wrapMiddlewareError?.(error) ?? error;\n }\n\n return;\n }\n\n terminalRan = true;\n await terminal();\n }\n\n await dispatch(0);\n\n return terminalRan;\n}\n\n// ─── Error reporting ──────────────────────────────────────────────────────────\n\nexport function reportError(\n error: unknown,\n context: RouterErrorContext,\n onError?: (e: unknown, ctx: RouterErrorContext) => void,\n): void {\n if (onError) {\n onError(error, context);\n\n return;\n }\n\n logError('Unhandled router error. Provide an onError callback to handle errors explicitly:', error);\n}\n"],"mappings":";;;AAoBA,SAAgB,EAAiB,GAKlB;CACb,OAAO;EACL,OAAO,EAAM;EACb,UAAU,EAAM;EAChB,SAAS,EAAM;EACf,QAAQ,EAAM;CAChB;AACF;AAKA,SAAgB,EACd,GACA,GACA,GACA,GACkB;CAClB,OAAO,EAAW,KACf,GAAK,OAAmB;EACvB,MAAM,EAAY;EAClB,MAAM,EAAI;EACV,QAAQ,EAAE,GAAG,EAAO;EACpB;CACF,EACF;AACF;AAIA,SAAgB,EACd,GACA,GACA,GACA,GACA,GACoC;CACpC,OAAO;EACL,MAAM,EAAS;EACf,cAAc,EAAS;EACvB,QAAQ,CAAC;EACT;EACA;EACA;EACA,UAAU,EAAS;EACnB,OAAO;CACT;AACF;AAIA,eAAsB,EACpB,GACA,GACA,GACA,GACkB;CAClB,IAAI,IAAc;CAElB,eAAe,EAAS,GAA8B;EACpD,IAAI,IAAQ,EAAW,QAAQ;GAC7B,IAAI,IAAS;GAEb,IAAI;IACF,MAAM,EAAW,EAAM,GAAG,GAAS,YAAY;KAC7C,IAAI,GAAQ,MAAM,IAAI,EAAkB,8BAA8B;KAGtE,AADA,IAAS,IACT,MAAM,EAAS,IAAQ,CAAC;IAC1B,CAAC;GACH,SAAS,GAAO;IACd,MAAM,IAAsB,CAAK,KAAK;GACxC;GAEA;EACF;EAGA,AADA,IAAc,IACd,MAAM,EAAS;CACjB;CAIA,OAFA,MAAM,EAAS,CAAC,GAET;AACT;AAIA,SAAgB,EACd,GACA,GACA,GACM;CACN,IAAI,GAAS;EACX,EAAQ,GAAO,CAAO;EAEtB;CACF;AAGF"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\nimport type {\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatch,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch;\n status: NavigationStatus;\n}): RouteState {\n return {\n error: input.error,\n location: input.location,\n matches: input.matches,\n status: input.status,\n };\n}\n\n/**\n * Build a RouteMatchBranch from compiled defs and data results.\n */\nexport function buildMatchBranch(\n branchDefs: readonly RouteBranchDef[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n): RouteMatchBranch {\n return branchDefs.map(\n (def, i): RouteMatch => ({\n data: dataResults[i],\n name: def.name,\n params: { ...params },\n pathname,\n }),\n );\n}\n\n// ─── Context factory ──────────────────────────────────────────────────────────\n\nexport function createRouteContext<TRoutes extends RouteTable>(\n location: RouteLocation,\n resolvedQuery: ResolvedQueryParams,\n params: RouteParams,\n matches: RouteMatchBranch,\n navigate: RouteContext<RouteParams, TRoutes>['navigate'],\n): RouteContext<RouteParams, TRoutes> {\n return {\n hash: location.hash,\n historyState: location.historyState,\n locals: {},\n matches,\n navigate,\n params,\n pathname: location.pathname,\n query: resolvedQuery,\n };\n}\n\n// ─── Middleware pipeline ──────────────────────────────────────────────────────\n\nexport async function executeMiddlewarePipeline<TRoutes extends RouteTable>(\n context: RouteContext<RouteParams, TRoutes>,\n middleware: readonly Middleware<TRoutes>[],\n terminal: () => Promise<void>,\n wrapMiddlewareError?: (error: unknown) => unknown,\n): Promise<boolean> {\n let terminalRan = false;\n\n async function dispatch(index: number): Promise<void> {\n if (index < middleware.length) {\n let called = false;\n\n try {\n await middleware[index]?.(context, async () => {\n if (called) throw new WayfinderApiError('next() called multiple times');\n\n called = true;\n await dispatch(index + 1);\n });\n } catch (error) {\n throw wrapMiddlewareError?.(error) ?? error;\n }\n\n return;\n }\n\n terminalRan = true;\n await terminal();\n }\n\n await dispatch(0);\n\n return terminalRan;\n}\n\n// ─── Error reporting ──────────────────────────────────────────────────────────\n\nexport function reportError(\n error: unknown,\n context: RouterErrorContext,\n onError?: (e: unknown, ctx: RouterErrorContext) => void,\n): void {\n if (onError) {\n onError(error, context);\n\n return;\n }\n\n logError('Unhandled router error. Provide an onError callback to handle errors explicitly:', error);\n}\n"],"mappings":"kEAoBA,SAAgB,iBAAiB,EAKlB,CACb,MAAO,CACL,MAAO,EAAM,MACb,SAAU,EAAM,SAChB,QAAS,EAAM,QACf,OAAQ,EAAM,MAChB,CACF,CAKA,SAAgB,iBACd,EACA,EACA,EACA,EACkB,CAClB,OAAO,EAAW,KACf,EAAK,KAAmB,CACvB,KAAM,EAAY,GAClB,KAAM,EAAI,KACV,OAAQ,CAAE,GAAG,CAAO,EACpB,UACF,EACF,CACF,CAIA,SAAgB,mBACd,EACA,EACA,EACA,EACA,EACoC,CACpC,MAAO,CACL,KAAM,EAAS,KACf,aAAc,EAAS,aACvB,OAAQ,CAAC,EACT,UACA,WACA,SACA,SAAU,EAAS,SACnB,MAAO,CACT,CACF,CAIA,eAAsB,0BACpB,EACA,EACA,EACA,EACkB,CAClB,IAAI,EAAc,GAElB,eAAe,SAAS,EAA8B,CACpD,GAAI,EAAQ,EAAW,OAAQ,CAC7B,IAAI,EAAS,GAEb,GAAI,CACF,MAAM,EAAW,EAAM,GAAG,EAAS,SAAY,CAC7C,GAAI,EAAQ,MAAM,IAAI,EAAkB,8BAA8B,EAEtE,EAAS,GACT,MAAM,SAAS,EAAQ,CAAC,CAC1B,CAAC,CACH,OAAS,EAAO,CACd,MAAM,IAAsB,CAAK,GAAK,CACxC,CAEA,MACF,CAEA,EAAc,GACd,MAAM,EAAS,CACjB,CAIA,OAFA,MAAM,SAAS,CAAC,EAET,CACT,CAIA,SAAgB,YACd,EACA,EACA,EACM,CACN,GAAI,EAAS,CACX,EAAQ,EAAO,CAAO,EAEtB,MACF,CAGF"}
package/dist/errors.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{constructor(){super(`Router is disposed`)}},n=class extends e{},r=class extends e{constructor(){super(`Redirect loop detected`)}},i=class extends e{};exports.WayfinderApiError=i,exports.WayfinderDisposedError=t,exports.WayfinderError=e,exports.WayfinderRedirectLoopError=r,exports.WayfinderRouteError=n;
1
+ var WayfinderError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},WayfinderDisposedError=class extends WayfinderError{constructor(){super(`Router is disposed`)}},WayfinderConfigError=class extends WayfinderError{},WayfinderRouteError=class extends WayfinderError{},WayfinderRedirectLoopError=class extends WayfinderError{constructor(){super(`Redirect loop detected`)}},WayfinderApiError=class extends WayfinderError{};exports.WayfinderApiError=WayfinderApiError,exports.WayfinderConfigError=WayfinderConfigError,exports.WayfinderDisposedError=WayfinderDisposedError,exports.WayfinderError=WayfinderError,exports.WayfinderRedirectLoopError=WayfinderRedirectLoopError,exports.WayfinderRouteError=WayfinderRouteError;
2
2
  //# sourceMappingURL=errors.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all wayfinder errors. Use `instanceof WayfinderError` to catch any router-originated error. */\nexport class WayfinderError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when any router method is called after the router has been disposed. */\nexport class WayfinderDisposedError extends WayfinderError {\n constructor() {\n super('Router is disposed');\n }\n}\n\n/** Thrown when a route or path definition is malformed. */\nexport class WayfinderRouteError extends WayfinderError {}\n\n/** Thrown when the router detects an infinite redirect loop. */\nexport class WayfinderRedirectLoopError extends WayfinderError {\n constructor() {\n super('Redirect loop detected');\n }\n}\n\n/** Thrown on API misuse (e.g. calling next() multiple times). */\nexport class WayfinderApiError extends WayfinderError {}\n"],"mappings":"AACA,IAAa,EAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,EAAb,cAA4C,CAAe,CACzD,aAAc,CACZ,MAAM,oBAAoB,CAC5B,CACF,EAGa,EAAb,cAAyC,CAAe,CAAC,EAG5C,EAAb,cAAgD,CAAe,CAC7D,aAAc,CACZ,MAAM,wBAAwB,CAChC,CACF,EAGa,EAAb,cAAuC,CAAe,CAAC"}
1
+ {"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all wayfinder errors. Use `instanceof WayfinderError` to catch any router-originated error. */\nexport class WayfinderError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when any router method is called after the router has been disposed. */\nexport class WayfinderDisposedError extends WayfinderError {\n constructor() {\n super('Router is disposed');\n }\n}\n\n/** Thrown when a route or path definition is malformed at `createRouter()` time. */\nexport class WayfinderConfigError extends WayfinderError {}\n\n/** Thrown when a route or path is malformed at navigation time (unknown name, missing param). */\nexport class WayfinderRouteError extends WayfinderError {}\n\n/** Thrown when the router detects an infinite redirect loop. */\nexport class WayfinderRedirectLoopError extends WayfinderError {\n constructor() {\n super('Redirect loop detected');\n }\n}\n\n/** Thrown on API misuse (e.g. calling next() multiple times). */\nexport class WayfinderApiError extends WayfinderError {}\n"],"mappings":"AACA,IAAa,eAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,uBAAb,cAA4C,cAAe,CACzD,aAAc,CACZ,MAAM,oBAAoB,CAC5B,CACF,EAGa,qBAAb,cAA0C,cAAe,CAAC,EAG7C,oBAAb,cAAyC,cAAe,CAAC,EAG5C,2BAAb,cAAgD,cAAe,CAC7D,aAAc,CACZ,MAAM,wBAAwB,CAChC,CACF,EAGa,kBAAb,cAAuC,cAAe,CAAC"}
package/dist/errors.d.ts CHANGED
@@ -6,7 +6,10 @@ export declare class WayfinderError extends Error {
6
6
  export declare class WayfinderDisposedError extends WayfinderError {
7
7
  constructor();
8
8
  }
9
- /** Thrown when a route or path definition is malformed. */
9
+ /** Thrown when a route or path definition is malformed at `createRouter()` time. */
10
+ export declare class WayfinderConfigError extends WayfinderError {
11
+ }
12
+ /** Thrown when a route or path is malformed at navigation time (unknown name, missing param). */
10
13
  export declare class WayfinderRouteError extends WayfinderError {
11
14
  }
12
15
  /** Thrown when the router detects an infinite redirect loop. */
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,kFAAkF;AAClF,qBAAa,sBAAuB,SAAQ,cAAc;;CAIzD;AAED,2DAA2D;AAC3D,qBAAa,mBAAoB,SAAQ,cAAc;CAAG;AAE1D,gEAAgE;AAChE,qBAAa,0BAA2B,SAAQ,cAAc;;CAI7D;AAED,iEAAiE;AACjE,qBAAa,iBAAkB,SAAQ,cAAc;CAAG"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED,kFAAkF;AAClF,qBAAa,sBAAuB,SAAQ,cAAc;;CAIzD;AAED,oFAAoF;AACpF,qBAAa,oBAAqB,SAAQ,cAAc;CAAG;AAE3D,iGAAiG;AACjG,qBAAa,mBAAoB,SAAQ,cAAc;CAAG;AAE1D,gEAAgE;AAChE,qBAAa,0BAA2B,SAAQ,cAAc;;CAI7D;AAED,iEAAiE;AACjE,qBAAa,iBAAkB,SAAQ,cAAc;CAAG"}
package/dist/errors.js CHANGED
@@ -1,18 +1,2 @@
1
- //#region src/errors.ts
2
- var e = class extends Error {
3
- constructor(e, t) {
4
- super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
5
- }
6
- }, t = class extends e {
7
- constructor() {
8
- super("Router is disposed");
9
- }
10
- }, n = class extends e {}, r = class extends e {
11
- constructor() {
12
- super("Redirect loop detected");
13
- }
14
- }, i = class extends e {};
15
- //#endregion
16
- export { i as WayfinderApiError, t as WayfinderDisposedError, e as WayfinderError, r as WayfinderRedirectLoopError, n as WayfinderRouteError };
17
-
1
+ var WayfinderError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},WayfinderDisposedError=class extends WayfinderError{constructor(){super(`Router is disposed`)}},WayfinderConfigError=class extends WayfinderError{},WayfinderRouteError=class extends WayfinderError{},WayfinderRedirectLoopError=class extends WayfinderError{constructor(){super(`Redirect loop detected`)}},WayfinderApiError=class extends WayfinderError{};export{WayfinderApiError,WayfinderConfigError,WayfinderDisposedError,WayfinderError,WayfinderRedirectLoopError,WayfinderRouteError};
18
2
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all wayfinder errors. Use `instanceof WayfinderError` to catch any router-originated error. */\nexport class WayfinderError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when any router method is called after the router has been disposed. */\nexport class WayfinderDisposedError extends WayfinderError {\n constructor() {\n super('Router is disposed');\n }\n}\n\n/** Thrown when a route or path definition is malformed. */\nexport class WayfinderRouteError extends WayfinderError {}\n\n/** Thrown when the router detects an infinite redirect loop. */\nexport class WayfinderRedirectLoopError extends WayfinderError {\n constructor() {\n super('Redirect loop detected');\n }\n}\n\n/** Thrown on API misuse (e.g. calling next() multiple times). */\nexport class WayfinderApiError extends WayfinderError {}\n"],"mappings":";AACA,IAAa,IAAb,cAAoC,MAAM;CACxC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAGa,IAAb,cAA4C,EAAe;CACzD,cAAc;EACZ,MAAM,oBAAoB;CAC5B;AACF,GAGa,IAAb,cAAyC,EAAe,CAAC,GAG5C,IAAb,cAAgD,EAAe;CAC7D,cAAc;EACZ,MAAM,wBAAwB;CAChC;AACF,GAGa,IAAb,cAAuC,EAAe,CAAC"}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all wayfinder errors. Use `instanceof WayfinderError` to catch any router-originated error. */\nexport class WayfinderError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** Thrown when any router method is called after the router has been disposed. */\nexport class WayfinderDisposedError extends WayfinderError {\n constructor() {\n super('Router is disposed');\n }\n}\n\n/** Thrown when a route or path definition is malformed at `createRouter()` time. */\nexport class WayfinderConfigError extends WayfinderError {}\n\n/** Thrown when a route or path is malformed at navigation time (unknown name, missing param). */\nexport class WayfinderRouteError extends WayfinderError {}\n\n/** Thrown when the router detects an infinite redirect loop. */\nexport class WayfinderRedirectLoopError extends WayfinderError {\n constructor() {\n super('Redirect loop detected');\n }\n}\n\n/** Thrown on API misuse (e.g. calling next() multiple times). */\nexport class WayfinderApiError extends WayfinderError {}\n"],"mappings":"AACA,IAAa,eAAb,cAAoC,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAGa,uBAAb,cAA4C,cAAe,CACzD,aAAc,CACZ,MAAM,oBAAoB,CAC5B,CACF,EAGa,qBAAb,cAA0C,cAAe,CAAC,EAG7C,oBAAb,cAAyC,cAAe,CAAC,EAG5C,2BAAb,cAAgD,cAAe,CAC7D,aAAc,CACZ,MAAM,wBAAwB,CAChC,CACF,EAGa,kBAAb,cAAuC,cAAe,CAAC"}
package/dist/guards.cjs CHANGED
@@ -1,2 +1,2 @@
1
- async function e(e,t,n){let r=new Set(t),i=[...e];for(let{handler:e,routes:t}of i)if((t===void 0||t.some(e=>r.has(e)))&&!await e(n))return!1;return!0}exports.runLeaveBlockers=e;
1
+ async function runLeaveBlockers(e,t,n){let r=new Set(t),i=[...e];for(let{handler:e,routes:t}of i)if((t===void 0||t.some(e=>r.has(e)))&&!await e(n))return!1;return!0}exports.runLeaveBlockers=runLeaveBlockers;
2
2
  //# sourceMappingURL=guards.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.cjs","names":[],"sources":["../src/guards.ts"],"sourcesContent":["import type { BeforeLeaveBlocker, NavigationDestination } from './types';\n\n/**\n * A registered leave guard. `routes` scopes the guard to navigations that depart from\n * any route whose name appears in the array (matched against any node in the active branch,\n * not just the leaf). When `routes` is omitted the guard fires on every navigation.\n */\nexport type RegisteredBlocker = {\n handler: BeforeLeaveBlocker;\n routes?: string[];\n};\n\n/**\n * Run all registered leave blockers in registration order.\n * Guards whose `routes` filter does not overlap the current active match names are skipped.\n * Returns `false` as soon as any blocker returns `false`; returns `true` if all pass.\n *\n * A snapshot of the blocker set is taken before iteration so that guards added or removed\n * during execution do not affect the current run.\n *\n * `destination` is passed to each blocker so guards can make context-aware decisions.\n */\nexport async function runLeaveBlockers(\n blockers: ReadonlySet<RegisteredBlocker>,\n activeMatchNames: readonly string[],\n destination: NavigationDestination,\n): Promise<boolean> {\n const activeNames = new Set(activeMatchNames);\n // Snapshot so that removals during iteration don't skip entries.\n const snapshot = [...blockers];\n\n for (const { handler, routes } of snapshot) {\n if (routes !== undefined && !routes.some((name) => activeNames.has(name))) continue;\n\n const allowed = await handler(destination);\n\n if (!allowed) return false;\n }\n\n return true;\n}\n"],"mappings":"AAsBA,eAAsB,EACpB,EACA,EACA,EACkB,CAClB,IAAM,EAAc,IAAI,IAAI,CAAgB,EAEtC,EAAW,CAAC,GAAG,CAAQ,EAE7B,IAAK,GAAM,CAAE,UAAS,YAAY,EAC5B,QAAW,IAAA,IAAc,EAAO,KAAM,GAAS,EAAY,IAAI,CAAI,CAAC,IAIpE,CAAC,MAFiB,EAAQ,CAAW,EAE3B,MAAO,GAGvB,MAAO,EACT"}
1
+ {"version":3,"file":"guards.cjs","names":[],"sources":["../src/guards.ts"],"sourcesContent":["import type { BeforeLeaveBlocker, NavigationDestination } from './types';\n\n/**\n * A registered leave guard. `routes` scopes the guard to navigations that depart from\n * any route whose name appears in the array (matched against any node in the active branch,\n * not just the leaf). When `routes` is omitted the guard fires on every navigation.\n */\nexport type RegisteredBlocker = {\n handler: BeforeLeaveBlocker;\n routes?: string[];\n};\n\n/**\n * Run all registered leave blockers in registration order.\n * Guards whose `routes` filter does not overlap the current active match names are skipped.\n * Returns `false` as soon as any blocker returns `false`; returns `true` if all pass.\n *\n * A snapshot of the blocker set is taken before iteration so that guards added or removed\n * during execution do not affect the current run.\n *\n * `destination` is passed to each blocker so guards can make context-aware decisions.\n */\nexport async function runLeaveBlockers(\n blockers: ReadonlySet<RegisteredBlocker>,\n activeMatchNames: readonly string[],\n destination: NavigationDestination,\n): Promise<boolean> {\n const activeNames = new Set(activeMatchNames);\n // Snapshot so that removals during iteration don't skip entries.\n const snapshot = [...blockers];\n\n for (const { handler, routes } of snapshot) {\n if (routes !== undefined && !routes.some((name) => activeNames.has(name))) continue;\n\n const allowed = await handler(destination);\n\n if (!allowed) return false;\n }\n\n return true;\n}\n"],"mappings":"AAsBA,eAAsB,iBACpB,EACA,EACA,EACkB,CAClB,IAAM,EAAc,IAAI,IAAI,CAAgB,EAEtC,EAAW,CAAC,GAAG,CAAQ,EAE7B,IAAK,GAAM,CAAE,UAAS,YAAY,EAC5B,QAAW,IAAA,IAAc,EAAO,KAAM,GAAS,EAAY,IAAI,CAAI,CAAC,IAIpE,CAAC,MAFiB,EAAQ,CAAW,EAE3B,MAAO,GAGvB,MAAO,EACT"}
package/dist/guards.js CHANGED
@@ -1,10 +1,2 @@
1
- //#region src/guards.ts
2
- async function e(e, t, n) {
3
- let r = new Set(t), i = [...e];
4
- for (let { handler: e, routes: t } of i) if ((t === void 0 || t.some((e) => r.has(e))) && !await e(n)) return !1;
5
- return !0;
6
- }
7
- //#endregion
8
- export { e as runLeaveBlockers };
9
-
1
+ async function runLeaveBlockers(e,t,n){let r=new Set(t),i=[...e];for(let{handler:e,routes:t}of i)if((t===void 0||t.some(e=>r.has(e)))&&!await e(n))return!1;return!0}export{runLeaveBlockers};
10
2
  //# sourceMappingURL=guards.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"guards.js","names":[],"sources":["../src/guards.ts"],"sourcesContent":["import type { BeforeLeaveBlocker, NavigationDestination } from './types';\n\n/**\n * A registered leave guard. `routes` scopes the guard to navigations that depart from\n * any route whose name appears in the array (matched against any node in the active branch,\n * not just the leaf). When `routes` is omitted the guard fires on every navigation.\n */\nexport type RegisteredBlocker = {\n handler: BeforeLeaveBlocker;\n routes?: string[];\n};\n\n/**\n * Run all registered leave blockers in registration order.\n * Guards whose `routes` filter does not overlap the current active match names are skipped.\n * Returns `false` as soon as any blocker returns `false`; returns `true` if all pass.\n *\n * A snapshot of the blocker set is taken before iteration so that guards added or removed\n * during execution do not affect the current run.\n *\n * `destination` is passed to each blocker so guards can make context-aware decisions.\n */\nexport async function runLeaveBlockers(\n blockers: ReadonlySet<RegisteredBlocker>,\n activeMatchNames: readonly string[],\n destination: NavigationDestination,\n): Promise<boolean> {\n const activeNames = new Set(activeMatchNames);\n // Snapshot so that removals during iteration don't skip entries.\n const snapshot = [...blockers];\n\n for (const { handler, routes } of snapshot) {\n if (routes !== undefined && !routes.some((name) => activeNames.has(name))) continue;\n\n const allowed = await handler(destination);\n\n if (!allowed) return false;\n }\n\n return true;\n}\n"],"mappings":";AAsBA,eAAsB,EACpB,GACA,GACA,GACkB;CAClB,IAAM,IAAc,IAAI,IAAI,CAAgB,GAEtC,IAAW,CAAC,GAAG,CAAQ;CAE7B,KAAK,IAAM,EAAE,YAAS,eAAY,GAC5B,WAAW,KAAA,KAAc,EAAO,MAAM,MAAS,EAAY,IAAI,CAAI,CAAC,MAIpE,CAAC,MAFiB,EAAQ,CAAW,GAE3B,OAAO;CAGvB,OAAO;AACT"}
1
+ {"version":3,"file":"guards.js","names":[],"sources":["../src/guards.ts"],"sourcesContent":["import type { BeforeLeaveBlocker, NavigationDestination } from './types';\n\n/**\n * A registered leave guard. `routes` scopes the guard to navigations that depart from\n * any route whose name appears in the array (matched against any node in the active branch,\n * not just the leaf). When `routes` is omitted the guard fires on every navigation.\n */\nexport type RegisteredBlocker = {\n handler: BeforeLeaveBlocker;\n routes?: string[];\n};\n\n/**\n * Run all registered leave blockers in registration order.\n * Guards whose `routes` filter does not overlap the current active match names are skipped.\n * Returns `false` as soon as any blocker returns `false`; returns `true` if all pass.\n *\n * A snapshot of the blocker set is taken before iteration so that guards added or removed\n * during execution do not affect the current run.\n *\n * `destination` is passed to each blocker so guards can make context-aware decisions.\n */\nexport async function runLeaveBlockers(\n blockers: ReadonlySet<RegisteredBlocker>,\n activeMatchNames: readonly string[],\n destination: NavigationDestination,\n): Promise<boolean> {\n const activeNames = new Set(activeMatchNames);\n // Snapshot so that removals during iteration don't skip entries.\n const snapshot = [...blockers];\n\n for (const { handler, routes } of snapshot) {\n if (routes !== undefined && !routes.some((name) => activeNames.has(name))) continue;\n\n const allowed = await handler(destination);\n\n if (!allowed) return false;\n }\n\n return true;\n}\n"],"mappings":"AAsBA,eAAsB,iBACpB,EACA,EACA,EACkB,CAClB,IAAM,EAAc,IAAI,IAAI,CAAgB,EAEtC,EAAW,CAAC,GAAG,CAAQ,EAE7B,IAAK,GAAM,CAAE,UAAS,YAAY,EAC5B,QAAW,IAAA,IAAc,EAAO,KAAM,GAAS,EAAY,IAAI,CAAI,CAAC,IAIpE,CAAC,MAFiB,EAAQ,CAAW,EAE3B,MAAO,GAGvB,MAAO,EACT"}
package/dist/history.cjs CHANGED
@@ -1,2 +1,2 @@
1
- function e(){return{back(){window.history.back()},get location(){return{hash:window.location.hash,pathname:window.location.pathname,search:window.location.search,state:window.history.state}},onPopstate(e){return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},push(e,t){window.history.pushState(t,``,e)},replace(e,t){window.history.replaceState(t,``,e)}}}function t(e=`/`){let t=new URL(e,`http://localhost`),n=[{hash:t.hash,pathname:t.pathname,search:t.search,state:null}],r=0,i=new Set;return{back(){r<=0||(--r,i.forEach(e=>{e()}))},get location(){return n[r]},onPopstate(e){return i.add(e),()=>i.delete(e)},push(e,t=null){let i=new URL(e,`http://localhost`);n.splice(r+1),n.push({hash:i.hash,pathname:i.pathname,search:i.search,state:t}),r=n.length-1},replace(e,t=null){let i=new URL(e,`http://localhost`);n[r]={hash:i.hash,pathname:i.pathname,search:i.search,state:t}}}}exports.createBrowserHistory=e,exports.createMemoryHistory=t;
1
+ const e=require("./path.cjs");function createBrowserHistory(){return{back(){window.history.back()},get location(){return{hash:window.location.hash,pathname:window.location.pathname,search:window.location.search,state:window.history.state}},onPopstate(e){return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},push(e,t){window.history.pushState(t,``,e)},replace(e,t){window.history.replaceState(t,``,e)}}}function createHashHistory(t={}){let n=e.normalizePath(t.base??`/`),r=n===`/`?`/`:`${n}/`,location=()=>{let t=new URL(window.location.hash.slice(1)||`/`,`http://localhost`);return{hash:t.hash,pathname:e.joinPaths(n,t.pathname),search:t.search,state:window.history.state}},destination=t=>{let i=new URL(t,`http://localhost`),a=e.stripBase(i.pathname,n);return`${r}#${a}${i.search}${i.hash}`};return{back(){window.history.back()},href:destination,get location(){return location()},onPopstate(e){return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},push(e,t){window.history.pushState(t,``,destination(e))},replace(e,t){window.history.replaceState(t,``,destination(e))}}}function createHistoryForBase(e){return e===`/`?createBrowserHistory():createHashHistory({base:e})}function createMemoryHistory(e=`/`){let t=new URL(e,`http://localhost`),n=[{hash:t.hash,pathname:t.pathname,search:t.search,state:null}],r=0,i=new Set;return{back(){r<=0||(--r,i.forEach(e=>{e()}))},get location(){return n[r]},onPopstate(e){return i.add(e),()=>i.delete(e)},push(e,t=null){let i=new URL(e,`http://localhost`);n.splice(r+1),n.push({hash:i.hash,pathname:i.pathname,search:i.search,state:t}),r=n.length-1},replace(e,t=null){let i=new URL(e,`http://localhost`);n[r]={hash:i.hash,pathname:i.pathname,search:i.search,state:t}}}}exports.createBrowserHistory=createBrowserHistory,exports.createHashHistory=createHashHistory,exports.createHistoryForBase=createHistoryForBase,exports.createMemoryHistory=createMemoryHistory;
2
2
  //# sourceMappingURL=history.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"history.cjs","names":[],"sources":["../src/history.ts"],"sourcesContent":["import type { HistoryDriver } from './types';\n\n/** Creates a history driver backed by the browser History API. */\nexport function createBrowserHistory(): HistoryDriver {\n return {\n back() {\n window.history.back();\n },\n get location() {\n return {\n hash: window.location.hash,\n pathname: window.location.pathname,\n search: window.location.search,\n // State lives on window.history.state, not window.location.\n state: window.history.state,\n };\n },\n onPopstate(listener) {\n window.addEventListener('popstate', listener);\n\n return () => window.removeEventListener('popstate', listener);\n },\n push(url, state) {\n window.history.pushState(state, '', url);\n },\n replace(url, state) {\n window.history.replaceState(state, '', url);\n },\n };\n}\n\ntype MemoryLocation = { hash: string; pathname: string; search: string; state: unknown };\n\n/**\n * Creates an in-memory history driver. Suitable for SSR, tests, and non-browser environments.\n *\n * Semantics mirror the browser History API:\n * - `push()` and `replace()` update the location silently (no listener notification),\n * matching `pushState`/`replaceState` which do not fire `popstate`.\n * - `back()` moves one entry back and notifies subscribers, matching a browser back-button press.\n */\nexport function createMemoryHistory(initialPath = '/'): HistoryDriver {\n const parsed = new URL(initialPath, 'http://localhost');\n const stack: MemoryLocation[] = [\n { hash: parsed.hash, pathname: parsed.pathname, search: parsed.search, state: null },\n ];\n let cursor = 0;\n const listeners = new Set<() => void>();\n\n return {\n back() {\n if (cursor <= 0) return;\n\n cursor -= 1;\n listeners.forEach((l) => {\n l();\n });\n },\n get location(): MemoryLocation {\n return stack[cursor]!;\n },\n onPopstate(listener) {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n push(url, state = null) {\n const p = new URL(url, 'http://localhost');\n\n stack.splice(cursor + 1);\n stack.push({ hash: p.hash, pathname: p.pathname, search: p.search, state });\n cursor = stack.length - 1;\n // Silent — mirrors browser pushState semantics. Router drives navigation via #handleRoute directly.\n },\n replace(url, state = null) {\n const p = new URL(url, 'http://localhost');\n\n stack[cursor] = { hash: p.hash, pathname: p.pathname, search: p.search, state };\n // Silent — mirrors browser replaceState semantics.\n },\n };\n}\n"],"mappings":"AAGA,SAAgB,GAAsC,CACpD,MAAO,CACL,MAAO,CACL,OAAO,QAAQ,KAAK,CACtB,EACA,IAAI,UAAW,CACb,MAAO,CACL,KAAM,OAAO,SAAS,KACtB,SAAU,OAAO,SAAS,SAC1B,OAAQ,OAAO,SAAS,OAExB,MAAO,OAAO,QAAQ,KACxB,CACF,EACA,WAAW,EAAU,CAGnB,OAFA,OAAO,iBAAiB,WAAY,CAAQ,MAE/B,OAAO,oBAAoB,WAAY,CAAQ,CAC9D,EACA,KAAK,EAAK,EAAO,CACf,OAAO,QAAQ,UAAU,EAAO,GAAI,CAAG,CACzC,EACA,QAAQ,EAAK,EAAO,CAClB,OAAO,QAAQ,aAAa,EAAO,GAAI,CAAG,CAC5C,CACF,CACF,CAYA,SAAgB,EAAoB,EAAc,IAAoB,CACpE,IAAM,EAAS,IAAI,IAAI,EAAa,kBAAkB,EAChD,EAA0B,CAC9B,CAAE,KAAM,EAAO,KAAM,SAAU,EAAO,SAAU,OAAQ,EAAO,OAAQ,MAAO,IAAK,CACrF,EACI,EAAS,EACP,EAAY,IAAI,IAEtB,MAAO,CACL,MAAO,CACD,GAAU,IAEd,IACA,EAAU,QAAS,GAAM,CACvB,EAAE,CACJ,CAAC,EACH,EACA,IAAI,UAA2B,CAC7B,OAAO,EAAM,EACf,EACA,WAAW,EAAU,CAGnB,OAFA,EAAU,IAAI,CAAQ,MAET,EAAU,OAAO,CAAQ,CACxC,EACA,KAAK,EAAK,EAAQ,KAAM,CACtB,IAAM,EAAI,IAAI,IAAI,EAAK,kBAAkB,EAEzC,EAAM,OAAO,EAAS,CAAC,EACvB,EAAM,KAAK,CAAE,KAAM,EAAE,KAAM,SAAU,EAAE,SAAU,OAAQ,EAAE,OAAQ,OAAM,CAAC,EAC1E,EAAS,EAAM,OAAS,CAE1B,EACA,QAAQ,EAAK,EAAQ,KAAM,CACzB,IAAM,EAAI,IAAI,IAAI,EAAK,kBAAkB,EAEzC,EAAM,GAAU,CAAE,KAAM,EAAE,KAAM,SAAU,EAAE,SAAU,OAAQ,EAAE,OAAQ,OAAM,CAEhF,CACF,CACF"}
1
+ {"version":3,"file":"history.cjs","names":[],"sources":["../src/history.ts"],"sourcesContent":["import { joinPaths, normalizePath, stripBase } from './path';\nimport type { HistoryDriver } from './types';\n\n/** Creates a history driver backed by the browser History API. */\nexport function createBrowserHistory(): HistoryDriver {\n return {\n back() {\n window.history.back();\n },\n get location() {\n return {\n hash: window.location.hash,\n pathname: window.location.pathname,\n search: window.location.search,\n // State lives on window.history.state, not window.location.\n state: window.history.state,\n };\n },\n onPopstate(listener) {\n window.addEventListener('popstate', listener);\n\n return () => window.removeEventListener('popstate', listener);\n },\n push(url, state) {\n window.history.pushState(state, '', url);\n },\n replace(url, state) {\n window.history.replaceState(state, '', url);\n },\n };\n}\n\nexport type HashHistoryOptions = { base?: string };\n\nexport function createHashHistory(options: HashHistoryOptions = {}): HistoryDriver {\n const base = normalizePath(options.base ?? '/');\n const baseRoot = base === '/' ? '/' : `${base}/`;\n const location = () => {\n const parsed = new URL(window.location.hash.slice(1) || '/', 'http://localhost');\n\n return {\n hash: parsed.hash,\n pathname: joinPaths(base, parsed.pathname),\n search: parsed.search,\n state: window.history.state,\n };\n };\n const destination = (url: string) => {\n const parsed = new URL(url, 'http://localhost');\n const pathname = stripBase(parsed.pathname, base);\n\n return `${baseRoot}#${pathname}${parsed.search}${parsed.hash}`;\n };\n\n return {\n back() {\n window.history.back();\n },\n /** Anchor-ready form of an internal URL: the hash driver stores routes behind `#`. */\n href: destination,\n get location() {\n return location();\n },\n onPopstate(listener) {\n window.addEventListener('popstate', listener);\n\n return () => window.removeEventListener('popstate', listener);\n },\n push(url, state) {\n window.history.pushState(state, '', destination(url));\n },\n replace(url, state) {\n window.history.replaceState(state, '', destination(url));\n },\n };\n}\n\n/**\n * Picks the history driver for a deployment base path: a site at the origin root\n * (`'/'`) gets real History-API paths; an app deployed under a sub-path\n * (`import.meta.env.BASE_URL` like `'/demos/primal/'`) gets the hash driver, so\n * deep links survive a static host that cannot rewrite the base path to the app.\n */\nexport function createHistoryForBase(base: string): HistoryDriver {\n return base === '/' ? createBrowserHistory() : createHashHistory({ base });\n}\n\ntype MemoryLocation = { hash: string; pathname: string; search: string; state: unknown };\n\n/**\n * Creates an in-memory history driver. Suitable for SSR, tests, and non-browser environments.\n *\n * Semantics mirror the browser History API:\n * - `push()` and `replace()` update the location silently (no listener notification),\n * matching `pushState`/`replaceState` which do not fire `popstate`.\n * - `back()` moves one entry back and notifies subscribers, matching a browser back-button press.\n */\nexport function createMemoryHistory(initialPath = '/'): HistoryDriver {\n const parsed = new URL(initialPath, 'http://localhost');\n const stack: MemoryLocation[] = [\n { hash: parsed.hash, pathname: parsed.pathname, search: parsed.search, state: null },\n ];\n let cursor = 0;\n const listeners = new Set<() => void>();\n\n return {\n back() {\n if (cursor <= 0) return;\n\n cursor -= 1;\n listeners.forEach((l) => {\n l();\n });\n },\n get location(): MemoryLocation {\n return stack[cursor]!;\n },\n onPopstate(listener) {\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n },\n push(url, state = null) {\n const p = new URL(url, 'http://localhost');\n\n stack.splice(cursor + 1);\n stack.push({ hash: p.hash, pathname: p.pathname, search: p.search, state });\n cursor = stack.length - 1;\n // Silent — mirrors browser pushState semantics. Router drives navigation via #handleRoute directly.\n },\n replace(url, state = null) {\n const p = new URL(url, 'http://localhost');\n\n stack[cursor] = { hash: p.hash, pathname: p.pathname, search: p.search, state };\n // Silent — mirrors browser replaceState semantics.\n },\n };\n}\n"],"mappings":"8BAIA,SAAgB,sBAAsC,CACpD,MAAO,CACL,MAAO,CACL,OAAO,QAAQ,KAAK,CACtB,EACA,IAAI,UAAW,CACb,MAAO,CACL,KAAM,OAAO,SAAS,KACtB,SAAU,OAAO,SAAS,SAC1B,OAAQ,OAAO,SAAS,OAExB,MAAO,OAAO,QAAQ,KACxB,CACF,EACA,WAAW,EAAU,CAGnB,OAFA,OAAO,iBAAiB,WAAY,CAAQ,MAE/B,OAAO,oBAAoB,WAAY,CAAQ,CAC9D,EACA,KAAK,EAAK,EAAO,CACf,OAAO,QAAQ,UAAU,EAAO,GAAI,CAAG,CACzC,EACA,QAAQ,EAAK,EAAO,CAClB,OAAO,QAAQ,aAAa,EAAO,GAAI,CAAG,CAC5C,CACF,CACF,CAIA,SAAgB,kBAAkB,EAA8B,CAAC,EAAkB,CACjF,IAAM,EAAO,EAAA,cAAc,EAAQ,MAAQ,GAAG,EACxC,EAAW,IAAS,IAAM,IAAM,GAAG,EAAK,GACxC,aAAiB,CACrB,IAAM,EAAS,IAAI,IAAI,OAAO,SAAS,KAAK,MAAM,CAAC,GAAK,IAAK,kBAAkB,EAE/E,MAAO,CACL,KAAM,EAAO,KACb,SAAU,EAAA,UAAU,EAAM,EAAO,QAAQ,EACzC,OAAQ,EAAO,OACf,MAAO,OAAO,QAAQ,KACxB,CACF,EACM,YAAe,GAAgB,CACnC,IAAM,EAAS,IAAI,IAAI,EAAK,kBAAkB,EACxC,EAAW,EAAA,UAAU,EAAO,SAAU,CAAI,EAEhD,MAAO,GAAG,EAAS,GAAG,IAAW,EAAO,SAAS,EAAO,MAC1D,EAEA,MAAO,CACL,MAAO,CACL,OAAO,QAAQ,KAAK,CACtB,EAEA,KAAM,YACN,IAAI,UAAW,CACb,OAAO,SAAS,CAClB,EACA,WAAW,EAAU,CAGnB,OAFA,OAAO,iBAAiB,WAAY,CAAQ,MAE/B,OAAO,oBAAoB,WAAY,CAAQ,CAC9D,EACA,KAAK,EAAK,EAAO,CACf,OAAO,QAAQ,UAAU,EAAO,GAAI,YAAY,CAAG,CAAC,CACtD,EACA,QAAQ,EAAK,EAAO,CAClB,OAAO,QAAQ,aAAa,EAAO,GAAI,YAAY,CAAG,CAAC,CACzD,CACF,CACF,CAQA,SAAgB,qBAAqB,EAA6B,CAChE,OAAO,IAAS,IAAM,qBAAqB,EAAI,kBAAkB,CAAE,MAAK,CAAC,CAC3E,CAYA,SAAgB,oBAAoB,EAAc,IAAoB,CACpE,IAAM,EAAS,IAAI,IAAI,EAAa,kBAAkB,EAChD,EAA0B,CAC9B,CAAE,KAAM,EAAO,KAAM,SAAU,EAAO,SAAU,OAAQ,EAAO,OAAQ,MAAO,IAAK,CACrF,EACI,EAAS,EACP,EAAY,IAAI,IAEtB,MAAO,CACL,MAAO,CACD,GAAU,IAEd,IACA,EAAU,QAAS,GAAM,CACvB,EAAE,CACJ,CAAC,EACH,EACA,IAAI,UAA2B,CAC7B,OAAO,EAAM,EACf,EACA,WAAW,EAAU,CAGnB,OAFA,EAAU,IAAI,CAAQ,MAET,EAAU,OAAO,CAAQ,CACxC,EACA,KAAK,EAAK,EAAQ,KAAM,CACtB,IAAM,EAAI,IAAI,IAAI,EAAK,kBAAkB,EAEzC,EAAM,OAAO,EAAS,CAAC,EACvB,EAAM,KAAK,CAAE,KAAM,EAAE,KAAM,SAAU,EAAE,SAAU,OAAQ,EAAE,OAAQ,OAAM,CAAC,EAC1E,EAAS,EAAM,OAAS,CAE1B,EACA,QAAQ,EAAK,EAAQ,KAAM,CACzB,IAAM,EAAI,IAAI,IAAI,EAAK,kBAAkB,EAEzC,EAAM,GAAU,CAAE,KAAM,EAAE,KAAM,SAAU,EAAE,SAAU,OAAQ,EAAE,OAAQ,OAAM,CAEhF,CACF,CACF"}
package/dist/history.d.ts CHANGED
@@ -1,6 +1,17 @@
1
1
  import type { HistoryDriver } from './types';
2
2
  /** Creates a history driver backed by the browser History API. */
3
3
  export declare function createBrowserHistory(): HistoryDriver;
4
+ export type HashHistoryOptions = {
5
+ base?: string;
6
+ };
7
+ export declare function createHashHistory(options?: HashHistoryOptions): HistoryDriver;
8
+ /**
9
+ * Picks the history driver for a deployment base path: a site at the origin root
10
+ * (`'/'`) gets real History-API paths; an app deployed under a sub-path
11
+ * (`import.meta.env.BASE_URL` like `'/demos/primal/'`) gets the hash driver, so
12
+ * deep links survive a static host that cannot rewrite the base path to the app.
13
+ */
14
+ export declare function createHistoryForBase(base: string): HistoryDriver;
4
15
  /**
5
16
  * Creates an in-memory history driver. Suitable for SSR, tests, and non-browser environments.
6
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,kEAAkE;AAClE,wBAAgB,oBAAoB,IAAI,aAAa,CA0BpD;AAID;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,SAAM,GAAG,aAAa,CAwCpE"}
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,kEAAkE;AAClE,wBAAgB,oBAAoB,IAAI,aAAa,CA0BpD;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAyCjF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAEhE;AAID;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,SAAM,GAAG,aAAa,CAwCpE"}
package/dist/history.js CHANGED
@@ -1,68 +1,2 @@
1
- //#region src/history.ts
2
- function e() {
3
- return {
4
- back() {
5
- window.history.back();
6
- },
7
- get location() {
8
- return {
9
- hash: window.location.hash,
10
- pathname: window.location.pathname,
11
- search: window.location.search,
12
- state: window.history.state
13
- };
14
- },
15
- onPopstate(e) {
16
- return window.addEventListener("popstate", e), () => window.removeEventListener("popstate", e);
17
- },
18
- push(e, t) {
19
- window.history.pushState(t, "", e);
20
- },
21
- replace(e, t) {
22
- window.history.replaceState(t, "", e);
23
- }
24
- };
25
- }
26
- function t(e = "/") {
27
- let t = new URL(e, "http://localhost"), n = [{
28
- hash: t.hash,
29
- pathname: t.pathname,
30
- search: t.search,
31
- state: null
32
- }], r = 0, i = /* @__PURE__ */ new Set();
33
- return {
34
- back() {
35
- r <= 0 || (--r, i.forEach((e) => {
36
- e();
37
- }));
38
- },
39
- get location() {
40
- return n[r];
41
- },
42
- onPopstate(e) {
43
- return i.add(e), () => i.delete(e);
44
- },
45
- push(e, t = null) {
46
- let i = new URL(e, "http://localhost");
47
- n.splice(r + 1), n.push({
48
- hash: i.hash,
49
- pathname: i.pathname,
50
- search: i.search,
51
- state: t
52
- }), r = n.length - 1;
53
- },
54
- replace(e, t = null) {
55
- let i = new URL(e, "http://localhost");
56
- n[r] = {
57
- hash: i.hash,
58
- pathname: i.pathname,
59
- search: i.search,
60
- state: t
61
- };
62
- }
63
- };
64
- }
65
- //#endregion
66
- export { e as createBrowserHistory, t as createMemoryHistory };
67
-
1
+ import{joinPaths as e,normalizePath as t,stripBase as n}from"./path.js";function createBrowserHistory(){return{back(){window.history.back()},get location(){return{hash:window.location.hash,pathname:window.location.pathname,search:window.location.search,state:window.history.state}},onPopstate(e){return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},push(e,t){window.history.pushState(t,``,e)},replace(e,t){window.history.replaceState(t,``,e)}}}function createHashHistory(r={}){let i=t(r.base??`/`),a=i===`/`?`/`:`${i}/`,location=()=>{let t=new URL(window.location.hash.slice(1)||`/`,`http://localhost`);return{hash:t.hash,pathname:e(i,t.pathname),search:t.search,state:window.history.state}},destination=e=>{let t=new URL(e,`http://localhost`),r=n(t.pathname,i);return`${a}#${r}${t.search}${t.hash}`};return{back(){window.history.back()},href:destination,get location(){return location()},onPopstate(e){return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},push(e,t){window.history.pushState(t,``,destination(e))},replace(e,t){window.history.replaceState(t,``,destination(e))}}}function createHistoryForBase(e){return e===`/`?createBrowserHistory():createHashHistory({base:e})}function createMemoryHistory(e=`/`){let t=new URL(e,`http://localhost`),n=[{hash:t.hash,pathname:t.pathname,search:t.search,state:null}],r=0,i=new Set;return{back(){r<=0||(--r,i.forEach(e=>{e()}))},get location(){return n[r]},onPopstate(e){return i.add(e),()=>i.delete(e)},push(e,t=null){let i=new URL(e,`http://localhost`);n.splice(r+1),n.push({hash:i.hash,pathname:i.pathname,search:i.search,state:t}),r=n.length-1},replace(e,t=null){let i=new URL(e,`http://localhost`);n[r]={hash:i.hash,pathname:i.pathname,search:i.search,state:t}}}}export{createBrowserHistory,createHashHistory,createHistoryForBase,createMemoryHistory};
68
2
  //# sourceMappingURL=history.js.map