svelte-navigator-lite 1.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # svelte-navigator-lite
2
2
 
3
- A lightweight, label-based router for Svelte 5. Define named routes that map to URL patterns, then use `router.route` reactively — not just to show components, but for any logic that depends on where you are.
3
+ A lightweight, pattern-based router for Svelte 5. Routes are defined with familiar URL patterns, guards are reusable named functions, and the reactive `router` singleton integrates directly with Svelte runes.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,261 +8,159 @@ A lightweight, label-based router for Svelte 5. Define named routes that map to
8
8
  npm install svelte-navigator-lite
9
9
  ```
10
10
 
11
- ## Setup
11
+ ## Quick start
12
12
 
13
- Call `createRouter` once at your app's entry point (e.g. `App.svelte`):
14
-
15
- ```ts
16
- import { createRouter, router } from 'svelte-navigator-lite';
17
- import type { RouteList } from 'svelte-navigator-lite';
18
-
19
- const routes: RouteList = {
20
- 'login': {
21
- rootPath: 'login',
22
- segments: [],
23
- },
24
- 'dashboard': {
25
- rootPath: 'dashboard',
26
- segments: [],
27
- },
28
- };
29
-
30
- createRouter(routes, 'dashboard'); // second argument is the default/fallback route
31
- ```
32
-
33
- Then use `router.route` anywhere in your Svelte components — it's a reactive Svelte 5 `$state` value:
13
+ Define your routes and guards, then call `createRouter` on mount.
34
14
 
35
15
  ```svelte
