eleva 1.0.1 → 1.1.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 (97) hide show
  1. package/README.md +21 -10
  2. package/dist/{eleva-plugins.cjs.js → eleva-plugins.cjs} +1002 -292
  3. package/dist/eleva-plugins.cjs.map +1 -0
  4. package/dist/eleva-plugins.d.cts +1352 -0
  5. package/dist/eleva-plugins.d.cts.map +1 -0
  6. package/dist/eleva-plugins.d.ts +1352 -0
  7. package/dist/eleva-plugins.d.ts.map +1 -0
  8. package/dist/{eleva-plugins.esm.js → eleva-plugins.js} +1002 -292
  9. package/dist/eleva-plugins.js.map +1 -0
  10. package/dist/eleva-plugins.umd.js +1001 -291
  11. package/dist/eleva-plugins.umd.js.map +1 -1
  12. package/dist/eleva-plugins.umd.min.js +1 -1
  13. package/dist/eleva-plugins.umd.min.js.map +1 -1
  14. package/dist/{eleva.cjs.js → eleva.cjs} +421 -191
  15. package/dist/eleva.cjs.map +1 -0
  16. package/dist/eleva.d.cts +1329 -0
  17. package/dist/eleva.d.cts.map +1 -0
  18. package/dist/eleva.d.ts +473 -226
  19. package/dist/eleva.d.ts.map +1 -0
  20. package/dist/{eleva.esm.js → eleva.js} +422 -192
  21. package/dist/eleva.js.map +1 -0
  22. package/dist/eleva.umd.js +420 -190
  23. package/dist/eleva.umd.js.map +1 -1
  24. package/dist/eleva.umd.min.js +1 -1
  25. package/dist/eleva.umd.min.js.map +1 -1
  26. package/dist/plugins/attr.cjs +279 -0
  27. package/dist/plugins/attr.cjs.map +1 -0
  28. package/dist/plugins/attr.d.cts +101 -0
  29. package/dist/plugins/attr.d.cts.map +1 -0
  30. package/dist/plugins/attr.d.ts +101 -0
  31. package/dist/plugins/attr.d.ts.map +1 -0
  32. package/dist/plugins/attr.js +276 -0
  33. package/dist/plugins/attr.js.map +1 -0
  34. package/dist/plugins/attr.umd.js +111 -22
  35. package/dist/plugins/attr.umd.js.map +1 -1
  36. package/dist/plugins/attr.umd.min.js +1 -1
  37. package/dist/plugins/attr.umd.min.js.map +1 -1
  38. package/dist/plugins/router.cjs +1873 -0
  39. package/dist/plugins/router.cjs.map +1 -0
  40. package/dist/plugins/router.d.cts +1296 -0
  41. package/dist/plugins/router.d.cts.map +1 -0
  42. package/dist/plugins/router.d.ts +1296 -0
  43. package/dist/plugins/router.d.ts.map +1 -0
  44. package/dist/plugins/router.js +1870 -0
  45. package/dist/plugins/router.js.map +1 -0
  46. package/dist/plugins/router.umd.js +482 -186
  47. package/dist/plugins/router.umd.js.map +1 -1
  48. package/dist/plugins/router.umd.min.js +1 -1
  49. package/dist/plugins/router.umd.min.js.map +1 -1
  50. package/dist/plugins/store.cjs +920 -0
  51. package/dist/plugins/store.cjs.map +1 -0
  52. package/dist/plugins/store.d.cts +266 -0
  53. package/dist/plugins/store.d.cts.map +1 -0
  54. package/dist/plugins/store.d.ts +266 -0
  55. package/dist/plugins/store.d.ts.map +1 -0
  56. package/dist/plugins/store.js +917 -0
  57. package/dist/plugins/store.js.map +1 -0
  58. package/dist/plugins/store.umd.js +410 -85
  59. package/dist/plugins/store.umd.js.map +1 -1
  60. package/dist/plugins/store.umd.min.js +1 -1
  61. package/dist/plugins/store.umd.min.js.map +1 -1
  62. package/package.json +112 -68
  63. package/src/core/Eleva.js +195 -115
  64. package/src/index.cjs +10 -0
  65. package/src/index.js +11 -0
  66. package/src/modules/Emitter.js +68 -20
  67. package/src/modules/Renderer.js +82 -20
  68. package/src/modules/Signal.js +43 -15
  69. package/src/modules/TemplateEngine.js +50 -9
  70. package/src/plugins/Attr.js +121 -19
  71. package/src/plugins/Router.js +526 -181
  72. package/src/plugins/Store.js +448 -69
  73. package/src/plugins/index.js +1 -0
  74. package/types/core/Eleva.d.ts +263 -169
  75. package/types/core/Eleva.d.ts.map +1 -1
  76. package/types/index.d.cts +3 -0
  77. package/types/index.d.cts.map +1 -0
  78. package/types/index.d.ts +5 -0
  79. package/types/index.d.ts.map +1 -1
  80. package/types/modules/Emitter.d.ts +73 -30
  81. package/types/modules/Emitter.d.ts.map +1 -1
  82. package/types/modules/Renderer.d.ts +48 -18
  83. package/types/modules/Renderer.d.ts.map +1 -1
  84. package/types/modules/Signal.d.ts +44 -16
  85. package/types/modules/Signal.d.ts.map +1 -1
  86. package/types/modules/TemplateEngine.d.ts +46 -11
  87. package/types/modules/TemplateEngine.d.ts.map +1 -1
  88. package/types/plugins/Attr.d.ts +83 -16
  89. package/types/plugins/Attr.d.ts.map +1 -1
  90. package/types/plugins/Router.d.ts +498 -207
  91. package/types/plugins/Router.d.ts.map +1 -1
  92. package/types/plugins/Store.d.ts +211 -37
  93. package/types/plugins/Store.d.ts.map +1 -1
  94. package/dist/eleva-plugins.cjs.js.map +0 -1
  95. package/dist/eleva-plugins.esm.js.map +0 -1
  96. package/dist/eleva.cjs.js.map +0 -1
  97. package/dist/eleva.esm.js.map +0 -1
