@ktjs/router 0.32.4 → 0.33.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 +48 -269
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,292 +1,71 @@
|
|
|
1
|
-
#
|
|
1
|
+
# KT.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/kt.js)
|
|
4
|
+
[](https://www.npmjs.com/package/kt.js)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://baendlorel.github.io/kt.js/">
|
|
9
|
+
<img src="https://raw.githubusercontent.com/baendlorel/kt.js/refs/heads/main/assets/ktjs-0.0.1.svg" width="240px" alt="KT.js logo" />
|
|
10
|
+
</a>
|
|
11
|
+
</p>
|
|
6
12
|
|
|
7
|
-
>
|
|
13
|
+
<p align="center"><strong>Visit KT.js: <a href="https://baendlorel.github.io/kt.js/">https://baendlorel.github.io/kt.js/</a></strong></p>
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
> kt.js is still under development, so there might be some breaking changes. Note the Update Log below
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
## Recent Updates
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
1. `ref.value` remains the standard read API, and it can also replace the whole outer value with `ref.value = nextValue`.
|
|
20
|
+
2. `ref.draft` is the deep-mutation entry for nested objects, arrays, `Map` / `Set`, and custom mutable objects.
|
|
21
|
+
3. `ref.draft` itself is not assignable; mutate nested fields or call mutating methods on the returned object instead.
|
|
22
|
+
4. `addOnChange((newValue, oldValue) => ...)` keeps `oldValue` as the previous reference, not a deep snapshot.
|
|
14
23
|
|
|
15
|
-
|
|
24
|
+
## Community
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
- QQ Group: `1070434849`
|
|
27
|
+
- Telegram: https://t.me/kt_js
|
|
18
28
|
|
|
19
|
-
|
|
20
|
-
- **Path Matching**: Static and dynamic route matching with parameter extraction
|
|
21
|
-
- Dynamic segments: `/user/:id`
|
|
22
|
-
- Wildcard matching support
|
|
23
|
-
- Optimized matching algorithm with pre-flattened routes
|
|
24
|
-
- **Async Navigation Guards**: Control navigation flow with Promise-based guard system
|
|
25
|
-
- `beforeEach`: Global guard before every navigation
|
|
26
|
-
- `beforeEnter`: Per-route guard for specific routes
|
|
27
|
-
- `afterEach`: Global hook after successful navigation
|
|
28
|
-
- Guard-level control with bitwise operations for fine-grained execution
|
|
29
|
-
- All guards are async - return `Promise` or immediate values
|
|
30
|
-
- **Named Routes**: Navigate using route names instead of paths
|
|
31
|
-
- **Query Parameters**: Built-in query string parsing and handling
|
|
32
|
-
- **Route Context**: Access route information in handlers
|
|
33
|
-
- Current route path and name
|
|
34
|
-
- Dynamic parameters (`params`)
|
|
35
|
-
- Query string parameters (`query`)
|
|
36
|
-
- **Error Handling**: Comprehensive error handling with `onError` callback
|
|
37
|
-
- **Type-Safe**: Full TypeScript support with intelligent type inference
|
|
38
|
-
- **Zero Dependencies**: Fully self-contained implementation (does **not** require `@ktjs/core` for runtime, only for TypeScript types)
|
|
39
|
-
- **ES5 Compatible**: Works in IE9+ and all modern browsers
|
|
29
|
+
## Introduction
|
|
40
30
|
|
|
41
|
-
|
|
31
|
+
kt.js is a simple framework with a tiny runtime that renders real DOM directly (no virtual DOM), uses explicit reactivity variables and gives you manual control over refs, bindings, and redraw timing.
|
|
42
32
|
|
|
43
|
-
|
|
33
|
+
KT.js focuses on one principle: keep direct control of the DOM and avoid unnecessary repainting.
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
pnpm create kt.js my-app
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Add router to an existing project
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pnpm add @ktjs/router @ktjs/core
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Basic Usage
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { createRouter } from '@ktjs/router';
|
|
59
|
-
import { div, h1 } from '@ktjs/core';
|
|
60
|
-
|
|
61
|
-
const router = createRouter({
|
|
62
|
-
routes: [
|
|
63
|
-
{
|
|
64
|
-
path: '/',
|
|
65
|
-
name: 'home',
|
|
66
|
-
beforeEnter: (to) => {
|
|
67
|
-
// Render your home page
|
|
68
|
-
const app = document.getElementById('app')!;
|
|
69
|
-
app.innerHTML = '';
|
|
70
|
-
app.appendChild(div({}, [h1({}, 'Home Page')]));
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
path: '/about',
|
|
75
|
-
name: 'about',
|
|
76
|
-
beforeEnter: (to) => {
|
|
77
|
-
// Render your about page
|
|
78
|
-
const app = document.getElementById('app')!;
|
|
79
|
-
app.innerHTML = '';
|
|
80
|
-
app.appendChild(div({}, [h1({}, 'About Page')]));
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
path: '/user/:id',
|
|
85
|
-
name: 'user',
|
|
86
|
-
beforeEnter: (to) => {
|
|
87
|
-
// Render user profile with params
|
|
88
|
-
const app = document.getElementById('app')!;
|
|
89
|
-
app.innerHTML = '';
|
|
90
|
-
app.appendChild(
|
|
91
|
-
div({}, [
|
|
92
|
-
h1({}, `User Profile`),
|
|
93
|
-
div({}, `User ID: ${to.params.id}`),
|
|
94
|
-
div({}, `Query: ${JSON.stringify(to.query)}`),
|
|
95
|
-
]),
|
|
96
|
-
);
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Navigate programmatically
|
|
103
|
-
router.push('/user/123?tab=profile');
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Advanced Usage
|
|
107
|
-
|
|
108
|
-
### Navigation Guards
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
import { createRouter, GuardLevel } from '@ktjs/router';
|
|
112
|
-
|
|
113
|
-
const router = createRouter({
|
|
114
|
-
routes: [
|
|
115
|
-
{
|
|
116
|
-
path: '/admin',
|
|
117
|
-
name: 'admin',
|
|
118
|
-
beforeEnter: (to) => {
|
|
119
|
-
// Route-specific guard and rendering
|
|
120
|
-
if (!isAuthenticated()) {
|
|
121
|
-
console.log('Access denied');
|
|
122
|
-
return false; // Block navigation
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Render admin panel
|
|
126
|
-
const app = document.getElementById('app')!;
|
|
127
|
-
app.innerHTML = '';
|
|
128
|
-
app.appendChild(div({}, 'Admin Panel'));
|
|
129
|
-
return true;
|
|
130
|
-
},
|
|
131
|
-
after: (to) => {
|
|
132
|
-
// Called after this route is successfully entered
|
|
133
|
-
console.log('Admin page rendered');
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
],
|
|
137
|
-
beforeEach: async (to, from) => {
|
|
138
|
-
// Global guard - can be async
|
|
139
|
-
console.log(`Navigating from ${from?.path} to ${to.path}`);
|
|
140
|
-
|
|
141
|
-
// You can return false to block navigation
|
|
142
|
-
if (to.path.includes('forbidden')) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Or return true to allow
|
|
147
|
-
return true;
|
|
148
|
-
},
|
|
149
|
-
afterEach: (to, from) => {
|
|
150
|
-
// Called after successful navigation
|
|
151
|
-
document.title = to.name || to.path;
|
|
152
|
-
|
|
153
|
-
// Track page views
|
|
154
|
-
analytics.track('pageview', { path: to.path });
|
|
155
|
-
},
|
|
156
|
-
onError: (error) => {
|
|
157
|
-
console.error('Navigation error:', error);
|
|
158
|
-
},
|
|
159
|
-
onNotFound: (path) => {
|
|
160
|
-
console.log('404:', path);
|
|
161
|
-
// You can render a 404 page here
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Named Route Navigation
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
// Navigate by route name with parameters
|
|
170
|
-
router.push({
|
|
171
|
-
name: 'user',
|
|
172
|
-
params: { id: '456' },
|
|
173
|
-
query: { tab: 'settings' },
|
|
174
|
-
});
|
|
35
|
+
## Reactive Contract
|
|
175
36
|
|
|
176
|
-
|
|
177
|
-
|
|
37
|
+
```ts
|
|
38
|
+
const user = ref({ profile: { name: 'John' }, tags: ['new'] });
|
|
178
39
|
|
|
179
|
-
|
|
40
|
+
console.log(user.value.profile.name); // read
|
|
180
41
|
|
|
181
|
-
|
|
182
|
-
|
|
42
|
+
user.value = {
|
|
43
|
+
...user.value,
|
|
44
|
+
profile: { ...user.value.profile, name: 'Jane' },
|
|
45
|
+
tags: [...user.value.tags],
|
|
46
|
+
}; // replace the whole outer value
|
|
183
47
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
console.log('Name:', current.name); // e.g., 'user'
|
|
187
|
-
console.log('Params:', current.params); // e.g., { id: '123' }
|
|
188
|
-
console.log('Query:', current.query); // e.g., { tab: 'profile' }
|
|
189
|
-
}
|
|
48
|
+
user.draft.profile.name = 'Jane'; // deep write
|
|
49
|
+
user.draft.tags.push('active'); // array / map / set / custom-object style mutation
|
|
190
50
|
```
|
|
191
51
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
### `createRouter(config)`
|
|
195
|
-
|
|
196
|
-
Creates and returns a router instance.
|
|
197
|
-
|
|
198
|
-
**Config Options:**
|
|
199
|
-
|
|
200
|
-
- `routes` (Array): Array of route configurations
|
|
201
|
-
- `path` (string): Route path with optional dynamic segments (`:param`)
|
|
202
|
-
- `name` (string, optional): Route name for named navigation
|
|
203
|
-
- `meta` (object, optional): Metadata attached to the route
|
|
204
|
-
- `component` (function): Function that returns HTMLElement or Promise<HTMLElement>
|
|
205
|
-
- `beforeEnter` (function, optional): Route-specific guard, receives `(to: RouteContext) => boolean | string | NavOptions | void | Promise<...>`
|
|
206
|
-
- `after` (function, optional): Route-specific hook after navigation
|
|
207
|
-
- `children` (array, optional): Nested child routes
|
|
208
|
-
- `beforeEach` (function, optional): Global guard before every navigation, receives `(to: RouteContext, from: RouteContext | null) => boolean | string | NavOptions | void | Promise<...>`
|
|
209
|
-
- `afterEach` (function, optional): Global hook after successful navigation, receives `(to: RouteContext, from: RouteContext | null) => void | Promise<void>`
|
|
210
|
-
- `onNotFound` (function, optional): Handler for 404 errors, receives `(path: string) => void`
|
|
211
|
-
- `onError` (function, optional): Error handler for navigation failures, receives `(error: Error) => void`
|
|
212
|
-
- `prefix` (string, optional): URL prefix for all routes (default: `''`)
|
|
213
|
-
|
|
214
|
-
**Router Instance Properties:**
|
|
52
|
+
Rules:
|
|
215
53
|
|
|
216
|
-
-
|
|
217
|
-
-
|
|
218
|
-
- `
|
|
54
|
+
- Read with `.value`.
|
|
55
|
+
- Replace the whole outer value with `.value = nextValue`.
|
|
56
|
+
- Use `.draft` for deep mutations on nested objects, arrays, `Map` / `Set`, or other mutable instances.
|
|
57
|
+
- Do not assign to `.draft` itself; mutate inside it.
|
|
58
|
+
- `computed` stays read-only and is consumed through `.value`.
|
|
59
|
+
- `oldValue` in change listeners is the previous reference only, not a deep-cloned snapshot.
|
|
60
|
+
- Correctness is expected to come from the transformer and TypeScript checks; runtime hot paths stay minimal on purpose.
|
|
219
61
|
|
|
220
|
-
|
|
62
|
+
This is an explicit contract, closer to a Rust-style model than permissive runtime magic: unclear code should fail early.
|
|
221
63
|
|
|
222
|
-
|
|
223
|
-
- `replace(location)`: Replace current history entry
|
|
224
|
-
- `back()`: Navigate back in history
|
|
225
|
-
- `listen()`: Start listening to hash changes (auto-called on router creation since v0.14.7)
|
|
226
|
-
- `init(routes)`: Initialize router with route configurations
|
|
64
|
+
## Quick Start
|
|
227
65
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
- `string`: Redirect to the given path
|
|
234
|
-
- `NavOptions` object: Redirect with options `{ name, params, query }`
|
|
235
|
-
- `void` or `undefined`: Continue navigation
|
|
236
|
-
|
|
237
|
-
```typescript
|
|
238
|
-
// Global guard
|
|
239
|
-
beforeEach: (async (to, from) => {
|
|
240
|
-
// Check authentication
|
|
241
|
-
const isAuthenticated = await checkAuth();
|
|
242
|
-
if (!isAuthenticated && to.path !== '/login') {
|
|
243
|
-
return '/login'; // Redirect to login
|
|
244
|
-
}
|
|
245
|
-
// Return nothing to continue
|
|
246
|
-
},
|
|
247
|
-
// Route guard
|
|
248
|
-
{
|
|
249
|
-
path: '/admin',
|
|
250
|
-
component: () => AdminPage(),
|
|
251
|
-
beforeEnter: async (to) => {
|
|
252
|
-
const hasPermission = await checkAdminPermission();
|
|
253
|
-
if (!hasPermission) {
|
|
254
|
-
return false; // Cancel navigation
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
});
|
|
66
|
+
```bash
|
|
67
|
+
pnpm create kt.js my-app
|
|
68
|
+
cd my-app
|
|
69
|
+
pnpm install
|
|
70
|
+
pnpm dev
|
|
258
71
|
```
|
|
259
|
-
|
|
260
|
-
### Route Context
|
|
261
|
-
|
|
262
|
-
Guards and hooks receive a `RouteContext` object with:
|
|
263
|
-
|
|
264
|
-
- `params`: Object containing dynamic route parameters
|
|
265
|
-
- `query`: Object containing query string parameters
|
|
266
|
-
- `path`: Current route path
|
|
267
|
-
- `name`: Current route name (if defined)
|
|
268
|
-
|
|
269
|
-
## Performance Optimizations
|
|
270
|
-
|
|
271
|
-
The router includes several performance optimizations:
|
|
272
|
-
|
|
273
|
-
- **Hash-Mode Only**: Simplified implementation focusing on hash-based routing (v0.14.7+)
|
|
274
|
-
- **Pre-flattened Routes**: Nested routes are flattened during initialization for faster lookups
|
|
275
|
-
- **Efficient Matching**: Optimized regex-based path matching with caching
|
|
276
|
-
- **Async Guards**: All guards use Promise-based architecture for consistent async handling
|
|
277
|
-
- **Guard Level Control**: Fine-grained control over guard execution using bitwise operations
|
|
278
|
-
- **Automatic Initialization**: Router auto-initializes on creation, no manual setup needed
|
|
279
|
-
|
|
280
|
-
## Browser Compatibility
|
|
281
|
-
|
|
282
|
-
Works in all modern browsers that support:
|
|
283
|
-
|
|
284
|
-
- Hash-based navigation
|
|
285
|
-
- ES5 (with transpilation)
|
|
286
|
-
- Promise API (required for async guards)
|
|
287
|
-
|
|
288
|
-
For older browsers without Promise support, include a Promise polyfill.
|
|
289
|
-
|
|
290
|
-
## License
|
|
291
|
-
|
|
292
|
-
MIT
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/core/matcher.ts","../src/core/kt-router.ts","../src/core/index.ts"],"sourcesContent":["import type { RouteConfig, RouteMatch } from '../types/router.js';\nimport { extractParams, normalizePath } from '@ktjs/shared';\n\n/**\n * Route matcher for finding matching routes and extracting params\n */\nexport const createMatcher = (routes: RouteConfig[]) => {\n const nameMap: Record<string, RouteConfig> = {};\n\n for (let i = 0; i < routes.length; i++) {\n const route = routes[i];\n if (route.name !== undefined) {\n if (route.name in nameMap) {\n $throw(`Duplicate route name detected: '${route.name}'`);\n }\n nameMap[route.name] = route;\n }\n }\n\n /**\n * Find route by name\n */\n const findByName = (name: string): RouteConfig | null => {\n return nameMap[name] ?? null;\n };\n\n /**\n * Match path against all routes\n */\n const match = (path: string): RouteMatch | null => {\n const normalizedPath = normalizePath(path);\n\n // Try exact match first\n for (const route of routes) {\n if (route.path === normalizedPath) {\n return {\n route,\n params: {},\n result: getMatchedChain(route),\n };\n }\n }\n\n // Try dynamic routes\n for (const route of routes) {\n if (route.path.includes(':')) {\n const params = extractParams(route.path, normalizedPath);\n if (params) {\n return {\n route,\n params,\n result: getMatchedChain(route),\n };\n }\n }\n }\n\n return null;\n };\n\n /**\n * Get chain of matched routes (for nested routes)\n * - parent roots ahead\n */\n const getMatchedChain = (route: RouteConfig): RouteConfig[] => {\n const matched: RouteConfig[] = [route];\n const path = route.path;\n\n // Find parent routes by path prefix matching\n for (let i = 0; i < routes.length; i++) {\n const r = routes[i];\n if (r !== route && path.startsWith(r.path) && path !== r.path) {\n matched.push(r);\n }\n }\n\n return matched.reverse();\n };\n\n return {\n findByName,\n match,\n };\n};\n","import { JSX } from '@ktjs/core/jsx-runtime';\nimport type { Router } from '../types/router.js';\n\n/**\n * Create a router view container that automatically renders route components\n */\nexport function KTRouter({ router }: { router: Router }): JSX.Element {\n const view = document.createElement('kt-router-view');\n router.setRouterView(view);\n return view as JSX.Element;\n}\n","import { $emptyFn, buildQuery, normalizePath, parseQuery, emplaceParams } from '@ktjs/shared';\n\nimport type { Router, RouterConfig, RouteContext, NavOptions, RawRouteConfig, RouteConfig } from '../types/router.js';\nimport { GuardLevel } from './consts.js';\nimport { createMatcher } from './matcher.js';\n\n/**\n * Create a new router instance\n */\nexport const createRouter = ({\n beforeEach = $emptyFn,\n afterEach = $emptyFn,\n onNotFound = $emptyFn,\n onError = $emptyFn,\n prefix = '',\n routes: rawRoutes,\n}: RouterConfig): Router => {\n // # private values\n const routes: RouteConfig[] = [];\n const history: RouteContext[] = [];\n let routerView: HTMLElement | null = null;\n let current: RouteContext | null = null;\n\n // # methods\n const normalize = (rawRoutes: RawRouteConfig[], parentPath: string): RouteConfig[] =>\n rawRoutes.map((route) => {\n const path = normalizePath(parentPath, route.path);\n const normalized = {\n path: prefix + path,\n name: route.name ?? '',\n meta: route.meta ?? {},\n beforeEnter: route.beforeEnter ?? $emptyFn,\n after: route.after ?? $emptyFn,\n children: route.children ? normalize(route.children, path) : [],\n component: route.component,\n };\n\n // directly push the normalized route to the list\n // avoid flatten them again\n routes.push(normalized);\n return normalized;\n });\n\n const guard = async (\n to: RouteContext,\n from: RouteContext | null,\n guardLevel: GuardLevel,\n ): Promise<{ continue: boolean; redirectTo?: NavOptions }> => {\n try {\n if (guardLevel === GuardLevel.None) {\n return { continue: true };\n }\n\n if (guardLevel & GuardLevel.Global) {\n const result = await beforeEach(to, from);\n if (result === false) {\n return { continue: false };\n }\n if (typeof result === 'string') {\n return { continue: false, redirectTo: { path: result } };\n }\n if (result && typeof result === 'object') {\n return { continue: false, redirectTo: result };\n }\n }\n\n if (guardLevel & GuardLevel.Route) {\n const targetRoute = to.matched[to.matched.length - 1];\n const result = await targetRoute.beforeEnter(to);\n if (result === false) {\n return { continue: false };\n }\n if (typeof result === 'string') {\n return { continue: false, redirectTo: { path: result } };\n }\n if (result && typeof result === 'object') {\n return { continue: false, redirectTo: result };\n }\n }\n\n return { continue: true };\n } catch (error) {\n onError(error as Error);\n return { continue: false };\n }\n };\n\n const navigatePrepare = (options: NavOptions) => {\n // Resolve target route\n let targetPath: string;\n let targetRoute;\n\n if (options.name) {\n targetRoute = findByName(options.name);\n if (!targetRoute) {\n $throw(`Route not found: ${options.name}`);\n }\n targetPath = targetRoute.path;\n } else if (options.path) {\n targetPath = normalizePath(options.path);\n targetRoute = match(targetPath)?.route;\n } else {\n $throw(`Either path or name must be provided`);\n }\n\n // Substitute params\n if (options.params) {\n targetPath = emplaceParams(targetPath, options.params);\n }\n\n // Match final path\n const matched = match(targetPath);\n if (!matched) {\n onNotFound(targetPath);\n return null;\n }\n\n // Build route context\n const queryString = options.query ? buildQuery(options.query) : '';\n const fullPath = targetPath + queryString;\n\n const to: RouteContext = {\n path: targetPath,\n name: matched.route.name,\n params: { ...matched.params, ...(options.params ?? {}) },\n query: options.query ?? {},\n meta: matched.route.meta ?? {},\n matched: matched.result,\n };\n\n return {\n guardLevel: options.guardLevel ?? GuardLevel.Default,\n replace: options.replace ?? false,\n to,\n fullPath,\n };\n };\n\n const navigate = async (options: NavOptions, redirectCount = 0): Promise<boolean> => {\n try {\n // Prevent infinite redirect loop\n if (redirectCount > 10) {\n onError(new Error('Maximum redirect count exceeded'));\n return false;\n }\n\n const prep = navigatePrepare(options);\n if (!prep) {\n return false;\n }\n\n const { guardLevel, replace, to, fullPath } = prep;\n\n const guardResult = await guard(to, current, guardLevel);\n if (!guardResult.continue) {\n // Check if there's a redirect\n if (guardResult.redirectTo) {\n return await navigate(guardResult.redirectTo, redirectCount + 1);\n }\n return false;\n }\n\n // ---- Guards passed ----\n\n const hashUrl = '#' + fullPath;\n if (replace) {\n window.location.replace(hashUrl);\n } else {\n window.location.hash = fullPath;\n }\n\n current = to;\n if (replace) {\n if (history.length > 0) {\n history[history.length - 1] = to;\n } else {\n history.push(to);\n }\n } else {\n history.push(to);\n }\n\n // Render component if routerView exists\n if (routerView && to.matched.length > 0) {\n const route = to.matched[to.matched.length - 1];\n if (route.component) {\n const element = await route.component();\n routerView.innerHTML = '';\n routerView.appendChild(element);\n }\n }\n\n executeAfterHooks(to, history[history.length - 2] ?? null);\n return true;\n } catch (error) {\n onError(error as Error);\n return false;\n }\n };\n\n const executeAfterHooks = async (to: RouteContext, from: RouteContext | null): Promise<void> => {\n const targetRoute = to.matched[to.matched.length - 1];\n await targetRoute.after(to);\n await afterEach(to, from);\n };\n\n /**\n * Normalize navigation argument\n */\n const normalizeLocation = (loc: string | NavOptions): NavOptions => {\n if (typeof loc !== 'string') {\n return loc;\n }\n\n const [path, queryString] = loc.split('?');\n return {\n path,\n query: queryString ? parseQuery(queryString) : undefined,\n };\n };\n\n // # register events\n window.addEventListener('hashchange', () => {\n const hash = window.location.hash.slice(1);\n const [path] = hash.split('?');\n const normalizedPath = normalizePath(path);\n if (current && current.path === normalizedPath) {\n return;\n }\n // render route for new hash without adding extra history entry\n const matched = match(normalizedPath);\n if (!matched) {\n onNotFound(normalizedPath);\n return;\n }\n const queryString = window.location.hash.slice(1).split('?')[1];\n const to: RouteContext = {\n path: normalizedPath,\n name: matched.route.name,\n params: matched.params,\n query: queryString ? parseQuery(queryString) : {},\n meta: matched.route.meta ?? {},\n matched: matched.result,\n };\n\n // apply without modifying browser history\n current = to;\n history.push(to);\n\n if (routerView && to.matched.length > 0) {\n const route = to.matched[to.matched.length - 1];\n if (route.component) {\n const element = route.component();\n if (element instanceof Promise) {\n element.then((el) => {\n routerView!.innerHTML = '';\n routerView!.appendChild(el);\n });\n } else {\n routerView.innerHTML = '';\n routerView.appendChild(element);\n }\n }\n }\n\n executeAfterHooks(to, history[history.length - 2] ?? null);\n });\n\n // # initialize\n const instance: Router = {\n get current() {\n return current;\n },\n\n get history() {\n return history.concat();\n },\n\n setRouterView(view: HTMLElement) {\n routerView = view;\n },\n\n push(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate(options);\n },\n\n silentPush(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate({ ...options, guardLevel: GuardLevel.Route });\n },\n\n replace(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate({ ...options, replace: true });\n },\n\n back() {\n window.history.back();\n },\n\n forward() {\n window.history.forward();\n },\n };\n normalize(rawRoutes, '/');\n const { findByName, match } = createMatcher(routes);\n const currentHash = window.location.hash.slice(1);\n if (currentHash) {\n instance.push(currentHash);\n }\n\n return instance;\n};\n\nexport { GuardLevel };\nexport { KTRouter } from './kt-router.js';\n"],"names":[],"mappings":";;AAGA;;AAEG;AACI,MAAM,aAAa,GAAG,CAAC,MAAqB,KAAI;IACrD,MAAM,OAAO,GAAgC,EAAE;AAE/C,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;AACvB,QAAA,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;AAC5B,YAAA,IAAI,KAAK,CAAC,IAAI,IAAI,OAAO,EAAE;AACzB,gBAAA,MAAA,IAAA,KAAA,CAAA,CAAA,qDAAO,EAAmC,KAAK,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC;YAC1D;AACA,YAAA,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK;QAC7B;IACF;AAEA;;AAEG;AACH,IAAA,MAAM,UAAU,GAAG,CAAC,IAAY,KAAwB;AACtD,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI;AAC9B,IAAA,CAAC;AAED;;AAEG;AACH,IAAA,MAAM,KAAK,GAAG,CAAC,IAAY,KAAuB;AAChD,QAAA,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC;;AAG1C,QAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC1B,YAAA,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE;gBACjC,OAAO;oBACL,KAAK;AACL,oBAAA,MAAM,EAAE,EAAE;AACV,oBAAA,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC;iBAC/B;YACH;QACF;;AAGA,QAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;YAC1B,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAC5B,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,cAAc,CAAC;gBACxD,IAAI,MAAM,EAAE;oBACV,OAAO;wBACL,KAAK;wBACL,MAAM;AACN,wBAAA,MAAM,EAAE,eAAe,CAAC,KAAK,CAAC;qBAC/B;gBACH;YACF;QACF;AAEA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AAED;;;AAGG;AACH,IAAA,MAAM,eAAe,GAAG,CAAC,KAAkB,KAAmB;AAC5D,QAAA,MAAM,OAAO,GAAkB,CAAC,KAAK,CAAC;AACtC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI;;AAGvB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACtC,YAAA,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AACnB,YAAA,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE;AAC7D,gBAAA,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACjB;QACF;AAEA,QAAA,OAAO,OAAO,CAAC,OAAO,EAAE;AAC1B,IAAA,CAAC;IAED,OAAO;QACL,UAAU;QACV,KAAK;KACN;AACH,CAAC;;AChFD;;AAEG;AACG,SAAU,QAAQ,CAAC,EAAE,MAAM,EAAsB,EAAA;IACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,gBAAgB,CAAC;AACrD,IAAA,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;AAC1B,IAAA,OAAO,IAAmB;AAC5B;;ACJA;;AAEG;AACI,MAAM,YAAY,GAAG,CAAC,EAC3B,UAAU,GAAG,QAAQ,EACrB,SAAS,GAAG,QAAQ,EACpB,UAAU,GAAG,QAAQ,EACrB,OAAO,GAAG,QAAQ,EAClB,MAAM,GAAG,EAAE,EACX,MAAM,EAAE,SAAS,GACJ,KAAY;;IAEzB,MAAM,MAAM,GAAkB,EAAE;IAChC,MAAM,OAAO,GAAmB,EAAE;IAClC,IAAI,UAAU,GAAuB,IAAI;IACzC,IAAI,OAAO,GAAwB,IAAI;;AAGvC,IAAA,MAAM,SAAS,GAAG,CAAC,SAA2B,EAAE,UAAkB,KAChE,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;QACtB,MAAM,IAAI,GAAG,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC;AAClD,QAAA,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,MAAM,GAAG,IAAI;AACnB,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;AACtB,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;AACtB,YAAA,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,QAAQ;AAC1C,YAAA,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,QAAQ;AAC9B,YAAA,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;YAC/D,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B;;;AAID,QAAA,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;AACvB,QAAA,OAAO,UAAU;AACnB,IAAA,CAAC,CAAC;IAEJ,MAAM,KAAK,GAAG,OACZ,EAAgB,EAChB,IAAyB,EACzB,UAAsB,KACqC;AAC3D,QAAA,IAAI;YACF,IAAI,UAAU,KAAA,CAAA,wBAAsB;AAClC,gBAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC3B;YAEA,IAAI,UAAU,GAAA,CAAA,0BAAsB;gBAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC;AACzC,gBAAA,IAAI,MAAM,KAAK,KAAK,EAAE;AACpB,oBAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAC5B;AACA,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC1D;AACA,gBAAA,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;oBACxC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE;gBAChD;YACF;YAEA,IAAI,UAAU,GAAA,CAAA,yBAAqB;AACjC,gBAAA,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;gBACrD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;AAChD,gBAAA,IAAI,MAAM,KAAK,KAAK,EAAE;AACpB,oBAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAC5B;AACA,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;gBAC1D;AACA,gBAAA,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;oBACxC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE;gBAChD;YACF;AAEA,YAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC3B;QAAE,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAc,CAAC;AACvB,YAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC5B;AACF,IAAA,CAAC;AAED,IAAA,MAAM,eAAe,GAAG,CAAC,OAAmB,KAAI;;AAE9C,QAAA,IAAI,UAAkB;AACtB,QAAA,IAAI,WAAW;AAEf,QAAA,IAAI,OAAO,CAAC,IAAI,EAAE;AAChB,YAAA,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;YACtC,IAAI,CAAC,WAAW,EAAE;AAChB,gBAAA,MAAA,IAAA,KAAA,CAAA,CAAA,sCAAO,EAAoB,OAAO,CAAC,IAAI,CAAA,CAAE,CAAC;YAC5C;AACA,YAAA,UAAU,GAAG,WAAW,CAAC,IAAI;QAC/B;AAAO,aAAA,IAAI,OAAO,CAAC,IAAI,EAAE;AACvB,YAAA,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC;AACxC,YAAA,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK;QACxC;aAAO;YACL,0EAAO,CAAsC,CAAC;QAChD;;AAGA,QAAA,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,UAAU,GAAG,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC;QACxD;;AAGA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC;QACjC,IAAI,CAAC,OAAO,EAAE;YACZ,UAAU,CAAC,UAAU,CAAC;AACtB,YAAA,OAAO,IAAI;QACb;;AAGA,QAAA,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;AAClE,QAAA,MAAM,QAAQ,GAAG,UAAU,GAAG,WAAW;AAEzC,QAAA,MAAM,EAAE,GAAiB;AACvB,YAAA,IAAI,EAAE,UAAU;AAChB,YAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;AACxB,YAAA,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE;AACxD,YAAA,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;AAC1B,YAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE;YAC9B,OAAO,EAAE,OAAO,CAAC,MAAM;SACxB;QAED,OAAO;AACL,YAAA,UAAU,EAAE,OAAO,CAAC,UAAU,IAAA,EAAA;AAC9B,YAAA,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;YACjC,EAAE;YACF,QAAQ;SACT;AACH,IAAA,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,OAAmB,EAAE,aAAa,GAAG,CAAC,KAAsB;AAClF,QAAA,IAAI;;AAEF,YAAA,IAAI,aAAa,GAAG,EAAE,EAAE;AACtB,gBAAA,OAAO,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;AACrD,gBAAA,OAAO,KAAK;YACd;AAEA,YAAA,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC;YACrC,IAAI,CAAC,IAAI,EAAE;AACT,gBAAA,OAAO,KAAK;YACd;YAEA,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAI;YAElD,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC;AACxD,YAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;;AAEzB,gBAAA,IAAI,WAAW,CAAC,UAAU,EAAE;oBAC1B,OAAO,MAAM,QAAQ,CAAC,WAAW,CAAC,UAAU,EAAE,aAAa,GAAG,CAAC,CAAC;gBAClE;AACA,gBAAA,OAAO,KAAK;YACd;;AAIA,YAAA,MAAM,OAAO,GAAG,GAAG,GAAG,QAAQ;YAC9B,IAAI,OAAO,EAAE;AACX,gBAAA,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;YAClC;iBAAO;AACL,gBAAA,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,QAAQ;YACjC;YAEA,OAAO,GAAG,EAAE;YACZ,IAAI,OAAO,EAAE;AACX,gBAAA,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;oBACtB,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE;gBAClC;qBAAO;AACL,oBAAA,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB;YACF;iBAAO;AACL,gBAAA,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAClB;;YAGA,IAAI,UAAU,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;AACvC,gBAAA,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/C,gBAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACnB,oBAAA,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;AACvC,oBAAA,UAAU,CAAC,SAAS,GAAG,EAAE;AACzB,oBAAA,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC;gBACjC;YACF;AAEA,YAAA,iBAAiB,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;AAC1D,YAAA,OAAO,IAAI;QACb;QAAE,OAAO,KAAK,EAAE;YACd,OAAO,CAAC,KAAc,CAAC;AACvB,YAAA,OAAO,KAAK;QACd;AACF,IAAA,CAAC;IAED,MAAM,iBAAiB,GAAG,OAAO,EAAgB,EAAE,IAAyB,KAAmB;AAC7F,QAAA,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AACrD,QAAA,MAAM,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3B,QAAA,MAAM,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC;AAC3B,IAAA,CAAC;AAED;;AAEG;AACH,IAAA,MAAM,iBAAiB,GAAG,CAAC,GAAwB,KAAgB;AACjE,QAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC3B,YAAA,OAAO,GAAG;QACZ;AAEA,QAAA,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QAC1C,OAAO;YACL,IAAI;AACJ,YAAA,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS;SACzD;AACH,IAAA,CAAC;;AAGD,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAK;AACzC,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAC9B,QAAA,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC;QAC1C,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;YAC9C;QACF;;AAEA,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE;YACZ,UAAU,CAAC,cAAc,CAAC;YAC1B;QACF;QACA,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC/D,QAAA,MAAM,EAAE,GAAiB;AACvB,YAAA,IAAI,EAAE,cAAc;AACpB,YAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,YAAA,KAAK,EAAE,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,EAAE;AACjD,YAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE;YAC9B,OAAO,EAAE,OAAO,CAAC,MAAM;SACxB;;QAGD,OAAO,GAAG,EAAE;AACZ,QAAA,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAEhB,IAAI,UAAU,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;AACvC,YAAA,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/C,YAAA,IAAI,KAAK,CAAC,SAAS,EAAE;AACnB,gBAAA,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE;AACjC,gBAAA,IAAI,OAAO,YAAY,OAAO,EAAE;AAC9B,oBAAA,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAI;AAClB,wBAAA,UAAW,CAAC,SAAS,GAAG,EAAE;AAC1B,wBAAA,UAAW,CAAC,WAAW,CAAC,EAAE,CAAC;AAC7B,oBAAA,CAAC,CAAC;gBACJ;qBAAO;AACL,oBAAA,UAAU,CAAC,SAAS,GAAG,EAAE;AACzB,oBAAA,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC;gBACjC;YACF;QACF;AAEA,QAAA,iBAAiB,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5D,IAAA,CAAC,CAAC;;AAGF,IAAA,MAAM,QAAQ,GAAW;AACvB,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,OAAO,OAAO;QAChB,CAAC;AAED,QAAA,IAAI,OAAO,GAAA;AACT,YAAA,OAAO,OAAO,CAAC,MAAM,EAAE;QACzB,CAAC;AAED,QAAA,aAAa,CAAC,IAAiB,EAAA;YAC7B,UAAU,GAAG,IAAI;QACnB,CAAC;AAED,QAAA,IAAI,CAAC,QAA6B,EAAA;AAChC,YAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC;AAC3C,YAAA,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC1B,CAAC;AAED,QAAA,UAAU,CAAC,QAA6B,EAAA;AACtC,YAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC;YAC3C,OAAO,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,UAAU,EAAA,CAAA,yBAAoB,CAAC;QAC/D,CAAC;AAED,QAAA,OAAO,CAAC,QAA6B,EAAA;AACnC,YAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC;YAC3C,OAAO,QAAQ,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAChD,CAAC;QAED,IAAI,GAAA;AACF,YAAA,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QACvB,CAAC;QAED,OAAO,GAAA;AACL,YAAA,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;QAC1B,CAAC;KACF;AACD,IAAA,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC;IACzB,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC;AACnD,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,IAAI,WAAW,EAAE;AACf,QAAA,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;IAC5B;AAEA,IAAA,OAAO,QAAQ;AACjB;;;;"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/core/matcher.ts","../src/core/kt-router.ts","../src/core/index.ts"],"sourcesContent":["import type { RouteConfig, RouteMatch } from '../types/router.js';\nimport { extractParams, normalizePath } from '@ktjs/shared';\n\n/**\n * Route matcher for finding matching routes and extracting params\n */\nexport const createMatcher = (routes: RouteConfig[]) => {\n const nameMap: Record<string, RouteConfig> = {};\n\n for (let i = 0; i < routes.length; i++) {\n const route = routes[i];\n if (route.name !== undefined) {\n if (route.name in nameMap) {\n $throw(`Duplicate route name detected: '${route.name}'`);\n }\n nameMap[route.name] = route;\n }\n }\n\n /**\n * Find route by name\n */\n const findByName = (name: string): RouteConfig | null => {\n return nameMap[name] ?? null;\n };\n\n /**\n * Match path against all routes\n */\n const match = (path: string): RouteMatch | null => {\n const normalizedPath = normalizePath(path);\n\n // Try exact match first\n for (const route of routes) {\n if (route.path === normalizedPath) {\n return {\n route,\n params: {},\n result: getMatchedChain(route),\n };\n }\n }\n\n // Try dynamic routes\n for (const route of routes) {\n if (route.path.includes(':')) {\n const params = extractParams(route.path, normalizedPath);\n if (params) {\n return {\n route,\n params,\n result: getMatchedChain(route),\n };\n }\n }\n }\n\n return null;\n };\n\n /**\n * Get chain of matched routes (for nested routes)\n * - parent roots ahead\n */\n const getMatchedChain = (route: RouteConfig): RouteConfig[] => {\n const matched: RouteConfig[] = [route];\n const path = route.path;\n\n // Find parent routes by path prefix matching\n for (let i = 0; i < routes.length; i++) {\n const r = routes[i];\n if (r !== route && path.startsWith(r.path) && path !== r.path) {\n matched.push(r);\n }\n }\n\n return matched.reverse();\n };\n\n return {\n findByName,\n match,\n };\n};\n","import type { JSX } from '@ktjs/core/jsx-runtime';\nimport type { Router } from '../types/router.js';\n\n/**\n * Create a router view container that automatically renders route components\n */\nexport function KTRouter({ router }: { router: Router }): JSX.Element {\n const view = document.createElement('kt-router-view');\n router.setRouterView(view);\n return view as JSX.Element;\n}\n","import { $emptyFn, buildQuery, normalizePath, parseQuery, emplaceParams } from '@ktjs/shared';\n\nimport type { Router, RouterConfig, RouteContext, NavOptions, RawRouteConfig, RouteConfig } from '../types/router.js';\nimport { GuardLevel } from './consts.js';\nimport { createMatcher } from './matcher.js';\n\n/**\n * Create a new router instance\n */\nexport const createRouter = ({\n beforeEach = $emptyFn,\n afterEach = $emptyFn,\n onNotFound = $emptyFn,\n onError = $emptyFn,\n prefix = '',\n routes: rawRoutes,\n}: RouterConfig): Router => {\n // # private values\n const routes: RouteConfig[] = [];\n const history: RouteContext[] = [];\n let routerView: HTMLElement | null = null;\n let current: RouteContext | null = null;\n\n // # methods\n const normalize = (rawRoutes: RawRouteConfig[], parentPath: string): RouteConfig[] =>\n rawRoutes.map((route) => {\n const path = normalizePath(parentPath, route.path);\n const normalized = {\n path: prefix + path,\n name: route.name ?? '',\n meta: route.meta ?? {},\n beforeEnter: route.beforeEnter ?? $emptyFn,\n after: route.after ?? $emptyFn,\n children: route.children ? normalize(route.children, path) : [],\n component: route.component,\n };\n\n // directly push the normalized route to the list\n // avoid flatten them again\n routes.push(normalized);\n return normalized;\n });\n\n const guard = async (\n to: RouteContext,\n from: RouteContext | null,\n guardLevel: GuardLevel,\n ): Promise<{ continue: boolean; redirectTo?: NavOptions }> => {\n try {\n if (guardLevel === GuardLevel.None) {\n return { continue: true };\n }\n\n if (guardLevel & GuardLevel.Global) {\n const result = await beforeEach(to, from);\n if (result === false) {\n return { continue: false };\n }\n if (typeof result === 'string') {\n return { continue: false, redirectTo: { path: result } };\n }\n if (result && typeof result === 'object') {\n return { continue: false, redirectTo: result };\n }\n }\n\n if (guardLevel & GuardLevel.Route) {\n const targetRoute = to.matched[to.matched.length - 1];\n const result = await targetRoute.beforeEnter(to);\n if (result === false) {\n return { continue: false };\n }\n if (typeof result === 'string') {\n return { continue: false, redirectTo: { path: result } };\n }\n if (result && typeof result === 'object') {\n return { continue: false, redirectTo: result };\n }\n }\n\n return { continue: true };\n } catch (error) {\n onError(error as Error);\n return { continue: false };\n }\n };\n\n const navigatePrepare = (options: NavOptions) => {\n // Resolve target route\n let targetPath: string;\n let targetRoute;\n\n if (options.name) {\n targetRoute = findByName(options.name);\n if (!targetRoute) {\n $throw(`Route not found: ${options.name}`);\n }\n targetPath = targetRoute.path;\n } else if (options.path) {\n targetPath = normalizePath(options.path);\n targetRoute = match(targetPath)?.route;\n } else {\n $throw(`Either path or name must be provided`);\n }\n\n // Substitute params\n if (options.params) {\n targetPath = emplaceParams(targetPath, options.params);\n }\n\n // Match final path\n const matched = match(targetPath);\n if (!matched) {\n onNotFound(targetPath);\n return null;\n }\n\n // Build route context\n const queryString = options.query ? buildQuery(options.query) : '';\n const fullPath = targetPath + queryString;\n\n const to: RouteContext = {\n path: targetPath,\n name: matched.route.name,\n params: { ...matched.params, ...(options.params ?? {}) },\n query: options.query ?? {},\n meta: matched.route.meta ?? {},\n matched: matched.result,\n };\n\n return {\n guardLevel: options.guardLevel ?? GuardLevel.Default,\n replace: options.replace ?? false,\n to,\n fullPath,\n };\n };\n\n const navigate = async (options: NavOptions, redirectCount = 0): Promise<boolean> => {\n try {\n // Prevent infinite redirect loop\n if (redirectCount > 10) {\n onError(new Error('Maximum redirect count exceeded'));\n return false;\n }\n\n const prep = navigatePrepare(options);\n if (!prep) {\n return false;\n }\n\n const { guardLevel, replace, to, fullPath } = prep;\n\n const guardResult = await guard(to, current, guardLevel);\n if (!guardResult.continue) {\n // Check if there's a redirect\n if (guardResult.redirectTo) {\n return await navigate(guardResult.redirectTo, redirectCount + 1);\n }\n return false;\n }\n\n // ---- Guards passed ----\n\n const hashUrl = '#' + fullPath;\n if (replace) {\n window.location.replace(hashUrl);\n } else {\n window.location.hash = fullPath;\n }\n\n current = to;\n if (replace) {\n if (history.length > 0) {\n history[history.length - 1] = to;\n } else {\n history.push(to);\n }\n } else {\n history.push(to);\n }\n\n // Render component if routerView exists\n if (routerView && to.matched.length > 0) {\n const route = to.matched[to.matched.length - 1];\n if (route.component) {\n const element = await route.component();\n routerView.innerHTML = '';\n routerView.appendChild(element);\n }\n }\n\n executeAfterHooks(to, history[history.length - 2] ?? null);\n return true;\n } catch (error) {\n onError(error as Error);\n return false;\n }\n };\n\n const executeAfterHooks = async (to: RouteContext, from: RouteContext | null): Promise<void> => {\n const targetRoute = to.matched[to.matched.length - 1];\n await targetRoute.after(to);\n await afterEach(to, from);\n };\n\n /**\n * Normalize navigation argument\n */\n const normalizeLocation = (loc: string | NavOptions): NavOptions => {\n if (typeof loc !== 'string') {\n return loc;\n }\n\n const [path, queryString] = loc.split('?');\n return {\n path,\n query: queryString ? parseQuery(queryString) : undefined,\n };\n };\n\n // # register events\n window.addEventListener('hashchange', () => {\n const hash = window.location.hash.slice(1);\n const [path] = hash.split('?');\n const normalizedPath = normalizePath(path);\n if (current && current.path === normalizedPath) {\n return;\n }\n // render route for new hash without adding extra history entry\n const matched = match(normalizedPath);\n if (!matched) {\n onNotFound(normalizedPath);\n return;\n }\n const queryString = window.location.hash.slice(1).split('?')[1];\n const to: RouteContext = {\n path: normalizedPath,\n name: matched.route.name,\n params: matched.params,\n query: queryString ? parseQuery(queryString) : {},\n meta: matched.route.meta ?? {},\n matched: matched.result,\n };\n\n // apply without modifying browser history\n current = to;\n history.push(to);\n\n if (routerView && to.matched.length > 0) {\n const route = to.matched[to.matched.length - 1];\n if (route.component) {\n const element = route.component();\n if (element instanceof Promise) {\n element.then((el) => {\n routerView!.innerHTML = '';\n routerView!.appendChild(el);\n });\n } else {\n routerView.innerHTML = '';\n routerView.appendChild(element);\n }\n }\n }\n\n executeAfterHooks(to, history[history.length - 2] ?? null);\n });\n\n // # initialize\n const instance: Router = {\n get current() {\n return current;\n },\n\n get history() {\n return history.concat();\n },\n\n setRouterView(view: HTMLElement) {\n routerView = view;\n },\n\n push(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate(options);\n },\n\n silentPush(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate({ ...options, guardLevel: GuardLevel.Route });\n },\n\n replace(location: string | NavOptions): boolean | Promise<boolean> {\n const options = normalizeLocation(location);\n return navigate({ ...options, replace: true });\n },\n\n back() {\n window.history.back();\n },\n\n forward() {\n window.history.forward();\n },\n };\n normalize(rawRoutes, '/');\n const { findByName, match } = createMatcher(routes);\n const currentHash = window.location.hash.slice(1);\n if (currentHash) {\n instance.push(currentHash);\n }\n\n return instance;\n};\n\nexport { GuardLevel };\nexport { KTRouter } from './kt-router.js';\n"],"names":[],"mappings":"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"}
|