@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 CHANGED
@@ -1,292 +1,71 @@
1
- # @ktjs/router
1
+ # KT.js
2
2
 
3
- <img src="https://raw.githubusercontent.com/baendlorel/kt.js/dev/.assets/ktjs-0.0.1.svg" alt="KT.js Logo" width="150"/>
3
+ [![npm version](https://img.shields.io/npm/v/kt.js.svg)](https://www.npmjs.com/package/kt.js)
4
+ [![npm downloads](https://img.shields.io/npm/dm/kt.js.svg)](https://www.npmjs.com/package/kt.js)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
6
 
5
- [![npm version](https://img.shields.io/npm/v/@ktjs/router.svg)](https://www.npmjs.com/package/@ktjs/router)
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
- > 📦 Part of [KT.js](https://github.com/baendlorel/kt.js) - A simple and easy-to-use web framework that never re-renders.
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
- Client-side router with navigation guards for KT.js.
15
+ > kt.js is still under development, so there might be some breaking changes. Note the Update Log below
10
16
 
11
- **Current Version:** 0.14.9
17
+ ## Recent Updates
12
18
 
13
- ## Overview
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
- `@ktjs/router` is a lightweight, hash-based client-side router with powerful async navigation guards. It provides all the essential routing features you need without the bloat. Simplified in v0.14.7+ to focus exclusively on hash-based routing for better performance and maintainability.
24
+ ## Community
16
25
 
17
- ## Features
26
+ - QQ Group: `1070434849`
27
+ - Telegram: https://t.me/kt_js
18
28
 
19
- - **Hash-Based Routing**: Uses URL hash for client-side navigation (`#/path`) - **hash-mode only** since v0.14.7
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
- ## Installation
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
- ### Create a KT.js project
33
+ KT.js focuses on one principle: keep direct control of the DOM and avoid unnecessary repainting.
44
34
 
45
- ```bash
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
- // Equivalent to: router.push('/user/456?tab=settings');
177
- ```
37
+ ```ts
38
+ const user = ref({ profile: { name: 'John' }, tags: ['new'] });
178
39
 
179
- ### Accessing Current Route
40
+ console.log(user.value.profile.name); // read
180
41
 
181
- ```typescript
182
- const current = router.current;
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
- if (current) {
185
- console.log('Path:', current.path); // e.g., '/user/123'
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
- ## API Reference
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
- - `current` (property): Current active route context (or `null`)
217
- - `history` (property): Array of navigation history
218
- - `routes` (property): Normalized route configurations
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
- **Router Instance Methods:**
62
+ This is an explicit contract, closer to a Rust-style model than permissive runtime magic: unclear code should fail early.
221
63
 
222
- - `push(location)`: Navigate to a new location (string path or route object with `name`/`params`)
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
- ### Navigation Guards (v0.14.7+)
229
-
230
- All guards are **async** and can return:
231
-
232
- - `false`: Cancel navigation
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
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ktjs/router",
3
- "version": "0.32.4",
3
+ "version": "0.33.0",
4
4
  "description": "Router for kt.js - client-side routing with navigation guards",
5
5
  "description_zh": "kt.js 的路由库,支持前端路由与导航守卫。",
6
6
  "type": "module",