@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
@@ -0,0 +1,184 @@
1
+ import { L as Limits, R as RouterValidator } from './RouterValidator-mx2Zooya.js';
2
+ import { DefaultDependencies, Params, ForwardToCallback, GuardFnFactory, State, SimpleState, GuardFn, RouteTreeState, Options, EventName, Plugin, EventMethodMap, Unsubscribe, PluginFactory, Router } from '@real-router/types';
3
+ import { a as RouteDefinition, R as RouteTree, M as Matcher, C as CreateMatcherOptions } from './index.d-y2b-8_3Y.js';
4
+
5
+ interface DependenciesStore<Dependencies extends DefaultDependencies = DefaultDependencies> {
6
+ dependencies: Partial<Dependencies>;
7
+ limits: Limits;
8
+ }
9
+
10
+ /**
11
+ * Dependencies injected into RoutesNamespace.
12
+ *
13
+ * These are function references from the Router facade,
14
+ * avoiding the need to pass the entire Router object.
15
+ */
16
+ interface RoutesDependencies<Dependencies extends DefaultDependencies = DefaultDependencies> {
17
+ /** Register canActivate handler for a route */
18
+ addActivateGuard: (name: string, handler: GuardFnFactory<Dependencies>) => void;
19
+ /** Register canDeactivate handler for a route */
20
+ addDeactivateGuard: (name: string, handler: GuardFnFactory<Dependencies>) => void;
21
+ /** Create state object */
22
+ makeState: <P extends Params = Params, MP extends Params = Params>(name: string, params?: P, path?: string, meta?: Record<string, Record<string, "url" | "query">>) => State<P, MP>;
23
+ /** Get current router state */
24
+ getState: () => State | undefined;
25
+ /** Compare two states for equality */
26
+ areStatesEqual: (state1: State | undefined, state2: State | undefined, ignoreQueryParams?: boolean) => boolean;
27
+ /** Get a dependency by name */
28
+ getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K];
29
+ /** Forward state through facade (allows plugin interception) */
30
+ forwardState: <P extends Params = Params>(name: string, params: P) => SimpleState<P>;
31
+ }
32
+ /**
33
+ * Configuration storage for routes.
34
+ * Stores decoders, encoders, default params, and forward mappings.
35
+ */
36
+ interface RouteConfig {
37
+ /** Custom param decoders per route */
38
+ decoders: Record<string, (params: Params) => Params>;
39
+ /** Custom param encoders per route */
40
+ encoders: Record<string, (params: Params) => Params>;
41
+ /** Default params per route */
42
+ defaultParams: Record<string, Params>;
43
+ /** Forward mappings (source -> target) */
44
+ forwardMap: Record<string, string>;
45
+ /** Dynamic forward callbacks (source -> callback) */
46
+ forwardFnMap: Record<string, ForwardToCallback<any>>;
47
+ }
48
+
49
+ interface RouteLifecycleDependencies<Dependencies extends DefaultDependencies = DefaultDependencies> {
50
+ compileFactory: (factory: GuardFnFactory<Dependencies>) => GuardFn;
51
+ }
52
+
53
+ /**
54
+ * Independent namespace for managing route lifecycle handlers.
55
+ *
56
+ * Static methods handle input validation (called by facade).
57
+ * Instance methods handle state-dependent validation, storage and business logic.
58
+ */
59
+ declare class RouteLifecycleNamespace<Dependencies extends DefaultDependencies = DefaultDependencies> {
60
+ #private;
61
+ setDependencies(deps: RouteLifecycleDependencies<Dependencies>): void;
62
+ /**
63
+ * Updates handler registration limits (max lifecycle handlers threshold).
64
+ *
65
+ * @param limits - Limits configuration with maxLifecycleHandlers
66
+ */
67
+ setLimits(limits: Limits): void;
68
+ setValidatorGetter(getter: () => RouterValidator | null): void;
69
+ getHandlerCount(type: "activate" | "deactivate"): number;
70
+ /**
71
+ * Adds a canActivate guard for a route.
72
+ * Handles overwrite detection and registration.
73
+ *
74
+ * @param name - Route name (input-validated by facade)
75
+ * @param handler - Guard function or boolean (input-validated by facade)
76
+ * @param isFromDefinition - True when guard comes from route definition (tracked for HMR replace)
77
+ */
78
+ addCanActivate(name: string, handler: GuardFnFactory<Dependencies> | boolean, isFromDefinition?: boolean): void;
79
+ /**
80
+ * Adds a canDeactivate guard for a route.
81
+ * Handles overwrite detection and registration.
82
+ *
83
+ * @param name - Route name (input-validated by facade)
84
+ * @param handler - Guard function or boolean (input-validated by facade)
85
+ * @param isFromDefinition - True when guard comes from route definition (tracked for HMR replace)
86
+ */
87
+ addCanDeactivate(name: string, handler: GuardFnFactory<Dependencies> | boolean, isFromDefinition?: boolean): void;
88
+ /**
89
+ * Removes a canActivate guard for a route.
90
+ * Input already validated by facade (not registering).
91
+ *
92
+ * @param name - Route name (already validated by facade)
93
+ */
94
+ clearCanActivate(name: string): void;
95
+ /**
96
+ * Removes a canDeactivate guard for a route.
97
+ * Input already validated by facade (not registering).
98
+ *
99
+ * @param name - Route name (already validated by facade)
100
+ */
101
+ clearCanDeactivate(name: string): void;
102
+ /**
103
+ * Clears all lifecycle handlers (canActivate and canDeactivate).
104
+ * Used by clearRoutes to reset all lifecycle state.
105
+ */
106
+ clearAll(): void;
107
+ /**
108
+ * Clears only lifecycle handlers that were registered from route definitions.
109
+ * Used by HMR to remove definition-sourced guards without touching externally-added guards.
110
+ */
111
+ clearDefinitionGuards(): void;
112
+ /**
113
+ * Returns lifecycle factories as records for cloning.
114
+ *
115
+ * @returns Tuple of [canDeactivateFactories, canActivateFactories]
116
+ */
117
+ getFactories(): [
118
+ Record<string, GuardFnFactory<Dependencies>>,
119
+ Record<string, GuardFnFactory<Dependencies>>
120
+ ];
121
+ /**
122
+ * Returns compiled lifecycle functions for transition execution.
123
+ *
124
+ * @returns Tuple of [canDeactivateFunctions, canActivateFunctions] as Maps
125
+ */
126
+ getFunctions(): [Map<string, GuardFn>, Map<string, GuardFn>];
127
+ canNavigateTo(toDeactivate: string[], toActivate: string[], toState: State, fromState: State | undefined): boolean;
128
+ }
129
+
130
+ interface RoutesStore<Dependencies extends DefaultDependencies = DefaultDependencies> {
131
+ readonly definitions: RouteDefinition[];
132
+ readonly config: RouteConfig;
133
+ tree: RouteTree;
134
+ matcher: Matcher;
135
+ resolvedForwardMap: Record<string, string>;
136
+ routeCustomFields: Record<string, Record<string, unknown>>;
137
+ rootPath: string;
138
+ readonly matcherOptions: CreateMatcherOptions | undefined;
139
+ depsStore: RoutesDependencies<Dependencies> | undefined;
140
+ lifecycleNamespace: RouteLifecycleNamespace<Dependencies> | undefined;
141
+ readonly pendingCanActivate: Map<string, GuardFnFactory<Dependencies>>;
142
+ readonly pendingCanDeactivate: Map<string, GuardFnFactory<Dependencies>>;
143
+ readonly treeOperations: {
144
+ readonly commitTreeChanges: (store: RoutesStore<Dependencies>) => void;
145
+ readonly resetStore: (store: RoutesStore<Dependencies>) => void;
146
+ readonly nodeToDefinition: (node: RouteTree) => RouteDefinition;
147
+ };
148
+ }
149
+
150
+ interface RouterInternals<D extends DefaultDependencies = DefaultDependencies> {
151
+ readonly makeState: <P extends Params = Params, MP extends Params = Params>(name: string, params?: P, path?: string, meta?: Record<string, Record<string, "url" | "query">>, forceId?: number) => State<P, MP>;
152
+ readonly forwardState: <P extends Params = Params>(routeName: string, routeParams: P) => SimpleState<P>;
153
+ readonly buildStateResolved: (resolvedName: string, resolvedParams: Params) => RouteTreeState | undefined;
154
+ readonly matchPath: <P extends Params = Params, MP extends Params = Params>(path: string, options?: Options) => State<P, MP> | undefined;
155
+ readonly getOptions: () => Options;
156
+ readonly addEventListener: <E extends EventName>(eventName: E, cb: Plugin[EventMethodMap[E]]) => Unsubscribe;
157
+ readonly buildPath: (route: string, params?: Params) => string;
158
+ readonly start: (path: string) => Promise<State>;
159
+ readonly interceptors: Map<string, ((next: (...args: any[]) => any, ...args: any[]) => any)[]>;
160
+ readonly setRootPath: (rootPath: string) => void;
161
+ readonly getRootPath: () => string;
162
+ readonly getTree: () => RouteTree;
163
+ readonly isDisposed: () => boolean;
164
+ validator: RouterValidator | null;
165
+ readonly dependenciesGetStore: () => DependenciesStore<D>;
166
+ readonly cloneOptions: () => Options;
167
+ readonly cloneDependencies: () => Record<string, unknown>;
168
+ readonly getLifecycleFactories: () => [
169
+ Record<string, GuardFnFactory<D>>,
170
+ Record<string, GuardFnFactory<D>>
171
+ ];
172
+ readonly getPluginFactories: () => PluginFactory<D>[];
173
+ readonly routeGetStore: () => RoutesStore<D>;
174
+ readonly getStateName: () => string | undefined;
175
+ readonly isTransitioning: () => boolean;
176
+ readonly clearState: () => void;
177
+ readonly setState: (state: State) => void;
178
+ readonly routerExtensions: {
179
+ keys: string[];
180
+ }[];
181
+ }
182
+ declare function getInternals<D extends DefaultDependencies>(router: Router<D>): RouterInternals<D>;
183
+
184
+ export { type RouterInternals, RouterValidator, getInternals };
@@ -0,0 +1 @@
1
+ var r=new WeakMap;exports.getInternals=function(n){const e=r.get(n);if(!e)throw new TypeError("[real-router] Invalid router instance — not found in internals registry");return e};//# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/internals.ts"],"names":[],"mappings":";AAgGA,IAAM,SAAA,uBAAgB,OAAA,EAAsC;AAErD,SAAS,aACd,MAAA,EACoB;AACpB,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,GAAA,CAAI,MAAM,CAAA;AAEhC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,SAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,GAAA;AACT","file":"validation.js","sourcesContent":["import type { DependenciesStore } from \"./namespaces/DependenciesNamespace\";\nimport type { RoutesStore } from \"./namespaces/RoutesNamespace\";\nimport type { Router as RouterClass } from \"./Router\";\nimport type { EventMethodMap, GuardFnFactory, PluginFactory } from \"./types\";\nimport type { RouterValidator } from \"./types/RouterValidator\";\nimport type {\n DefaultDependencies,\n EventName,\n Options,\n Params,\n Plugin,\n Router as RouterInterface,\n RouteTreeState,\n SimpleState,\n State,\n Unsubscribe,\n} from \"@real-router/types\";\nimport type { RouteTree } from \"route-tree\";\n\nexport interface RouterInternals<\n D extends DefaultDependencies = DefaultDependencies,\n> {\n readonly makeState: <P extends Params = Params, MP extends Params = Params>(\n name: string,\n params?: P,\n path?: string,\n meta?: Record<string, Record<string, \"url\" | \"query\">>,\n forceId?: number,\n ) => State<P, MP>;\n\n readonly forwardState: <P extends Params = Params>(\n routeName: string,\n routeParams: P,\n ) => SimpleState<P>;\n\n readonly buildStateResolved: (\n resolvedName: string,\n resolvedParams: Params,\n ) => RouteTreeState | undefined;\n\n readonly matchPath: <P extends Params = Params, MP extends Params = Params>(\n path: string,\n options?: Options,\n ) => State<P, MP> | undefined;\n\n readonly getOptions: () => Options;\n\n readonly addEventListener: <E extends EventName>(\n eventName: E,\n cb: Plugin[EventMethodMap[E]],\n ) => Unsubscribe;\n\n readonly buildPath: (route: string, params?: Params) => string;\n\n readonly start: (path: string) => Promise<State>;\n\n /* eslint-disable @typescript-eslint/no-explicit-any -- heterogeneous map: stores different InterceptorFn<M> types under different keys */\n readonly interceptors: Map<\n string,\n ((next: (...args: any[]) => any, ...args: any[]) => any)[]\n >;\n /* eslint-enable @typescript-eslint/no-explicit-any */\n\n readonly setRootPath: (rootPath: string) => void;\n readonly getRootPath: () => string;\n\n readonly getTree: () => RouteTree;\n\n readonly isDisposed: () => boolean;\n\n validator: RouterValidator | null;\n\n // Dependencies (issue #172)\n readonly dependenciesGetStore: () => DependenciesStore<D>;\n\n // Clone support (issue #173)\n readonly cloneOptions: () => Options;\n readonly cloneDependencies: () => Record<string, unknown>;\n readonly getLifecycleFactories: () => [\n Record<string, GuardFnFactory<D>>,\n Record<string, GuardFnFactory<D>>,\n ];\n readonly getPluginFactories: () => PluginFactory<D>[];\n\n // Consolidated route data store (issue #174 Phase 2)\n readonly routeGetStore: () => RoutesStore<D>;\n\n // Cross-namespace state (issue #174)\n readonly getStateName: () => string | undefined;\n readonly isTransitioning: () => boolean;\n readonly clearState: () => void;\n readonly setState: (state: State) => void;\n readonly routerExtensions: { keys: string[] }[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- existential type: stores RouterInternals for all Dependencies types\nconst internals = new WeakMap<object, RouterInternals<any>>();\n\nexport function getInternals<D extends DefaultDependencies>(\n router: RouterInterface<D>,\n): RouterInternals<D> {\n const ctx = internals.get(router);\n\n if (!ctx) {\n throw new TypeError(\n \"[real-router] Invalid router instance — not found in internals registry\",\n );\n }\n\n return ctx as RouterInternals<D>;\n}\n\nexport function registerInternals<D extends DefaultDependencies>(\n router: RouterClass<D>,\n ctx: RouterInternals<D>,\n): void {\n internals.set(router, ctx);\n}\n\n/* 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) */\nfunction executeInterceptorChain<T>(\n interceptors: ((next: (...args: any[]) => any, ...args: any[]) => any)[],\n original: (...args: any[]) => T,\n args: any[],\n): T {\n let chain = original as (...args: any[]) => any;\n\n for (const interceptor of interceptors) {\n const prev = chain;\n\n chain = (...chainArgs: any[]) => interceptor(prev, ...chainArgs);\n }\n\n return chain(...args) as T;\n}\n\nexport function createInterceptable<T extends (...args: any[]) => any>(\n name: string,\n original: T,\n interceptors: Map<\n string,\n ((next: (...args: any[]) => any, ...args: any[]) => any)[]\n >,\n): T {\n return ((...args: any[]) => {\n const chain = interceptors.get(name);\n\n if (!chain || chain.length === 0) {\n return original(...args);\n }\n\n return executeInterceptorChain(chain, original, args);\n }) as T;\n}\n\nexport function createInterceptable2<A, B, R>(\n name: string,\n original: (a: A, b: B) => R,\n interceptors: Map<\n string,\n ((next: (...args: any[]) => any, ...args: any[]) => any)[]\n >,\n): (a: A, b: B) => R {\n return (arg1: A, arg2: B) => {\n const chain = interceptors.get(name);\n\n if (!chain || chain.length === 0) {\n return original(arg1, arg2);\n }\n\n return executeInterceptorChain(chain, original, [arg1, arg2]);\n };\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-argument */\n"]}
@@ -0,0 +1,46 @@
1
+ import { DefaultDependencies, Router as Router$1, Route, Options, Params, State, PluginFactory, Unsubscribe, SubscribeFn, NavigationOptions } from '@real-router/types';
2
+
3
+ /**
4
+ * Router class with integrated namespace architecture.
5
+ *
6
+ * All functionality is provided by namespace classes:
7
+ * - OptionsNamespace: getOptions (immutable)
8
+ * - DependenciesStore: get/set/remove dependencies
9
+ * - EventEmitter: subscribe
10
+ * - StateNamespace: state storage (getState, setState, getPreviousState)
11
+ * - RoutesNamespace: route tree operations
12
+ * - RouteLifecycleNamespace: canActivate/canDeactivate guards
13
+ * - PluginsNamespace: plugin lifecycle
14
+ * - NavigationNamespace: navigate
15
+ * - RouterLifecycleNamespace: start, stop, isStarted
16
+ *
17
+ * @internal This class implementation is internal. Use createRouter() instead.
18
+ */
19
+ declare class Router<Dependencies extends DefaultDependencies = DefaultDependencies> implements Router$1<Dependencies> {
20
+ #private;
21
+ [key: string]: unknown;
22
+ /**
23
+ * @param routes - Route definitions
24
+ * @param options - Router options
25
+ * @param dependencies - DI dependencies
26
+ */
27
+ constructor(routes?: Route<Dependencies>[], options?: Partial<Options>, dependencies?: Dependencies);
28
+ isActiveRoute(name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean): boolean;
29
+ buildPath(route: string, params?: Params): string;
30
+ getState<P extends Params = Params, MP extends Params = Params>(): State<P, MP> | undefined;
31
+ getPreviousState(): State | undefined;
32
+ areStatesEqual(state1: State | undefined, state2: State | undefined, ignoreQueryParams?: boolean): boolean;
33
+ shouldUpdateNode(nodeName: string): (toState: State, fromState?: State) => boolean;
34
+ isActive(): boolean;
35
+ start(startPath: string): Promise<State>;
36
+ stop(): this;
37
+ dispose(): void;
38
+ canNavigateTo(name: string, params?: Params): boolean;
39
+ usePlugin(...plugins: (PluginFactory<Dependencies> | false | null | undefined)[]): Unsubscribe;
40
+ subscribe(listener: SubscribeFn): Unsubscribe;
41
+ navigate(routeName: string, routeParams?: Params, options?: NavigationOptions): Promise<State>;
42
+ navigateToDefault(options?: NavigationOptions): Promise<State>;
43
+ navigateToNotFound(path?: string): State;
44
+ }
45
+
46
+ export { Router as R };
@@ -0,0 +1,136 @@
1
+ import { Params, RouteTreeState, LimitsConfig } from '@real-router/types';
2
+
3
+ /**
4
+ * Core-internal types + re-exports from @real-router/types.
5
+ *
6
+ * Factory types (PluginFactory, GuardFnFactory) and
7
+ * route config types (Route, RouteConfigUpdate) are canonical in @real-router/types
8
+ * and re-exported here for backward compatibility.
9
+ */
10
+
11
+ /**
12
+ * Immutable limits configuration type.
13
+ */
14
+ type Limits = Readonly<LimitsConfig>;
15
+ /**
16
+ * Extended build result that includes segments for path building.
17
+ * Used internally to avoid duplicate getSegmentsByName calls.
18
+ *
19
+ * @param segments - Route segments from getSegmentsByName (typed as unknown[] for cross-package compatibility)
20
+ * @internal
21
+ */
22
+ interface BuildStateResultWithSegments<P extends Params = Params> {
23
+ readonly state: RouteTreeState<P>;
24
+ readonly segments: readonly unknown[];
25
+ }
26
+
27
+ /**
28
+ * RouterValidator interface - defines all validation methods used by the router.
29
+ *
30
+ * This interface is implemented by the validation plugin and injected into RouterInternals.
31
+ * When ctx.validator is null (default), validation is skipped.
32
+ * When ctx.validator is set (by validation plugin), all methods are called.
33
+ *
34
+ * All parameters use `unknown` type to avoid coupling to internal type names.
35
+ */
36
+ interface RouterValidator {
37
+ /**
38
+ * Route validation methods
39
+ */
40
+ routes: {
41
+ validateBuildPathArgs: (route: unknown) => void;
42
+ validateMatchPathArgs: (path: unknown) => void;
43
+ validateIsActiveRouteArgs: (name: unknown, params: unknown, strict: unknown, ignoreQP: unknown) => void;
44
+ validateShouldUpdateNodeArgs: (name: unknown) => void;
45
+ validateStateBuilderArgs: (name: unknown, params: unknown, caller: string) => void;
46
+ validateAddRouteArgs: (routes: unknown) => void;
47
+ validateRoutes: (routes: unknown[], tree: unknown) => void;
48
+ validateRemoveRouteArgs: (name: unknown) => void;
49
+ validateUpdateRouteBasicArgs: (name: unknown, updates: unknown) => void;
50
+ validateUpdateRoutePropertyTypes: (name: string, updates: unknown) => void;
51
+ validateUpdateRoute: (name: string, updates: unknown, tree: unknown) => void;
52
+ validateParentOption: (parent: unknown, tree: unknown) => void;
53
+ validateRouteName: (name: unknown, caller: string) => void;
54
+ throwIfInternalRoute: (name: unknown, caller: string) => void;
55
+ throwIfInternalRouteInArray: (routes: unknown[], caller: string) => void;
56
+ validateExistingRoutes: (store: unknown) => void;
57
+ validateForwardToConsistency: (store: unknown) => void;
58
+ validateSetRootPathArgs: (rootPath: unknown) => void;
59
+ guardRouteCallbacks: (route: unknown) => void;
60
+ guardNoAsyncCallbacks: (route: unknown) => void;
61
+ };
62
+ /**
63
+ * Options validation methods
64
+ */
65
+ options: {
66
+ validateLimitValue: (name: string, value: unknown) => void;
67
+ validateLimits: (limits: unknown) => void;
68
+ validateOptions: (options: unknown, methodName: string) => void;
69
+ };
70
+ /**
71
+ * Dependencies validation methods
72
+ */
73
+ dependencies: {
74
+ validateDependencyName: (name: unknown, caller: string) => void;
75
+ validateSetDependencyArgs: (name: unknown, value: unknown, caller: string) => void;
76
+ validateDependenciesObject: (deps: unknown, caller: string) => void;
77
+ validateDependencyExists: (name: string, store: unknown) => void;
78
+ validateDependencyLimit: (store: unknown, limits: unknown) => void;
79
+ validateDependenciesStructure: (store: unknown) => void;
80
+ validateDependencyCount: (store: unknown, methodName: string) => void;
81
+ validateCloneArgs: (dependencies: unknown) => void;
82
+ warnOverwrite: (name: string, methodName: string) => void;
83
+ warnBatchOverwrite: (keys: string[], methodName: string) => void;
84
+ warnRemoveNonExistent: (name: unknown) => void;
85
+ };
86
+ /**
87
+ * Plugin validation methods
88
+ */
89
+ plugins: {
90
+ validatePluginLimit: (count: number, limits: unknown) => void;
91
+ validateNoDuplicatePlugins: (factory: unknown, factories: unknown[]) => void;
92
+ validatePluginKeys: (plugin: unknown) => void;
93
+ validateCountThresholds: (count: number) => void;
94
+ warnBatchDuplicates: (plugins: unknown[]) => void;
95
+ warnPluginMethodType: (methodName: string) => void;
96
+ warnPluginAfterStart: (methodName: string) => void;
97
+ validateAddInterceptorArgs: (method: unknown, fn: unknown) => void;
98
+ };
99
+ /**
100
+ * Lifecycle guard validation methods
101
+ */
102
+ lifecycle: {
103
+ validateHandler: (handler: unknown, caller: string) => void;
104
+ validateNotRegistering: (name: string, guards: unknown, caller: string) => void;
105
+ validateHandlerLimit: (count: number, limits: unknown, caller: string) => void;
106
+ validateCountThresholds: (count: number, methodName: string) => void;
107
+ warnOverwrite: (name: string, type: string, methodName: string) => void;
108
+ warnAsyncGuardSync: (name: string, methodName: string) => void;
109
+ };
110
+ /**
111
+ * Navigation validation methods
112
+ */
113
+ navigation: {
114
+ validateNavigateArgs: (name: unknown) => void;
115
+ validateNavigateToDefaultArgs: (options: unknown) => void;
116
+ validateNavigationOptions: (options: unknown, caller: string) => void;
117
+ validateParams: (params: unknown, methodName: string) => void;
118
+ validateStartArgs: (path: unknown) => void;
119
+ };
120
+ /**
121
+ * State validation methods
122
+ */
123
+ state: {
124
+ validateMakeStateArgs: (name: unknown, params: unknown, path: unknown, forceId: unknown) => void;
125
+ validateAreStatesEqualArgs: (s1: unknown, s2: unknown, ignoreQP: unknown) => void;
126
+ };
127
+ /**
128
+ * Event bus validation methods
129
+ */
130
+ eventBus: {
131
+ validateEventName: (name: unknown) => void;
132
+ validateListenerArgs: (name: unknown, cb: unknown) => void;
133
+ };
134
+ }
135
+
136
+ export type { BuildStateResultWithSegments as B, Limits as L, RouterValidator as R };
@@ -1,6 +1,7 @@
1
1
  import { PluginApi as PluginApi$1, DefaultDependencies, Router, RoutesApi, DependenciesApi, LifecycleApi } from '@real-router/types';
