@real-router/core 0.55.0 → 0.57.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.
Files changed (145) hide show
  1. package/dist/cjs/Router-BSGzVINO.js +6 -0
  2. package/dist/cjs/Router-BSGzVINO.js.map +1 -0
  3. package/dist/{esm/Router-Dg-zk8AS.d.mts → cjs/Router-hW6ivqrX.d.ts} +2 -2
  4. package/dist/cjs/Router-hW6ivqrX.d.ts.map +1 -0
  5. package/dist/cjs/api.d.ts +2 -2
  6. package/dist/cjs/api.d.ts.map +1 -1
  7. package/dist/cjs/api.js +1 -1
  8. package/dist/cjs/api.js.map +1 -1
  9. package/dist/cjs/{cloneRouter-C9Rth_8U.js → cloneRouter-7z-60z_f.js} +2 -2
  10. package/dist/cjs/{cloneRouter-C9Rth_8U.js.map → cloneRouter-7z-60z_f.js.map} +1 -1
  11. package/dist/cjs/{index-C-i6vx5Y.d.ts → index-BWUmnecT.d.ts} +1 -2
  12. package/dist/cjs/index-BWUmnecT.d.ts.map +1 -0
  13. package/dist/cjs/{RouterError-WhCzIWuc.d.ts → index-CYpAZCoc.d.ts} +19 -2
  14. package/dist/cjs/index-CYpAZCoc.d.ts.map +1 -0
  15. package/dist/cjs/{index-K1U_fqfJ.d.ts → index-D2WRiyWS.d.ts} +2 -2
  16. package/dist/cjs/index-D2WRiyWS.d.ts.map +1 -0
  17. package/dist/cjs/index.d.ts +5 -5
  18. package/dist/cjs/index.js +1 -1
  19. package/dist/cjs/{internals-CWMOL1B8.js → internals-DJjgSePy.js} +2 -2
  20. package/dist/cjs/internals-DJjgSePy.js.map +1 -0
  21. package/dist/cjs/utils.d.ts +1 -1
  22. package/dist/cjs/utils.js +1 -1
  23. package/dist/cjs/utils.js.map +1 -1
  24. package/dist/cjs/validation.d.ts +17 -5
  25. package/dist/cjs/validation.d.ts.map +1 -1
  26. package/dist/cjs/validation.js +1 -1
  27. package/dist/esm/Router-B7txWo9N.mjs +6 -0
  28. package/dist/esm/Router-B7txWo9N.mjs.map +1 -0
  29. package/dist/{cjs/Router-Dg-zk8AS.d.ts → esm/Router-hW6ivqrX.d.mts} +2 -2
  30. package/dist/esm/Router-hW6ivqrX.d.mts.map +1 -0
  31. package/dist/esm/api.d.mts +2 -2
  32. package/dist/esm/api.d.mts.map +1 -1
  33. package/dist/esm/api.mjs +1 -1
  34. package/dist/esm/api.mjs.map +1 -1
  35. package/dist/esm/{cloneRouter-BYNiwchg.mjs → cloneRouter-BNCQ7tIa.mjs} +2 -2
  36. package/dist/esm/{cloneRouter-BYNiwchg.mjs.map → cloneRouter-BNCQ7tIa.mjs.map} +1 -1
  37. package/dist/esm/{index-C-i6vx5Y.d.mts → index-BWUmnecT.d.mts} +1 -2
  38. package/dist/esm/index-BWUmnecT.d.mts.map +1 -0
  39. package/dist/esm/{RouterError-WhCzIWuc.d.mts → index-CYpAZCoc.d.mts} +19 -2
  40. package/dist/esm/index-CYpAZCoc.d.mts.map +1 -0
  41. package/dist/esm/{index-DKzxav48.d.mts → index-CjWKWPY6.d.mts} +2 -2
  42. package/dist/esm/index-CjWKWPY6.d.mts.map +1 -0
  43. package/dist/esm/index.d.mts +5 -5
  44. package/dist/esm/index.mjs +1 -1
  45. package/dist/esm/index.mjs.map +1 -1
  46. package/dist/esm/{internals-DT4mneSz.mjs → internals-C8mRvTxc.mjs} +2 -2
  47. package/dist/esm/internals-C8mRvTxc.mjs.map +1 -0
  48. package/dist/esm/utils.d.mts +1 -1
  49. package/dist/esm/utils.mjs +1 -1
  50. package/dist/esm/utils.mjs.map +1 -1
  51. package/dist/esm/validation.d.mts +17 -5
  52. package/dist/esm/validation.d.mts.map +1 -1
  53. package/dist/esm/validation.mjs +1 -1
  54. package/package.json +3 -4
  55. package/dist/cjs/Router-C7eE1kIK.js +0 -6
  56. package/dist/cjs/Router-C7eE1kIK.js.map +0 -1
  57. package/dist/cjs/Router-Dg-zk8AS.d.ts.map +0 -1
  58. package/dist/cjs/RouterError-WhCzIWuc.d.ts.map +0 -1
  59. package/dist/cjs/index-C-i6vx5Y.d.ts.map +0 -1
  60. package/dist/cjs/index-K1U_fqfJ.d.ts.map +0 -1
  61. package/dist/cjs/internals-CWMOL1B8.js.map +0 -1
  62. package/dist/esm/Router-Dg-zk8AS.d.mts.map +0 -1
  63. package/dist/esm/Router-DiZbYMLx.mjs +0 -6
  64. package/dist/esm/Router-DiZbYMLx.mjs.map +0 -1
  65. package/dist/esm/RouterError-WhCzIWuc.d.mts.map +0 -1
  66. package/dist/esm/index-C-i6vx5Y.d.mts.map +0 -1
  67. package/dist/esm/index-DKzxav48.d.mts.map +0 -1
  68. package/dist/esm/internals-DT4mneSz.mjs.map +0 -1
  69. package/src/Router.ts +0 -725
  70. package/src/RouterError.ts +0 -324
  71. package/src/api/cloneRouter.ts +0 -159
  72. package/src/api/getDependenciesApi.ts +0 -160
  73. package/src/api/getLifecycleApi.ts +0 -65
  74. package/src/api/getPluginApi.ts +0 -228
  75. package/src/api/getRoutesApi.ts +0 -546
  76. package/src/api/helpers.ts +0 -10
  77. package/src/api/index.ts +0 -16
  78. package/src/api/types.ts +0 -12
  79. package/src/constants.ts +0 -101
  80. package/src/createRouter.ts +0 -32
  81. package/src/fsm/index.ts +0 -5
  82. package/src/fsm/routerFSM.ts +0 -130
  83. package/src/getNavigator.ts +0 -30
  84. package/src/guards.ts +0 -46
  85. package/src/helpers.ts +0 -197
  86. package/src/index.ts +0 -50
  87. package/src/internals.ts +0 -200
  88. package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +0 -30
  89. package/src/namespaces/DependenciesNamespace/index.ts +0 -5
  90. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +0 -485
  91. package/src/namespaces/EventBusNamespace/index.ts +0 -5
  92. package/src/namespaces/EventBusNamespace/types.ts +0 -11
  93. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -552
  94. package/src/namespaces/NavigationNamespace/constants.ts +0 -55
  95. package/src/namespaces/NavigationNamespace/index.ts +0 -5
  96. package/src/namespaces/NavigationNamespace/transition/completeTransition.ts +0 -108
  97. package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +0 -124
  98. package/src/namespaces/NavigationNamespace/transition/guardPhase.ts +0 -283
  99. package/src/namespaces/NavigationNamespace/types.ts +0 -110
  100. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +0 -28
  101. package/src/namespaces/OptionsNamespace/constants.ts +0 -19
  102. package/src/namespaces/OptionsNamespace/helpers.ts +0 -50
  103. package/src/namespaces/OptionsNamespace/index.ts +0 -7
  104. package/src/namespaces/OptionsNamespace/validators.ts +0 -13
  105. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +0 -291
  106. package/src/namespaces/PluginsNamespace/constants.ts +0 -34
  107. package/src/namespaces/PluginsNamespace/index.ts +0 -7
  108. package/src/namespaces/PluginsNamespace/types.ts +0 -22
  109. package/src/namespaces/PluginsNamespace/validators.ts +0 -28
  110. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +0 -558
  111. package/src/namespaces/RouteLifecycleNamespace/index.ts +0 -5
  112. package/src/namespaces/RouteLifecycleNamespace/types.ts +0 -10
  113. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -81
  114. package/src/namespaces/RouterLifecycleNamespace/constants.ts +0 -25
  115. package/src/namespaces/RouterLifecycleNamespace/index.ts +0 -5
  116. package/src/namespaces/RouterLifecycleNamespace/types.ts +0 -30
  117. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +0 -582
  118. package/src/namespaces/RoutesNamespace/constants.ts +0 -6
  119. package/src/namespaces/RoutesNamespace/forwardChain.ts +0 -34
  120. package/src/namespaces/RoutesNamespace/helpers.ts +0 -204
  121. package/src/namespaces/RoutesNamespace/index.ts +0 -11
  122. package/src/namespaces/RoutesNamespace/routeGuards.ts +0 -62
  123. package/src/namespaces/RoutesNamespace/routesStore.ts +0 -566
  124. package/src/namespaces/RoutesNamespace/types.ts +0 -81
  125. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -224
  126. package/src/namespaces/StateNamespace/helpers.ts +0 -24
  127. package/src/namespaces/StateNamespace/index.ts +0 -5
  128. package/src/namespaces/StateNamespace/types.ts +0 -15
  129. package/src/namespaces/index.ts +0 -35
  130. package/src/stateMetaStore.ts +0 -15
  131. package/src/transitionPath.ts +0 -436
  132. package/src/typeGuards.ts +0 -59
  133. package/src/types/RouterValidator.ts +0 -156
  134. package/src/types.ts +0 -69
  135. package/src/utils/createRequestScope.ts +0 -174
  136. package/src/utils/getStaticPaths.ts +0 -50
  137. package/src/utils/hydrateRouter.ts +0 -89
  138. package/src/utils/index.ts +0 -27
  139. package/src/utils/serializeRouterState.ts +0 -120
  140. package/src/utils/serializeState.ts +0 -63
  141. package/src/validation.ts +0 -12
  142. package/src/wiring/RouterWiringBuilder.ts +0 -275
  143. package/src/wiring/index.ts +0 -7
  144. package/src/wiring/types.ts +0 -47
  145. package/src/wiring/wireRouter.ts +0 -26
