@ktjs/router 0.32.4 → 0.32.5

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.
Files changed (2) hide show
  1. package/README.md +24 -277
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,292 +1,39 @@
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
+ ## Recent Updates
10
16
 
11
- **Current Version:** 0.14.9
17
+ 1. Special refs for `Array`, `Set`, `Map`, `WeakMap`, `WeakSet`, `Date` to better track mutations.
18
+ - e.g. `const a = ref.array([1, 2])`, then we can call `a.push(3)` to make a reactive change instead of `a.value.push(3)`.
19
+ 2. Fixed issues of `svg` and `mathml` elements.
12
20
 
13
- ## Overview
21
+ ## Community
14
22
 
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.
23
+ - QQ Group: `1070434849`
24
+ - Telegram: https://t.me/kt_js
16
25
 
17
- ## Features
26
+ ## Introduction
18
27
 
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
28
+ 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.
40
29
 
41
- ## Installation
30
+ KT.js focuses on one principle: keep direct control of the DOM and avoid unnecessary repainting.
42
31
 
43
- ### Create a KT.js project
32
+ ## Quick Start
44
33
 
45
34
  ```bash
46
35
  pnpm create kt.js my-app
36
+ cd my-app
37
+ pnpm install
38
+ pnpm dev
47
39
  ```
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
- });
175
-
176
- // Equivalent to: router.push('/user/456?tab=settings');
177
- ```
178
-
179
- ### Accessing Current Route
180
-
181
- ```typescript
182
- const current = router.current;
183
-
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
- }
190
- ```
191
-
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:**
215
-
216
- - `current` (property): Current active route context (or `null`)
217
- - `history` (property): Array of navigation history
218
- - `routes` (property): Normalized route configurations
219
-
220
- **Router Instance Methods:**
221
-
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
227
-
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
- });
258
- ```
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ktjs/router",
3
- "version": "0.32.4",
3
+ "version": "0.32.5",
4
4
  "description": "Router for kt.js - client-side routing with navigation guards",
5
5
  "description_zh": "kt.js 的路由库,支持前端路由与导航守卫。",
6
6
  "type": "module",