@real-router/core 0.80.0 → 0.82.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 (179) hide show
  1. package/README.md +68 -55
  2. package/dist/cjs/Router-CCmcEi-S.js +2 -0
  3. package/dist/cjs/Router-CCmcEi-S.js.map +1 -0
  4. package/dist/cjs/Router.d.ts +7 -6
  5. package/dist/cjs/Router.d.ts.map +1 -1
  6. package/dist/cjs/Router.js +1 -1
  7. package/dist/cjs/Router.js.map +1 -1
  8. package/dist/cjs/api/getPluginApi.d.ts.map +1 -1
  9. package/dist/cjs/api/getPluginApi.js +1 -1
  10. package/dist/cjs/api/getPluginApi.js.map +1 -1
  11. package/dist/cjs/api/getRoutesApi.d.ts.map +1 -1
  12. package/dist/cjs/api/getRoutesApi.js +1 -1
  13. package/dist/cjs/api/getRoutesApi.js.map +1 -1
  14. package/dist/cjs/api.js +2 -1
  15. package/dist/cjs/api.js.map +1 -1
  16. package/dist/cjs/buildParamMeta-0m11OIJS.js +2 -0
  17. package/dist/cjs/buildParamMeta-0m11OIJS.js.map +1 -0
  18. package/dist/cjs/channels/defaults.js +2 -0
  19. package/dist/cjs/channels/defaults.js.map +1 -0
  20. package/dist/cjs/channels/guard.js +2 -0
  21. package/dist/cjs/channels/guard.js.map +1 -0
  22. package/dist/cjs/channels/modeGate.js +2 -0
  23. package/dist/cjs/channels/modeGate.js.map +1 -0
  24. package/dist/cjs/constants.d.ts.map +1 -1
  25. package/dist/cjs/constants.js +1 -1
  26. package/dist/cjs/constants.js.map +1 -1
  27. package/dist/cjs/createRouter.d.ts +1 -1
  28. package/dist/cjs/createRouter.d.ts.map +1 -1
  29. package/dist/cjs/createRouter.js.map +1 -1
  30. package/dist/cjs/engine/builder/buildTree.js +1 -1
  31. package/dist/cjs/engine/builder/buildTree.js.map +1 -1
  32. package/dist/cjs/engine/path-matcher/SegmentMatcher.d.ts +14 -1
  33. package/dist/cjs/engine/path-matcher/SegmentMatcher.d.ts.map +1 -1
  34. package/dist/cjs/engine/path-matcher/SegmentMatcher.js +1 -1
  35. package/dist/cjs/engine/path-matcher/SegmentMatcher.js.map +1 -1
  36. package/dist/cjs/engine/path-matcher/registration/buildParts.js +1 -1
  37. package/dist/cjs/engine/path-matcher/registration/buildParts.js.map +1 -1
  38. package/dist/cjs/engine/path-matcher/registration/context.js +1 -1
  39. package/dist/cjs/engine/path-matcher/registration/context.js.map +1 -1
  40. package/dist/cjs/engine/path-matcher/registration/errors.js +1 -1
  41. package/dist/cjs/engine/path-matcher/registration/errors.js.map +1 -1
  42. package/dist/cjs/engine/path-matcher/registration/index.js +1 -1
  43. package/dist/cjs/engine/path-matcher/registration/index.js.map +1 -1
  44. package/dist/cjs/engine/path-matcher/registration/trieNodes.js.map +1 -1
  45. package/dist/cjs/engine/path-matcher/types.d.ts +3 -0
  46. package/dist/cjs/engine/path-matcher/types.d.ts.map +1 -1
  47. package/dist/cjs/engine/search-params/strategies/number.js +1 -1
  48. package/dist/cjs/engine/search-params/strategies/number.js.map +1 -1
  49. package/dist/cjs/engine/validation/routes.js +1 -1
  50. package/dist/cjs/engine/validation/routes.js.map +1 -1
  51. package/dist/cjs/helpers.js +1 -1
  52. package/dist/cjs/helpers.js.map +1 -1
  53. package/dist/cjs/index.d.ts +3 -3
  54. package/dist/cjs/index.js +2 -1
  55. package/dist/cjs/index.js.map +1 -1
  56. package/dist/cjs/internals.d.ts +30 -8
  57. package/dist/cjs/internals.d.ts.map +1 -1
  58. package/dist/cjs/internals.js +1 -1
  59. package/dist/cjs/internals.js.map +1 -1
  60. package/dist/cjs/limits.js +2 -0
  61. package/dist/cjs/limits.js.map +1 -0
  62. package/dist/cjs/namespaces/EventBusNamespace/EventBusNamespace.js.map +1 -1
  63. package/dist/cjs/namespaces/NavigationNamespace/NavigationNamespace.js +1 -1
  64. package/dist/cjs/namespaces/NavigationNamespace/NavigationNamespace.js.map +1 -1
  65. package/dist/cjs/namespaces/OptionsNamespace/OptionsNamespace.js.map +1 -1
  66. package/dist/cjs/namespaces/OptionsNamespace/constants.js +1 -1
  67. package/dist/cjs/namespaces/OptionsNamespace/constants.js.map +1 -1
  68. package/dist/cjs/namespaces/OptionsNamespace/helpers.js.map +1 -1
  69. package/dist/cjs/namespaces/RoutesNamespace/RoutesNamespace.js +1 -1
  70. package/dist/cjs/namespaces/RoutesNamespace/RoutesNamespace.js.map +1 -1
  71. package/dist/cjs/namespaces/RoutesNamespace/helpers.js +1 -1
  72. package/dist/cjs/namespaces/RoutesNamespace/helpers.js.map +1 -1
  73. package/dist/cjs/namespaces/RoutesNamespace/routesStore.d.ts +8 -0
  74. package/dist/cjs/namespaces/RoutesNamespace/routesStore.d.ts.map +1 -1
  75. package/dist/cjs/namespaces/RoutesNamespace/routesStore.js +1 -1
  76. package/dist/cjs/namespaces/RoutesNamespace/routesStore.js.map +1 -1
  77. package/dist/cjs/namespaces/RoutesNamespace/types.d.ts +24 -7
  78. package/dist/cjs/namespaces/RoutesNamespace/types.d.ts.map +1 -1
  79. package/dist/cjs/namespaces/StateNamespace/StateNamespace.js +1 -1
  80. package/dist/cjs/namespaces/StateNamespace/StateNamespace.js.map +1 -1
  81. package/dist/cjs/pipeline/buildURL.js +2 -0
  82. package/dist/cjs/pipeline/buildURL.js.map +1 -0
  83. package/dist/cjs/pipeline/canonicalize.js +2 -0
  84. package/dist/cjs/pipeline/canonicalize.js.map +1 -0
  85. package/dist/cjs/pipeline/materialize.js +2 -0
  86. package/dist/cjs/pipeline/materialize.js.map +1 -0
  87. package/dist/cjs/pipeline/port.d.ts +147 -0
  88. package/dist/cjs/pipeline/port.d.ts.map +1 -0
  89. package/dist/cjs/routerFSM.js +1 -1
  90. package/dist/cjs/routerFSM.js.map +1 -1
  91. package/dist/cjs/transitionPath.js +1 -1
  92. package/dist/cjs/transitionPath.js.map +1 -1
  93. package/dist/cjs/types/RouterValidator.d.ts +14 -0
  94. package/dist/cjs/types/RouterValidator.d.ts.map +1 -1
  95. package/dist/cjs/types/api.d.ts +20 -11
  96. package/dist/cjs/types/api.d.ts.map +1 -1
  97. package/dist/cjs/types/base.d.ts +63 -4
  98. package/dist/cjs/types/base.d.ts.map +1 -1
  99. package/dist/cjs/types/constants.d.ts +1 -0
  100. package/dist/cjs/types/constants.d.ts.map +1 -1
  101. package/dist/cjs/types/router.d.ts +112 -23
  102. package/dist/cjs/types/router.d.ts.map +1 -1
  103. package/dist/cjs/types/tree-changed.d.ts +1 -1
  104. package/dist/cjs/types/tree-changed.d.ts.map +1 -1
  105. package/dist/cjs/types.d.ts +20 -11
  106. package/dist/cjs/types.d.ts.map +1 -1
  107. package/dist/cjs/utils/event-emitter/EventEmitter.js.map +1 -0
  108. package/dist/cjs/utils/fsm/fsm.js.map +1 -0
  109. package/dist/cjs/utils/logger/RouterLogger.js.map +1 -0
  110. package/dist/cjs/utils/logger/constants.js.map +1 -0
  111. package/dist/cjs/validation.js +2 -1
  112. package/dist/cjs/validation.js.map +1 -1
  113. package/dist/cjs/wiring/wireNamespaces.js +1 -1
  114. package/dist/cjs/wiring/wireNamespaces.js.map +1 -1
  115. package/dist/esm/Router-DEpNuwBW.mjs +2 -0
  116. package/dist/esm/Router-DEpNuwBW.mjs.map +1 -0
  117. package/dist/esm/Router.d.mts +7 -6
  118. package/dist/esm/Router.d.mts.map +1 -1
  119. package/dist/esm/api/getPluginApi.d.mts.map +1 -1
  120. package/dist/esm/api/getRoutesApi.d.mts.map +1 -1
  121. package/dist/esm/api.mjs +1 -1
  122. package/dist/esm/api.mjs.map +1 -1
  123. package/dist/esm/buildParamMeta-D8td47fL.mjs +2 -0
  124. package/dist/esm/buildParamMeta-D8td47fL.mjs.map +1 -0
  125. package/dist/esm/constants.d.mts.map +1 -1
  126. package/dist/esm/createRouter.d.mts +1 -1
  127. package/dist/esm/createRouter.d.mts.map +1 -1
  128. package/dist/esm/engine/path-matcher/SegmentMatcher.d.mts +14 -1
  129. package/dist/esm/engine/path-matcher/SegmentMatcher.d.mts.map +1 -1
  130. package/dist/esm/engine/path-matcher/types.d.mts +3 -0
  131. package/dist/esm/engine/path-matcher/types.d.mts.map +1 -1
  132. package/dist/esm/index.d.mts +3 -3
  133. package/dist/esm/index.mjs +1 -1
  134. package/dist/esm/index.mjs.map +1 -1
  135. package/dist/esm/internals.d.mts +30 -8
  136. package/dist/esm/internals.d.mts.map +1 -1
  137. package/dist/esm/namespaces/RoutesNamespace/routesStore.d.mts +8 -0
  138. package/dist/esm/namespaces/RoutesNamespace/routesStore.d.mts.map +1 -1
  139. package/dist/esm/namespaces/RoutesNamespace/types.d.mts +24 -7
  140. package/dist/esm/namespaces/RoutesNamespace/types.d.mts.map +1 -1
  141. package/dist/esm/pipeline/port.d.mts +147 -0
  142. package/dist/esm/pipeline/port.d.mts.map +1 -0
  143. package/dist/esm/types/RouterValidator.d.mts +14 -0
  144. package/dist/esm/types/RouterValidator.d.mts.map +1 -1
  145. package/dist/esm/types/api.d.mts +20 -11
  146. package/dist/esm/types/api.d.mts.map +1 -1
  147. package/dist/esm/types/base.d.mts +63 -4
  148. package/dist/esm/types/base.d.mts.map +1 -1
  149. package/dist/esm/types/constants.d.mts +1 -0
  150. package/dist/esm/types/constants.d.mts.map +1 -1
  151. package/dist/esm/types/router.d.mts +112 -23
  152. package/dist/esm/types/router.d.mts.map +1 -1
  153. package/dist/esm/types/tree-changed.d.mts +1 -1
  154. package/dist/esm/types/tree-changed.d.mts.map +1 -1
  155. package/dist/esm/types.d.mts +20 -11
  156. package/dist/esm/types.d.mts.map +1 -1
  157. package/dist/esm/validation.mjs +1 -1
  158. package/dist/esm/validation.mjs.map +1 -1
  159. package/package.json +2 -2
  160. package/dist/cjs/Router-DGUed2F4.js +0 -2
  161. package/dist/cjs/Router-DGUed2F4.js.map +0 -1
  162. package/dist/cjs/buildParamMeta-DniluAIV.js +0 -2
  163. package/dist/cjs/buildParamMeta-DniluAIV.js.map +0 -1
  164. package/dist/cjs/foundation/event-emitter/EventEmitter.js.map +0 -1
  165. package/dist/cjs/foundation/fsm/fsm.js.map +0 -1
  166. package/dist/cjs/foundation/logger/RouterLogger.js.map +0 -1
  167. package/dist/cjs/foundation/logger/constants.js.map +0 -1
  168. package/dist/cjs/namespaces/StateNamespace/helpers.js +0 -2
  169. package/dist/cjs/namespaces/StateNamespace/helpers.js.map +0 -1
  170. package/dist/cjs/stateMetaStore.js +0 -2
  171. package/dist/cjs/stateMetaStore.js.map +0 -1
  172. package/dist/esm/Router-Bk6PfSE8.mjs +0 -2
  173. package/dist/esm/Router-Bk6PfSE8.mjs.map +0 -1
  174. package/dist/esm/buildParamMeta-bOLhLF9h.mjs +0 -2
  175. package/dist/esm/buildParamMeta-bOLhLF9h.mjs.map +0 -1
  176. /package/dist/cjs/{foundation → utils}/event-emitter/EventEmitter.js +0 -0
  177. /package/dist/cjs/{foundation → utils}/fsm/fsm.js +0 -0
  178. /package/dist/cjs/{foundation → utils}/logger/RouterLogger.js +0 -0
  179. /package/dist/cjs/{foundation → utils}/logger/constants.js +0 -0