@@ -1,546 +0,0 @@
1
- import { logger } from "@real-router/logger";
2
-
3
- import { throwIfDisposed } from "./helpers";
4
- import { guardRouteStructure } from "../guards";
5
- import { createInterceptable, getInternals } from "../internals";
6
- import {
7
- clearConfigEntries,
8
- removeFromDefinitions,
9
- } from "../namespaces/RoutesNamespace/helpers";
10
- import {
11
- validateClearRoutes,
12
- validateRemoveRoute,
13
- } from "../namespaces/RoutesNamespace/routeGuards";
14
- import {
15
- adoptRouteArtifacts,
16
- assertAddable,
17
- buildAddArtifacts,
18
- buildReplaceArtifacts,
19
- refreshForwardMap,
20
- } from "../namespaces/RoutesNamespace/routesStore";
21
-
22
- import type { RoutesApi } from "./types";
23
- import type { RouterInternals } from "../internals";
24
- import type { RouteLifecycleNamespace, RouteConfig } from "../namespaces";
25
- import type { RoutesStore } from "../namespaces/RoutesNamespace";
26
- import type { GuardFnFactory, Route } from "../types";
27
- import type {
28
- DefaultDependencies,
29
- ForwardToCallback,
30
- Params,
31
- Router,
32
- TransitionMeta,
33
- } from "@real-router/types";
34
- import type { RouteDefinition, RouteTree } from "route-tree";
35
-
36
- // ============================================================================
37
- // Helpers
38
- // ============================================================================
39
-
40
- /**
41
- * Clears all config entries and lifecycle handlers for a removed route
42
- * (and all its descendants).
43
- */
44
- function clearRouteConfigurations<
45
- Dependencies extends DefaultDependencies = DefaultDependencies,
46
- >(
47
- routeName: string,
48
- config: RouteConfig,
49
- routeCustomFields: Record<string, Record<string, unknown>>,
50
- lifecycleNamespace: RouteLifecycleNamespace<Dependencies>,
51
- ): void {
52
- const shouldClear = (name: string): boolean =>
53
- name === routeName || name.startsWith(`${routeName}.`);
54
-
55
- clearConfigEntries(config.decoders, shouldClear);
56
- clearConfigEntries(config.encoders, shouldClear);
57
- clearConfigEntries(config.defaultParams, shouldClear);
58
- clearConfigEntries(config.forwardMap, shouldClear);
59
- clearConfigEntries(config.forwardFnMap, shouldClear);
60
- clearConfigEntries(routeCustomFields, shouldClear);
61
-
62
- // Clear forwardMap entries pointing TO the deleted route (or its descendants)
63
- clearConfigEntries(config.forwardMap, (key) =>
64
- shouldClear(config.forwardMap[key]),
65
- );
66
-
67
- // Clear lifecycle handlers
68
- const [canDeactivateFactories, canActivateFactories] =
69
- lifecycleNamespace.getFactories();
70
-
71
- for (const name of Object.keys(canActivateFactories)) {
72
- if (shouldClear(name)) {
73
- lifecycleNamespace.clearCanActivate(name);
74
- }
75
- }
76
-
77
- for (const name of Object.keys(canDeactivateFactories)) {
78
- if (shouldClear(name)) {
79
- lifecycleNamespace.clearCanDeactivate(name);
80
- }
81
- }
82
- }
83
-
84
- /**
85
- * Updates forwardTo for a route in config and returns the refreshed resolved
86
- * forward map (REPLACE semantics — caller must call ctx.setResolvedForwardMap).
87
- */
88
- function updateForwardTo<
89
- Dependencies extends DefaultDependencies = DefaultDependencies,
90
- >(
91
- name: string,
92
- forwardTo: string | ForwardToCallback<Dependencies> | null,
93
- config: RouteConfig,
94
- ): Record<string, string> {
95
- // Prepare-then-commit (issue #698): apply the change to CLONES of the forward
96
- // maps, resolve the chain (a cycle throws here), and only then swap the clones
97
- // in — so a rejected update never leaves config.forwardMap poisoned.
98
- const forwardMap = Object.assign(
99
- Object.create(null) as RouteConfig["forwardMap"],
100
- config.forwardMap,
101
- );
102
- const forwardFnMap = Object.assign(
103
- Object.create(null) as RouteConfig["forwardFnMap"],
104
- config.forwardFnMap,
105
- );
106
-
107
- if (forwardTo === null) {
108
- delete forwardMap[name];
109
- delete forwardFnMap[name];
110
- } else if (typeof forwardTo === "string") {
111
- delete forwardFnMap[name];
112
- forwardMap[name] = forwardTo;
113
- } else {
114
- delete forwardMap[name];
115
- forwardFnMap[name] = forwardTo;
116
- }
117
-
118
- const resolved = refreshForwardMap({ ...config, forwardMap });
119
-
120
- config.forwardMap = forwardMap;
121
- config.forwardFnMap = forwardFnMap;
122
-
123
- return resolved;
124
- }
125
-
126
- /**
127
- * Builds a full Route object from a bare RouteDefinition by re-attaching
128
- * config entries and lifecycle factories.
129
- *
130
- * RECURSIVE — call with the factories tuple obtained ONCE from
131
- * `lifecycleNamespace.getFactories()` and pass it through to children.
132
- */
133
- function enrichRoute<
134
- Dependencies extends DefaultDependencies = DefaultDependencies,
135
- >(
136
- routeDef: RouteDefinition,
137
- routeName: string,
138
- config: RouteConfig,
139
- factories: [
140
- Record<string, GuardFnFactory<Dependencies>>,
141
- Record<string, GuardFnFactory<Dependencies>>,
142
- ],
143
- ): Route<Dependencies> {
144
- const route: Route<Dependencies> = {
145
- name: routeDef.name,
146
- path: routeDef.path,
147
- };
148
-
149
- const forwardToFn = config.forwardFnMap[routeName];
150
- const forwardToStr = config.forwardMap[routeName];
151
-
152
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
153
- if (forwardToFn !== undefined) {
154
- route.forwardTo = forwardToFn;
155
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
156
- } else if (forwardToStr !== undefined) {
157
- route.forwardTo = forwardToStr;
158
- }
159
-
160
- if (routeName in config.defaultParams) {
161
- route.defaultParams = config.defaultParams[routeName];
162
- }
163
-
164
- if (routeName in config.decoders) {
165
- route.decodeParams = config.decoders[routeName];
166
- }
167
-
168
- if (routeName in config.encoders) {
169
- route.encodeParams = config.encoders[routeName];
170
- }
171
-
172
- const [canDeactivateFactories, canActivateFactories] = factories;
173
-
174
- if (routeName in canActivateFactories) {
175
- route.canActivate = canActivateFactories[routeName];
176
- }
177
-
178
- if (routeName in canDeactivateFactories) {
179
- route.canDeactivate = canDeactivateFactories[routeName];
180
- }
181
-
182
- if (routeDef.children) {
183
- route.children = routeDef.children.map((child) =>
184
- enrichRoute(child, `${routeName}.${child.name}`, config, factories),
185
- );
186
- }
187
-
188
- return route;
189
- }
190
-
191
- // ============================================================================
192
- // CRUD operations
193
- // ============================================================================
194
-
195
- /**
196
- * Adds one or more routes to the router.
197
- * Input already validated by facade.
198
- */
199
- function addRoutes<
200
- Dependencies extends DefaultDependencies = DefaultDependencies,
201
- >(
202
- store: RoutesStore<Dependencies>,
203
- routes: Route<Dependencies>[],
204
- parentName?: string,
205
- ): void {
206
- // Prepare-then-commit (issue #698): reject the silent-corruption cases
207
- // up front (dup name vs existing, missing parent), build the merged tree /
208
- // config into locals (async/circular forwardTo + invalid constraint throw
209
- // here), then swap atomically. A rejected add leaves the store untouched.
210
- assertAddable(store, routes, parentName);
211
- adoptRouteArtifacts(store, buildAddArtifacts(store, routes, parentName));
212
- }
213
-
214
- /**
215
- * Atomically replaces all routes with a new set (HMR / code-splitting).
216
- * Prepare-then-commit (issue #698): the new set is fully built into locals
217
- * first — a circular/async forwardTo or invalid path throws here, leaving the
218
- * existing tree intact — then committed.
219
- */
220
- function replaceRoutes<
221
- Dependencies extends DefaultDependencies = DefaultDependencies,
222
- >(
223
- store: RoutesStore<Dependencies>,
224
- routes: Route<Dependencies>[],
225
- ctx: RouterInternals<Dependencies>,
226
- currentPath: string | undefined,
227
- previousTransition: TransitionMeta | undefined,
228
- ): void {
229
- // Build the whole new set BEFORE touching the store.
230
- const artifacts = buildReplaceArtifacts(
231
- routes,
232
- store.rootPath,
233
- store.matcherOptions,
234
- );
235
-
236
- // Clear definition lifecycle handlers (preserve external guards), then swap.
237
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
238
- store.lifecycleNamespace!.clearDefinitionGuards();
239
- adoptRouteArtifacts(store, artifacts);
240
-
241
- // Revalidate state (preserve transition from previous state)
242
- if (currentPath !== undefined) {
243
- const revalidated = ctx.matchPath(currentPath, ctx.getOptions());
244
-
245
- if (revalidated) {
246
- ctx.setState({
247
- ...revalidated,
248
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- previousTransition is guaranteed defined: currentPath is only set when getState() returned a state, which always has transition
249
- transition: previousTransition!,
250
- });
251
- } else {
252
- ctx.clearState();
253
- }
254
- }
255
- }
256
-
257
- /**
258
- * Removes a route and all its children.
259
- *
260
- * @returns true if removed, false if not found
261
- */
262
- function removeRoute<
263
- Dependencies extends DefaultDependencies = DefaultDependencies,
264
- >(store: RoutesStore<Dependencies>, name: string): boolean {
265
- const wasRemoved = removeFromDefinitions(store.definitions, name);
266
-
267
- if (!wasRemoved) {
268
- return false;
269
- }
270
-
271
- clearRouteConfigurations(
272
- name,
273
- store.config,
274
- store.routeCustomFields,
275
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
276
- store.lifecycleNamespace!,
277
- );
278
-
279
- store.treeOperations.commitTreeChanges(store);
280
-
281
- return true;
282
- }
283
-
284
- /**
285
- * Updates a route's configuration in place.
286
- */
287
- function updateRouteConfig<
288
- Dependencies extends DefaultDependencies = DefaultDependencies,
289
- >(
290
- store: RoutesStore<Dependencies>,
291
- name: string,
292
- updates: {
293
- forwardTo?: string | ForwardToCallback<Dependencies> | null | undefined;
294
- defaultParams?: Params | null | undefined;
295
- decodeParams?: ((params: Params) => Params) | null | undefined;
296
- encodeParams?: ((params: Params) => Params) | null | undefined;
297
- },
298
- ): void {
299
- if (updates.forwardTo !== undefined) {
300
- store.resolvedForwardMap = updateForwardTo(
301
- name,
302
- updates.forwardTo,
303
- store.config,
304
- );
305
- }
306
-
307
- if (updates.defaultParams !== undefined) {
308
- if (updates.defaultParams === null) {
309
- delete store.config.defaultParams[name];
310
- } else {
311
- store.config.defaultParams[name] = updates.defaultParams;
312
- }
313
- }
314
-
315
- if (updates.decodeParams !== undefined) {
316
- if (updates.decodeParams === null) {
317
- delete store.config.decoders[name];
318
- } else {
319
- const decoder = updates.decodeParams;
320
-
321
- store.config.decoders[name] = (params: Params): Params =>
322
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime fallback if user-provided decoder violates its return type
323
- decoder(params) ?? params;
324
- }
325
- }
326
-
327
- if (updates.encodeParams !== undefined) {
328
- if (updates.encodeParams === null) {
329
- delete store.config.encoders[name];
330
- } else {
331
- const encoder = updates.encodeParams;
332
-
333
- store.config.encoders[name] = (params: Params): Params =>
334
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime fallback if user-provided encoder violates its return type
335
- encoder(params) ?? params;
336
- }
337
- }
338
- }
339
-
340
- /**
341
- * Gets a route by name with all its configuration.
342
- */
343
- function getRoute<
344
- Dependencies extends DefaultDependencies = DefaultDependencies,
345
- >(
346
- store: RoutesStore<Dependencies>,
347
- name: string,
348
- ): Route<Dependencies> | undefined {
349
- const segments = store.matcher.getSegmentsByName(name);
350
-
351
- if (!segments) {
352
- return undefined;
353
- }
354
-
355
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- segments is non-empty (checked above)
356
- const targetNode = segments.at(-1)! as RouteTree;
357
- const definition = store.treeOperations.nodeToDefinition(targetNode);
358
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
359
- const factories = store.lifecycleNamespace!.getFactories();
360
-
361
- return enrichRoute(definition, name, store.config, factories);
362
- }
363
-
364
- // ============================================================================
365
- // API factory
366
- // ============================================================================
367
-
368
- export function getRoutesApi<
369
- Dependencies extends DefaultDependencies = DefaultDependencies,
370
- >(router: Router<Dependencies>): RoutesApi<Dependencies> {
371
- const ctx = getInternals(router);
372
-
373
- const store = ctx.routeGetStore();
374
-
375
- const interceptableAdd = createInterceptable(
376
- "add",
377
- (routeArray: Route<Dependencies>[], options?: { parent?: string }) => {
378
- addRoutes(store, routeArray, options?.parent);
379
- },
380
- ctx.interceptors,
381
- );
382
-
383
- return {
384
- add: (routes, options) => {
385
- throwIfDisposed(ctx.isDisposed);
386
-
387
- const routeArray = Array.isArray(routes) ? routes : [routes];
388
- const parentName = options?.parent;
389
-
390
- guardRouteStructure(routeArray, ctx.validator);
391
-
392
- if (parentName !== undefined) {
393
- ctx.validator?.routes.validateParentOption(parentName, store.tree);
394
- }
395
-
396
- ctx.validator?.routes.throwIfInternalRouteInArray(routeArray, "addRoute");
397
- ctx.validator?.routes.validateAddRouteArgs(routeArray);
398
- ctx.validator?.routes.validateRoutes(routeArray, store);
399
-
400
- interceptableAdd(
401
- routeArray,
402
- parentName === undefined ? undefined : { parent: parentName },
403
- );
404
- },
405
-
406
- remove: (name) => {
407
- throwIfDisposed(ctx.isDisposed);
408
-
409
- ctx.validator?.routes.validateRemoveRouteArgs(name);
410
- ctx.validator?.routes.throwIfInternalRoute(name, "removeRoute");
411
-
412
- const canRemove = validateRemoveRoute(
413
- name,
414
- ctx.getStateName(),
415
- ctx.isTransitioning(),
416
- );
417
-
418
- if (!canRemove) {
419
- return;
420
- }
421
-
422
- const wasRemoved = removeRoute(store, name);
423
-
424
- if (!wasRemoved) {
425
- logger.warn(
426
- "router.removeRoute",
427
- `Route "${name}" not found. No changes made.`,
428
- );
429
- }
430
- },
431
-
432
- update: (name, updates) => {
433
- throwIfDisposed(ctx.isDisposed);
434
-
435
- ctx.validator?.routes.validateUpdateRouteBasicArgs(name, updates);
436
- ctx.validator?.routes.throwIfInternalRoute(name, "updateRoute");
437
-
438
- const {
439
- forwardTo,
440
- defaultParams,
441
- decodeParams,
442
- encodeParams,
443
- canActivate,
444
- canDeactivate,
445
- } = updates;
446
-
447
- ctx.validator?.routes.validateUpdateRoutePropertyTypes(name, updates);
448
-
449
- /* v8 ignore next 6 -- @preserve: race condition guard, mirrors Router.updateRoute() same-path guard tested via Router.ts unit tests */
450
- if (ctx.isTransitioning()) {
451
- logger.error(
452
- "router.updateRoute",
453
- `Updating route "${name}" while navigation is in progress. This may cause unexpected behavior.`,
454
- );
455
- }
456
-
457
- ctx.validator?.routes.validateUpdateRoute(name, updates, store);
458
-
459
- updateRouteConfig(store, name, {
460
- forwardTo,
461
- defaultParams,
462
- decodeParams,
463
- encodeParams,
464
- });
465
-
466
- if (canActivate !== undefined) {
467
- if (canActivate === null) {
468
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
469
- store.lifecycleNamespace!.clearCanActivate(name);
470
- } else {
471
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
472
- store.lifecycleNamespace!.addCanActivate(name, canActivate, true);
473
- }
474
- }
475
-
476
- if (canDeactivate !== undefined) {
477
- if (canDeactivate === null) {
478
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
479
- store.lifecycleNamespace!.clearCanDeactivate(name);
480
- } else {
481
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
482
- store.lifecycleNamespace!.addCanDeactivate(name, canDeactivate, true);
483
- }
484
- }
485
- },
486
-
487
- clear: () => {
488
- throwIfDisposed(ctx.isDisposed);
489
-
490
- const canClear = validateClearRoutes(ctx.isTransitioning());
491
-
492
- /* v8 ignore next 3 -- @preserve: race condition guard, mirrors Router.clearRoutes() same-path guard tested via validateClearRoutes unit tests */
493
- if (!canClear) {
494
- return;
495
- }
496
-
497
- store.treeOperations.resetStore(store);
498
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- guaranteed set after wiring
499
- store.lifecycleNamespace!.clearAll();
500
- ctx.clearState();
501
- },
502
-
503
- has: (name) => {
504
- ctx.validator?.routes.validateRouteName(name, "hasRoute");
505
-
506
- return store.matcher.hasRoute(name);
507
- },
508
-
509
- get: (name) => {
510
- ctx.validator?.routes.validateRouteName(name, "getRoute");
511
-
512
- return getRoute(store, name);
513
- },
514
-
515
- replace: (routes) => {
516
- throwIfDisposed(ctx.isDisposed);
517
-
518
- const routeArray = Array.isArray(routes) ? routes : [routes];
519
-
520
- const canReplace = validateClearRoutes(ctx.isTransitioning());
521
-
522
- if (!canReplace) {
523
- return;
524
- }
525
-
526
- guardRouteStructure(routeArray, ctx.validator);
527
-
528
- ctx.validator?.routes.throwIfInternalRouteInArray(
529
- routeArray,
530
- "replaceRoutes",
531
- );
532
- ctx.validator?.routes.validateAddRouteArgs(routeArray);
533
- ctx.validator?.routes.validateRoutes(routeArray, store);
534
-
535
- const currentState = router.getState();
536
-
537
- replaceRoutes(
538
- store,
539
- routeArray,
540
- ctx,
541
- currentState?.path,
542
- currentState?.transition,
543
- );
544
- },
545
- };
546
- }
@@ -1,10 +0,0 @@
1
- // packages/core/src/api/helpers.ts
2
-
3
- import { errorCodes } from "../constants";
4
- import { RouterError } from "../RouterError";
5
-
6
- export function throwIfDisposed(isDisposed: () => boolean): void {
7
- if (isDisposed()) {
8
- throw new RouterError(errorCodes.ROUTER_DISPOSED);
9
- }
10
- }
package/src/api/index.ts DELETED
@@ -1,16 +0,0 @@
1
- export { getPluginApi } from "./getPluginApi";
2
-
3
- export { getRoutesApi } from "./getRoutesApi";
4
-
5
- export { getDependenciesApi } from "./getDependenciesApi";
6
-
7
- export { getLifecycleApi } from "./getLifecycleApi";
8
-
9
- export { cloneRouter } from "./cloneRouter";
10
-
11
- export type {
12
- PluginApi,
13
- RoutesApi,
14
- DependenciesApi,
15
- LifecycleApi,
16
- } from "./types";
package/src/api/types.ts DELETED
@@ -1,12 +0,0 @@
1
- import type { PluginApi as BasePluginApi } from "@real-router/types";
2
- import type { RouteTree } from "route-tree";
3
-
4
- export interface PluginApi extends Omit<BasePluginApi, "getTree"> {
5
- getTree: () => RouteTree;
6
- }
7
-
8
- export {
9
- type RoutesApi,
10
- type LifecycleApi,
11
- type DependenciesApi,
12
- } from "@real-router/types";
package/src/constants.ts DELETED
@@ -1,101 +0,0 @@
1
- // packages/core/src/constants.ts
2
-
3
- import type {
4
- EventToNameMap,
5
- EventToPluginMap,
6
- ErrorCodeToValueMap,
7
- ErrorCodeKeys,
8
- ErrorCodeValues,
9
- TransitionMeta,
10
- } from "@real-router/types";
11
-
12
- export type ConstantsKeys = "UNKNOWN_ROUTE";
13
-
14
- export type Constants = Record<ConstantsKeys, string>;
15
-
16
- // =============================================================================
17
- // Error Codes (migrated from router-error)
18
- // =============================================================================
19
-
20
- export type ErrorCodes = Record<ErrorCodeKeys, ErrorCodeValues>;
21
-
22
- /**
23
- * Error codes for router operations.
24
- * Used to identify specific failure scenarios in navigation and lifecycle.
25
- * Frozen to prevent accidental modifications.
26
- */
27
- export const errorCodes: ErrorCodeToValueMap = Object.freeze({
28
- ROUTER_NOT_STARTED: "NOT_STARTED", // navigate() called before start()
29
- NO_START_PATH_OR_STATE: "NO_START_PATH_OR_STATE", // start() without initial route
30
- ROUTER_ALREADY_STARTED: "ALREADY_STARTED", // start() called twice
31
- ROUTE_NOT_FOUND: "ROUTE_NOT_FOUND", // Navigation to non-existent route
32
- SAME_STATES: "SAME_STATES", // Navigate to current route without reload
33
- CANNOT_DEACTIVATE: "CANNOT_DEACTIVATE", // canDeactivate guard blocked navigation
34
- CANNOT_ACTIVATE: "CANNOT_ACTIVATE", // canActivate guard blocked navigation
35
- TRANSITION_ERR: "TRANSITION_ERR", // Generic transition failure
36
- TRANSITION_CANCELLED: "CANCELLED", // Navigation cancelled by user or new navigation
37
- ROUTER_DISPOSED: "DISPOSED", // Router has been disposed
38
- PLUGIN_CONFLICT: "PLUGIN_CONFLICT", // Plugin tried to extend router with already-existing property
39
- CONTEXT_NAMESPACE_ALREADY_CLAIMED: "CONTEXT_NAMESPACE_ALREADY_CLAIMED", // Plugin tried to claim a context namespace already owned by another plugin
40
- });
41
-
42
- /**
43
- * General router constants.
44
- * Special route names and identifiers.
45
- */
46
- export const UNKNOWN_ROUTE = "@@router/UNKNOWN_ROUTE";
47
-
48
- export const constants: Constants = {
49
- UNKNOWN_ROUTE,
50
- };
51
-
52
- /**
53
- * Plugin method names.
54
- * Maps to methods that plugins can implement to hook into router lifecycle.
55
- */
56
- export const plugins: EventToPluginMap = {
57
- ROUTER_START: "onStart", // Plugin method called when router starts
58
- ROUTER_STOP: "onStop", // Plugin method called when router stops
59
- TRANSITION_START: "onTransitionStart", // Plugin method called when navigation begins
60
- TRANSITION_LEAVE_APPROVE: "onTransitionLeaveApprove", // Plugin method called when deactivation guards pass
61
- TRANSITION_CANCEL: "onTransitionCancel", // Plugin method called when navigation cancelled
62
- TRANSITION_SUCCESS: "onTransitionSuccess", // Plugin method called when navigation succeeds
63
- TRANSITION_ERROR: "onTransitionError", // Plugin method called when navigation fails
64
- };
65
-
66
- /**
67
- * Event names for router event system.
68
- * Used with addEventListener/removeEventListener for reactive subscriptions.
69
- */
70
- export const events: EventToNameMap = {
71
- ROUTER_START: "$start", // Emitted when router.start() succeeds
72
- ROUTER_STOP: "$stop", // Emitted when router.stop() is called
73
- TRANSITION_START: "$$start", // Emitted when navigation begins
74
- TRANSITION_LEAVE_APPROVE: "$$leaveApprove", // Emitted when deactivation guards pass
75
- TRANSITION_CANCEL: "$$cancel", // Emitted when navigation is cancelled
76
- TRANSITION_SUCCESS: "$$success", // Emitted when navigation completes successfully
77
- TRANSITION_ERROR: "$$error", // Emitted when navigation fails
78
- };
79
-
80
- export const DEFAULT_LIMITS = {
81
- maxDependencies: 100,
82
- maxPlugins: 50,
83
- maxListeners: 10_000,
84
- warnListeners: 1000,
85
- maxEventDepth: 5,
86
- maxLifecycleHandlers: 200,
87
- } as const;
88
-
89
- export const EMPTY_PARAMS: Readonly<Record<string, never>> = Object.freeze({});
90
-
91
- const FROZEN_EMPTY_SEGMENTS = Object.freeze({
92
- deactivated: Object.freeze([]) as unknown as string[],
93
- activated: Object.freeze([]) as unknown as string[],
94
- intersection: "",
95
- });
96
-
97
- export const DEFAULT_TRANSITION = Object.freeze({
98
- phase: "activating",
99
- reason: "success",
100
- segments: FROZEN_EMPTY_SEGMENTS,
101
- }) as TransitionMeta;