36
- {#if router.is('login')}
37
- <Login />
38
- {:else if router.is('dashboard')}
39
- <Dashboard />
40
- {/if}
41
- ```
42
-
43
- ---
44
-
45
- ## Defining Routes
46
-
47
- Every route has a `rootPath` — the first URL segment — and an array of `segments` for everything after it.
48
-
49
- ### Static routes
50
-
51
- ```ts
52
- 'login': {
53
- rootPath: 'login', // matches /login
54
- segments: [],
55
- }
56
- ```
57
-
58
- ### Dynamic params
59
-
60
- Use `name` to capture a URL segment into `router.params`:
61
-
62
- ```ts
63
- 'event': {
64
- rootPath: 'event',
65
- segments: [{ name: 'eventId' }], // matches /event/123
66
- }
67
- // router.params.eventId === '123'
68
- ```
69
-
70
- ### Enforced static segments
71
-
72
- Use `enforceVal` to require a literal string at that position:
73
-
74
- ```ts
75
- 'create-calendar': {
76
- rootPath: 'calendar',
77
- segments: [{ enforceVal: 'create' }], // matches /calendar/create only
78
- }
79
- ```
80
-
81
- ### Mixed segments
82
-
83
- `enforceVal` and `name` segments can be combined in any order:
84
-
85
- ```ts
86
- 'edit-event': {
87
- rootPath: 'event',
88
- segments: [
89
- { name: 'eventId' }, // matches /event/:eventId/edit
90
- { enforceVal: 'edit' },
91
- ],
92
- }
93
- ```
94
-
95
- ### Optional segments
96
-
97
- Add `optional: true` to make a trailing segment optional. Optional segments must come after all required segments.
98
-
99
- ```ts
100
- 'event': {
101
- rootPath: 'event',
102
- segments: [
103
- { name: 'eventId' },
104
- { enforceVal: 'edit', optional: true }, // matches /event/123 AND /event/123/edit
105
- ],
106
- }
107
- ```
108
-
109
- ---
110
-
111
- ## Search Params
112
-
113
- Search params are automatically captured into `router.searchParams` when present in the URL. No configuration is needed — they never affect whether a route matches.
114
-
115
- ```ts
116
- // /password-reset?token=abc → router.searchParams.token === 'abc'
117
- // /password-reset → router.searchParams === {}
118
- ```
119
-
120
- ---
16
+ <!-- App.svelte -->
17
+ <script lang="ts">
18
+ import { onMount } from 'svelte';
19
+ import { createRouter, router } from 'svelte-navigator-lite';
20
+ import { auth } from '$stores/auth.svelte';
21
+ import AppShell from '$lib/components/AppShell.svelte';
22
+
23
+ onMount(() => {
24
+ createRouter({
25
+ routes: [
26
+ { name: 'cal', pattern: '/cal' },
27
+ { name: 'cal-date', pattern: '/cal/:mm/:dd/:yyyy' },
28
+ { name: 'event', pattern: '/event/:eventId' },
29
+ { name: 'edit', pattern: '/event/:eventId/edit' },
30
+ { name: 'login', pattern: '/login', guards: ['unauth'] },
31
+ { name: 'signup', pattern: '/signup', guards: ['unauth'] },
32
+ ],
33
+ guards: {
34
+ auth: { condition: () => !auth.isValid(), redirectTo: 'login' },
35
+ unauth: { condition: () => auth.isValid(), redirectTo: 'cal' },
36
+ },
37
+ fallback: 'cal',
38
+ });
39
+ });
40
+ </script>
41
+
42
+ <AppShell />
43
+ ```
44
+
45
+ ## Route patterns
46
+
47
+ Patterns follow standard URL conventions.
48
+
49
+ | Pattern | Example URL | Params |
50
+ |---|---|---|
51
+ | `/cal` | `/cal` | `{}` |
52
+ | `/event/:eventId` | `/event/abc-123` | `{ eventId: 'abc-123' }` |
53
+ | `/event/:eventId/edit` | `/event/abc-123/edit` | `{ eventId: 'abc-123' }` |
54
+ | `/cal/:mm/:dd/:yyyy` | `/cal/05/13/2026` | `{ mm: '05', dd: '13', yyyy: '2026' }` |
55
+ | `/settings/:page?` | `/settings` or `/settings/account` | `{}` or `{ page: 'account' }` |
56
+
57
+ Append `?` to a param name to make it optional. Optional params must come at the end of the pattern.
121
58
 
122
59
  ## Navigating
123
60
 
124
- ### `router.navigate(route, params?, searchParams?)`
61
+ ```typescript
62
+ import { router } from 'svelte-navigator-lite';
125
63
 
126
- Navigate to a named route. Path params fill dynamic segments; pass search params separately as the third argument.
64
+ // Static route
65
+ router.navigate('login');
127
66
 
128
- ```ts
67
+ // With path params
129
68
  router.navigate('event', { eventId: '123' });
130
- // → /event/123
131
69
 
132
- router.navigate('password-reset', undefined, { token: 'abc123' });
133
- // /password-reset?token=abc123
134
-
135
- router.navigate('event', { eventId: '123' }, { tab: 'details' });
136
- // → /event/123?tab=details
70
+ // With path params + search params
71
+ router.navigate('edit', { eventId: '123' }, { from: 'calendar' });
137
72
  ```
138
73
 
139
- Throws if a required param is missing.
74
+ `navigate` returns a `Promise<void>`. Guards are evaluated before navigation — if a guard fires, the router redirects instead and original params are not forwarded.
140
75
 
141
- ### `goto(path)`
76
+ ## Reading state
142
77
 
143
- Lower-level navigation to a raw path. Accepts an optional `{ replaceState: true }` option to replace instead of push.
78
+ ```typescript
79
+ import { router } from 'svelte-navigator-lite';
144
80
 
145
- ```ts
146
- import { goto } from 'svelte-navigator-lite';
81
+ router.route // current route name: string
82
+ router.params // path params: Record<string, string>
83
+ router.searchParams // query params: Record<string, string>
84
+ router.notFound // true if the URL matched no route and the fallback was used
147
85
 
148
- goto('/login');
149
- goto('/login', { replaceState: true });
86
+ router.is('cal') // true if current route === 'cal'
87
+ router.matches(['cal', 'event']) // true if current route is in the list
150
88
  ```
151
89
 
152
- ---
90
+ All properties are reactive — use them in Svelte templates or `$effect` blocks and they update automatically on navigation.
153
91
 
154
- ## Route Guards
92
+ ## Guards
155
93
 
156
- Guards run before navigation and redirect if their condition is met. `fn` returning `true` triggers the redirect.
94
+ Guards are defined once in `createRouter` and referenced by name in route definitions.
157
95
 
158
- ```ts
159
- import type { RouteGuard } from 'svelte-navigator-lite';
160
-
161
- const guards = {
162
- authenticated: {
163
- fn: () => !auth.isValid(), // redirect if NOT authenticated
164
- redirectTo: 'login',
165
- } satisfies RouteGuard,
166
- unauthenticated: {
167
- fn: () => auth.isValid(), // redirect if already authenticated
168
- redirectTo: 'dashboard',
169
- } satisfies RouteGuard,
170
- };
171
-
172
- const routes: RouteList = {
173
- 'login': {
174
- rootPath: 'login',
175
- segments: [],
176
- routeGuards: [guards.unauthenticated],
177
- },
178
- 'dashboard': {
179
- rootPath: 'dashboard',
180
- segments: [],
181
- routeGuards: [guards.authenticated],
96
+ ```typescript
97
+ createRouter({
98
+ routes: [
99
+ { name: 'cal', pattern: '/cal', guards: ['auth'] },
100
+ { name: 'login', pattern: '/login', guards: ['unauth'] },
101
+ { name: 'verify-email', pattern: '/verify-email', guards: ['unauth'] },
102
+ { name: 'login-check', pattern: '/login', guards: ['unauth', 'emailCheck'] },
103
+ ],
104
+ guards: {
105
+ auth: {
106
+ condition: () => !auth.isValid(),
107
+ redirectTo: 'login',
108
+ },
109
+ unauth: {
110
+ condition: () => auth.isValid(),
111
+ redirectTo: 'cal',
112
+ },
113
+ emailCheck: {
114
+ condition: () => auth.containsCreds() && !auth.user?.verified,
115
+ redirectTo: 'verify-email',
116
+ },
182
117
  },
183
- };
118
+ fallback: 'cal',
119
+ });
184
120
  ```
185
121
 
186
- Guards run in order and stop at the first redirect.
187
-
188
- ---
189
-
190
- ## API Reference
191
-
192
- ### `createRouter(routes, defaultRoute)`
193
-
194
- Registers all routes and sets the fallback route. Parses the current URL immediately. Must be called once before using `router`.
195
-
196
- ### `router.route`
122
+ **`condition`** called before entering the route. Return `true` to trigger the redirect.
197
123
 
198
- The label of the currently matched route. Falls back to `defaultRoute` if no route matches.
124
+ **`redirectTo`** route name to navigate to instead.
199
125
 
200
- ### `router.params`
126
+ Multiple guards on a route are checked in order; the first one that fires wins. Guard redirects are also checked for guards (recursively), with cycle detection to prevent infinite loops.
201
127
 
202
- An object containing the captured path param values for the current route.
128
+ ## `page` store
203
129
 
204
- ### `router.searchParams`
130
+ A Svelte readable store that emits `{ url: URL }` on every navigation. Compatible with SvelteKit's `$app/stores` page store shape.
205
131
 
206
- An object containing the search params present in the current URL. Empty object when none are present.
207
-
208
- ### `router.notFound`
209
-
210
- `true` when the current URL did not match any defined route and the router fell back to `defaultRoute`. Use this to render a 404 state without needing a dedicated catch-all route.
132
+ ```typescript
133
+ import { page } from 'svelte-navigator-lite';
211
134
 
