@real-router/core 0.44.2 → 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 (79) hide show
  1. package/dist/cjs/api.js +1 -1
  2. package/dist/cjs/api.js.map +1 -1
  3. package/dist/esm/api.mjs +1 -1
  4. package/dist/esm/api.mjs.map +1 -1
  5. package/package.json +6 -7
  6. package/src/Router.ts +0 -684
  7. package/src/RouterError.ts +0 -324
  8. package/src/api/cloneRouter.ts +0 -77
  9. package/src/api/getDependenciesApi.ts +0 -168
  10. package/src/api/getLifecycleApi.ts +0 -65
  11. package/src/api/getPluginApi.ts +0 -167
  12. package/src/api/getRoutesApi.ts +0 -562
  13. package/src/api/helpers.ts +0 -10
  14. package/src/api/index.ts +0 -16
  15. package/src/api/types.ts +0 -12
  16. package/src/constants.ts +0 -87
  17. package/src/createRouter.ts +0 -32
  18. package/src/fsm/index.ts +0 -5
  19. package/src/fsm/routerFSM.ts +0 -120
  20. package/src/getNavigator.ts +0 -30
  21. package/src/guards.ts +0 -46
  22. package/src/helpers.ts +0 -179
  23. package/src/index.ts +0 -50
  24. package/src/internals.ts +0 -173
  25. package/src/namespaces/DependenciesNamespace/dependenciesStore.ts +0 -30
  26. package/src/namespaces/DependenciesNamespace/index.ts +0 -5
  27. package/src/namespaces/EventBusNamespace/EventBusNamespace.ts +0 -311
  28. package/src/namespaces/EventBusNamespace/index.ts +0 -5
  29. package/src/namespaces/EventBusNamespace/types.ts +0 -11
  30. package/src/namespaces/NavigationNamespace/NavigationNamespace.ts +0 -405
  31. package/src/namespaces/NavigationNamespace/constants.ts +0 -55
  32. package/src/namespaces/NavigationNamespace/index.ts +0 -5
  33. package/src/namespaces/NavigationNamespace/transition/completeTransition.ts +0 -100
  34. package/src/namespaces/NavigationNamespace/transition/errorHandling.ts +0 -124
  35. package/src/namespaces/NavigationNamespace/transition/guardPhase.ts +0 -221
  36. package/src/namespaces/NavigationNamespace/types.ts +0 -100
  37. package/src/namespaces/OptionsNamespace/OptionsNamespace.ts +0 -28
  38. package/src/namespaces/OptionsNamespace/constants.ts +0 -19
  39. package/src/namespaces/OptionsNamespace/helpers.ts +0 -50
  40. package/src/namespaces/OptionsNamespace/index.ts +0 -7
  41. package/src/namespaces/OptionsNamespace/validators.ts +0 -13
  42. package/src/namespaces/PluginsNamespace/PluginsNamespace.ts +0 -291
  43. package/src/namespaces/PluginsNamespace/constants.ts +0 -34
  44. package/src/namespaces/PluginsNamespace/index.ts +0 -7
  45. package/src/namespaces/PluginsNamespace/types.ts +0 -22
  46. package/src/namespaces/PluginsNamespace/validators.ts +0 -28
  47. package/src/namespaces/RouteLifecycleNamespace/RouteLifecycleNamespace.ts +0 -377
  48. package/src/namespaces/RouteLifecycleNamespace/index.ts +0 -5
  49. package/src/namespaces/RouteLifecycleNamespace/types.ts +0 -10
  50. package/src/namespaces/RouterLifecycleNamespace/RouterLifecycleNamespace.ts +0 -81
  51. package/src/namespaces/RouterLifecycleNamespace/constants.ts +0 -25
  52. package/src/namespaces/RouterLifecycleNamespace/index.ts +0 -5
  53. package/src/namespaces/RouterLifecycleNamespace/types.ts +0 -26
  54. package/src/namespaces/RoutesNamespace/RoutesNamespace.ts +0 -535
  55. package/src/namespaces/RoutesNamespace/constants.ts +0 -6
  56. package/src/namespaces/RoutesNamespace/forwardChain.ts +0 -34
  57. package/src/namespaces/RoutesNamespace/helpers.ts +0 -126
  58. package/src/namespaces/RoutesNamespace/index.ts +0 -11
  59. package/src/namespaces/RoutesNamespace/routeGuards.ts +0 -62
  60. package/src/namespaces/RoutesNamespace/routesStore.ts +0 -346
  61. package/src/namespaces/RoutesNamespace/types.ts +0 -81
  62. package/src/namespaces/StateNamespace/StateNamespace.ts +0 -211
  63. package/src/namespaces/StateNamespace/helpers.ts +0 -24
  64. package/src/namespaces/StateNamespace/index.ts +0 -5
  65. package/src/namespaces/StateNamespace/types.ts +0 -15
  66. package/src/namespaces/index.ts +0 -35
  67. package/src/stateMetaStore.ts +0 -15
  68. package/src/transitionPath.ts +0 -436
  69. package/src/typeGuards.ts +0 -59
  70. package/src/types/RouterValidator.ts +0 -154
  71. package/src/types.ts +0 -69
  72. package/src/utils/getStaticPaths.ts +0 -50
  73. package/src/utils/index.ts +0 -5
  74. package/src/utils/serializeState.ts +0 -22
  75. package/src/validation.ts +0 -12
  76. package/src/wiring/RouterWiringBuilder.ts +0 -261
  77. package/src/wiring/index.ts +0 -7
  78. package/src/wiring/types.ts +0 -47
  79. package/src/wiring/wireRouter.ts +0 -26
