@real-router/types 0.1.0 → 0.3.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.
@@ -295,61 +295,12 @@ interface Params {
295
295
  }
296
296
 
297
297
  /**
298
- * Plugin lifecycle method names
299
- */
300
- type PluginMethod = "onStart" | "onStop" | "onTransitionStart" | "onTransitionCancel" | "onTransitionSuccess" | "onTransitionError";
301
- /**
302
- * Router event names
303
- */
304
- type EventName = "$start" | "$stop" | "$$start" | "$$cancel" | "$$success" | "$$error";
305
- /**
306
- * Event type keys
307
- */
308
- type EventsKeys = "ROUTER_START" | "ROUTER_STOP" | "TRANSITION_START" | "TRANSITION_CANCEL" | "TRANSITION_SUCCESS" | "TRANSITION_ERROR";
309
- /**
310
- * Error code values
311
- */
312
- type ErrorCodeValues = "NOT_STARTED" | "NO_START_PATH_OR_STATE" | "ALREADY_STARTED" | "ROUTE_NOT_FOUND" | "SAME_STATES" | "CANNOT_DEACTIVATE" | "CANNOT_ACTIVATE" | "TRANSITION_ERR" | "CANCELLED";
313
- /**
314
- * Error code keys
315
- */
316
- type ErrorCodeKeys = "ROUTER_NOT_STARTED" | "NO_START_PATH_OR_STATE" | "ROUTER_ALREADY_STARTED" | "ROUTE_NOT_FOUND" | "SAME_STATES" | "CANNOT_DEACTIVATE" | "CANNOT_ACTIVATE" | "TRANSITION_ERR" | "TRANSITION_CANCELLED";
317
- /**
318
- * Mapping of event keys to plugin methods
319
- */
320
- interface EventToPluginMap {
321
- readonly ROUTER_START: "onStart";
322
- readonly ROUTER_STOP: "onStop";
323
- readonly TRANSITION_START: "onTransitionStart";
324
- readonly TRANSITION_CANCEL: "onTransitionCancel";
325
- readonly TRANSITION_SUCCESS: "onTransitionSuccess";
326
- readonly TRANSITION_ERROR: "onTransitionError";
327
- }
328
- /**
329
- * Mapping of event keys to event names
330
- */
331
- interface EventToNameMap {
332
- ROUTER_START: "$start";
333
- ROUTER_STOP: "$stop";
334
- TRANSITION_START: "$$start";
335
- TRANSITION_CANCEL: "$$cancel";
336
- TRANSITION_SUCCESS: "$$success";
337
- TRANSITION_ERROR: "$$error";
338
- }
339
- /**
340
- * Mapping of error code keys to their values
298
+ * Base router types without Router class dependency.
299
+ *
300
+ * Router-dependent types (Route, RouteConfigUpdate, ActivationFnFactory,
301
+ * MiddlewareFactory, PluginFactory) are defined in @real-router/core
302
+ * to avoid circular dependencies.
341
303
  */
342
- interface ErrorCodeToValueMap {
343
- ROUTER_NOT_STARTED: "NOT_STARTED";
344
- NO_START_PATH_OR_STATE: "NO_START_PATH_OR_STATE";
345
- ROUTER_ALREADY_STARTED: "ALREADY_STARTED";
346
- ROUTE_NOT_FOUND: "ROUTE_NOT_FOUND";
347
- SAME_STATES: "SAME_STATES";
348
- CANNOT_DEACTIVATE: "CANNOT_DEACTIVATE";
349
- CANNOT_ACTIVATE: "CANNOT_ACTIVATE";
350
- TRANSITION_ERR: "TRANSITION_ERR";
351
- TRANSITION_CANCELLED: "CANCELLED";
352
- }
353
304
 
354
305
  type LogLevel = "log" | "warn" | "error";
355
306
  type LogLevelConfig = "all" | "warn-error" | "error-only" | "none";
@@ -359,82 +310,6 @@ interface LoggerConfig {
359
310
  callback?: LogCallback | undefined;
360
311
  callbackIgnoresLevel?: boolean;
361
312
  }
362
- /**
363
- * Extended build result that includes segments for path building.
364
- * Used internally to avoid duplicate getSegmentsByName calls.
365
- *
366
- * @param segments - Route segments from getSegmentsByName (typed as unknown[] for cross-package compatibility)
367
- * @internal
368
- */
369
- interface BuildStateResultWithSegments<P extends Params = Params> {
370
- readonly state: RouteTreeState<P>;
371
- readonly segments: readonly unknown[];
372
- }
373
- /**
374
- * Route configuration.
375
- */
376
- interface Route<Dependencies extends DefaultDependencies = DefaultDependencies> {
377
- [key: string]: unknown;
378
- /** Route name (dot-separated for nested routes). */
379
- name: string;
380
- /** URL path pattern for this route. */
381
- path: string;
382
- /** Factory function that returns a guard for route activation. */
383
- canActivate?: ActivationFnFactory<Dependencies>;
384
- /**
385
- * Redirects navigation to another route.
386
- *
387
- * IMPORTANT: forwardTo creates a URL alias, not a transition chain.
388
- * Guards (canActivate) on the source route are NOT executed.
389
- * Only guards on the final destination are executed.
390
- *
391
- * This matches Vue Router and Angular Router behavior.
392
- *
393
- * @example
394
- * // Correct: guard on target
395
- * { name: "old", path: "/old", forwardTo: "new" }
396
- * { name: "new", path: "/new", canActivate: myGuard }
397
- *
398
- * // Wrong: guard on source (will be ignored with warning)
399
- * { name: "old", path: "/old", forwardTo: "new", canActivate: myGuard }
400
- */
401
- forwardTo?: string;
402
- /** Nested child routes. */
403
- children?: Route<Dependencies>[];
404
- /** Encodes state params to URL params. */
405
- encodeParams?: (stateParams: Params) => Params;
406
- /** Decodes URL params to state params. */
407
- decodeParams?: (pathParams: Params) => Params;
408
- /**
409
- * Default parameters for this route.
410
- *
411
- * @remarks
412
- * **Type Contract:**
413
- * The type of defaultParams MUST match the expected params type P
414
- * when using `router.makeState<P>()` or `router.navigate<P>()`.
415
- *
416
- * These values are merged into state.params when creating route states.
417
- * Missing URL params are filled from defaultParams.
418
- *
419
- * @example
420
- * ```typescript
421
- * // Define route with pagination defaults
422
- * {
423
- * name: "users",
424
- * path: "/users",
425
- * defaultParams: { page: 1, limit: 10 }
426
- * }
427
- *
428
- * // Navigate without specifying page/limit
429
- * router.navigate("users", { filter: "active" });
430
- * // Result: state.params = { page: 1, limit: 10, filter: "active" }
431
- *
432
- * // Correct typing — include defaultParams properties
433
- * type UsersParams = { page: number; limit: number; filter?: string };
434
- * ```
435
- */
436
- defaultParams?: Params;
437
- }
438
313
  /**
439
314
  * Router configuration options.
440
315
  *
@@ -512,9 +387,15 @@ interface Options {
512
387
  * @default undefined
513
388
  */