2
2
  export { DependenciesApi, LifecycleApi, RoutesApi } from '@real-router/types';
3
- import { a as RouteTree, R as Router$1 } from './index.d-DDimDpYc.mjs';
3
+ import { R as RouteTree } from './index.d-y2b-8_3Y.mjs';
4
+ import { R as Router$1 } from './Router-B-Pev7K2.mjs';
4
5
 
5
6
  interface PluginApi extends Omit<PluginApi$1, "getTree"> {
6
7
  getTree: () => RouteTree;
package/dist/esm/api.mjs CHANGED
@@ -1 +1 @@
1
- import{getInternals as e,RouterError as t,errorCodes as n,validateStateBuilderArgs as a,validateSetRootPathArgs as o,validateMatchPathArgs as r,validateClearRoutes as i,throwIfInternalRouteInArray as s,validateAddRouteArgs as d,g as c,validateUpdateRouteBasicArgs as l,throwIfInternalRoute as f,validateUpdateRoutePropertyTypes as u,validateUpdateRoute as p,validateRemoveRouteArgs as m,validateRemoveRoute as g,validateParentOption as v,validateDependencyName as h,j as w,validateDependenciesObject as y,validateDependencyLimit as D,validateSetDependencyArgs as O,validateDependencyExists as S,validateHandler as b,f as P,Router as C,b as T,s as R,clearRouteData as V,sanitizeRoute as G,registerAllRouteHandlers as j,removeFromDefinitions as $,validEventNames as A,clearConfigEntries as E,computeThresholds as N,refreshForwardMap as x}from"./chunk-CG7TKDP3.mjs";import{logger as F}from"@real-router/logger";function M(e){if(e())throw new t(n.ROUTER_DISPOSED)}function k(i){const s=e(i);return{makeState:(e,t,n,a,o)=>(s.noValidate||function(e,t,n,a){if(!T(e))throw new TypeError(`[router.makeState] Invalid name: ${w(e)}. Expected string.`);if(void 0!==t&&!R(t))throw new TypeError(`[router.makeState] Invalid params: ${w(t)}. Expected plain object.`);if(void 0!==n&&!T(n))throw new TypeError(`[router.makeState] Invalid path: ${w(n)}. Expected string.`);if(void 0!==a&&"number"!=typeof a)throw new TypeError(`[router.makeState] Invalid forceId: ${w(a)}. Expected number.`)}(e,t,n,o),s.makeState(e,t,n,a?.params,o)),buildState:(e,t)=>{s.noValidate||a(e,t,"buildState");const{name:n,params:o}=s.forwardState(e,t);return s.buildStateResolved(n,o)},forwardState:(e,t)=>(s.noValidate||a(e,t,"forwardState"),s.forwardState(e,t)),matchPath:e=>(s.noValidate||r(e),s.matchPath(e,s.getOptions())),setRootPath:e=>{M(s.isDisposed),s.noValidate||o(e),s.setRootPath(e)},getRootPath:s.getRootPath,addEventListener:(e,t)=>(M(s.isDisposed),s.noValidate||function(e,t){if(function(e){if(!A.has(e))throw new Error(`Invalid event name: ${String(e)}`)}(e),"function"!=typeof t)throw new TypeError(`Expected callback to be a function for event ${e}`)}(e,t),s.addEventListener(e,t)),buildNavigationState:(e,t={})=>{s.noValidate||a(e,t,"buildNavigationState");const{name:n,params:o}=s.forwardState(e,t),r=s.buildStateResolved(n,o);if(r)return s.makeState(r.name,r.params,s.buildPath(r.name,r.params),r.meta)},getOptions:s.getOptions,getTree:s.getTree,addInterceptor:(e,t)=>{M(s.isDisposed);let n=s.interceptors.get(e);return n||(n=[],s.interceptors.set(e,n)),n.push(t),()=>{const e=n.indexOf(t);-1!==e&&n.splice(e,1)}},getRouteConfig:e=>{const t=s.routeGetStore();if(t.matcher.hasRoute(e))return t.routeCustomFields[e]},extendRouter:e=>{M(s.isDisposed);const a=Object.keys(e);for(const e of a)if(e in i)throw new t(n.PLUGIN_CONFLICT,{message:`Cannot extend router: property "${e}" already exists`});for(const t of a)i[t]=e[t];const o={keys:a};s.routerExtensions.push(o);let r=!1;return()=>{if(r)return;r=!0;for(const e of o.keys)delete i[e];const e=s.routerExtensions.indexOf(o);-1!==e&&s.routerExtensions.splice(e,1)}}}}function I(e,t,n=""){for(const a of e){const e=n?`${n}.${a.name}`:a.name;if(e===t)return a;if(a.children&&t.startsWith(`${e}.`))return I(a.children,t,e)}}function L(e,t,n,a){const o={name:e.name,path:e.path},r=n.forwardFnMap[t],i=n.forwardMap[t];void 0!==r?o.forwardTo=r:void 0!==i&&(o.forwardTo=i),t in n.defaultParams&&(o.defaultParams=n.defaultParams[t]),t in n.decoders&&(o.decodeParams=n.decoders[t]),t in n.encoders&&(o.encodeParams=n.encoders[t]);const[s,d]=a;return t in d&&(o.canActivate=d[t]),t in s&&(o.canDeactivate=s[t]),e.children&&(o.children=e.children.map(e=>L(e,`${t}.${e.name}`,n,a))),o}function U(e,t,n,a){if(a){const t=I(e.definitions,a);t.children??=[];for(const e of n)t.children.push(G(e))}else for(const t of n)e.definitions.push(G(t));j(n,e.config,e.routeCustomFields,e.pendingCanActivate,e.pendingCanDeactivate,e.depsStore,a??""),e.treeOperations.commitTreeChanges(e,t)}function _(e,t){const n=e.matcher.getSegmentsByName(t);if(!n)return;const a=n.at(-1),o=e.treeOperations.nodeToDefinition(a),r=e.lifecycleNamespace.getFactories();return L(o,t,e.config,r)}function W(t){const n=e(t),a=n.routeGetStore(),o=n.noValidate;return{add:(e,t)=>{M(n.isDisposed);const r=Array.isArray(e)?e:[e],i=t?.parent;n.noValidate||(void 0!==i&&v(i),s(r,"addRoute"),d(r),a.treeOperations.validateRoutes(r,a.tree,a.config.forwardMap,i)),U(a,o,r,i)},remove:e=>{M(n.isDisposed),n.noValidate||(m(e),f(e,"removeRoute")),g(e,n.getStateName(),n.isTransitioning())&&(function(e,t,n){return!!$(e.definitions,n)&&(function(e,t,n,a){const o=t=>t===e||t.startsWith(`${e}.`);E(t.decoders,o),E(t.encoders,o),E(t.defaultParams,o),E(t.forwardMap,o),E(t.forwardFnMap,o),E(n,o),E(t.forwardMap,e=>o(t.forwardMap[e]));const[r,i]=a.getFactories();for(const e of Object.keys(i))o(e)&&a.clearCanActivate(e);for(const e of Object.keys(r))o(e)&&a.clearCanDeactivate(e)}(n,e.config,e.routeCustomFields,e.lifecycleNamespace),e.treeOperations.commitTreeChanges(e,t),!0)}(a,o,e)||F.warn("router.removeRoute",`Route "${e}" not found. No changes made.`))},update:(e,t)=>{M(n.isDisposed),n.noValidate||(l(e,t),f(e,"updateRoute"));const{forwardTo:r,defaultParams:i,decodeParams:s,encodeParams:d,canActivate:c,canDeactivate:m}=t;n.noValidate||u(r,i,s,d),n.isTransitioning()&&F.error("router.updateRoute",`Updating route "${e}" while navigation is in progress. This may cause unexpected behavior.`),n.noValidate||p(e,r,e=>a.matcher.hasRoute(e),a.matcher,a.config),function(e,t,n,a){if(void 0!==a.forwardTo&&(e.resolvedForwardMap=function(e,t,n,a,o){return null===t?(delete n.forwardMap[e],delete n.forwardFnMap[e]):"string"==typeof t?(delete n.forwardFnMap[e],n.forwardMap[e]=t):(delete n.forwardMap[e],n.forwardFnMap[e]=t),o(n,a)}(n,a.forwardTo,e.config,t,x)),void 0!==a.defaultParams&&(null===a.defaultParams?delete e.config.defaultParams[n]:e.config.defaultParams[n]=a.defaultParams),void 0!==a.decodeParams)if(null===a.decodeParams)delete e.config.decoders[n];else{const t=a.decodeParams;e.config.decoders[n]=e=>t(e)??e}if(void 0!==a.encodeParams)if(null===a.encodeParams)delete e.config.encoders[n];else{const t=a.encodeParams;e.config.encoders[n]=e=>t(e)??e}}(a,o,e,{forwardTo:r,defaultParams:i,decodeParams:s,encodeParams:d}),void 0!==c&&(null===c?a.lifecycleNamespace.clearCanActivate(e):a.lifecycleNamespace.addCanActivate(e,c,o,!0)),void 0!==m&&(null===m?a.lifecycleNamespace.clearCanDeactivate(e):a.lifecycleNamespace.addCanDeactivate(e,m,o,!0))},clear:()=>{M(n.isDisposed),i(n.isTransitioning())&&(a.treeOperations.resetStore(a),a.lifecycleNamespace.clearAll(),n.clearState())},has:e=>(n.noValidate||c(e,"hasRoute"),a.matcher.hasRoute(e)),get:e=>(n.noValidate||c(e,"getRoute"),_(a,e)),replace:e=>{M(n.isDisposed);const r=Array.isArray(e)?e:[e];if(!i(n.isTransitioning()))return;n.noValidate||(s(r,"replaceRoutes"),d(r),a.treeOperations.validateRoutes(r));const c=t.getState()?.path;!function(e,t,n,a,o){V(e),e.lifecycleNamespace.clearDefinitionGuards();for(const t of n)e.definitions.push(G(t));if(j(n,e.config,e.routeCustomFields,e.pendingCanActivate,e.pendingCanDeactivate,e.depsStore,""),e.treeOperations.commitTreeChanges(e,t),void 0!==o){const e=a.matchPath(o,a.getOptions());e?a.setState(e):a.clearState()}}(a,o,r,n,c)}}}function B(t){const n=e(t);return{get:e=>{n.noValidate||h(e,"getDependency");const t=n.dependenciesGetStore().dependencies[e];return n.noValidate||S(t,e),t},getAll:()=>({...n.dependenciesGetStore().dependencies}),set:(e,t)=>{M(n.isDisposed),n.noValidate||O(e),function(e,t,n){if(void 0===n)return!1;if(Object.hasOwn(e.dependencies,t)){const a=e.dependencies[t],o=a!==n,r=Number.isNaN(a)&&Number.isNaN(n);o&&!r&&F.warn("router.setDependency","Router dependency already exists and is being overwritten:",t)}else!function(e,t){const n=e.limits.maxDependencies;if(0===n)return;const a=Object.keys(e.dependencies).length,{warn:o,error:r}=N(n);if(a===o)F.warn(`router.${t}`,`${o} dependencies registered. Consider if all are necessary.`);else if(a===r)F.error(`router.${t}`,`${r} dependencies registered! This indicates architectural problems. Hard limit at ${n}.`);else if(a>=n)throw new Error(`[router.${t}] Dependency limit exceeded (${n}). Current: ${a}. This is likely a bug in your code. If you genuinely need more dependencies, your architecture needs refactoring.`)}(e,"setDependency");e.dependencies[t]=n}(n.dependenciesGetStore(),e,t)},setAll:e=>{M(n.isDisposed);const t=n.dependenciesGetStore();n.noValidate||(y(e,"setDependencies"),D(Object.keys(t.dependencies).length,Object.keys(e).length,"setDependencies",t.limits.maxDependencies)),function(e,t){const n=[];for(const a in t)void 0!==t[a]&&(Object.hasOwn(e.dependencies,a)&&n.push(a),e.dependencies[a]=t[a]);n.length>0&&F.warn("router.setDependencies","Overwritten:",n.join(", "))}(t,e)},remove:e=>{M(n.isDisposed),n.noValidate||h(e,"removeDependency");const t=n.dependenciesGetStore();Object.hasOwn(t.dependencies,e)||F.warn("router.removeDependency",`Attempted to remove non-existent dependency: "${w(e)}"`),delete t.dependencies[e]},reset:()=>{M(n.isDisposed),n.dependenciesGetStore().dependencies=Object.create(null)},has:e=>(n.noValidate||h(e,"hasDependency"),Object.hasOwn(n.dependenciesGetStore().dependencies,e))}}function H(t){const n=e(t),a=n.routeGetStore().lifecycleNamespace;return{addActivateGuard(e,t){M(n.isDisposed),n.noValidate||(c(e,"addActivateGuard"),b(t,"addActivateGuard")),a.addCanActivate(e,t,n.noValidate)},addDeactivateGuard(e,t){M(n.isDisposed),n.noValidate||(c(e,"addDeactivateGuard"),b(t,"addDeactivateGuard")),a.addCanDeactivate(e,t,n.noValidate)},removeActivateGuard(e){M(n.isDisposed),n.noValidate||c(e,"removeActivateGuard"),a.clearCanActivate(e)},removeDeactivateGuard(e){M(n.isDisposed),n.noValidate||c(e,"removeDeactivateGuard"),a.clearCanDeactivate(e)}}}function K(a,o){const r=e(a);if(r.isDisposed())throw new t(n.ROUTER_DISPOSED);r.noValidate||function(e){if(void 0!==e){if(!e||"object"!=typeof e||e.constructor!==Object)throw new TypeError(`[cloneRouter] Invalid dependencies: expected plain object or undefined, received ${w(e)}`);for(const t in e)if(Object.getOwnPropertyDescriptor(e,t)?.get)throw new TypeError(`[cloneRouter] Getters not allowed in dependencies: "${t}"`)}}(o);const i=r.routeGetStore(),s=P(i.tree),d=i.config,c=i.resolvedForwardMap,l=i.routeCustomFields,f=r.cloneOptions(),u=r.cloneDependencies(),[p,m]=r.getLifecycleFactories(),g=r.getPluginFactories(),v={...u,...o},h=new C(s,f,v),y=H(h);for(const[e,t]of Object.entries(p))y.addDeactivateGuard(e,t);for(const[e,t]of Object.entries(m))y.addActivateGuard(e,t);g.length>0&&h.usePlugin(...g);const D=e(h).routeGetStore();return Object.assign(D.config.decoders,d.decoders),Object.assign(D.config.encoders,d.encoders),Object.assign(D.config.defaultParams,d.defaultParams),Object.assign(D.config.forwardMap,d.forwardMap),Object.assign(D.config.forwardFnMap,d.forwardFnMap),Object.assign(D.resolvedForwardMap,c),Object.assign(D.routeCustomFields,l),h}export{K as cloneRouter,B as getDependenciesApi,H as getLifecycleApi,k as getPluginApi,W as getRoutesApi};//# sourceMappingURL=api.mjs.map
1
+ import{guardRouteStructure as e,f as t,Router as a,clearRouteData as n,sanitizeRoute as r,registerAllRouteHandlers as o,removeFromDefinitions as i,clearConfigEntries as d,refreshForwardMap as s}from"./chunk-RA5VYM7M.mjs";import{throwIfDisposed as c}from"./chunk-HHIXK5UM.mjs";export{getPluginApi}from"./chunk-HHIXK5UM.mjs";import{RouterError as l,errorCodes as u}from"./chunk-5QXFUUDL.mjs";import{getInternals as p}from"./chunk-QUUNDESP.mjs";import{logger as v}from"@real-router/logger";function f(e){return!e||(v.error("router.clearRoutes","Cannot clear routes while navigation is in progress. Wait for navigation to complete."),!1)}function m(e,t,a=""){for(const n of e){const e=a?`${a}.${n.name}`:n.name;if(e===t)return n;if(n.children&&t.startsWith(`${e}.`))return m(n.children,t,e)}}function g(e,t,a,n){const r={name:e.name,path:e.path},o=a.forwardFnMap[t],i=a.forwardMap[t];void 0!==o?r.forwardTo=o:void 0!==i&&(r.forwardTo=i),t in a.defaultParams&&(r.defaultParams=a.defaultParams[t]),t in a.decoders&&(r.decodeParams=a.decoders[t]),t in a.encoders&&(r.encodeParams=a.encoders[t]);const[d,s]=n;return t in s&&(r.canActivate=s[t]),t in d&&(r.canDeactivate=d[t]),e.children&&(r.children=e.children.map(e=>g(e,`${t}.${e.name}`,a,n))),r}function D(e,t,a){if(a){const n=m(e.definitions,a);n.children??=[];for(const e of t)n.children.push(r(e))}else for(const a of t)e.definitions.push(r(a));o(t,e.config,e.routeCustomFields,e.pendingCanActivate,e.pendingCanDeactivate,e.depsStore,a??""),e.treeOperations.commitTreeChanges(e)}function h(e,t){const a=e.matcher.getSegmentsByName(t);if(!a)return;const n=a.at(-1),r=e.treeOperations.nodeToDefinition(n),o=e.lifecycleNamespace.getFactories();return g(r,t,e.config,o)}function w(t){const a=p(t),l=a.routeGetStore();return{add:(t,n)=>{c(a.isDisposed);const r=Array.isArray(t)?t:[t],o=n?.parent;e(r,a.validator),void 0!==o&&a.validator?.routes.validateParentOption(o,l.tree),a.validator?.routes.throwIfInternalRouteInArray(r,"addRoute"),a.validator?.routes.validateAddRouteArgs(r),a.validator?.routes.validateRoutes(r,l),D(l,r,o)},remove:e=>{c(a.isDisposed),a.validator?.routes.validateRemoveRouteArgs(e),a.validator?.routes.throwIfInternalRoute(e,"removeRoute");const t=function(e,t,a){if(t){const a=t===e,n=t.startsWith(`${e}.`);if(a||n)return v.warn("router.removeRoute",`Cannot remove route "${e}" — it is currently active${a?"":` (current: "${t}")`}. Navigate away first.`),!1}return a&&v.warn("router.removeRoute",`Route "${e}" removed while navigation is in progress. This may cause unexpected behavior.`),!0}(e,a.getStateName(),a.isTransitioning());t&&(function(e,t){return!!i(e.definitions,t)&&(function(e,t,a,n){const r=t=>t===e||t.startsWith(`${e}.`);d(t.decoders,r),d(t.encoders,r),d(t.defaultParams,r),d(t.forwardMap,r),d(t.forwardFnMap,r),d(a,r),d(t.forwardMap,e=>r(t.forwardMap[e]));const[o,i]=n.getFactories();for(const e of Object.keys(i))r(e)&&n.clearCanActivate(e);for(const e of Object.keys(o))r(e)&&n.clearCanDeactivate(e)}(t,e.config,e.routeCustomFields,e.lifecycleNamespace),e.treeOperations.commitTreeChanges(e),!0)}(l,e)||v.warn("router.removeRoute",`Route "${e}" not found. No changes made.`))},update:(e,t)=>{c(a.isDisposed),a.validator?.routes.validateUpdateRouteBasicArgs(e,t),a.validator?.routes.throwIfInternalRoute(e,"updateRoute");const{forwardTo:n,defaultParams:r,decodeParams:o,encodeParams:i,canActivate:d,canDeactivate:u}=t;a.validator?.routes.validateUpdateRoutePropertyTypes(e,t),a.isTransitioning()&&v.error("router.updateRoute",`Updating route "${e}" while navigation is in progress. This may cause unexpected behavior.`),a.validator?.routes.validateUpdateRoute(e,t,l),function(e,t,a){if(void 0!==a.forwardTo&&(e.resolvedForwardMap=function(e,t,a){return null===t?(delete a.forwardMap[e],delete a.forwardFnMap[e]):"string"==typeof t?(delete a.forwardFnMap[e],a.forwardMap[e]=t):(delete a.forwardMap[e],a.forwardFnMap[e]=t),(e=>s(e))(a)}(t,a.forwardTo,e.config)),void 0!==a.defaultParams&&(null===a.defaultParams?delete e.config.defaultParams[t]:e.config.defaultParams[t]=a.defaultParams),void 0!==a.decodeParams)if(null===a.decodeParams)delete e.config.decoders[t];else{const n=a.decodeParams;e.config.decoders[t]=e=>n(e)??e}if(void 0!==a.encodeParams)if(null===a.encodeParams)delete e.config.encoders[t];else{const n=a.encodeParams;e.config.encoders[t]=e=>n(e)??e}}(l,e,{forwardTo:n,defaultParams:r,decodeParams:o,encodeParams:i}),void 0!==d&&(null===d?l.lifecycleNamespace.clearCanActivate(e):l.lifecycleNamespace.addCanActivate(e,d,!0)),void 0!==u&&(null===u?l.lifecycleNamespace.clearCanDeactivate(e):l.lifecycleNamespace.addCanDeactivate(e,u,!0))},clear:()=>{c(a.isDisposed),f(a.isTransitioning())&&(l.treeOperations.resetStore(l),l.lifecycleNamespace.clearAll(),a.clearState())},has:e=>(a.validator?.routes.validateRouteName(e,"hasRoute"),l.matcher.hasRoute(e)),get:e=>(a.validator?.routes.validateRouteName(e,"getRoute"),h(l,e)),replace:i=>{c(a.isDisposed);const d=Array.isArray(i)?i:[i];if(!f(a.isTransitioning()))return;e(d,a.validator),a.validator?.routes.throwIfInternalRouteInArray(d,"replaceRoutes"),a.validator?.routes.validateAddRouteArgs(d),a.validator?.routes.validateRoutes(d,l);const s=t.getState()?.path;!function(e,t,a,i){n(e),e.lifecycleNamespace.clearDefinitionGuards();for(const a of t)e.definitions.push(r(a));if(o(t,e.config,e.routeCustomFields,e.pendingCanActivate,e.pendingCanDeactivate,e.depsStore,""),e.treeOperations.commitTreeChanges(e),void 0!==i){const e=a.matchPath(i,a.getOptions());e?a.setState(e):a.clearState()}}(l,d,a,s)}}}function y(e){const t=p(e);return{get:e=>{t.validator?.dependencies.validateDependencyName(e,"getDependency");const a=t.dependenciesGetStore(),n=a.dependencies[e];return t.validator?.dependencies.validateDependencyExists(e,a),n},getAll:()=>({...t.dependenciesGetStore().dependencies}),set:(e,a)=>{c(t.isDisposed),t.validator?.dependencies.validateSetDependencyArgs(e,a,"setDependency"),function(e,t,a,n){if(void 0===a)return!1;if(Object.hasOwn(e.dependencies,t)){const r=e.dependencies[t],o=r!==a,i=Number.isNaN(r)&&Number.isNaN(a);o&&!i&&n?.dependencies.warnOverwrite(t,"setDependency")}else n?.dependencies.validateDependencyCount(e,"setDependency");e.dependencies[t]=a}(t.dependenciesGetStore(),e,a,t.validator)},setAll:e=>{c(t.isDisposed);const a=t.dependenciesGetStore();t.validator?.dependencies.validateDependenciesObject(e,"setDependencies"),t.validator?.dependencies.validateDependencyLimit(a,a.limits),function(e,t,a){const n=[];for(const r in t)void 0!==t[r]&&(Object.hasOwn(e.dependencies,r)?n.push(r):a?.dependencies.validateDependencyCount(e,"setDependencies"),e.dependencies[r]=t[r]);n.length>0&&a?.dependencies.warnBatchOverwrite(n,"setDependencies")}(a,e,t.validator)},remove:e=>{c(t.isDisposed),t.validator?.dependencies.validateDependencyName(e,"removeDependency");const a=t.dependenciesGetStore();Object.hasOwn(a.dependencies,e)||t.validator?.dependencies.warnRemoveNonExistent(e),delete a.dependencies[e]},reset:()=>{c(t.isDisposed),t.dependenciesGetStore().dependencies=Object.create(null)},has:e=>(t.validator?.dependencies.validateDependencyName(e,"hasDependency"),Object.hasOwn(t.dependenciesGetStore().dependencies,e))}}function R(e){const t=p(e),a=t.routeGetStore().lifecycleNamespace;return{addActivateGuard(e,n){c(t.isDisposed),t.validator?.routes.validateRouteName(e,"addActivateGuard"),t.validator?.lifecycle.validateHandler(n,"addActivateGuard");const r=a.getHandlerCount("activate");t.validator?.lifecycle.validateHandlerLimit(r,t.dependenciesGetStore().limits,"canActivate"),a.addCanActivate(e,n)},addDeactivateGuard(e,n){c(t.isDisposed),t.validator?.routes.validateRouteName(e,"addDeactivateGuard"),t.validator?.lifecycle.validateHandler(n,"addDeactivateGuard");const r=a.getHandlerCount("deactivate");t.validator?.lifecycle.validateHandlerLimit(r,t.dependenciesGetStore().limits,"canDeactivate"),a.addCanDeactivate(e,n)},removeActivateGuard(e){c(t.isDisposed),t.validator?.routes.validateRouteName(e,"removeActivateGuard"),a.clearCanActivate(e)},removeDeactivateGuard(e){c(t.isDisposed),t.validator?.routes.validateRouteName(e,"removeDeactivateGuard"),a.clearCanDeactivate(e)}}}function A(e,n){const r=p(e);if(r.isDisposed())throw new l(u.ROUTER_DISPOSED);r.validator?.dependencies.validateCloneArgs(n);const o=r.routeGetStore(),i=t(o.tree),d=o.config,s=o.resolvedForwardMap,c=o.routeCustomFields,v=r.cloneOptions(),f=r.cloneDependencies(),[m,g]=r.getLifecycleFactories(),D=r.getPluginFactories(),h={...f,...n},w=new a(i,v,h),y=R(w);for(const[e,t]of Object.entries(m))y.addDeactivateGuard(e,t);for(const[e,t]of Object.entries(g))y.addActivateGuard(e,t);D.length>0&&w.usePlugin(...D);const A=p(w).routeGetStore();return Object.assign(A.config.decoders,d.decoders),Object.assign(A.config.encoders,d.encoders),Object.assign(A.config.defaultParams,d.defaultParams),Object.assign(A.config.forwardMap,d.forwardMap),Object.assign(A.config.forwardFnMap,d.forwardFnMap),Object.assign(A.resolvedForwardMap,s),Object.assign(A.routeCustomFields,c),w}export{A as cloneRouter,y as getDependenciesApi,R as getLifecycleApi,w as getRoutesApi};//# sourceMappingURL=api.mjs.map