@buzola/router 0.0.10 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/matcher.d.ts +6 -4
- package/dist/engine/matcher.d.ts.map +1 -1
- package/dist/engine/matcher.js +35 -84
- package/dist/engine/matcher.js.map +1 -1
- package/dist/engine/route-tree.d.ts +8 -6
- package/dist/engine/route-tree.d.ts.map +1 -1
- package/dist/engine/route-tree.js +89 -55
- package/dist/engine/route-tree.js.map +1 -1
- package/dist/engine/router.d.ts +4 -4
- package/dist/engine/router.d.ts.map +1 -1
- package/dist/engine/router.js.map +1 -1
- package/dist/engine/types.d.ts +28 -9
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/react/provider.d.ts +2 -2
- package/dist/react/provider.d.ts.map +1 -1
- package/package.json +2 -4
- package/src/__tests__/matcher.test.ts +169 -0
- package/src/__tests__/router.test.ts +9 -3
- package/src/engine/matcher.ts +44 -88
- package/src/engine/route-tree.ts +108 -62
- package/src/engine/router.ts +5 -5
- package/src/engine/types.ts +27 -9
- package/src/env.d.ts +1 -45
- package/src/index.ts +1 -3
- package/src/react/provider.tsx +2 -2
package/src/engine/router.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LoaderCache } from './loader-cache.js'
|
|
2
2
|
import { matchRoutes } from './matcher.js'
|
|
3
|
-
import type { BlockerFn, NavigateOptions, NavigationAdapter,
|
|
3
|
+
import type { BlockerFn, NavigateOptions, NavigationAdapter, RouterState, RouteTree } from './types.js'
|
|
4
4
|
import { extractParamNames, parseParamSegment } from './utils.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -16,8 +16,8 @@ export class NavigationAbortedError extends Error {
|
|
|
16
16
|
export type RouterSubscriber = (state: RouterState) => void
|
|
17
17
|
|
|
18
18
|
export interface RouterOptions {
|
|
19
|
-
/** Route tree
|
|
20
|
-
routes:
|
|
19
|
+
/** Route tree (segment trie). */
|
|
20
|
+
routes: RouteTree
|
|
21
21
|
/** Navigation adapter (browser or memory). */
|
|
22
22
|
adapter: NavigationAdapter
|
|
23
23
|
/** Enable View Transitions API for navigations. */
|
|
@@ -52,7 +52,7 @@ export interface RouterOptions {
|
|
|
52
52
|
* Intercepts all navigations via the Navigation API and manages route matching.
|
|
53
53
|
*/
|
|
54
54
|
export class Router {
|
|
55
|
-
private routes:
|
|
55
|
+
private routes: RouteTree
|
|
56
56
|
private adapter: NavigationAdapter
|
|
57
57
|
private viewTransitions: boolean
|
|
58
58
|
private readonly _basePath: string
|
|
@@ -414,7 +414,7 @@ export class Router {
|
|
|
414
414
|
/**
|
|
415
415
|
* Update the route tree (for HMR).
|
|
416
416
|
*/
|
|
417
|
-
updateRoutes(routes:
|
|
417
|
+
updateRoutes(routes: RouteTree): void {
|
|
418
418
|
this.routes = routes
|
|
419
419
|
// Re-match current URL with new routes
|
|
420
420
|
const matches = matchRoutes(this.routes, this.createMatchUrl(this.state.location)) ?? []
|
package/src/engine/types.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface RouteMatch {
|
|
|
89
89
|
|
|
90
90
|
// ─── Route tree ─────────────────────────────────────────────────────────────
|
|
91
91
|
|
|
92
|
-
/** A node in
|
|
92
|
+
/** A node in a route match chain. Represents a layout or page with its component and metadata. */
|
|
93
93
|
export interface RouteNode {
|
|
94
94
|
/** Unique ID for this node. */
|
|
95
95
|
id: string
|
|
@@ -97,26 +97,44 @@ export interface RouteNode {
|
|
|
97
97
|
path: string
|
|
98
98
|
/** Full path from root (e.g., "/users/:userId"). */
|
|
99
99
|
fullPath: string
|
|
100
|
-
/** Compiled URLPattern for matching (leaf/index routes). */
|
|
101
|
-
pattern?: URLPattern
|
|
102
|
-
/** Compiled prefix URLPattern for param extraction (layout routes). */
|
|
103
|
-
prefixPattern?: URLPattern
|
|
104
100
|
/** Component to render. */
|
|
105
101
|
component?: RouteComponent
|
|
106
102
|
/** Search params schema. */
|
|
107
103
|
searchSchema?: StandardSchema
|
|
108
104
|
/** Preload function — triggers lazy component import ahead of navigation. */
|
|
109
105
|
preload?: () => void
|
|
110
|
-
/** Child nodes. */
|
|
111
|
-
children: RouteNode[]
|
|
112
|
-
/** Parent node reference. */
|
|
113
|
-
parent?: RouteNode
|
|
114
106
|
/** Whether this is a layout node (renders children via Outlet). */
|
|
115
107
|
isLayout: boolean
|
|
116
108
|
/** Whether this is an index route. */
|
|
117
109
|
isIndex: boolean
|
|
118
110
|
}
|
|
119
111
|
|
|
112
|
+
// ─── Route trie ─────────────────────────────────────────────────────────────
|
|
113
|
+
|
|
114
|
+
/** A node in the segment trie used for URL matching. */
|
|
115
|
+
export interface TrieNode {
|
|
116
|
+
/** Static children — exact segment match via Map lookup (O(1)). */
|
|
117
|
+
staticChildren: Map<string, TrieNode>
|
|
118
|
+
/** Dynamic child — matches any single segment as a named param. */
|
|
119
|
+
dynamicChild?: { paramName: string; node: TrieNode }
|
|
120
|
+
/** Catch-all child — matches all remaining segments. */
|
|
121
|
+
catchAllChild?: { paramName: string; chain: RouteNode[] }
|
|
122
|
+
/** When defined, a route terminates at this trie node. */
|
|
123
|
+
route?: TrieRoute
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** A terminal route in the trie, containing the layout chain from root to leaf. */
|
|
127
|
+
export interface TrieRoute {
|
|
128
|
+
/** Match chain: array of RouteNode from root layout to leaf page. */
|
|
129
|
+
chain: RouteNode[]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Opaque route tree built from RouteConfig[]. Passed to matchRoutes() and Router. */
|
|
133
|
+
export interface RouteTree {
|
|
134
|
+
/** @internal Root of the segment trie. */
|
|
135
|
+
root: TrieNode
|
|
136
|
+
}
|
|
137
|
+
|
|
120
138
|
// ─── Router state ───────────────────────────────────────────────────────────
|
|
121
139
|
|
|
122
140
|
/** The current state of the router. */
|
package/src/env.d.ts
CHANGED
|
@@ -1,50 +1,6 @@
|
|
|
1
|
-
// Type declarations for Navigation API
|
|
1
|
+
// Type declarations for Navigation API
|
|
2
2
|
// These are Baseline Newly Available (Jan 2026) but not yet in TypeScript's lib.
|
|
3
3
|
|
|
4
|
-
interface URLPatternInit {
|
|
5
|
-
protocol?: string
|
|
6
|
-
username?: string
|
|
7
|
-
password?: string
|
|
8
|
-
hostname?: string
|
|
9
|
-
port?: string
|
|
10
|
-
pathname?: string
|
|
11
|
-
search?: string
|
|
12
|
-
hash?: string
|
|
13
|
-
baseURL?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface URLPatternComponentResult {
|
|
17
|
-
input: string
|
|
18
|
-
groups: Record<string, string | undefined>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface URLPatternResult {
|
|
22
|
-
inputs: [URLPatternInit] | [URLPatternInit, string]
|
|
23
|
-
protocol: URLPatternComponentResult
|
|
24
|
-
username: URLPatternComponentResult
|
|
25
|
-
password: URLPatternComponentResult
|
|
26
|
-
hostname: URLPatternComponentResult
|
|
27
|
-
port: URLPatternComponentResult
|
|
28
|
-
pathname: URLPatternComponentResult
|
|
29
|
-
search: URLPatternComponentResult
|
|
30
|
-
hash: URLPatternComponentResult
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
declare class URLPattern {
|
|
34
|
-
constructor(init: URLPatternInit)
|
|
35
|
-
constructor(pattern: string, baseURL?: string)
|
|
36
|
-
test(input?: URLPatternInit | string): boolean
|
|
37
|
-
exec(input?: URLPatternInit | string): URLPatternResult | null
|
|
38
|
-
readonly protocol: string
|
|
39
|
-
readonly username: string
|
|
40
|
-
readonly password: string
|
|
41
|
-
readonly hostname: string
|
|
42
|
-
readonly port: string
|
|
43
|
-
readonly pathname: string
|
|
44
|
-
readonly search: string
|
|
45
|
-
readonly hash: string
|
|
46
|
-
}
|
|
47
|
-
|
|
48
4
|
interface NavigationDestination {
|
|
49
5
|
url: string
|
|
50
6
|
key: string
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// ─── Polyfills ──────────────────────────────────────────────────────────────
|
|
2
|
-
import 'urlpattern-polyfill'
|
|
3
|
-
|
|
4
1
|
// ─── Engine ─────────────────────────────────────────────────────────────────
|
|
5
2
|
export { LoaderCache } from './engine/loader-cache.js'
|
|
6
3
|
|
|
@@ -31,6 +28,7 @@ export type {
|
|
|
31
28
|
RouteMatch,
|
|
32
29
|
RouteNode,
|
|
33
30
|
RouterState,
|
|
31
|
+
RouteTree,
|
|
34
32
|
StandardSchema,
|
|
35
33
|
} from './engine/types.js'
|
|
36
34
|
|
package/src/react/provider.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useLayoutEffect, useMemo, useRef, useSyncExternalStore } from 'react'
|
|
2
2
|
import { createBrowserNavigationAdapter } from '../engine/navigation-adapter.js'
|
|
3
3
|
import { Router } from '../engine/router.js'
|
|
4
|
-
import type { RouteMatch,
|
|
4
|
+
import type { RouteMatch, RouteTree } from '../engine/types.js'
|
|
5
5
|
import { RouteContext, type RouteContextValue, RouterContext } from './context.js'
|
|
6
6
|
import { Outlet } from './outlet.js'
|
|
7
7
|
|
|
@@ -28,7 +28,7 @@ export type BuzolaProviderProps =
|
|
|
28
28
|
| { router: Router; routes?: never; persistentParams?: never; pageRegistry?: never }
|
|
29
29
|
| {
|
|
30
30
|
router?: never
|
|
31
|
-
routes:
|
|
31
|
+
routes: RouteTree
|
|
32
32
|
persistentParams?: () => Record<string, string>
|
|
33
33
|
pageRegistry?: Record<string, string>
|
|
34
34
|
}
|