@@ -1,6 +1,5 @@
1
- import { RouteTreeState } from "./route-node-types.mjs";
2
- import { Params, SimpleState, State, StateMetaInput, Unsubscribe } from "./base.mjs";
3
- import { DefaultDependencies, GuardFnFactory, Options, Plugin, Route, RouteConfigUpdate } from "./router.mjs";
1
+ import { Params, SearchParams, SimpleState, State, Unsubscribe } from "./base.mjs";
2
+ import { AnyOptions, DefaultDependencies, GuardFnFactory, Plugin, Route, RouteConfigUpdate } from "./router.mjs";
4
3
  import { EventMethodMap, EventName } from "./constants.mjs";
5
4
  import { TreeChangedEvent } from "./tree-changed.mjs";
6
5
  import { NavigationOptions, StateContext } from "../types.mjs";
@@ -11,14 +10,14 @@ import { NavigationOptions, StateContext } from "../types.mjs";
11
10
  *
12
11
  * To add a new interceptable method:
13
12
  * 1. Add its signature here
14
- * 2. Wrap it with `createInterceptable()` / `createBinaryInterceptable()` in
13
+ * 2. Wrap it with `createInterceptable()` / `createTernaryInterceptable()` in
15
14
  * the `registerInternals` block of the Router constructor
16
15
  * (`packages/core/src/Router.ts`)
17
16
  */
18
17
  interface InterceptableMethodMap {
19
18
  start: (path?: string) => Promise<State>;
20
- buildPath: (route: string, params?: Params) => string;
21
- forwardState: (routeName: string, routeParams: Params) => SimpleState;
19
+ buildPath: (route: string, params?: Params, search?: SearchParams) => string;
20
+ forwardState: (routeName: string, routeParams: Params, routeSearch?: SearchParams) => SimpleState;
22
21
  }
23
22
  /**
24
23
  * Type-safe interceptor callback.
@@ -69,9 +68,8 @@ interface ContextNamespaceClaim<T = unknown> {
69
68
  * Hides plugin-internal methods from public autocomplete.
70
69
  */
