@vielzeug/wayfinder 1.0.4 → 2.0.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.
- package/README.md +8 -2
- package/dist/_dev.cjs +1 -1
- package/dist/_dev.cjs.map +1 -1
- package/dist/_dev.js +3 -8
- package/dist/_dev.js.map +1 -1
- package/dist/_navigation.cjs +2 -0
- package/dist/_navigation.cjs.map +1 -0
- package/dist/_navigation.d.ts +10 -0
- package/dist/_navigation.d.ts.map +1 -0
- package/dist/_navigation.js +21 -0
- package/dist/_navigation.js.map +1 -0
- package/dist/compile.cjs +1 -1
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +33 -33
- package/dist/compile.js.map +1 -1
- package/dist/context.cjs +1 -1
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +18 -18
- package/dist/context.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/router.cjs +1 -1
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.ts +11 -13
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +159 -141
- package/dist/router.js.map +1 -1
- package/dist/wayfinder.cjs +1 -1
- package/dist/wayfinder.cjs.map +1 -1
- package/dist/wayfinder.iife.js +1 -1
- package/dist/wayfinder.iife.js.map +1 -1
- package/dist/wayfinder.js +1 -1
- package/dist/wayfinder.js.map +1 -1
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
- Declarative `notFound` fallback route
|
|
32
32
|
- Browser and memory history drivers
|
|
33
33
|
- `redirectTo()` middleware helper
|
|
34
|
-
- SSR-compatible `
|
|
35
|
-
- `
|
|
34
|
+
- SSR-compatible `loadPath()` for data prefetching without side effects
|
|
35
|
+
- `matchPath()` for synchronous route inspection
|
|
36
|
+
- `ready` and `waitFor(name)` for lifecycle coordination
|
|
36
37
|
|
|
37
38
|
## Installation
|
|
38
39
|
|
|
@@ -44,6 +45,8 @@ yarn add @vielzeug/wayfinder
|
|
|
44
45
|
|
|
45
46
|
## Quick Start
|
|
46
47
|
|
|
48
|
+
Create a memory-backed router, await initial routing, then navigate by route name.
|
|
49
|
+
|
|
47
50
|
```ts
|
|
48
51
|
import { createRouter } from '@vielzeug/wayfinder';
|
|
49
52
|
|
|
@@ -66,6 +69,8 @@ const router = createRouter({
|
|
|
66
69
|
},
|
|
67
70
|
});
|
|
68
71
|
|
|
72
|
+
await router.ready;
|
|
73
|
+
|
|
69
74
|
// React to state changes:
|
|
70
75
|
router.subscribe((state) => {
|
|
71
76
|
const leaf = state.matches.at(-1);
|
|
@@ -81,6 +86,7 @@ await router.navigate({ name: 'dashboard.settings' });
|
|
|
81
86
|
- [Usage Guide](https://vielzeug.dev/wayfinder/usage)
|
|
82
87
|
- [API Reference](https://vielzeug.dev/wayfinder/api)
|
|
83
88
|
- [Examples](https://vielzeug.dev/wayfinder/examples)
|
|
89
|
+
- [Migration Guide](https://vielzeug.dev/wayfinder/migration)
|
|
84
90
|
- [React Integration Example](https://vielzeug.dev/wayfinder/examples/react-integration)
|
|
85
91
|
- [Vue Integration Example](https://vielzeug.dev/wayfinder/examples/vue-integration)
|
|
86
92
|
- [Svelte Integration Example](https://vielzeug.dev/wayfinder/examples/svelte-integration)
|
package/dist/_dev.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
function e(e){}function t(e,...t){}exports.error=t,exports.warn=e;
|
|
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\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"
|
|
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\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC,CAGA,SAAgB,EAAM,EAAa,GAAG,EAAuB,CAE7D"}
|
package/dist/_dev.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
//#region src/_dev.ts
|
|
2
|
-
|
|
3
|
-
function t(t) {
|
|
4
|
-
e && console.warn(`[@vielzeug/wayfinder] ${t}`);
|
|
5
|
-
}
|
|
6
|
-
function n(t, ...n) {
|
|
7
|
-
e && console.error(`[@vielzeug/wayfinder] ${t}`, ...n);
|
|
8
|
-
}
|
|
2
|
+
function e(e) {}
|
|
3
|
+
function t(e, ...t) {}
|
|
9
4
|
//#endregion
|
|
10
|
-
export {
|
|
5
|
+
export { t as error, e as warn };
|
|
11
6
|
|
|
12
7
|
//# 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\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";
|
|
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\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC;AAGA,SAAgB,EAAM,GAAa,GAAG,GAAuB,CAE7D"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type NavigationAttempt = {
|
|
2
|
+
isCurrent(): boolean;
|
|
3
|
+
readonly signal: AbortSignal;
|
|
4
|
+
};
|
|
5
|
+
/** Coordinates navigation ownership so stale work cannot commit router state. */
|
|
6
|
+
export declare function createNavigationCoordinator(): {
|
|
7
|
+
begin(): NavigationAttempt;
|
|
8
|
+
invalidate(reason?: unknown): void;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=_navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_navigation.d.ts","sourceRoot":"","sources":["../src/_navigation.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,IAAI,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,2BAA2B;aAI9B,iBAAiB;wBAaN,OAAO,GAAG,IAAI;EAKrC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
|
|
21
|
+
//# sourceMappingURL=_navigation.js.map
|
|
@@ -0,0 +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"}
|
package/dist/compile.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
require("./_dev.cjs");const e=require("./errors.cjs"),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,{component:a.component,dataFn:a.data,lazy:a.lazy,meta:a.meta,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.lazy!==void 0||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;
|
|
2
2
|
//# sourceMappingURL=compile.cjs.map
|
package/dist/compile.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.cjs","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nimport { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\n\nexport type CompiledRoutes<TMeta = unknown, TComponent = unknown> = {\n records: readonly RouteRecord<TMeta, TComponent>[];\n routesByName: ReadonlyMap<string, RouteRecord<TMeta, TComponent>>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable, TMeta, TComponent>(\n options: RouterOptions<TRoutes, TMeta, TComponent>,\n): CompiledRoutes<TMeta, TComponent> {\n const records: RouteRecord<TMeta, TComponent>[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef<TMeta, TComponent>[],\n ancestorMiddleware: RouteRecord<TMeta, TComponent>['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<TMeta, TComponent>[] = [\n ...ancestorBranchDefs,\n {\n component: route.component as TComponent | undefined,\n dataFn: route.data,\n lazy: route.lazy as RouteBranchDef<TMeta, TComponent>['lazy'],\n meta: route.meta as TMeta | undefined,\n name,\n onError: route.onError as RouteBranchDef<TMeta, TComponent>['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 // R9: emit a record for leaf routes (no children), redirects, lazy routes, and routes with data.\n // A bare parent-only route (children but no data/lazy/redirect) is not emitted as a leaf.\n if (route.lazy !== undefined || 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":"
|
|
1
|
+
{"version":3,"file":"compile.cjs","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nimport { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\n\nexport type CompiledRoutes<TMeta = unknown, TComponent = unknown> = {\n records: readonly RouteRecord<TMeta, TComponent>[];\n routesByName: ReadonlyMap<string, RouteRecord<TMeta, TComponent>>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable, TMeta, TComponent>(\n options: RouterOptions<TRoutes, TMeta, TComponent>,\n): CompiledRoutes<TMeta, TComponent> {\n const records: RouteRecord<TMeta, TComponent>[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef<TMeta, TComponent>[],\n ancestorMiddleware: RouteRecord<TMeta, TComponent>['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<TMeta, TComponent>[] = [\n ...ancestorBranchDefs,\n {\n component: route.component as TComponent | undefined,\n dataFn: route.data,\n lazy: route.lazy as RouteBranchDef<TMeta, TComponent>['lazy'],\n meta: route.meta as TMeta | undefined,\n name,\n onError: route.onError as RouteBranchDef<TMeta, TComponent>['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 // R9: emit a record for leaf routes (no children), redirects, lazy routes, and routes with data.\n // A bare parent-only route (children but no data/lazy/redirect) is not emitted as a leaf.\n if (route.lazy !== undefined || 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":"8EAWA,SAAgB,EACd,EACmC,CACnC,IAAM,EAA4C,CAAC,EAE7C,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,EAAkD,CACtD,GAAG,EACH,CACE,UAAW,EAAM,UACjB,OAAQ,EAAM,KACd,KAAM,EAAM,KACZ,KAAM,EAAM,KACZ,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,OAAS,IAAA,IAAa,EAAM,WAAa,IAAA,IAAa,CAAC,EAAM,UAAY,EAAM,OAAS,IAAA,GAAW,CAC3G,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"}
|
package/dist/compile.js
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { WayfinderRouteError as
|
|
3
|
-
import { compilePathMatcher as
|
|
1
|
+
import "./_dev.js";
|
|
2
|
+
import { WayfinderRouteError as e } from "./errors.js";
|
|
3
|
+
import { compilePathMatcher as t, joinPaths as n, normalizePath as r } from "./path.js";
|
|
4
4
|
//#region src/compile.ts
|
|
5
|
-
function
|
|
6
|
-
let
|
|
7
|
-
if (
|
|
8
|
-
if (!
|
|
9
|
-
let d =
|
|
10
|
-
component:
|
|
11
|
-
dataFn:
|
|
12
|
-
lazy:
|
|
13
|
-
meta:
|
|
14
|
-
name:
|
|
15
|
-
onError:
|
|
16
|
-
}], p = [...u, ...
|
|
17
|
-
if (
|
|
18
|
-
if (
|
|
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
|
+
component: s.component,
|
|
11
|
+
dataFn: s.data,
|
|
12
|
+
lazy: s.lazy,
|
|
13
|
+
meta: s.meta,
|
|
14
|
+
name: i,
|
|
15
|
+
onError: s.onError
|
|
16
|
+
}], p = [...u, ...s.middleware ?? []];
|
|
17
|
+
if (s.children) for (let [e, t] of Object.entries(s.children)) o(`${i}.${e}`, t, d, f, p);
|
|
18
|
+
if (s.lazy !== void 0 || s.redirect !== void 0 || !s.children || s.data !== void 0) {
|
|
19
19
|
let e = f[f.length - 1];
|
|
20
|
-
|
|
20
|
+
a.push({
|
|
21
21
|
branchDefs: f,
|
|
22
|
-
coerceSearch:
|
|
22
|
+
coerceSearch: s.coerceSearch,
|
|
23
23
|
leaf: e,
|
|
24
|
-
matcher:
|
|
24
|
+
matcher: t(d),
|
|
25
25
|
ownMiddleware: p,
|
|
26
26
|
path: d,
|
|
27
|
-
redirect:
|
|
27
|
+
redirect: s.redirect
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
|
-
for (let [e, t] of Object.entries(
|
|
32
|
-
let
|
|
33
|
-
for (let
|
|
34
|
-
if (
|
|
35
|
-
|
|
31
|
+
for (let [e, t] of Object.entries(i.routes)) o(e, t, "/", [], []);
|
|
32
|
+
let s = /* @__PURE__ */ new Set();
|
|
33
|
+
for (let t of a) {
|
|
34
|
+
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.`);
|
|
35
|
+
s.add(t.leaf.name);
|
|
36
36
|
}
|
|
37
|
-
let
|
|
38
|
-
for (let
|
|
39
|
-
let
|
|
40
|
-
|
|
37
|
+
let c = !1;
|
|
38
|
+
for (let e of a) {
|
|
39
|
+
let t = e.path === "/*" || e.path.endsWith("/*") || e.path.includes(":") && e.path.endsWith("*");
|
|
40
|
+
c && !t && `${e.leaf.name}${e.path}`, t && (c = !0);
|
|
41
41
|
}
|
|
42
42
|
return {
|
|
43
|
-
records:
|
|
44
|
-
routesByName: new Map(
|
|
43
|
+
records: a,
|
|
44
|
+
routesByName: new Map(a.map((e) => [e.leaf.name, e]))
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
//#endregion
|
|
48
|
-
export {
|
|
48
|
+
export { i as compileRoutes };
|
|
49
49
|
|
|
50
50
|
//# sourceMappingURL=compile.js.map
|
package/dist/compile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.js","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nimport { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\n\nexport type CompiledRoutes<TMeta = unknown, TComponent = unknown> = {\n records: readonly RouteRecord<TMeta, TComponent>[];\n routesByName: ReadonlyMap<string, RouteRecord<TMeta, TComponent>>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable, TMeta, TComponent>(\n options: RouterOptions<TRoutes, TMeta, TComponent>,\n): CompiledRoutes<TMeta, TComponent> {\n const records: RouteRecord<TMeta, TComponent>[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef<TMeta, TComponent>[],\n ancestorMiddleware: RouteRecord<TMeta, TComponent>['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<TMeta, TComponent>[] = [\n ...ancestorBranchDefs,\n {\n component: route.component as TComponent | undefined,\n dataFn: route.data,\n lazy: route.lazy as RouteBranchDef<TMeta, TComponent>['lazy'],\n meta: route.meta as TMeta | undefined,\n name,\n onError: route.onError as RouteBranchDef<TMeta, TComponent>['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 // R9: emit a record for leaf routes (no children), redirects, lazy routes, and routes with data.\n // A bare parent-only route (children but no data/lazy/redirect) is not emitted as a leaf.\n if (route.lazy !== undefined || 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":";;;;AAWA,SAAgB,EACd,GACmC;CACnC,IAAM,IAA4C,CAAC,GAE7C,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,IAAkD,CACtD,GAAG,GACH;GACE,WAAW,EAAM;GACjB,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,MAAM,EAAM;GACZ;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,SAAS,KAAA,KAAa,EAAM,aAAa,KAAA,KAAa,CAAC,EAAM,YAAY,EAAM,SAAS,KAAA,GAAW;GAC3G,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,
|
|
1
|
+
{"version":3,"file":"compile.js","names":[],"sources":["../src/compile.ts"],"sourcesContent":["import type { Middleware, RouteBranchDef, RouteDefinition, RouteRecord, RouterOptions, RouteTable } from './types';\n\nimport { warn } from './_dev';\nimport { WayfinderRouteError } from './errors';\nimport { compilePathMatcher, joinPaths, normalizePath } from './path';\n\nexport type CompiledRoutes<TMeta = unknown, TComponent = unknown> = {\n records: readonly RouteRecord<TMeta, TComponent>[];\n routesByName: ReadonlyMap<string, RouteRecord<TMeta, TComponent>>;\n};\n\nexport function compileRoutes<TRoutes extends RouteTable, TMeta, TComponent>(\n options: RouterOptions<TRoutes, TMeta, TComponent>,\n): CompiledRoutes<TMeta, TComponent> {\n const records: RouteRecord<TMeta, TComponent>[] = [];\n\n const compile = (\n name: string,\n route: RouteDefinition,\n ancestorPath: string,\n ancestorBranchDefs: RouteBranchDef<TMeta, TComponent>[],\n ancestorMiddleware: RouteRecord<TMeta, TComponent>['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<TMeta, TComponent>[] = [\n ...ancestorBranchDefs,\n {\n component: route.component as TComponent | undefined,\n dataFn: route.data,\n lazy: route.lazy as RouteBranchDef<TMeta, TComponent>['lazy'],\n meta: route.meta as TMeta | undefined,\n name,\n onError: route.onError as RouteBranchDef<TMeta, TComponent>['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 // R9: emit a record for leaf routes (no children), redirects, lazy routes, and routes with data.\n // A bare parent-only route (children but no data/lazy/redirect) is not emitted as a leaf.\n if (route.lazy !== undefined || 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":";;;;AAWA,SAAgB,EACd,GACmC;CACnC,IAAM,IAA4C,CAAC,GAE7C,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,IAAkD,CACtD,GAAG,GACH;GACE,WAAW,EAAM;GACjB,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,MAAM,EAAM;GACZ;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,SAAS,KAAA,KAAa,EAAM,aAAa,KAAA,KAAa,CAAC,EAAM,YAAY,EAAM,SAAS,KAAA,GAAW;GAC3G,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"}
|
package/dist/context.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
require("./_dev.cjs");const e=require("./errors.cjs");function t(e){return{error:e.error,location:e.location,matches:e.matches,status:e.status}}function n(e,t,n,r,i){return e.map((e,a)=>({component:e.component,data:r[a],meta:e.meta,name:e.name,params:{...t},pathname:n,status:i?.[a]??`idle`}))}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){let i=!1;async function a(o){if(o<n.length){let r=!1;await n[o](t,async()=>{if(r)throw new e.WayfinderApiError(`next() called multiple times`);r=!0,await a(o+1)});return}i=!0,await r()}return await a(0),i}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;
|
|
2
2
|
//# sourceMappingURL=context.cjs.map
|
package/dist/context.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.cjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import type {\n MatchStatus,\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\nimport { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** R5: No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState<TMeta = unknown, TComponent = unknown>(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch<TMeta, TComponent>;\n status: NavigationStatus;\n}): RouteState<TMeta, TComponent> {\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, data results, and optional per-node statuses.\n * F1: Each node carries its own `status` for fine-grained nested layout feedback.\n */\nexport function buildMatchBranch<TMeta = unknown, TComponent = unknown>(\n branchDefs: readonly RouteBranchDef<TMeta, TComponent>[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n statuses?: readonly MatchStatus[],\n): RouteMatchBranch<TMeta, TComponent> {\n return branchDefs.map((def, i): RouteMatchBranch<TMeta, TComponent>[number] => ({\n component: def.component as TComponent,\n data: dataResults[i],\n meta: def.meta as TMeta,\n name: def.name,\n params: { ...params },\n pathname,\n status: statuses?.[i] ?? 'idle',\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): Promise<
|
|
1
|
+
{"version":3,"file":"context.cjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["import type {\n MatchStatus,\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\nimport { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** R5: No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState<TMeta = unknown, TComponent = unknown>(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch<TMeta, TComponent>;\n status: NavigationStatus;\n}): RouteState<TMeta, TComponent> {\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, data results, and optional per-node statuses.\n * F1: Each node carries its own `status` for fine-grained nested layout feedback.\n */\nexport function buildMatchBranch<TMeta = unknown, TComponent = unknown>(\n branchDefs: readonly RouteBranchDef<TMeta, TComponent>[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n statuses?: readonly MatchStatus[],\n): RouteMatchBranch<TMeta, TComponent> {\n return branchDefs.map((def, i): RouteMatchBranch<TMeta, TComponent>[number] => ({\n component: def.component as TComponent,\n data: dataResults[i],\n meta: def.meta as TMeta,\n name: def.name,\n params: { ...params },\n pathname,\n status: statuses?.[i] ?? 'idle',\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): 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 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\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":"sDAqBA,SAAgB,EAAwD,EAKtC,CAChC,MAAO,CACL,MAAO,EAAM,MACb,SAAU,EAAM,SAChB,QAAS,EAAM,QACf,OAAQ,EAAM,MAChB,CACF,CAMA,SAAgB,EACd,EACA,EACA,EACA,EACA,EACqC,CACrC,OAAO,EAAW,KAAK,EAAK,KAAoD,CAC9E,UAAW,EAAI,UACf,KAAM,EAAY,GAClB,KAAM,EAAI,KACV,KAAM,EAAI,KACV,OAAQ,CAAE,GAAG,CAAO,EACpB,WACA,OAAQ,IAAW,IAAM,MAC3B,EAAE,CACJ,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,EACkB,CAClB,IAAI,EAAc,GAElB,eAAe,EAAS,EAA8B,CACpD,GAAI,EAAQ,EAAW,OAAQ,CAC7B,IAAI,EAAS,GAEb,MAAM,EAAW,EAAM,CAAE,EAAS,SAAY,CAC5C,GAAI,EAAQ,MAAM,IAAI,EAAA,kBAAkB,8BAA8B,EAEtE,EAAS,GACT,MAAM,EAAS,EAAQ,CAAC,CAC1B,CAAC,EAED,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"}
|
package/dist/context.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export declare function createRouteState<TMeta = unknown, TComponent = unknown>(
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function buildMatchBranch<TMeta = unknown, TComponent = unknown>(branchDefs: readonly RouteBranchDef<TMeta, TComponent>[], params: RouteParams, pathname: string, dataResults: unknown[], statuses?: readonly MatchStatus[]): RouteMatchBranch<TMeta, TComponent>;
|
|
14
14
|
export declare function createRouteContext<TRoutes extends RouteTable>(location: RouteLocation, resolvedQuery: ResolvedQueryParams, params: RouteParams, matches: RouteMatchBranch, navigate: RouteContext<RouteParams, TRoutes>['navigate']): RouteContext<RouteParams, TRoutes>;
|
|
15
|
-
export declare function executeMiddlewarePipeline<TRoutes extends RouteTable>(context: RouteContext<RouteParams, TRoutes>, middleware: readonly Middleware<TRoutes>[], terminal: () => Promise<void>): Promise<
|
|
15
|
+
export declare function executeMiddlewarePipeline<TRoutes extends RouteTable>(context: RouteContext<RouteParams, TRoutes>, middleware: readonly Middleware<TRoutes>[], terminal: () => Promise<void>): Promise<boolean>;
|
|
16
16
|
export declare function reportError(error: unknown, context: RouterErrorContext, onError?: (e: unknown, ctx: RouterErrorContext) => void): void;
|
|
17
17
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,UAAU,EACX,MAAM,SAAS,CAAC;AAOjB,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,KAAK,EAAE;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,EAAE,gBAAgB,CAAC;CAC1B,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAOhC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,EACpE,UAAU,EAAE,SAAS,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,EACxD,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,OAAO,EAAE,EACtB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAChC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAUrC;AAID,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,UAAU,EAC3D,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,mBAAmB,EAClC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GACvD,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAWpC;AAID,wBAAsB,yBAAyB,CAAC,OAAO,SAAS,UAAU,EACxE,OAAO,EAAE,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,EAC3C,UAAU,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,EAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,UAAU,EACX,MAAM,SAAS,CAAC;AAOjB,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,EAAE,KAAK,EAAE;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,EAAE,gBAAgB,CAAC;CAC1B,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAOhC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,UAAU,GAAG,OAAO,EACpE,UAAU,EAAE,SAAS,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,EACxD,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,OAAO,EAAE,EACtB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,GAChC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAUrC;AAID,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,UAAU,EAC3D,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,mBAAmB,EAClC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,gBAAgB,EACzB,QAAQ,EAAE,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,GACvD,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAWpC;AAID,wBAAsB,yBAAyB,CAAC,OAAO,SAAS,UAAU,EACxE,OAAO,EAAE,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,EAC3C,UAAU,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,EAC1C,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAwBlB;AAID,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,GACtD,IAAI,CAQN"}
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { WayfinderApiError as
|
|
1
|
+
import "./_dev.js";
|
|
2
|
+
import { WayfinderApiError as e } from "./errors.js";
|
|
3
3
|
//#region src/context.ts
|
|
4
|
-
function
|
|
4
|
+
function t(e) {
|
|
5
5
|
return {
|
|
6
6
|
error: e.error,
|
|
7
7
|
location: e.location,
|
|
@@ -9,7 +9,7 @@ function n(e) {
|
|
|
9
9
|
status: e.status
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
-
function
|
|
12
|
+
function n(e, t, n, r, i) {
|
|
13
13
|
return e.map((e, a) => ({
|
|
14
14
|
component: e.component,
|
|
15
15
|
data: r[a],
|
|
@@ -20,7 +20,7 @@ function r(e, t, n, r, i) {
|
|
|
20
20
|
status: i?.[a] ?? "idle"
|
|
21
21
|
}));
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function r(e, t, n, r, i) {
|
|
24
24
|
return {
|
|
25
25
|
hash: e.hash,
|
|
26
26
|
historyState: e.historyState,
|
|
@@ -32,28 +32,28 @@ function i(e, t, n, r, i) {
|
|
|
32
32
|
query: t
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
async function
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
async function i(t, n, r) {
|
|
36
|
+
let i = !1;
|
|
37
|
+
async function a(o) {
|
|
38
|
+
if (o < n.length) {
|
|
38
39
|
let r = !1;
|
|
39
|
-
await n[
|
|
40
|
-
if (r) throw new
|
|
41
|
-
r = !0, await
|
|
40
|
+
await n[o](t, async () => {
|
|
41
|
+
if (r) throw new e("next() called multiple times");
|
|
42
|
+
r = !0, await a(o + 1);
|
|
42
43
|
});
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
|
-
await r();
|
|
46
|
+
i = !0, await r();
|
|
46
47
|
}
|
|
47
|
-
await
|
|
48
|
+
return await a(0), i;
|
|
48
49
|
}
|
|
49
|
-
function
|
|
50
|
-
if (
|
|
51
|
-
|
|
50
|
+
function a(e, t, n) {
|
|
51
|
+
if (n) {
|
|
52
|
+
n(e, t);
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
e("Unhandled router error. Provide an onError callback to handle errors explicitly:", t);
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
|
-
export {
|
|
57
|
+
export { n as buildMatchBranch, r as createRouteContext, t as createRouteState, i as executeMiddlewarePipeline, a as reportError };
|
|
58
58
|
|
|
59
59
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import type {\n MatchStatus,\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\nimport { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** R5: No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState<TMeta = unknown, TComponent = unknown>(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch<TMeta, TComponent>;\n status: NavigationStatus;\n}): RouteState<TMeta, TComponent> {\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, data results, and optional per-node statuses.\n * F1: Each node carries its own `status` for fine-grained nested layout feedback.\n */\nexport function buildMatchBranch<TMeta = unknown, TComponent = unknown>(\n branchDefs: readonly RouteBranchDef<TMeta, TComponent>[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n statuses?: readonly MatchStatus[],\n): RouteMatchBranch<TMeta, TComponent> {\n return branchDefs.map((def, i): RouteMatchBranch<TMeta, TComponent>[number] => ({\n component: def.component as TComponent,\n data: dataResults[i],\n meta: def.meta as TMeta,\n name: def.name,\n params: { ...params },\n pathname,\n status: statuses?.[i] ?? 'idle',\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): Promise<
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../src/context.ts"],"sourcesContent":["import type {\n MatchStatus,\n Middleware,\n NavigationStatus,\n ResolvedQueryParams,\n RouteBranchDef,\n RouteContext,\n RouteLocation,\n RouteMatchBranch,\n RouteParams,\n RouterErrorContext,\n RouteState,\n RouteTable,\n} from './types';\n\nimport { error as logError } from './_dev';\nimport { WayfinderApiError } from './errors';\n\n// ─── Route state ──────────────────────────────────────────────────────────────\n\n/** R5: No defensive deep-copy — RouteState is typed readonly; callers always pass fresh objects. */\nexport function createRouteState<TMeta = unknown, TComponent = unknown>(input: {\n error?: unknown;\n location: RouteLocation;\n matches: RouteMatchBranch<TMeta, TComponent>;\n status: NavigationStatus;\n}): RouteState<TMeta, TComponent> {\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, data results, and optional per-node statuses.\n * F1: Each node carries its own `status` for fine-grained nested layout feedback.\n */\nexport function buildMatchBranch<TMeta = unknown, TComponent = unknown>(\n branchDefs: readonly RouteBranchDef<TMeta, TComponent>[],\n params: RouteParams,\n pathname: string,\n dataResults: unknown[],\n statuses?: readonly MatchStatus[],\n): RouteMatchBranch<TMeta, TComponent> {\n return branchDefs.map((def, i): RouteMatchBranch<TMeta, TComponent>[number] => ({\n component: def.component as TComponent,\n data: dataResults[i],\n meta: def.meta as TMeta,\n name: def.name,\n params: { ...params },\n pathname,\n status: statuses?.[i] ?? 'idle',\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): 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 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\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":";;;AAqBA,SAAgB,EAAwD,GAKtC;CAChC,OAAO;EACL,OAAO,EAAM;EACb,UAAU,EAAM;EAChB,SAAS,EAAM;EACf,QAAQ,EAAM;CAChB;AACF;AAMA,SAAgB,EACd,GACA,GACA,GACA,GACA,GACqC;CACrC,OAAO,EAAW,KAAK,GAAK,OAAoD;EAC9E,WAAW,EAAI;EACf,MAAM,EAAY;EAClB,MAAM,EAAI;EACV,MAAM,EAAI;EACV,QAAQ,EAAE,GAAG,EAAO;EACpB;EACA,QAAQ,IAAW,MAAM;CAC3B,EAAE;AACJ;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,GACkB;CAClB,IAAI,IAAc;CAElB,eAAe,EAAS,GAA8B;EACpD,IAAI,IAAQ,EAAW,QAAQ;GAC7B,IAAI,IAAS;GAEb,MAAM,EAAW,EAAM,CAAE,GAAS,YAAY;IAC5C,IAAI,GAAQ,MAAM,IAAI,EAAkB,8BAA8B;IAGtE,AADA,IAAS,IACT,MAAM,EAAS,IAAQ,CAAC;GAC1B,CAAC;GAED;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"}
|
package/dist/errors.cjs.map
CHANGED
|
@@ -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 static is(err: unknown): err is WayfinderError {\n return err instanceof WayfinderError;\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,MAAa,UAAuB,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,
|
|
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 static is(err: unknown): err is WayfinderError {\n return err instanceof WayfinderError;\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,MAAa,UAAuB,KAAM,CACxC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAqC,CAC7C,OAAO,aAAe,CACxB,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"}
|
package/dist/errors.js.map
CHANGED
|
@@ -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 static is(err: unknown): err is WayfinderError {\n return err instanceof WayfinderError;\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,MAAa,UAAuB,MAAM;CACxC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,
|
|
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 static is(err: unknown): err is WayfinderError {\n return err instanceof WayfinderError;\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,MAAa,UAAuB,MAAM;CACxC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;CAEA,OAAO,GAAG,GAAqC;EAC7C,OAAO,aAAe;CACxB;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"}
|
package/dist/router.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./errors.cjs"),t=require("./path.cjs"),n=require("./compile.cjs"),r=require("./context.cjs"),i=require("./guards.cjs"),a=require("./history.cjs"),o=require("./hydration.cjs"),s=require("./preload.cjs");function c(t,n){let r=n.get(t);if(r)return r;let i=[...n.keys()].join(`, `);throw new e.WayfinderRouteError(i?`Unknown route name: ${t}. Available routes: ${i}`:`Unknown route name: ${t}`)}function l(e,n,r=`/`){if(`path`in e)return e.path;let i=t.buildUrl(r,c(e.name,n).path,e.params,e.query);return e.hash?`${i}#${e.hash}`:i}var u=Symbol(`wayfinder.errorContext`);function d(e,t){typeof e==`object`&&e&&(e[u]=t)}function f(e){if(typeof e==`object`&&e)return e[u]}function p(e){return typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`&&typeof e.next==`function`&&typeof e.return==`function`}var m=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l=null;#u=new Set;#d;#f=!1;#p=new AbortController;#m=`/`;#h=new Set;#g;#_;#v;#y;constructor(e){let i=n.compileRoutes(e);if(this.#e=t.normalizePath(e.base??`/`),this.#t=e.middleware??[],this.#n=e.coerceSearch,this.#r=e.history??a.createBrowserHistory(),this.#s=e.viewTransition??!1,this.#o=e.scroll,this.#c=e.onError,this.#i=i.records,this.#a=i.routesByName,this.#_=o.createHydrationManager(),this.#v=s.createPreloadManager(),this.#d=r.createRouteState({location:{hash:``,historyState:null,pathname:`/`,query:{}},matches:[],status:`idle`}),e.notFound){let t=e.notFound,n={component:t.component,dataFn:t.data,meta:t.meta,name:`__notFound__`};this.#g={branchDefs:[n],leaf:n,matcher:{paramNames:[],pattern:/(?:)/,prefixPattern:/(?:)/},ownMiddleware:t.middleware??[],path:`/*`}}else this.#g=null;this.#y=this.#x();let{hash:c,pathname:l,search:u}=this.#r.location;this.#m=`${l}${u}${c}`,this.#w(this.#F(),{source:`initial-navigation`})}getSnapshot(){return this.#d}subscribe(e){return this.#b(),this.#h.add(e),()=>{this.#h.delete(e)}}navigate(e,t){let n=l(typeof e==`string`?{path:e}:e,this.#a);return this.#z(n,t)}url(e,n,r){let i=c(e,this.#a);return t.buildUrl(this.#e,i.path,n,r)}isActive(e,n={}){let r=c(e,this.#a),i=this.#d.location.pathname;return n.exact??!1?t.matchRouteFor(i,[r]).record!=null:t.matchesPrefix(i,r)}resolve(e){let n=t.stripBase(t.normalizePath(e),this.#e),{params:i,record:a}=t.matchRouteFor(n,this.#i);if(!a||a.redirect)return null;let o=this.#_.effectiveDefs(a),s=r.buildMatchBranch(o,i,n,o.map(()=>void 0));return s.length?s:null}async match(e,t){let n=await this.#k(e);if(n.type!==`matched`)return null;let{location:i,params:a,record:o,resolvedQuery:s}=n,c=this.#_.effectiveDefs(o),l=c.some(e=>e.dataFn!=null),u=c.map(()=>void 0),d,f=`idle`;if(l){let e=t?.signal??new AbortController().signal,n=r.createRouteContext(i,s,a,r.buildMatchBranch(c,a,i.pathname,u),()=>Promise.resolve());try{u=await this.#D(c,n,e)}catch(e){d=e,f=`error`}}return r.createRouteState({error:d,location:i,matches:r.buildMatchBranch(c,a,i.pathname,u),status:f})}waitFor(e){return this.#b(),new Promise((t,n)=>{let r=t=>t.status===`idle`&&t.matches.some(t=>t.name===e);if(this.#d.status===`error`){n(this.#d.error);return}if(r(this.#d)){t(this.#d);return}let i=this.subscribe(e=>{r(e)?(i(),t(e)):e.status===`error`&&(i(),n(e.error))});this.#p.signal.addEventListener(`abort`,()=>{i(),n(this.#p.signal.reason)},{once:!0})})}async preload(e,n,r){this.#b();let i=c(e,this.#a),a=t.buildPreloadKey(this.#e,i.path,n,r),o=this.#v.getInflight(a);if(o)return o;let s=this.#A(a,this.#p.signal,r).finally(()=>{this.#v.untrack(a)});this.#v.track(a,s);try{return await s}catch(e){throw this.#c&&this.#C(e,{source:`preload`}),e}}beforeLeave(e,t){this.#b();let n={handler:e,routes:t?.routes};return this.#u.add(n),()=>{this.#u.delete(n)}}get disposalSignal(){return this.#p.signal}get disposed(){return this.#f}dispose(){this.#f||(this.#f=!0,this.#u.clear(),this.#h.clear(),this.#l?.abort(),this.#l=null,this.#y(),this.#p.abort(new e.WayfinderDisposedError))}[Symbol.dispose](){this.dispose()}#b(){if(this.#f)throw new e.WayfinderDisposedError}#x(){return this.#r.onPopstate(()=>{let{hash:e,pathname:t,search:n}=this.#r.location,r=`${t}${n}${e}`,i=this.#m;r!==i&&this.#w(this.#S(r,i),{source:`history-listener`})})}async#S(e,n){let r=this.#d.matches.map(e=>e.name),a=new URL(e,`http://localhost`),o=t.stripBase(a.pathname,this.#e),{params:s,record:c}=t.matchRouteFor(o,this.#i),l={name:c?.leaf.name,params:s,pathname:o,query:t.parseQuery(a.search)};if(!await i.runLeaveBlockers(this.#u,r,l)){this.#r.replace(n,this.#d.location.historyState);return}this.#m=e,await this.#F()}#C(e,t){r.reportError(e,t,this.#c)}#w(e,t){e.catch(e=>{this.#C(e,f(e)??t)})}#T(){this.#h.forEach(e=>e(this.#d))}async#E(e,t){let n;for(;;){if(t.aborted)return await e.return(void 0).catch(()=>void 0),n;let{done:r,value:i}=await e.next();if(r)return i??n;n=i}}async#D(e,t,n){return Promise.all(e.map(async e=>{if(!e.dataFn)return;let r=e.dataFn,i=r({...t,signal:n});try{return p(i)?await this.#E(i,n):await i}catch(r){if(e.onError)return e.onError(r,{...t,signal:n});throw r}}))}async#O(e,t,n,i,a,o){let s=e.map(e=>{if(!e.dataFn)return;let r=e.dataFn;return r({...t,signal:n})}),c=[],l=await Promise.all(s.map(async(r,i)=>{if(p(r)){c.push(i);return}if(r!==void 0)try{return await r}catch(r){let a=e[i];if(a.onError)return a.onError(r,{...t,signal:n});throw r}}));if(c.length===0)return l;let u=[...l],d=(t,n)=>{if(!i())return;u[n]=t;let s=e.map((e,t)=>c.includes(t)?`streaming`:`idle`);this.#d=r.createRouteState({location:a,matches:r.buildMatchBranch(e,o,a.pathname,u,s),status:`streaming`}),this.#T()};return await Promise.all(c.map(async r=>{let a=s[r];try{u[r]=await this.#M(a,r,n,i,d)}catch(i){let a=e[r];if(a.onError)u[r]=await a.onError(i,{...t,signal:n});else throw i}})),u}async#k(n){let r=n;for(let e=0;e<5;e+=1){let e=new URL(r,`http://localhost`),n={hash:e.hash.replace(/^#/,``),historyState:null,pathname:t.stripBase(e.pathname,this.#e),query:t.parseQuery(e.search)},i=await this.#j(n);if(i.type!==`redirect`)return i;r=this.#L(i.redirectTo)}throw new e.WayfinderRedirectLoopError}async#A(e,n,i){let a=await this.#k(e);if(a.type!==`matched`)return;let{location:o,params:s,record:c,resolvedQuery:l}=a,u=this.#_.effectiveDefs(c);if(!u.some(e=>e.dataFn!=null))return;let d=r.createRouteContext(o,l,s,r.buildMatchBranch(u,s,o.pathname,u.map(()=>void 0)),()=>Promise.resolve()),f=await this.#D(u,d,n);this.#v.set(t.buildPreloadKey(this.#e,c.path,s,i??o.query),f)}async#j(e){let{params:n,record:i}=t.matchRouteFor(e.pathname,this.#i);if(!i)return{location:e,params:n,type:`unmatched`};if(i.redirect)return{location:e,params:n,redirectTo:l(i.redirect,this.#a,this.#e),type:`redirect`};let a=e.query,o=i.coerceSearch??this.#n;if(o)try{a=o(e.query)}catch(t){this.#C(t,{source:`coerce-search`}),a=e.query}await this.#_.hydrate(i);let s=this.#_.effectiveDefs(i);return{branch:r.buildMatchBranch(s,n,e.pathname,s.map(()=>void 0)),location:e,params:n,record:i,resolvedQuery:a,type:`matched`}}async#M(e,t,n,r,i){let a;try{for(;;){if(n.aborted||!r())return await e.return(void 0),a;let{done:o,value:s}=await e.next();if(o)return s??a;a=s,i(s,t)}}catch(t){throw await e.return(void 0).catch(()=>void 0),t}}async#N(e,n,i,a,o,s,c){if(!c())return;let l=this.#_.effectiveDefs(e),u=l.some(e=>e.dataFn!=null),f=l.map(()=>void 0);if(u){let o=t.buildPreloadKey(this.#e,e.path,a,i.query),u=this.#v.consume(o);if(u)f=u;else{let t=l.map(e=>e.dataFn?`loading`:`idle`);this.#d=r.createRouteState({location:i,matches:r.buildMatchBranch(l,a,i.pathname,f,t),status:`loading`}),this.#T();try{f=await this.#O(l,n,s,c,i,a)}catch(t){throw this.#d=r.createRouteState({error:t,location:i,matches:r.buildMatchBranch(l,a,i.pathname,f),status:`error`}),d(t,{routeName:e.leaf.name,source:`data-loader`}),t}}}c()&&(this.#d=r.createRouteState({location:i,matches:r.buildMatchBranch(l,a,i.pathname,f),status:`idle`}))}async#P(e,t){if((t??this.#s)&&typeof document<`u`){let t=document;if(t.startViewTransition){await t.startViewTransition(e).finished;return}}await e()}async#F(e,n=0){this.#l?.abort();let i=new AbortController;this.#l=i;let a=this.#d,o=()=>!i.signal.aborted&&!this.#f,s=t.readLocation(this.#e,this.#r),c=await this.#j(s);if(!o())return;if(c.type===`redirect`){await this.#R(c.redirectTo,!0,n);return}if(c.type===`unmatched`){if(this.#g){let t=r.buildMatchBranch([this.#g.leaf],{},s.pathname,[void 0]),n=!1,c=s.query;if(this.#n)try{c=this.#n(s.query)}catch(e){this.#C(e,{source:`coerce-search`})}let l=async()=>{if(!o())return;let e=r.createRouteContext(s,c,{},t,(e,t)=>this.navigate(e,t));await r.executeMiddlewarePipeline(e,[...this.#t,...this.#g.ownMiddleware],async()=>{n=!0,await this.#N(this.#g,e,s,{},t,i.signal,o)})};try{await this.#P(l,e)}finally{o()&&n&&(this.#T(),this.#I(this.#d,a))}return}this.#d=r.createRouteState({location:c.location,matches:[],status:`idle`}),this.#T(),this.#I(this.#d,a);return}let{branch:l,location:u,params:d,record:f,resolvedQuery:p}=c,m=!1,h=async()=>{if(!o())return;let e=r.createRouteContext(u,p,d,l,(e,t)=>this.navigate(e,t));await r.executeMiddlewarePipeline(e,[...this.#t,...f.ownMiddleware],async()=>{m=!0,await this.#N(f,e,u,d,l,i.signal,o)})};try{await this.#P(h,e)}finally{o()&&m&&(this.#T(),this.#I(this.#d,a))}}#I(e,t){if(!this.#o||typeof window>`u`)return;let n=this.#o(e,t);if(n!==`preserve`){if(n===`top`){window.scrollTo(0,0);return}window.scrollTo(n.x,n.y)}}#L(e){let n=new URL(e,`http://localhost`),r=t.stripBase(n.pathname,this.#e);return`${t.joinPaths(this.#e,r)}${n.search}${n.hash}`}async#R(t,n=!0,r=0){if(r>=5)throw new e.WayfinderRedirectLoopError;let i=this.#L(t);this.#m=i,n?this.#r.replace(i):this.#r.push(i),await this.#F(void 0,r+1)}async#z(e,n={}){this.#b();let r=this.#L(e);if(!n.force&&r===this.#m)return;let a=this.#m,o=this.#d.matches.map(e=>e.name),s=new URL(r,`http://localhost`),c=t.stripBase(s.pathname,this.#e),{params:l,record:u}=t.matchRouteFor(c,this.#i),d={name:u?.leaf.name,params:l,pathname:c,query:t.parseQuery(s.search)};if(await i.runLeaveBlockers(this.#u,o,d)){this.#m=r,n.replace?this.#r.replace(r,n.state):this.#r.push(r,n.state);try{await this.#F(n.viewTransition)}catch(e){throw this.#m=a,e}}}};function h(e){return new m(e)}exports.createRouter=h;
|
|
1
|
+
const e=require("./_navigation.cjs"),t=require("./errors.cjs"),n=require("./path.cjs"),r=require("./compile.cjs"),i=require("./context.cjs"),a=require("./guards.cjs"),o=require("./history.cjs"),s=require("./hydration.cjs"),c=require("./preload.cjs");function l(e,n){let r=n.get(e);if(r)return r;let i=[...n.keys()].join(`, `);throw new t.WayfinderRouteError(i?`Unknown route name: ${e}. Available routes: ${i}`:`Unknown route name: ${e}`)}function u(e,t,r=`/`){if(`path`in e)return e.path;let i=l(e.name,t),a=n.buildUrl(r,i.path,e.params,e.query);return e.hash?`${a}#${e.hash}`:a}var d=Symbol(`wayfinder.errorContext`);function f(e,t){typeof e==`object`&&e&&(e[d]=t)}function p(e){if(typeof e==`object`&&e)return e[d]}function m(e){return typeof e==`object`&&!!e&&typeof e[Symbol.asyncIterator]==`function`&&typeof e.next==`function`&&typeof e.return==`function`}var h=class{#e;#t;#n;#r;#i;#a;#o;#s;#c;#l=new Set;#u=e.createNavigationCoordinator();#d;#f=!1;#p=new AbortController;#m=`/`;#h=new Set;#g;#_;#v;#y;ready;constructor(e){let t=r.compileRoutes(e);if(this.#e=n.normalizePath(e.base??`/`),this.#t=e.middleware??[],this.#n=e.coerceSearch,this.#r=e.history??o.createBrowserHistory(),this.#s=e.viewTransition??!1,this.#o=e.scroll,this.#c=e.onError,this.#i=t.records,this.#a=t.routesByName,this.#_=s.createHydrationManager(),this.#v=c.createPreloadManager(),this.#d=i.createRouteState({location:{hash:``,historyState:null,pathname:`/`,query:{}},matches:[],status:`idle`}),e.notFound){let t=e.notFound,n={component:t.component,dataFn:t.data,meta:t.meta,name:`__notFound__`};this.#g={branchDefs:[n],leaf:n,matcher:{paramNames:[],pattern:/(?:)/,prefixPattern:/(?:)/},ownMiddleware:t.middleware??[],path:`/*`}}else this.#g=null;this.#y=this.#x();let{hash:a,pathname:l,search:u}=this.#r.location;this.#m=`${l}${u}${a}`;let d=this.#u.begin();this.ready=this.#F(d,n.readLocation(this.#e,this.#r),void 0,0,!1,(e,t)=>{if(!d.isCurrent())return;let n=this.#z(e);t&&this.#r.replace(n,e.historyState),this.#m=n}).then(()=>void 0),this.#w(this.ready,{source:`initial-navigation`}),this.beforeLeave=this.beforeLeave.bind(this),this.dispose=this.dispose.bind(this),this.getSnapshot=this.getSnapshot.bind(this),this.isActive=this.isActive.bind(this),this.loadPath=this.loadPath.bind(this),this.matchPath=this.matchPath.bind(this),this.navigate=this.navigate.bind(this),this.preload=this.preload.bind(this),this.subscribe=this.subscribe.bind(this),this.url=this.url.bind(this),this.waitFor=this.waitFor.bind(this)}getSnapshot(){return this.#d}subscribe(e){return this.#b(),this.#h.add(e),()=>{this.#h.delete(e)}}navigate(e,t){let n=u(typeof e==`string`?{path:e}:e,this.#a);return this.#V(n,t)}url(e,t,r){let i=l(e,this.#a);return n.buildUrl(this.#e,i.path,t,r)}isActive(e,t={}){let r=l(e,this.#a),i=this.#d.location.pathname;return t.exact??!1?n.matchRouteFor(i,[r]).record!=null:n.matchesPrefix(i,r)}matchPath(e){let t=n.stripBase(n.normalizePath(e),this.#e),{params:r,record:a}=n.matchRouteFor(t,this.#i);if(!a||a.redirect)return null;let o=this.#_.effectiveDefs(a),s=i.buildMatchBranch(o,r,t,o.map(()=>void 0));return s.length?s:null}async loadPath(e,t){let n=await this.#k(e);if(n.type!==`matched`)return null;let{location:r,params:a,record:o,resolvedQuery:s}=n,c=this.#_.effectiveDefs(o),l=c.some(e=>e.dataFn!=null),u=c.map(()=>void 0),d,f=`idle`;if(l){let e=t?.signal??new AbortController().signal,n=i.buildMatchBranch(c,a,r.pathname,u),o=i.createRouteContext(r,s,a,n,()=>Promise.resolve());try{u=await this.#D(c,o,e)}catch(e){d=e,f=`error`}}return i.createRouteState({error:d,location:r,matches:i.buildMatchBranch(c,a,r.pathname,u),status:f})}waitFor(e){return this.#b(),new Promise((t,n)=>{let r=t=>t.status===`idle`&&t.matches.some(t=>t.name===e);if(this.#d.status===`error`){n(this.#d.error);return}if(r(this.#d)){t(this.#d);return}let i=this.subscribe(e=>{r(e)?(i(),t(e)):e.status===`error`&&(i(),n(e.error))});this.#p.signal.addEventListener(`abort`,()=>{i(),n(this.#p.signal.reason)},{once:!0})})}async preload(e,t,r){this.#b();let i=l(e,this.#a),a=n.buildPreloadKey(this.#e,i.path,t,r),o=this.#v.getInflight(a);if(o)return o;let s=this.#A(a,this.#p.signal,r).finally(()=>{this.#v.untrack(a)});this.#v.track(a,s);try{return await s}catch(e){throw this.#c&&this.#C(e,{source:`preload`}),e}}beforeLeave(e,t){this.#b();let n={handler:e,routes:t?.routes};return this.#l.add(n),()=>{this.#l.delete(n)}}get disposalSignal(){return this.#p.signal}get disposed(){return this.#f}dispose(){this.#f||(this.#f=!0,this.#l.clear(),this.#h.clear(),this.#u.invalidate(new t.WayfinderDisposedError),this.#y(),this.#p.abort(new t.WayfinderDisposedError))}[Symbol.dispose](){this.dispose()}#b(){if(this.#f)throw new t.WayfinderDisposedError}#x(){return this.#r.onPopstate(()=>{let{hash:e,pathname:t,search:n}=this.#r.location,r=`${t}${n}${e}`,i=this.#m;r!==i&&this.#w(this.#S(r,i),{source:`history-listener`})})}async#S(e,t){let r=this.#u.begin(),i=this.#d.matches.map(e=>e.name),o=this.#B(e),s=await a.runLeaveBlockers(this.#l,i,o);if(!r.isCurrent())return;if(!s){this.#r.replace(t,this.#d.location.historyState);return}let c=await this.#F(r,n.readLocation(this.#e,this.#r),void 0,0,!1,(e,t)=>{if(!r.isCurrent())return;let n=this.#z(e);t&&this.#r.replace(n,e.historyState),this.#m=n});r.isCurrent()&&!c&&this.#r.replace(t,this.#d.location.historyState)}#C(e,t){i.reportError(e,t,this.#c)}#w(e,t){e.catch(e=>{this.#C(e,p(e)??t)})}#T(){this.#h.forEach(e=>e(this.#d))}async#E(e,t){let n;for(;;){if(t.aborted)return await e.return(void 0).catch(()=>void 0),n;let{done:r,value:i}=await e.next();if(r)return i??n;n=i}}async#D(e,t,n){return Promise.all(e.map(async e=>{if(!e.dataFn)return;let r=e.dataFn,i=r({...t,signal:n});try{return m(i)?await this.#E(i,n):await i}catch(r){if(e.onError)return e.onError(r,{...t,signal:n});throw r}}))}async#O(e,t,n,r,a,o){let s=e.map(e=>{if(!e.dataFn)return;let r=e.dataFn;return r({...t,signal:n})}),c=[],l=await Promise.all(s.map(async(r,i)=>{if(m(r)){c.push(i);return}if(r!==void 0)try{return await r}catch(r){let a=e[i];if(a.onError)return a.onError(r,{...t,signal:n});throw r}}));if(c.length===0)return l;let u=[...l],d=(t,n)=>{if(!r())return;u[n]=t;let s=e.map((e,t)=>c.includes(t)?`streaming`:`idle`);this.#d=i.createRouteState({location:a,matches:i.buildMatchBranch(e,o,a.pathname,u,s),status:`streaming`}),this.#T()};return await Promise.all(c.map(async i=>{let a=s[i];try{u[i]=await this.#M(a,i,n,r,d)}catch(r){let a=e[i];if(a.onError)u[i]=await a.onError(r,{...t,signal:n});else throw r}})),u}async#k(e){let r=e;for(let e=0;e<5;e+=1){let e=new URL(r,`http://localhost`),t={hash:e.hash.replace(/^#/,``),historyState:null,pathname:n.stripBase(e.pathname,this.#e),query:n.parseQuery(e.search)},i=await this.#j(t);if(i.type!==`redirect`)return i;r=this.#L(i.redirectTo)}throw new t.WayfinderRedirectLoopError}async#A(e,t,r){let a=await this.#k(e);if(a.type!==`matched`)return;let{location:o,params:s,record:c,resolvedQuery:l}=a,u=this.#_.effectiveDefs(c);if(!u.some(e=>e.dataFn!=null))return;let d=i.buildMatchBranch(u,s,o.pathname,u.map(()=>void 0)),f=i.createRouteContext(o,l,s,d,()=>Promise.resolve()),p=await this.#D(u,f,t);this.#v.set(n.buildPreloadKey(this.#e,c.path,s,r??o.query),p)}async#j(e){let{params:t,record:r}=n.matchRouteFor(e.pathname,this.#i);if(!r)return{location:e,params:t,type:`unmatched`};if(r.redirect)return{location:e,params:t,redirectTo:u(r.redirect,this.#a,this.#e),type:`redirect`};let a=e.query,o=r.coerceSearch??this.#n;if(o)try{a=o(e.query)}catch(t){this.#C(t,{source:`coerce-search`}),a=e.query}await this.#_.hydrate(r);let s=this.#_.effectiveDefs(r);return{branch:i.buildMatchBranch(s,t,e.pathname,s.map(()=>void 0)),location:e,params:t,record:r,resolvedQuery:a,type:`matched`}}async#M(e,t,n,r,i){let a;try{for(;;){if(n.aborted||!r())return await e.return(void 0),a;let{done:o,value:s}=await e.next();if(o)return s??a;a=s,i(s,t)}}catch(t){throw await e.return(void 0).catch(()=>void 0),t}}async#N(e,t,r,a,o,s,c){if(!c())return;let l=this.#_.effectiveDefs(e),u=l.some(e=>e.dataFn!=null),d=l.map(()=>void 0);if(u){let o=n.buildPreloadKey(this.#e,e.path,a,r.query),u=this.#v.consume(o);if(u)d=u;else{let n=l.map(e=>e.dataFn?`loading`:`idle`);this.#d=i.createRouteState({location:r,matches:i.buildMatchBranch(l,a,r.pathname,d,n),status:`loading`}),this.#T();try{d=await this.#O(l,t,s,c,r,a)}catch(t){if(!c())return;throw this.#d=i.createRouteState({error:t,location:r,matches:i.buildMatchBranch(l,a,r.pathname,d),status:`error`}),f(t,{routeName:e.leaf.name,source:`data-loader`}),t}}}c()&&(this.#d=i.createRouteState({location:r,matches:i.buildMatchBranch(l,a,r.pathname,d),status:`idle`}))}async#P(e,t){if((t??this.#s)&&typeof document<`u`){let t=document;if(t.startViewTransition){await t.startViewTransition(e).finished;return}}await e()}async#F(e,n,r,a=0,o=!1,s=()=>void 0){let c=this.#d,l=()=>e.isCurrent()&&!this.#f,u=await this.#j(n);if(!l())return!1;if(u.type===`redirect`){if(a>=5)throw new t.WayfinderRedirectLoopError;return this.#F(e,this.#R(u.redirectTo,n.historyState),r,a+1,!0,s)}if(u.type===`unmatched`){if(this.#g){let t=[this.#g.leaf],a=i.buildMatchBranch(t,{},n.pathname,[void 0]),u=!1,d=!1,f=n.query;if(this.#n)try{f=this.#n(n.query)}catch(e){this.#C(e,{source:`coerce-search`})}let p=async()=>{if(!l())return;let t=i.createRouteContext(n,f,{},a,(e,t)=>this.navigate(e,t));d=await i.executeMiddlewarePipeline(t,[...this.#t,...this.#g.ownMiddleware],async()=>{l()&&(u=!0,s(n,o),l()&&await this.#N(this.#g,t,n,{},a,e.signal,l))})};try{await this.#P(p,r)}finally{l()&&u&&(this.#T(),this.#I(this.#d,c))}return d&&u}return!l()||(s(u.location,o),!l())?!1:(this.#d=i.createRouteState({location:u.location,matches:[],status:`idle`}),this.#T(),this.#I(this.#d,c),!0)}let{branch:d,location:f,params:p,record:m,resolvedQuery:h}=u,g=!1,_=!1,v=async()=>{if(!l())return;let t=i.createRouteContext(f,h,p,d,(e,t)=>this.navigate(e,t));_=await i.executeMiddlewarePipeline(t,[...this.#t,...m.ownMiddleware],async()=>{l()&&(g=!0,s(f,o),l()&&await this.#N(m,t,f,p,d,e.signal,l))})};try{await this.#P(v,r)}finally{l()&&g&&(this.#T(),this.#I(this.#d,c))}return _&&g}#I(e,t){if(!this.#o||typeof window>`u`)return;let n=this.#o(e,t);if(n!==`preserve`){if(n===`top`){window.scrollTo(0,0);return}window.scrollTo(n.x,n.y)}}#L(e){let t=new URL(e,`http://localhost`),r=n.stripBase(t.pathname,this.#e);return`${n.joinPaths(this.#e,r)}${t.search}${t.hash}`}#R(e,t){let r=new URL(this.#L(e),`http://localhost`);return{hash:r.hash.replace(/^#/,``),historyState:t,pathname:n.stripBase(r.pathname,this.#e),query:n.parseQuery(r.search)}}#z(e){let t=new URLSearchParams;for(let[n,r]of Object.entries(e.query))Array.isArray(r)?r.forEach(e=>t.append(n,e)):t.set(n,r);let r=t.toString(),i=e.hash?`#${e.hash}`:``;return`${n.joinPaths(this.#e,e.pathname)}${r?`?${r}`:``}${i}`}#B(e){let t=new URL(e,`http://localhost`),r=n.stripBase(t.pathname,this.#e),{params:i,record:a}=n.matchRouteFor(r,this.#i);return{name:a?.leaf.name,params:i,pathname:r,query:n.parseQuery(t.search)}}async#V(e,t={}){this.#b();let n=this.#L(e);if(!t.force&&n===this.#m)return;let r=this.#u.begin(),i=this.#d.matches.map(e=>e.name),o=await a.runLeaveBlockers(this.#l,i,this.#B(n));!r.isCurrent()||!o||await this.#F(r,this.#R(n,t.state),t.viewTransition,0,t.replace??!1,(e,t)=>{if(!r.isCurrent())return;let n=this.#z(e);t?this.#r.replace(n,e.historyState):this.#r.push(n,e.historyState),this.#m=n})}};function g(e){return new h(e)}exports.createRouter=g;
|
|
2
2
|
//# sourceMappingURL=router.cjs.map
|