514
389
  logger?: Partial<LoggerConfig>;
390
+ /**
391
+ * Disables argument validation in public router methods.
392
+ * Use in production for performance. Keep false in development for early error detection.
393
+ *
394
+ * @default false
395
+ */
396
+ noValidate?: boolean;
515
397
  }
516
398
  type ActivationFn = (toState: State, fromState: State | undefined, done: DoneFn) => boolean | Promise<boolean | object | void> | State | void;
517
- type ActivationFnFactory<Dependencies extends DefaultDependencies = DefaultDependencies> = (router: Router<Dependencies>, getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K]) => ActivationFn;
518
399
  type DefaultDependencies = object;
519
400
  interface Config {
520
401
  decoders: Record<string, (params: Params) => Params>;
@@ -522,944 +403,6 @@ interface Config {
522
403
  defaultParams: Record<string, Params>;
523
404
  forwardMap: Record<string, string>;
524
405
  }
525
- /**
526
- * Configuration update options for updateRoute().
527
- * All properties are optional. Set to null to remove the configuration.
528
- */
529
- interface RouteConfigUpdate<Dependencies extends DefaultDependencies = DefaultDependencies> {
530
- /** Set to null to remove forwardTo */
531
- forwardTo?: string | null;
532
- /** Set to null to remove defaultParams */
533
- defaultParams?: Params | null;
534
- /** Set to null to remove decoder */
535
- decodeParams?: ((params: Params) => Params) | null;
536
- /** Set to null to remove encoder */
537
- encodeParams?: ((params: Params) => Params) | null;
538
- /** Set to null to remove canActivate */
539
- canActivate?: ActivationFnFactory<Dependencies> | null;
540
- }
541
- interface Router<Dependencies extends DefaultDependencies = DefaultDependencies> {
542
- [key: symbol]: unknown;
543
- [key: string]: unknown;
544
- addRoute: (routes: Route<Dependencies>[] | Route<Dependencies>) => Router<Dependencies>;
545
- isActiveRoute: (name: string, params?: Params, strictEquality?: boolean, ignoreQueryParams?: boolean) => boolean;
546
- buildPath: (route: string, params?: Params) => string;
547
- /**
548
- * Internal path builder that accepts pre-computed segments.
549
- * Avoids duplicate getSegmentsByName call when segments are already available.
550
- *
551
- * @param segments - Route segments from getSegmentsByName (typed as unknown[] for cross-package compatibility)
552
- * @internal
553
- */
554
- buildPathWithSegments: (route: string, params: Params, segments: readonly unknown[]) => string;
555
- matchPath: <P extends Params = Params, MP extends Params = Params>(path: string, source?: string) => State<P, MP> | undefined;
556
- /**
557
- * Sets the root path for the router.
558
- *
559
- * @param rootPath - New root path
560
- * @returns void
561
- */
562
- setRootPath: (rootPath: string) => void;
563
- /**
564
- * Gets the current root path for the router.
565
- *
566
- * @returns Current root path
567
- */
568
- getRootPath: () => string;
569
- /**
570
- * Removes route configurations (metadata only).
571
- *
572
- * @description
573
- * Clears associated configurations for a route (decoders, encoders, defaultParams,
574
- * forwardMap). Note: RouteNode doesn't provide API for actual route removal from tree.
575
- * Consider recreating the router with filtered routes for full removal.
576
- *
577
- * @param name - Route name to remove configurations for
578
- * @returns Router instance for chaining
579
- * @throws {TypeError} If name is not a valid route name
580
- */
581
- removeRoute: (name: string) => Router<Dependencies>;
582
- /**
583
- * Clears all routes from the router.
584
- *
585
- * @description
586
- * Removes all route definitions, configurations, and lifecycle handlers.
587
- * Preserves: listeners, plugins, dependencies, options, state.
588
- * After clearing, you can add new routes with addRoute().
589
- *
590
- * @returns Router instance for chaining
591
- *
592
- * @example
593
- * // Clear all routes and add new ones
594
- * router.clearRoutes().addRoute([
595
- * { name: 'home', path: '/' },
596
- * { name: 'about', path: '/about' }
597
- * ]);
598
- */
599
- clearRoutes: () => Router<Dependencies>;
600
- /**
601
- * Retrieves the full configuration of a route by name.
602
- *
603
- * @description
604
- * Reconstructs the Route object from internal storage, including:
605
- * - name, path, children from route definitions
606
- * - forwardTo from forwardMap
607
- * - defaultParams, decodeParams, encodeParams from config
608
- * - canActivate from lifecycle factories
609
- *
610
- * Note: Custom properties (meta, etc.) are NOT preserved and won't be returned.
611
- *
612
- * @param name - Route name (dot-notation for nested routes, e.g., 'users.profile')
613
- * @returns Route configuration or undefined if not found
614
- *
615
- * @throws {TypeError} If name is not a valid route name
616
- *
617
- * @example
618
- * const route = router.getRoute('users.profile');
619
- * if (route) {
620
- * console.log(route.path, route.defaultParams);
621
- * }
622
- */
623
- getRoute: (name: string) => Route<Dependencies> | undefined;
624
- /**
625
- * Checks if a route exists in the router.
626
- *
627
- * @description
628
- * Lightweight check for route existence without constructing the full Route object.
629
- * More efficient than `!!router.getRoute(name)` when you only need to check existence.
630
- *
631
- * @param name - Route name to check (supports dot notation for nested routes)
632
- * @returns true if route exists, false otherwise
633
- *
634
- * @throws {TypeError} If name is not a valid route name
635
- *
636
- * @example
637
- * if (router.hasRoute('users.profile')) {
638
- * router.navigate('users.profile', { id: 123 });
639
- * }
640
- */
641
- hasRoute: (name: string) => boolean;
642
- /**
643
- * Updates configuration properties of an existing route.
644
- *
645
- * @description
646
- * Only updates configuration (forwardTo, defaultParams, encoders, decoders, canActivate).
647
- * Does NOT update path or children (requires tree rebuild - use removeRoute + addRoute).
648
- *
649
- * Set a property to null to remove it. For example:
650
- * - `{ forwardTo: null }` removes the forwardTo redirect
651
- * - `{ canActivate: null }` removes the canActivate guard
652
- *
653
- * @param name - Route name to update
654
- * @param updates - Partial route configuration to apply
655
- * @returns Router instance for chaining
656
- *
657
- * @throws {TypeError} If name is not a valid route name
658
- * @throws {ReferenceError} If route does not exist
659
- * @throws {Error} If updating forwardTo with invalid target or cycle
660
- *
661
- * @example
662
- * // Add/update configuration
663
- * router.updateRoute('users', {
664
- * defaultParams: { page: 1 },
665
- * canActivate: authGuard
666
- * });
667
- *
668
- * @example
669
- * // Remove configuration
670
- * router.updateRoute('oldRoute', { forwardTo: null });
671
- */
672
- updateRoute: (name: string, updates: RouteConfigUpdate<Dependencies>) => Router<Dependencies>;
673
- /**
674
- * Returns a copy of the previous state before the last navigation.
675
- *
676
- * @returns Copy of the previous state or undefined if no previous state exists
677
- */
678
- getPreviousState: () => State | undefined;
679
- shouldUpdateNode: (nodeName: string) => (toState: State, fromState?: State) => boolean;
680
- /**
681
- * Returns a copy of the router's current configuration options.
682
- *
683
- * @description
684
- * Provides read-only access to the router's configuration by returning a shallow
685
- * copy of all current options. This method is useful for inspecting settings,
686
- * debugging, passing configuration to other components, or conditional logic
687
- * based on router configuration.
688
- *
689
- * @returns A shallow copy of the current router options. Each call returns
690
- * a new object with all configuration properties.
691
- *
692
- * @example
693
- * // Basic usage - inspect configuration
694
- * const options = router.getOptions();
695
- * console.log('Case sensitive:', options.caseSensitive);
696
- * console.log('Trailing slash mode:', options.trailingSlash);
697
- *
698
- * @see {@link setOption} for modifying individual options
699
- */
700
- getOptions: () => Options;
701
- /**
702
- * Sets a single configuration option value.
703
- *
704
- * @description
705
- * Modifies an individual router configuration option with type-safe validation.
706
- * This method can ONLY be used before calling router.start() - after the router
707
- * starts, all options become immutable and any attempt to modify them will throw
708
- * an error.
709
- *
710
- * @param option - The name of the option to set. Must be a valid option key.
711
- * @param value - The new value for the option. Type must match the option's expected type.
712
- *
713
- * @returns The router instance for method chaining.
714
- *
715
- * @throws {Error} If router is already started (router.isStarted() === true)
716
- * @throws {ReferenceError} If option name doesn't exist in Options interface
717
- * @throws {TypeError} If value type doesn't match expected type for the option
718
- * @throws {TypeError} If object option receives non-plain object (array, date, class, null)
719
- *
720
- * @see {@link getOptions} for retrieving current options
721
- */
722
- setOption: (option: keyof Options, value: Options[keyof Options]) => Router<Dependencies>;
723
- makeState: <P extends Params = Params, MP extends Params = Params>(name: string, params?: P, path?: string, meta?: StateMetaInput<MP>, forceId?: number) => State<P, MP>;
724
- makeNotFoundState: (path: string, options?: NavigationOptions) => State;
725
- getState: <P extends Params = Params, MP extends Params = Params>() => State<P, MP> | undefined;
726
- setState: <P extends Params = Params, MP extends Params = Params>(state?: State<P, MP>) => void;
727
- areStatesEqual: (state1: State | undefined, state2: State | undefined, ignoreQueryParams?: boolean) => boolean;
728
- areStatesDescendants: (parentState: State, childState: State) => boolean;
729
- forwardState: <P extends Params = Params>(routeName: string, routeParams: P) => SimpleState<P>;
730
- buildState: (routeName: string, routeParams: Params) => RouteTreeState | undefined;
731
- /**
732
- * Builds state with segments for internal use.
733
- * Avoids duplicate getSegmentsByName call when path building is needed.
734
- *
735
- * @internal
736
- */
737
- buildStateWithSegments: <P extends Params = Params>(routeName: string, routeParams: P) => BuildStateResultWithSegments<P> | undefined;
738
- /**
739
- * Checks whether the router has been successfully started.
740
- *
741
- * @description
742
- * Returns true if the router has been started via the `start()` method and has not
743
- * been stopped. When the router is started, it means:
744
- * - Initial navigation has been attempted
745
- * - Event listeners can receive navigation events
746
- * - The router is ready to handle navigation requests
747
- *
748
- * Note: A router being "started" doesn't guarantee that the initial navigation
749
- * succeeded. Use `getState()` to verify if a valid state exists.
750
- *
751
- * @returns true if the router is started, false otherwise
752
- *
753
- * @example
754
- * // Check if router is started before navigation
755
- * if (!router.isStarted()) {
756
- * router.start('/home');
757
- * }
758
- *
759
- * @example
760
- * // Conditional logic based on router state
761
- * const isReady = router.isStarted() && router.getState() !== undefined;
762
- */
763
- isStarted: () => boolean;
764
- /**
765
- * Checks if the router is active (starting or started).
766
- *
767
- * @description
768
- * Returns true if the router is in the process of starting or has already started.
769
- * This is different from `isStarted()` which only returns true after successful
770
- * initial transition.
771
- *
772
- * This method is primarily used internally by the transition module to determine
773
- * if transitions should be cancelled. During the initial start transition,
774
- * `isStarted()` is false but `isActive()` is true, allowing the transition to proceed.
775
- *
776
- * @returns true if router is active (starting or started), false if stopped
777
- *
778
- * @example
779
- * // Check if router is active (even during initial start)
780
- * if (router.isActive()) {
781
- * console.log('Router is active');
782
- * }
783
- *
784
- * @see {@link isStarted} to check if initial transition completed
785
- * @see https://github.com/greydragon888/real-router/issues/50
786
- */
787
- isActive: () => boolean;
788
- /**
789
- * Checks if a navigation transition is currently in progress.
790
- *
791
- * @description
792
- * Returns true when the router is actively processing a navigation request.
793
- * This includes the time spent executing guards (canDeactivate, canActivate)
794
- * and middleware functions.
795
- *
796
- * Useful for:
797
- * - Preventing route modifications during navigation
798
- * - Showing loading indicators
799
- * - Debouncing navigation requests
800
- *
801
- * @returns true if navigation is in progress, false otherwise
802
- *
803
- * @example
804
- * // Prevent route removal during navigation
805
- * if (router.isNavigating()) {
806
- * console.warn('Cannot modify routes during navigation');
807
- * return;
808
- * }
809
- *
810
- * @example
811
- * // Show loading state
812
- * const isLoading = router.isNavigating();
813
- *
814
- * @remarks
815
- * After FSM migration (RFC-2), this will use RouterState.TRANSITIONING
816
- * for more granular state tracking.
817
- */
818
- isNavigating: () => boolean;
819
- /**
820
- * Initializes the router and performs the initial navigation.
821
- *
822
- * @description
823
- * Starts the router and navigates to the initial route. This method must be called
824
- * before any navigation operations. The initial route can be specified as a path
825
- * string, a state object, or determined by the default route option.
826
- *
827
- * @param startPathOrState - Optional. The initial route as a path string or state object.
828
- * If omitted, uses the default route if configured.
829
- * @param done - Optional. Callback function called when start completes or fails.
830
- *
831
- * @returns The router instance for method chaining
832
- *
833
- * @example
834
- * router.start()
835
- *
836
- * @example
837
- * router.start('/users/123', (err, state) => {
838
- * if (!err) console.log('Started at:', state.name)
839
- * })
840
- */
841
- start: (() => Router<Dependencies>) & ((done: DoneFn) => Router<Dependencies>) & ((startPathOrState: string | State) => Router<Dependencies>) & ((startPathOrState: string | State, done: DoneFn) => Router<Dependencies>);
842
- /**
843
- * Stops the router and cleans up its state.
844
- *
845
- * @description
846
- * Stops the router, clearing the current state and preventing further navigation.
847
- * This method should be called when the router is no longer needed, typically
848
- * during application cleanup or before unmounting.
849
- *
850
- * If the router is not started, this method does nothing and returns silently.
851
- *
852
- * @returns The router instance for method chaining
853
- *
854
- * @example
855
- * // Stop the router
856
- * router.stop();
857
- *
858
- * @fires ROUTER_STOP - When the router is successfully stopped
859
- *
860
- * @see {@link start} to restart the router
861
- * @see {@link isStarted} to check router status
862
- */
863
- stop: () => Router<Dependencies>;
864
- canDeactivate: (name: string, canDeactivateHandler: ActivationFnFactory<Dependencies> | boolean) => Router<Dependencies>;
865
- clearCanDeactivate: (name: string, silent?: boolean) => Router<Dependencies>;
866
- canActivate: (name: string, canActivateHandler: ActivationFnFactory<Dependencies> | boolean) => Router<Dependencies>;
867
- clearCanActivate: (name: string, silent?: boolean) => Router<Dependencies>;
868
- getLifecycleFactories: () => [
869
- Record<string, ActivationFnFactory<Dependencies>>,
870
- Record<string, ActivationFnFactory<Dependencies>>
871
- ];
872
- getLifecycleFunctions: () => [
873
- Map<string, ActivationFn>,
874
- Map<string, ActivationFn>
875
- ];
876
- /**
877
- * Registers plugin(s) to extend router functionality through lifecycle event subscriptions.
878
- *
879
- * @description
880
- * Provides the primary mechanism for adding cross-cutting functionality to the router
881
- * through a plugin-based architecture. Plugins can react to router lifecycle events
882
- * (start/stop, navigation transitions) without modifying the core router code.
883
- *
884
- * @param plugins - Variable number of plugin factory functions.
885
- * Each factory receives (router, getDependency) and must return
886
- * a Plugin object with optional event handler methods.
887
- *
888
- * @returns Unsubscribe function that removes only the plugins registered in this call.
889
- * Calls teardown() for each plugin and removes all event subscriptions.
890
- * Safe to call multiple times (subsequent calls are no-op with error logging).
891
- *
892
- * @throws {TypeError} If any plugin parameter is not a function
893
- * @throws {TypeError} If any factory returns a non-object value
894
- * @throws {TypeError} If returned plugin object contains unknown properties
895
- * @throws {Error} If any plugin factory is already registered (duplicate by reference)
896
- * @throws {Error} If total plugin count would exceed 50 after registration
897
- * @throws {*} Rethrows any exception thrown by factory functions (after rollback)
898
- *
899
- * @example
900
- * // Basic logging plugin
901
- * const loggingPlugin = (router) => ({
902
- * onTransitionStart: (toState, fromState) => {
903
- * console.log(`Navigating: ${fromState?.name} → ${toState.name}`);
904
- * },
905
- * onTransitionSuccess: (toState) => {
906
- * console.log(`Arrived at: ${toState.name}`);
907
- * },
908
- * });
909
- *
910
- * @example
911
- * // Remove plugin
912
- * const remove = router.usePlugin(loggerPlugin)
913
- * remove() // Stop logging
914
- *
915
- * const unsubscribe = router.usePlugin(loggingPlugin);
916
- *
917
- * @see {@link getPlugins} for retrieving registered plugin factories (internal use)
918
- * @see {@link useMiddleware} for navigation-specific middleware (different from plugins)
919
- * @see {@link addEventListener} for low-level event subscription
920
- */
921
- usePlugin: (...plugins: PluginFactory<Dependencies>[]) => Unsubscribe;
922
- getPlugins: () => PluginFactory<Dependencies>[];
923
- /**
924
- * Registers middleware functions to execute during navigation transitions.
925
- *
926
- * @description
927
- * Provides the primary mechanism for adding custom logic to the navigation pipeline
928
- * through middleware functions. Middleware execute after lifecycle hooks (canActivate/
929
- * canDeactivate) and can modify or validate state during route transitions.
930
- *
931
- * @param middlewares - Variable number of middleware factory functions.
932
- * Each factory receives (router, getDependency) and must return
933
- * a middleware function with signature:
934
- * (toState, fromState, done) => void | Promise<State | boolean | void>
935
- *
936
- * @returns Unsubscribe function that removes only the middleware registered in this call.
937
- * Safe to call multiple times (subsequent calls are no-op with warnings).
938
- *
939
- * @throws {TypeError} If any middleware parameter is not a function
940
- * @throws {TypeError} If any factory returns a non-function value
941
- * @throws {Error} If any middleware factory is already registered (duplicate)
942
- * @throws {Error} If total middleware count would exceed 50 after registration
943
- * @throws {*} Rethrows any exception thrown by factory functions during initialization
944
- *
945
- * @example
946
- *
947
- * router.useMiddleware((router) => (toState, fromState, done) => {
948
- * console.log('Navigating to:', toState.name)
949
- * done()
950
- * })
951
- *
952
- * @example
953
- * // Auth middleware
954
- * router.useMiddleware(() => (toState, fromState, done) => {
955
- * if (toState.meta.requiresAuth && !isAuthenticated()) {
956
- * done({ redirect: { name: 'login' } })
957
- * } else {
958
- * done()
959
- * }
960
- * })
961
- */
962
- useMiddleware: (...middlewares: MiddlewareFactory<Dependencies>[]) => Unsubscribe;
963
- clearMiddleware: () => Router<Dependencies>;
964
- getMiddlewareFactories: () => MiddlewareFactory<Dependencies>[];
965
- getMiddlewareFunctions: () => Middleware[];
966
- setDependency: <K extends keyof Dependencies & string>(dependencyName: K, dependency: Dependencies[K]) => Router<Dependencies>;
967
- /**
968
- * Sets multiple dependencies at once using a batch operation.
969
- *
970
- * @description
971
- * Provides an optimized way to register multiple dependencies in a single operation.
972
- * This method is the primary approach for initializing dependencies during router
973
- * setup and for bulk updates of the dependency container.
974
- *
975
- * @param deps - Object containing dependencies to set. Must be a plain object.
976
- * Properties with undefined values are ignored (not set).
977
- * All other values (including null, false, 0) are set.
978
- *
979
- * @returns The router instance for method chaining.
980
- *
981
- * @throws {TypeError} If deps is not a plain object (e.g., class instance, array, null)
982
- * @throws {TypeError} If any property in deps has a getter (accessor property)
983
- * @throws {Error} If total dependencies would exceed 100 after the operation
984
- *
985
- * @example
986
- * // Basic batch setup
987
- * router.setDependencies({
988
- * api: new ApiService(),
989
- * logger: console,
990
- * cache: cacheService,
991
- * });
992
- *
993
- * @see {@link setDependency} for setting individual dependencies
994
- * @see {@link getDependencies} for retrieving all dependencies
995
- * @see {@link resetDependencies} for clearing all dependencies
996
- * @see {@link removeDependency} for removing specific dependencies
997
- */
998
- setDependencies: (deps: Dependencies) => Router<Dependencies>;
999
- /**
1000
- * Retrieves a dependency from the router's dependency container by name.
1001
- *
1002
- * @description
1003
- * Provides type-safe access to dependencies registered in the router's dependency
1004
- * injection container. This method is the primary way to access services and utilities
1005
- * within middleware, plugins, and lifecycle hooks.
1006
- *
1007
- * @template K - The dependency name, must be a key of the Dependencies type
1008
- *
1009
- * @param key - The name of the dependency to retrieve. Must be a string and
1010
- * must exist in the Dependencies type definition.
1011
- *
1012
- * @returns The dependency value with proper type inference based on Dependencies type.
1013
- * Returns the same reference on repeated calls (not a copy).
1014
- *
1015
- * @throws {TypeError} If the key parameter is not a string type
1016
- * (e.g., number, object, null, undefined)
1017
- * @throws {ReferenceError} If no dependency exists with the given name.
1018
- * Error message includes the dependency name for debugging.
1019
- *
1020
- * @example
1021
- * // Basic usage - direct access
1022
- * interface MyDependencies {
1023
- * api: ApiService;
1024
- * logger: Logger;
1025
- * }
1026
- *
1027
- * router.setDependency('api', new ApiService());
1028
- * const api = router.getDependency('api'); // Type: ApiService
1029
- *
1030
- * @see {@link getDependencies} for retrieving all dependencies at once
1031
- * @see {@link setDependency} for registering dependencies
1032
- * @see {@link hasDependency} for checking dependency existence
1033
- * @see {@link removeDependency} for removing dependencies
1034
- */
1035
- getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K];
1036
- /**
1037
- * Returns a shallow copy of all registered dependencies.
1038
- *
1039
- * @description
1040
- * Retrieves a snapshot of all dependencies currently stored in the router's
1041
- * dependency container. The method creates a new object on each call, protecting
1042
- * the internal container structure from external modifications.
1043
- *
1044
- * @returns A new object containing all dependencies as key-value pairs.
1045
- * Returns {} if no dependencies are registered.
1046
- *
1047
- * @example
1048
- * // Basic usage - get all dependencies
1049
- * const deps = router.getDependencies();
1050
- * console.log(deps); // { api: ApiService, logger: Logger }
1051
- *
1052
- * @see {@link getDependency} for accessing individual dependencies
1053
- * @see {@link setDependency} for adding dependencies
1054
- * @see {@link setDependencies} for batch setting
1055
- * @see {@link removeDependency} for removing dependencies
1056
- * @see {@link resetDependencies} for clearing all dependencies
1057
- * @see {@link hasDependency} for checking dependency existence
1058
- */
1059
- getDependencies: () => Partial<Dependencies>;
1060
- /**
1061
- * Removes a dependency from the router's dependency container.
1062
- *
1063
- * @description
1064
- * Safely removes a registered dependency by name. This method is idempotent,
1065
- * meaning it can be called multiple times with the same dependency name without
1066
- * causing errors. If the dependency doesn't exist, a warning is logged but
1067
- * execution continues normally.
1068
- *
1069
- * @param dependencyName - The name of the dependency to remove.
1070
- * Type-safe in TypeScript (must be a key of Dependencies).
1071
- * Safe to call with non-existent dependencies (logs warning).
1072
- *
1073
- * @returns The router instance for method chaining.
1074
- *
1075
- * @example
1076
- * // Basic removal
1077
- * router.setDependency('tempLogger', logger);
1078
- * router.removeDependency('tempLogger');
1079
- *
1080
- * console.log(router.hasDependency('tempLogger')); // false
1081
- *
1082
- * @see {@link setDependency} for adding dependencies
1083
- * @see {@link getDependency} for retrieving dependencies (throws after removal)
1084
- * @see {@link hasDependency} for checking dependency existence (returns false after removal)
1085
- * @see {@link resetDependencies} for removing all dependencies at once
1086
- */
1087
- removeDependency: (dependencyName: keyof Dependencies) => Router<Dependencies>;
1088
- /**
1089
- * Checks whether a dependency with the specified name exists in the router.
1090
- *
1091
- * @description
1092
- * Provides a safe way to check for dependency existence without throwing errors.
1093
- * This method is essential for implementing conditional logic based on optional
1094
- * dependencies and for validating dependency setup before accessing them.
1095
- *
1096
- * @param dependencyName - The name of the dependency to check.
1097
- * Type-safe in TypeScript (must be a key of Dependencies).
1098
- * In runtime, non-string primitives are coerced to strings.
1099
- *
1100
- * @returns true if the dependency exists (even with falsy values like null/false/0),
1101
- * false if the dependency has never been set or was removed.
1102
- *
1103
- * @example
1104
- * // Basic existence check
1105
- * router.setDependency('api', apiService);
1106
- * console.log(router.hasDependency('api')); // true
1107
- * console.log(router.hasDependency('nonexistent')); // false
1108
- *
1109
- * const ready = hasAllDependencies(router, ['api', 'auth', 'logger']);
1110
- *
1111
- * @see {@link getDependency} for retrieving dependencies (throws if not found)
1112
- * @see {@link getDependencies} for getting all dependencies at once
1113
- * @see {@link setDependency} for registering dependencies
1114
- * @see {@link removeDependency} for removing dependencies
1115
- */
1116
- hasDependency: (dependencyName: keyof Dependencies) => boolean;
1117
- /**
1118
- * Removes all dependencies from the router's dependency container.
1119
- *
1120
- * @description
1121
- * Performs a complete reset of the dependency container by removing all registered
1122
- * dependencies at once. This is a destructive operation that clears the entire
1123
- * dependency state, effectively returning the container to its initial empty state.
1124
- *
1125
- * @returns The router instance for method chaining.
1126
- *
1127
- * @example
1128
- * // Basic reset
1129
- * router.setDependency('logger', logger);
1130
- * router.setDependency('api', apiService);
1131
- * router.setDependency('cache', cacheService);
1132
- *
1133
- * router.resetDependencies();
1134
- *
1135
- * console.log(router.getDependencies()); // {}
1136
- * console.log(router.hasDependency('logger')); // false
1137
- *
1138
- * @see {@link setDependency} for adding individual dependencies
1139
- * @see {@link setDependencies} for setting multiple dependencies at once
1140
- * @see {@link removeDependency} for removing individual dependencies
1141
- * @see {@link getDependencies} for getting all current dependencies
1142
- * @see {@link hasDependency} for checking if specific dependency exists
1143
- */
1144
- resetDependencies: () => Router<Dependencies>;
1145
- /**
1146
- * Invokes all registered event listeners for a specific router lifecycle event.
1147
- *
1148
- * @internal
1149
- * This is an internal method used by the router core. It should NOT be called
1150
- * directly by application code. Events are automatically dispatched by router
1151
- * methods like start(), stop(), navigate(), etc.
1152
- *
1153
- * @description
1154
- * Synchronously invokes all registered event listeners for a given router lifecycle
1155
- * event in their registration order (FIFO). The method provides critical guarantees:
1156
- * fail-safe execution, state immutability, recursion protection, and iteration safety.
1157
- *
1158
- * @param eventName - The event type to invoke listeners for.
1159
- * Must be one of: ROUTER_START, ROUTER_STOP, TRANSITION_START,
1160
- * TRANSITION_SUCCESS, TRANSITION_ERROR, TRANSITION_CANCEL.
1161
- *
1162
- * @param toState - Target state for navigation events. Deep frozen before passing.
1163
- * Optional for ROUTER_START/STOP, required for TRANSITION_*.
1164
- *
1165
- * @param fromState - Source state for navigation events. Deep frozen before passing.
1166
- * Optional for all events (undefined for first navigation).
1167
- *
1168
- * @param arg - Additional event data:
1169
- * - NavigationOptions for TRANSITION_SUCCESS
1170
- * - RouterError for TRANSITION_ERROR
1171
- * - undefined for other events
1172
- *
1173
- * @returns void - Method performs side effects (invokes listeners)
1174
- *
1175
- * @throws {Error} If recursion depth exceeds MAX_DEPTH (5) for the event type
1176
- * @throws {TypeError} If state validation fails (invalid State object structure)
1177
- *
1178
- * @see {@link addEventListener} for subscribing to router events (public API)
1179
- * @see {@link removeEventListener} for unsubscribing from events (public API)
1180
- * @see {@link usePlugin} for plugin-based event handling (recommended)
1181
- */
1182
- invokeEventListeners: (eventName: EventToNameMap[EventsKeys], toState?: State, fromState?: State, arg?: RouterError | NavigationOptions) => void;
1183
- /**
1184
- * Checks if there are any listeners registered for a given event.
1185
- *
1186
- * @internal
1187
- * Used for performance optimization to skip event emission when no listeners exist.
1188
- * This avoids the overhead of argument validation and event dispatch when
1189
- * there are no subscribers.
1190
- *
1191
- * @param eventName - The event type to check for listeners. Must be one of the
1192
- * predefined event constants.
1193
- *
1194
- * @returns true if at least one listener is registered for the event, false otherwise.
1195
- * Returns false for invalid event names instead of throwing.
1196
- *
1197
- * @example
1198
- * ```typescript
1199
- * // Skip expensive event emission if no listeners
1200
- * if (router.hasListeners(events.TRANSITION_ERROR)) {
1201
- * router.invokeEventListeners(events.TRANSITION_ERROR, toState, fromState, error);
1202
- * }
1203
- * ```
1204
- *
1205
- * @see {@link invokeEventListeners} for the internal event dispatch mechanism
1206
- * @see {@link addEventListener} for registering event listeners
1207
- */
1208
- hasListeners: (eventName: EventToNameMap[EventsKeys]) => boolean;
1209
- /**
1210
- * Removes a previously registered event listener from the router's event system.
1211
- *
1212
- * @internal
1213
- * This is a low-level internal API used primarily by the router core and plugin system.
1214
- * For application code, use the unsubscribe function returned by addEventListener instead.
1215
- *
1216
- * @description
1217
- * Removes a specific event listener callback from the router's event system, preventing it
1218
- * from being invoked on future events. This method is a fundamental part of the subscription
1219
- * lifecycle, ensuring proper cleanup and preventing memory leaks.
1220
- *
1221
- * @param eventName - The event type to remove the listener from. Must be one of the
1222
- * predefined event constants (events.ROUTER_START, events.TRANSITION_SUCCESS, etc.).
1223
- * TypeScript enforces valid event names at compile time.
1224
- *
1225
- * @param cb - The callback function to remove. Must be the **exact same reference** that was
1226
- * passed to addEventListener. Using a different function (even with identical code)
1227
- * will not match and will log a warning.
1228
- *
1229
- * @returns void - No return value (follows DOM API convention). Use the unsubscribe function
1230
- * from addEventListener if you need guaranteed cleanup confirmation.
1231
- *
1232
- * @throws {Error} If eventName is not a valid event constant
1233
- * @throws {TypeError} If cb is not a function (null, undefined, string, etc.)
1234
- *
1235
- * @see {@link addEventListener} for registering event listeners (returns unsubscribe function)
1236
- * @see {@link usePlugin} for plugin-based event handling (handles cleanup automatically)
1237
- * @see {@link invokeEventListeners} for the internal event dispatch mechanism
1238
- */
1239
- removeEventListener: (eventName: EventToNameMap[EventsKeys], cb: Plugin[keyof Plugin]) => void;
1240
- /**
1241
- * Registers an event listener for a specific router lifecycle event.
1242
- *
1243
- * @description
1244
- * Provides type-safe subscription to router events with automatic memory leak protection
1245
- * and state immutability guarantees. This is the low-level API for event handling - for
1246
- * most use cases, consider using plugins (usePlugin) or the subscribe method instead.
1247
- *
1248
- * @param eventName - The event type to listen for. Must be one of the predefined
1249
- * event constants (events.ROUTER_START, events.TRANSITION_SUCCESS, etc.).
1250
- * TypeScript enforces valid event names at compile time.
1251
- *
1252
- * @param cb - The callback function to invoke when the event occurs. Signature must
1253
- * match the event type. TypeScript enforces correct callback signature.
1254
- * All State parameters will be deeply frozen before passing.
1255
- *
1256
- * @returns Unsubscribe function that removes the listener. Safe to call multiple times
1257
- * (subsequent calls log warning but don't throw). Closure captures event and
1258
- * callback for automatic cleanup.
1259
- *
1260
- * @throws {Error} If the same callback is already registered for this event
1261
- * @throws {Error} If listener count reaches 10000 (hard limit, indicates memory leak)
1262
- * @throws {Error} If eventName is not a valid event constant
1263
- * @throws {TypeError} If callback is not a function
1264
- *
1265
- * @example
1266
- * const unsub = router.addEventListener('TRANSITION_START', (toState, fromState) => {
1267
- * console.log('Starting navigation:', toState.name)
1268
- * })
1269
- *
1270
- * @example
1271
- * router.addEventListener('TRANSITION_ERROR', (toState, fromState, err) => {
1272
- * console.error('Navigation failed:', err)
1273
- * })
1274
- *
1275
- * @see {@link usePlugin} for plugin-based event handling (recommended)
1276
- * @see {@link subscribe} for simplified navigation event subscription
1277
- * @see {@link removeEventListener} for manual listener removal (use unsubscribe instead)
1278
- */
1279
- addEventListener: (eventName: EventToNameMap[EventsKeys], cb: Plugin[keyof Plugin]) => Unsubscribe;
1280
- forward: (fromRoute: string, toRoute: string) => Router<Dependencies>;
1281
- /**
1282
- * Navigates to the specified route.
1283
- *
1284
- * @description
1285
- * Performs a navigation transition from the current route to the target route.
1286
- * The method handles route activation/deactivation lifecycle, middleware execution,
1287
- * and state management. Navigation can be customized with options and supports
1288
- * both synchronous and asynchronous operations.
1289
- *
1290
- * @param routeName - The name of the route to navigate to. Must be a registered route.
1291
- * @param routeParams - Optional parameters to pass to the route. These will be used
1292
- * to build the route path and will be available in the route state.
1293
- * @param options - Optional navigation options to control the transition behavior
1294
- * @param done - Optional callback function called when navigation completes or fails.
1295
- * Receives error as first argument and state as second.
1296
- *
1297
- * @returns A cancel function that can be called to abort the navigation.
1298
- * Calling cancel will trigger the TRANSITION_CANCELLED event.
1299
- *
1300
- * @example
1301
- * // Simple navigation
1302
- * router.navigate('home');
1303
- *
1304
- * @example
1305
- * // Navigation with parameters
1306
- * router.navigate('user', { id: '123' });
1307
- *
1308
- * @example
1309
- * // Cancellable navigation
1310
- * const cancel = router.navigate('slow-route', {}, {}, (err) => {
1311
- * if (err?.code === 'CANCELLED') console.log('Navigation was cancelled');
1312
- * });
1313
- * // Later...
1314
- * cancel(); // Abort the navigation
1315
- *
1316
- * @throws {RouterError} With code 'NOT_STARTED' if router is not started
1317
- * @throws {RouterError} With code 'ROUTE_NOT_FOUND' if route doesn't exist
1318
- * @throws {RouterError} With code 'SAME_STATES' if navigating to current route without reload
1319
- * @throws {RouterError} With code 'CANNOT_DEACTIVATE' if canDeactivate guard prevents navigation
1320
- * @throws {RouterError} With code 'CANNOT_ACTIVATE' if canActivate guard prevents navigation
1321
- * @throws {RouterError} With code 'TRANSITION_ERR' if middleware throws an error
1322
- */
1323
- navigate: ((routeName: string) => CancelFn) & ((routeName: string, routeParams: Params) => CancelFn) & ((routeName: string, done: DoneFn) => CancelFn) & ((routeName: string, routeParams: Params, options: NavigationOptions) => CancelFn) & ((routeName: string, routeParams: Params, done: DoneFn) => CancelFn) & ((routeName: string, routeParams: Params, options: NavigationOptions, done: DoneFn) => CancelFn);
1324
- /**
1325
- * Navigates to the default route if one is configured.
1326
- *
1327
- * Uses `defaultRoute` and `defaultParams` from router options.
1328
- * Returns no-op if no default route configured.
1329
- *
1330
- * @description
1331
- * Convenience method that navigates to the route specified in router options
1332
- * as `defaultRoute` with `defaultParams`. If no default route is configured,
1333
- * this method does nothing and returns a no-op cancel function.
1334
- *
1335
- * @param opts - Optional navigation options (same as navigate method)
1336
- * @param done - Optional callback function called when navigation completes
1337
- *
1338
- * @returns A cancel function that can be called to abort the navigation.
1339
- * Returns no-op function if no default route is configured.
1340
- *
1341
- * @see {@link navigate} for detailed behavior and error handling
1342
- */
1343
- navigateToDefault: (() => CancelFn) & ((done: DoneFn) => CancelFn) & ((opts: NavigationOptions) => CancelFn) & ((opts: NavigationOptions, done: DoneFn) => CancelFn);
1344
- /**
1345
- * Internal navigation method that accepts pre-built state.
1346
- *
1347
- * @internal
1348
- * @description
1349
- * This is an internal method used by the router and plugins to perform navigation
1350
- * with a pre-built state object. It should not be used directly by application code.
1351
- * Use `navigate()` instead for normal navigation operations.
1352
- *
1353
- * The method provides control over TRANSITION_SUCCESS event emission through the
1354
- * `emitSuccess` parameter, allowing internal callers to manage event emission
1355
- * themselves to avoid duplicate events.
1356
- *
1357
- * @param toState - The target state to navigate to (pre-built)
1358
- * @param fromState - The current state to navigate from
1359
- * @param opts - Navigation options
1360
- * @param callback - Callback function called when navigation completes
1361
- * @param emitSuccess - Whether to emit TRANSITION_SUCCESS event (false for internal use)
1362
- *
1363
- * @returns A cancel function that can be called to abort the navigation
1364
- *
1365
- * @private
1366
- */
1367
- navigateToState: (toState: State, fromState: State | undefined, opts: NavigationOptions, callback: DoneFn, emitSuccess: boolean) => CancelFn;
1368
- /**
1369
- * Subscribes to successful navigation transitions.
1370
- *
1371
- * @description
1372
- * Registers a listener function that will be called whenever a navigation transition
1373
- * completes successfully. This is the primary method for integrating UI frameworks
1374
- * with the router to react to route changes.
1375
- *
1376
- * @param listener - Function called on each successful navigation transition.
1377
- * Receives { route, previousRoute } where:
1378
- * - route: The new state (frozen/immutable)
1379
- * - previousRoute: The previous state (frozen/immutable, undefined on first navigation)
1380
- *
1381
- * @returns Unsubscribe function to remove the listener. Safe to call multiple times.
1382
- *
1383
- * @example
1384
- * // Basic subscription
1385
- * const unsubscribe = router.subscribe(({ route, previousRoute }) => {
1386
- * console.log(`Navigation: ${previousRoute?.name || 'init'} → ${route.name}`);
1387
- * });
1388
- *
1389
- * // Later, cleanup
1390
- * unsubscribe();
1391
- *
1392
- * @example
1393
- *
1394
- * // Analytics
1395
- * router.subscribe(({ route }) => {
1396
- * analytics.track('page_view', { path: route.path })
1397
- * })
1398
- *
1399
- * @throws {TypeError} If listener is not a function. Error message includes
1400
- * hint about using Symbol.observable for Observable pattern.
1401
- *
1402
- * @see {@link addEventListener} for low-level event subscription
1403
- * @see {@link usePlugin} for subscribing to all router events
1404
- * @see {@link navigate} for triggering navigation
1405
- */
1406
- subscribe: (listener: SubscribeFn) => Unsubscribe;
1407
- /**
1408
- * Creates a clone of this router with the same configuration.
1409
- *
1410
- * @description
1411
- * Creates a new router instance with the same routes, options, middleware,
1412
- * plugins, and lifecycle handlers as the original. The cloned router is
1413
- * independent of the original - changes to one do not affect the other.
1414
- *
1415
- * Use cases:
1416
- * - Server-side rendering (SSR): Create a fresh router for each request
1417
- * - Testing: Clone router to test different scenarios without side effects
1418
- * - Feature flags: Create alternative router configurations
1419
- *
1420
- * What is cloned:
1421
- * - Route tree structure (via rootNode)
1422
- * - Router options (defaultRoute, trailingSlash, etc.)
1423
- * - Middleware factories
1424
- * - Plugin factories
1425
- * - Lifecycle factories (canActivate, canDeactivate)
1426
- * - Config (encoders, decoders, defaultParams, forwardMap)
1427
- *
1428
- * What is NOT cloned:
1429
- * - Current state (cloned router starts fresh)
1430
- * - Event listeners (subscribers must re-register)
1431
- * - Started status (cloned router is not started)
1432
- *
1433
- * @param dependencies - Optional new dependencies for the cloned router.
1434
- * If not provided, uses empty dependencies.
1435
- *
1436
- * @returns A new router instance with the same configuration.
1437
- *
1438
- * @example
1439
- * // Basic cloning
1440
- * const router = createRouter(routes, options);
1441
- * const clonedRouter = router.clone();
1442
- *
1443
- * @example
1444
- * // SSR: Clone with request-specific dependencies
1445
- * app.get('*', (req, res) => {
1446
- * const ssrRouter = router.clone({ request: req });
1447
- * ssrRouter.start(req.url, (err, state) => {
1448
- * // Render with state...
1449
- * });
1450
- * });
1451
- *
1452
- * @example
1453
- * // Testing: Clone for isolated test
1454
- * it('should navigate to user', () => {
1455
- * const testRouter = router.clone();
1456
- * testRouter.start();
1457
- * testRouter.navigate('user', { id: '123' });
1458
- * expect(testRouter.getState().name).toBe('user');
1459
- * });
1460
- */
1461
- clone: (dependencies?: Dependencies) => Router<Dependencies>;
1462
- }
1463
406
  interface Plugin {
1464
407
  onStart?: () => void;
1465
408
  onStop?: () => void;
@@ -1470,8 +413,6 @@ interface Plugin {
1470
413
  teardown?: () => void;
1471
414
  }
1472
415
  type Middleware = ActivationFn;
1473
- type MiddlewareFactory<Dependencies extends DefaultDependencies = DefaultDependencies> = (router: Router<Dependencies>, getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K]) => Middleware;
1474
- type PluginFactory<Dependencies extends DefaultDependencies = DefaultDependencies> = (router: Router<Dependencies>, getDependency: <K extends keyof Dependencies>(key: K) => Dependencies[K]) => Plugin;
1475
416
  interface SubscribeState {
1476
417
  route: State;
1477
418
  previousRoute?: State | undefined;
@@ -1487,4 +428,61 @@ interface Subscription {
1487
428
  unsubscribe: Unsubscribe;
1488
429
  }
1489
430
 
1490
- export type { ActivationFn, ActivationFnFactory, BuildStateResultWithSegments, CancelFn, Config, DefaultDependencies, DoneFn, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, Listener, Middleware, MiddlewareFactory, NavigationOptions, Options, Params, Plugin, PluginFactory, PluginMethod, QueryParamsMode, QueryParamsOptions, Route, RouteTreeState, Router, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, Unsubscribe };
431
+ /**
432
+ * Plugin lifecycle method names
433
+ */
434
+ type PluginMethod = "onStart" | "onStop" | "onTransitionStart" | "onTransitionCancel" | "onTransitionSuccess" | "onTransitionError";
435
+ /**
436
+ * Router event names
437
+ */
438
+ type EventName = "$start" | "$stop" | "$$start" | "$$cancel" | "$$success" | "$$error";
439
+ /**
440
+ * Event type keys
441
+ */
442
+ type EventsKeys = "ROUTER_START" | "ROUTER_STOP" | "TRANSITION_START" | "TRANSITION_CANCEL" | "TRANSITION_SUCCESS" | "TRANSITION_ERROR";
443
+ /**
444
+ * Error code values
445
+ */
446
+ type ErrorCodeValues = "NOT_STARTED" | "NO_START_PATH_OR_STATE" | "ALREADY_STARTED" | "ROUTE_NOT_FOUND" | "SAME_STATES" | "CANNOT_DEACTIVATE" | "CANNOT_ACTIVATE" | "TRANSITION_ERR" | "CANCELLED";
447
+ /**
448
+ * Error code keys
449
+ */
450
+ type ErrorCodeKeys = "ROUTER_NOT_STARTED" | "NO_START_PATH_OR_STATE" | "ROUTER_ALREADY_STARTED" | "ROUTE_NOT_FOUND" | "SAME_STATES" | "CANNOT_DEACTIVATE" | "CANNOT_ACTIVATE" | "TRANSITION_ERR" | "TRANSITION_CANCELLED";
451
+ /**
452
+ * Mapping of event keys to plugin methods
453
+ */
454
+ interface EventToPluginMap {
455
+ readonly ROUTER_START: "onStart";
456
+ readonly ROUTER_STOP: "onStop";
457
+ readonly TRANSITION_START: "onTransitionStart";
458
+ readonly TRANSITION_CANCEL: "onTransitionCancel";
459
+ readonly TRANSITION_SUCCESS: "onTransitionSuccess";
460
+ readonly TRANSITION_ERROR: "onTransitionError";
461
+ }
462
+ /**
463
+ * Mapping of event keys to event names
464
+ */
465
+ interface EventToNameMap {
466
+ ROUTER_START: "$start";
467
+ ROUTER_STOP: "$stop";
468
+ TRANSITION_START: "$$start";
469
+ TRANSITION_CANCEL: "$$cancel";
470
+ TRANSITION_SUCCESS: "$$success";
471
+ TRANSITION_ERROR: "$$error";
472
+ }
473
+ /**
474
+ * Mapping of error code keys to their values
475
+ */
476
+ interface ErrorCodeToValueMap {
477
+ ROUTER_NOT_STARTED: "NOT_STARTED";
478
+ NO_START_PATH_OR_STATE: "NO_START_PATH_OR_STATE";
479
+ ROUTER_ALREADY_STARTED: "ALREADY_STARTED";
480
+ ROUTE_NOT_FOUND: "ROUTE_NOT_FOUND";
481
+ SAME_STATES: "SAME_STATES";
482
+ CANNOT_DEACTIVATE: "CANNOT_DEACTIVATE";
483
+ CANNOT_ACTIVATE: "CANNOT_ACTIVATE";
484
+ TRANSITION_ERR: "TRANSITION_ERR";
485
+ TRANSITION_CANCELLED: "CANCELLED";
486
+ }
487
+
488
+ export type { ActivationFn, CancelFn, Config, DefaultDependencies, DoneFn, ErrorCodeKeys, ErrorCodeToValueMap, ErrorCodeValues, EventName, EventToNameMap, EventToPluginMap, EventsKeys, Listener, Middleware, NavigationOptions, Options, Params, Plugin, PluginMethod, QueryParamsMode, QueryParamsOptions, RouteTreeState, RouterError, SimpleState, State, StateMeta, StateMetaInput, SubscribeFn, SubscribeState, Subscription, Unsubscribe };