@real-router/core 0.38.0 → 0.40.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 (89) hide show
  1. package/README.md +27 -5
  2. package/dist/cjs/Router-B-Pev7K2.d.ts +46 -0
  3. package/dist/cjs/RouterValidator-mx2Zooya.d.ts +136 -0
  4. package/dist/cjs/api.d.ts +2 -1
  5. package/dist/cjs/api.js +1 -1
  6. package/dist/cjs/api.js.map +1 -1
  7. package/dist/cjs/index.d-y2b-8_3Y.d.ts +236 -0
  8. package/dist/cjs/index.d.ts +7 -24
  9. package/dist/cjs/index.js +1 -1
  10. package/dist/cjs/index.js.map +1 -1
  11. package/dist/cjs/metafile-cjs.json +1 -1
  12. package/dist/cjs/utils.d.ts +6 -1
  13. package/dist/cjs/utils.js +1 -1
  14. package/dist/cjs/utils.js.map +1 -1
  15. package/dist/cjs/validation.d.ts +184 -0
  16. package/dist/cjs/validation.js +1 -0
  17. package/dist/cjs/validation.js.map +1 -0
  18. package/dist/esm/Router-B-Pev7K2.d.mts +46 -0
  19. package/dist/esm/RouterValidator-mx2Zooya.d.mts +136 -0
  20. package/dist/esm/api.d.mts +2 -1
  21. package/dist/esm/api.mjs +1 -1
  22. package/dist/esm/api.mjs.map +1 -1
  23. package/dist/esm/chunk-5QXFUUDL.mjs +1 -0
  24. package/dist/esm/chunk-5QXFUUDL.mjs.map +1 -0
  25. package/dist/esm/chunk-HHIXK5UM.mjs +1 -0
  26. package/dist/esm/chunk-HHIXK5UM.mjs.map +1 -0
  27. package/dist/esm/chunk-QUUNDESP.mjs +1 -0
  28. package/dist/esm/chunk-QUUNDESP.mjs.map +1 -0
  29. package/dist/esm/chunk-RA5VYM7M.mjs +1 -0
  30. package/dist/esm/chunk-RA5VYM7M.mjs.map +1 -0
  31. package/dist/esm/index.d-y2b-8_3Y.d.mts +236 -0
  32. package/dist/esm/index.d.mts +7 -24
  33. package/dist/esm/index.mjs +1 -1
  34. package/dist/esm/metafile-esm.json +1 -1
  35. package/dist/esm/utils.d.mts +6 -1
  36. package/dist/esm/utils.mjs +1 -1
  37. package/dist/esm/utils.mjs.map +1 -1
  38. package/dist/esm/validation.d.mts +184 -0
  39. package/dist/esm/validation.mjs +1 -0
  40. package/dist/esm/validation.mjs.map +1 -0
  41. package/package.json +18 -5
  42. package/src/Router.ts +73 -99
  43. package/src/api/cloneRouter.ts +1 -30
  44. package/src/api/getDependenciesApi.ts +45 -86
  45. package/src/api/getLifecycleApi.ts +24 -19
  46. package/src/api/getPluginApi.ts +20 -28
  47. package/src/api/getRoutesApi.ts +49 -106
  48. package/src/constants.ts +0 -30
  49. package/src/guards.ts +46 -0
  50. package/src/helpers.ts +0 -17
  51. package/src/index.ts +4 -0
  52. package/src/internals.ts +6 -5
  53. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +2 -2
  54. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -25
  55. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +4 -26
  56. package/src/namespaces/OptionsNamespace/constants.ts +0 -20
  57. package/src/namespaces/OptionsNamespace/index.ts +1 -5
  58. package/src/namespaces/OptionsNamespace/validators.ts +6 -245
  59. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +18 -59
  60. package/src/namespaces/PluginsNamespace/constants.ts +3 -6
  61. package/src/namespaces/PluginsNamespace/validators.ts +2 -57
  62. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +27 -84
  63. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -16
  64. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +3 -12
  65. package/src/namespaces/RoutesNamespace/constants.ts +0 -8
  66. package/src/namespaces/RoutesNamespace/forwardChain.ts +34 -0
  67. package/src/namespaces/RoutesNamespace/index.ts +1 -1
  68. package/src/namespaces/RoutesNamespace/routeGuards.ts +62 -0
  69. package/src/namespaces/RoutesNamespace/routesStore.ts +7 -51
  70. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -33
  71. package/src/namespaces/StateNamespace/helpers.ts +1 -1
  72. package/src/namespaces/index.ts +0 -3
  73. package/src/typeGuards.ts +1 -15
  74. package/src/types/RouterValidator.ts +155 -0
  75. package/src/utils/getStaticPaths.ts +50 -0
  76. package/src/utils/index.ts +4 -0
  77. package/src/validation.ts +12 -0
  78. package/src/wiring/RouterWiringBuilder.ts +32 -9
  79. package/dist/cjs/index.d-DDimDpYc.d.ts +0 -165
  80. package/dist/esm/chunk-CG7TKDP3.mjs +0 -1
  81. package/dist/esm/chunk-CG7TKDP3.mjs.map +0 -1
  82. package/dist/esm/index.d-DDimDpYc.d.mts +0 -165
  83. package/src/namespaces/DependenciesNamespace/validators.ts +0 -103
  84. package/src/namespaces/EventBusNamespace/validators.ts +0 -36
  85. package/src/namespaces/NavigationNamespace/validators.ts +0 -47
  86. package/src/namespaces/RouteLifecycleNamespace/validators.ts +0 -65
  87. package/src/namespaces/RoutesNamespace/forwardToValidation.ts +0 -408
  88. package/src/namespaces/RoutesNamespace/validators.ts +0 -566
  89. package/src/namespaces/StateNamespace/validators.ts +0 -46
