@real-router/core 0.35.0 → 0.35.2
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.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/metafile-cjs.json +1 -1
- 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 +1 -1
- package/src/Router.ts +8 -27
- package/src/api/getDependenciesApi.ts +2 -9
- package/src/api/getLifecycleApi.ts +1 -8
- package/src/api/getPluginApi.ts +1 -6
- package/src/api/getRoutesApi.ts +3 -11
- package/src/api/helpers.ts +10 -0
- package/src/getNavigator.ts +18 -8
- package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +14 -20
- package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +25 -60
- package/src/namespaces/NavigationNamespace/index.ts +1 -1
- package/src/namespaces/NavigationNamespace/transition/index.ts +5 -2
- package/src/namespaces/NavigationNamespace/types.ts +19 -28
- package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +1 -9
- package/src/namespaces/PluginsNamespace/types.ts +2 -12
- package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +32 -58
- package/src/namespaces/RouteLifecycleNamespace/types.ts +3 -10
- package/src/wiring/RouterWiringBuilder.ts +50 -33
|
@@ -11,13 +11,8 @@ import {
|
|
|
11
11
|
import { errorCodes, constants } from "../../constants";
|
|
12
12
|
import { RouterError } from "../../RouterError";
|
|
13
13
|
import { nameToIDs } from "../../transitionPath";
|
|
14
|
-
import { resolveOption } from "../OptionsNamespace";
|
|
15
14
|
|
|
16
|
-
import type {
|
|
17
|
-
NavigationDependencies,
|
|
18
|
-
TransitionDependencies,
|
|
19
|
-
TransitionOutput,
|
|
20
|
-
} from "./types";
|
|
15
|
+
import type { NavigationDependencies, TransitionOutput } from "./types";
|
|
21
16
|
import type {
|
|
22
17
|
NavigationOptions,
|
|
23
18
|
Params,
|
|
@@ -63,15 +58,7 @@ function routeTransitionError(
|
|
|
63
58
|
return;
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
routerError.code === errorCodes.CANNOT_ACTIVATE ||
|
|
69
|
-
routerError.code === errorCodes.CANNOT_DEACTIVATE
|
|
70
|
-
) {
|
|
71
|
-
deps.sendTransitionBlocked(toState, fromState, routerError);
|
|
72
|
-
} else {
|
|
73
|
-
deps.sendTransitionError(toState, fromState, routerError);
|
|
74
|
-
}
|
|
61
|
+
deps.sendTransitionFail(toState, fromState, routerError);
|
|
75
62
|
}
|
|
76
63
|
|
|
77
64
|
function buildSuccessState(
|
|
@@ -106,9 +93,7 @@ function buildSuccessState(
|
|
|
106
93
|
* Handles navigate(), navigateToDefault(), navigateToNotFound(), and transition state.
|
|
107
94
|
*/
|
|
108
95
|
export class NavigationNamespace {
|
|
109
|
-
#canNavigate!: () => boolean;
|
|
110
96
|
#deps!: NavigationDependencies;
|
|
111
|
-
#transitionDeps!: TransitionDependencies;
|
|
112
97
|
#currentController: AbortController | null = null;
|
|
113
98
|
|
|
114
99
|
// =========================================================================
|
|
@@ -135,26 +120,10 @@ export class NavigationNamespace {
|
|
|
135
120
|
// Dependency injection
|
|
136
121
|
// =========================================================================
|
|
137
122
|
|
|
138
|
-
setCanNavigate(fn: () => boolean): void {
|
|
139
|
-
this.#canNavigate = fn;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Sets dependencies for navigation operations.
|
|
144
|
-
* Must be called before using navigation methods.
|
|
145
|
-
*/
|
|
146
123
|
setDependencies(deps: NavigationDependencies): void {
|
|
147
124
|
this.#deps = deps;
|
|
148
125
|
}
|
|
149
126
|
|
|
150
|
-
/**
|
|
151
|
-
* Sets dependencies for transition operations.
|
|
152
|
-
* Must be called before using navigation methods.
|
|
153
|
-
*/
|
|
154
|
-
setTransitionDependencies(deps: TransitionDependencies): void {
|
|
155
|
-
this.#transitionDeps = deps;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
127
|
// =========================================================================
|
|
159
128
|
// Instance methods
|
|
160
129
|
// =========================================================================
|
|
@@ -168,7 +137,7 @@ export class NavigationNamespace {
|
|
|
168
137
|
params: Params,
|
|
169
138
|
opts: NavigationOptions,
|
|
170
139
|
): Promise<State> {
|
|
171
|
-
if (!this.#canNavigate()) {
|
|
140
|
+
if (!this.#deps.canNavigate()) {
|
|
172
141
|
throw new RouterError(errorCodes.ROUTER_NOT_STARTED);
|
|
173
142
|
}
|
|
174
143
|
|
|
@@ -212,19 +181,7 @@ export class NavigationNamespace {
|
|
|
212
181
|
throw err;
|
|
213
182
|
}
|
|
214
183
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (transitionDeps.isTransitioning()) {
|
|
218
|
-
logger.warn(
|
|
219
|
-
"router.navigate",
|
|
220
|
-
"Concurrent navigation detected on shared router instance. " +
|
|
221
|
-
"For SSR, use cloneRouter() to create isolated instance per request.",
|
|
222
|
-
);
|
|
223
|
-
this.#currentController?.abort(
|
|
224
|
-
new RouterError(errorCodes.TRANSITION_CANCELLED),
|
|
225
|
-
);
|
|
226
|
-
deps.cancelNavigation();
|
|
227
|
-
}
|
|
184
|
+
this.#abortPreviousNavigation();
|
|
228
185
|
|
|
229
186
|
const controller = new AbortController();
|
|
230
187
|
|
|
@@ -252,7 +209,7 @@ export class NavigationNamespace {
|
|
|
252
209
|
|
|
253
210
|
try {
|
|
254
211
|
const { state: finalState, meta: transitionOutput } = await transition(
|
|
255
|
-
|
|
212
|
+
deps,
|
|
256
213
|
toState,
|
|
257
214
|
fromState,
|
|
258
215
|
opts,
|
|
@@ -283,7 +240,7 @@ export class NavigationNamespace {
|
|
|
283
240
|
routeName: finalState.name,
|
|
284
241
|
});
|
|
285
242
|
|
|
286
|
-
deps.
|
|
243
|
+
deps.sendTransitionFail(finalState, fromState, err);
|
|
287
244
|
|
|
288
245
|
throw err;
|
|
289
246
|
}
|
|
@@ -313,26 +270,20 @@ export class NavigationNamespace {
|
|
|
313
270
|
});
|
|
314
271
|
}
|
|
315
272
|
|
|
316
|
-
const
|
|
317
|
-
options.defaultRoute,
|
|
318
|
-
deps.getDependency,
|
|
319
|
-
);
|
|
273
|
+
const { route, params } = deps.resolveDefault();
|
|
320
274
|
|
|
321
|
-
if (!
|
|
275
|
+
if (!route) {
|
|
322
276
|
throw new RouterError(errorCodes.ROUTE_NOT_FOUND, {
|
|
323
277
|
routeName: "defaultRoute resolved to empty",
|
|
324
278
|
});
|
|
325
279
|
}
|
|
326
280
|
|
|
327
|
-
|
|
328
|
-
options.defaultParams,
|
|
329
|
-
deps.getDependency,
|
|
330
|
-
);
|
|
331
|
-
|
|
332
|
-
return this.navigate(resolvedRoute, resolvedParams, opts);
|
|
281
|
+
return this.navigate(route, params, opts);
|
|
333
282
|
}
|
|
334
283
|
|
|
335
284
|
navigateToNotFound(path: string): State {
|
|
285
|
+
this.#abortPreviousNavigation();
|
|
286
|
+
|
|
336
287
|
const fromState = this.#deps.getState();
|
|
337
288
|
const deactivated: string[] = fromState
|
|
338
289
|
? nameToIDs(fromState.name).toReversed()
|
|
@@ -378,4 +329,18 @@ export class NavigationNamespace {
|
|
|
378
329
|
);
|
|
379
330
|
this.#currentController = null;
|
|
380
331
|
}
|
|
332
|
+
|
|
333
|
+
#abortPreviousNavigation(): void {
|
|
334
|
+
if (this.#deps.isTransitioning()) {
|
|
335
|
+
logger.warn(
|
|
336
|
+
"router.navigate",
|
|
337
|
+
"Concurrent navigation detected on shared router instance. " +
|
|
338
|
+
"For SSR, use cloneRouter() to create isolated instance per request.",
|
|
339
|
+
);
|
|
340
|
+
this.#currentController?.abort(
|
|
341
|
+
new RouterError(errorCodes.TRANSITION_CANCELLED),
|
|
342
|
+
);
|
|
343
|
+
this.#deps.cancelNavigation();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
381
346
|
}
|
|
@@ -5,11 +5,14 @@ import { constants, errorCodes } from "../../../constants";
|
|
|
5
5
|
import { RouterError } from "../../../RouterError";
|
|
6
6
|
import { getTransitionPath } from "../../../transitionPath";
|
|
7
7
|
|
|
8
|
-
import type {
|
|
8
|
+
import type { NavigationDependencies, TransitionOutput } from "../types";
|
|
9
9
|
import type { NavigationOptions, State } from "@real-router/types";
|
|
10
10
|
|
|
11
11
|
export async function transition(
|
|
12
|
-
deps:
|
|
12
|
+
deps: Pick<
|
|
13
|
+
NavigationDependencies,
|
|
14
|
+
"getLifecycleFunctions" | "isActive" | "clearCanDeactivate"
|
|
15
|
+
>,
|
|
13
16
|
toState: State,
|
|
14
17
|
fromState: State | undefined,
|
|
15
18
|
opts: NavigationOptions,
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
*
|
|
17
17
|
* These are function references from other namespaces/facade,
|
|
18
18
|
* avoiding the need to pass the entire Router object.
|
|
19
|
-
|
|
19
|
+
**/
|
|
20
20
|
export interface NavigationDependencies {
|
|
21
21
|
/** Get router options */
|
|
22
22
|
getOptions: () => Options;
|
|
@@ -54,8 +54,8 @@ export interface NavigationDependencies {
|
|
|
54
54
|
ignoreQueryParams?: boolean,
|
|
55
55
|
) => boolean;
|
|
56
56
|
|
|
57
|
-
/**
|
|
58
|
-
|
|
57
|
+
/** Resolve defaultRoute and defaultParams options (static value or callback) */
|
|
58
|
+
resolveDefault: () => { route: string; params: Params };
|
|
59
59
|
|
|
60
60
|
/** Start transition and send NAVIGATE event to routerFSM */
|
|
61
61
|
startTransition: (toState: State, fromState: State | undefined) => void;
|
|
@@ -70,15 +70,8 @@ export interface NavigationDependencies {
|
|
|
70
70
|
opts: NavigationOptions,
|
|
71
71
|
) => void;
|
|
72
72
|
|
|
73
|
-
/** Send FAIL event to routerFSM
|
|
74
|
-
|
|
75
|
-
toState: State,
|
|
76
|
-
fromState: State | undefined,
|
|
77
|
-
error: unknown,
|
|
78
|
-
) => void;
|
|
79
|
-
|
|
80
|
-
/** Send FAIL event to routerFSM (transition error) */
|
|
81
|
-
sendTransitionError: (
|
|
73
|
+
/** Send FAIL event to routerFSM */
|
|
74
|
+
sendTransitionFail: (
|
|
82
75
|
toState: State,
|
|
83
76
|
fromState: State | undefined,
|
|
84
77
|
error: unknown,
|
|
@@ -97,24 +90,10 @@ export interface NavigationDependencies {
|
|
|
97
90
|
fromState?: State,
|
|
98
91
|
opts?: NavigationOptions,
|
|
99
92
|
) => void;
|
|
100
|
-
}
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
meta: {
|
|
105
|
-
phase: TransitionPhase;
|
|
106
|
-
segments: {
|
|
107
|
-
deactivated: string[];
|
|
108
|
-
activated: string[];
|
|
109
|
-
intersection: string;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
112
|
-
}
|
|
94
|
+
/** Check if navigation can begin (router is started) */
|
|
95
|
+
canNavigate: () => boolean;
|
|
113
96
|
|
|
114
|
-
/**
|
|
115
|
-
* Dependencies required for the transition function.
|
|
116
|
-
*/
|
|
117
|
-
export interface TransitionDependencies {
|
|
118
97
|
/** Get lifecycle functions (canDeactivate, canActivate maps) */
|
|
119
98
|
getLifecycleFunctions: () => [Map<string, GuardFn>, Map<string, GuardFn>];
|
|
120
99
|
|
|
@@ -127,3 +106,15 @@ export interface TransitionDependencies {
|
|
|
127
106
|
/** Clear canDeactivate guard for a route */
|
|
128
107
|
clearCanDeactivate: (name: string) => void;
|
|
129
108
|
}
|
|
109
|
+
|
|
110
|
+
export interface TransitionOutput {
|
|
111
|
+
state: State;
|
|
112
|
+
meta: {
|
|
113
|
+
phase: TransitionPhase;
|
|
114
|
+
segments: {
|
|
115
|
+
deactivated: string[];
|
|
116
|
+
activated: string[];
|
|
117
|
+
intersection: string;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -12,7 +12,6 @@ import { DEFAULT_LIMITS } from "../../constants";
|
|
|
12
12
|
import { computeThresholds } from "../../helpers";
|
|
13
13
|
|
|
14
14
|
import type { PluginsDependencies } from "./types";
|
|
15
|
-
import type { Router } from "../../Router";
|
|
16
15
|
import type { Limits, PluginFactory } from "../../types";
|
|
17
16
|
import type {
|
|
18
17
|
DefaultDependencies,
|
|
@@ -32,7 +31,6 @@ export class PluginsNamespace<
|
|
|
32
31
|
readonly #plugins = new Set<PluginFactory<Dependencies>>();
|
|
33
32
|
readonly #unsubscribes = new Set<Unsubscribe>();
|
|
34
33
|
|
|
35
|
-
#router!: Router<Dependencies>;
|
|
36
34
|
#deps!: PluginsDependencies<Dependencies>;
|
|
37
35
|
#limits: Limits = DEFAULT_LIMITS;
|
|
38
36
|
|
|
@@ -77,10 +75,6 @@ export class PluginsNamespace<
|
|
|
77
75
|
// Dependency injection
|
|
78
76
|
// =========================================================================
|
|
79
77
|
|
|
80
|
-
setRouter(router: Router<Dependencies>): void {
|
|
81
|
-
this.#router = router;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
78
|
setDependencies(deps: PluginsDependencies<Dependencies>): void {
|
|
85
79
|
this.#deps = deps;
|
|
86
80
|
}
|
|
@@ -289,9 +283,7 @@ export class PluginsNamespace<
|
|
|
289
283
|
}
|
|
290
284
|
|
|
291
285
|
#startPlugin(pluginFactory: PluginFactory<Dependencies>): Unsubscribe {
|
|
292
|
-
|
|
293
|
-
// Plugin factories receive full router as part of their public API
|
|
294
|
-
const appliedPlugin = pluginFactory(this.#router, this.#deps.getDependency);
|
|
286
|
+
const appliedPlugin = this.#deps.compileFactory(pluginFactory);
|
|
295
287
|
|
|
296
288
|
PluginsNamespace.validatePlugin(appliedPlugin);
|
|
297
289
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// packages/core/src/namespaces/PluginsNamespace/types.ts
|
|
2
2
|
|
|
3
|
-
import type { EventMethodMap } from "../../types";
|
|
3
|
+
import type { EventMethodMap, PluginFactory } from "../../types";
|
|
4
4
|
import type {
|
|
5
5
|
DefaultDependencies,
|
|
6
6
|
EventName,
|
|
@@ -8,25 +8,15 @@ import type {
|
|
|
8
8
|
Unsubscribe,
|
|
9
9
|
} from "@real-router/types";
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Dependencies injected into PluginsNamespace.
|
|
13
|
-
*
|
|
14
|
-
* Note: Plugin factories still receive the router object directly
|
|
15
|
-
* as they need access to various router methods. This interface
|
|
16
|
-
* only covers the internal namespace operations.
|
|
17
|
-
*/
|
|
18
11
|
export interface PluginsDependencies<
|
|
19
12
|
Dependencies extends DefaultDependencies = DefaultDependencies,
|
|
20
13
|
> {
|
|
21
|
-
/** Add event listener for plugin subscription */
|
|
22
14
|
addEventListener: <E extends EventName>(
|
|
23
15
|
eventName: E,
|
|
24
16
|
cb: Plugin[EventMethodMap[E]],
|
|
25
17
|
) => Unsubscribe;
|
|
26
18
|
|
|
27
|
-
/** Check if navigation is possible (for warning about late onStart) */
|
|
28
19
|
canNavigate: () => boolean;
|
|
29
20
|
|
|
30
|
-
|
|
31
|
-
getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K];
|
|
21
|
+
compileFactory: (factory: PluginFactory<Dependencies>) => Plugin;
|
|
32
22
|
}
|
|
@@ -8,7 +8,6 @@ import { DEFAULT_LIMITS } from "../../constants";
|
|
|
8
8
|
import { computeThresholds } from "../../helpers";
|
|
9
9
|
|
|
10
10
|
import type { RouteLifecycleDependencies } from "./types";
|
|
11
|
-
import type { Router } from "../../Router";
|
|
12
11
|
import type { GuardFnFactory, Limits } from "../../types";
|
|
13
12
|
import type { DefaultDependencies, GuardFn, State } from "@real-router/types";
|
|
14
13
|
|
|
@@ -48,24 +47,9 @@ export class RouteLifecycleNamespace<
|
|
|
48
47
|
readonly #definitionActivateGuardNames = new Set<string>();
|
|
49
48
|
readonly #definitionDeactivateGuardNames = new Set<string>();
|
|
50
49
|
|
|
51
|
-
#router!: Router<Dependencies>;
|
|
52
50
|
#deps!: RouteLifecycleDependencies<Dependencies>;
|
|
53
51
|
#limits: Limits = DEFAULT_LIMITS;
|
|
54
52
|
|
|
55
|
-
/**
|
|
56
|
-
* Injects the router instance during wiring phase.
|
|
57
|
-
*
|
|
58
|
-
* @param router - Router instance to use for factory compilation
|
|
59
|
-
*/
|
|
60
|
-
setRouter(router: Router<Dependencies>): void {
|
|
61
|
-
this.#router = router;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Injects namespace dependencies (getDependency accessor) during wiring phase.
|
|
66
|
-
*
|
|
67
|
-
* @param deps - Dependencies object containing getDependency accessor
|
|
68
|
-
*/
|
|
69
53
|
setDependencies(deps: RouteLifecycleDependencies<Dependencies>): void {
|
|
70
54
|
this.#deps = deps;
|
|
71
55
|
}
|
|
@@ -268,50 +252,41 @@ export class RouteLifecycleNamespace<
|
|
|
268
252
|
return [this.#canDeactivateFunctions, this.#canActivateFunctions];
|
|
269
253
|
}
|
|
270
254
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
* Returns `false` if the guard blocks, returns a Promise, or throws.
|
|
275
|
-
*
|
|
276
|
-
* @param name - Route name to check the guard for
|
|
277
|
-
* @param toState - Target navigation state
|
|
278
|
-
* @param fromState - Current state (`undefined` on initial navigation)
|
|
279
|
-
*/
|
|
280
|
-
checkActivateGuardSync(
|
|
281
|
-
name: string,
|
|
255
|
+
canNavigateTo(
|
|
256
|
+
toDeactivate: string[],
|
|
257
|
+
toActivate: string[],
|
|
282
258
|
toState: State,
|
|
283
259
|
fromState: State | undefined,
|
|
284
260
|
): boolean {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
261
|
+
for (const segment of toDeactivate) {
|
|
262
|
+
if (
|
|
263
|
+
!this.#checkGuardSync(
|
|
264
|
+
this.#canDeactivateFunctions,
|
|
265
|
+
segment,
|
|
266
|
+
toState,
|
|
267
|
+
fromState,
|
|
268
|
+
"canNavigateTo",
|
|
269
|
+
)
|
|
270
|
+
) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
293
274
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
return
|
|
309
|
-
this.#canDeactivateFunctions,
|
|
310
|
-
name,
|
|
311
|
-
toState,
|
|
312
|
-
fromState,
|
|
313
|
-
"checkDeactivateGuardSync",
|
|
314
|
-
);
|
|
275
|
+
for (const segment of toActivate) {
|
|
276
|
+
if (
|
|
277
|
+
!this.#checkGuardSync(
|
|
278
|
+
this.#canActivateFunctions,
|
|
279
|
+
segment,
|
|
280
|
+
toState,
|
|
281
|
+
fromState,
|
|
282
|
+
"canNavigateTo",
|
|
283
|
+
)
|
|
284
|
+
) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return true;
|
|
315
290
|
}
|
|
316
291
|
|
|
317
292
|
// =========================================================================
|
|
@@ -361,8 +336,7 @@ export class RouteLifecycleNamespace<
|
|
|
361
336
|
this.#registering.add(name);
|
|
362
337
|
|
|
363
338
|
try {
|
|
364
|
-
|
|
365
|
-
const fn = factory(this.#router, this.#deps.getDependency);
|
|
339
|
+
const fn = this.#deps.compileFactory(factory);
|
|
366
340
|
|
|
367
341
|
if (typeof fn !== "function") {
|
|
368
342
|
throw new TypeError(
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
// packages/core/src/namespaces/RouteLifecycleNamespace/types.ts
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type { GuardFnFactory } from "../../types";
|
|
4
|
+
import type { DefaultDependencies, GuardFn } from "@real-router/types";
|
|
4
5
|
|
|
5
|
-
/**
|
|
6
|
-
* Dependencies injected into RouteLifecycleNamespace.
|
|
7
|
-
*
|
|
8
|
-
* Note: Lifecycle factories still receive the router object directly
|
|
9
|
-
* as they need access to various router methods. This interface
|
|
10
|
-
* only covers the internal namespace operations.
|
|
11
|
-
*/
|
|
12
6
|
export interface RouteLifecycleDependencies<
|
|
13
7
|
Dependencies extends DefaultDependencies = DefaultDependencies,
|
|
14
8
|
> {
|
|
15
|
-
|
|
16
|
-
getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K];
|
|
9
|
+
compileFactory: (factory: GuardFnFactory<Dependencies>) => GuardFn;
|
|
17
10
|
}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
// packages/core/src/wiring/RouterWiringBuilder.ts
|
|
2
2
|
|
|
3
3
|
import { getInternals } from "../internals";
|
|
4
|
+
import { resolveOption } from "../namespaces/OptionsNamespace";
|
|
4
5
|
import { validateStateBuilderArgs } from "../namespaces/RoutesNamespace/validators";
|
|
5
6
|
|
|
6
7
|
import type { EventBusNamespace } from "../namespaces";
|
|
7
8
|
import type { WiringOptions } from "./types";
|
|
8
|
-
import type {
|
|
9
|
-
NavigationDependencies,
|
|
10
|
-
TransitionDependencies,
|
|
11
|
-
} from "../namespaces/NavigationNamespace";
|
|
9
|
+
import type { NavigationDependencies } from "../namespaces/NavigationNamespace";
|
|
12
10
|
import type { PluginsDependencies } from "../namespaces/PluginsNamespace";
|
|
13
11
|
import type { RouteLifecycleDependencies } from "../namespaces/RouteLifecycleNamespace";
|
|
14
12
|
import type { RouterLifecycleDependencies } from "../namespaces/RouterLifecycleNamespace";
|
|
@@ -56,11 +54,8 @@ export class RouterWiringBuilder<
|
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
wireRouteLifecycleDeps(): void {
|
|
59
|
-
this.routeLifecycle.setRouter(this.router);
|
|
60
|
-
|
|
61
57
|
const routeLifecycleDeps: RouteLifecycleDependencies<Dependencies> = {
|
|
62
|
-
|
|
63
|
-
this.dependenciesStore.dependencies[dependencyName] as Dependencies[K],
|
|
58
|
+
compileFactory: this.createCompileFactory(),
|
|
64
59
|
};
|
|
65
60
|
|
|
66
61
|
this.routeLifecycle.setDependencies(routeLifecycleDeps);
|
|
@@ -97,14 +92,11 @@ export class RouterWiringBuilder<
|
|
|
97
92
|
}
|
|
98
93
|
|
|
99
94
|
wirePluginsDeps(): void {
|
|
100
|
-
this.plugins.setRouter(this.router);
|
|
101
|
-
|
|
102
95
|
const pluginsDeps: PluginsDependencies<Dependencies> = {
|
|
103
96
|
addEventListener: (eventName, cb) =>
|
|
104
97
|
this.eventBus.addEventListener(eventName, cb),
|
|
105
98
|
canNavigate: () => this.eventBus.canBeginTransition(),
|
|
106
|
-
|
|
107
|
-
this.dependenciesStore.dependencies[dependencyName] as Dependencies[K],
|
|
99
|
+
compileFactory: this.createCompileFactory(),
|
|
108
100
|
};
|
|
109
101
|
|
|
110
102
|
this.plugins.setDependencies(pluginsDeps);
|
|
@@ -141,47 +133,54 @@ export class RouterWiringBuilder<
|
|
|
141
133
|
},
|
|
142
134
|
areStatesEqual: (state1, state2, ignoreQueryParams) =>
|
|
143
135
|
this.state.areStatesEqual(state1, state2, ignoreQueryParams),
|
|
144
|
-
|
|
145
|
-
this.
|
|
136
|
+
resolveDefault: () => {
|
|
137
|
+
const options = this.options.get();
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
route: resolveOption(
|
|
141
|
+
options.defaultRoute,
|
|
142
|
+
(name: string) =>
|
|
143
|
+
this.dependenciesStore.dependencies[name as keyof Dependencies],
|
|
144
|
+
),
|
|
145
|
+
params: resolveOption(
|
|
146
|
+
options.defaultParams,
|
|
147
|
+
/* v8 ignore next -- @preserve: unreachable unless defaultParams is a callback that calls getDependency */
|
|
148
|
+
(name: string) =>
|
|
149
|
+
this.dependenciesStore.dependencies[name as keyof Dependencies],
|
|
150
|
+
),
|
|
151
|
+
};
|
|
152
|
+
},
|
|
146
153
|
startTransition: (toState, fromState) => {
|
|
147
|
-
this.eventBus.
|
|
154
|
+
this.eventBus.sendNavigate(toState, fromState);
|
|
148
155
|
},
|
|
149
156
|
cancelNavigation: () => {
|
|
150
|
-
this.eventBus.
|
|
157
|
+
this.eventBus.sendCancel(
|
|
151
158
|
this.eventBus.getCurrentToState()!, // eslint-disable-line @typescript-eslint/no-non-null-assertion -- guaranteed set before TRANSITIONING
|
|
152
159
|
this.state.get(),
|
|
153
160
|
);
|
|
154
161
|
},
|
|
155
162
|
sendTransitionDone: (state, fromState, opts) => {
|
|
156
|
-
this.eventBus.
|
|
163
|
+
this.eventBus.sendComplete(state, fromState, opts);
|
|
157
164
|
},
|
|
158
|
-
|
|
159
|
-
this.eventBus.
|
|
160
|
-
},
|
|
161
|
-
sendTransitionError: (toState, fromState, error) => {
|
|
162
|
-
this.eventBus.failTransition(toState, fromState, error);
|
|
165
|
+
sendTransitionFail: (toState, fromState, error) => {
|
|
166
|
+
this.eventBus.sendFail(toState, fromState, error);
|
|
163
167
|
},
|
|
164
168
|
emitTransitionError: (toState, fromState, error) => {
|
|
165
|
-
this.eventBus.
|
|
169
|
+
this.eventBus.sendFailSafe(toState, fromState, error);
|
|
166
170
|
},
|
|
167
171
|
emitTransitionSuccess: (toState, fromState, opts) => {
|
|
168
172
|
this.eventBus.emitTransitionSuccess(toState, fromState, opts);
|
|
169
173
|
},
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this.navigation.setDependencies(navigationDeps);
|
|
173
|
-
this.navigation.setCanNavigate(() => this.eventBus.canBeginTransition());
|
|
174
|
-
|
|
175
|
-
const transitionDeps: TransitionDependencies = {
|
|
174
|
+
canNavigate: () => this.eventBus.canBeginTransition(),
|
|
176
175
|
getLifecycleFunctions: () => this.routeLifecycle.getFunctions(),
|
|
177
176
|
isActive: () => this.router.isActive(),
|
|
178
177
|
isTransitioning: () => this.eventBus.isTransitioning(),
|
|
179
|
-
clearCanDeactivate: (name) => {
|
|
178
|
+
clearCanDeactivate: (name: string) => {
|
|
180
179
|
this.routeLifecycle.clearCanDeactivate(name);
|
|
181
180
|
},
|
|
182
181
|
};
|
|
183
182
|
|
|
184
|
-
this.navigation.
|
|
183
|
+
this.navigation.setDependencies(navigationDeps);
|
|
185
184
|
}
|
|
186
185
|
|
|
187
186
|
wireLifecycleDeps(): void {
|
|
@@ -195,10 +194,10 @@ export class RouterWiringBuilder<
|
|
|
195
194
|
},
|
|
196
195
|
matchPath: (path) => this.routes.matchPath(path, this.options.get()),
|
|
197
196
|
completeStart: () => {
|
|
198
|
-
this.eventBus.
|
|
197
|
+
this.eventBus.sendStarted();
|
|
199
198
|
},
|
|
200
199
|
emitTransitionError: (toState, fromState, error) => {
|
|
201
|
-
this.eventBus.
|
|
200
|
+
this.eventBus.sendFail(toState, fromState, error);
|
|
202
201
|
},
|
|
203
202
|
};
|
|
204
203
|
|
|
@@ -216,4 +215,22 @@ export class RouterWiringBuilder<
|
|
|
216
215
|
getUrlParams: (name) => this.routes.getUrlParams(name),
|
|
217
216
|
});
|
|
218
217
|
}
|
|
218
|
+
|
|
219
|
+
private createCompileFactory() {
|
|
220
|
+
const { router, dependenciesStore } = this;
|
|
221
|
+
|
|
222
|
+
return <T>(
|
|
223
|
+
factory: (
|
|
224
|
+
router: WiringOptions<Dependencies>["router"],
|
|
225
|
+
getDependency: <K extends keyof Dependencies>(
|
|
226
|
+
name: K,
|
|
227
|
+
) => Dependencies[K],
|
|
228
|
+
) => T,
|
|
229
|
+
): T =>
|
|
230
|
+
factory(
|
|
231
|
+
router,
|
|
232
|
+
<K extends keyof Dependencies>(name: K) =>
|
|
233
|
+
dependenciesStore.dependencies[name] as Dependencies[K],
|
|
234
|
+
);
|
|
235
|
+
}
|
|
219
236
|
}
|