@real-router/core 0.45.0 → 0.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/package.json +6 -7
  2. package/src/Router.ts +0 -684
  3. package/src/RouterError.ts +0 -324
  4. package/src/api/cloneRouter.ts +0 -77
  5. package/src/api/getDependenciesApi.ts +0 -168
  6. package/src/api/getLifecycleApi.ts +0 -65
  7. package/src/api/getPluginApi.ts +0 -167
  8. package/src/api/getRoutesApi.ts +0 -573
  9. package/src/api/helpers.ts +0 -10
  10. package/src/api/index.ts +0 -16
  11. package/src/api/types.ts +0 -12
  12. package/src/constants.ts +0 -87
  13. package/src/createRouter.ts +0 -32
  14. package/src/fsm/index.ts +0 -5
  15. package/src/fsm/routerFSM.ts +0 -120
  16. package/src/getNavigator.ts +0 -30
  17. package/src/guards.ts +0 -46
  18. package/src/helpers.ts +0 -179
  19. package/src/index.ts +0 -50
  20. package/src/internals.ts +0 -173
  21. package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +0 -30
  22. package/src/namespaces/DependenciesNamespace/index.ts +0 -5
  23. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +0 -311
  24. package/src/namespaces/EventBusNamespace/index.ts +0 -5
  25. package/src/namespaces/EventBusNamespace/types.ts +0 -11
  26. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -405
  27. package/src/namespaces/NavigationNamespace/constants.ts +0 -55
  28. package/src/namespaces/NavigationNamespace/index.ts +0 -5
  29. package/src/namespaces/NavigationNamespace/transition/completeTransition.ts +0 -100
  30. package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +0 -124
  31. package/src/namespaces/NavigationNamespace/transition/guardPhase.ts +0 -221
  32. package/src/namespaces/NavigationNamespace/types.ts +0 -100
  33. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +0 -28
  34. package/src/namespaces/OptionsNamespace/constants.ts +0 -19
  35. package/src/namespaces/OptionsNamespace/helpers.ts +0 -50
  36. package/src/namespaces/OptionsNamespace/index.ts +0 -7
  37. package/src/namespaces/OptionsNamespace/validators.ts +0 -13
  38. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +0 -291
  39. package/src/namespaces/PluginsNamespace/constants.ts +0 -34
  40. package/src/namespaces/PluginsNamespace/index.ts +0 -7
  41. package/src/namespaces/PluginsNamespace/types.ts +0 -22
  42. package/src/namespaces/PluginsNamespace/validators.ts +0 -28
  43. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +0 -377
  44. package/src/namespaces/RouteLifecycleNamespace/index.ts +0 -5
  45. package/src/namespaces/RouteLifecycleNamespace/types.ts +0 -10
  46. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -81
  47. package/src/namespaces/RouterLifecycleNamespace/constants.ts +0 -25
  48. package/src/namespaces/RouterLifecycleNamespace/index.ts +0 -5
  49. package/src/namespaces/RouterLifecycleNamespace/types.ts +0 -26
  50. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +0 -535
  51. package/src/namespaces/RoutesNamespace/constants.ts +0 -6
  52. package/src/namespaces/RoutesNamespace/forwardChain.ts +0 -34
  53. package/src/namespaces/RoutesNamespace/helpers.ts +0 -126
  54. package/src/namespaces/RoutesNamespace/index.ts +0 -11
  55. package/src/namespaces/RoutesNamespace/routeGuards.ts +0 -62
  56. package/src/namespaces/RoutesNamespace/routesStore.ts +0 -346
  57. package/src/namespaces/RoutesNamespace/types.ts +0 -81
  58. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -211
  59. package/src/namespaces/StateNamespace/helpers.ts +0 -24
  60. package/src/namespaces/StateNamespace/index.ts +0 -5
  61. package/src/namespaces/StateNamespace/types.ts +0 -15
  62. package/src/namespaces/index.ts +0 -35
  63. package/src/stateMetaStore.ts +0 -15
  64. package/src/transitionPath.ts +0 -436
  65. package/src/typeGuards.ts +0 -59
  66. package/src/types/RouterValidator.ts +0 -154
  67. package/src/types.ts +0 -69
  68. package/src/utils/getStaticPaths.ts +0 -50
  69. package/src/utils/index.ts +0 -5
  70. package/src/utils/serializeState.ts +0 -22
  71. package/src/validation.ts +0 -12
  72. package/src/wiring/RouterWiringBuilder.ts +0 -261
  73. package/src/wiring/index.ts +0 -7
  74. package/src/wiring/types.ts +0 -47
  75. package/src/wiring/wireRouter.ts +0 -26