@@ -1,14 +1,10 @@
1
1
  // packages/core/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts
2
2
 
3
- import { logger } from "@real-router/logger";
4
- import { isBoolean, getTypeDescription } from "type-guards";
5
-
6
- import { validateHandlerLimit, validateNotRegistering } from "./validators";
7
3
  import { DEFAULT_LIMITS } from "../../constants";
8
- import { computeThresholds } from "../../helpers";
9
4
 
10
5
  import type { RouteLifecycleDependencies } from "./types";
11
6
  import type { GuardFnFactory, Limits } from "../../types";
7
+ import type { RouterValidator } from "../../types/RouterValidator";
12
8
  import type { DefaultDependencies, GuardFn, State } from "@real-router/types";
13
9
 
14
10
  /**
@@ -54,6 +50,7 @@ export class RouteLifecycleNamespace<
54
50
 
55
51
  #deps!: RouteLifecycleDependencies<Dependencies>;
56
52
  #limits: Limits = DEFAULT_LIMITS;
53
+ #getValidator: (() => RouterValidator | null) | null = null;
57
54
 
58
55
  setDependencies(deps: RouteLifecycleDependencies<Dependencies>): void {
59
56
  this.#deps = deps;
@@ -66,6 +63,18 @@ export class RouteLifecycleNamespace<
66
63
  */
67
64
  setLimits(limits: Limits): void {
68
65
  this.#limits = limits;
66
+ // eslint-disable-next-line sonarjs/void-use -- @preserve: Wave 3 validator reads limits via RouterInternals; void suppresses TS6133 until then
67
+ void this.#limits;
68
+ }
69
+
70
+ setValidatorGetter(getter: () => RouterValidator | null): void {
71
+ this.#getValidator = getter;
72
+ }
73
+
74
+ getHandlerCount(type: "activate" | "deactivate"): number {
75
+ return type === "activate"
76
+ ? this.#canActivateFactories.size
77
+ : this.#canDeactivateFactories.size;
69
78
  }
70
79
 
71
80
  // =========================================================================