71
70
  interface PluginApi {
72
- makeState: <P extends Params = Params>(name: string, params?: P, path?: string, meta?: StateMetaInput) => State<P>;
73
- buildState: (routeName: string, routeParams: Params) => RouteTreeState | undefined;
74
- forwardState: <P extends Params = Params>(routeName: string, routeParams: P) => SimpleState<P>;
71
+ makeState: <P extends Params = Params, S extends SearchParams = SearchParams>(name: string, params?: P, search?: S, path?: string) => State<P, S>;
72
+ forwardState: <P extends Params = Params, S extends SearchParams = SearchParams>(routeName: string, routeParams: P, routeSearch?: S) => SimpleState<P, S>;
75
73
  matchPath: <P extends Params = Params>(path: string) => State<P> | undefined;
76
74
  /**
77
75
  * Navigate to a fully-built `State`, skipping the redundant
@@ -97,8 +95,19 @@ interface PluginApi {
97
95
  setRootPath: (rootPath: string) => void;
98
96
  getRootPath: () => string;
99
97
  addEventListener: <E extends EventName>(eventName: E, cb: Plugin[EventMethodMap[E]]) => Unsubscribe;
100
- buildNavigationState: (name: string, params?: Params) => State | undefined;
101
- getOptions: () => Options;
98
+ /**
99
+ * Builds the State `navigate` would commit, without committing it: resolves
100
+ * `forwardTo`, checks existence (`undefined` = unknown route) and merges the
101
+ * route defaults.
102
+ *
103
+ * `search` is the query channel (#1571). It was the ONE pipeline entry point
104
+ * without the slot — `navigate` / `buildPath` / `canNavigateTo` /
105
+ * `isActiveRoute` / `makeState` all take one — so a query intent could only
106
+ * be spelled by riding declared keys in the `params` bag. An explicit value
107
+ * beats such a twin, matching the other five.
108
+ */
109
+ buildNavigationState: (name: string, params?: Params, search?: SearchParams) => State | undefined;
110
+ getOptions: () => AnyOptions;
102
111
  getTree: () => unknown;
103
112
  addInterceptor: <M extends keyof InterceptableMethodMap>(method: M, fn: InterceptorFn<M>) => Unsubscribe;
104
113
  extendRouter: (extensions: Record<string, unknown>) => Unsubscribe;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.mts","names":[],"sources":["../../../src/types/api.ts"],"mappings":";;;;;;;;;;;;;;;;;UAqCiB;EACf,QAAQ,kBAAkB,QAAQ;EAClC,YAAY,eAAe,SAAS;EACpC,eAAe,mBAAmB,aAAa,WAAW;;;;;;KAOhD,cAAc,gBAAgB,2BACxC,MAAM,uBAAuB,OAC1B,MAAM,WAAW,uBAAuB,QACxC,WAAW,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAqCtB,sBAAsB;EACrC,QAAQ,OAAO,OAAO,OAAO;EAC7B;;;;;;UAOe;EACf,YAAY,UAAU,SAAS,QAC7B,cACA,SAAS,GACT,eACA,OAAO,mBACJ,MAAM;EAEX,aACE,mBACA,aAAa,WACV;EAEL,eAAe,UAAU,SAAS,QAChC,mBACA,aAAa,MACV,YAAY;EAEjB,YAAY,UAAU,SAAS,QAAQ,iBAAiB,MAAM;;;;;;;;;;;;;;;;;;;;;EAsB9D,kBACE,OAAO,OACP,UAAU,sBACP,QAAQ;EAEb,cAAc;EACd;EAEA,mBAAmB,UAAU,WAC3B,WAAW,GACX,IAAI,OAAO,eAAe,QACvB;EAEL,uBAAuB,cAAc,SAAS,WAAW;EAEzD,kBAAkB;EAElB;EAEA,iBAAiB,gBAAgB,wBAC/B,QAAQ,GACR,IAAI,cAAc,OACf;EAEL,eAAe,YAAY,4BAA4B;;;;;;;;;;;;;EAcvD,sBAAsB,OAAO;EAE7B;KAEG,gBAAgB,uBACf,WAAW,IACV,sBAAsB,aAAa;KACrC,oBAAoB;;EAGvB,iBAAiB,iBAAiB;;;;;UAMnB,UACf,qBAAqB,sBAAsB;EAE3C,MACE,QAAQ,MAAM,kBAAkB,MAAM,eACtC;IAAY;;EAGd,SAAS;;;;;;;;;;;EAYT,SAAS,cAAc,SAAS,kBAAkB;EAElD;EAEA,UAAU,QAAQ,MAAM,kBAAkB,MAAM;EAEhD,MAAM;EAEN,MAAM,iBAAiB,MAAM;;;;;;;;;;;;;EAc7B,mBACE,UAAU,OAAO,iBAAiB,2BAC/B;;;;;UAMU,gBACf,qBAAqB,sBAAsB;EAE3C,MAAM,gBAAgB,cAAc,KAAK,MAAM,aAAa;EAC5D,cAAc,QAAQ;EACtB,MAAM,gBAAgB,uBACpB,MAAM,GACN,OAAO,aAAa;EAEtB,SAAS,MAAM;EACf,SAAS,YAAY;EACrB;EACA,MAAM,YAAY;;;;;UAMH,aACf,qBAAqB,sBAAsB;EAE3C,mBACE,cACA,oBAAoB,eAAe;EAErC,qBACE,cACA,sBAAsB,eAAe;EAEvC,sBAAsB;EACtB,wBAAwB"}
1
+ {"version":3,"file":"api.d.mts","names":[],"sources":["../../../src/types/api.ts"],"mappings":";;;;;;;;;;;;;;;;UAoCiB;EACf,QAAQ,kBAAkB,QAAQ;EAClC,YAAY,eAAe,SAAS,QAAQ,SAAS;EACrD,eACE,mBACA,aAAa,QACb,cAAc,iBACX;;;;;;KAOK,cAAc,gBAAgB,2BACxC,MAAM,uBAAuB,OAC1B,MAAM,WAAW,uBAAuB,QACxC,WAAW,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAqCtB,sBAAsB;EACrC,QAAQ,OAAO,OAAO,OAAO;EAC7B;;;;;;UAOe;EACf,YAAY,UAAU,SAAS,QAAQ,UAAU,eAAe,cAC9D,cACA,SAAS,GACT,SAAS,GACT,kBACG,MAAM,GAAG;EAEd,eACE,UAAU,SAAS,QACnB,UAAU,eAAe,cAEzB,mBACA,aAAa,GACb,cAAc,MACX,YAAY,GAAG;EAEpB,YAAY,UAAU,SAAS,QAAQ,iBAAiB,MAAM;;;;;;;;;;;;;;;;;;;;;EAsB9D,kBACE,OAAO,OACP,UAAU,sBACP,QAAQ;EAEb,cAAc;EACd;EAEA,mBAAmB,UAAU,WAC3B,WAAW,GACX,IAAI,OAAO,eAAe,QACvB;;;;;;;;;;;;EAaL,uBACE,cACA,SAAS,QACT,SAAS,iBACN;EAEL,kBAAkB;EAElB;EAEA,iBAAiB,gBAAgB,wBAC/B,QAAQ,GACR,IAAI,cAAc,OACf;EAEL,eAAe,YAAY,4BAA4B;;;;;;;;;;;;;EAcvD,sBAAsB,OAAO;EAE7B;KAEG,gBAAgB,uBACf,WAAW,IACV,sBAAsB,aAAa;KACrC,oBAAoB;;EAGvB,iBAAiB,iBAAiB;;;;;UAMnB,UACf,qBAAqB,sBAAsB;EAE3C,MACE,QAAQ,MAAM,kBAAkB,MAAM,eACtC;IAAY;;EAGd,SAAS;;;;;;;;;;;EAYT,SAAS,cAAc,SAAS,kBAAkB;EAElD;EAEA,UAAU,QAAQ,MAAM,kBAAkB,MAAM;EAEhD,MAAM;EAEN,MAAM,iBAAiB,MAAM;;;;;;;;;;;;;EAc7B,mBACE,UAAU,OAAO,iBAAiB,2BAC/B;;;;;UAMU,gBACf,qBAAqB,sBAAsB;EAE3C,MAAM,gBAAgB,cAAc,KAAK,MAAM,aAAa;EAC5D,cAAc,QAAQ;EACtB,MAAM,gBAAgB,uBACpB,MAAM,GACN,OAAO,aAAa;EAEtB,SAAS,MAAM;EACf,SAAS,YAAY;EACrB;EACA,MAAM,YAAY;;;;;UAMH,aACf,qBAAqB,sBAAsB;EAE3C,mBACE,cACA,oBAAoB,eAAe;EAErC,qBACE,cACA,sBAAsB,eAAe;EAEvC,sBAAsB;EACtB,wBAAwB"}
@@ -10,9 +10,15 @@ import { StateContext } from "../types.mjs";
10
10
  * has no additional effect after the first call.
11
11
  */
12
12
  type Unsubscribe = () => void;
13
- interface SimpleState<P extends Params = Params> {
13
+ interface SimpleState<P extends Params = Params, S extends SearchParams = SearchParams> {
14
14
  name: string;
15
15
  params: P;
16
+ /**
17
+ * Query channel — see {@link SearchParams}. Split out of the former single
18
+ * `params` bag (RFC-4 M2 / #1548). Always present: a frozen empty object when
19
+ * there are no query params.
20
+ */
21
+ search: S;
16
22
  }
17
23
  type TransitionPhase = "deactivating" | "activating";
18
24
  type TransitionReason = "success" | "blocked" | "cancelled" | "error";
@@ -30,9 +36,15 @@ interface TransitionMeta {
30
36
  intersection: string;
31
37
  };
32
38
  }
33
- interface State<P extends Params = Params> {
39
+ interface State<P extends Params = Params, S extends SearchParams = SearchParams> {
34
40
  name: string;
35
41
  params: P;
42
+ /**
43
+ * Query channel — see {@link SearchParams}. Holds ONLY query-string params;
44
+ * path params live in {@link State.params} (RFC-4 M2 / #1548). Always present:
45
+ * a frozen empty object when there are no query params.
46
+ */
47
+ search: S;
36
48
  path: string;
37
49
  transition: TransitionMeta;
38
50
  /**
@@ -57,8 +69,36 @@ interface State<P extends Params = Params> {
57
69
  */
58
70
  context: StateContext & Record<string, unknown>;
59
71
  }
60
- interface StateMetaInput<P extends Params = Params> {
72
+ /**
73
+ * Descriptor form of a navigation target (RFC-4 M2 / #1548). The two-channel
74
+ * counterpart to the positional `navigate(name, params, search, opts)` form:
75
+ * `params` is the path channel, `search` the query channel. Passed as the first
76
+ * argument to `router.navigate(target, opts?)` / `router.buildPath(target)` /
77
+ * `router.isActiveRoute(target)` and as the `to` prop of framework `<Link>`s,
78
+ * so a target can be threaded as one value instead of positional arguments.
79
+ */
80
+ interface NavigationTarget<P extends Params = Params, S extends SearchParams = SearchParams> {
81
+ name: string;
82
+ params?: P;
83
+ search?: S;
84
+ }
85
+ /**
86
+ * The two navigation channels a per-route codec operates on (RFC-4 M2 / #1548):
87
+ * `params` is the path channel, `search` the query channel. Used as **both** the
88
+ * input and the output of {@link Route.encodeParams} / {@link Route.decodeParams}
89
+ * — a codec transforms whichever channel(s) it owns and returns the other channel
90
+ * unchanged (it must be passed through explicitly).
91
+ *
92
+ * @remarks
93
+ * v1 ran the whole (path + query) bag through both callbacks, so a query value
94
+ * reached `decodeParams`. This two-channel shape preserves that reach: the query
95
+ * arrives in `search` rather than merged into `params`. Value semantics are
96
+ * unchanged — only the storage location differs (M2 keeps query parsing/printing
97
+ * exactly as v1).
98
+ */
99
+ interface ParamsSearch<P extends Params = Params, S extends SearchParams = SearchParams> {
61
100
  params: P;
101
+ search: S;
62
102
  }
63
103
  /**
64
104
  * Parsed shape produced by `serializeRouterState()` (`@real-router/ssr-utils`,
@@ -90,6 +130,25 @@ interface RouterError extends Error {
90
130
  interface Params {
91
131
  [key: string]: string | string[] | number | number[] | boolean | boolean[] | Params | Params[] | Record<string, string | number | boolean> | null | undefined;
92
132
  }
133
+ /**
134
+ * Query-parameter primitive values. Mirrors the engine's `QueryParamPrimitive`
135
+ * (`engine/search-params/types.ts`) — the value form is identical to v1's query
136
+ * half (the union produced across `queryParamsMode` formats).
137
+ */
138
+ type SearchParamPrimitive = string | number | boolean | null;
139
+ /**
140
+ * A single query-parameter value — a primitive or an array of primitives.
141
+ */
142
+ type SearchParamValue = SearchParamPrimitive | SearchParamPrimitive[];
143
+ /**
144
+ * Query-parameter bag carried by {@link State.search} — the query channel,
145
+ * split out of the former single `params` bag in M2 (RFC-4 M2 / #1548). Only
146
+ * the storage location changes vs v1; value semantics (modes, `queryParamsMode`,
147
+ * ternary arrays) are unchanged. Structurally matches the engine's internal
148
+ * `SearchParams` (`engine/search-params/types.ts`), so match results flow into
149
+ * `State.search` without conversion.
150
+ */
151
+ type SearchParams = Record<string, SearchParamValue | undefined>;
93
152
  //#endregion
94
- export { Params, RouterError, SerializedRouterState, SimpleState, State, StateMetaInput, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
153
+ export { NavigationTarget, Params, ParamsSearch, RouterError, SearchParamPrimitive, SearchParamValue, SearchParams, SerializedRouterState, SimpleState, State, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe };
95
154
  //# sourceMappingURL=base.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.mts","names":[],"sources":["../../../src/types/base.ts"],"mappings":";;;;;;;;;;;KAmBY;UAEK,YAAY,UAAU,SAAS;EAC9C;EACA,QAAQ;;KAGE;KAEA;UAEK;EACf,OAAO;EACP,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;;;UAIa,MAAM,UAAU,SAAS;EACxC;EACA,QAAQ;EACR;EACA,YAAY;;;;;;;;;;;;;;;;;;;;;EAqBZ,SAAS,eAAe;;UAGT,eAAe,UAAU,SAAS;EACjD,QAAQ;;;;;;;;;;KAWE,sBAAsB,UAAU,SAAS,UAAU,KAC7D,MAAM;;;;;;;UAUS,oBAAoB;GAClC;WACQ;WACA;WACA;EACT,UAAU;EACV,mBAAmB,KAAK;EACxB,sBAAsB,QAAQ;EAC9B,WAAW;EACX,WAAW;EACX,cAAc;;UAGC;GACd,4EAOG,SACA,WACA"}
1
+ {"version":3,"file":"base.d.mts","names":[],"sources":["../../../src/types/base.ts"],"mappings":";;;;;;;;;;;KAmBY;UAEK,YACf,UAAU,SAAS,QACnB,UAAU,eAAe;EAEzB;EACA,QAAQ;;;;;;EAMR,QAAQ;;KAGE;KAEA;UAEK;EACf,OAAO;EACP,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;;;UAIa,MACf,UAAU,SAAS,QACnB,UAAU,eAAe;EAEzB;EACA,QAAQ;;;;;;EAMR,QAAQ;EACR;EACA,YAAY;;;;;;;;;;;;;;;;;;;;;EAqBZ,SAAS,eAAe;;;;;;;;;;UAWT,iBACf,UAAU,SAAS,QACnB,UAAU,eAAe;EAEzB;EACA,SAAS;EACT,SAAS;;;;;;;;;;;;;;;;UAiBM,aACf,UAAU,SAAS,QACnB,UAAU,eAAe;EAEzB,QAAQ;EACR,QAAQ;;;;;;;;;;KAWE,sBAAsB,UAAU,SAAS,UAAU,KAC7D,MAAM;;;;;;;UAUS,oBAAoB;GAClC;WACQ;WACA;WACA;EACT,UAAU;EACV,mBAAmB,KAAK;EACxB,sBAAsB,QAAQ;EAC9B,WAAW;EACX,WAAW;EACX,cAAc;;UAGC;GACd,4EAOG,SACA,WACA;;;;;;;KAUM;;;;KAKA,mBAAmB,uBAAuB;;;;;;;;;KAU1C,eAAe,eAAe"}
@@ -66,6 +66,7 @@ interface ErrorCodeToValueMap {
66
66
  CONTEXT_NAMESPACE_ALREADY_CLAIMED: "CONTEXT_NAMESPACE_ALREADY_CLAIMED";
67
67
  REENTRANT_NAVIGATION: "REENTRANT_NAVIGATION";
68
68
  REENTRANT_TREE_MUTATION: "REENTRANT_TREE_MUTATION";
69
+ WRONG_CHANNEL: "WRONG_CHANNEL";
69
70
  }
70
71
  //#endregion
71
72
  export { ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventMethodMap, EventName, EventToNameMap, EventToPluginMap, EventsKeys, PluginMethod };
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.mts","names":[],"sources":["../../../src/types/constants.ts"],"mappings":";;;;KAGY;;;;KAYA;;;;KAYA;;;;KAYA;;;;KAiBA;;;;UAmBK;WACN;WACA;WACA;WACA;WACA;WACA;WACA;;;;;UAMM;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;KAOU,oBACT,KAAK,cAAc,eAAe,KAAK,iBAAiB;;;;UAM1C;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}
1
+ {"version":3,"file":"constants.d.mts","names":[],"sources":["../../../src/types/constants.ts"],"mappings":";;;;KAGY;;;;KAYA;;;;KAYA;;;;KAYA;;;;KAiBA;;;;UAmBK;WACN;WACA;WACA;WACA;WACA;WACA;WACA;;;;;UAMM;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;KAOU,oBACT,KAAK,cAAc,eAAe,KAAK,iBAAiB;;;;UAM1C;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA"}
@@ -1,5 +1,5 @@
1
1
  import { QueryParamsMode, QueryParamsOptions } from "./route-node-types.mjs";
2
- import { Params, RouterError, State, Unsubscribe } from "./base.mjs";
2
+ import { NavigationTarget, Params, ParamsSearch, RouterError, SearchParams, State, Unsubscribe } from "./base.mjs";
3
3
  import { LimitsConfig } from "./limits.mjs";
4
4
  import { NavigationOptions } from "../types.mjs";
5
5
  //#region src/types/router.d.ts
@@ -18,7 +18,7 @@ interface LoggerConfig {
18
18
  * Core stores a concrete instance on `RouterInternals.logger` (built from
19
19
  * `options.logger` in the `Router` constructor); plugins and other consumers
20
20
  * reach that same per-instance logger via `getPluginApi(router).logger`. The
21
- * concrete `RouterLogger` class lives in core's `foundation/logger` — this
21
+ * concrete `RouterLogger` class lives in core's `utils/logger` — this
22
22
  * interface is the shared contract, so nothing outside core needs to import the
23
23
  * class (or depend on the former standalone `@real-router/logger` package).
24
24
  */
@@ -42,26 +42,60 @@ type ForwardToCallback<Dependencies = object> = (getDependency: <K extends keyof
42
42
  * Receives a dependency getter function to access router dependencies.
43
43
  */
44
44
  type DefaultParamsCallback<Dependencies = object> = (getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K]) => Params;
45
+ /**
46
+ * Callback function for dynamically resolving the default query params.
47
+ * Receives a dependency getter function to access router dependencies.
48
+ */
49
+ type DefaultSearchCallback<Dependencies = object> = (getDependency: <K extends keyof Dependencies>(name: K) => Dependencies[K]) => SearchParams;
45
50
  /**
46
51
  * Router configuration options.
47
52
  *
48
53
  * Note: For input, use `Partial<Options>` as all fields have defaults.
49
54
  * After initialization, `getOptions()` returns resolved `Options` with all fields populated.
55
+ *
56
+ * Generic over the router's dependency map so the three resolver callbacks
57
+ * (`defaultRoute` / `defaultParams` / `defaultSearch`) receive a TYPED
58
+ * `getDependency`. Code that cannot know that map — anything plugin-facing,
59
+ * and every consumer that reads configuration rather than resolving it —
60
+ * takes {@link AnyOptions} instead of infecting itself with the parameter.
50
61
  */
51
- interface Options {
62
+ interface Options<Dependencies extends DefaultDependencies = DefaultDependencies> {
52
63
  /**
53
64
  * Default route to navigate to on start.
54
65
  * Empty string means no default route.
55
66
  *
56
67
  * @default ""
57
68
  */
58
- defaultRoute: string | DefaultRouteCallback;
69
+ defaultRoute: string | DefaultRouteCallback<Dependencies>;
59
70
  /**
60
- * Default parameters for the default route.
71
+ * Default **path** parameters for the default route.
72
+ *
73
+ * Query defaults belong in {@link defaultSearch} — the two are separate
74
+ * channels (RFC-4 M2 / #1548), exactly as on a route's own config. Until that
75
+ * twin existed, a query-declared name written here reached the URL only
76
+ * because the `forwardState` seam still re-channelled the bag on its way
77
+ * through; that repair is scheduled for removal, so this slot is for path
78
+ * params and arbitrary app-level data, nothing else.
61
79
  *
62
80
  * @default {}
63
81
  */
64
- defaultParams: Params | DefaultParamsCallback;
82
+ defaultParams: Params | DefaultParamsCallback<Dependencies>;
83
+ /**
84
+ * Default **query** parameters for the default route (RFC-4 M2 / #1548) —
85
+ * the query-channel twin of {@link defaultParams}, and the router-level
86
+ * counterpart of a route's own `defaultSearch`.
87
+ *
88
+ * Passed to `navigateToDefault()` in the query slot, so it is merged into
89
+ * `state.search` and, subject to `queryParamsMode`, printed into the URL
90
+ * query string. Like `defaultRoute` / `defaultParams`, it may be a callback,
91
+ * re-evaluated on every `navigateToDefault()` — the default route can itself
92
+ * be chosen dynamically, so its query defaults have to be able to follow.
93
+ * `Options` is generic over the dependency map, so the callback's
94
+ * `getDependency` is typed against the router's OWN dependencies.
95
+ *
96
+ * @default {}
97
+ */
98
+ defaultSearch: SearchParams | DefaultSearchCallback<Dependencies>;
65
99
  /**
66
100
  * How to handle trailing slashes in URLs.
67
101
  * - "strict": Route must match exactly
@@ -144,6 +178,21 @@ interface Options {
144
178
  */
145
179
  limits?: Partial<LimitsConfig>;
146
180
  }
181
+ /**
182
+ * `Options` as seen by code that cannot know the router's dependency map —
183
+ * `PluginApi.getOptions()`, the matcher, the URL builders.
184
+ *
185
+ * `Options<never>` rather than `Options<object>`, and the difference is the
186
+ * whole point: `keyof never` is `PropertyKey`, so the erased `getDependency`
187
+ * accepts ANY key and returns `never` — a wider parameter and a narrower
188
+ * return, which is exactly what contravariance needs for `Options<D>` to flow
189
+ * in for every `D`. `Options<object>` erases `keyof` to `never` instead and
190
+ * therefore accepts NOTHING but itself (verified: the assignment fails).
191
+ *
192
+ * Every field stays visible; only the callbacks become uncallable, which is
193
+ * honest — a plugin has no dependency map to resolve them against.
194
+ */
195
+ type AnyOptions = Options<never>;
147
196
  type GuardFn = (toState: State, fromState: State | undefined, signal?: AbortSignal) => boolean | Promise<boolean>;
148
197
  type DefaultDependencies = object;
149
198
  interface Plugin {
@@ -186,10 +235,13 @@ interface Subscription {
186
235
  * For full router access, use the Router interface directly or the useRouter() hook.
187
236
  */
188
237
  interface Navigator {
189
- navigate: (routeName: string, routeParams?: Params, options?: NavigationOptions) => Promise<State>;
238
+ navigate: {
239
+ (target: NavigationTarget, options?: NavigationOptions): Promise<State>;
240
+ (routeName: string, routeParams?: Params, routeSearch?: SearchParams, options?: NavigationOptions): Promise<State>;
241
+ };
190
242
  getState: () => State | undefined;
191
- isActiveRoute: (name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean) => boolean;
192
- canNavigateTo: (name: string, params?: Params) => boolean;
243
+ isActiveRoute: (name: string, params?: Params, search?: SearchParams, strictEquality?: boolean, ignoreQueryParams?: boolean) => boolean;
244
+ canNavigateTo: (name: string, params?: Params, search?: SearchParams) => boolean;
193
245
  subscribe: (listener: SubscribeFn) => Unsubscribe;
194
246
  subscribeLeave: (listener: LeaveFn) => Unsubscribe;
195
247
  isLeaveApproved: () => boolean;
@@ -203,8 +255,8 @@ interface Navigator {
203
255
  */
204
256
  interface Router<D extends DefaultDependencies = DefaultDependencies> {
205
257
  [key: string]: unknown;
206
- isActiveRoute: (name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean) => boolean;
207
- buildPath: (route: string, params?: Params) => string;
258
+ isActiveRoute: (name: string, params?: Params, search?: SearchParams, strictEquality?: boolean, ignoreQueryParams?: boolean) => boolean;
259
+ buildPath: (route: string, params?: Params, search?: SearchParams) => string;
208
260
  getState: <P extends Params = Params>() => State<P> | undefined;
209
261
  getPreviousState: () => State | undefined;
210
262
  areStatesEqual: (state1: State | undefined, state2: State | undefined, ignoreQueryParams?: boolean) => boolean;
@@ -213,12 +265,15 @@ interface Router<D extends DefaultDependencies = DefaultDependencies> {
213
265
  start: (startPath: string) => Promise<State>;
214
266
  stop: () => this;
215
267
  dispose: () => void;
216
- canNavigateTo: (name: string, params?: Params) => boolean;
268
+ canNavigateTo: (name: string, params?: Params, search?: SearchParams) => boolean;
217
269
  usePlugin: (...plugins: (PluginFactory<D> | false | null | undefined)[]) => Unsubscribe;
218
270
  subscribe: (listener: SubscribeFn) => Unsubscribe;
219
271
  subscribeLeave: (listener: LeaveFn) => Unsubscribe;
220
272
  isLeaveApproved: () => boolean;
221
- navigate: (routeName: string, routeParams?: Params, options?: NavigationOptions) => Promise<State>;
273
+ navigate: {
274
+ (target: NavigationTarget, options?: NavigationOptions): Promise<State>;
275
+ (routeName: string, routeParams?: Params, routeSearch?: SearchParams, options?: NavigationOptions): Promise<State>;
276
+ };
222
277
  navigateToDefault: (options?: NavigationOptions) => Promise<State>;
223
278
  navigateToNotFound: (path?: string) => State;
224
279
  }
@@ -257,17 +312,49 @@ interface Route<Dependencies extends DefaultDependencies = DefaultDependencies>
257
312
  forwardTo?: string | ForwardToCallback<Dependencies>;
258
313
  /** Nested child routes. */
259
314
  children?: Route<Dependencies>[];
260
- /** Encodes state params to URL params. */
261
- encodeParams?: (stateParams: Params) => Params;
262
- /** Decodes URL params to state params. */
263
- decodeParams?: (pathParams: Params) => Params;
264
315
  /**
265
- * Default parameters for this route.
316
+ * Encodes the state channels to URL channels before path building (RFC-4 M2 /
317
+ * #1548). Receives `{ params, search }` and returns `{ params, search }` —
318
+ * transform whichever channel you own and pass the other through. The path
319
+ * slots are built from the returned `params`, the query string from the
320
+ * returned `search`.
321
+ */
322
+ encodeParams?: (channels: ParamsSearch) => ParamsSearch;
323
+ /**
324
+ * Decodes the matched URL channels to state channels (RFC-4 M2 / #1548).
325
+ * Receives `{ params, search }` (path params + parsed query) and returns
326
+ * `{ params, search }`. Runs inside `matchPath`, **before** any search-schema
327
+ * plugin validation — the v1 transformation order (engine codec → plugin).
328
+ */
329
+ decodeParams?: (channels: ParamsSearch) => ParamsSearch;
330
+ /**
331
+ * Default **path** parameters for this route (and arbitrary app-level
332
+ * defaults). Merged into `state.params`; missing path params are filled from
333
+ * here. Query defaults belong in {@link defaultSearch} (RFC-4 M2 / #1548).
334
+ *
335
+ * ⚠ **The slot IS the channel** — `ba0f6b18b` retired the routing #1549
336
+ * introduced, and this doc described it for one release. A name the route
337
+ * declares with `?` written here is NOT re-routed to the query string: it is
338
+ * REFUSED at registration, so `createRouter` / `add` / `replace` / `update` /
339
+ * `setRootPath` throw, naming the key and telling you to move it to
340
+ * {@link defaultSearch}. Without that check the router would build a state out
341
+ * of config it had just accepted and its own always-on channel guard would
342
+ * reject it on `start()`.
266
343
  *
267
- * These values are merged into state.params when creating route states.
268
- * Missing URL params are filled from defaultParams.
344
+ * A key the route declares NOWHERE is legitimate here and stays in
345
+ * `state.params` as app-level data it never reaches the URL, which
346
+ * `@real-router/validation-plugin` reports once per route+key (#1579).
269
347
  */
270
348
  defaultParams?: Params;
349
+ /**
350
+ * Default **query** (search) parameters for this route (RFC-4 M2 / #1548) —
351
+ * the query-channel twin of {@link defaultParams}. Merged into `state.search`
352
+ * and, subject to `queryParamsMode`, printed into the URL query string. A key
353
+ * the route does not declare as a query param (`?name`) follows the same
354
+ * `queryParamsMode` rules as a runtime `search` value (loose prints,
355
+ * default/strict drops).
356
+ */
357
+ defaultSearch?: SearchParams;
271
358
  }
272
359
  /**
273
360
  * Configuration update options for `updateRoute()`.
@@ -299,15 +386,17 @@ interface RouteConfigUpdate<Dependencies extends DefaultDependencies = DefaultDe
299
386
  forwardTo?: string | ForwardToCallback<Dependencies> | null;
300
387
  /** Set to null to remove defaultParams */
301
388
  defaultParams?: Params | null;
389
+ /** Set to null to remove defaultSearch (RFC-4 M2 / #1548) */
390
+ defaultSearch?: SearchParams | null;
302
391
  /** Set to null to remove decoder */
303
- decodeParams?: ((params: Params) => Params) | null;
392
+ decodeParams?: ((channels: ParamsSearch) => ParamsSearch) | null;
304
393
  /** Set to null to remove encoder */
305
- encodeParams?: ((params: Params) => Params) | null;
394
+ encodeParams?: ((channels: ParamsSearch) => ParamsSearch) | null;
306
395
  /** Set to null to remove canActivate */
307
396
  canActivate?: GuardFnFactory<Dependencies> | null;
308
397
  /** Set to null to remove canDeactivate */
309
398
  canDeactivate?: GuardFnFactory<Dependencies> | null;
310
399
  }
311
400
  //#endregion
312
- export { DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ForwardToCallback, GuardFn, GuardFnFactory, LeaveFn, LeaveState, Listener, LogCallback, LogLevel, LogLevelConfig, LoggerConfig, Navigator, Options, Plugin, PluginFactory, Route, RouteConfigUpdate, Router, RouterLogger, SubscribeFn, SubscribeState, Subscription };
401
+ export { AnyOptions, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, DefaultSearchCallback, ForwardToCallback, GuardFn, GuardFnFactory, LeaveFn, LeaveState, Listener, LogCallback, LogLevel, LogLevelConfig, LoggerConfig, Navigator, Options, Plugin, PluginFactory, Route, RouteConfigUpdate, Router, RouterLogger, SubscribeFn, SubscribeState, Subscription };
313
402
  //# sourceMappingURL=router.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.mts","names":[],"sources":["../../../src/types/router.ts"],"mappings":"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"}
1
+ {"version":3,"file":"router.d.mts","names":[],"sources":["../../../src/types/router.ts"],"mappings":"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"}
@@ -8,7 +8,7 @@ import { DefaultDependencies, Route, RouteConfigUpdate } from "./router.mjs";
8
8
  * guards are invoked-on-demand (fresh-read per navigation), not cached derived
9
9
  * state, so they need no observation channel.
10
10
  */
11
- type TreeStructuralPatch<Dependencies extends DefaultDependencies = DefaultDependencies> = Pick<RouteConfigUpdate<Dependencies>, "forwardTo" | "defaultParams" | "encodeParams" | "decodeParams">;
11
+ type TreeStructuralPatch<Dependencies extends DefaultDependencies = DefaultDependencies> = Pick<RouteConfigUpdate<Dependencies>, "forwardTo" | "defaultParams" | "defaultSearch" | "encodeParams" | "decodeParams">;
12
12
  interface TreeChangedAdd<Dependencies extends DefaultDependencies = DefaultDependencies> {
13
13
  readonly op: "add";
14
14
  /** Top-level routes that were added (deep-cloned + frozen; caller untouched). */
@@ -1 +1 @@
1
- {"version":3,"file":"tree-changed.d.mts","names":[],"sources":["../../../src/types/tree-changed.ts"],"mappings":";;;;;;;;;;KAsBY,oBACV,qBAAqB,sBAAsB,uBACzC,KACF,kBAAkB;UAIH,eACf,qBAAqB,sBAAsB;WAElC;;WAEA,gBAAgB,MAAM;;WAEtB;;UAGM,kBACf,qBAAqB,sBAAsB;WAElC;WACA;;;;;WAKA,yBAAyB,MAAM;;UAGzB,kBACf,qBAAqB,sBAAsB;WAElC;WACA;;WAEA,OAAO,SAAS,oBAAoB;;UAG9B,mBACf,qBAAqB,sBAAsB;WAElC;;WAEA,kBAAkB,MAAM;;WAExB,gBAAgB,MAAM;;UAGhB,iBACf,qBAAqB,sBAAsB;WAElC;;WAEA,kBAAkB,MAAM;;;;;;;;KASvB,iBACV,qBAAqB,sBAAsB,uBAEzC,eAAe,gBACf,kBAAkB,gBAClB,kBAAkB,gBAClB,mBAAmB,gBACnB,iBAAiB"}
1
+ {"version":3,"file":"tree-changed.d.mts","names":[],"sources":["../../../src/types/tree-changed.ts"],"mappings":";;;;;;;;;;KAsBY,oBACV,qBAAqB,sBAAsB,uBACzC,KACF,kBAAkB;UAQH,eACf,qBAAqB,sBAAsB;WAElC;;WAEA,gBAAgB,MAAM;;WAEtB;;UAGM,kBACf,qBAAqB,sBAAsB;WAElC;WACA;;;;;WAKA,yBAAyB,MAAM;;UAGzB,kBACf,qBAAqB,sBAAsB;WAElC;WACA;;WAEA,OAAO,SAAS,oBAAoB;;UAG9B,mBACf,qBAAqB,sBAAsB;WAElC;;WAEA,kBAAkB,MAAM;;WAExB,gBAAgB,MAAM;;UAGhB,iBACf,qBAAqB,sBAAsB;WAElC;;WAEA,kBAAkB,MAAM;;;;;;;;KASvB,iBACV,qBAAqB,sBAAsB,uBAEzC,eAAe,gBACf,kBAAkB,gBAClB,kBAAkB,gBAClB,mBAAmB,gBACnB,iBAAiB"}
@@ -1,7 +1,7 @@
1
1
  import { QueryParamsMode, QueryParamsOptions, RouteParams, RouteTreeState } from "./types/route-node-types.mjs";
2
- import { Params, RouterError, SerializedRouterState, SimpleState, State, StateMetaInput, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe } from "./types/base.mjs";
2
+ import { NavigationTarget, Params, ParamsSearch, RouterError, SearchParamPrimitive, SearchParamValue, SearchParams, SerializedRouterState, SimpleState, State, TransitionMeta, TransitionPhase, TransitionReason, Unsubscribe } from "./types/base.mjs";
3
3
  import { LimitsConfig } from "./types/limits.mjs";
4
- import { DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, ForwardToCallback, GuardFn, GuardFnFactory, LeaveFn, LeaveState, Listener, LogCallback, LogLevel, LogLevelConfig, LoggerConfig, Navigator, Options, Plugin, PluginFactory, Route, RouteConfigUpdate, Router, RouterLogger, SubscribeFn, SubscribeState, Subscription } from "./types/router.mjs";
4
+ import { AnyOptions, DefaultDependencies, DefaultParamsCallback, DefaultRouteCallback, DefaultSearchCallback, ForwardToCallback, GuardFn, GuardFnFactory, LeaveFn, LeaveState, Listener, LogCallback, LogLevel, LogLevelConfig, LoggerConfig, Navigator, Options, Plugin, PluginFactory, Route, RouteConfigUpdate, Router, RouterLogger, SubscribeFn, SubscribeState, Subscription } from "./types/router.mjs";
5
5
  import { ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventMethodMap, EventName, EventToNameMap, EventToPluginMap, EventsKeys, PluginMethod } from "./types/constants.mjs";
6
6
  import { TreeChangedAdd, TreeChangedClear, TreeChangedEvent, TreeChangedRemove, TreeChangedReplace, TreeChangedUpdate, TreeStructuralPatch } from "./types/tree-changed.mjs";
7
7
  import { ContextNamespaceClaim, DependenciesApi, InterceptableMethodMap, InterceptorFn, LifecycleApi, PluginApi, RoutesApi } from "./types/api.mjs";
@@ -55,7 +55,7 @@ interface NavigationOptions {
55
55
  *
56
56
  * @example
57
57
  * // Redirect after login - prevent back button to login page
58
- * router.navigate('dashboard', {}, { replace: true });
58
+ * router.navigate('dashboard', {}, undefined, { replace: true });
59
59
  *
60
60
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState}
61
61
  */
@@ -97,13 +97,22 @@ interface NavigationOptions {
97
97
  * @default false
98
98
  *
99
99
  * @example
100
- * // Refresh current page data
101
- * router.navigate(currentRoute.name, currentRoute.params, { reload: true });
100
+ * // Refresh current page data. Options sit at slot 4 since RFC-4 M2
101
+ * // (#1548) — slot 3 is the query channel, so the pre-M2 three-argument
102
+ * // spelling puts `{ reload: true }` in `search`: the reload never happens
103
+ * // and the page's own query is rebuilt from an object that does not have
104
+ * // it (measured: `/search?term=react` → `/search`).
105
+ * router.navigate(
106
+ * currentRoute.name,
107
+ * currentRoute.params,
108
+ * currentRoute.search,
109
+ * { reload: true },
110
+ * );
102
111
  *
103
112
  * @example
104
- * // Force re-fetch on same route with different query params
105
- * // Note: query params are in path, not checked for equality
106
- * router.navigate('search', { term: 'react' }, { reload: true });
113
+ * // Force re-fetch on the same route with a different query. The query is
114
+ * // its own channel now pass it at slot 3, not inside the path bag.
115
+ * router.navigate('search', {}, { term: 'react' }, { reload: true });
107
116
  *
108
117
  * @see {@link force} for alternative that forces transition
109
118
  * @see {@link Router.areStatesEqual} for state comparison logic
@@ -130,7 +139,7 @@ interface NavigationOptions {
130
139
  *
131
140
  * @example
132
141
  * // Force transition for tracking even if params didn't change
133
- * router.navigate('analytics', { event: 'pageview' }, { force: true });
142
+ * router.navigate('analytics', {}, { event: 'pageview' }, { force: true });
134
143
  *
135
144
  * @see {@link reload} for semantic equivalent (preferred for refresh scenarios)
136
145
  */
@@ -159,7 +168,7 @@ interface NavigationOptions {
159
168
  * @example
160
169
  * // Force logout even with unsaved changes
161
170
  * function forceLogout() {
162
- * router.navigate('login', {}, {
171
+ * router.navigate('login', {}, undefined, {
163
172
  * forceDeactivate: true,
164
173
  * replace: true
165
174
  * });
@@ -204,5 +213,5 @@ interface NavigationOptions {
204
213
  signal?: AbortSignal | undefined;
205
214
  }
206
215
  //#endregion
207
- export { type ContextNamespaceClaim, type DefaultDependencies, type DefaultParamsCallback, type DefaultRouteCallback, type DependenciesApi, type ErrorCodeKeys, type ErrorCodeToValueMap, type ErrorCodeValues, type EventMethodMap, type EventName, type EventToNameMap, type EventToPluginMap, type EventsKeys, type ForwardToCallback, type GuardFn, type GuardFnFactory, type InterceptableMethodMap, type InterceptorFn, type LeaveFn, type LeaveState, type LifecycleApi, type LimitsConfig, type Listener, type LogCallback, type LogLevel, type LogLevelConfig, type LoggerConfig, NavigationOptions, type Navigator, type Options, type Params, type Plugin, type PluginApi, type PluginFactory, type PluginMethod, type QueryParamsMode, type QueryParamsOptions, type Route, type RouteConfigUpdate, type RouteParams, type RouteTreeState, type Router, type RouterError, type RouterLogger, type RoutesApi, type SerializedRouterState, type SimpleState, type State, StateContext, type StateMetaInput, type SubscribeFn, type SubscribeState, type Subscription, type TransitionMeta, type TransitionPhase, type TransitionReason, type TreeChangedAdd, type TreeChangedClear, type TreeChangedEvent, type TreeChangedRemove, type TreeChangedReplace, type TreeChangedUpdate, type TreeStructuralPatch, type Unsubscribe };
216
+ export { type AnyOptions, type ContextNamespaceClaim, type DefaultDependencies, type DefaultParamsCallback, type DefaultRouteCallback, type DefaultSearchCallback, type DependenciesApi, type ErrorCodeKeys, type ErrorCodeToValueMap, type ErrorCodeValues, type EventMethodMap, type EventName, type EventToNameMap, type EventToPluginMap, type EventsKeys, type ForwardToCallback, type GuardFn, type GuardFnFactory, type InterceptableMethodMap, type InterceptorFn, type LeaveFn, type LeaveState, type LifecycleApi, type LimitsConfig, type Listener, type LogCallback, type LogLevel, type LogLevelConfig, type LoggerConfig, NavigationOptions, type NavigationTarget, type Navigator, type Options, type Params, type ParamsSearch, type Plugin, type PluginApi, type PluginFactory, type PluginMethod, type QueryParamsMode, type QueryParamsOptions, type Route, type RouteConfigUpdate, type RouteParams, type RouteTreeState, type Router, type RouterError, type RouterLogger, type RoutesApi, type SearchParamPrimitive, type SearchParamValue, type SearchParams, type SerializedRouterState, type SimpleState, type State, StateContext, type SubscribeFn, type SubscribeState, type Subscription, type TransitionMeta, type TransitionPhase, type TransitionReason, type TreeChangedAdd, type TreeChangedClear, type TreeChangedEvent, type TreeChangedRemove, type TreeChangedReplace, type TreeChangedUpdate, type TreeStructuralPatch, type Unsubscribe };
208
217
  //# sourceMappingURL=types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2DiB;;;;;;;;;;;;;;UAeA;;;;;;;;;;;;;;;;;EAiBf;;;;;;;;;;;;;;;EAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCA;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA;;;;;;;;;;;;;;;;;;;;;;;EAwBA;;;;;;;;;;;EAYA,SAAS"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+DiB;;;;;;;;;;;;;;UAeA;;;;;;;;;;;;;;;;;EAiBf;;;;;;;;;;;;;;;EAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4CA;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA;;;;;;;;;;;;;;;;;;;;;;;EAwBA;;;;;;;;;;;EAYA,SAAS"}
@@ -1,2 +1,2 @@
1
- import{a as e,i as t,n,r,u as i}from"./buildParamMeta-bOLhLF9h.mjs";function a(e,t){return TypeError(`[router.${e}] ${t}`)}function o(e,t,n,r){let i=new Set;for(let o of e){if(i.has(o))throw a(n,`Invalid path for route "${t}": duplicate parameter name ':${o}' in "${r}" (a param name must be unique within a route — the second binding would overwrite the first)`);i.add(o)}}function s(e,t,r,i,o){let s=new Set(e);for(let e of t){if(n.test(e))throw a(i,`Invalid path for route "${r}": invalid query-param name "${e}" in "${o}" (a query-param name cannot contain '<' or '>' — it would never round-trip; rename the query param)`);if(s.has(e))throw a(i,`Invalid path for route "${r}": "${e}" is declared as both a path param and a query param in "${o}" — buildPath would emit its value twice (rename one)`)}}function c(e){let t=!0,n=!1;for(let r of e){if(r===`/`){t=!0;continue}if(t&&=(n=r===`:`||r===`*`,!1),!n&&r.codePointAt(0)>=128)return!0}return!1}function l(e,t,n){switch(e){case`name-less`:case`trailing-marker`:return`Invalid path for route "${t}": parameter marker (':' or '*') without a name in "${n}"`;case`fused-marker`:return`Invalid path for route "${t}": parameter marker (':' or '*') must begin a segment, but "${n}" fuses one to a static prefix (use a boundary marker like "/a/:b")`}}function u(e,t){return e.code===`optional-removed`?`Invalid path for route "${t}": optional params are not supported — "${e.segment}". Declare two sibling routes instead: "${e.withoutSegment}" and "${e.requiredForm}" (the route hierarchy already expresses optionality)`:`Invalid path for route "${t}": regex constraints are not supported — '<' and '>' are reserved in path segments ("${e.segment}"). Match the segment as a plain string and validate the value in a guard (canActivate) or app code`}function d(n,i,d,f){if(typeof n!=`string`){let e;throw e=n===null?`null`:Array.isArray(n)?`array`:typeof n,a(d,`Route path must be a string, got ${e}`)}if(n===``)return;if(/\s/.test(n))throw a(d,`Invalid path for route "${i}": whitespace not allowed in "${n}"`);if(!/^([/?~]|[^/]+$)/.test(n))throw a(d,`Route "${i}" has invalid path format: "${n}". Path should start with '/', '~', '?' or be a relative segment.`);if(n.includes(`//`))throw a(d,`Invalid path for route "${i}": double slashes not allowed in "${n}"`);let{pathPattern:p,urlParams:m,queryParams:h}=r(n);o(m,i,d,n),s(m,h,i,d,n);let g=t(p);if(g!==void 0)throw a(d,u(g,i));let _=e(p);if(_!==void 0)throw a(d,l(_,i,n));if(c(p))throw a(d,`Invalid path for route "${i}": non-ASCII static segment in "${n}" — match compares static segments raw and rejects non-ASCII input, so this route would never match. Percent-encode it (e.g. '/caf%C3%A9') or use a param`);let v=f&&f.paramMeta.urlParams.length>0;if(n.startsWith(`~`)&&v)throw a(d,`Absolute path "${n}" cannot be used under parent route with URL parameters`)}const f=/^[A-Z_a-z][\w-]*$/,p=/\S/,m=1e4;function h(e){if(e===null)return`null`;if(typeof e==`object`){try{let t=e.constructor;if(typeof t==`function`&&t.name!==`Object`)return t.name||`object`}catch{}return`object`}return typeof e}function g(e){for(let t of Object.keys(e)){let n=Object.getOwnPropertyDescriptor(e,t);if(n&&(n.get||n.set))return!0}return!1}function _(e,t){if(!e||typeof e!=`object`)throw TypeError(`[router.${t}] Route must be an object, got ${h(e)}`);let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)throw TypeError(`[router.${t}] Route must be a plain object, got ${h(e)}`);if(g(e))throw TypeError(`[router.${t}] Route must not have getters or setters`)}function v(e,t){if(e.encodeParams!==void 0&&typeof e.encodeParams!=`function`)throw TypeError(`[router.${t}] Route "${String(e.name)}" encodeParams must be a function`)}function y(e,t){if(e.decodeParams!==void 0&&typeof e.decodeParams!=`function`)throw TypeError(`[router.${t}] Route "${String(e.name)}" decodeParams must be a function`)}function b(e,t){if(typeof e.name!=`string`)throw TypeError(`[router.${t}] Route name must be a string, got ${h(e.name)}`);let n=e.name;if(n===``)throw TypeError(`[router.${t}] Route name cannot be empty`);if(!p.test(n))throw TypeError(`[router.${t}] Route name cannot contain only whitespace`);if(n.length>m)throw TypeError(`[router.${t}] Route name exceeds maximum length of ${m} characters`);if(!n.startsWith(`@@`)){if(n.includes(`.`))throw TypeError(`[router.${t}] Route name "${n}" cannot contain dots. Use children array or { parent } option in addRoute() instead.`);if(!f.test(n))throw TypeError(`[router.${t}] Invalid route name "${n}". Name must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens.`)}}function x(e,t){if(!t.includes(`.`))return e.children.get(t);let n=e;for(let e of t.split(`.`))if(n=n.children.get(e),!n)return;return n}function S(e,t,n){if(x(e,t))throw Error(`[router.${n}] Route "${t}" already exists`)}function C(e,t,n){if(e.has(t))throw Error(`[router.${n}] Duplicate route "${t}" in batch`);e.add(t)}function w(e,t,n,r){let i=t===``?e:x(e,t);if(i){for(let e of i.children.values())if(e.path===n)throw Error(`[router.${r}] Path "${n}" is already defined`)}}function T(e,t,n,r){let i=e.get(t);if(i?.has(n))throw Error(`[router.${r}] Path "${n}" is already defined`);i?i.add(n):e.set(t,new Set([n]))}function E(e,t,n,r=``,i,a){_(e,t);let o=e;b(o,t),d(o.path,o.name,t,n),v(o,t),y(o,t);let s=o.name,c=r?`${r}.${s}`:s;n&&c&&S(n,c,t),i&&C(i,c,t);let l=o.path,u=r;if(n&&w(n,u,l,t),a&&T(a,u,l,t),o.children!==void 0){if(!Array.isArray(o.children))throw TypeError(`[router.${t}] Route "${s}" children must be an array, got ${h(o.children)}`);for(let e of o.children)E(e,t,n,c,i,a)}}export{i as getInternals,E as validateRoute};
1
+ import{a as e,i as t,n,r,u as i}from"./buildParamMeta-D8td47fL.mjs";function a(e,t){return TypeError(`[router.${e}] ${t}`)}function o(e,t,n,r){let i=new Set;for(let o of e){if(i.has(o))throw a(n,`Invalid path for route "${t}": duplicate parameter name ':${o}' in "${r}" (a param name must be unique within a route — the second binding would overwrite the first)`);i.add(o)}}function s(e,t,r,i){for(let o of e)if(n.test(o))throw a(r,`Invalid path for route "${t}": invalid query-param name "${o}" in "${i}" (a query-param name cannot contain '<' or '>' — it would never round-trip; rename the query param)`)}function c(e){let t=!0,n=!1;for(let r of e){if(r===`/`){t=!0;continue}if(t&&=(n=r===`:`||r===`*`,!1),!n&&r.codePointAt(0)>=128)return!0}return!1}function l(e,t,n){switch(e){case`name-less`:case`trailing-marker`:return`Invalid path for route "${t}": parameter marker (':' or '*') without a name in "${n}"`;case`fused-marker`:return`Invalid path for route "${t}": parameter marker (':' or '*') must begin a segment, but "${n}" fuses one to a static prefix (use a boundary marker like "/a/:b")`}}function u(e,t){return e.code===`optional-removed`?`Invalid path for route "${t}": optional params are not supported — "${e.segment}". Declare two sibling routes instead: "${e.withoutSegment}" and "${e.requiredForm}" (the route hierarchy already expresses optionality)`:`Invalid path for route "${t}": regex constraints are not supported — '<' and '>' are reserved in path segments ("${e.segment}"). Match the segment as a plain string and validate the value in a guard (canActivate) or app code`}function d(n,i,d,f){if(typeof n!=`string`){let e;throw e=n===null?`null`:Array.isArray(n)?`array`:typeof n,a(d,`Route path must be a string, got ${e}`)}if(n===``)return;if(/\s/.test(n))throw a(d,`Invalid path for route "${i}": whitespace not allowed in "${n}"`);if(!/^([/?~]|[^/]+$)/.test(n))throw a(d,`Route "${i}" has invalid path format: "${n}". Path should start with '/', '~', '?' or be a relative segment.`);if(n.includes(`//`))throw a(d,`Invalid path for route "${i}": double slashes not allowed in "${n}"`);let{pathPattern:p,urlParams:m,queryParams:h}=r(n);o(m,i,d,n),s(h,i,d,n);let g=t(p);if(g!==void 0)throw a(d,u(g,i));let _=e(p);if(_!==void 0)throw a(d,l(_,i,n));if(c(p))throw a(d,`Invalid path for route "${i}": non-ASCII static segment in "${n}" — match compares static segments raw and rejects non-ASCII input, so this route would never match. Percent-encode it (e.g. '/caf%C3%A9') or use a param`);let v=f&&f.paramMeta.urlParams.length>0;if(n.startsWith(`~`)&&v)throw a(d,`Absolute path "${n}" cannot be used under parent route with URL parameters`)}const f=/^[A-Z_a-z][\w-]*$/,p=/\S/,m=1e4;function h(e){if(e===null)return`null`;if(typeof e==`object`){try{let t=e.constructor;if(typeof t==`function`&&t.name!==`Object`)return t.name||`object`}catch{}return`object`}return typeof e}function g(e){for(let t of Object.keys(e)){let n=Object.getOwnPropertyDescriptor(e,t);if(n&&(n.get||n.set))return!0}return!1}function _(e,t){if(!e||typeof e!=`object`)throw TypeError(`[router.${t}] Route must be an object, got ${h(e)}`);let n=Object.getPrototypeOf(e);if(n!==Object.prototype&&n!==null)throw TypeError(`[router.${t}] Route must be a plain object, got ${h(e)}`);if(g(e))throw TypeError(`[router.${t}] Route must not have getters or setters`)}function v(e,t){if(e.encodeParams!==void 0&&typeof e.encodeParams!=`function`)throw TypeError(`[router.${t}] Route "${String(e.name)}" encodeParams must be a function`)}function y(e,t){if(e.decodeParams!==void 0&&typeof e.decodeParams!=`function`)throw TypeError(`[router.${t}] Route "${String(e.name)}" decodeParams must be a function`)}function b(e,t){if(typeof e.name!=`string`)throw TypeError(`[router.${t}] Route name must be a string, got ${h(e.name)}`);let n=e.name;if(n===``)throw TypeError(`[router.${t}] Route name cannot be empty`);if(!p.test(n))throw TypeError(`[router.${t}] Route name cannot contain only whitespace`);if(n.length>m)throw TypeError(`[router.${t}] Route name exceeds maximum length of ${m} characters`);if(!n.startsWith(`@@`)){if(n.includes(`.`))throw TypeError(`[router.${t}] Route name "${n}" cannot contain dots. Use children array or { parent } option in addRoute() instead.`);if(!f.test(n))throw TypeError(`[router.${t}] Invalid route name "${n}". Name must start with a letter or underscore, followed by letters, numbers, underscores, or hyphens.`)}}function x(e,t){if(!t.includes(`.`))return e.children.get(t);let n=e;for(let e of t.split(`.`))if(n=n.children.get(e),!n)return;return n}function S(e,t,n){if(x(e,t))throw Error(`[router.${n}] Route "${t}" already exists`)}function C(e,t,n){if(e.has(t))throw Error(`[router.${n}] Duplicate route "${t}" in batch`);e.add(t)}function w(e,t,n,r){let i=t===``?e:x(e,t);if(i){for(let e of i.children.values())if(e.path===n)throw Error(`[router.${r}] Path "${n}" is already defined`)}}function T(e,t,n,r){let i=e.get(t);if(i?.has(n))throw Error(`[router.${r}] Path "${n}" is already defined`);i?i.add(n):e.set(t,new Set([n]))}function E(e,t,n,r=``,i,a){_(e,t);let o=e;b(o,t),d(o.path,o.name,t,n),v(o,t),y(o,t);let s=o.name,c=r?`${r}.${s}`:s;n&&c&&S(n,c,t),i&&C(i,c,t);let l=o.path,u=r;if(n&&w(n,u,l,t),a&&T(a,u,l,t),o.children!==void 0){if(!Array.isArray(o.children))throw TypeError(`[router.${t}] Route "${s}" children must be an array, got ${h(o.children)}`);for(let e of o.children)E(e,t,n,c,i,a)}}export{i as getInternals,E as validateRoute};
2
2
  //# sourceMappingURL=validation.mjs.map