@@ -1,324 +0,0 @@
1
- // packages/core/src/RouterError.ts
2
-
3
- import { errorCodes } from "./constants";
4
- import { deepFreezeState } from "./helpers";
5
-
6
- import type { State } from "@real-router/types";
7
-
8
- // Pre-compute Set of error code values for O(1) lookup in setCode()
9
- // This avoids creating array and doing linear search on every setCode() call
10
- const errorCodeValues = new Set(Object.values(errorCodes));
11
-
12
- // Reserved built-in properties - throw error if user tries to set these
13
- const reservedProperties = new Set(["code", "segment", "path", "redirect"]);
14
-
15
- // Reserved method names - silently ignore attempts to overwrite these
16
- const reservedMethods = new Set([
17
- "setCode",
18
- "setErrorInstance",
19
- "setAdditionalFields",
20
- "hasField",
21
- "getField",
22
- "toJSON",
23
- ]);
24
-
25
- export class RouterError extends Error {
26
- [key: string]: unknown;
27
-
28
- // Using public properties to ensure structural compatibility
29
- // with RouterError interface in core-types
30
- readonly segment: string | undefined;
31
- readonly path: string | undefined;
32
- readonly redirect: State | undefined;
33
-
34
- // Note: code appears to be writable but setCode() should be used
35
- // to properly update both code and message together
36
- code: string;
37
-
38
- /**
39
- * Creates a new RouterError instance.
40
- *
41
- * The options object accepts built-in fields (message, segment, path, redirect)
42
- * and any additional custom fields, which will all be attached to the error instance.
43
- *
44
- * @param code - The error code (e.g., "ROUTE_NOT_FOUND", "CANNOT_ACTIVATE")
45
- * @param options - Optional configuration object
46
- * @param options.message - Custom error message (defaults to code if not provided)
47
- * @param options.segment - The route segment where the error occurred
48
- * @param options.path - The full path where the error occurred
49
- * @param options.redirect - Optional redirect state for navigation errors
50
- *
51
- * @example
52
- * ```typescript
53
- * // Basic error
54
- * const err1 = new RouterError("ROUTE_NOT_FOUND");
55
- *
56
- * // Error with custom message
57
- * const err2 = new RouterError("ERR", { message: "Something went wrong" });
58
- *
59
- * // Error with context and custom fields
60
- * const err3 = new RouterError("CANNOT_ACTIVATE", {
61
- * message: "Insufficient permissions",
62
- * segment: "admin",
63
- * path: "/admin/users",
64
- * userId: "123" // custom field
65
- * });
66
- *
67
- * // Error with redirect
68
- * const err4 = new RouterError("TRANSITION_ERR", {
69
- * redirect: { name: "home", path: "/", params: {} }
70
- * });
71
- * ```
72
- */
73
- constructor(
74
- code: string,
75
- {
76
- message,
77
- segment,
78
- path,
79
- redirect,
80
- ...rest
81
- }: {
82
- [key: string]: unknown;
83
- message?: string | undefined;
84
- segment?: string | undefined;
85
- path?: string | undefined;
86
- redirect?: State | undefined;
87
- } = {},
88
- ) {
89
- super(message ?? code);
90
-
91
- this.code = code;
92
- this.segment = segment;
93
- this.path = path;
94
- // Deep freeze redirect to prevent mutations (creates a frozen clone)
95
- this.redirect = redirect ? deepFreezeState(redirect) : undefined;
96
-
97
- // Assign custom fields, checking reserved properties and filtering out reserved method names
98
- // Issue #39: Throw for reserved properties to match setAdditionalFields behavior
99
- for (const [key, value] of Object.entries(rest)) {
100
- if (reservedProperties.has(key)) {
101
- throw new TypeError(
102
- `[RouterError] Cannot set reserved property "${key}"`,
103
- );
104
- }
105
-
106
- if (!reservedMethods.has(key)) {
107
- this[key] = value;
108
- }
109
- }
110
- }
111
-
112
- /**
113
- * Updates the error code and conditionally updates the message.
114
- *
115
- * If the current message is one of the standard error code values
116
- * (e.g., "ROUTE_NOT_FOUND", "SAME_STATES"), it will be replaced with the new code.
117
- * This allows keeping error messages in sync with codes when using standard error codes.
118
- *
119
- * If the message is custom (not a standard error code), it will be preserved.
120
- *
121
- * @param newCode - The new error code to set
122
- *
123
- * @example
124
- * // Message follows code (standard error code as message)
125
- * const err = new RouterError("ROUTE_NOT_FOUND", { message: "ROUTE_NOT_FOUND" });
126
- * err.setCode("CUSTOM_ERROR"); // message becomes "CUSTOM_ERROR"
127
- *
128
- * @example
129
- * // Custom message is preserved
130
- * const err = new RouterError("ERR", { message: "Custom error message" });
131
- * err.setCode("NEW_CODE"); // message stays "Custom error message"
132
- */
133
- setCode(newCode: string): void {
134
- this.code = newCode;
135
-
136
- // Only update message if it's a standard error code value (not a custom message)
137
- if (errorCodeValues.has(this.message)) {
138
- this.message = newCode;
139
- }
140
- }
141
-
142
- /**
143
- * Copies properties from another Error instance to this RouterError.
144
- *
145
- * This method updates the message, cause, and stack trace from the provided error.
146
- * Useful for wrapping native errors while preserving error context.
147
- *
148
- * @param err - The Error instance to copy properties from
149
- * @throws {TypeError} If err is null or undefined
150
- *
151
- * @example
152
- * ```typescript
153
- * const routerErr = new RouterError("TRANSITION_ERR");
154
- * try {
155
- * // some operation that might fail
156
- * } catch (nativeErr) {
157
- * routerErr.setErrorInstance(nativeErr);
158
- * throw routerErr;
159
- * }
160
- * ```
161
- */
162
- setErrorInstance(err: Error): void {
163
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
164
- if (!err) {
165
- throw new TypeError(
166
- "[RouterError.setErrorInstance] err parameter is required and must be an Error instance",
167
- );
168
- }
169
-
170
- this.message = err.message;
171
- this.cause = err.cause;
172
- this.stack = err.stack ?? "";
173
- }
174
-
175
- /**
176
- * Adds custom fields to the error object.
177
- *
178
- * This method allows attaching arbitrary data to the error for debugging or logging purposes.
179
- * All fields become accessible as properties on the error instance and are included in JSON serialization.
180
- *
181
- * Reserved method names (setCode, setErrorInstance, setAdditionalFields, hasField, getField, toJSON)
182
- * are automatically filtered out to prevent accidental overwriting of class methods.
183
- *
184
- * @param fields - Object containing custom fields to add to the error
185
- *
186
- * @example
187
- * ```typescript
188
- * const err = new RouterError("CANNOT_ACTIVATE");
189
- * err.setAdditionalFields({
190
- * userId: "123",
191
- * attemptedRoute: "/admin",
192
- * reason: "insufficient permissions"
193
- * });
194
- *
195
- * console.log(err.userId); // "123"
196
- * console.log(JSON.stringify(err)); // includes all custom fields
197
- * ```
198
- */
199
- setAdditionalFields(fields: Record<string, unknown>): void {
200
- // Assign fields, throwing for reserved properties, silently ignoring methods
201
- for (const [key, value] of Object.entries(fields)) {
202
- if (reservedProperties.has(key)) {
203
- throw new TypeError(
204
- `[RouterError.setAdditionalFields] Cannot set reserved property "${key}"`,
205
- );
206
- }
207
-
208
- if (!reservedMethods.has(key)) {
209
- this[key] = value;
210
- }
211
- }
212
- }
213
-
214
- /**
215
- * Checks if a custom field exists on the error object.
216
- *
217
- * This method checks for both custom fields added via setAdditionalFields()
218
- * and built-in fields (code, message, segment, etc.).
219
- *
220
- * @param key - The field name to check
221
- * @returns `true` if the field exists, `false` otherwise
222
- *
223
- * @example
224
- * ```typescript
225
- * const err = new RouterError("ERR", { segment: "users" });
226
- * err.setAdditionalFields({ userId: "123" });
227
- *
228
- * err.hasField("userId"); // true
229
- * err.hasField("segment"); // true
230
- * err.hasField("unknown"); // false
231
- * ```
232
- */
233
- hasField(key: string): boolean {
234
- return key in this;
235
- }
236
-
237
- /**
238
- * Retrieves a custom field value from the error object.
239
- *
240
- * This method can access both custom fields and built-in fields.
241
- * Returns `undefined` if the field doesn't exist.
242
- *
243
- * @param key - The field name to retrieve
244
- * @returns The field value, or `undefined` if it doesn't exist
245
- *
246
- * @example
247
- * ```typescript
248
- * const err = new RouterError("ERR");
249
- * err.setAdditionalFields({ userId: "123", role: "admin" });
250
- *
251
- * err.getField("userId"); // "123"
252
- * err.getField("role"); // "admin"
253
- * err.getField("code"); // "ERR" (built-in field)
254
- * err.getField("unknown"); // undefined
255
- * ```
256
- */
257
- getField(key: string): unknown {
258
- return this[key];
259
- }
260
-
261
- /**
262
- * Serializes the error to a JSON-compatible object.
263
- *
264
- * This method is automatically called by JSON.stringify() and includes:
265
- * - Built-in fields: code, message, segment (if set), path (if set), redirect (if set)
266
- * - All custom fields added via setAdditionalFields() or constructor
267
- * - Excludes: stack trace (for security/cleanliness)
268
- *
269
- * @returns A plain object representation of the error, suitable for JSON serialization
270
- *
271
- * @example
272
- * ```typescript
273
- * const err = new RouterError("ROUTE_NOT_FOUND", {
274
- * message: "Route not found",
275
- * path: "/admin/users/123"
276
- * });
277
- * err.setAdditionalFields({ userId: "123" });
278
- *
279
- * JSON.stringify(err);
280
- * // {
281
- * // "code": "ROUTE_NOT_FOUND",
282
- * // "message": "Route not found",
283
- * // "path": "/admin/users/123",
284
- * // "userId": "123"
285
- * // }
286
- * ```
287
- */
288
- toJSON(): Record<string, unknown> {
289
- const result: Record<string, unknown> = {
290
- code: this.code,
291
- message: this.message,
292
- };
293
-
294
- if (this.segment !== undefined) {
295
- result.segment = this.segment;
296
- }
297
- if (this.path !== undefined) {
298
- result.path = this.path;
299
- }
300
- if (this.redirect !== undefined) {
301
- result.redirect = this.redirect;
302
- }
303
-
304
- // add all public fields
305
- // Using Set.has() for O(1) lookup instead of Array.includes() O(n)
306
- // Overall complexity: O(n) instead of O(n*m)
307
- const excludeKeys = new Set([
308
- "code",
309
- "message",
310
- "segment",
311
- "path",
312
- "redirect",
313
- "stack",
314
- ]);
315
-
316
- for (const key in this) {
317
- if (Object.hasOwn(this, key) && !excludeKeys.has(key)) {
318
- result[key] = this[key];
319
- }
320
- }
321
-
322
- return result;
323
- }
324
- }
@@ -1,77 +0,0 @@
1
- import { routeTreeToDefinitions } from "route-tree";
2
-
3
- import { errorCodes } from "../constants";
4
- import { getInternals } from "../internals";
5
- import { Router as RouterClass } from "../Router";
6
- import { RouterError } from "../RouterError";
7
- import { getLifecycleApi } from "./getLifecycleApi";
8
-
9
- import type { Route } from "../types";
10
- import type { DefaultDependencies, Router } from "@real-router/types";
11
-
12
- export function cloneRouter<
13
- Dependencies extends DefaultDependencies = DefaultDependencies,
14
- >(
15
- router: Router<Dependencies>,
16
- dependencies?: Dependencies,
17
- ): RouterClass<Dependencies> {
18
- const ctx = getInternals(router);
19
-
20
- if (ctx.isDisposed()) {
21
- throw new RouterError(errorCodes.ROUTER_DISPOSED);
22
- }
23
-
24
- ctx.validator?.dependencies.validateCloneArgs(dependencies);
25
-
26
- // Get source store directly
27
- const sourceStore = ctx.routeGetStore();
28
- const routes = routeTreeToDefinitions(sourceStore.tree);
29
- const routeConfig = sourceStore.config;
30
- const resolvedForwardMap = sourceStore.resolvedForwardMap;
31
- const routeCustomFields = sourceStore.routeCustomFields;
32
-
33
- const options = ctx.cloneOptions();
34
- const sourceDeps = ctx.cloneDependencies();
35
- const [canDeactivateFactories, canActivateFactories] =
36
- ctx.getLifecycleFactories();
37
- const pluginFactories = ctx.getPluginFactories();
38
-
39
- const mergedDeps = {
40
- ...sourceDeps,
41
- ...dependencies,
42
- } as Dependencies;
43
-
44
- const newRouter = new RouterClass<Dependencies>(
45
- routes as Route<Dependencies>[],
46
- options,
47
- mergedDeps,
48
- );
49
-
50
- const lifecycle = getLifecycleApi(newRouter);
51
-
52
- for (const [name, handler] of Object.entries(canDeactivateFactories)) {
53
- lifecycle.addDeactivateGuard(name, handler);
54
- }
55
-
56
- for (const [name, handler] of Object.entries(canActivateFactories)) {
57
- lifecycle.addActivateGuard(name, handler);
58
- }
59
-
60
- if (pluginFactories.length > 0) {
61
- newRouter.usePlugin(...pluginFactories);
62
- }
63
-
64
- const newCtx = getInternals(newRouter);
65
- const newStore = newCtx.routeGetStore();
66
-
67
- // Apply cloned config directly to new store
68
- Object.assign(newStore.config.decoders, routeConfig.decoders);
69
- Object.assign(newStore.config.encoders, routeConfig.encoders);
70
- Object.assign(newStore.config.defaultParams, routeConfig.defaultParams);
71
- Object.assign(newStore.config.forwardMap, routeConfig.forwardMap);
72
- Object.assign(newStore.config.forwardFnMap, routeConfig.forwardFnMap);
73
- Object.assign(newStore.resolvedForwardMap, resolvedForwardMap);
74
- Object.assign(newStore.routeCustomFields, routeCustomFields);
75
-
76
- return newRouter;
77
- }
@@ -1,168 +0,0 @@
1
- import { throwIfDisposed } from "./helpers";
2
- import { getInternals } from "../internals";
3
-
4
- import type { DependenciesApi } from "./types";
5
- import type { DependenciesStore } from "../namespaces";
6
- import type { RouterValidator } from "../types/RouterValidator";
7
- import type { DefaultDependencies, Router } from "@real-router/types";
8
-
9
- // =============================================================================
10
- // Module-private CRUD functions
11
- // =============================================================================
12
-
13
- function setDependency(
14
- store: DependenciesStore,
15
- dependencyName: string,
16
- dependencyValue: unknown,
17
- validator?: RouterValidator | null,
18
- ): boolean {
19
- // undefined = "don't set" (feature for conditional setting)
20
- if (dependencyValue === undefined) {
21
- return false;
22
- }
23
-
24
- const isNewKey = !Object.hasOwn(store.dependencies, dependencyName);
25
-
26
- if (isNewKey) {
27
- // Only check limit when adding new keys (overwrites don't increase count)
28
- validator?.dependencies.validateDependencyCount(store, "setDependency");
29
- } else {
30
- const oldValue = (store.dependencies as Record<string, unknown>)[
31
- dependencyName
32
- ];
33
- const isChanging = oldValue !== dependencyValue;
34
- // Special case for NaN idempotency (NaN !== NaN is always true)
35
- const bothAreNaN = Number.isNaN(oldValue) && Number.isNaN(dependencyValue);
36
-
37
- if (isChanging && !bothAreNaN) {
38
- validator?.dependencies.warnOverwrite(dependencyName, "setDependency");
39
- }
40
- }
41
-
42
- (store.dependencies as Record<string, unknown>)[dependencyName] =
43
- dependencyValue;
44
-
45
- return true;
46
- }
47
-
48
- function setMultipleDependencies(
49
- store: DependenciesStore,
50
- deps: Record<string, unknown>,
51
- validator?: RouterValidator | null,
52
- ): void {
53
- const overwrittenKeys: string[] = [];
54
-
55
- for (const key in deps) {
56
- if (deps[key] !== undefined) {
57
- if (Object.hasOwn(store.dependencies, key)) {
58
- overwrittenKeys.push(key);
59
- } else {
60
- validator?.dependencies.validateDependencyCount(
61
- store,
62
- "setDependencies",
63
- );
64
- }
65
-
66
- (store.dependencies as Record<string, unknown>)[key] = deps[key];
67
- }
68
- }
69
-
70
- if (overwrittenKeys.length > 0) {
71
- validator?.dependencies.warnBatchOverwrite(
72
- overwrittenKeys,
73
- "setDependencies",
74
- );
75
- }
76
- }
77
-
78
- // =============================================================================
79
- // Public API factory
80
- // =============================================================================
81
-
82
- export function getDependenciesApi<
83
- Dependencies extends DefaultDependencies = DefaultDependencies,
84
- >(router: Router<Dependencies>): DependenciesApi<Dependencies> {
85
- const ctx = getInternals(router);
86
-
87
- return {
88
- get: (name) => {
89
- ctx.validator?.dependencies.validateDependencyName(name, "getDependency");
90
-
91
- const store = ctx.dependenciesGetStore();
92
- const value = (store.dependencies as Record<string, unknown>)[
93
- name as string
94
- ];
95
-
96
- ctx.validator?.dependencies.validateDependencyExists(
97
- name as string,
98
- store,
99
- );
100
-
101
- return value as Dependencies[typeof name];
102
- },
103
- getAll: () => ({ ...ctx.dependenciesGetStore().dependencies }),
104
- set: (name, value) => {
105
- throwIfDisposed(ctx.isDisposed);
106
-
107
- ctx.validator?.dependencies.validateSetDependencyArgs(
108
- name,
109
- value,
110
- "setDependency",
111
- );
112
-
113
- setDependency(
114
- ctx.dependenciesGetStore(),
115
- name as string,
116
- value,
117
- ctx.validator,
118
- );
119
- },
120
- setAll: (deps) => {
121
- throwIfDisposed(ctx.isDisposed);
122
-
123
- const store = ctx.dependenciesGetStore();
124
-
125
- ctx.validator?.dependencies.validateDependenciesObject(
126
- deps,
127
- "setDependencies",
128
- );
129
- ctx.validator?.dependencies.validateDependencyLimit(store, store.limits);
130
-
131
- setMultipleDependencies(
132
- store,
133
- deps as Record<string, unknown>,
134
- ctx.validator,
135
- );
136
- },
137
- remove: (name) => {
138
- throwIfDisposed(ctx.isDisposed);
139
-
140
- ctx.validator?.dependencies.validateDependencyName(
141
- name,
142
- "removeDependency",
143
- );
144
-
145
- const store = ctx.dependenciesGetStore();
146
-
147
- if (!Object.hasOwn(store.dependencies, name as string)) {
148
- ctx.validator?.dependencies.warnRemoveNonExistent(name);
149
- }
150
-
151
- delete (store.dependencies as Record<string, unknown>)[name as string];
152
- },
153
- reset: () => {
154
- throwIfDisposed(ctx.isDisposed);
155
- const store = ctx.dependenciesGetStore();
156
-
157
- store.dependencies = Object.create(null) as Partial<Dependencies>;
158
- },
159
- has: (name) => {
160
- ctx.validator?.dependencies.validateDependencyName(name, "hasDependency");
161
-
162
- return Object.hasOwn(
163
- ctx.dependenciesGetStore().dependencies,
164
- name as string,
165
- );
166
- },
167
- };
168
- }
@@ -1,65 +0,0 @@
1
- import { throwIfDisposed } from "./helpers";
2
- import { getInternals } from "../internals";
3
-
4
- import type { LifecycleApi } from "./types";
5
- import type { DefaultDependencies, Router } from "@real-router/types";
6
-
7
- export function getLifecycleApi<
8
- Dependencies extends DefaultDependencies = DefaultDependencies,
9
- >(router: Router<Dependencies>): LifecycleApi<Dependencies> {
10
- const ctx = getInternals(router);
11
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
12
- const lifecycleNamespace = ctx.routeGetStore().lifecycleNamespace!;
13
-
14
- return {
15
- addActivateGuard(name, handler) {
16
- throwIfDisposed(ctx.isDisposed);
17
-
18
- ctx.validator?.routes.validateRouteName(name, "addActivateGuard");
19
- ctx.validator?.lifecycle.validateHandler(handler, "addActivateGuard");
20
-
21
- const activateCount = lifecycleNamespace.getHandlerCount("activate");
22
-
23
- ctx.validator?.lifecycle.validateHandlerLimit(
24
- activateCount,
25
- ctx.dependenciesGetStore().limits,
26
- "canActivate",
27
- );
28
-
29
- lifecycleNamespace.addCanActivate(name, handler);
30
- },
31
-
32
- addDeactivateGuard(name, handler) {
33
- throwIfDisposed(ctx.isDisposed);
34
-
35
- ctx.validator?.routes.validateRouteName(name, "addDeactivateGuard");
36
- ctx.validator?.lifecycle.validateHandler(handler, "addDeactivateGuard");
37
-
38
- const deactivateCount = lifecycleNamespace.getHandlerCount("deactivate");
39
-
40
- ctx.validator?.lifecycle.validateHandlerLimit(
41
- deactivateCount,
42
- ctx.dependenciesGetStore().limits,
43
- "canDeactivate",
44
- );
45
-
46
- lifecycleNamespace.addCanDeactivate(name, handler);
47
- },
48
-
49
- removeActivateGuard(name) {
50
- throwIfDisposed(ctx.isDisposed);
51
-
52
- ctx.validator?.routes.validateRouteName(name, "removeActivateGuard");
53
-
54
- lifecycleNamespace.clearCanActivate(name);
55
- },
56
-
57
- removeDeactivateGuard(name) {
58
- throwIfDisposed(ctx.isDisposed);
59
-
60
- ctx.validator?.routes.validateRouteName(name, "removeDeactivateGuard");
61
-
62
- lifecycleNamespace.clearCanDeactivate(name);
63
- },
64
- };
65
- }