@@ -74,17 +83,15 @@ export class RouteLifecycleNamespace<
74
83
 
75
84
  /**
76
85
  * Adds a canActivate guard for a route.
77
- * Handles state-dependent validation, overwrite detection, and registration.
86
+ * Handles overwrite detection and registration.
78
87
  *
79
88
  * @param name - Route name (input-validated by facade)
80
89
  * @param handler - Guard function or boolean (input-validated by facade)
81
- * @param skipValidation - True when called during route config building (#noValidate)
82
90
  * @param isFromDefinition - True when guard comes from route definition (tracked for HMR replace)
83
91
  */
84
92
  addCanActivate(
85
93
  name: string,
86
94
  handler: GuardFnFactory<Dependencies> | boolean,
87
- skipValidation: boolean,
88
95
  isFromDefinition = false,
89
96
  ): void {
90
97
  if (isFromDefinition) {
@@ -92,24 +99,9 @@ export class RouteLifecycleNamespace<
92
99
  } else {
93
100
  this.#definitionActivateGuardNames.delete(name);
94
101
  }
95
- if (!skipValidation) {
96
- validateNotRegistering(
97
- this.#registering.has(name),
98
- name,
99
- "addActivateGuard",
100
- );
101
- }
102
102
 
103
103
  const isOverwrite = this.#canActivateFactories.has(name);
104
104
 
105
- if (!isOverwrite && !skipValidation) {
106
- validateHandlerLimit(
107
- this.#canActivateFactories.size + 1,
108
- "addActivateGuard",
109
- this.#limits.maxLifecycleHandlers,
110
- );
111
- }
112
-
113
105
  this.#registerHandler(
114
106
  "activate",
115
107
  name,
@@ -123,17 +115,15 @@ export class RouteLifecycleNamespace<
123
115
 
124
116
  /**
125
117
  * Adds a canDeactivate guard for a route.
126
- * Handles state-dependent validation, overwrite detection, and registration.
118
+ * Handles overwrite detection and registration.
127
119
  *
128
120
  * @param name - Route name (input-validated by facade)
129
121
  * @param handler - Guard function or boolean (input-validated by facade)
130
- * @param skipValidation - True when called during route config building (#noValidate)
131
122
  * @param isFromDefinition - True when guard comes from route definition (tracked for HMR replace)
132
123
  */
133
124
  addCanDeactivate(
134
125
  name: string,
135
126
  handler: GuardFnFactory<Dependencies> | boolean,
136
- skipValidation: boolean,
137
127
  isFromDefinition = false,
138
128
  ): void {
139
129
  if (isFromDefinition) {
@@ -141,24 +131,9 @@ export class RouteLifecycleNamespace<
141
131
  } else {
142
132
  this.#definitionDeactivateGuardNames.delete(name);
143
133
  }
144
- if (!skipValidation) {
145
- validateNotRegistering(
146
- this.#registering.has(name),
147
- name,
148
- "addDeactivateGuard",
149
- );
150
- }
151
134
 
152
135
  const isOverwrite = this.#canDeactivateFactories.has(name);
153
136
 
154
- if (!isOverwrite && !skipValidation) {
155
- validateHandlerLimit(
156
- this.#canDeactivateFactories.size + 1,
157
- "addDeactivateGuard",
158
- this.#limits.maxLifecycleHandlers,
159
- );
160
- }
161
-
162
137
  this.#registerHandler(
163
138
  "deactivate",
164
139
  name,
@@ -321,18 +296,19 @@ export class RouteLifecycleNamespace<
321
296
  ): void {
322
297
  // Emit warnings
323
298
  if (isOverwrite) {
324
- logger.warn(
325
- `router.${methodName}`,
326
- `Overwriting existing ${type} handler for route "${name}"`,
327
- );
299
+ this.#getValidator?.()?.lifecycle.warnOverwrite(name, type, methodName);
328
300
  } else {
329
- this.#checkCountThresholds(factories.size + 1, methodName);
301
+ this.#getValidator?.()?.lifecycle.validateCountThresholds(
302
+ factories.size + 1,
303
+ methodName,
304
+ );
330
305
  }
331
306
 
332
307
  // Convert boolean to factory if needed
333
- const factory = isBoolean(handler)
334
- ? booleanToFactory<Dependencies>(handler)
335
- : handler;
308
+ const factory =
309
+ typeof handler === "boolean"
310
+ ? booleanToFactory<Dependencies>(handler)
311
+ : handler;
336
312
 
337
313
  // Store factory
338
314
  factories.set(name, factory);
@@ -345,7 +321,7 @@ export class RouteLifecycleNamespace<
345
321
 
346
322
  if (typeof fn !== "function") {
347
323
  throw new TypeError(
348
- `[router.${methodName}] Factory must return a function, got ${getTypeDescription(fn)}`,
324
+ `[router.${methodName}] Factory must return a function, got ${typeof fn}`,
349
325
  );
350
326
  }
351
327
 
@@ -391,44 +367,11 @@ export class RouteLifecycleNamespace<
391
367
  return result;
392
368
  }