@@ -0,0 +1,1296 @@
1
+ import * as eleva from 'eleva';
2
+
3
+ /**
4
+ * Interface for router plugins.
5
+ */
6
+ type RouterPlugin = {
7
+ /**
8
+ * Unique plugin identifier.
9
+ */
10
+ name: string;
11
+ /**
12
+ * Plugin version (recommended to match router version).
13
+ */
14
+ version?: string | undefined;
15
+ /**
16
+ * Installation function.
17
+ */
18
+ install: (router: Router, options?: Record<string, unknown>) => void;
19
+ /**
20
+ * Cleanup function called on router.destroy().
21
+ */
22
+ destroy?: ((router: Router) => void | Promise<void>) | undefined;
23
+ };
24
+ declare namespace RouterPlugin {
25
+ let name: string;
26
+ let version: string;
27
+ let description: string;
28
+ /**
29
+ * Installs the RouterPlugin into an Eleva instance.
30
+ *
31
+ * @public
32
+ * @param {Eleva} eleva - The Eleva instance.
33
+ * @param {RouterOptions} options - Router configuration options.
34
+ * @param {string} options.mount - A CSS selector for the main element where the app is mounted.
35
+ * @param {RouteDefinition[]} options.routes - An array of route definitions.
36
+ * @param {'hash' | 'query' | 'history'} [options.mode='hash'] - The routing mode.
37
+ * @param {string} [options.queryParam='view'] - The query parameter to use in 'query' mode.
38
+ * @param {string} [options.viewSelector='view'] - Base selector for the view element (matched as #id, .class, [data-*], or raw selector).
39
+ * @param {boolean} [options.autoStart=true] - Whether to start the router automatically.
40
+ * @param {NavigationGuard} [options.onBeforeEach] - A global guard executed before every navigation.
41
+ * @param {RouteComponent} [options.globalLayout] - A global layout for all routes.
42
+ * @returns {Router} The created router instance.
43
+ * @throws {Error} If 'mount' option is not provided.
44
+ * @throws {Error} If 'routes' option is not an array.
45
+ * @throws {Error} If component registration fails during route processing.
46
+ * @description
47
+ * Registers route/layout components, sets `eleva.router`, and adds helpers
48
+ * (`eleva.navigate`, `eleva.getCurrentRoute`, `eleva.getRouteParams`, `eleva.getRouteQuery`).
49
+ * When `autoStart` is enabled, startup is scheduled via microtask.
50
+ *
51
+ * @example
52
+ * // main.js
53
+ * import Eleva from 'eleva';
54
+ * import { RouterPlugin } from './plugins/RouterPlugin.js';
55
+ *
56
+ * const app = new Eleva('myApp');
57
+ *
58
+ * const HomePage = { template: () => `<h1>Home</h1>` };
59
+ * const AboutPage = { template: () => `<h1>About Us</h1>` };
60
+ *
61
+ * app.use(RouterPlugin, {
62
+ * mount: '#app',
63
+ * routes: [
64
+ * { path: '/', component: HomePage },
65
+ * { path: '/about', component: AboutPage }
66
+ * ]
67
+ * });
68
+ */
69
+ function install(eleva: Eleva, options?: RouterOptions): Router;
70
+ /**
71
+ * Uninstalls the plugin from the Eleva instance.
72
+ *
73
+ * @public
74
+ * @async
75
+ * @param {Eleva} eleva - The Eleva instance.
76
+ * @returns {Promise<void>}
77
+ * @description
78
+ * Destroys the router instance, removes `eleva.router`, and deletes helper methods
79
+ * (`eleva.navigate`, `eleva.getCurrentRoute`, `eleva.getRouteParams`, `eleva.getRouteQuery`).
80
+ */
81
+ function uninstall(eleva: Eleva): Promise<void>;
82
+ }
83
+
84
+ /**
85
+ * Type imports from the Eleva core library.
86
+ */
87
+ type Eleva = eleva.Eleva;
88
+ /**
89
+ * Type imports from the Eleva core library.
90
+ */
91
+ type ComponentDefinition = eleva.ComponentDefinition;
92
+ /**
93
+ * Type imports from the Eleva core library.
94
+ */
95
+ type Emitter = eleva.Emitter;
96
+ /**
97
+ * Type imports from the Eleva core library.
98
+ */
99
+ type MountResult = eleva.MountResult;
100
+ /**
101
+ * Type imports from the Eleva core library.
102
+ */
103
+ type UnsubscribeFunction = eleva.UnsubscribeFunction;
104
+ /**
105
+ * Generic type import.
106
+ */
107
+ type Signal<T> = eleva.Signal<T>;
108
+ /**
109
+ * The routing mode determines how the router manages URL state.
110
+ * - `hash`: Uses URL hash (e.g., `/#/path`) - works without server config
111
+ * - `history`: Uses HTML5 History API (e.g., `/path`) - requires server config
112
+ * - `query`: Uses query parameters (e.g., `?view=/path`) - useful for embedded apps
113
+ */
114
+ type RouterMode = "hash" | "history" | "query";
115
+ /**
116
+ * Route parameters extracted from the URL path.
117
+ */
118
+ type RouteParams = Record<string, string>;
119
+ /**
120
+ * Query parameters from the URL query string.
121
+ */
122
+ type QueryParams = Record<string, string>;
123
+ /**
124
+ * Navigation input parameters supporting multiple value types.
125
+ */
126
+ type NavigationParams = Record<string, string | number | boolean>;
127
+ /**
128
+ * Function signature for programmatic navigation.
129
+ */
130
+ type NavigateFunction = (location: string | NavigationTarget, params?: NavigationParams) => Promise<boolean>;
131
+ /**
132
+ * Router configuration options.
133
+ */
134
+ type RouterOptions = {
135
+ /**
136
+ * The routing mode to use.
137
+ */
138
+ mode?: RouterMode | undefined;
139
+ /**
140
+ * Query parameter name for 'query' mode.
141
+ */
142
+ queryParam?: string | undefined;
143
+ /**
144
+ * Base selector for the view element.
145
+ */
146
+ viewSelector?: string | undefined;
147
+ /**
148
+ * CSS selector for the mount point element.
149
+ */
150
+ mount: string;
151
+ /**
152
+ * Array of route definitions.
153
+ */
154
+ routes: RouteDefinition[];
155
+ /**
156
+ * Default layout for all routes.
157
+ */
158
+ globalLayout?: RouteComponent | undefined;
159
+ /**
160
+ * Global navigation guard.
161
+ */
162
+ onBeforeEach?: NavigationGuard | undefined;
163
+ /**
164
+ * Whether to start the router automatically.
165
+ */
166
+ autoStart?: boolean | undefined;
167
+ };
168
+ /**
169
+ * Object describing a navigation target for `router.navigate()`.
170
+ */
171
+ type NavigationTarget = {
172
+ /**
173
+ * The target path (can include params like '/users/:id').
174
+ */
175
+ path: string;
176
+ /**
177
+ * Route parameters to inject.
178
+ */
179
+ params?: NavigationParams | undefined;
180
+ /**
181
+ * Query parameters to append.
182
+ */
183
+ query?: NavigationParams | undefined;
184
+ /**
185
+ * Whether to replace current history entry.
186
+ */
187
+ replace?: boolean | undefined;
188
+ /**
189
+ * History state to pass.
190
+ */
191
+ state?: unknown;
192
+ };
193
+ /**
194
+ * Saved scroll position.
195
+ */
196
+ type ScrollPosition = {
197
+ /**
198
+ * Horizontal scroll position.
199
+ */
200
+ x: number;
201
+ /**
202
+ * Vertical scroll position.
203
+ */
204
+ y: number;
205
+ };
206
+ /**
207
+ * Internal representation of a parsed route path segment.
208
+ */
209
+ type RouteSegment = {
210
+ /**
211
+ * The segment type.
212
+ */
213
+ type: "static" | "param";
214
+ /**
215
+ * The segment value (static segments).
216
+ */
217
+ value?: string | undefined;
218
+ /**
219
+ * The parameter name (param segments).
220
+ */
221
+ name?: string | undefined;
222
+ };
223
+ /**
224
+ * Result of matching a path against route definitions.
225
+ */
226
+ type RouteMatch = {
227
+ /**
228
+ * The matched route definition.
229
+ */
230
+ route: RouteDefinition;
231
+ /**
232
+ * The extracted route parameters.
233
+ */
234
+ params: RouteParams;
235
+ };
236
+ /**
237
+ * Arbitrary metadata attached to routes for use in guards and components.
238
+ */
239
+ type RouteMeta = Record<string, unknown>;
240
+ /**
241
+ * Interface for the router's error handling system.
242
+ */
243
+ type RouterErrorHandler = {
244
+ /**
245
+ * Throws a formatted error.
246
+ */
247
+ handle: (error: Error, context: string, details?: Record<string, unknown>) => void;
248
+ /**
249
+ * Logs a warning.
250
+ */
251
+ warn: (message: string, details?: Record<string, unknown>) => void;
252
+ /**
253
+ * Logs an error without throwing.
254
+ */
255
+ log: (message: string, error: Error, details?: Record<string, unknown>) => void;
256
+ };
257
+ /**
258
+ * Callback for `router:beforeEach` event.
259
+ */
260
+ type NavigationContextCallback = (context: NavigationContext) => void | Promise<void>;
261
+ /**
262
+ * Callback for `router:beforeResolve` and `router:afterResolve` events.
263
+ */
264
+ type ResolveContextCallback = (context: ResolveContext) => void | Promise<void>;
265
+ /**
266
+ * Callback for `router:beforeRender` and `router:afterRender` events.
267
+ */
268
+ type RenderContextCallback = (context: RenderContext) => void | Promise<void>;
269
+ /**
270
+ * Callback for `router:scroll` event.
271
+ */
272
+ type ScrollContextCallback = (context: ScrollContext) => void | Promise<void>;
273
+ /**
274
+ * Callback for `router:afterEnter`, `router:afterLeave`, `router:afterEach` events.
275
+ */
276
+ type RouteChangeCallback = (to: RouteLocation, from: RouteLocation | null) => void | Promise<void>;
277
+ /**
278
+ * Router context injected into component setup as `ctx.router`.
279
+ */
280
+ type RouterContext = {
281
+ /**
282
+ * Programmatic navigation function.
283
+ */
284
+ navigate: NavigateFunction;
285
+ /**
286
+ * Reactive signal for current route.
287
+ */
288
+ current: Signal<RouteLocation | null>;
289
+ /**
290
+ * Reactive signal for previous route.
291
+ */
292
+ previous: Signal<RouteLocation | null>;
293
+ /**
294
+ * Current route params (getter).
295
+ */
296
+ params: RouteParams;
297
+ /**
298
+ * Current route query (getter).
299
+ */
300
+ query: QueryParams;
301
+ /**
302
+ * Current route path (getter).
303
+ */
304
+ path: string;
305
+ /**
306
+ * Current routed URL string (getter).
307
+ */
308
+ fullUrl: string;
309
+ /**
310
+ * Current route meta (getter).
311
+ */
312
+ meta: RouteMeta;
313
+ };
314
+ /**
315
+ * Callback for `router:error` event.
316
+ */
317
+ type RouterErrorCallback = (error: Error, to?: RouteLocation | undefined, from?: RouteLocation | null | undefined) => void | Promise<void>;
318
+ /**
319
+ * Callback for `router:ready` event.
320
+ */
321
+ type RouterReadyCallback = (router: Router) => void | Promise<void>;
322
+ /**
323
+ * Callback for `router:routeAdded` event.
324
+ */
325
+ type RouteAddedCallback = (route: RouteDefinition) => void | Promise<void>;
326
+ /**
327
+ * Callback for `router:routeRemoved` event.
328
+ */
329
+ type RouteRemovedCallback = (route: RouteDefinition) => void | Promise<void>;
330
+ /**
331
+ * Represents the current or target location in the router.
332
+ */
333
+ type RouteLocation = {
334
+ /**
335
+ * The path of the route (e.g., '/users/123').
336
+ */
337
+ path: string;
338
+ /**
339
+ * Query parameters as key-value pairs.
340
+ */
341
+ query: QueryParams;
342
+ /**
343
+ * The routed URL string (path plus query).
344
+ */
345
+ fullUrl: string;
346
+ /**
347
+ * Dynamic route parameters.
348
+ */
349
+ params: RouteParams;
350
+ /**
351
+ * Metadata associated with the matched route.
352
+ */
353
+ meta: RouteMeta;
354
+ /**
355
+ * The optional name of the matched route.
356
+ */
357
+ name?: string | undefined;
358
+ /**
359
+ * The raw route definition that was matched.
360
+ */
361
+ matched: RouteDefinition;
362
+ };
363
+ /**
364
+ * Return value of a navigation guard.
365
+ * - `true` or `undefined/void`: Allow navigation
366
+ * - `false`: Abort navigation
367
+ * - `string`: Redirect to path
368
+ * - `NavigationTarget`: Redirect with options
369
+ */
370
+ type NavigationGuardResult = boolean | string | NavigationTarget | void;
371
+ /**
372
+ * Navigation guard function that controls navigation flow.
373
+ */
374
+ type NavigationGuard = (to: RouteLocation, from: RouteLocation | null) => NavigationGuardResult | Promise<NavigationGuardResult>;
375
+ /**
376
+ * Navigation hook for side effects. Does not affect navigation flow.
377
+ */
378
+ type NavigationHook = (to: RouteLocation, from: RouteLocation | null) => void | Promise<void>;
379
+ /**
380
+ * Context object for navigation events that plugins can modify.
381
+ */
382
+ type NavigationContext = {
383
+ /**
384
+ * The target route location.
385
+ */
386
+ to: RouteLocation;
387
+ /**
388
+ * The source route location.
389
+ */
390
+ from: RouteLocation | null;
391
+ /**
392
+ * Whether navigation has been cancelled.
393
+ */
394
+ cancelled: boolean;
395
+ /**
396
+ * Redirect target if set.
397
+ */
398
+ redirectTo: string | NavigationTarget | null;
399
+ };
400
+ /**
401
+ * Context object for component resolution events.
402
+ */
403
+ type ResolveContext = {
404
+ /**
405
+ * The target route location.
406
+ */
407
+ to: RouteLocation;
408
+ /**
409
+ * The source route location.
410
+ */
411
+ from: RouteLocation | null;
412
+ /**
413
+ * The matched route definition.
414
+ */
415
+ route: RouteDefinition;
416
+ /**
417
+ * The resolved layout component (available in afterResolve).
418
+ */
419
+ layoutComponent: ComponentDefinition | null;
420
+ /**
421
+ * The resolved page component (available in afterResolve).
422
+ */
423
+ pageComponent: ComponentDefinition | null;
424
+ /**
425
+ * Whether navigation has been cancelled.
426
+ */
427
+ cancelled: boolean;
428
+ /**
429
+ * Redirect target if set.
430
+ */
431
+ redirectTo: string | NavigationTarget | null;
432
+ };
433
+ /**
434
+ * Context object for render events.
435
+ */
436
+ type RenderContext = {
437
+ /**
438
+ * The target route location.
439
+ */
440
+ to: RouteLocation;
441
+ /**
442
+ * The source route location.
443
+ */
444
+ from: RouteLocation | null;
445
+ /**
446
+ * The layout component being rendered.
447
+ */
448
+ layoutComponent: ComponentDefinition | null;
449
+ /**
450
+ * The page component being rendered.
451
+ */
452
+ pageComponent: ComponentDefinition;
453
+ };
454
+ /**
455
+ * Context object for scroll events.
456
+ */
457
+ type ScrollContext = {
458
+ /**
459
+ * The target route location.
460
+ */
461
+ to: RouteLocation;
462
+ /**
463
+ * The source route location.
464
+ */
465
+ from: RouteLocation | null;
466
+ /**
467
+ * Saved position (back/forward nav).
468
+ */
469
+ savedPosition: {
470
+ x: number;
471
+ y: number;
472
+ } | null;
473
+ };
474
+ /**
475
+ * A component that can be rendered for a route.
476
+ * - `string`: Name of a registered component
477
+ * - `ComponentDefinition`: Inline component definition
478
+ * - `() => ComponentDefinition`: Factory function returning a component
479
+ * - `() => Promise<ComponentDefinition>`: Async factory function
480
+ * - `() => Promise<{default: ComponentDefinition}>`: Lazy-loaded module (e.g., `() => import('./Page.js')`)
481
+ */
482
+ type RouteComponent = string | ComponentDefinition | (() => ComponentDefinition | Promise<ComponentDefinition | {
483
+ default: ComponentDefinition;
484
+ }>);
485
+ /**
486
+ * Defines a route in the application.
487
+ */
488
+ type RouteDefinition = {
489
+ /**
490
+ * URL path pattern. Supports:
491
+ * - Static: '/about'
492
+ * - Dynamic params: '/users/:id'
493
+ * - Wildcard: '*' (catch-all, conventionally last)
494
+ */
495
+ path: string;
496
+ /**
497
+ * The component to render for this route.
498
+ */
499
+ component: RouteComponent;
500
+ /**
501
+ * Optional layout component to wrap the route component.
502
+ */
503
+ layout?: RouteComponent | undefined;
504
+ /**
505
+ * Optional route name for programmatic navigation.
506
+ */
507
+ name?: string | undefined;
508
+ /**
509
+ * Optional metadata (auth flags, titles, etc.).
510
+ */
511
+ meta?: RouteMeta | undefined;
512
+ /**
513
+ * Route-specific guard before entering.
514
+ */
515
+ beforeEnter?: NavigationGuard | undefined;
516
+ /**
517
+ * Hook after entering and component is mounted.
518
+ */
519
+ afterEnter?: NavigationHook | undefined;
520
+ /**
521
+ * Guard before leaving this route.
522
+ */
523
+ beforeLeave?: NavigationGuard | undefined;
524
+ /**
525
+ * Hook after leaving and component is unmounted.
526
+ */
527
+ afterLeave?: NavigationHook | undefined;
528
+ /**
529
+ * Internal: parsed path segments (added by router).
530
+ */
531
+ segments?: RouteSegment[] | undefined;
532
+ };
533
+ /**
534
+ * Represents the current or target location in the router.
535
+ * @typedef {Object} RouteLocation
536
+ * @property {string} path
537
+ * The path of the route (e.g., '/users/123').
538
+ * @property {QueryParams} query
539
+ * Query parameters as key-value pairs.
540
+ * @property {string} fullUrl
541
+ * The routed URL string (path plus query).
542
+ * @property {RouteParams} params
543
+ * Dynamic route parameters.
544
+ * @property {RouteMeta} meta
545
+ * Metadata associated with the matched route.
546
+ * @property {string} [name]
547
+ * The optional name of the matched route.
548
+ * @property {RouteDefinition} matched
549
+ * The raw route definition that was matched.
550
+ * @description Represents the current or target location in the router.
551
+ */
552
+ /**
553
+ * Return value of a navigation guard.
554
+ * - `true` or `undefined/void`: Allow navigation
555
+ * - `false`: Abort navigation
556
+ * - `string`: Redirect to path
557
+ * - `NavigationTarget`: Redirect with options
558
+ * @typedef {boolean | string | NavigationTarget | void} NavigationGuardResult
559
+ */
560
+ /**
561
+ * Navigation guard function that controls navigation flow.
562
+ * @callback NavigationGuard
563
+ * @param {RouteLocation} to
564
+ * The target route location.
565
+ * @param {RouteLocation | null} from
566
+ * The source route location (null on initial).
567
+ * @returns {NavigationGuardResult | Promise<NavigationGuardResult>}
568
+ * @description A function that controls navigation flow. Runs before navigation is confirmed.
569
+ * @example
570
+ * // Simple auth guard
571
+ * const authGuard = (to, from) => {
572
+ * if (to.meta.requiresAuth && !isLoggedIn()) {
573
+ * return '/login'; // Redirect
574
+ * }
575
+ * // Allow navigation (implicit return undefined)
576
+ * };
577
+ */
578
+ /**
579
+ * Navigation hook for side effects. Does not affect navigation flow.
580
+ * @callback NavigationHook
581
+ * @param {RouteLocation} to
582
+ * The target route location.
583
+ * @param {RouteLocation | null} from
584
+ * The source route location.
585
+ * @returns {void | Promise<void>}
586
+ * @description A lifecycle hook for side effects. Does not affect navigation flow.
587
+ * @example
588
+ * // Analytics hook
589
+ * const analyticsHook = (to, from) => {
590
+ * analytics.trackPageView(to.path);
591
+ * };
592
+ */
593
+ /**
594
+ * Interface for router plugins.
595
+ * @typedef {Object} RouterPlugin
596
+ * @property {string} name
597
+ * Unique plugin identifier.
598
+ * @property {string} [version]
599
+ * Plugin version (recommended to match router version).
600
+ * @property {(router: Router, options?: Record<string, unknown>) => void} install
601
+ * Installation function.
602
+ * @property {(router: Router) => void | Promise<void>} [destroy]
603
+ * Cleanup function called on router.destroy().
604
+ * @description Interface for router plugins. Plugins can extend router functionality.
605
+ * @example
606
+ * const AnalyticsPlugin = {
607
+ * name: 'analytics',
608
+ * version: '1.0.0',
609
+ * install(router, options) {
610
+ * router.emitter.on('router:afterEach', (to, from) => {
611
+ * analytics.track(to.path);
612
+ * });
613
+ * }
614
+ * };
615
+ */
616
+ /**
617
+ * Context object for navigation events that plugins can modify.
618
+ * @typedef {Object} NavigationContext
619
+ * @property {RouteLocation} to
620
+ * The target route location.
621
+ * @property {RouteLocation | null} from
622
+ * The source route location.
623
+ * @property {boolean} cancelled
624
+ * Whether navigation has been cancelled.
625
+ * @property {string | NavigationTarget | null} redirectTo
626
+ * Redirect target if set.
627
+ * @description Passed to navigation events. Plugins can modify to control navigation flow.
628
+ */
629
+ /**
630
+ * Context object for component resolution events.
631
+ * @typedef {Object} ResolveContext
632
+ * @property {RouteLocation} to
633
+ * The target route location.
634
+ * @property {RouteLocation | null} from
635
+ * The source route location.
636
+ * @property {RouteDefinition} route
637
+ * The matched route definition.
638
+ * @property {ComponentDefinition | null} layoutComponent
639
+ * The resolved layout component (available in afterResolve).
640
+ * @property {ComponentDefinition | null} pageComponent
641
+ * The resolved page component (available in afterResolve).
642
+ * @property {boolean} cancelled
643
+ * Whether navigation has been cancelled.
644
+ * @property {string | NavigationTarget | null} redirectTo
645
+ * Redirect target if set.
646
+ * @description Passed to component resolution events.
647
+ */
648
+ /**
649
+ * Context object for render events.
650
+ * @typedef {Object} RenderContext
651
+ * @property {RouteLocation} to
652
+ * The target route location.
653
+ * @property {RouteLocation | null} from
654
+ * The source route location.
655
+ * @property {ComponentDefinition | null} layoutComponent
656
+ * The layout component being rendered.
657
+ * @property {ComponentDefinition} pageComponent
658
+ * The page component being rendered.
659
+ * @description Passed to render events.
660
+ */
661
+ /**
662
+ * Context object for scroll events.
663
+ * @typedef {Object} ScrollContext
664
+ * @property {RouteLocation} to
665
+ * The target route location.
666
+ * @property {RouteLocation | null} from
667
+ * The source route location.
668
+ * @property {{x: number, y: number} | null} savedPosition
669
+ * Saved position (back/forward nav).
670
+ * @description Passed to scroll events for plugins to handle scroll behavior.
671
+ */
672
+ /**
673
+ * A component that can be rendered for a route.
674
+ * - `string`: Name of a registered component
675
+ * - `ComponentDefinition`: Inline component definition
676
+ * - `() => ComponentDefinition`: Factory function returning a component
677
+ * - `() => Promise<ComponentDefinition>`: Async factory function
678
+ * - `() => Promise<{default: ComponentDefinition}>`: Lazy-loaded module (e.g., `() => import('./Page.js')`)
679
+ * @typedef {string | ComponentDefinition | (() => ComponentDefinition | Promise<ComponentDefinition | {default: ComponentDefinition}>)} RouteComponent
680
+ */
681
+ /**
682
+ * Defines a route in the application.
683
+ * @typedef {Object} RouteDefinition
684
+ * @property {string} path
685
+ * URL path pattern. Supports:
686
+ * - Static: '/about'
687
+ * - Dynamic params: '/users/:id'
688
+ * - Wildcard: '*' (catch-all, conventionally last)
689
+ * @property {RouteComponent} component
690
+ * The component to render for this route.
691
+ * @property {RouteComponent} [layout]
692
+ * Optional layout component to wrap the route component.
693
+ * @property {string} [name]
694
+ * Optional route name for programmatic navigation.
695
+ * @property {RouteMeta} [meta]
696
+ * Optional metadata (auth flags, titles, etc.).
697
+ * @property {NavigationGuard} [beforeEnter]
698
+ * Route-specific guard before entering.
699
+ * @property {NavigationHook} [afterEnter]
700
+ * Hook after entering and component is mounted.
701
+ * @property {NavigationGuard} [beforeLeave]
702
+ * Guard before leaving this route.
703
+ * @property {NavigationHook} [afterLeave]
704
+ * Hook after leaving and component is unmounted.
705
+ * @property {RouteSegment[]} [segments]
706
+ * Internal: parsed path segments (added by router).
707
+ * @description Defines a route in the application.
708
+ * @note Nested routes are not supported. Use shared layouts with flat routes instead.
709
+ * @example
710
+ * // Static route
711
+ * { path: '/about', component: AboutPage }
712
+ *
713
+ * // Dynamic route with params
714
+ * { path: '/users/:id', component: UserPage, meta: { requiresAuth: true } }
715
+ *
716
+ * // Lazy-loaded route with layout
717
+ * {
718
+ * path: '/dashboard',
719
+ * component: () => import('./Dashboard.js'),
720
+ * layout: DashboardLayout,
721
+ * beforeEnter: (to, from) => isLoggedIn() || '/login'
722
+ * }
723
+ *
724
+ * // Catch-all 404 route (conventionally last)
725
+ * { path: '*', component: NotFoundPage }
726
+ */
727
+ /**
728
+ * @class 🛤️ Router
729
+ * @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.
730
+ * This class manages all routing logic, including state, navigation, and rendering.
731
+ *
732
+ * ## Features
733
+ * - Multiple routing modes (hash, history, query)
734
+ * - Reactive route state via Signals
735
+ * - Navigation guards and lifecycle hooks
736
+ * - Lazy-loaded components
737
+ * - Layout system
738
+ * - Plugin architecture
739
+ * - Scroll position management
740
+ *
741
+ * ## Events Reference
742
+ * | Event | Callback Type | Can Block | Description |
743
+ * |-------|--------------|-----------|-------------|
744
+ * | `router:ready` | {@link RouterReadyCallback} | No | Router initialized |
745
+ * | `router:beforeEach` | {@link NavigationContextCallback} | Yes | Before guards run |
746
+ * | `router:beforeResolve` | {@link ResolveContextCallback} | Yes | Before component loading |
747
+ * | `router:afterResolve` | {@link ResolveContextCallback} | No | After components loaded |
748
+ * | `router:afterLeave` | {@link RouteChangeCallback} | No | After leaving route |
749
+ * | `router:beforeRender` | {@link RenderContextCallback} | No | Before DOM update |
750
+ * | `router:afterRender` | {@link RenderContextCallback} | No | After DOM update |
751
+ * | `router:scroll` | {@link ScrollContextCallback} | No | For scroll behavior |
752
+ * | `router:afterEnter` | {@link RouteChangeCallback} | No | After entering route |
753
+ * | `router:afterEach` | {@link RouteChangeCallback} | No | Navigation complete |
754
+ * | `router:error` | {@link RouterErrorCallback} | No | Navigation error |
755
+ * | `router:routeAdded` | {@link RouteAddedCallback} | No | Dynamic route added |
756
+ * | `router:routeRemoved` | {@link RouteRemovedCallback} | No | Dynamic route removed |
757
+ *
758
+ * ## Reactive Signals
759
+ * - `currentRoute: Signal<RouteLocation | null>` - Current route info
760
+ * - `previousRoute: Signal<RouteLocation | null>` - Previous route info
761
+ * - `currentParams: Signal<RouteParams>` - Current route params
762
+ * - `currentQuery: Signal<QueryParams>` - Current query params
763
+ * - `currentLayout: Signal<MountResult | null>` - Mounted layout instance
764
+ * - `currentView: Signal<MountResult | null>` - Mounted view instance
765
+ * - `isReady: Signal<boolean>` - Router readiness state
766
+ *
767
+ * @note Internal API Access Policy:
768
+ * As a core Eleva plugin, the Router may access internal Eleva APIs (prefixed with _)
769
+ * such as `eleva._components`. This is intentional and these internal APIs are
770
+ * considered stable for official plugins. Third-party plugins should avoid
771
+ * accessing internal APIs as they may change without notice.
772
+ *
773
+ * @example
774
+ * // Basic setup
775
+ * const router = new Router(eleva, {
776
+ * mode: 'hash',
777
+ * mount: '#app',
778
+ * routes: [
779
+ * { path: '/', component: HomePage },
780
+ * { path: '/users/:id', component: UserPage },
781
+ * { path: '*', component: NotFoundPage }
782
+ * ]
783
+ * });
784
+ *
785
+ * // Start router
786
+ * await router.start();
787
+ *
788
+ * // Navigate programmatically
789
+ * const success = await router.navigate('/users/123');
790
+ *
791
+ * // Watch for route changes
792
+ * router.currentRoute.watch((route) => {
793
+ * document.title = route?.meta?.title || 'My App';
794
+ * });
795
+ *
796
+ * @private
797
+ */
798
+ declare class Router {
799
+ /**
800
+ * Creates an instance of the Router.
801
+ * @param {Eleva} eleva - The Eleva framework instance.
802
+ * @param {RouterOptions} options - The configuration options for the router.
803
+ * @throws {Error} If the routing mode is invalid.
804
+ */
805
+ constructor(eleva: Eleva, options?: RouterOptions);
806
+ /** @type {Eleva} The Eleva framework instance. */
807
+ eleva: Eleva;
808
+ /** @type {RouterOptions} The merged router options. */
809
+ options: RouterOptions;
810
+ /** @private @type {RouteDefinition[]} The processed list of route definitions. */
811
+ private routes;
812
+ /** @private @type {Emitter} The shared Eleva event emitter for global hooks. */
813
+ private emitter;
814
+ /** @private @type {boolean} A flag indicating if the router has been started. */
815
+ private isStarted;
816
+ /** @private @type {boolean} A flag to prevent navigation loops from history events. */
817
+ private _isNavigating;
818
+ /** @private @type {number} Counter for tracking navigation operations to prevent race conditions. */
819
+ private _navigationId;
820
+ /** @private @type {UnsubscribeFunction[]} A collection of cleanup functions for event listeners. */
821
+ private eventListeners;
822
+ /** @type {Signal<RouteLocation | null>} A reactive signal holding the current route's information. */
823
+ currentRoute: Signal<RouteLocation | null>;
824
+ /** @type {Signal<RouteLocation | null>} A reactive signal holding the previous route's information. */
825
+ previousRoute: Signal<RouteLocation | null>;
826
+ /** @type {Signal<RouteParams>} A reactive signal holding the current route's parameters. */
827
+ currentParams: Signal<RouteParams>;
828
+ /** @type {Signal<QueryParams>} A reactive signal holding the current route's query parameters. */
829
+ currentQuery: Signal<QueryParams>;
830
+ /** @type {Signal<MountResult | null>} A reactive signal for the currently mounted layout instance. */
831
+ currentLayout: Signal<MountResult | null>;
832
+ /** @type {Signal<MountResult | null>} A reactive signal for the currently mounted view (page) instance. */
833
+ currentView: Signal<MountResult | null>;
834
+ /** @type {Signal<boolean>} A reactive signal indicating if the router is ready (started and initial navigation complete). */
835
+ isReady: Signal<boolean>;
836
+ /** @private @type {Map<string, RouterPlugin>} Map of registered plugins by name. */
837
+ private plugins;
838
+ /** @private @type {NavigationGuard[]} Array of global before-each navigation guards. */
839
+ private _beforeEachGuards;
840
+ /** @type {RouterErrorHandler} The error handler instance. Can be overridden by plugins. */
841
+ errorHandler: RouterErrorHandler;
842
+ /** @private @type {Map<string, {x: number, y: number}>} Saved scroll positions by route path. */
843
+ private _scrollPositions;
844
+ /**
845
+ * Validates the provided router options.
846
+ * @private
847
+ * @throws {Error} If the routing mode is invalid.
848
+ */
849
+ private _validateOptions;
850
+ /**
851
+ * Pre-processes route definitions to parse their path segments for efficient matching.
852
+ * @private
853
+ * @param {RouteDefinition[]} routes - The raw route definitions.
854
+ * @returns {RouteDefinition[]} The processed routes.
855
+ */
856
+ private _processRoutes;
857
+ /**
858
+ * Parses a route path string into an array of static and parameter segments.
859
+ * @private
860
+ * @param {string} path - The path pattern to parse.
861
+ * @returns {{type: 'static' | 'param', value?: string, name?: string}[]} An array of segment objects.
862
+ * @throws {Error} If the route path is not a valid string.
863
+ */
864
+ private _parsePathIntoSegments;
865
+ /**
866
+ * Finds the view element within a container using multiple selector strategies.
867
+ * @private
868
+ * @param {HTMLElement} container - The parent element to search within.
869
+ * @returns {HTMLElement} The found view element or the container itself as a fallback.
870
+ */
871
+ private _findViewElement;
872
+ /**
873
+ * Starts the router, initializes event listeners, and performs the initial navigation.
874
+ * @returns {Promise<Router>} The router instance for method chaining.
875
+ * @listens window:hashchange In hash mode, triggers route changes.
876
+ * @listens window:popstate In history/query mode, triggers route changes.
877
+ * @emits router:ready When initialization completes successfully.
878
+ * @see destroy - Stop the router and clean up listeners.
879
+ * @see navigate - Programmatically navigate to a route.
880
+ *
881
+ * @example
882
+ * // Basic usage
883
+ * await router.start();
884
+ *
885
+ * // Method chaining
886
+ * await router.start().then(r => r.navigate('/home'));
887
+ *
888
+ * // Reactive readiness
889
+ * router.isReady.watch((ready) => {
890
+ * if (ready) console.log('Router is ready!');
891
+ * });
892
+ */
893
+ start(): Promise<Router>;
894
+ /**
895
+ * Stops the router and cleans up event listeners.
896
+ * Unmounts the current layout instance if present.
897
+ * @async
898
+ * @returns {Promise<void>}
899
+ * @see start - Restart the router after destroying.
900
+ */
901
+ destroy(): Promise<void>;
902
+ /**
903
+ * Alias for destroy(). Stops the router and cleans up all resources.
904
+ * Provided for semantic consistency (start/stop pattern).
905
+ * @async
906
+ * @returns {Promise<void>}
907
+ *
908
+ * @example
909
+ * await router.start();
910
+ * // ... later
911
+ * await router.stop();
912
+ */
913
+ stop(): Promise<void>;
914
+ /**
915
+ * Programmatically navigates to a new route.
916
+ * @async
917
+ * @param {string | NavigationTarget} location - The target location as a path string or navigation target object.
918
+ * @param {NavigationParams} [params] - Route parameters (only used when location is a string).
919
+ * @returns {Promise<boolean>} True if navigation succeeded, false if blocked by guards or failed.
920
+ * @emits router:error When navigation fails due to an exception.
921
+ * @see start - Initialize the router before navigating.
922
+ * @see currentRoute - Access the current route after navigation.
923
+ *
924
+ * @example
925
+ * // Basic navigation
926
+ * await router.navigate('/users/123');
927
+ *
928
+ * // Check if navigation succeeded
929
+ * const success = await router.navigate('/protected');
930
+ * if (!success) {
931
+ * console.log('Navigation was blocked by a guard');
932
+ * }
933
+ *
934
+ * // Navigate with options
935
+ * await router.navigate({
936
+ * path: '/users/:id',
937
+ * params: { id: '123' },
938
+ * query: { tab: 'profile' },
939
+ * replace: true
940
+ * });
941
+ */
942
+ navigate(location: string | NavigationTarget, params?: NavigationParams): Promise<boolean>;
943
+ /**
944
+ * Builds a URL for query mode.
945
+ * @private
946
+ * @param {string} path - The path to set as the query parameter.
947
+ * @returns {string} The full URL with the updated query string.
948
+ */
949
+ private _buildQueryUrl;
950
+ /**
951
+ * Checks if the target route is identical to the current route.
952
+ * @private
953
+ * @param {string} path - The target path with query string.
954
+ * @param {object} params - The target params.
955
+ * @param {object} query - The target query.
956
+ * @returns {boolean} True if the routes are the same.
957
+ */
958
+ private _isSameRoute;
959
+ /**
960
+ * Injects dynamic parameters into a path string.
961
+ * Replaces `:param` placeholders with URL-encoded values from the params object.
962
+ *
963
+ * @private
964
+ * @param {string} path - The path pattern containing `:param` placeholders.
965
+ * @param {RouteParams} params - Key-value pairs to inject into the path.
966
+ * @returns {string} The path with all parameters replaced.
967
+ *
968
+ * @example
969
+ * this._buildPath('/users/:id/posts/:postId', { id: '123', postId: '456' });
970
+ * // Returns: '/users/123/posts/456'
971
+ */
972
+ private _buildPath;
973
+ /**
974
+ * The handler for browser-initiated route changes (e.g., back/forward buttons).
975
+ *
976
+ * @private
977
+ * @async
978
+ * @param {boolean} [isPopState=true] - Whether this is a popstate event (back/forward navigation).
979
+ * @returns {Promise<void>}
980
+ * @emits router:error When route change handling fails.
981
+ */
982
+ private _handleRouteChange;
983
+ /**
984
+ * Manages the core navigation lifecycle. Runs guards before committing changes.
985
+ *
986
+ * @private
987
+ * @async
988
+ * @param {string} fullPath - The full path (e.g., '/users/123?foo=bar') to navigate to.
989
+ * @param {boolean} [isPopState=false] - Whether this navigation was triggered by popstate (back/forward).
990
+ * @returns {Promise<boolean>} `true` if navigation succeeded, `false` if aborted.
991
+ * @emits router:notFound When no matching route is found.
992
+ * @emits router:beforeResolve Before component resolution (can block/redirect).
993
+ * @emits router:afterResolve After components are resolved.
994
+ * @emits router:afterLeave After leaving the previous route.
995
+ * @emits router:beforeRender Before DOM rendering.
996
+ * @emits router:afterRender After DOM rendering completes.
997
+ * @emits router:scroll After render, for scroll behavior handling.
998
+ * @emits router:afterEnter After entering the new route.
999
+ * @emits router:afterEach After navigation completes successfully.
1000
+ * @emits router:error When an error occurs during navigation.
1001
+ * @see _runGuards - Guard execution.
1002
+ * @see _resolveComponents - Component resolution.
1003
+ * @see _render - DOM rendering.
1004
+ */
1005
+ private _proceedWithNavigation;
1006
+ /**
1007
+ * Executes all applicable navigation guards for a transition in order.
1008
+ * Guards are executed in the following order:
1009
+ * 1. Global beforeEach event (emitter-based, can block via context)
1010
+ * 2. Global beforeEach guards (registered via onBeforeEach)
1011
+ * 3. Route-specific beforeLeave guard (from the route being left)
1012
+ * 4. Route-specific beforeEnter guard (from the route being entered)
1013
+ *
1014
+ * @private
1015
+ * @param {RouteLocation} to - The target route location.
1016
+ * @param {RouteLocation | null} from - The current route location (null on initial navigation).
1017
+ * @param {RouteDefinition} route - The matched route definition.
1018
+ * @returns {Promise<boolean>} `false` if navigation should be aborted.
1019
+ * @emits router:beforeEach Before guards run (can block/redirect via context).
1020
+ */
1021
+ private _runGuards;
1022
+ /**
1023
+ * Resolves a string component definition to a component object.
1024
+ * @private
1025
+ * @param {string} def - The component name to resolve.
1026
+ * @returns {ComponentDefinition} The resolved component.
1027
+ * @throws {Error} If the component is not registered.
1028
+ *
1029
+ * @note Core plugins (Router, Attr, Store) may access eleva._components
1030
+ * directly. This is intentional and stable for official Eleva plugins shipped
1031
+ * with the framework. Third-party plugins should use eleva.component() for
1032
+ * registration and avoid direct access to internal APIs.
1033
+ */
1034
+ private _resolveStringComponent;
1035
+ /**
1036
+ * Resolves a function component definition to a component object.
1037
+ * @private
1038
+ * @async
1039
+ * @param {() => ComponentDefinition | Promise<ComponentDefinition | { default: ComponentDefinition }>} def - The function to resolve.
1040
+ * @returns {Promise<ComponentDefinition>} The resolved component.
1041
+ * @throws {Error} If the function fails to load the component.
1042
+ */
1043
+ private _resolveFunctionComponent;
1044
+ /**
1045
+ * Validates a component definition object.
1046
+ * @private
1047
+ * @param {unknown} def - The component definition to validate.
1048
+ * @returns {ComponentDefinition} The validated component.
1049
+ * @throws {Error} If the component definition is invalid.
1050
+ */
1051
+ private _validateComponentDefinition;
1052
+ /**
1053
+ * Resolves a component definition to a component object.
1054
+ * @private
1055
+ * @param {unknown} def - The component definition to resolve.
1056
+ * @returns {Promise<ComponentDefinition | null>} The resolved component or null.
1057
+ */
1058
+ private _resolveComponent;
1059
+ /**
1060
+ * Asynchronously resolves the layout and page components for a route.
1061
+ * @private
1062
+ * @async
1063
+ * @param {RouteDefinition} route - The route to resolve components for.
1064
+ * @returns {Promise<{layoutComponent: ComponentDefinition | null, pageComponent: ComponentDefinition}>}
1065
+ * @throws {Error} If page component cannot be resolved.
1066
+ */
1067
+ private _resolveComponents;
1068
+ /**
1069
+ * Renders the components for the current route into the DOM.
1070
+ *
1071
+ * Rendering algorithm:
1072
+ * 1. Find the mount element using options.mount selector
1073
+ * 2. If layoutComponent exists:
1074
+ * a. Mount layout to mount element
1075
+ * b. Find view element within layout (using viewSelector)
1076
+ * c. Mount page component to view element
1077
+ * 3. If no layoutComponent:
1078
+ * a. Mount page component directly to mount element
1079
+ * b. Set currentLayout to null
1080
+ *
1081
+ * @private
1082
+ * @async
1083
+ * @param {ComponentDefinition | null} layoutComponent - The pre-loaded layout component.
1084
+ * @param {ComponentDefinition} pageComponent - The pre-loaded page component.
1085
+ * @returns {Promise<void>}
1086
+ * @throws {Error} If mount element is not found in the DOM.
1087
+ * @throws {Error} If component mounting fails (propagated from eleva.mount).
1088
+ */
1089
+ private _render;
1090
+ /**
1091
+ * Creates a getter function for router context properties.
1092
+ * @private
1093
+ * @param {string} property - The property name to access.
1094
+ * @param {unknown} defaultValue - The default value if property is undefined.
1095
+ * @returns {() => unknown} A getter function.
1096
+ */
1097
+ private _createRouteGetter;
1098
+ /**
1099
+ * Wraps a component definition to inject router-specific context into its setup function.
1100
+ * @private
1101
+ * @param {ComponentDefinition} component - The component to wrap.
1102
+ * @returns {ComponentDefinition} The wrapped component definition.
1103
+ */
1104
+ private _wrapComponent;
1105
+ /**
1106
+ * Recursively wraps all child components to ensure they have access to router context.
1107
+ * String component references are returned as-is (context injected during mount).
1108
+ * Objects are wrapped with router context and their children are recursively wrapped.
1109
+ *
1110
+ * @private
1111
+ * @param {ComponentDefinition | string} component - The component to wrap (can be a definition object or a registered component name).
1112
+ * @returns {ComponentDefinition | string} The wrapped component definition or the original string reference.
1113
+ * @see _wrapComponent - Single component wrapping.
1114
+ */
1115
+ private _wrapComponentWithChildren;
1116
+ /**
1117
+ * Gets the current location information from the browser's window object.
1118
+ * @private
1119
+ * @returns {Omit<RouteLocation, 'params' | 'meta' | 'name' | 'matched'>}
1120
+ */
1121
+ private _getCurrentLocation;
1122
+ /**
1123
+ * Parses a query string into a key-value object.
1124
+ * Uses URLSearchParams for robust parsing of encoded values.
1125
+ *
1126
+ * @private
1127
+ * @param {string} queryString - The query string to parse (without leading '?').
1128
+ * @returns {QueryParams} Key-value pairs from the query string.
1129
+ *
1130
+ * @example
1131
+ * this._parseQuery('foo=bar&baz=qux');
1132
+ * // Returns: { foo: 'bar', baz: 'qux' }
1133
+ */
1134
+ private _parseQuery;
1135
+ /**
1136
+ * Matches a given path against the registered routes.
1137
+ * @private
1138
+ * @param {string} path - The path to match.
1139
+ * @returns {{route: RouteDefinition, params: Object<string, string>} | null} The matched route and its params, or null.
1140
+ */
1141
+ private _matchRoute;
1142
+ /**
1143
+ * Adds a new route dynamically at runtime.
1144
+ * The route will be processed and available for navigation immediately.
1145
+ * Routes are inserted before the wildcard (*) route if one exists.
1146
+ *
1147
+ * @param {RouteDefinition} route - The route definition to add.
1148
+ * @param {RouteDefinition} [parentRoute] - Optional parent route to add as a child (not yet implemented).
1149
+ * @returns {() => void} A function to remove the added route (returns no-op if route was invalid).
1150
+ * @emits router:routeAdded When a route is successfully added.
1151
+ *
1152
+ * @example
1153
+ * // Add a route dynamically
1154
+ * const removeRoute = router.addRoute({
1155
+ * path: '/dynamic',
1156
+ * component: DynamicPage,
1157
+ * meta: { title: 'Dynamic Page' }
1158
+ * });
1159
+ *
1160
+ * // Later, remove the route
1161
+ * removeRoute();
1162
+ */
1163
+ addRoute(route: RouteDefinition, parentRoute?: RouteDefinition): () => void;
1164
+ /**
1165
+ * Removes a route by its path.
1166
+ *
1167
+ * @param {string} path - The path of the route to remove.
1168
+ * @returns {boolean} True if the route was removed, false if not found.
1169
+ * @emits router:routeRemoved When a route is successfully removed.
1170
+ *
1171
+ * @example
1172
+ * router.removeRoute('/dynamic');
1173
+ */
1174
+ removeRoute(path: string): boolean;
1175
+ /**
1176
+ * Checks if a route with the given path exists.
1177
+ *
1178
+ * @param {string} path - The path to check.
1179
+ * @returns {boolean} True if the route exists.
1180
+ *
1181
+ * @example
1182
+ * if (router.hasRoute('/users/:id')) {
1183
+ * console.log('User route exists');
1184
+ * }
1185
+ */
1186
+ hasRoute(path: string): boolean;
1187
+ /**
1188
+ * Gets all registered routes.
1189
+ *
1190
+ * @returns {RouteDefinition[]} A copy of the routes array.
1191
+ *
1192
+ * @example
1193
+ * const routes = router.getRoutes();
1194
+ * console.log('Available routes:', routes.map(r => r.path));
1195
+ */
1196
+ getRoutes(): RouteDefinition[];
1197
+ /**
1198
+ * Gets a route by its path.
1199
+ *
1200
+ * @param {string} path - The path of the route to get.
1201
+ * @returns {RouteDefinition | undefined} The route definition or undefined.
1202
+ *
1203
+ * @example
1204
+ * const route = router.getRoute('/users/:id');
1205
+ * if (route) {
1206
+ * console.log('Route meta:', route.meta);
1207
+ * }
1208
+ */
1209
+ getRoute(path: string): RouteDefinition | undefined;
1210
+ /**
1211
+ * Registers a global pre-navigation guard.
1212
+ * Multiple guards can be registered and will be executed in order.
1213
+ * Guards can also be registered via the emitter using `router:beforeEach` event.
1214
+ *
1215
+ * @param {NavigationGuard} guard - The guard function to register.
1216
+ * @returns {() => void} A function to unregister the guard.
1217
+ *
1218
+ * @example
1219
+ * // Register a guard
1220
+ * const unregister = router.onBeforeEach((to, from) => {
1221
+ * if (to.meta.requiresAuth && !isAuthenticated()) {
1222
+ * return '/login';
1223
+ * }
1224
+ * });
1225
+ *
1226
+ * // Later, unregister the guard
1227
+ * unregister();
1228
+ */
1229
+ onBeforeEach(guard: NavigationGuard): () => void;
1230
+ /**
1231
+ * Registers a global hook that runs after a new route component has been mounted.
1232
+ * @param {NavigationHook} hook - The hook function to register.
1233
+ * @returns {() => void} A function to unregister the hook.
1234
+ * @listens router:afterEnter
1235
+ */
1236
+ onAfterEnter(hook: NavigationHook): () => void;
1237
+ /**
1238
+ * Registers a global hook that runs after a route component has been unmounted.
1239
+ * @param {NavigationHook} hook - The hook function to register.
1240
+ * @returns {() => void} A function to unregister the hook.
1241
+ * @listens router:afterLeave
1242
+ */
1243
+ onAfterLeave(hook: NavigationHook): () => void;
1244
+ /**
1245
+ * Registers a global hook that runs after a navigation has been confirmed and all hooks have completed.
1246
+ * @param {NavigationHook} hook - The hook function to register.
1247
+ * @returns {() => void} A function to unregister the hook.
1248
+ * @listens router:afterEach
1249
+ */
1250
+ onAfterEach(hook: NavigationHook): () => void;
1251
+ /**
1252
+ * Registers a global error handler for navigation errors.
1253
+ * @param {(error: Error, to?: RouteLocation, from?: RouteLocation) => void} handler - The error handler function.
1254
+ * @returns {() => void} A function to unregister the handler.
1255
+ * @listens router:error
1256
+ */
1257
+ onError(handler: (error: Error, to?: RouteLocation, from?: RouteLocation) => void): () => void;
1258
+ /**
1259
+ * Registers a plugin with the router.
1260
+ * Logs a warning if the plugin is already registered.
1261
+ *
1262
+ * @param {RouterPlugin} plugin - The plugin to register (must have install method).
1263
+ * @param {Record<string, unknown>} [options={}] - Options to pass to plugin.install().
1264
+ * @returns {void}
1265
+ * @throws {Error} If plugin does not have an install method.
1266
+ */
1267
+ use(plugin: RouterPlugin, options?: Record<string, unknown>): void;
1268
+ /**
1269
+ * Gets all registered plugins.
1270
+ * @returns {RouterPlugin[]} Array of registered plugins.
1271
+ */
1272
+ getPlugins(): RouterPlugin[];
1273
+ /**
1274
+ * Gets a plugin by name.
1275
+ * @param {string} name - The plugin name.
1276
+ * @returns {RouterPlugin | undefined} The plugin or undefined.
1277
+ */
1278
+ getPlugin(name: string): RouterPlugin | undefined;
1279
+ /**
1280
+ * Removes a plugin from the router.
1281
+ * @param {string} name - The plugin name.
1282
+ * @returns {boolean} True if the plugin was removed.
1283
+ */
1284
+ removePlugin(name: string): boolean;
1285
+ /**
1286
+ * Sets a custom error handler. Used by error handling plugins.
1287
+ * Logs a warning if the provided handler is invalid (missing required methods).
1288
+ * @param {RouterErrorHandler} errorHandler - The error handler object with handle, warn, and log methods.
1289
+ * @returns {void}
1290
+ */
1291
+ setErrorHandler(errorHandler: RouterErrorHandler): void;
1292
+ }
1293
+
1294
+ export { RouterPlugin as Router, RouterPlugin };
1295
+ export type { ComponentDefinition, Eleva, Emitter, MountResult, NavigateFunction, NavigationContext, NavigationContextCallback, NavigationGuard, NavigationGuardResult, NavigationHook, NavigationParams, NavigationTarget, QueryParams, RenderContext, RenderContextCallback, ResolveContext, ResolveContextCallback, RouteAddedCallback, RouteChangeCallback, RouteComponent, RouteDefinition, RouteLocation, RouteMatch, RouteMeta, RouteParams, RouteRemovedCallback, RouteSegment, RouterContext, RouterErrorCallback, RouterErrorHandler, RouterMode, RouterOptions, RouterReadyCallback, ScrollContext, ScrollContextCallback, ScrollPosition, Signal, UnsubscribeFunction };
1296
+ //# sourceMappingURL=router.d.ts.map