@real-router/types 0.12.0 → 0.14.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/dist/cjs/index.d.ts +10 -11
- package/dist/cjs/metafile-cjs.json +1 -1
- package/dist/esm/index.d.mts +10 -11
- package/dist/esm/metafile-esm.json +1 -1
- package/package.json +4 -2
- package/src/base.ts +259 -0
- package/src/constants.ts +104 -0
- package/src/index.ts +63 -0
- package/src/limits.ts +61 -0
- package/src/route-node-types.ts +73 -0
- package/src/router.ts +307 -0
package/dist/cjs/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This module exports ONLY the essential types used by real-router:
|
|
5
5
|
* - QueryParamsMode, QueryParamsOptions
|
|
6
|
-
* - RouteTreeState
|
|
6
|
+
* - RouteParams, RouteTreeState
|
|
7
7
|
*
|
|
8
8
|
* These types are copied from route-node to avoid circular dependencies.
|
|
9
9
|
*
|
|
@@ -68,8 +68,6 @@ interface StateMeta<P extends Params = Params> {
|
|
|
68
68
|
id: number;
|
|
69
69
|
params: P;
|
|
70
70
|
options: NavigationOptions;
|
|
71
|
-
redirected: boolean;
|
|
72
|
-
source?: string | undefined;
|
|
73
71
|
}
|
|
74
72
|
/**
|
|
75
73
|
* Input type for makeState meta parameter.
|
|
@@ -230,7 +228,7 @@ interface NavigationOptions {
|
|
|
230
228
|
* @description
|
|
231
229
|
* Automatically set by the router when a navigation is triggered by a redirect from
|
|
232
230
|
* middleware or lifecycle hooks. This flag is used internally to track redirect chains
|
|
233
|
-
* and is stored in state.meta.redirected.
|
|
231
|
+
* and is stored in state.meta.options.redirected.
|
|
234
232
|
*
|
|
235
233
|
* @default false (auto-set by router during redirects)
|
|
236
234
|
*
|
|
@@ -246,14 +244,14 @@ interface NavigationOptions {
|
|
|
246
244
|
* @example
|
|
247
245
|
* // Accessing redirect flag in lifecycle
|
|
248
246
|
* router.addActivateGuard('dashboard', (toState, fromState) => {
|
|
249
|
-
* if (toState.meta?.redirected) {
|
|
247
|
+
* if (toState.meta?.options?.redirected) {
|
|
250
248
|
* console.log('This navigation is from a redirect');
|
|
251
249
|
* }
|
|
252
250
|
* return true;
|
|
253
251
|
* });
|
|
254
252
|
*
|
|
255
253
|
* @see {@link Router.navigate} for redirect handling implementation
|
|
256
|
-
* @see {@link
|
|
254
|
+
* @see {@link NavigationOptions.redirected} for the input mechanism
|
|
257
255
|
*/
|
|
258
256
|
redirected?: boolean | undefined;
|
|
259
257
|
}
|
|
@@ -435,6 +433,7 @@ interface Options {
|
|
|
435
433
|
noValidate?: boolean;
|
|
436
434
|
}
|
|
437
435
|
type ActivationFn = (toState: State, fromState: State | undefined) => boolean | Promise<boolean | State | void> | State | void;
|
|
436
|
+
type GuardFn = (toState: State, fromState: State | undefined) => boolean | Promise<boolean>;
|
|
438
437
|
type DefaultDependencies = object;
|
|
439
438
|
interface Config {
|
|
440
439
|
decoders: Record<string, (params: Params) => Params>;
|
|
@@ -488,9 +487,9 @@ interface Navigator {
|
|
|
488
487
|
* Defines the contract for router implementations. The actual Router class in
|
|
489
488
|
* @real-router/core implements this interface with full functionality.
|
|
490
489
|
*
|
|
491
|
-
* This interface uses `
|
|
490
|
+
* This interface uses `GuardFn | boolean` for guard types to avoid circular
|
|
492
491
|
* dependencies. The concrete Router class in @real-router/core narrows this to
|
|
493
|
-
* `
|
|
492
|
+
* `GuardFnFactory | boolean` for more precise type checking.
|
|
494
493
|
*/
|
|
495
494
|
interface Router {
|
|
496
495
|
/**
|
|
@@ -500,7 +499,7 @@ interface Router {
|
|
|
500
499
|
* @param guard - Guard function or boolean
|
|
501
500
|
* @returns this for method chaining
|
|
502
501
|
*/
|
|
503
|
-
addActivateGuard: (name: string, guard:
|
|
502
|
+
addActivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
504
503
|
/**
|
|
505
504
|
* Register a deactivation guard for a route.
|
|
506
505
|
*
|
|
@@ -508,7 +507,7 @@ interface Router {
|
|
|
508
507
|
* @param guard - Guard function or boolean
|
|
509
508
|
* @returns this for method chaining
|
|
510
509
|
*/
|
|
511
|
-
addDeactivateGuard: (name: string, guard:
|
|
510
|
+
addDeactivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
512
511
|
/**
|
|
513
512
|
* Remove an activation guard from a route.
|
|
514
513
|
*
|
|
@@ -601,4 +600,4 @@ interface ErrorCodeToValueMap {
|
|
|
601
600
|
ROUTER_DISPOSED: "DISPOSED";
|
|
602
601
|
}
|
|
603
602
|
|
|
604
|
-
export type { ActivationFn, Config, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, ForwardToCallback, LimitsConfig, Listener, Middleware, NavigationOptions, Navigator, Options, Params, Plugin, PluginMethod, QueryParamsMode, QueryParamsOptions, RouteTreeState, Router, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
|
|
603
|
+
export type { ActivationFn, Config, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, ForwardToCallback, GuardFn, LimitsConfig, Listener, Middleware, NavigationOptions, Navigator, Options, Params, Plugin, PluginMethod, QueryParamsMode, QueryParamsOptions, RouteParams, RouteTreeState, Router, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"src/index.ts":{"bytes":
|
|
1
|
+
{"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"src/index.ts":{"bytes":1309,"imports":[{"path":"/home/runner/work/real-router/real-router/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/cjs/index.js":{"imports":[],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0}},"bytes":0}}}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This module exports ONLY the essential types used by real-router:
|
|
5
5
|
* - QueryParamsMode, QueryParamsOptions
|
|
6
|
-
* - RouteTreeState
|
|
6
|
+
* - RouteParams, RouteTreeState
|
|
7
7
|
*
|
|
8
8
|
* These types are copied from route-node to avoid circular dependencies.
|
|
9
9
|
*
|
|
@@ -68,8 +68,6 @@ interface StateMeta<P extends Params = Params> {
|
|
|
68
68
|
id: number;
|
|
69
69
|
params: P;
|
|
70
70
|
options: NavigationOptions;
|
|
71
|
-
redirected: boolean;
|
|
72
|
-
source?: string | undefined;
|
|
73
71
|
}
|
|
74
72
|
/**
|
|
75
73
|
* Input type for makeState meta parameter.
|
|
@@ -230,7 +228,7 @@ interface NavigationOptions {
|
|
|
230
228
|
* @description
|
|
231
229
|
* Automatically set by the router when a navigation is triggered by a redirect from
|
|
232
230
|
* middleware or lifecycle hooks. This flag is used internally to track redirect chains
|
|
233
|
-
* and is stored in state.meta.redirected.
|
|
231
|
+
* and is stored in state.meta.options.redirected.
|
|
234
232
|
*
|
|
235
233
|
* @default false (auto-set by router during redirects)
|
|
236
234
|
*
|
|
@@ -246,14 +244,14 @@ interface NavigationOptions {
|
|
|
246
244
|
* @example
|
|
247
245
|
* // Accessing redirect flag in lifecycle
|
|
248
246
|
* router.addActivateGuard('dashboard', (toState, fromState) => {
|
|
249
|
-
* if (toState.meta?.redirected) {
|
|
247
|
+
* if (toState.meta?.options?.redirected) {
|
|
250
248
|
* console.log('This navigation is from a redirect');
|
|
251
249
|
* }
|
|
252
250
|
* return true;
|
|
253
251
|
* });
|
|
254
252
|
*
|
|
255
253
|
* @see {@link Router.navigate} for redirect handling implementation
|
|
256
|
-
* @see {@link
|
|
254
|
+
* @see {@link NavigationOptions.redirected} for the input mechanism
|
|
257
255
|
*/
|
|
258
256
|
redirected?: boolean | undefined;
|
|
259
257
|
}
|
|
@@ -435,6 +433,7 @@ interface Options {
|
|
|
435
433
|
noValidate?: boolean;
|
|
436
434
|
}
|
|
437
435
|
type ActivationFn = (toState: State, fromState: State | undefined) => boolean | Promise<boolean | State | void> | State | void;
|
|
436
|
+
type GuardFn = (toState: State, fromState: State | undefined) => boolean | Promise<boolean>;
|
|
438
437
|
type DefaultDependencies = object;
|
|
439
438
|
interface Config {
|
|
440
439
|
decoders: Record<string, (params: Params) => Params>;
|
|
@@ -488,9 +487,9 @@ interface Navigator {
|
|
|
488
487
|
* Defines the contract for router implementations. The actual Router class in
|
|
489
488
|
* @real-router/core implements this interface with full functionality.
|
|
490
489
|
*
|
|
491
|
-
* This interface uses `
|
|
490
|
+
* This interface uses `GuardFn | boolean` for guard types to avoid circular
|
|
492
491
|
* dependencies. The concrete Router class in @real-router/core narrows this to
|
|
493
|
-
* `
|
|
492
|
+
* `GuardFnFactory | boolean` for more precise type checking.
|
|
494
493
|
*/
|
|
495
494
|
interface Router {
|
|
496
495
|
/**
|
|
@@ -500,7 +499,7 @@ interface Router {
|
|
|
500
499
|
* @param guard - Guard function or boolean
|
|
501
500
|
* @returns this for method chaining
|
|
502
501
|
*/
|
|
503
|
-
addActivateGuard: (name: string, guard:
|
|
502
|
+
addActivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
504
503
|
/**
|
|
505
504
|
* Register a deactivation guard for a route.
|
|
506
505
|
*
|
|
@@ -508,7 +507,7 @@ interface Router {
|
|
|
508
507
|
* @param guard - Guard function or boolean
|
|
509
508
|
* @returns this for method chaining
|
|
510
509
|
*/
|
|
511
|
-
addDeactivateGuard: (name: string, guard:
|
|
510
|
+
addDeactivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
512
511
|
/**
|
|
513
512
|
* Remove an activation guard from a route.
|
|
514
513
|
*
|
|
@@ -601,4 +600,4 @@ interface ErrorCodeToValueMap {
|
|
|
601
600
|
ROUTER_DISPOSED: "DISPOSED";
|
|
602
601
|
}
|
|
603
602
|
|
|
604
|
-
export type { ActivationFn, Config, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, ForwardToCallback, LimitsConfig, Listener, Middleware, NavigationOptions, Navigator, Options, Params, Plugin, PluginMethod, QueryParamsMode, QueryParamsOptions, RouteTreeState, Router, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
|
|
603
|
+
export type { ActivationFn, Config, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, ForwardToCallback, GuardFn, LimitsConfig, Listener, Middleware, NavigationOptions, Navigator, Options, Params, Plugin, PluginMethod, QueryParamsMode, QueryParamsOptions, RouteParams, RouteTreeState, Router, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"src/index.ts":{"bytes":
|
|
1
|
+
{"inputs":{"src/index.ts":{"bytes":1309,"imports":[],"format":"esm"}},"outputs":{"dist/esm/index.mjs":{"imports":[],"exports":[],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":0}},"bytes":0}}}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@real-router/types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "Shared TypeScript types for Real Router ecosystem",
|
|
6
6
|
"types": "./dist/esm/index.d.mts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
+
"development": "./src/index.ts",
|
|
9
10
|
"types": {
|
|
10
11
|
"import": "./dist/esm/index.d.mts",
|
|
11
12
|
"require": "./dist/cjs/index.d.ts"
|
|
@@ -13,7 +14,8 @@
|
|
|
13
14
|
}
|
|
14
15
|
},
|
|
15
16
|
"files": [
|
|
16
|
-
"dist"
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
17
19
|
],
|
|
18
20
|
"repository": {
|
|
19
21
|
"type": "git",
|
package/src/base.ts
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// packages/core-types/modules/base.ts
|
|
2
|
+
|
|
3
|
+
// Note: RouteTreeState is exported from route-node-types.ts
|
|
4
|
+
// It uses RouteParams as default type parameter.
|
|
5
|
+
// Real Router code should use RouteTreeState<Params> when needed.
|
|
6
|
+
|
|
7
|
+
export type Unsubscribe = () => void;
|
|
8
|
+
|
|
9
|
+
export interface SimpleState<P extends Params = Params> {
|
|
10
|
+
name: string;
|
|
11
|
+
params: P;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type TransitionPhase = "deactivating" | "activating" | "middleware";
|
|
15
|
+
|
|
16
|
+
export type TransitionReason = "success" | "blocked" | "cancelled" | "error";
|
|
17
|
+
|
|
18
|
+
export interface TransitionMeta {
|
|
19
|
+
phase: TransitionPhase;
|
|
20
|
+
from?: string;
|
|
21
|
+
reason: TransitionReason;
|
|
22
|
+
blocker?: string;
|
|
23
|
+
segments: {
|
|
24
|
+
deactivated: string[];
|
|
25
|
+
activated: string[];
|
|
26
|
+
intersection: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface State<P extends Params = Params, MP extends Params = Params> {
|
|
31
|
+
name: string;
|
|
32
|
+
params: P;
|
|
33
|
+
path: string;
|
|
34
|
+
meta?: StateMeta<MP> | undefined;
|
|
35
|
+
transition?: TransitionMeta | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface StateMeta<P extends Params = Params> {
|
|
39
|
+
id: number;
|
|
40
|
+
params: P;
|
|
41
|
+
options: NavigationOptions;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Input type for makeState meta parameter.
|
|
46
|
+
* Omits `id` since it's auto-generated by makeState.
|
|
47
|
+
*/
|
|
48
|
+
export type StateMetaInput<P extends Params = Params> = Omit<
|
|
49
|
+
StateMeta<P>,
|
|
50
|
+
"id"
|
|
51
|
+
>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* RouterError interface describing the public API of the RouterError class.
|
|
55
|
+
* The actual class implementation is in the real-router package.
|
|
56
|
+
* This interface enables structural typing compatibility between
|
|
57
|
+
* core-types and real-router packages.
|
|
58
|
+
*/
|
|
59
|
+
export interface RouterError extends Error {
|
|
60
|
+
[key: string]: unknown;
|
|
61
|
+
readonly code: string;
|
|
62
|
+
readonly segment: string | undefined;
|
|
63
|
+
readonly path: string | undefined;
|
|
64
|
+
readonly redirect: State | undefined;
|
|
65
|
+
setCode: (code: string) => void;
|
|
66
|
+
setErrorInstance: (err: Error) => void;
|
|
67
|
+
setAdditionalFields: (fields: Record<string, unknown>) => void;
|
|
68
|
+
hasField: (key: string) => boolean;
|
|
69
|
+
getField: (key: string) => unknown;
|
|
70
|
+
toJSON: () => Record<string, unknown>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Configuration options that control navigation transition behavior.
|
|
75
|
+
*
|
|
76
|
+
* @description
|
|
77
|
+
* NavigationOptions provides fine-grained control over how the router performs navigation
|
|
78
|
+
* transitions. These options affect history management, transition lifecycle execution,
|
|
79
|
+
* guard enforcement, and state comparison logic.
|
|
80
|
+
*
|
|
81
|
+
* All options are optional and have sensible defaults. Options can be combined to achieve
|
|
82
|
+
* complex navigation behaviors. The options object is stored in state.meta.options and is
|
|
83
|
+
* available to middleware, guards, and event listeners.
|
|
84
|
+
*
|
|
85
|
+
* @see {@link Router.navigate} for navigation method that accepts these options
|
|
86
|
+
* @see {@link State.meta} for where options are stored after navigation
|
|
87
|
+
*/
|
|
88
|
+
export interface NavigationOptions {
|
|
89
|
+
[key: string]:
|
|
90
|
+
| string
|
|
91
|
+
| number
|
|
92
|
+
| boolean
|
|
93
|
+
| Record<string, unknown>
|
|
94
|
+
| undefined;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Replace the current history entry instead of pushing a new one.
|
|
98
|
+
*
|
|
99
|
+
* @description
|
|
100
|
+
* When `true`, the navigation will replace the current entry in browser history instead
|
|
101
|
+
* of adding a new entry. This is typically used by history plugins (browser plugin) to
|
|
102
|
+
* control how navigation affects the browser's back/forward buttons.
|
|
103
|
+
*
|
|
104
|
+
* @default false
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* // Redirect after login - prevent back button to login page
|
|
108
|
+
* router.navigate('dashboard', {}, { replace: true });
|
|
109
|
+
*
|
|
110
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState}
|
|
111
|
+
*/
|
|
112
|
+
replace?: boolean | undefined;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Force reload of the current route even if states are equal.
|
|
116
|
+
*
|
|
117
|
+
* @description
|
|
118
|
+
* When `true`, bypasses the "same state" check that normally prevents navigation when
|
|
119
|
+
* the target state equals the current state. This forces a full transition lifecycle
|
|
120
|
+
* execution, allowing route components to reload with the same parameters.
|
|
121
|
+
*
|
|
122
|
+
* Without `reload`:
|
|
123
|
+
* - Navigation to current route throws SAME_STATES error
|
|
124
|
+
* - No lifecycle hooks or middleware execute
|
|
125
|
+
* - No events are fired
|
|
126
|
+
*
|
|
127
|
+
* With `reload`:
|
|
128
|
+
* - Full transition executes (deactivate → activate → middleware)
|
|
129
|
+
* - All lifecycle hooks run again
|
|
130
|
+
* - TRANSITION_SUCCESS event fires with same state
|
|
131
|
+
* - State object is recreated (new reference)
|
|
132
|
+
*
|
|
133
|
+
* @default false
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* // Refresh current page data
|
|
137
|
+
* router.navigate(currentRoute.name, currentRoute.params, { reload: true });
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* // Force re-fetch on same route with different query params
|
|
141
|
+
* // Note: query params are in path, not checked for equality
|
|
142
|
+
* router.navigate('search', { term: 'react' }, { reload: true });
|
|
143
|
+
*
|
|
144
|
+
* @see {@link force} for alternative that forces transition
|
|
145
|
+
* @see {@link Router.areStatesEqual} for state comparison logic
|
|
146
|
+
*/
|
|
147
|
+
reload?: boolean | undefined;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Force navigation even if target state equals current state.
|
|
151
|
+
*
|
|
152
|
+
* @description
|
|
153
|
+
* When `true`, bypasses the "same state" equality check but still executes the full
|
|
154
|
+
* transition lifecycle. Similar to `reload` but can be used
|
|
155
|
+
* for any forced navigation scenario.
|
|
156
|
+
*
|
|
157
|
+
* Difference from `reload`:
|
|
158
|
+
* - `reload`: semantic meaning is "refresh current route"
|
|
159
|
+
* - `force`: general-purpose bypass of equality check
|
|
160
|
+
* - Both have identical implementation effect
|
|
161
|
+
*
|
|
162
|
+
* The equality check compares:
|
|
163
|
+
* - state.name (route name)
|
|
164
|
+
* - state.params (route parameters, shallow comparison)
|
|
165
|
+
*
|
|
166
|
+
* @default false
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* // Force transition for tracking even if params didn't change
|
|
170
|
+
* router.navigate('analytics', { event: 'pageview' }, { force: true });
|
|
171
|
+
*
|
|
172
|
+
* @see {@link reload} for semantic equivalent (preferred for refresh scenarios)
|
|
173
|
+
*/
|
|
174
|
+
force?: boolean | undefined;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Skip canDeactivate guards during transition.
|
|
178
|
+
*
|
|
179
|
+
* @description
|
|
180
|
+
* When `true`, bypasses only the canDeactivate lifecycle hooks for segments being
|
|
181
|
+
* deactivated. canActivate guards and middleware still execute normally. This allows
|
|
182
|
+
* forcing navigation away from routes with confirmation dialogs or unsaved changes.
|
|
183
|
+
*
|
|
184
|
+
* Skipped vs executed:
|
|
185
|
+
* ```
|
|
186
|
+
* // Normal transition
|
|
187
|
+
* deactivate(fromSegments) → activate(toSegments) → middleware → success
|
|
188
|
+
*
|
|
189
|
+
* // With forceDeactivate: true
|
|
190
|
+
* [skip deactivate] → activate(toSegments) → middleware → success
|
|
191
|
+
* ```
|
|
192
|
+
*
|
|
193
|
+
* ⚠️ Data loss risk: Bypassing canDeactivate means unsaved changes will be lost
|
|
194
|
+
*
|
|
195
|
+
* @default false
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* // Force logout even with unsaved changes
|
|
199
|
+
* function forceLogout() {
|
|
200
|
+
* router.navigate('login', {}, {
|
|
201
|
+
* forceDeactivate: true,
|
|
202
|
+
* replace: true
|
|
203
|
+
* });
|
|
204
|
+
* }
|
|
205
|
+
*
|
|
206
|
+
* @see {@link Router.clearCanDeactivate} for programmatically clearing guards
|
|
207
|
+
*/
|
|
208
|
+
forceDeactivate?: boolean | undefined;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Internal flag indicating navigation is result of a redirect.
|
|
212
|
+
*
|
|
213
|
+
* @internal
|
|
214
|
+
*
|
|
215
|
+
* @description
|
|
216
|
+
* Automatically set by the router when a navigation is triggered by a redirect from
|
|
217
|
+
* middleware or lifecycle hooks. This flag is used internally to track redirect chains
|
|
218
|
+
* and is stored in state.meta.options.redirected.
|
|
219
|
+
*
|
|
220
|
+
* @default false (auto-set by router during redirects)
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* // Middleware triggers automatic redirect
|
|
224
|
+
* router.useMiddleware((toState, fromState, opts) => {
|
|
225
|
+
* if (!isAuthenticated && toState.name !== 'login') {
|
|
226
|
+
* // Router will automatically set redirected: true
|
|
227
|
+
* return { name: 'login', params: { next: toState.path } };
|
|
228
|
+
* }
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* // Accessing redirect flag in lifecycle
|
|
233
|
+
* router.addActivateGuard('dashboard', (toState, fromState) => {
|
|
234
|
+
* if (toState.meta?.options?.redirected) {
|
|
235
|
+
* console.log('This navigation is from a redirect');
|
|
236
|
+
* }
|
|
237
|
+
* return true;
|
|
238
|
+
* });
|
|
239
|
+
*
|
|
240
|
+
* @see {@link Router.navigate} for redirect handling implementation
|
|
241
|
+
* @see {@link NavigationOptions.redirected} for the input mechanism
|
|
242
|
+
*/
|
|
243
|
+
redirected?: boolean | undefined;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface Params {
|
|
247
|
+
[key: string]:
|
|
248
|
+
| string
|
|
249
|
+
| string[]
|
|
250
|
+
| number
|
|
251
|
+
| number[]
|
|
252
|
+
| boolean
|
|
253
|
+
| boolean[]
|
|
254
|
+
| Params
|
|
255
|
+
| Params[]
|
|
256
|
+
| Record<string, string | number | boolean>
|
|
257
|
+
| null
|
|
258
|
+
| undefined;
|
|
259
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// packages/core-types/modules/constants.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plugin lifecycle method names
|
|
5
|
+
*/
|
|
6
|
+
export type PluginMethod =
|
|
7
|
+
| "onStart"
|
|
8
|
+
| "onStop"
|
|
9
|
+
| "onTransitionStart"
|
|
10
|
+
| "onTransitionCancel"
|
|
11
|
+
| "onTransitionSuccess"
|
|
12
|
+
| "onTransitionError";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Router event names
|
|
16
|
+
*/
|
|
17
|
+
export type EventName =
|
|
18
|
+
| "$start"
|
|
19
|
+
| "$stop"
|
|
20
|
+
| "$$start"
|
|
21
|
+
| "$$cancel"
|
|
22
|
+
| "$$success"
|
|
23
|
+
| "$$error";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Event type keys
|
|
27
|
+
*/
|
|
28
|
+
export type EventsKeys =
|
|
29
|
+
| "ROUTER_START"
|
|
30
|
+
| "ROUTER_STOP"
|
|
31
|
+
| "TRANSITION_START"
|
|
32
|
+
| "TRANSITION_CANCEL"
|
|
33
|
+
| "TRANSITION_SUCCESS"
|
|
34
|
+
| "TRANSITION_ERROR";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Error code values
|
|
38
|
+
*/
|
|
39
|
+
export type ErrorCodeValues =
|
|
40
|
+
| "NOT_STARTED"
|
|
41
|
+
| "NO_START_PATH_OR_STATE"
|
|
42
|
+
| "ALREADY_STARTED"
|
|
43
|
+
| "ROUTE_NOT_FOUND"
|
|
44
|
+
| "SAME_STATES"
|
|
45
|
+
| "CANNOT_DEACTIVATE"
|
|
46
|
+
| "CANNOT_ACTIVATE"
|
|
47
|
+
| "TRANSITION_ERR"
|
|
48
|
+
| "CANCELLED"
|
|
49
|
+
| "DISPOSED";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Error code keys
|
|
53
|
+
*/
|
|
54
|
+
export type ErrorCodeKeys =
|
|
55
|
+
| "ROUTER_NOT_STARTED"
|
|
56
|
+
| "NO_START_PATH_OR_STATE"
|
|
57
|
+
| "ROUTER_ALREADY_STARTED"
|
|
58
|
+
| "ROUTE_NOT_FOUND"
|
|
59
|
+
| "SAME_STATES"
|
|
60
|
+
| "CANNOT_DEACTIVATE"
|
|
61
|
+
| "CANNOT_ACTIVATE"
|
|
62
|
+
| "TRANSITION_ERR"
|
|
63
|
+
| "TRANSITION_CANCELLED"
|
|
64
|
+
| "ROUTER_DISPOSED";
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Mapping of event keys to plugin methods
|
|
68
|
+
*/
|
|
69
|
+
export interface EventToPluginMap {
|
|
70
|
+
readonly ROUTER_START: "onStart";
|
|
71
|
+
readonly ROUTER_STOP: "onStop";
|
|
72
|
+
readonly TRANSITION_START: "onTransitionStart";
|
|
73
|
+
readonly TRANSITION_CANCEL: "onTransitionCancel";
|
|
74
|
+
readonly TRANSITION_SUCCESS: "onTransitionSuccess";
|
|
75
|
+
readonly TRANSITION_ERROR: "onTransitionError";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Mapping of event keys to event names
|
|
80
|
+
*/
|
|
81
|
+
export interface EventToNameMap {
|
|
82
|
+
ROUTER_START: "$start";
|
|
83
|
+
ROUTER_STOP: "$stop";
|
|
84
|
+
TRANSITION_START: "$$start";
|
|
85
|
+
TRANSITION_CANCEL: "$$cancel";
|
|
86
|
+
TRANSITION_SUCCESS: "$$success";
|
|
87
|
+
TRANSITION_ERROR: "$$error";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Mapping of error code keys to their values
|
|
92
|
+
*/
|
|
93
|
+
export interface ErrorCodeToValueMap {
|
|
94
|
+
ROUTER_NOT_STARTED: "NOT_STARTED";
|
|
95
|
+
NO_START_PATH_OR_STATE: "NO_START_PATH_OR_STATE";
|
|
96
|
+
ROUTER_ALREADY_STARTED: "ALREADY_STARTED";
|
|
97
|
+
ROUTE_NOT_FOUND: "ROUTE_NOT_FOUND";
|
|
98
|
+
SAME_STATES: "SAME_STATES";
|
|
99
|
+
CANNOT_DEACTIVATE: "CANNOT_DEACTIVATE";
|
|
100
|
+
CANNOT_ACTIVATE: "CANNOT_ACTIVATE";
|
|
101
|
+
TRANSITION_ERR: "TRANSITION_ERR";
|
|
102
|
+
TRANSITION_CANCELLED: "CANCELLED";
|
|
103
|
+
ROUTER_DISPOSED: "DISPOSED";
|
|
104
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// packages/core-types/modules/index.ts
|
|
2
|
+
|
|
3
|
+
// Route node types
|
|
4
|
+
export type {
|
|
5
|
+
QueryParamsMode,
|
|
6
|
+
QueryParamsOptions,
|
|
7
|
+
RouteParams,
|
|
8
|
+
RouteTreeState,
|
|
9
|
+
} from "./route-node-types";
|
|
10
|
+
|
|
11
|
+
// Base types
|
|
12
|
+
export type {
|
|
13
|
+
Params,
|
|
14
|
+
State,
|
|
15
|
+
StateMeta,
|
|
16
|
+
StateMetaInput,
|
|
17
|
+
SimpleState,
|
|
18
|
+
NavigationOptions,
|
|
19
|
+
Unsubscribe,
|
|
20
|
+
RouterError,
|
|
21
|
+
TransitionPhase,
|
|
22
|
+
TransitionReason,
|
|
23
|
+
TransitionMeta,
|
|
24
|
+
} from "./base";
|
|
25
|
+
|
|
26
|
+
// Router types (base types without Router dependency)
|
|
27
|
+
// Note: Route, RouteConfigUpdate, ActivationFnFactory, MiddlewareFactory,
|
|
28
|
+
// PluginFactory, BuildStateResultWithSegments are in @real-router/core
|
|
29
|
+
export type {
|
|
30
|
+
Options,
|
|
31
|
+
DefaultRouteCallback,
|
|
32
|
+
ForwardToCallback,
|
|
33
|
+
DefaultParamsCallback,
|
|
34
|
+
ActivationFn,
|
|
35
|
+
GuardFn,
|
|
36
|
+
DefaultDependencies,
|
|
37
|
+
Config,
|
|
38
|
+
Plugin,
|
|
39
|
+
Middleware,
|
|
40
|
+
SubscribeState,
|
|
41
|
+
SubscribeFn,
|
|
42
|
+
Listener,
|
|
43
|
+
Subscription,
|
|
44
|
+
Navigator,
|
|
45
|
+
Router,
|
|
46
|
+
} from "./router";
|
|
47
|
+
|
|
48
|
+
// Limits configuration
|
|
49
|
+
export type { LimitsConfig } from "./limits";
|
|
50
|
+
|
|
51
|
+
export type {
|
|
52
|
+
PluginMethod,
|
|
53
|
+
EventName,
|
|
54
|
+
EventsKeys,
|
|
55
|
+
ErrorCodeValues,
|
|
56
|
+
ErrorCodeKeys,
|
|
57
|
+
EventToPluginMap,
|
|
58
|
+
EventToNameMap,
|
|
59
|
+
ErrorCodeToValueMap,
|
|
60
|
+
} from "./constants";
|
|
61
|
+
|
|
62
|
+
// Note: RouterError type is a forward declaration matching the class in real-router package
|
|
63
|
+
// Use import { RouterError } from "real-router" for the actual class implementation
|
package/src/limits.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for router resource limits.
|
|
3
|
+
* Controls maximum allowed values for various router operations to prevent resource exhaustion.
|
|
4
|
+
*/
|
|
5
|
+
export interface LimitsConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Maximum number of route dependencies allowed.
|
|
8
|
+
* Prevents circular dependency chains and excessive dependency graphs.
|
|
9
|
+
*
|
|
10
|
+
* @default 100
|
|
11
|
+
*/
|
|
12
|
+
maxDependencies: number;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Maximum number of plugins that can be registered.
|
|
16
|
+
* Limits plugin stack depth to prevent performance degradation.
|
|
17
|
+
*
|
|
18
|
+
* @default 50
|
|
19
|
+
*/
|
|
20
|
+
maxPlugins: number;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maximum number of middleware functions in the navigation pipeline.
|
|
24
|
+
* Controls middleware chain length to prevent stack overflow and performance issues.
|
|
25
|
+
*
|
|
26
|
+
* @default 50
|
|
27
|
+
*/
|
|
28
|
+
maxMiddleware: number;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Maximum number of event listeners per event type.
|
|
32
|
+
* Prevents memory leaks from excessive listener registration.
|
|
33
|
+
*
|
|
34
|
+
* @default 10000
|
|
35
|
+
*/
|
|
36
|
+
maxListeners: number;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Listener count at which a memory leak warning is logged per event type.
|
|
40
|
+
* Set to 0 to disable the warning.
|
|
41
|
+
*
|
|
42
|
+
* @default 1000
|
|
43
|
+
*/
|
|
44
|
+
warnListeners: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Maximum depth of nested event propagation.
|
|
48
|
+
* Prevents infinite recursion in event handling chains.
|
|
49
|
+
*
|
|
50
|
+
* @default 5
|
|
51
|
+
*/
|
|
52
|
+
maxEventDepth: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Maximum number of lifecycle handlers (canActivate/canDeactivate) per route.
|
|
56
|
+
* Controls guard function stack to prevent excessive validation overhead.
|
|
57
|
+
*
|
|
58
|
+
* @default 200
|
|
59
|
+
*/
|
|
60
|
+
maxLifecycleHandlers: number;
|
|
61
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// packages/core-types/modules/route-node-types.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Route Node Type Definitions — Minimal Public API.
|
|
5
|
+
*
|
|
6
|
+
* This module exports ONLY the essential types used by real-router:
|
|
7
|
+
* - QueryParamsMode, QueryParamsOptions
|
|
8
|
+
* - RouteParams, RouteTreeState
|
|
9
|
+
*
|
|
10
|
+
* These types are copied from route-node to avoid circular dependencies.
|
|
11
|
+
*
|
|
12
|
+
* @module route-node-types
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Search Params Types
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
type ArrayFormat = "none" | "brackets" | "index" | "comma";
|
|
20
|
+
type BooleanFormat = "none" | "string" | "empty-true";
|
|
21
|
+
type NullFormat = "default" | "hidden";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Options for query parameter parsing and building.
|
|
25
|
+
*/
|
|
26
|
+
export interface QueryParamsOptions {
|
|
27
|
+
arrayFormat?: ArrayFormat;
|
|
28
|
+
booleanFormat?: BooleanFormat;
|
|
29
|
+
nullFormat?: NullFormat;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Mode Types
|
|
34
|
+
// =============================================================================
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Controls how query parameters are handled during matching.
|
|
38
|
+
*/
|
|
39
|
+
export type QueryParamsMode = "default" | "strict" | "loose";
|
|
40
|
+
|
|
41
|
+
// =============================================================================
|
|
42
|
+
// Route State Types
|
|
43
|
+
// =============================================================================
|
|
44
|
+
|
|
45
|
+
type ParamSource = "url" | "query";
|
|
46
|
+
type ParamTypeMap = Record<string, ParamSource>;
|
|
47
|
+
type RouteTreeStateMeta = Record<string, ParamTypeMap>;
|
|
48
|
+
|
|
49
|
+
export interface RouteParams {
|
|
50
|
+
[key: string]:
|
|
51
|
+
| string
|
|
52
|
+
| string[]
|
|
53
|
+
| number
|
|
54
|
+
| number[]
|
|
55
|
+
| boolean
|
|
56
|
+
| boolean[]
|
|
57
|
+
| RouteParams
|
|
58
|
+
| RouteParams[]
|
|
59
|
+
| Record<string, string | number | boolean>
|
|
60
|
+
| null
|
|
61
|
+
| undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Complete state representation of a matched route.
|
|
66
|
+
*/
|
|
67
|
+
export interface RouteTreeState<
|
|
68
|
+
P extends Record<string, unknown> = RouteParams,
|
|
69
|
+
> {
|
|
70
|
+
name: string;
|
|
71
|
+
params: P;
|
|
72
|
+
meta: RouteTreeStateMeta;
|
|
73
|
+
}
|
package/src/router.ts
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
// packages/core-types/modules/router.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base router types without Router class dependency.
|
|
5
|
+
*
|
|
6
|
+
* Router-dependent types (Route, RouteConfigUpdate, ActivationFnFactory,
|
|
7
|
+
* MiddlewareFactory, PluginFactory) are defined in @real-router/core
|
|
8
|
+
* to avoid circular dependencies.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
State,
|
|
13
|
+
Params,
|
|
14
|
+
NavigationOptions,
|
|
15
|
+
RouterError,
|
|
16
|
+
Unsubscribe,
|
|
17
|
+
} from "./base";
|
|
18
|
+
import type { LimitsConfig } from "./limits";
|
|
19
|
+
import type { QueryParamsMode, QueryParamsOptions } from "./route-node-types";
|
|
20
|
+
|
|
21
|
+
// Logger types (duplicated from @real-router/logger to avoid dependency)
|
|
22
|
+
type LogLevel = "log" | "warn" | "error";
|
|
23
|
+
type LogLevelConfig = "all" | "warn-error" | "error-only" | "none";
|
|
24
|
+
type LogCallback = (
|
|
25
|
+
level: LogLevel,
|
|
26
|
+
context: string,
|
|
27
|
+
message: string,
|
|
28
|
+
...args: unknown[]
|
|
29
|
+
) => void;
|
|
30
|
+
interface LoggerConfig {
|
|
31
|
+
level: LogLevelConfig;
|
|
32
|
+
callback?: LogCallback | undefined;
|
|
33
|
+
callbackIgnoresLevel?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Callback function for dynamically resolving the default route.
|
|
38
|
+
* Receives a dependency getter function to access router dependencies.
|
|
39
|
+
*/
|
|
40
|
+
export type DefaultRouteCallback<Dependencies = object> = (
|
|
41
|
+
getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],
|
|
42
|
+
) => string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Callback function for dynamically resolving the forward target route.
|
|
46
|
+
* Receives a dependency getter function and current route parameters.
|
|
47
|
+
*/
|
|
48
|
+
export type ForwardToCallback<Dependencies = object> = (
|
|
49
|
+
getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],
|
|
50
|
+
params: Params,
|
|
51
|
+
) => string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Callback function for dynamically resolving the default parameters.
|
|
55
|
+
* Receives a dependency getter function to access router dependencies.
|
|
56
|
+
*/
|
|
57
|
+
export type DefaultParamsCallback<Dependencies = object> = (
|
|
58
|
+
getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K],
|
|
59
|
+
) => Params;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Router configuration options.
|
|
63
|
+
*
|
|
64
|
+
* Note: For input, use `Partial<Options>` as all fields have defaults.
|
|
65
|
+
* After initialization, `getOptions()` returns resolved `Options` with all fields populated.
|
|
66
|
+
*/
|
|
67
|
+
export interface Options {
|
|
68
|
+
/**
|
|
69
|
+
* Default route to navigate to on start.
|
|
70
|
+
* Empty string means no default route.
|
|
71
|
+
*
|
|
72
|
+
* @default ""
|
|
73
|
+
*/
|
|
74
|
+
defaultRoute: string | DefaultRouteCallback;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Default parameters for the default route.
|
|
78
|
+
*
|
|
79
|
+
* @default {}
|
|
80
|
+
*/
|
|
81
|
+
defaultParams: Params | DefaultParamsCallback;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* How to handle trailing slashes in URLs.
|
|
85
|
+
* - "strict": Route must match exactly
|
|
86
|
+
* - "never": Always remove trailing slash
|
|
87
|
+
* - "always": Always add trailing slash
|
|
88
|
+
* - "preserve": Keep as provided
|
|
89
|
+
*
|
|
90
|
+
* @default "preserve"
|
|
91
|
+
*/
|
|
92
|
+
trailingSlash: "strict" | "never" | "always" | "preserve";
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* How to encode URL parameters.
|
|
96
|
+
* - "default": Standard encoding
|
|
97
|
+
* - "uri": URI encoding (encodeURI)
|
|
98
|
+
* - "uriComponent": Component encoding (encodeURIComponent)
|
|
99
|
+
* - "none": No encoding
|
|
100
|
+
*
|
|
101
|
+
* @default "default"
|
|
102
|
+
*/
|
|
103
|
+
urlParamsEncoding: "default" | "uri" | "uriComponent" | "none";
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* How to handle query parameters.
|
|
107
|
+
*
|
|
108
|
+
* @default "loose"
|
|
109
|
+
*/
|
|
110
|
+
queryParamsMode: QueryParamsMode;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Query parameter parsing options.
|
|
114
|
+
*
|
|
115
|
+
* @default undefined
|
|
116
|
+
*/
|
|
117
|
+
queryParams?: QueryParamsOptions;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Allow matching routes that don't exist.
|
|
121
|
+
* When true, unknown routes navigate without error.
|
|
122
|
+
*
|
|
123
|
+
* @default true
|
|
124
|
+
*/
|
|
125
|
+
allowNotFound: boolean;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Rewrite path on successful match.
|
|
129
|
+
*
|
|
130
|
+
* @default false
|
|
131
|
+
*/
|
|
132
|
+
rewritePathOnMatch: boolean;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Logger configuration.
|
|
136
|
+
*
|
|
137
|
+
* @default undefined
|
|
138
|
+
*/
|
|
139
|
+
logger?: Partial<LoggerConfig>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Router resource limits configuration.
|
|
143
|
+
* Controls maximum allowed values for various router operations.
|
|
144
|
+
*
|
|
145
|
+
* @default DEFAULT_LIMITS (from LimitsNamespace)
|
|
146
|
+
*/
|
|
147
|
+
limits?: Partial<LimitsConfig>;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Disables argument validation in public router methods.
|
|
151
|
+
* Use in production for performance. Keep false in development for early error detection.
|
|
152
|
+
*
|
|
153
|
+
* @default false
|
|
154
|
+
*/
|
|
155
|
+
noValidate?: boolean;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export type ActivationFn = (
|
|
159
|
+
toState: State,
|
|
160
|
+
fromState: State | undefined,
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
162
|
+
) => boolean | Promise<boolean | State | void> | State | void;
|
|
163
|
+
|
|
164
|
+
export type GuardFn = (
|
|
165
|
+
toState: State,
|
|
166
|
+
fromState: State | undefined,
|
|
167
|
+
) => boolean | Promise<boolean>;
|
|
168
|
+
|
|
169
|
+
export type DefaultDependencies = object;
|
|
170
|
+
|
|
171
|
+
export interface Config {
|
|
172
|
+
decoders: Record<string, (params: Params) => Params>;
|
|
173
|
+
encoders: Record<string, (params: Params) => Params>;
|
|
174
|
+
defaultParams: Record<string, Params>;
|
|
175
|
+
forwardMap: Record<string, string>;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface Plugin {
|
|
179
|
+
onStart?: () => void;
|
|
180
|
+
onStop?: () => void;
|
|
181
|
+
onTransitionStart?: (toState: State, fromState?: State) => void;
|
|
182
|
+
onTransitionCancel?: (toState: State, fromState?: State) => void;
|
|
183
|
+
onTransitionError?: (
|
|
184
|
+
toState: State | undefined,
|
|
185
|
+
fromState: State | undefined,
|
|
186
|
+
err: RouterError,
|
|
187
|
+
) => void;
|
|
188
|
+
onTransitionSuccess?: (
|
|
189
|
+
toState: State,
|
|
190
|
+
fromState: State | undefined,
|
|
191
|
+
opts: NavigationOptions,
|
|
192
|
+
) => void;
|
|
193
|
+
teardown?: () => void;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// eslint-disable-next-line sonarjs/redundant-type-aliases
|
|
197
|
+
export type Middleware = ActivationFn;
|
|
198
|
+
|
|
199
|
+
export interface SubscribeState {
|
|
200
|
+
route: State;
|
|
201
|
+
previousRoute?: State | undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export type SubscribeFn = (state: SubscribeState) => void;
|
|
205
|
+
|
|
206
|
+
export interface Listener {
|
|
207
|
+
[key: string]: unknown;
|
|
208
|
+
next: (val: unknown) => void;
|
|
209
|
+
error?: (err: unknown) => void;
|
|
210
|
+
complete?: () => void;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface Subscription {
|
|
214
|
+
unsubscribe: Unsubscribe;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Navigator interface - a minimal, safe subset of Router methods.
|
|
219
|
+
*
|
|
220
|
+
* Provides only the essential navigation and state inspection methods.
|
|
221
|
+
* Excludes lifecycle methods (start, stop), plugin management, and internal APIs.
|
|
222
|
+
* Use this when you need to pass a limited router interface to components.
|
|
223
|
+
*
|
|
224
|
+
* For full router access, use the Router interface directly or the useRouter() hook.
|
|
225
|
+
*/
|
|
226
|
+
export interface Navigator {
|
|
227
|
+
navigate: (
|
|
228
|
+
routeName: string,
|
|
229
|
+
routeParams?: Params,
|
|
230
|
+
options?: NavigationOptions,
|
|
231
|
+
) => Promise<State>;
|
|
232
|
+
getState: () => State | undefined;
|
|
233
|
+
isActiveRoute: (
|
|
234
|
+
name: string,
|
|
235
|
+
params?: Params,
|
|
236
|
+
strictEquality?: boolean,
|
|
237
|
+
ignoreQueryParams?: boolean,
|
|
238
|
+
) => boolean;
|
|
239
|
+
canNavigateTo: (name: string, params?: Params) => boolean;
|
|
240
|
+
subscribe: (listener: SubscribeFn) => Unsubscribe;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Router interface - public API for route navigation and lifecycle management.
|
|
245
|
+
*
|
|
246
|
+
* Defines the contract for router implementations. The actual Router class in
|
|
247
|
+
* @real-router/core implements this interface with full functionality.
|
|
248
|
+
*
|
|
249
|
+
* This interface uses `GuardFn | boolean` for guard types to avoid circular
|
|
250
|
+
* dependencies. The concrete Router class in @real-router/core narrows this to
|
|
251
|
+
* `GuardFnFactory | boolean` for more precise type checking.
|
|
252
|
+
*/
|
|
253
|
+
export interface Router {
|
|
254
|
+
/**
|
|
255
|
+
* Register an activation guard for a route.
|
|
256
|
+
*
|
|
257
|
+
* @param name - Route name
|
|
258
|
+
* @param guard - Guard function or boolean
|
|
259
|
+
* @returns this for method chaining
|
|
260
|
+
*/
|
|
261
|
+
addActivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Register a deactivation guard for a route.
|
|
265
|
+
*
|
|
266
|
+
* @param name - Route name
|
|
267
|
+
* @param guard - Guard function or boolean
|
|
268
|
+
* @returns this for method chaining
|
|
269
|
+
*/
|
|
270
|
+
addDeactivateGuard: (name: string, guard: GuardFn | boolean) => this;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Remove an activation guard from a route.
|
|
274
|
+
*
|
|
275
|
+
* @param name - Route name
|
|
276
|
+
*/
|
|
277
|
+
removeActivateGuard: (name: string) => void;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Remove a deactivation guard from a route.
|
|
281
|
+
*
|
|
282
|
+
* @param name - Route name
|
|
283
|
+
*/
|
|
284
|
+
removeDeactivateGuard: (name: string) => void;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Check if navigation to a route is allowed without performing actual navigation.
|
|
288
|
+
*
|
|
289
|
+
* Synchronously checks all activation and deactivation guards in the transition path.
|
|
290
|
+
* Async guards return false with a console warning.
|
|
291
|
+
*
|
|
292
|
+
* @param name - Route name to check
|
|
293
|
+
* @param params - Route parameters (optional)
|
|
294
|
+
* @returns true if navigation is allowed, false otherwise
|
|
295
|
+
*/
|
|
296
|
+
canNavigateTo: (name: string, params?: Params) => boolean;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Dispose the router and release all resources.
|
|
300
|
+
*
|
|
301
|
+
* Stops the router if active, calls plugin teardown, clears all event
|
|
302
|
+
* listeners, middleware, routes, and dependencies. After disposal, all
|
|
303
|
+
* mutating methods throw a ROUTER_DISPOSED error. Idempotent — safe to
|
|
304
|
+
* call multiple times.
|
|
305
|
+
*/
|
|
306
|
+
dispose: () => void;
|
|
307
|
+
}
|