393
369
 
394
- logger.warn(
395
- `router.${methodName}`,
396
- `Guard for "${name}" returned a Promise. Sync check cannot resolve async guards — returning false.`,
397
- );
370
+ this.#getValidator?.()?.lifecycle.warnAsyncGuardSync(name, methodName);
398
371
 
399
372
  return false;
400
373
  } catch {
401
374
  return false;
402
375
  }
403
376
  }
404
-
405
- /**
406
- * Emits warn/error log messages when handler count approaches the configured limit.
407
- *
408
- * @param currentSize - Current handler count (after adding the new one)
409
- * @param methodName - Public API method name for warning messages
410
- */
411
- #checkCountThresholds(currentSize: number, methodName: string): void {
412
- const maxLifecycleHandlers = this.#limits.maxLifecycleHandlers;
413
-
414
- if (maxLifecycleHandlers === 0) {
415
- return;
416
- }
417
-
418
- const { warn, error } = computeThresholds(maxLifecycleHandlers);
419
-
420
- if (currentSize >= error) {
421
- logger.error(
422
- `router.${methodName}`,
423
- `${currentSize} lifecycle handlers registered! ` +
424
- `This is excessive. Hard limit at ${maxLifecycleHandlers}.`,
425
- );
426
- } else if (currentSize >= warn) {
427
- logger.warn(
428
- `router.${methodName}`,
429
- `${currentSize} lifecycle handlers registered. ` +
430
- `Consider consolidating logic.`,
431
- );
432
- }
433
- }
434
377
  }
