@real-router/core 0.25.3 → 0.26.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 +163 -325
- package/dist/cjs/index.d.ts +47 -178
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/metafile-cjs.json +1 -1
- package/dist/esm/index.d.mts +47 -178
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/metafile-esm.json +1 -1
- package/package.json +3 -3
- package/src/Router.ts +84 -574
- package/src/api/cloneRouter.ts +106 -0
- package/src/api/getDependenciesApi.ts +216 -0
- package/src/api/getLifecycleApi.ts +67 -0
- package/src/api/getPluginApi.ts +118 -0
- package/src/api/getRoutesApi.ts +566 -0
- package/src/api/index.ts +16 -0
- package/src/api/types.ts +7 -0
- package/src/getNavigator.ts +5 -2
- package/src/index.ts +17 -3
- package/src/internals.ts +115 -0
- package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +30 -0
- package/src/namespaces/DependenciesNamespace/index.ts +3 -1
- package/src/namespaces/DependenciesNamespace/validators.ts +2 -4
- package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +1 -20
- package/src/namespaces/EventBusNamespace/validators.ts +36 -0
- package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +1 -10
- package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +2 -0
- package/src/namespaces/NavigationNamespace/transition/{executeLifecycleHooks.ts → executeLifecycleGuards.ts} +9 -7
- package/src/namespaces/NavigationNamespace/transition/index.ts +3 -3
- package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +1 -16
- package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +133 -1089
- package/src/namespaces/RoutesNamespace/forwardToValidation.ts +411 -0
- package/src/namespaces/RoutesNamespace/helpers.ts +1 -407
- package/src/namespaces/RoutesNamespace/index.ts +2 -0
- package/src/namespaces/RoutesNamespace/routesStore.ts +388 -0
- package/src/namespaces/RoutesNamespace/validators.ts +209 -3
- package/src/namespaces/StateNamespace/StateNamespace.ts +1 -44
- package/src/namespaces/StateNamespace/validators.ts +46 -0
- package/src/namespaces/index.ts +3 -5
- package/src/types.ts +12 -138
- package/src/wiring/RouterWiringBuilder.ts +30 -36
- package/src/wiring/types.ts +3 -6
- package/src/wiring/wireRouter.ts +0 -1
- package/src/namespaces/CloneNamespace/CloneNamespace.ts +0 -120
- package/src/namespaces/CloneNamespace/index.ts +0 -3
- package/src/namespaces/CloneNamespace/types.ts +0 -42
- package/src/namespaces/DependenciesNamespace/DependenciesNamespace.ts +0 -248
- package/src/namespaces/RoutesNamespace/stateBuilder.ts +0 -70
package/README.md
CHANGED
|
@@ -29,13 +29,16 @@ const routes = [
|
|
|
29
29
|
|
|
30
30
|
const router = createRouter(routes);
|
|
31
31
|
|
|
32
|
-
router.start();
|
|
33
|
-
router.navigate("users.profile", { id: "123" });
|
|
32
|
+
await router.start("/");
|
|
33
|
+
await router.navigate("users.profile", { id: "123" });
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
38
|
-
##
|
|
38
|
+
## Router API
|
|
39
|
+
|
|
40
|
+
The Router class provides core lifecycle, navigation, state, and subscription methods.
|
|
41
|
+
Domain-specific operations (routes, dependencies, guards, plugin infrastructure, cloning) are available through standalone API functions for tree-shaking.
|
|
39
42
|
|
|
40
43
|
### `createRouter(routes?, options?, dependencies?)`
|
|
41
44
|
|
|
@@ -53,23 +56,23 @@ const router = createRouter(
|
|
|
53
56
|
|
|
54
57
|
### Lifecycle
|
|
55
58
|
|
|
56
|
-
#### `router.start(
|
|
59
|
+
#### `router.start(path): Promise<State>`
|
|
57
60
|
|
|
58
|
-
Starts the router. [Wiki](https://github.com/greydragon888/real-router/wiki/start)
|
|
61
|
+
Starts the router with an initial path. Returns a Promise that resolves with the matched state. [Wiki](https://github.com/greydragon888/real-router/wiki/start)
|
|
59
62
|
|
|
60
63
|
```typescript
|
|
61
|
-
router.start();
|
|
62
|
-
router.start("/users/123");
|
|
63
|
-
router.start("/users/123", (err, state) => {
|
|
64
|
-
if (err) console.error(err);
|
|
65
|
-
});
|
|
64
|
+
const state = await router.start("/users/123");
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
#### `router.stop()`
|
|
67
|
+
#### `router.stop(): this`
|
|
68
|
+
|
|
69
|
+
Stops the router. Cancels any in-progress transition. [Wiki](https://github.com/greydragon888/real-router/wiki/stop)
|
|
70
|
+
|
|
71
|
+
#### `router.dispose(): void`
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
Permanently terminates the router. Unlike `stop()`, it cannot be restarted. All mutating methods throw `RouterError(DISPOSED)` after disposal. Idempotent. [Wiki](https://github.com/greydragon888/real-router/wiki/dispose)
|
|
71
74
|
|
|
72
|
-
#### `router.isActive()`
|
|
75
|
+
#### `router.isActive(): boolean`
|
|
73
76
|
|
|
74
77
|
Returns whether the router is active (started and has current state). [Wiki](https://github.com/greydragon888/real-router/wiki/isActive)
|
|
75
78
|
|
|
@@ -77,26 +80,48 @@ Returns whether the router is active (started and has current state). [Wiki](htt
|
|
|
77
80
|
|
|
78
81
|
### Navigation
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
All navigation methods return `Promise<State>`.
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
#### `router.navigate(name, params?, options?): Promise<State>`
|
|
86
|
+
|
|
87
|
+
Navigates to a route by name. [Wiki](https://github.com/greydragon888/real-router/wiki/navigate)
|
|
83
88
|
|
|
84
89
|
```typescript
|
|
85
|
-
router.navigate("users");
|
|
86
|
-
router.navigate("users.profile", { id: "123" });
|
|
87
|
-
router.navigate("users.profile", { id: "123" }, { replace: true });
|
|
90
|
+
const state = await router.navigate("users.profile", { id: "123" });
|
|
88
91
|
|
|
89
|
-
// With
|
|
90
|
-
router.navigate("users", {}, {
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
// With navigation options
|
|
93
|
+
await router.navigate("users", {}, { replace: true });
|
|
94
|
+
|
|
95
|
+
// Concurrent navigation cancels previous
|
|
96
|
+
router.navigate("slow-route");
|
|
97
|
+
router.navigate("fast-route"); // Previous rejects with TRANSITION_CANCELLED
|
|
93
98
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
// Error handling
|
|
100
|
+
try {
|
|
101
|
+
await router.navigate("admin");
|
|
102
|
+
} catch (err) {
|
|
103
|
+
if (err instanceof RouterError) {
|
|
104
|
+
// ROUTE_NOT_FOUND, CANNOT_ACTIVATE, CANNOT_DEACTIVATE,
|
|
105
|
+
// TRANSITION_CANCELLED, SAME_STATES, ROUTER_DISPOSED
|
|
106
|
+
}
|
|
107
|
+
}
|
|
97
108
|
```
|
|
98
109
|
|
|
99
|
-
|
|
110
|
+
**Fire-and-forget safe:** calling `router.navigate(...)` without `await` suppresses expected errors (`SAME_STATES`, `TRANSITION_CANCELLED`).
|
|
111
|
+
|
|
112
|
+
#### `router.navigateToDefault(options?): Promise<State>`
|
|
113
|
+
|
|
114
|
+
Navigates to the default route. [Wiki](https://github.com/greydragon888/real-router/wiki/navigateToDefault)
|
|
115
|
+
|
|
116
|
+
#### `router.canNavigateTo(name, params?): boolean`
|
|
117
|
+
|
|
118
|
+
Synchronously checks if navigation to a route would be allowed by guards. [Wiki](https://github.com/greydragon888/real-router/wiki/canNavigateTo)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### State
|
|
123
|
+
|
|
124
|
+
#### `router.getState(): State | undefined`
|
|
100
125
|
|
|
101
126
|
Returns the current router state. [Wiki](https://github.com/greydragon888/real-router/wiki/getState)
|
|
102
127
|
|
|
@@ -105,85 +130,56 @@ const state = router.getState();
|
|
|
105
130
|
// { name: "users.profile", params: { id: "123" }, path: "/users/123" }
|
|
106
131
|
```
|
|
107
132
|
|
|
108
|
-
#### `router.
|
|
133
|
+
#### `router.getPreviousState(): State | undefined`
|
|
109
134
|
|
|
110
|
-
|
|
135
|
+
Returns the previous router state. [Wiki](https://github.com/greydragon888/real-router/wiki/getPreviousState)
|
|
111
136
|
|
|
112
|
-
|
|
137
|
+
#### `router.areStatesEqual(state1, state2, ignoreQueryParams?): boolean`
|
|
113
138
|
|
|
114
|
-
|
|
139
|
+
Compare two states for equality. Query params ignored by default. [Wiki](https://github.com/greydragon888/real-router/wiki/areStatesEqual)
|
|
115
140
|
|
|
116
|
-
#### `router.
|
|
141
|
+
#### `router.shouldUpdateNode(nodeName): (toState, fromState?) => boolean`
|
|
117
142
|
|
|
118
|
-
|
|
143
|
+
Create a predicate to check if a route node should update during transition. [Wiki](https://github.com/greydragon888/real-router/wiki/shouldUpdateNode)
|
|
119
144
|
|
|
120
|
-
|
|
121
|
-
router.addActivateGuard("admin", () => (toState, fromState, done) => {
|
|
122
|
-
if (!isAuthenticated()) {
|
|
123
|
-
done({ redirect: { name: "login" } });
|
|
124
|
-
} else {
|
|
125
|
-
done();
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
```
|
|
145
|
+
---
|
|
129
146
|
|
|
130
|
-
|
|
147
|
+
### Path Operations
|
|
131
148
|
|
|
132
|
-
|
|
149
|
+
#### `router.buildPath(name, params?): string`
|
|
150
|
+
|
|
151
|
+
Build URL path from route name. [Wiki](https://github.com/greydragon888/real-router/wiki/buildPath)
|
|
133
152
|
|
|
134
153
|
```typescript
|
|
135
|
-
router.
|
|
136
|
-
|
|
137
|
-
done({ error: new Error("Unsaved changes") });
|
|
138
|
-
} else {
|
|
139
|
-
done();
|
|
140
|
-
}
|
|
141
|
-
});
|
|
154
|
+
const path = router.buildPath("users.profile", { id: "123" });
|
|
155
|
+
// "/users/123"
|
|
142
156
|
```
|
|
143
157
|
|
|
158
|
+
#### `router.isActiveRoute(name, params?, strictEquality?, ignoreQueryParams?): boolean`
|
|
159
|
+
|
|
160
|
+
Check if route is currently active. [Wiki](https://github.com/greydragon888/real-router/wiki/isActiveRoute)
|
|
161
|
+
|
|
144
162
|
---
|
|
145
163
|
|
|
146
164
|
### Events
|
|
147
165
|
|
|
148
|
-
#### `router.subscribe(listener)`
|
|
166
|
+
#### `router.subscribe(listener): Unsubscribe`
|
|
149
167
|
|
|
150
168
|
Subscribes to successful transitions. [Wiki](https://github.com/greydragon888/real-router/wiki/subscribe)
|
|
151
169
|
|
|
152
170
|
```typescript
|
|
153
171
|
const unsubscribe = router.subscribe(({ route, previousRoute }) => {
|
|
154
|
-
console.log("Navigation:", previousRoute?.name, "
|
|
172
|
+
console.log("Navigation:", previousRoute?.name, "->", route.name);
|
|
155
173
|
});
|
|
156
174
|
```
|
|
157
175
|
|
|
158
|
-
#### `router.addEventListener(event, listener)`
|
|
159
|
-
|
|
160
|
-
Adds an event listener. Returns an unsubscribe function. [Wiki](https://github.com/greydragon888/real-router/wiki/addEventListener)
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
import { events } from "@real-router/core";
|
|
164
|
-
|
|
165
|
-
const unsubscribe = router.addEventListener(
|
|
166
|
-
events.TRANSITION_START,
|
|
167
|
-
(toState, fromState) => {
|
|
168
|
-
console.log("Starting:", toState.name);
|
|
169
|
-
},
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
// To remove listener, call the returned unsubscribe function
|
|
173
|
-
unsubscribe();
|
|
174
|
-
|
|
175
|
-
// Available events:
|
|
176
|
-
// ROUTER_START, ROUTER_STOP
|
|
177
|
-
// TRANSITION_START, TRANSITION_SUCCESS, TRANSITION_ERROR, TRANSITION_CANCEL
|
|
178
|
-
```
|
|
179
|
-
|
|
180
176
|
---
|
|
181
177
|
|
|
182
178
|
### Plugins
|
|
183
179
|
|
|
184
|
-
#### `router.usePlugin(
|
|
180
|
+
#### `router.usePlugin(...plugins): Unsubscribe`
|
|
185
181
|
|
|
186
|
-
Registers
|
|
182
|
+
Registers one or more plugins. Returns an unsubscribe function. [Wiki](https://github.com/greydragon888/real-router/wiki/usePlugin)
|
|
187
183
|
|
|
188
184
|
```typescript
|
|
189
185
|
import { browserPluginFactory } from "@real-router/browser-plugin";
|
|
@@ -193,284 +189,123 @@ const unsubscribe = router.usePlugin(browserPluginFactory());
|
|
|
193
189
|
|
|
194
190
|
---
|
|
195
191
|
|
|
196
|
-
##
|
|
197
|
-
|
|
198
|
-
### Routes
|
|
199
|
-
|
|
200
|
-
#### `router.addRoute(route, options?): void`
|
|
201
|
-
|
|
202
|
-
Add a route definition at runtime.
|
|
192
|
+
## Standalone API
|
|
203
193
|
|
|
204
|
-
|
|
194
|
+
Standalone functions provide domain-specific operations. They are tree-shakeable — only imported functions are bundled.
|
|
205
195
|
|
|
206
|
-
|
|
207
|
-
- `options?: { parent?: string }` — optional parent route fullName
|
|
196
|
+
### Routes — `getRoutesApi(router)`
|
|
208
197
|
|
|
209
|
-
|
|
198
|
+
Runtime route management. [Wiki](https://github.com/greydragon888/real-router/wiki/getRoutesApi)
|
|
210
199
|
|
|
211
200
|
```typescript
|
|
212
|
-
|
|
213
|
-
router.addRoute({
|
|
214
|
-
name: "users",
|
|
215
|
-
path: "/users",
|
|
216
|
-
children: [{ name: "profile", path: "/:id" }],
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// Add route under existing parent using { parent } option
|
|
220
|
-
router.addRoute({ name: "profile", path: "/:id" }, { parent: "users" });
|
|
221
|
-
// Creates "users.profile" fullName
|
|
222
|
-
|
|
223
|
-
// Batch add under same parent
|
|
224
|
-
router.addRoute(
|
|
225
|
-
[
|
|
226
|
-
{ name: "profile", path: "/:id" },
|
|
227
|
-
{ name: "settings", path: "/settings" },
|
|
228
|
-
],
|
|
229
|
-
{ parent: "users" },
|
|
230
|
-
);
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
Returns: `void`\
|
|
234
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/addRoute)
|
|
235
|
-
|
|
236
|
-
#### `router.removeRoute(name: string): void`
|
|
237
|
-
|
|
238
|
-
Remove a route by name.\
|
|
239
|
-
`name: string` — route name to remove\
|
|
240
|
-
Returns: `void`\
|
|
241
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/removeRoute)
|
|
242
|
-
|
|
243
|
-
#### `router.getRoute(name: string): Route | undefined`
|
|
244
|
-
|
|
245
|
-
Get route definition by name.\
|
|
246
|
-
`name: string` — route name\
|
|
247
|
-
Returns: `Route | undefined`\
|
|
248
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getRoute)
|
|
201
|
+
import { getRoutesApi } from "@real-router/core";
|
|
249
202
|
|
|
250
|
-
|
|
203
|
+
const routes = getRoutesApi(router);
|
|
251
204
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/hasRoute)
|
|
205
|
+
// Add routes
|
|
206
|
+
routes.add({ name: "settings", path: "/settings" });
|
|
207
|
+
routes.add({ name: "profile", path: "/:id" }, { parent: "users" });
|
|
256
208
|
|
|
257
|
-
|
|
209
|
+
// Query
|
|
210
|
+
routes.has("users"); // true
|
|
211
|
+
routes.get("users"); // Route | undefined
|
|
258
212
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
#### `router.updateRoute(name: string, updates: Partial<Route>): void`
|
|
264
|
-
|
|
265
|
-
Update route configuration.\
|
|
266
|
-
`name: string` — route name\
|
|
267
|
-
`updates: Partial<Route>` — properties to update\
|
|
268
|
-
Returns: `void`\
|
|
269
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/updateRoute)
|
|
270
|
-
|
|
271
|
-
**Note:** To set up route forwarding (redirect), use the `forwardTo` option in route configuration:
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
router.addRoute({ name: "old-url", path: "/old", forwardTo: "new-url" });
|
|
275
|
-
// Or update existing route
|
|
276
|
-
router.updateRoute("old-url", { forwardTo: "new-url" });
|
|
213
|
+
// Modify
|
|
214
|
+
routes.update("users", { forwardTo: "users.list" });
|
|
215
|
+
routes.remove("settings");
|
|
216
|
+
routes.clear();
|
|
277
217
|
```
|
|
278
218
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
### State Utilities
|
|
282
|
-
|
|
283
|
-
#### `router.getPreviousState(): State | undefined`
|
|
284
|
-
|
|
285
|
-
Get previous router state.\
|
|
286
|
-
Returns: `State | undefined`\
|
|
287
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getPreviousState)
|
|
288
|
-
|
|
289
|
-
#### `router.shouldUpdateNode(nodeName: string): (toState, fromState?) => boolean`
|
|
290
|
-
|
|
291
|
-
Create a predicate to check if a route node should update during transition.\
|
|
292
|
-
`nodeName: string` — route node name\
|
|
293
|
-
Returns: predicate function\
|
|
294
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/shouldUpdateNode)
|
|
295
|
-
|
|
296
|
-
#### `router.areStatesEqual(state1: State, state2: State, ignoreQueryParams?: boolean): boolean`
|
|
297
|
-
|
|
298
|
-
Compare two states for equality.\
|
|
299
|
-
`state1: State` — first state\
|
|
300
|
-
`state2: State` — second state\
|
|
301
|
-
`ignoreQueryParams?: boolean` — ignore query params (default: true)\
|
|
302
|
-
Returns: `boolean`\
|
|
303
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/areStatesEqual)
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
### Path Operations
|
|
308
|
-
|
|
309
|
-
#### `router.buildPath(name: string, params?: Params): string`
|
|
310
|
-
|
|
311
|
-
Build URL path from route name.\
|
|
312
|
-
`name: string` — route name\
|
|
313
|
-
`params?: Params` — route parameters\
|
|
314
|
-
Returns: `string`\
|
|
315
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/buildPath)
|
|
316
|
-
|
|
317
|
-
#### `router.buildUrl(name: string, params?: Params, options?: object): string`
|
|
318
|
-
|
|
319
|
-
Build full URL from route name (includes base path and query string).\
|
|
320
|
-
`name: string` — route name\
|
|
321
|
-
`params?: Params` — route parameters\
|
|
322
|
-
`options?: object` — URL building options\
|
|
323
|
-
Returns: `string`\
|
|
324
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/buildUrl)
|
|
325
|
-
|
|
326
|
-
#### `router.isActiveRoute(name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean): boolean`
|
|
327
|
-
|
|
328
|
-
Check if route is currently active.\
|
|
329
|
-
`name: string` — route name\
|
|
330
|
-
`params?: Params` — route parameters\
|
|
331
|
-
`strictEquality?: boolean` — exact match (default: false)\
|
|
332
|
-
`ignoreQueryParams?: boolean` — ignore query params (default: true)\
|
|
333
|
-
Returns: `boolean`\
|
|
334
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/isActiveRoute)
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
### Dependencies
|
|
219
|
+
**Methods:** `add`, `remove`, `update`, `clear`, `has`, `get`, `getConfig`
|
|
339
220
|
|
|
340
|
-
|
|
221
|
+
### Dependencies — `getDependenciesApi(router)`
|
|
341
222
|
|
|
342
|
-
|
|
343
|
-
`name: string` — dependency name\
|
|
344
|
-
Returns: `unknown`\
|
|
345
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getDependency)
|
|
223
|
+
Dependency injection container. [Wiki](https://github.com/greydragon888/real-router/wiki/getDependenciesApi)
|
|
346
224
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
Get all dependencies.\
|
|
350
|
-
Returns: `Dependencies`\
|
|
351
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getDependencies)
|
|
352
|
-
|
|
353
|
-
#### `router.setDependency(name: string, value: unknown): void`
|
|
354
|
-
|
|
355
|
-
Set a dependency.\
|
|
356
|
-
`name: string` — dependency name\
|
|
357
|
-
`value: unknown` — dependency value\
|
|
358
|
-
Returns: `void`\
|
|
359
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/setDependency)
|
|
360
|
-
|
|
361
|
-
#### `router.setDependencies(deps: Dependencies): void`
|
|
362
|
-
|
|
363
|
-
Set multiple dependencies.\
|
|
364
|
-
`deps: Dependencies` — dependencies object\
|
|
365
|
-
Returns: `void`\
|
|
366
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/setDependencies)
|
|
367
|
-
|
|
368
|
-
#### `router.hasDependency(name: string): boolean`
|
|
369
|
-
|
|
370
|
-
Check if dependency exists.\
|
|
371
|
-
`name: string` — dependency name\
|
|
372
|
-
Returns: `boolean`\
|
|
373
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/hasDependency)
|
|
374
|
-
|
|
375
|
-
#### `router.removeDependency(name: string): void`
|
|
376
|
-
|
|
377
|
-
Remove a dependency.\
|
|
378
|
-
`name: string` — dependency name\
|
|
379
|
-
Returns: `void`\
|
|
380
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/removeDependency)
|
|
381
|
-
|
|
382
|
-
#### `router.resetDependencies(): void`
|
|
225
|
+
```typescript
|
|
226
|
+
import { getDependenciesApi } from "@real-router/core";
|
|
383
227
|
|
|
384
|
-
|
|
385
|
-
Returns: `void`\
|
|
386
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/resetDependencies)
|
|
228
|
+
const deps = getDependenciesApi(router);
|
|
387
229
|
|
|
388
|
-
|
|
230
|
+
deps.set("authService", authService);
|
|
231
|
+
deps.get("authService"); // authService
|
|
232
|
+
deps.has("authService"); // true
|
|
233
|
+
deps.getAll(); // { authService: ... }
|
|
234
|
+
deps.remove("authService");
|
|
235
|
+
deps.reset();
|
|
236
|
+
```
|
|
389
237
|
|
|
390
|
-
|
|
238
|
+
**Methods:** `get`, `getAll`, `set`, `setAll`, `remove`, `reset`, `has`
|
|
391
239
|
|
|
392
|
-
|
|
240
|
+
### Guards — `getLifecycleApi(router)`
|
|
393
241
|
|
|
394
|
-
|
|
395
|
-
Returns: `Options`\
|
|
396
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getOptions)
|
|
242
|
+
Route activation/deactivation guards. [Wiki](https://github.com/greydragon888/real-router/wiki/getLifecycleApi)
|
|
397
243
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
### Other
|
|
244
|
+
```typescript
|
|
245
|
+
import { getLifecycleApi } from "@real-router/core";
|
|
401
246
|
|
|
402
|
-
|
|
247
|
+
const lifecycle = getLifecycleApi(router);
|
|
403
248
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
249
|
+
// Guard returns boolean or Promise<boolean> (true = allow, false = block)
|
|
250
|
+
lifecycle.addActivateGuard("admin", () => (toState, fromState) => {
|
|
251
|
+
return isAuthenticated(); // sync
|
|
252
|
+
});
|
|
408
253
|
|
|
409
|
-
|
|
254
|
+
lifecycle.addDeactivateGuard("editor", () => async (toState, fromState) => {
|
|
255
|
+
return !(await checkUnsavedChanges()); // async
|
|
256
|
+
});
|
|
410
257
|
|
|
411
|
-
|
|
258
|
+
// Remove guards
|
|
259
|
+
lifecycle.removeActivateGuard("admin");
|
|
260
|
+
lifecycle.removeDeactivateGuard("editor");
|
|
261
|
+
```
|
|
412
262
|
|
|
413
|
-
|
|
263
|
+
**Methods:** `addActivateGuard`, `addDeactivateGuard`, `removeActivateGuard`, `removeDeactivateGuard`
|
|
414
264
|
|
|
415
|
-
|
|
265
|
+
### Plugin Infrastructure — `getPluginApi(router)`
|
|
416
266
|
|
|
417
|
-
|
|
267
|
+
Low-level API for plugin authors. Provides access to state building, path matching, event system, and navigation. [Wiki](https://github.com/greydragon888/real-router/wiki/getPluginApi)
|
|
418
268
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
Returns: `State | undefined`\
|
|
422
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/matchPath)
|
|
269
|
+
```typescript
|
|
270
|
+
import { getPluginApi } from "@real-router/core";
|
|
423
271
|
|
|
424
|
-
|
|
272
|
+
const api = getPluginApi(router);
|
|
425
273
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
`path?: string` — URL path\
|
|
430
|
-
`meta?: object` — metadata\
|
|
431
|
-
`forceId?: number` — force specific `meta.id` value\
|
|
432
|
-
Returns: `State`\
|
|
433
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/makeState)
|
|
274
|
+
// State building
|
|
275
|
+
const state = api.matchPath("/users/123");
|
|
276
|
+
const builtState = api.makeState("users.profile", { id: "123" });
|
|
434
277
|
|
|
435
|
-
|
|
278
|
+
// Event system
|
|
279
|
+
const unsub = api.addEventListener(events.TRANSITION_START, (toState, fromState) => {
|
|
280
|
+
console.log("Starting:", toState.name);
|
|
281
|
+
});
|
|
436
282
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
`params?: Params` — route parameters\
|
|
440
|
-
Returns: `State | undefined`\
|
|
441
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/buildState)
|
|
283
|
+
// Navigation with pre-built state
|
|
284
|
+
await api.navigateToState(toState, fromState, opts);
|
|
442
285
|
|
|
443
|
-
|
|
286
|
+
// Root path management
|
|
287
|
+
api.setRootPath("/app");
|
|
288
|
+
api.getRootPath(); // "/app"
|
|
444
289
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
Returns: `{ name, params }` — resolved route name and merged params\
|
|
449
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/forwardState)
|
|
290
|
+
// Forward state interception (used by persistent-params-plugin)
|
|
291
|
+
api.setForwardState((name, params) => ({ name, params: withPersistent(params) }));
|
|
292
|
+
```
|
|
450
293
|
|
|
451
|
-
|
|
294
|
+
**Methods:** `makeState`, `buildState`, `buildNavigationState`, `forwardState`, `matchPath`, `setRootPath`, `getRootPath`, `navigateToState`, `addEventListener`, `getOptions`, `getTree`, `getForwardState`, `setForwardState`
|
|
452
295
|
|
|
453
|
-
|
|
454
|
-
`toState: State` — target state\
|
|
455
|
-
`fromState: State | undefined` — current state\
|
|
456
|
-
`opts: NavigationOptions` — navigation options\
|
|
457
|
-
`done: DoneFn` — callback\
|
|
458
|
-
`emitSuccess: boolean` — whether to emit TRANSITION_SUCCESS\
|
|
459
|
-
Returns: `CancelFn`\
|
|
460
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/navigateToState)
|
|
296
|
+
### SSR Cloning — `cloneRouter(router, deps?)`
|
|
461
297
|
|
|
462
|
-
|
|
298
|
+
Clone router for server-side rendering. [Wiki](https://github.com/greydragon888/real-router/wiki/cloneRouter)
|
|
463
299
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
Returns: `void`\
|
|
467
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/setRootPath)
|
|
300
|
+
```typescript
|
|
301
|
+
import { cloneRouter } from "@real-router/core";
|
|
468
302
|
|
|
469
|
-
|
|
303
|
+
// Server: clone router per request
|
|
304
|
+
const serverRouter = cloneRouter(router, { request: req });
|
|
305
|
+
await serverRouter.start(req.url);
|
|
306
|
+
```
|
|
470
307
|
|
|
471
|
-
|
|
472
|
-
Returns: `string`\
|
|
473
|
-
[Wiki](https://github.com/greydragon888/real-router/wiki/getRootPath)
|
|
308
|
+
Shares immutable route tree (O(1)), copies mutable state (dependencies, options, plugins, guards).
|
|
474
309
|
|
|
475
310
|
---
|
|
476
311
|
|
|
@@ -508,22 +343,25 @@ Navigation errors are instances of `RouterError`:
|
|
|
508
343
|
```typescript
|
|
509
344
|
import { RouterError, errorCodes } from "@real-router/core";
|
|
510
345
|
|
|
511
|
-
|
|
346
|
+
try {
|
|
347
|
+
await router.navigate("users");
|
|
348
|
+
} catch (err) {
|
|
512
349
|
if (err instanceof RouterError) {
|
|
513
350
|
console.log(err.code, err.message);
|
|
514
351
|
}
|
|
515
|
-
}
|
|
352
|
+
}
|
|
516
353
|
```
|
|
517
354
|
|
|
518
|
-
| Code
|
|
519
|
-
|
|
|
520
|
-
| `ROUTE_NOT_FOUND`
|
|
521
|
-
| `CANNOT_ACTIVATE`
|
|
522
|
-
| `CANNOT_DEACTIVATE`
|
|
523
|
-
| `CANCELLED`
|
|
524
|
-
| `SAME_STATES`
|
|
525
|
-
| `NOT_STARTED`
|
|
526
|
-
| `ALREADY_STARTED`
|
|
355
|
+
| Code | Description |
|
|
356
|
+
| --------------------- | ------------------------------ |
|
|
357
|
+
| `ROUTE_NOT_FOUND` | Route doesn't exist |
|
|
358
|
+
| `CANNOT_ACTIVATE` | Blocked by canActivate guard |
|
|
359
|
+
| `CANNOT_DEACTIVATE` | Blocked by canDeactivate guard |
|
|
360
|
+
| `CANCELLED` | Navigation was cancelled |
|
|
361
|
+
| `SAME_STATES` | Already at target route |
|
|
362
|
+
| `NOT_STARTED` | Router not started |
|
|
363
|
+
| `ALREADY_STARTED` | Router already started |
|
|
364
|
+
| `DISPOSED` | Router has been disposed |
|
|
527
365
|
|
|
528
366
|
See [RouterError](https://github.com/greydragon888/real-router/wiki/RouterError) and [Error Codes](https://github.com/greydragon888/real-router/wiki/error-codes) for details.
|
|
529
367
|
|