212
- ```svelte
213
- {#if router.notFound}
214
- <NotFound />
215
- {:else if router.is('dashboard')}
216
- <Dashboard />
217
- {/if}
135
+ page.subscribe(({ url }) => {
136
+ console.log(url.pathname);
137
+ });
218
138
  ```
219
139
 
220
- ### `router.navigate(route, params?, searchParams?)`
221
-
222
- Navigate to a named route, applying guards and building the URL from the route definition.
223
-
224
- ### `router.is(route)`
225
-
226
- Returns `true` if `router.route === route`. Useful for active link styling.
227
-
228
- ```ts
229
- class:active={router.is('dashboard')}
230
- ```
140
+ ## `goto`
231
141
 
232
- ### `router.matches(routes)`
142
+ Low-level path navigation. Prefer `router.navigate` for named routes.
233
143
 
234
- Returns `true` if `router.route` is any of the provided route names.
144
+ ```typescript
145
+ import { goto } from 'svelte-navigator-lite';
235
146
 
236
- ```ts
237
- class:active={router.matches(['dashboard', 'settings'])}
147
+ await goto('/some/path');
148
+ await goto('/some/path', { replaceState: true }); // replace instead of push
238
149
  ```
239
150
 
240
- ### `router.registerRoute(name, route)`
241
-
242
- Register a new route.
243
- ```ts
244
- registerRoute('settings', {
245
- rootPath: 'settings',
246
- segments: [],
247
- routeGuards: [guards.authenticated],
248
- })
249
-
250
- ### `page`
151
+ ## Migrating from v1
251
152
 
252
- A readable Svelte store that emits `{ url: URL }` and updates on every navigation. Useful when you need the raw URL.
153
+ The `rootPath` + `segments` route definition is replaced by a single `pattern` string, and `routeGuards` inline on each route are replaced by named guards defined once.
253
154
 