@@ -19,22 +19,6 @@ Object.freeze(REPLACE_OPTS);
19
19
  export class RouterLifecycleNamespace {
20
20
  #deps!: RouterLifecycleDependencies;
21
21
 
22
- // =========================================================================
23
- // Static validation methods (called by facade before instance methods)
24
- // =========================================================================
25
-
26
- /**
27
- * Validates start() arguments.
28
- */
29
- static validateStartArgs(args: unknown[]): void {
30
- /* v8 ignore next 4 -- @preserve: facade enforces 1 arg via TypeScript signature */
31
- if (args.length !== 1 || typeof args[0] !== "string") {
32
- throw new Error(
33
- "[router.start] Expected exactly 1 string argument (startPath).",
34
- );
35
- }
36
- }
37
-
38
22
  // =========================================================================
39
23
  // Dependency injection
40
24
  // =========================================================================
@@ -1,8 +1,6 @@
1
1
  // packages/core/src/namespaces/RoutesNamespace/RoutesNamespace.ts
2
2
 
3
- import { isString, validateRouteName } from "type-guards";
4
-
5
- import { DEFAULT_ROUTE_NAME, validatedRouteNames } from "./constants";
3
+ import { DEFAULT_ROUTE_NAME } from "./constants";
6
4
  import { paramsMatch, paramsMatchExcluding } from "./helpers";
7
5
  import {
8
6
  createRoutesStore,
@@ -89,10 +87,9 @@ export class RoutesNamespace<
89
87
 
90
88
  constructor(
91
89
  routes: Route<Dependencies>[] = [],
92
- noValidate = false,
93
90
  matcherOptions?: CreateMatcherOptions,
94
91
  ) {
95
- this.#store = createRoutesStore(routes, noValidate, matcherOptions);
92
+ this.#store = createRoutesStore(routes, matcherOptions);
96
93
  }
97
94
 
98
95
  /**
@@ -200,7 +197,7 @@ export class RoutesNamespace<
200
197
  */
201
198
  buildPath(route: string, params?: Params, options?: Options): string {
202
199
  if (route === constants.UNKNOWN_ROUTE) {
203
- return isString(params?.path) ? params.path : "";
200
+ return typeof params?.path === "string" ? params.path : "";
204
201
  }
205
202
 
206
203
  const paramsWithDefault = Object.hasOwn(
@@ -374,12 +371,6 @@ export class RoutesNamespace<
374
371
  strictEquality = false,
375
372
  ignoreQueryParams = true,
376
373
  ): boolean {
377
- // Fast path: skip regex validation for already-validated route names
378
- if (!validatedRouteNames.has(name)) {
379
- validateRouteName(name, "isActiveRoute");
380
- validatedRouteNames.add(name);
381
- }
382
-
383
374
  // Note: empty string check is handled by Router.ts facade
384
375
  const activeState = this.#deps.getState();
385
376
 
@@ -4,11 +4,3 @@
4
4
  * Default route name for the root node.
5
5
  */
6
6
  export const DEFAULT_ROUTE_NAME = "";
7
-
8
- /**
9
- * Cache for validated route names to skip regex validation on repeated calls.
10
- * Key insight: validateRouteName() regex takes ~40ns, but cache lookup is ~1ns.
11
- * This cache is module-level (shared across all router instances) since route name
12
- * validity is independent of router instance.
13
- */
14
- export const validatedRouteNames = new Set<string>();
@@ -0,0 +1,34 @@
1
+ // packages/core/src/namespaces/RoutesNamespace/forwardChain.ts
2
+
3
+ export function resolveForwardChain(
4
+ startRoute: string,
5
+ forwardMap: Record<string, string>,
6
+ maxDepth = 100,
7
+ ): string {
8
+ const visited = new Set<string>();
9
+ const chain: string[] = [startRoute];
10
+ let current = startRoute;
11
+
12
+ while (forwardMap[current]) {
13
+ const next = forwardMap[current];
14
+
15
+ if (visited.has(next)) {
16
+ const cycleStart = chain.indexOf(next);
17
+ const cycle = [...chain.slice(cycleStart), next];
18
+
19
+ throw new Error(`Circular forwardTo: ${cycle.join(" → ")}`);
20
+ }
21
+
22
+ visited.add(current);
23
+ chain.push(next);
24
+ current = next;
25
+
26
+ if (chain.length > maxDepth) {
27
+ throw new Error(
28
+ `forwardTo chain exceeds maximum depth (${maxDepth}): ${chain.join(" → ")}`,
29
+ );
30
+ }
31
+ }
32
+
33
+ return current;
34
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  export { RoutesNamespace } from "./RoutesNamespace";
4
4
 
5
- export { DEFAULT_ROUTE_NAME, validatedRouteNames } from "./constants";
5
+ export { DEFAULT_ROUTE_NAME } from "./constants";
6
6
 
7
7
  export { createEmptyConfig } from "./helpers";
8
8
 
@@ -0,0 +1,62 @@
1
+ import { logger } from "@real-router/logger";
2
+
3
+ /**
4
+ * Validates removeRoute constraints.
5
+ * Returns false if removal should be blocked (route is active).
6
+ * Logs warnings for edge cases.
7
+ *
8
+ * @param name - Route name to remove
9
+ * @param currentStateName - Current active route name (or undefined)
10
+ * @param isNavigating - Whether navigation is in progress
11
+ * @returns true if removal can proceed, false if blocked
12
+ */
13
+ export function validateRemoveRoute(
14
+ name: string,
15
+ currentStateName: string | undefined,
16
+ isNavigating: boolean,
17
+ ): boolean {
18
+ if (currentStateName) {
19
+ const isExactMatch = currentStateName === name;
20
+ const isParentOfCurrent = currentStateName.startsWith(`${name}.`);
21
+
22
+ if (isExactMatch || isParentOfCurrent) {
23
+ const suffix = isExactMatch ? "" : ` (current: "${currentStateName}")`;
24
+
25
+ logger.warn(
26
+ "router.removeRoute",
27
+ `Cannot remove route "${name}" — it is currently active${suffix}. Navigate away first.`,
28
+ );
29
+
30
+ return false;
31
+ }
32
+ }
33
+
34
+ if (isNavigating) {
35
+ logger.warn(
36
+ "router.removeRoute",
37
+ `Route "${name}" removed while navigation is in progress. This may cause unexpected behavior.`,
38
+ );
39
+ }
40
+
41
+ return true;
42
+ }
43
+
44
+ /**
45
+ * Validates clearRoutes operation.
46
+ * Returns false if operation should be blocked (navigation in progress).
47
+ *
48
+ * @param isNavigating - Whether navigation is in progress
49
+ * @returns true if clearRoutes can proceed, false if blocked
50
+ */
51
+ export function validateClearRoutes(isNavigating: boolean): boolean {
52
+ if (isNavigating) {
53
+ logger.error(
54
+ "router.clearRoutes",
55
+ "Cannot clear routes while navigation is in progress. Wait for navigation to complete.",
56
+ );
57
+
58
+ return false;
59
+ }
60
+
61
+ return true;
62
+ }
@@ -4,9 +4,8 @@ import { logger } from "@real-router/logger";
4
4
  import { createMatcher, createRouteTree, nodeToDefinition } from "route-tree";
5
5
 
6
6
  import { DEFAULT_ROUTE_NAME } from "./constants";
7
- import { resolveForwardChain } from "./forwardToValidation";
7
+ import { resolveForwardChain } from "./forwardChain";
8
8
  import { createEmptyConfig, sanitizeRoute } from "./helpers";
9
- import { validateRoutes } from "./validators";
10
9
 
11
10
  import type { RouteConfig, RoutesDependencies } from "./types";
12
11
  import type { GuardFnFactory, Route } from "../../types";
@@ -39,18 +38,9 @@ export interface RoutesStore<
39
38
  readonly pendingCanActivate: Map<string, GuardFnFactory<Dependencies>>;
40
39
  readonly pendingCanDeactivate: Map<string, GuardFnFactory<Dependencies>>;
41
40
  readonly treeOperations: {
42
- readonly commitTreeChanges: (
43
- store: RoutesStore<Dependencies>,
44
- noValidate: boolean,
45
- ) => void;
41
+ readonly commitTreeChanges: (store: RoutesStore<Dependencies>) => void;
46
42
  readonly resetStore: (store: RoutesStore<Dependencies>) => void;
47
43
  readonly nodeToDefinition: (node: RouteTree) => RouteDefinition;
48
- readonly validateRoutes: (
49
- routes: Route<Dependencies>[],
50
- tree?: RouteTree,
51
- forwardMap?: Record<string, string>,
52
- parentName?: string,
53
- ) => void;
54
44
  };
55
45
  }
56
46
 
@@ -73,7 +63,7 @@ function rebuildTree(
73
63
 
74
64
  export function commitTreeChanges<
75
65
  Dependencies extends DefaultDependencies = DefaultDependencies,
76
- >(store: RoutesStore<Dependencies>, noValidate: boolean): void {
66
+ >(store: RoutesStore<Dependencies>): void {
77
67
  const result = rebuildTree(
78
68
  store.definitions,
79
69
  store.rootPath,
@@ -82,7 +72,7 @@ export function commitTreeChanges<
82
72
 
83
73
  store.tree = result.tree;
84
74
  store.matcher = result.matcher;
85
- store.resolvedForwardMap = refreshForwardMap(store.config, noValidate);
75
+ store.resolvedForwardMap = refreshForwardMap(store.config);
86
76
  }
87
77
 
88
78
  export function rebuildTreeInPlace<
@@ -135,20 +125,7 @@ export function clearRouteData<
135
125
  // Forward map
136
126
  // =============================================================================
137
127
 
138
- export function refreshForwardMap(
139
- config: RouteConfig,
140
- noValidate: boolean,
141
- ): Record<string, string> {
142
- if (noValidate) {
143
- return cacheForwardMap(config);
144
- }
145
-
146
- return validateAndCacheForwardMap(config);
147
- }
148
-
149
- function validateAndCacheForwardMap(
150
- config: RouteConfig,
151
- ): Record<string, string> {
128
+ export function refreshForwardMap(config: RouteConfig): Record<string, string> {
152
129
  const map = Object.create(null) as Record<string, string>;
153
130
 
154
131
  for (const fromRoute of Object.keys(config.forwardMap)) {
@@ -158,22 +135,6 @@ function validateAndCacheForwardMap(
158
135
  return map;
159
136
  }
160
137
 
161
- function cacheForwardMap(config: RouteConfig): Record<string, string> {
162
- const map = Object.create(null) as Record<string, string>;
163
-
164
- for (const fromRoute of Object.keys(config.forwardMap)) {
165
- let current = fromRoute;
166
-
167
- while (config.forwardMap[current]) {
168
- current = config.forwardMap[current];
169
- }
170
-
171
- map[fromRoute] = current;
172
- }
173
-
174
- return map;
175
- }
176
-
177
138
  // =============================================================================
178
139
  // Route handler registration
179
140
  // =============================================================================
@@ -209,7 +170,6 @@ function registerForwardTo<Dependencies extends DefaultDependencies>(
209
170
  );
210
171
  }
211
172
 
212
- // Async validation ALWAYS runs (even with noValidate=true)
213
173
  if (typeof route.forwardTo === "function") {
214
174
  const isNativeAsync =
215
175
  (route.forwardTo as { constructor: { name: string } }).constructor
@@ -254,7 +214,7 @@ function registerSingleRouteHandlers<Dependencies extends DefaultDependencies>(
254
214
  "defaultParams",
255
215
  ]);
256
216
  const customFields = Object.fromEntries(
257
- Object.entries(route).filter(([k]) => !standardKeys.has(k)),
217
+ Object.entries(route).filter(([key]) => !standardKeys.has(key)),
258
218
  );
259
219
 
260
220
  if (Object.keys(customFields).length > 0) {
@@ -342,7 +302,6 @@ export function createRoutesStore<
342
302
  Dependencies extends DefaultDependencies = DefaultDependencies,
343
303
  >(
344
304
  routes: Route<Dependencies>[],
345
- noValidate: boolean,
346
305
  matcherOptions?: CreateMatcherOptions,
347
306
  ): RoutesStore<Dependencies> {
348
307
  const definitions: RouteDefinition[] = [];
@@ -370,9 +329,7 @@ export function createRoutesStore<
370
329
  "",
371
330
  );
372
331
 
373
- const resolvedForwardMap: Record<string, string> = noValidate
374
- ? cacheForwardMap(config)
375
- : validateAndCacheForwardMap(config);
332
+ const resolvedForwardMap = refreshForwardMap(config);
376
333
 
377
334
  return {
378
335
  definitions,
@@ -391,7 +348,6 @@ export function createRoutesStore<
391
348
  commitTreeChanges,
392
349
  resetStore,
393
350
  nodeToDefinition,
394
- validateRoutes,
395
351
  },
396
352
  };
397
353
  }
@@ -1,7 +1,5 @@
1
1
  // packages/core/src/namespaces/StateNamespace/StateNamespace.ts
2
2
 
3
- import { getTypeDescription, validateState } from "type-guards";
4
-
5
3
  import { areParamValuesEqual, getUrlParamsFromMeta } from "./helpers";
6
4
  import { EMPTY_PARAMS } from "../../constants";
7
5
  import { freezeStateInPlace } from "../../helpers";
@@ -42,37 +40,6 @@ export class StateNamespace {
42
40
  */
43
41
  readonly #urlParamsCache = new Map<string, string[]>();
44
42
 
45
- // =========================================================================
46
- // Static validation methods (called by facade before instance methods)
47
- // =========================================================================
48
-
49
- /**
50
- * Validates areStatesEqual arguments.
51
- */
52
- static validateAreStatesEqualArgs(
53
- state1: unknown,
54
- state2: unknown,
55
- ignoreQueryParams: unknown,
56
- ): void {
57
- // null/undefined are valid (represent "no state")
58
- if (state1 != null) {
59
- validateState(state1, "areStatesEqual");
60
- }
61
-
62
- if (state2 != null) {
63
- validateState(state2, "areStatesEqual");
64
- }
65
-
66
- if (
67
- ignoreQueryParams !== undefined &&
68
- typeof ignoreQueryParams !== "boolean"
69
- ) {
70
- throw new TypeError(
71
- `[router.areStatesEqual] Invalid ignoreQueryParams: ${getTypeDescription(ignoreQueryParams)}. Expected boolean.`,
72
- );
73
- }
74
- }
75
-
76
43
  // =========================================================================
77
44
  // Instance methods (trust input - already validated by facade)
78
45
  // =========================================================================
@@ -36,7 +36,7 @@ export function areParamValuesEqual(val1: unknown, val2: unknown): boolean {
36
36
  return false;
37
37
  }
38
38
 
39
- return val1.every((v, i) => areParamValuesEqual(v, val2[i]));
39
+ return val1.every((value, i) => areParamValuesEqual(value, val2[i]));
40
40
  }
41
41
 
42
42
  return false;
@@ -8,8 +8,6 @@ export {
8
8
  deepFreeze,
9
9
  defaultOptions,
10
10
  OptionsNamespace,
11
- VALID_OPTION_VALUES,
12
- VALID_QUERY_PARAMS,
13
11
  } from "./OptionsNamespace";
14
12
 
15
13
  export { StateNamespace } from "./StateNamespace";
@@ -25,7 +23,6 @@ export { RouteLifecycleNamespace } from "./RouteLifecycleNamespace";
25
23
  export {
26
24
  RoutesNamespace,
27
25
  DEFAULT_ROUTE_NAME,
28
- validatedRouteNames,
29
26
  createEmptyConfig,
30
27
  } from "./RoutesNamespace";
31
28
 
package/src/typeGuards.ts CHANGED
@@ -1,23 +1,9 @@
1
1
  // packages/core/src/typeGuards.ts
2
2
 
3
- /**
4
- * Re-export common type guards from centralized type-guards package
5
- */
6
- import type { LoggerConfig, LogLevelConfig } from "@real-router/logger";
7
-
8
- export {
9
- isObjKey,
10
- isString,
11
- isState,
12
- isParams,
13
- isNavigationOptions,
14
- isBoolean,
15
- validateRouteName,
16
- } from "type-guards";
17
-
18
3
  /**
19
4
  * RealRouter-specific type guards for logger configuration
20
5
  */
6
+ import type { LoggerConfig, LogLevelConfig } from "@real-router/logger";
21
7
 
22
8
  const VALID_LEVELS_SET = new Set<string>(["all", "warn-error", "error-only"]);
23
9