@vobs/router 0.3.0 → 1.1.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/LICENSE +1 -1
- package/README.md +63 -0
- package/package.json +13 -36
- package/src/debug.ts +41 -0
- package/src/index.test.ts +574 -0
- package/src/index.ts +1173 -0
- package/dist/history.d.ts +0 -25
- package/dist/history.js +0 -174
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -14
- package/dist/keep-alive.d.ts +0 -20
- package/dist/keep-alive.js +0 -75
- package/dist/location.d.ts +0 -20
- package/dist/location.js +0 -107
- package/dist/match.d.ts +0 -23
- package/dist/match.js +0 -203
- package/dist/mount.d.ts +0 -18
- package/dist/mount.js +0 -205
- package/dist/navigation.d.ts +0 -9
- package/dist/navigation.js +0 -95
- package/dist/resolve.d.ts +0 -27
- package/dist/resolve.js +0 -272
- package/dist/router.d.ts +0 -8
- package/dist/router.js +0 -406
- package/dist/types.d.ts +0 -272
- package/dist/types.js +0 -9
package/LICENSE
CHANGED
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# @vobs/router
|
|
2
|
+
|
|
3
|
+
Signals-first client router for Vobs with guards, route loaders, and cancellation of superseded navigations.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @vobs/router
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { createVobs, createText } from '@vobs/vobs'
|
|
15
|
+
import { createRouter, createMemoryHistory, RouterView, routerPlugin } from '@vobs/router'
|
|
16
|
+
|
|
17
|
+
const router = createRouter({
|
|
18
|
+
history: createMemoryHistory('/'),
|
|
19
|
+
routes: [
|
|
20
|
+
{ path: '/', name: 'home', component: () => createText('home') },
|
|
21
|
+
{ path: '/users/:id', name: 'user', component: () => createText('user') }
|
|
22
|
+
]
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Guards return undefined (allow), false (cancel), or a redirect target.
|
|
26
|
+
router.beforeEach(to => (to.path.startsWith('/admin') ? '/login' : undefined))
|
|
27
|
+
|
|
28
|
+
const app = createVobs({
|
|
29
|
+
render: () => RouterView({ loading: () => createText('loading'), notFound: () => createText('not-found') }),
|
|
30
|
+
plugins: [routerPlugin({ router })]
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
await router.push({ name: 'user', params: { id: '7' }, query: { tab: 'activity' } })
|
|
34
|
+
router.currentRoute.value.fullPath // '/users/7?tab=activity'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
| Signature | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `createRouter(options: RouterOptions): Router` | Creates a router; defaults to browser history in the DOM and memory history otherwise. |
|
|
42
|
+
| `router.currentRoute: Signal<RouteLocation>` | Reactive current route with `path`, `params`, `query`, `hash`, `meta`, and `matched` records. |
|
|
43
|
+
| `router.push(to: RouteTarget)` | Navigates and resolves to the new `RouteLocation`, or `false` when a guard cancels. |
|
|
44
|
+
| `router.replace(to: RouteTarget)` | Like `push` but replaces the history entry. |
|
|
45
|
+
| `router.resolve(to: RouteTarget): RouteLocation` | Resolves a target to a location without navigating. |
|
|
46
|
+
| `router.back(): void` | Goes back in history. |
|
|
47
|
+
| `router.beforeEach(guard: NavigationGuard): () => void` | Registers a global guard and returns its unregister function. |
|
|
48
|
+
| `router.getViewState(route: RouteLocation): RouterViewState` | Resolves `ready`, `loading`, `error`, or `not-found` for the matched components. |
|
|
49
|
+
| `router.devtools: RouterDevToolsAPI` | Navigation traces, data-request tracking, errors, metrics, and revalidation. |
|
|
50
|
+
| `router.destroy(): void` | Stops history listening and disposes internal signals. |
|
|
51
|
+
| `routerPlugin(options?: RouterPluginOptions): VobsPlugin` | Provides the router through `ROUTER_KEY`. |
|
|
52
|
+
| `RouterView(props?: RouterViewProps): VobsNode` | Renders the matched component with nested layouts plus `loading`, `notFound`, and `error` slots. |
|
|
53
|
+
| `useRouter(): Router` | Injects the router inside components. |
|
|
54
|
+
| `useRoute(): Signal<RouteLocation>` | Injects the current-route signal. |
|
|
55
|
+
| `lazy(loader: RouteComponentLoader): LazyRouteComponent` | Wraps a dynamic import as a lazy route component. |
|
|
56
|
+
| `createMemoryHistory(initial?): RouterHistory` | In-memory history for tests and SSR. |
|
|
57
|
+
| `createBrowserHistory(base?): RouterHistory` | History API adapter with `popstate` support. |
|
|
58
|
+
|
|
59
|
+
Guards and route `loader`s run before a navigation commits. A newer navigation cancels the pending one: its promise rejects with `NavigationCancelledError`, and a late loader result cannot overwrite the current route or history. Guard redirects are capped at 10 hops (`NavigationRedirectError`).
|
|
60
|
+
|
|
61
|
+
## Types
|
|
62
|
+
|
|
63
|
+
`RouteLocation`, `RouteRecord`, `RouteComponent`, `RouteComponentProps`, `RouteComponentModule`, `RouteComponentLoader`, `RouteComponentDefinition`, `LazyRouteComponent`, `RouteLoader`, `RouteLoaderContext`, `NavigationGuard`, `NavigationGuardResult`, `RouteTarget`, `RouteLocationRaw`, `RouteQueryInput`, `RouteParams`, `RouteQuery`, `RouteQueryValue`, `RouteMeta`, `RouterOptions`, `RouterHistory`, `RouterViewState`, `Router`, `RouterViewProps`, `RouterPluginOptions`, `NavigationState`, `NavigationTrace`, `RouteErrorTrace`, `NavigationCancelledError`, `NavigationRedirectError`, `RouterPerformanceMetrics`, `RouterDevToolsAPI`, `RouterDevToolsEvent`, `RouterDataRequestKind`, `RouterDataRequestTrace`, `RouterDataRequestOptions`, `RouteDebugNode`, `RouterDebugEvent`, `RouterDebugEventType`
|
package/package.json
CHANGED
|
@@ -1,44 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "@vobs/router",
|
|
3
|
-
"version": "0.3.0",
|
|
4
|
-
"description": "Client and server route resolution for vobs pages.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"publishConfig": {
|
|
7
|
-
"access": "public"
|
|
8
|
-
},
|
|
9
2
|
"license": "MIT",
|
|
10
|
-
"author": "vobsjs",
|
|
11
|
-
"repository": {
|
|
12
|
-
"type": "git",
|
|
13
|
-
"url": "git+https://github.com/vobsjs/vobs.git",
|
|
14
|
-
"directory": "packages/features/router"
|
|
15
|
-
},
|
|
16
|
-
"bugs": {
|
|
17
|
-
"url": "https://github.com/vobsjs/vobs/issues"
|
|
18
|
-
},
|
|
19
|
-
"homepage": "https://github.com/vobsjs/vobs#readme",
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@vobs/reactivity": "0.3.0",
|
|
22
|
-
"@vobs/runtime-core": "0.3.0"
|
|
23
|
-
},
|
|
24
3
|
"files": [
|
|
25
|
-
"
|
|
4
|
+
"src",
|
|
5
|
+
"README.md",
|
|
6
|
+
"LICENSE"
|
|
26
7
|
],
|
|
8
|
+
"name": "@vobs/router",
|
|
9
|
+
"version": "1.1.0",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "src/index.ts",
|
|
12
|
+
"types": "src/index.ts",
|
|
27
13
|
"exports": {
|
|
28
|
-
".":
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js"
|
|
31
|
-
},
|
|
32
|
-
"./package.json": "./package.json"
|
|
14
|
+
".": "./src/index.ts"
|
|
33
15
|
},
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"devDependencies": {
|
|
39
|
-
"@vobs/resource": "0.3.0"
|
|
40
|
-
},
|
|
41
|
-
"engines": {
|
|
42
|
-
"node": ">=22.12.0"
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@vobs/reactivity": "1.1.0",
|
|
18
|
+
"@vobs/vobs": "1.1.0",
|
|
19
|
+
"@vobs/runtime": "1.1.0"
|
|
43
20
|
}
|
|
44
21
|
}
|
package/src/debug.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { RuntimeDebugContext } from '@vobs/runtime'
|
|
2
|
+
|
|
3
|
+
export type RouterDebugEventType =
|
|
4
|
+
| 'navigation:start'
|
|
5
|
+
| 'navigation:end'
|
|
6
|
+
| 'route:update'
|
|
7
|
+
| 'data-request'
|
|
8
|
+
| 'error'
|
|
9
|
+
|
|
10
|
+
export interface RouterDebugEvent {
|
|
11
|
+
readonly routerId: string
|
|
12
|
+
readonly type: RouterDebugEventType
|
|
13
|
+
readonly payload: unknown
|
|
14
|
+
readonly context?: RuntimeDebugContext
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type RouterDebugListener = (event: RouterDebugEvent) => void
|
|
18
|
+
|
|
19
|
+
const listeners = new Set<RouterDebugListener>()
|
|
20
|
+
let nextRouterId = 1
|
|
21
|
+
|
|
22
|
+
export function createRouterDebugId(): string {
|
|
23
|
+
return `router-${nextRouterId++}`
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function subscribeRouterDebug(listener: RouterDebugListener): () => void {
|
|
27
|
+
listeners.add(listener)
|
|
28
|
+
return () => listeners.delete(listener)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function emitRouterDebug(
|
|
32
|
+
routerId: string,
|
|
33
|
+
type: RouterDebugEventType,
|
|
34
|
+
payload: unknown,
|
|
35
|
+
context?: RuntimeDebugContext
|
|
36
|
+
): void {
|
|
37
|
+
const event: RouterDebugEvent = { routerId, type, payload, context }
|
|
38
|
+
for (const listener of [...listeners]) {
|
|
39
|
+
try { listener(event) } catch { /* diagnostics must not affect navigation */ }
|
|
40
|
+
}
|
|
41
|
+
}
|