254
- ```ts
255
- import { page } from 'svelte-navigator-lite';
155
+ ```typescript
156
+ // v1
157
+ 'edit': {
158
+ rootPath: 'event',
159
+ segments: [{ name: 'eventId' }, { enforceVal: 'edit' }],
160
+ routeGuards: [{ fn: () => !auth.isValid(), redirectTo: 'login' }],
161
+ }
256
162
 
257
- $page.url.pathname;
163
+ // v2
164
+ { name: 'edit', pattern: '/event/:eventId/edit', guards: ['auth'] }
165
+ // with guard defined once in createRouter: auth: { condition: () => !auth.isValid(), redirectTo: 'login' }
258
166
  ```
259
-
260
- ---
261
-
262
- ## Matching Rules
263
-
264
- - Routes are matched in the order they are defined — first match wins.
265
- - `rootPath` is always required and must match the first URL segment exactly.
266
- - Segment count must be between `required segments + 1` and `total segments + 1` (the `+1` accounts for `rootPath`).
267
- - A route with no segments only matches its `rootPath` with nothing after it (e.g. `/login` not `/login/extra`).
268
- - Unmatched URLs fall back to the `defaultRoute`.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { createRouter, router, page, goto } from './router.svelte';
2
- export type { Route, RouteList, Router, RouteGuard } from './router.svelte';
1
+ export { createRouter, router, page, goto, _createRouter } from './router.svelte.js';
2
+ export type { RouteDefinition, Guard, RouterConfig } from './types.js';
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- // svelte-navigator-lite
2
- export { createRouter, router, page, goto } from './router.svelte';
1
+ export { createRouter, router, page, goto, _createRouter } from './router.svelte.js';
@@ -0,0 +1,16 @@
1
+ import type { RouteDefinition } from './types.js';
2
+ type CompiledRoute = {
3
+ name: string;
4
+ pattern: string;
5
+ regex: RegExp;
6
+ paramNames: string[];
7
+ guards: string[];
8
+ };
9
+ export type RouteMatch = {
10
+ name: string;
11
+ params: Record<string, string>;
12
+ };
13
+ export declare function compileRoutes(routes: RouteDefinition[]): CompiledRoute[];
14
+ export declare function matchPath(compiled: CompiledRoute[], pathname: string): RouteMatch | null;
15
+ export declare function buildPath(pattern: string, params?: Record<string, string>): string;
16
+ export {};
package/dist/match.js ADDED
@@ -0,0 +1,54 @@
1
+ export function compileRoutes(routes) {
2
+ return routes.map(route => {
3
+ const paramNames = [];
4
+ const regexStr = route.pattern
5
+ // Escape regex special chars (except : and /)
6
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
7
+ // Optional params /:name? — make the whole slash+segment optional together
8
+ .replace(/\/:([a-zA-Z_][a-zA-Z0-9_]*)\?/g, (_, name) => {
9
+ paramNames.push(name);
10
+ return '(?:/([^/]*))?';
11
+ })
12
+ // Required params :name
13
+ .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {
14
+ paramNames.push(name);
15
+ return '([^/]+)';
16
+ });
17
+ return {
18
+ name: route.name,
19
+ pattern: route.pattern,
20
+ regex: new RegExp(`^${regexStr}/?$`),
21
+ paramNames,
22
+ guards: route.guards ?? [],
23
+ };
24
+ });
25
+ }
26
+ export function matchPath(compiled, pathname) {
27
+ for (const route of compiled) {
28
+ const m = pathname.match(route.regex);
29
+ if (!m)
30
+ continue;
31
+ const params = {};
32
+ route.paramNames.forEach((name, i) => {
33
+ const val = m[i + 1];
34
+ if (val)
35
+ params[name] = decodeURIComponent(val);
36
+ });
37
+ return { name: route.name, params };
38
+ }
39
+ return null;
40
+ }
41
+ // Build a URL path from a pattern and params.
42
+ // Optional params omitted from params are dropped cleanly.
43
+ export function buildPath(pattern, params = {}) {
44
+ const path = pattern
45
+ .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)\?/g, (_, name) => name in params ? encodeURIComponent(params[name]) : '')
46
+ .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {
47
+ if (!(name in params))
48
+ throw new Error(`[router] missing required param "${name}" for pattern "${pattern}"`);
49
+ return encodeURIComponent(params[name]);
50
+ })
51
+ .replace(/\/+/g, '/') // collapse double slashes left by dropped optional params
52
+ .replace(/\/$/, ''); // strip trailing slash
53
+ return path || '/';
54
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,120 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { compileRoutes, matchPath, buildPath } from './match';
3
+ // ─── matchPath ────────────────────────────────────────────────────────────────
4
+ describe('matchPath — static routes', () => {
5
+ it('matches an exact path', () => {
6
+ const compiled = compileRoutes([{ name: 'login', pattern: '/login' }]);
7
+ expect(matchPath(compiled, '/login')).toEqual({ name: 'login', params: {} });
8
+ });
9
+ it('does not match a different path', () => {
10
+ const compiled = compileRoutes([{ name: 'login', pattern: '/login' }]);
11
+ expect(matchPath(compiled, '/signup')).toBeNull();
12
+ });
13
+ it('returns null when no routes match', () => {
14
+ const compiled = compileRoutes([{ name: 'login', pattern: '/login' }]);
15
+ expect(matchPath(compiled, '/unknown/path')).toBeNull();
16
+ });
17
+ it('returns the first matching route', () => {
18
+ const compiled = compileRoutes([
19
+ { name: 'first', pattern: '/cal' },
20
+ { name: 'second', pattern: '/cal' },
21
+ ]);
22
+ expect(matchPath(compiled, '/cal')?.name).toBe('first');
23
+ });
24
+ });
25
+ describe('matchPath — required params', () => {
26
+ it('captures a single param', () => {
27
+ const compiled = compileRoutes([{ name: 'event', pattern: '/event/:eventId' }]);
28
+ expect(matchPath(compiled, '/event/abc-123')).toEqual({
29
+ name: 'event',
30
+ params: { eventId: 'abc-123' },
31
+ });
32
+ });
33
+ it('does not match when a required param is absent', () => {
34
+ const compiled = compileRoutes([{ name: 'event', pattern: '/event/:eventId' }]);
35
+ expect(matchPath(compiled, '/event')).toBeNull();
36
+ });
37
+ it('captures multiple params', () => {
38
+ const compiled = compileRoutes([{ name: 'cal-date', pattern: '/cal/:mm/:dd/:yyyy' }]);
39
+ expect(matchPath(compiled, '/cal/05/13/2026')).toEqual({
40
+ name: 'cal-date',
41
+ params: { mm: '05', dd: '13', yyyy: '2026' },
42
+ });
43
+ });
44
+ it('captures params mixed with literal segments', () => {
45
+ const compiled = compileRoutes([{ name: 'edit', pattern: '/event/:eventId/edit' }]);
46
+ expect(matchPath(compiled, '/event/99/edit')).toEqual({
47
+ name: 'edit',
48
+ params: { eventId: '99' },
49
+ });
50
+ });
51
+ it('does not match when a literal segment differs', () => {
52
+ const compiled = compileRoutes([{ name: 'edit', pattern: '/event/:eventId/edit' }]);
53
+ expect(matchPath(compiled, '/event/99/delete')).toBeNull();
54
+ });
55
+ it('does not match when there are extra segments', () => {
56
+ const compiled = compileRoutes([{ name: 'event', pattern: '/event/:eventId' }]);
57
+ expect(matchPath(compiled, '/event/99/unexpected')).toBeNull();
58
+ });
59
+ it('differentiates routes with the same prefix by segment count', () => {
60
+ const compiled = compileRoutes([
61
+ { name: 'event', pattern: '/event/:eventId' },
62
+ { name: 'edit', pattern: '/event/:eventId/edit' },
63
+ ]);
64
+ expect(matchPath(compiled, '/event/99')?.name).toBe('event');
65
+ expect(matchPath(compiled, '/event/99/edit')?.name).toBe('edit');
66
+ });
67
+ it('URL-decodes param values', () => {
68
+ const compiled = compileRoutes([{ name: 'search', pattern: '/search/:query' }]);
69
+ expect(matchPath(compiled, '/search/hello%20world')?.params.query).toBe('hello world');
70
+ });
71
+ });
72
+ describe('matchPath — optional params', () => {
73
+ const compiled = compileRoutes([{ name: 'settings', pattern: '/settings/:page?' }]);
74
+ it('matches when the optional param is present', () => {
75
+ expect(matchPath(compiled, '/settings/account')).toEqual({
76
+ name: 'settings',
77
+ params: { page: 'account' },
78
+ });
79
+ });
80
+ it('matches when the optional param is absent', () => {
81
+ const result = matchPath(compiled, '/settings');
82
+ expect(result?.name).toBe('settings');
83
+ expect(result?.params).not.toHaveProperty('page');
84
+ });
85
+ });
86
+ // ─── buildPath ────────────────────────────────────────────────────────────────
87
+ describe('buildPath — static patterns', () => {
88
+ it('returns the pattern as-is', () => {
89
+ expect(buildPath('/login')).toBe('/login');
90
+ });
91
+ it('returns / for an empty pattern', () => {
92
+ expect(buildPath('')).toBe('/');
93
+ });
94
+ });
95
+ describe('buildPath — required params', () => {
96
+ it('substitutes a single param', () => {
97
+ expect(buildPath('/event/:eventId', { eventId: '42' })).toBe('/event/42');
98
+ });
99
+ it('substitutes multiple params', () => {
100
+ expect(buildPath('/cal/:mm/:dd/:yyyy', { mm: '05', dd: '13', yyyy: '2026' }))
101
+ .toBe('/cal/05/13/2026');
102
+ });
103
+ it('substitutes params among literal segments', () => {
104
+ expect(buildPath('/event/:eventId/edit', { eventId: '99' })).toBe('/event/99/edit');
105
+ });
106
+ it('URL-encodes param values', () => {
107
+ expect(buildPath('/search/:query', { query: 'hello world' })).toBe('/search/hello%20world');
108
+ });
109
+ it('throws when a required param is missing', () => {
110
+ expect(() => buildPath('/event/:eventId', {})).toThrow('missing required param "eventId"');
111
+ });
112
+ });
113
+ describe('buildPath — optional params', () => {
114
+ it('inserts the value when the optional param is provided', () => {
115
+ expect(buildPath('/settings/:page?', { page: 'account' })).toBe('/settings/account');
116
+ });
117
+ it('drops the segment cleanly when the optional param is absent', () => {
118
+ expect(buildPath('/settings/:page?', {})).toBe('/settings');
119
+ });
120
+ });
@@ -1,35 +1,31 @@
1
+ import type { RouterConfig } from './types.js';
1
2
  export declare const page: import("svelte/store").Readable<{
2
3
  url: URL;
3
4
  }>;
4
5
  export declare function goto(path: string, { replaceState }?: {
5
6
  replaceState?: boolean | undefined;
6
7
  }): Promise<void>;
7
- export type Route = {
8
- rootPath: string;
9
- segments: ({
10
- name?: string;
11
- enforceVal?: string;
12
- optional?: boolean;
13
- })[];
14
- routeGuards?: RouteGuard[];
15
- };
16
- export type RouteGuard = {
17
- fn: () => boolean;
18
- redirectTo: string;
8
+ declare function _createRouter(): {
9
+ readonly route: string;
10
+ readonly params: Record<string, string>;
11
+ readonly searchParams: Record<string, string>;
12
+ readonly notFound: boolean;
13
+ is(route: string): boolean;
14
+ matches(routes: string[]): boolean;
15
+ parseUrl: (url: string) => void;
16
+ navigate(routeName: string, params?: Record<string, string>, searchParams?: Record<string, string>): Promise<void>;
17
+ init(config: RouterConfig): void;
19
18
  };
20
- export type RouteList = Record<string, Route>;
21
- export type Router = ReturnType<typeof _createRouter>;
22
- export declare function _createRouter(routeList?: RouteList): {
19
+ export { _createRouter };
20
+ export declare const router: {
23
21
  readonly route: string;
24
22
  readonly params: Record<string, string>;
25
23
  readonly searchParams: Record<string, string>;
26
24
  readonly notFound: boolean;
27
- rootRoute: string;
28
25
  is(route: string): boolean;
29
26
  matches(routes: string[]): boolean;
30
27
  parseUrl: (url: string) => void;
31
- navigate(route: string, params?: Record<string, string>, searchParams?: Record<string, string>): Promise<void>;
32
- registerRoute(name: string, route: Route): void;
28
+ navigate(routeName: string, params?: Record<string, string>, searchParams?: Record<string, string>): Promise<void>;
29
+ init(config: RouterConfig): void;
33
30
  };
34
- export declare let router: Router;
35
- export declare function createRouter(RouteList: RouteList, defaultRoute: string): void;
31
+ export declare function createRouter(config: RouterConfig): void;