@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.
@@ -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, RouteNode, RouterState } from './types.js'
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 nodes. */
20
- routes: RouteNode[]
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: RouteNode[]
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: RouteNode[]): void {
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)) ?? []
@@ -89,7 +89,7 @@ export interface RouteMatch {
89
89
 
90
90
  // ─── Route tree ─────────────────────────────────────────────────────────────
91
91
 
92
- /** A node in the route tree. */
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 and URLPattern
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
 
@@ -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, RouteNode } from '../engine/types.js'
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: RouteNode[]
31
+ routes: RouteTree
32
32
  persistentParams?: () => Record<string, string>
33
33
  pageRegistry?: Record<string, string>
34
34
  }