@@ -1,32 +0,0 @@
1
- // packages/core/src/createRouter.ts
2
-
3
- import { Router } from "./Router";
4
-
5
- import type { Route } from "./types";
6
- import type { DefaultDependencies, Options } from "@real-router/types";
7
-
8
- /**
9
- * Creates a new router instance.
10
- *
11
- * @param routes - Array of route definitions
12
- * @param options - Router configuration options
13
- * @param dependencies - Dependencies to inject into the router
14
- * @returns A new Router instance
15
- *
16
- * @example
17
- * const router = createRouter([
18
- * { name: 'home', path: '/' },
19
- * { name: 'users', path: '/users' },
20
- * ]);
21
- *
22
- * router.start('/');
23
- */
24
- export const createRouter = <
25
- Dependencies extends DefaultDependencies = DefaultDependencies,
26
- >(
27
- routes: Route<Dependencies>[] = [],
28
- options: Partial<Options> = {},
29
- dependencies: Dependencies = {} as Dependencies,
30
- ): Router<Dependencies> => {
31
- return new Router<Dependencies>(routes, options, dependencies);
32
- };
package/src/fsm/index.ts DELETED
@@ -1,5 +0,0 @@
1
- // packages/core/src/fsm/index.ts
2
-
3
- export { createRouterFSM, routerStates, routerEvents } from "./routerFSM";
4
-
5
- export type { RouterEvent, RouterPayloads, RouterState } from "./routerFSM";
@@ -1,120 +0,0 @@
1
- // packages/core/src/fsm/routerFSM.ts
2
-
3
- import { FSM } from "@real-router/fsm";
4
-
5
- import type { FSMConfig } from "@real-router/fsm";
6
-
7
- /**
8
- * Router FSM states.
9
- *
10
- * - IDLE: Router not started or stopped
11
- * - STARTING: Router is initializing
12
- * - READY: Router is ready for navigation
13
- * - TRANSITION_STARTED: Navigation in progress (before deactivation guards)
14
- * - LEAVE_APPROVED: Deactivation guards passed, activation guards pending
15
- * - DISPOSED: Router has been disposed (R2+)
16
- */
17
- export const routerStates = {
18
- IDLE: "IDLE",
19
- STARTING: "STARTING",
20
- READY: "READY",
21
- TRANSITION_STARTED: "TRANSITION_STARTED",
22
- LEAVE_APPROVED: "LEAVE_APPROVED",
23
- DISPOSED: "DISPOSED",
24
- } as const;
25
-
26
- export type RouterState = (typeof routerStates)[keyof typeof routerStates];
27
-
28
- /**
29
- * Router FSM events.
30
- *
31
- * - START: Begin router initialization
32
- * - STARTED: Router initialization complete
33
- * - NAVIGATE: Begin navigation
34
- * - COMPLETE: Navigation completed successfully
35
- * - FAIL: Navigation or initialization failed
36
- * - CANCEL: Navigation cancelled
37
- * - STOP: Stop router
38
- * - DISPOSE: Dispose router (R2+)
39
- */
40
- export const routerEvents = {
41
- START: "START",
42
- STARTED: "STARTED",
43
- NAVIGATE: "NAVIGATE",
44
- LEAVE_APPROVE: "LEAVE_APPROVE",
45
- COMPLETE: "COMPLETE",
46
- FAIL: "FAIL",
47
- CANCEL: "CANCEL",
48
- STOP: "STOP",
49
- DISPOSE: "DISPOSE",
50
- } as const;
51
-
52
- export type RouterEvent = (typeof routerEvents)[keyof typeof routerEvents];
53
-
54
- /**
55
- * Typed payloads for router FSM events.
56
- *
57
- * Events without entries have no payload.
58
- */
59
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- payloads stored in EventBusNamespace fields (N8+N9 optimization)
60
- export interface RouterPayloads {}
61
-
62
- /**
63
- * Router FSM configuration.
64
- *
65
- * Transitions:
66
- * - IDLE → STARTING (START), DISPOSED (DISPOSE)
67
- * - STARTING → READY (STARTED), IDLE (FAIL)
68
- * - READY → TRANSITION_STARTED (NAVIGATE), READY (FAIL, self-loop for early validation errors), IDLE (STOP)
69
- * - TRANSITION_STARTED → LEAVE_APPROVED (LEAVE_APPROVE), TRANSITION_STARTED (NAVIGATE, self-loop), READY (CANCEL, FAIL)
70
- * - LEAVE_APPROVED → READY (COMPLETE, CANCEL, FAIL), TRANSITION_STARTED (NAVIGATE)
71
- * - DISPOSED → (no transitions)
72
- */
73
- const routerFSMConfig: FSMConfig<RouterState, RouterEvent, null> = {
74
- initial: routerStates.IDLE,
75
- context: null,
76
- transitions: {
77
- [routerStates.IDLE]: {
78
- [routerEvents.START]: routerStates.STARTING,
79
- [routerEvents.DISPOSE]: routerStates.DISPOSED,
80
- },
81
- [routerStates.STARTING]: {
82
- [routerEvents.STARTED]: routerStates.READY,
83
- [routerEvents.FAIL]: routerStates.IDLE,
84
- },
85
- [routerStates.READY]: {
86
- [routerEvents.NAVIGATE]: routerStates.TRANSITION_STARTED,
87
- [routerEvents.FAIL]: routerStates.READY,
88
- [routerEvents.STOP]: routerStates.IDLE,
89
- },
90
- [routerStates.TRANSITION_STARTED]: {
91
- [routerEvents.NAVIGATE]: routerStates.TRANSITION_STARTED,
92
- [routerEvents.LEAVE_APPROVE]: routerStates.LEAVE_APPROVED,
93
- [routerEvents.CANCEL]: routerStates.READY,
94
- [routerEvents.FAIL]: routerStates.READY,
95
- },
96
- [routerStates.LEAVE_APPROVED]: {
97
- [routerEvents.NAVIGATE]: routerStates.TRANSITION_STARTED,
98
- [routerEvents.COMPLETE]: routerStates.READY,
99
- [routerEvents.CANCEL]: routerStates.READY,
100
- [routerEvents.FAIL]: routerStates.READY,
101
- },
102
- [routerStates.DISPOSED]: {},
103
- },
104
- };
105
-
106
- /**
107
- * Factory function to create a router FSM instance.
108
- *
109
- * @returns FSM instance with initial state "IDLE"
110
- */
111
- export function createRouterFSM(): FSM<
112
- RouterState,
113
- RouterEvent,
114
- null,
115
- RouterPayloads
116
- > {
117
- return new FSM<RouterState, RouterEvent, null, RouterPayloads>(
118
- routerFSMConfig,
119
- );
120
- }
@@ -1,30 +0,0 @@
1
- import type {
2
- Navigator,
3
- DefaultDependencies,
4
- Router,
5
- } from "@real-router/types";
6
-
7
- const cache = new WeakMap<Router, Navigator>();
8
-
9
- export const getNavigator = <
10
- Dependencies extends DefaultDependencies = DefaultDependencies,
11
- >(
12
- router: Router<Dependencies>,
13
- ): Navigator => {
14
- let nav = cache.get(router);
15
-
16
- if (!nav) {
17
- nav = Object.freeze({
18
- navigate: router.navigate,
19
- getState: router.getState,
20
- isActiveRoute: router.isActiveRoute,
21
- canNavigateTo: router.canNavigateTo,
22
- subscribe: router.subscribe,
23
- subscribeLeave: router.subscribeLeave,
24
- isLeaveApproved: router.isLeaveApproved,
25
- } as Navigator);
26
- cache.set(router, nav);
27
- }
28
-
29
- return nav;
30
- };
package/src/guards.ts DELETED
@@ -1,46 +0,0 @@
1
- // packages/core/src/guards.ts
2
-
3
- import type { Route } from "./types";
4
- import type { RouterValidator } from "./types/RouterValidator";
5
-
6
- export function guardDependencies(deps: unknown): void {
7
- if (
8
- !deps ||
9
- typeof deps !== "object" ||
10
- (deps as { constructor: unknown }).constructor !== Object
11
- ) {
12
- throw new TypeError("dependencies must be a plain object");
13
- }
14
- for (const key in deps as Record<string, unknown>) {
15
- if (Object.getOwnPropertyDescriptor(deps, key)?.get) {
16
- throw new TypeError(`dependencies cannot contain getters: "${key}"`);
17
- }
18
- }
19
- }
20
-
21
- /* eslint-disable @typescript-eslint/no-explicit-any -- accepts any Route type */
22
- export function guardRouteStructure(
23
- routes: Route<any>[],
24
- validator?: RouterValidator | null,
25
- ): void {
26
- /* eslint-enable @typescript-eslint/no-explicit-any */
27
- for (const route of routes) {
28
- const routeValue: unknown = route;
29
-
30
- if (
31
- routeValue === null ||
32
- typeof routeValue !== "object" ||
33
- Array.isArray(routeValue)
34
- ) {
35
- throw new TypeError("route must be a non-array object");
36
- }
37
-
38
- validator?.routes.guardRouteCallbacks(route as Route);
39
- validator?.routes.guardNoAsyncCallbacks(route as Route);
40
- const children = (route as Route).children;
41
-
42
- if (children) {
43
- guardRouteStructure(children, validator);
44
- }
45
- }
46
- }
package/src/helpers.ts DELETED
@@ -1,179 +0,0 @@
1
- // packages/core/src/helpers.ts
2
-
3
- import { DEFAULT_LIMITS } from "./constants";
4
-
5
- import type { Limits } from "./types";
6
- import type { State, LimitsConfig } from "@real-router/types";
7
-
8
- // =============================================================================
9
- // State Helpers
10
- // =============================================================================
11
-
12
- /**
13
- * Structural type guard for State object.
14
- * Only checks required fields exist with correct types.
15
- * Does NOT validate params serializability (allows circular refs).
16
- *
17
- * Use `isState` from type-guards for full validation (serializable params).
18
- * Use this for internal operations like deepFreezeState that handle any object structure.
19
- *
20
- * @param value - Value to check
21
- * @returns true if value has State structure
22
- * @internal
23
- */
24
- function isStateStructural(value: unknown): value is State {
25
- if (value === null || typeof value !== "object") {
26
- return false;
27
- }
28
-
29
- const obj = value as Record<string, unknown>;
30
-
31
- return (
32
- typeof obj.name === "string" &&
33
- typeof obj.path === "string" &&
34
- typeof obj.params === "object" &&
35
- obj.params !== null
36
- );
37
- }
38
-
39
- /**
40
- * Deep freezes State object to prevent mutations.
41
- * Creates a deep clone first, then recursively freezes the clone and all nested objects.
42
- * Uses simple recursive freezing after cloning (no need for WeakSet since clone has no circular refs).
43
- *
44
- * @param state - The State object to freeze
45
- * @returns A frozen deep clone of the state
46
- * @throws {TypeError} If state is not a valid State object
47
- *
48
- * @example
49
- * const state = { name: 'home', params: {}, path: '/' };
50
- * const frozen = deepFreezeState(state);
51
- * // frozen.params is now immutable
52
- * // original state is unchanged
53
- */
54
- export function deepFreezeState<T extends State>(state: T): T {
55
- // Early return for null/undefined
56
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
57
- if (!state) {
58
- return state;
59
- }
60
-
61
- // Validate State structure (structural check, allows circular refs)
62
- if (!isStateStructural(state)) {
63
- throw new TypeError(
64
- `[deepFreezeState] Expected valid State object, got: ${typeof state}`,
65
- );
66
- }
67
-
68
- // Create a deep clone to avoid mutating the original
69
- // structuredClone preserves circular references, so we need to track visited objects
70
- const clonedState = structuredClone(state);
71
-
72
- // WeakSet to track visited objects (prevent infinite recursion with circular refs)
73
- const visited = new WeakSet<object>();
74
-
75
- // Recursive freeze function with circular reference protection
76
- function freezeClonedRecursive(obj: unknown): void {
77
- // Skip primitives, null, undefined
78
- // Note: typeof undefined === "undefined" !== "object", so checking undefined is redundant
79
- if (obj === null || typeof obj !== "object") {
80
- return;
81
- }
82
-
83
- // Skip already visited objects (circular reference protection)
84
- if (visited.has(obj)) {
85
- return;
86
- }
87
-
88
- // Mark as visited
89
- visited.add(obj);
90
-
91
- // Freeze the object/array itself
92
- Object.freeze(obj);
93
-
94
- // Iterate without Object.values() allocation
95
- if (Array.isArray(obj)) {
96
- for (const item of obj) {
97
- freezeClonedRecursive(item);
98
- }
99
- } else {
100
- for (const key in obj) {
101
- freezeClonedRecursive((obj as Record<string, unknown>)[key]);
102
- }
103
- }
104
- }
105
-
106
- // Freeze the entire cloned state tree
107
- freezeClonedRecursive(clonedState);
108
-
109
- return clonedState;
110
- }
111
-
112
- // WeakSet to track already frozen root objects for O(1) re-freeze check
113
- const frozenRoots = new WeakSet<object>();
114
-
115
- // Module-scope recursive freeze function - better JIT optimization, no allocation per call
116
- function freezeRecursive(obj: unknown): void {
117
- // Skip primitives, null
118
- if (obj === null || typeof obj !== "object") {
119
- return;
120
- }
121
-
122
- // Skip already frozen objects (handles potential shared refs)
123
- if (Object.isFrozen(obj)) {
124
- return;
125
- }
126
-
127
- // Freeze the object/array
128
- Object.freeze(obj);
129
-
130
- // Iterate without Object.values() allocation
131
- if (Array.isArray(obj)) {
132
- for (const item of obj) {
133
- freezeRecursive(item);
134
- }
135
- } else {
136
- for (const key in obj) {
137
- freezeRecursive((obj as Record<string, unknown>)[key]);
138
- }
139
- }
140
- }
141
-
142
- /**
143
- * Freezes State object in-place without cloning.
144
- * Optimized for hot paths where state is known to be a fresh object.
145
- *
146
- * IMPORTANT: Only use this when you know the state is a fresh object
147
- * that hasn't been exposed to external code yet (e.g., from makeState()).
148
- *
149
- * @param state - The State object to freeze (must be a fresh object)
150
- * @returns The same state object, now frozen
151
- * @internal
152
- */
153
- export function freezeStateInPlace<T extends State>(state: T): T {
154
- // Early return for null/undefined - state from makeState() is never null
155
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
156
- if (!state) {
157
- return state;
158
- }
159
-
160
- // Fast path: already processed root object - O(1) check
161
- if (frozenRoots.has(state)) {
162
- return state;
163
- }
164
-
165
- freezeRecursive(state);
166
-
167
- // Mark root as processed for future calls
168
- frozenRoots.add(state);
169
-
170
- return state;
171
- }
172
-
173
- /**
174
- * Merges user limits with defaults.
175
- * Returns frozen object for immutability.
176
- */
177
- export function createLimits(userLimits: Partial<LimitsConfig> = {}): Limits {
178
- return { ...DEFAULT_LIMITS, ...userLimits };
179
- }
package/src/index.ts DELETED
@@ -1,50 +0,0 @@
1
- // packages/core/src/index.ts
2
-
3
- // Router-dependent types (re-exported from @real-router/types)
4
-
5
- export type {
6
- BuildStateResultWithSegments,
7
- GuardFnFactory,
8
- PluginFactory,
9
- Route,
10
- RouteConfigUpdate,
11
- } from "./types";
12
-
13
- export type { RouterValidator } from "./types/RouterValidator";
14
-
15
- // Router class (replaces Router interface from core-types)
16
- export { Router } from "./Router";
17
-
18
- // Types (re-exported from core-types - no Router dependency)
19
- export type {
20
- Config,
21
- DefaultDependencies,
22
- GuardFn,
23
- Listener,
24
- Navigator,
25
- NavigationOptions,
26
- Options,
27
- Params,
28
- Plugin,
29
- SimpleState,
30
- State,
31
- SubscribeFn,
32
- SubscribeState,
33
- Subscription,
34
- Unsubscribe,
35
- } from "@real-router/types";
36
-
37
- export type { ErrorCodes, Constants } from "./constants";
38
-
39
- export { events, constants, errorCodes, UNKNOWN_ROUTE } from "./constants";
40
-
41
- // RouterError class (migrated from router-error package)
42
- export { RouterError } from "./RouterError";
43
-
44
- export { createRouter } from "./createRouter";
45
-
46
- export { getNavigator } from "./getNavigator";
47
-
48
- export { resolveForwardChain } from "./namespaces/RoutesNamespace/forwardChain";
49
-
50
- export type { RouteTree } from "route-tree";
package/src/internals.ts DELETED
@@ -1,173 +0,0 @@
1
- import type { DependenciesStore } from "./namespaces/DependenciesNamespace";
2
- import type { RoutesStore } from "./namespaces/RoutesNamespace";
3
- import type { Router as RouterClass } from "./Router";
4
- import type { EventMethodMap, GuardFnFactory, PluginFactory } from "./types";
5
- import type { RouterValidator } from "./types/RouterValidator";
6
- import type {
7
- DefaultDependencies,
8
- EventName,
9
- Options,
10
- Params,
11
- Plugin,
12
- Router as RouterInterface,
13
- RouteTreeState,
14
- SimpleState,
15
- State,
16
- Unsubscribe,
17
- } from "@real-router/types";
18
- import type { RouteTree } from "route-tree";
19
-
20
- export interface RouterInternals<
21
- D extends DefaultDependencies = DefaultDependencies,
22
- > {
23
- readonly makeState: <P extends Params = Params>(
24
- name: string,
25
- params?: P,
26
- path?: string,
27
- meta?: Record<string, Record<string, "url" | "query">>,
28
- ) => State<P>;
29
-
30
- readonly forwardState: <P extends Params = Params>(
31
- routeName: string,
32
- routeParams: P,
33
- ) => SimpleState<P>;
34
-
35
- readonly buildStateResolved: (
36
- resolvedName: string,
37
- resolvedParams: Params,
38
- ) => RouteTreeState | undefined;
39
-
40
- readonly matchPath: <P extends Params = Params>(
41
- path: string,
42
- options?: Options,
43
- ) => State<P> | undefined;
44
-
45
- readonly getOptions: () => Options;
46
-
47
- readonly addEventListener: <E extends EventName>(
48
- eventName: E,
49
- cb: Plugin[EventMethodMap[E]],
50
- ) => Unsubscribe;
51
-
52
- readonly buildPath: (route: string, params?: Params) => string;
53
-
54
- readonly start: (path: string) => Promise<State>;
55
-
56
- /* eslint-disable @typescript-eslint/no-explicit-any -- heterogeneous map: stores different InterceptorFn<M> types under different keys */
57
- readonly interceptors: Map<
58
- string,
59
- ((next: (...args: any[]) => any, ...args: any[]) => any)[]
60
- >;
61
- /* eslint-enable @typescript-eslint/no-explicit-any */
62
-
63
- readonly setRootPath: (rootPath: string) => void;
64
- readonly getRootPath: () => string;
65
-
66
- readonly getTree: () => RouteTree;
67
-
68
- readonly isDisposed: () => boolean;
69
-
70
- validator: RouterValidator | null;
71
-
72
- // Dependencies (issue #172)
73
- readonly dependenciesGetStore: () => DependenciesStore<D>;
74
-
75
- // Clone support (issue #173)
76
- readonly cloneOptions: () => Options;
77
- readonly cloneDependencies: () => Record<string, unknown>;
78
- readonly getLifecycleFactories: () => [
79
- Record<string, GuardFnFactory<D>>,
80
- Record<string, GuardFnFactory<D>>,
81
- ];
82
- readonly getPluginFactories: () => PluginFactory<D>[];
83
-
84
- // Consolidated route data store (issue #174 Phase 2)
85
- readonly routeGetStore: () => RoutesStore<D>;
86
-
87
- // Cross-namespace state (issue #174)
88
- readonly getStateName: () => string | undefined;
89
- readonly isTransitioning: () => boolean;
90
- readonly clearState: () => void;
91
- readonly setState: (state: State) => void;
92
- readonly routerExtensions: { keys: string[] }[];
93
- }
94
-
95
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- existential type: stores RouterInternals for all Dependencies types
96
- const internals = new WeakMap<object, RouterInternals<any>>();
97
-
98
- export function getInternals<D extends DefaultDependencies>(
99
- router: RouterInterface<D>,
100
- ): RouterInternals<D> {
101
- const ctx = internals.get(router);
102
-
103
- if (!ctx) {
104
- throw new TypeError(
105
- "[real-router] Invalid router instance — not found in internals registry",
106
- );
107
- }
108
-
109
- return ctx as RouterInternals<D>;
110
- }
111
-
112
- export function registerInternals<D extends DefaultDependencies>(
113
- router: RouterClass<D>,
114
- ctx: RouterInternals<D>,
115
- ): void {
116
- internals.set(router, ctx);
117
- }
118
-
119
- /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-argument -- internal chain execution: type safety enforced at public API boundary (PluginApi.addInterceptor) */
120
- function executeInterceptorChain<T>(
121
- interceptors: ((next: (...args: any[]) => any, ...args: any[]) => any)[],
122
- original: (...args: any[]) => T,
123
- args: any[],
124
- ): T {
125
- let chain = original as (...args: any[]) => any;
126
-
127
- for (const interceptor of interceptors) {
128
- const prev = chain;
129
-
130
- chain = (...chainArgs: any[]) => interceptor(prev, ...chainArgs);
131
- }
132
-
133
- return chain(...args) as T;
134
- }
135
-
136
- export function createInterceptable<T extends (...args: any[]) => any>(
137
- name: string,
138
- original: T,
139
- interceptors: Map<
140
- string,
141
- ((next: (...args: any[]) => any, ...args: any[]) => any)[]
142
- >,
143
- ): T {
144
- return ((...args: any[]) => {
145
- const chain = interceptors.get(name);
146
-
147
- if (!chain || chain.length === 0) {
148
- return original(...args);
149
- }
150
-
151
- return executeInterceptorChain(chain, original, args);
152
- }) as T;
153
- }
154
-
155
- export function createInterceptable2<A, B, R>(
156
- name: string,
157
- original: (a: A, b: B) => R,
158
- interceptors: Map<
159
- string,
160
- ((next: (...args: any[]) => any, ...args: any[]) => any)[]
161
- >,
162
- ): (a: A, b: B) => R {
163
- return (arg1: A, arg2: B) => {
164
- const chain = interceptors.get(name);
165
-
166
- if (!chain || chain.length === 0) {
167
- return original(arg1, arg2);
168
- }
169
-
170
- return executeInterceptorChain(chain, original, [arg1, arg2]);
171
- };
172
- }
173
- /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-argument */
@@ -1,30 +0,0 @@
1
- import { DEFAULT_LIMITS } from "../../constants";
2
-
3
- import type { Limits } from "../../types";
4
- import type { DefaultDependencies } from "@real-router/types";
5
-
6
- export interface DependenciesStore<
7
- Dependencies extends DefaultDependencies = DefaultDependencies,
8
- > {
9
- dependencies: Partial<Dependencies>;
10
- limits: Limits;
11
- }
12
-
13
- export function createDependenciesStore<
14
- Dependencies extends DefaultDependencies = DefaultDependencies,
15
- >(
16
- initialDependencies: Partial<Dependencies> = {} as Dependencies,
17
- ): DependenciesStore<Dependencies> {
18
- const dependencies = Object.create(null) as Partial<Dependencies>;
19
-
20
- for (const key in initialDependencies) {
21
- if (initialDependencies[key] !== undefined) {
22
- dependencies[key] = initialDependencies[key];
23
- }
24
- }
25
-
26
- return {
27
- dependencies,
28
- limits: DEFAULT_LIMITS,
29
- };
30
- }
@@ -1,5 +0,0 @@
1
- // packages/core/src/namespaces/DependenciesNamespace/index.ts
2
-
3
- export { createDependenciesStore } from "./dependenciesStore";
4
-
5
- export type { DependenciesStore } from "./dependenciesStore";