@pithyjs/router 0.1.0-beta.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 (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +621 -0
  3. package/dist/index.d.ts +29 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +49 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/router/core/config.d.ts +22 -0
  8. package/dist/router/core/config.d.ts.map +1 -0
  9. package/dist/router/core/config.js +54 -0
  10. package/dist/router/core/config.js.map +1 -0
  11. package/dist/router/core/constants.d.ts +89 -0
  12. package/dist/router/core/constants.d.ts.map +1 -0
  13. package/dist/router/core/constants.js +95 -0
  14. package/dist/router/core/constants.js.map +1 -0
  15. package/dist/router/core/history.d.ts +54 -0
  16. package/dist/router/core/history.d.ts.map +1 -0
  17. package/dist/router/core/history.js +89 -0
  18. package/dist/router/core/history.js.map +1 -0
  19. package/dist/router/core/matcher.d.ts +43 -0
  20. package/dist/router/core/matcher.d.ts.map +1 -0
  21. package/dist/router/core/matcher.js +242 -0
  22. package/dist/router/core/matcher.js.map +1 -0
  23. package/dist/router/core/params.d.ts +88 -0
  24. package/dist/router/core/params.d.ts.map +1 -0
  25. package/dist/router/core/params.js +150 -0
  26. package/dist/router/core/params.js.map +1 -0
  27. package/dist/router/core/pipeline.d.ts +90 -0
  28. package/dist/router/core/pipeline.d.ts.map +1 -0
  29. package/dist/router/core/pipeline.js +323 -0
  30. package/dist/router/core/pipeline.js.map +1 -0
  31. package/dist/router/core/route-tree.d.ts +76 -0
  32. package/dist/router/core/route-tree.d.ts.map +1 -0
  33. package/dist/router/core/route-tree.js +143 -0
  34. package/dist/router/core/route-tree.js.map +1 -0
  35. package/dist/router/core/router.d.ts +229 -0
  36. package/dist/router/core/router.d.ts.map +1 -0
  37. package/dist/router/core/router.js +762 -0
  38. package/dist/router/core/router.js.map +1 -0
  39. package/dist/router/core/types.d.ts +387 -0
  40. package/dist/router/core/types.d.ts.map +1 -0
  41. package/dist/router/core/types.js +22 -0
  42. package/dist/router/core/types.js.map +1 -0
  43. package/dist/router/core/utils.d.ts +66 -0
  44. package/dist/router/core/utils.d.ts.map +1 -0
  45. package/dist/router/core/utils.js +152 -0
  46. package/dist/router/core/utils.js.map +1 -0
  47. package/dist/router/features/coordinator.d.ts +75 -0
  48. package/dist/router/features/coordinator.d.ts.map +1 -0
  49. package/dist/router/features/coordinator.js +203 -0
  50. package/dist/router/features/coordinator.js.map +1 -0
  51. package/dist/router/features/errors/error-codes.d.ts +107 -0
  52. package/dist/router/features/errors/error-codes.d.ts.map +1 -0
  53. package/dist/router/features/errors/error-codes.js +247 -0
  54. package/dist/router/features/errors/error-codes.js.map +1 -0
  55. package/dist/router/features/errors/error-resolution.d.ts +31 -0
  56. package/dist/router/features/errors/error-resolution.d.ts.map +1 -0
  57. package/dist/router/features/errors/error-resolution.js +47 -0
  58. package/dist/router/features/errors/error-resolution.js.map +1 -0
  59. package/dist/router/features/errors/error-types.d.ts +60 -0
  60. package/dist/router/features/errors/error-types.d.ts.map +1 -0
  61. package/dist/router/features/errors/error-types.js +57 -0
  62. package/dist/router/features/errors/error-types.js.map +1 -0
  63. package/dist/router/features/errors/global-error-fallback.d.ts +33 -0
  64. package/dist/router/features/errors/global-error-fallback.d.ts.map +1 -0
  65. package/dist/router/features/errors/global-error-fallback.js +182 -0
  66. package/dist/router/features/errors/global-error-fallback.js.map +1 -0
  67. package/dist/router/features/errors/index.d.ts +15 -0
  68. package/dist/router/features/errors/index.d.ts.map +1 -0
  69. package/dist/router/features/errors/index.js +18 -0
  70. package/dist/router/features/errors/index.js.map +1 -0
  71. package/dist/router/features/errors/router-errors.d.ts +44 -0
  72. package/dist/router/features/errors/router-errors.d.ts.map +1 -0
  73. package/dist/router/features/errors/router-errors.js +53 -0
  74. package/dist/router/features/errors/router-errors.js.map +1 -0
  75. package/dist/router/features/guards/engine.d.ts +40 -0
  76. package/dist/router/features/guards/engine.d.ts.map +1 -0
  77. package/dist/router/features/guards/engine.js +67 -0
  78. package/dist/router/features/guards/engine.js.map +1 -0
  79. package/dist/router/features/guards/index.d.ts +52 -0
  80. package/dist/router/features/guards/index.d.ts.map +1 -0
  81. package/dist/router/features/guards/index.js +95 -0
  82. package/dist/router/features/guards/index.js.map +1 -0
  83. package/dist/router/features/loaders/cache.d.ts +60 -0
  84. package/dist/router/features/loaders/cache.d.ts.map +1 -0
  85. package/dist/router/features/loaders/cache.js +80 -0
  86. package/dist/router/features/loaders/cache.js.map +1 -0
  87. package/dist/router/features/loaders/engine.d.ts +17 -0
  88. package/dist/router/features/loaders/engine.d.ts.map +1 -0
  89. package/dist/router/features/loaders/engine.js +27 -0
  90. package/dist/router/features/loaders/engine.js.map +1 -0
  91. package/dist/router/features/loaders/index.d.ts +49 -0
  92. package/dist/router/features/loaders/index.d.ts.map +1 -0
  93. package/dist/router/features/loaders/index.js +112 -0
  94. package/dist/router/features/loaders/index.js.map +1 -0
  95. package/dist/router/features/loading-ui-manager.d.ts +69 -0
  96. package/dist/router/features/loading-ui-manager.d.ts.map +1 -0
  97. package/dist/router/features/loading-ui-manager.js +209 -0
  98. package/dist/router/features/loading-ui-manager.js.map +1 -0
  99. package/dist/router/features/module-loader.d.ts +50 -0
  100. package/dist/router/features/module-loader.d.ts.map +1 -0
  101. package/dist/router/features/module-loader.js +121 -0
  102. package/dist/router/features/module-loader.js.map +1 -0
  103. package/dist/router/features/outlet/errors.d.ts +24 -0
  104. package/dist/router/features/outlet/errors.d.ts.map +1 -0
  105. package/dist/router/features/outlet/errors.js +96 -0
  106. package/dist/router/features/outlet/errors.js.map +1 -0
  107. package/dist/router/features/outlet/index.d.ts +45 -0
  108. package/dist/router/features/outlet/index.d.ts.map +1 -0
  109. package/dist/router/features/outlet/index.js +95 -0
  110. package/dist/router/features/outlet/index.js.map +1 -0
  111. package/dist/router/features/outlet/mount.d.ts +38 -0
  112. package/dist/router/features/outlet/mount.d.ts.map +1 -0
  113. package/dist/router/features/outlet/mount.js +301 -0
  114. package/dist/router/features/outlet/mount.js.map +1 -0
  115. package/dist/router/features/outlet/segment-chain.d.ts +16 -0
  116. package/dist/router/features/outlet/segment-chain.d.ts.map +1 -0
  117. package/dist/router/features/outlet/segment-chain.js +62 -0
  118. package/dist/router/features/outlet/segment-chain.js.map +1 -0
  119. package/dist/router/features/prefetch/index.d.ts +97 -0
  120. package/dist/router/features/prefetch/index.d.ts.map +1 -0
  121. package/dist/router/features/prefetch/index.js +345 -0
  122. package/dist/router/features/prefetch/index.js.map +1 -0
  123. package/dist/router/features/ux/focus.d.ts +62 -0
  124. package/dist/router/features/ux/focus.d.ts.map +1 -0
  125. package/dist/router/features/ux/focus.js +136 -0
  126. package/dist/router/features/ux/focus.js.map +1 -0
  127. package/dist/router/features/ux/live-region.d.ts +81 -0
  128. package/dist/router/features/ux/live-region.d.ts.map +1 -0
  129. package/dist/router/features/ux/live-region.js +166 -0
  130. package/dist/router/features/ux/live-region.js.map +1 -0
  131. package/dist/router/features/ux/scroll-focus.d.ts +105 -0
  132. package/dist/router/features/ux/scroll-focus.d.ts.map +1 -0
  133. package/dist/router/features/ux/scroll-focus.js +111 -0
  134. package/dist/router/features/ux/scroll-focus.js.map +1 -0
  135. package/dist/router/features/ux/scroll.d.ts +71 -0
  136. package/dist/router/features/ux/scroll.d.ts.map +1 -0
  137. package/dist/router/features/ux/scroll.js +137 -0
  138. package/dist/router/features/ux/scroll.js.map +1 -0
  139. package/dist/router/features/ux/transitions.d.ts +120 -0
  140. package/dist/router/features/ux/transitions.d.ts.map +1 -0
  141. package/dist/router/features/ux/transitions.js +235 -0
  142. package/dist/router/features/ux/transitions.js.map +1 -0
  143. package/dist/router/integration/directive-binder.d.ts +20 -0
  144. package/dist/router/integration/directive-binder.d.ts.map +1 -0
  145. package/dist/router/integration/directive-binder.js +139 -0
  146. package/dist/router/integration/directive-binder.js.map +1 -0
  147. package/dist/router/integration/directives.d.ts +42 -0
  148. package/dist/router/integration/directives.d.ts.map +1 -0
  149. package/dist/router/integration/directives.js +109 -0
  150. package/dist/router/integration/directives.js.map +1 -0
  151. package/dist/router/integration/history-adapter.d.ts +76 -0
  152. package/dist/router/integration/history-adapter.d.ts.map +1 -0
  153. package/dist/router/integration/history-adapter.js +157 -0
  154. package/dist/router/integration/history-adapter.js.map +1 -0
  155. package/dist/router/integration/hmr.d.ts +83 -0
  156. package/dist/router/integration/hmr.d.ts.map +1 -0
  157. package/dist/router/integration/hmr.js +160 -0
  158. package/dist/router/integration/hmr.js.map +1 -0
  159. package/dist/router/integration/link-interceptor.d.ts +49 -0
  160. package/dist/router/integration/link-interceptor.d.ts.map +1 -0
  161. package/dist/router/integration/link-interceptor.js +94 -0
  162. package/dist/router/integration/link-interceptor.js.map +1 -0
  163. package/package.json +47 -0
@@ -0,0 +1,120 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.view-transitions",
4
+ "title": "View Transitions API Integration",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionPreset","stability":"experimental","signature":"type ViewTransitionPreset"} */
9
+ /**
10
+ * Built-in transition presets
11
+ * These transitions work globally without requiring additional parameters.
12
+ */
13
+ export type ViewTransitionPreset = 'slide' | 'fade' | 'none';
14
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionType","stability":"experimental","signature":"type ViewTransitionType"} */
15
+ /**
16
+ * View transition types
17
+ * Includes built-in presets plus 'custom' for element-specific transitions.
18
+ * The 'custom' type requires a transition name via data-transition-name attribute.
19
+ */
20
+ export type ViewTransitionType = ViewTransitionPreset | 'custom';
21
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionConfig","stability":"experimental","signature":"interface ViewTransitionConfig"} */
22
+ /**
23
+ * View transition configuration
24
+ * Controls global view transition behavior for the router.
25
+ * Browser support required: Chrome 111+, Edge 111+
26
+ */
27
+ export interface ViewTransitionConfig {
28
+ /** Whether to enable view transitions */
29
+ enabled?: boolean;
30
+ /** Default transition preset (cannot be 'custom' as it requires a name parameter) */
31
+ defaultTransition?: ViewTransitionPreset;
32
+ /** Custom transition duration (ms) */
33
+ duration?: number;
34
+ /** Easing function for transitions */
35
+ easing?: string;
36
+ }
37
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionOptions","stability":"experimental","signature":"interface ViewTransitionOptions"} */
38
+ /**
39
+ * View transition options for individual navigations
40
+ * Allows per-navigation customization of transition behavior.
41
+ */
42
+ export interface ViewTransitionOptions {
43
+ /** Transition type to use */
44
+ type?: ViewTransitionType | undefined;
45
+ /** Whether to skip transition for this navigation */
46
+ skipTransition?: boolean | undefined;
47
+ /** Custom transition name */
48
+ name?: string | undefined;
49
+ }
50
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionManager","stability":"experimental","signature":"class ViewTransitionManager"} */
51
+ /**
52
+ * View transition manager for enhanced navigation UX
53
+ * Integrates the browser's View Transitions API for smooth route changes.
54
+ * Provides slide, fade, and custom animations with graceful fallback for unsupported browsers.
55
+ */
56
+ export declare class ViewTransitionManager {
57
+ private config;
58
+ constructor(config?: ViewTransitionConfig);
59
+ /**
60
+ * Check if View Transitions API is supported (dynamic check for testing)
61
+ */
62
+ private isSupported;
63
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"isAvailable","stability":"experimental","signature":"() => boolean"} */
64
+ /**
65
+ * Check if view transitions are supported and enabled
66
+ * Returns true only if both browser support exists AND transitions are enabled in config.
67
+ */
68
+ isAvailable(): boolean;
69
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"executeTransition","stability":"experimental","signature":"<T>(updateCallback: () => Promise<T> | T, options?: ViewTransitionOptions) => Promise<T>"} */
70
+ /**
71
+ * Execute a view transition for navigation
72
+ * Wraps the DOM update callback with View Transitions API animation.
73
+ * Gracefully falls back to immediate execution if unsupported or disabled.
74
+ */
75
+ executeTransition<T>(updateCallback: () => Promise<T> | T, options?: ViewTransitionOptions): Promise<T>;
76
+ /**
77
+ * Apply custom transition styles
78
+ */
79
+ private applyTransitionStyles;
80
+ /**
81
+ * Clear transition styles
82
+ */
83
+ private clearTransitionStyles;
84
+ /**
85
+ * Get transition options from element attributes
86
+ * Reads data-transition and data-transition-name attributes to configure transitions.
87
+ * If no element is provided, returns default transition options from config.
88
+ * @internal Used internally by the router during navigation
89
+ */
90
+ getTransitionOptionsFromElement(element?: Element | null): ViewTransitionOptions | null;
91
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"updateConfig","stability":"experimental","signature":"(config: Partial<ViewTransitionConfig>) => void"} */
92
+ /**
93
+ * Update configuration
94
+ * Allows runtime configuration changes for view transitions.
95
+ */
96
+ updateConfig(config: Partial<ViewTransitionConfig>): void;
97
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"cleanup","stability":"experimental","signature":"() => void"} */
98
+ /**
99
+ * Cleanup transition styles and resources
100
+ * Removes injected transition styles from the document.
101
+ */
102
+ cleanup(): void;
103
+ }
104
+ /**
105
+ * Global view transition manager instance
106
+ * Singleton instance used by the router for view transition management.
107
+ * @internal Used internally by the router; users should configure via RouterConfig
108
+ */
109
+ export declare const viewTransitionManager: ViewTransitionManager;
110
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"useViewTransitions","stability":"experimental","signature":"(config?: ViewTransitionConfig) => ViewTransitionManager"} */
111
+ /**
112
+ * View transition utilities
113
+ */
114
+ export declare function useViewTransitions(config?: ViewTransitionConfig): ViewTransitionManager;
115
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"supportsViewTransitions","stability":"stable","signature":"() => boolean"} */
116
+ /**
117
+ * Check if view transitions are supported in the current environment
118
+ */
119
+ export declare function supportsViewTransitions(): boolean;
120
+ //# sourceMappingURL=transitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.d.ts","sourceRoot":"","sources":["../../../../src/router/features/ux/transitions.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,4JAA4J;AAC5J;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7D,wJAAwJ;AACxJ;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,oBAAoB,GAAG,QAAQ,CAAC;AAEjE,iKAAiK;AACjK;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,oBAAoB,CAAC;IACzC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,mKAAmK;AACnK;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACtC,qDAAqD;IACrD,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,+JAA+J;AAC/J;;;;GAIG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAiC;gBAEnC,MAAM,GAAE,oBAAyB;IAU7C;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB,uIAAuI;IACvI;;;OAGG;IACH,WAAW,IAAI,OAAO;IAItB,wNAAwN;IACxN;;;;OAIG;IACG,iBAAiB,CAAC,CAAC,EACvB,cAAc,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACpC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,CAAC,CAAC;IA+Cb;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA4E7B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;;;;OAKG;IACH,+BAA+B,CAC7B,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvB,qBAAqB,GAAG,IAAI;IA4B/B,0KAA0K;IAC1K;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI;IAIzD,gIAAgI;IAChI;;;OAGG;IACH,OAAO,IAAI,IAAI;CAGhB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,uBAA8B,CAAC;AAEjE,yLAAyL;AACzL;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,qBAAqB,CAKvB;AAED,6IAA6I;AAC7I;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD"}
@@ -0,0 +1,235 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.view-transitions",
4
+ "title": "View Transitions API Integration",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"ViewTransitionManager","stability":"experimental","signature":"class ViewTransitionManager"} */
9
+ /**
10
+ * View transition manager for enhanced navigation UX
11
+ * Integrates the browser's View Transitions API for smooth route changes.
12
+ * Provides slide, fade, and custom animations with graceful fallback for unsupported browsers.
13
+ */
14
+ export class ViewTransitionManager {
15
+ constructor(config = {}) {
16
+ this.config = {
17
+ enabled: true,
18
+ defaultTransition: 'fade',
19
+ duration: 400,
20
+ easing: 'ease-in-out',
21
+ ...config,
22
+ };
23
+ }
24
+ /**
25
+ * Check if View Transitions API is supported (dynamic check for testing)
26
+ */
27
+ isSupported() {
28
+ return typeof document !== 'undefined' && 'startViewTransition' in document;
29
+ }
30
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"isAvailable","stability":"experimental","signature":"() => boolean"} */
31
+ /**
32
+ * Check if view transitions are supported and enabled
33
+ * Returns true only if both browser support exists AND transitions are enabled in config.
34
+ */
35
+ isAvailable() {
36
+ return this.isSupported() && this.config.enabled;
37
+ }
38
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"executeTransition","stability":"experimental","signature":"<T>(updateCallback: () => Promise<T> | T, options?: ViewTransitionOptions) => Promise<T>"} */
39
+ /**
40
+ * Execute a view transition for navigation
41
+ * Wraps the DOM update callback with View Transitions API animation.
42
+ * Gracefully falls back to immediate execution if unsupported or disabled.
43
+ */
44
+ async executeTransition(updateCallback, options) {
45
+ // If transitions are not available or disabled, just run the callback
46
+ if (!this.isAvailable() || options?.skipTransition) {
47
+ return await updateCallback();
48
+ }
49
+ // Apply custom transition styles BEFORE starting transition
50
+ if (options?.type && options.type !== 'none') {
51
+ this.applyTransitionStyles(options.type, options.name);
52
+ }
53
+ // Use the native View Transitions API
54
+ if (document.startViewTransition) {
55
+ return await new Promise((resolve, reject) => {
56
+ const transition = document.startViewTransition(async () => {
57
+ try {
58
+ const result = await updateCallback();
59
+ return result;
60
+ }
61
+ catch (error) {
62
+ reject(error);
63
+ throw error;
64
+ }
65
+ });
66
+ // Handle transition completion
67
+ transition.finished
68
+ .then(() => {
69
+ // Transition completed successfully
70
+ })
71
+ .catch(error => {
72
+ console.warn('View transition failed:', error);
73
+ // Continue with the result even if transition failed
74
+ });
75
+ // The result will be available when the callback completes
76
+ transition.ready
77
+ .then(result => {
78
+ resolve(result);
79
+ })
80
+ .catch(reject);
81
+ });
82
+ }
83
+ // Fallback for browsers without View Transitions API
84
+ return await updateCallback();
85
+ }
86
+ /**
87
+ * Apply custom transition styles
88
+ */
89
+ applyTransitionStyles(type, name) {
90
+ if (typeof document === 'undefined')
91
+ return;
92
+ // Remove existing transition styles
93
+ this.clearTransitionStyles();
94
+ const style = document.createElement('style');
95
+ style.id = 'pithy-view-transition-styles';
96
+ let css = '';
97
+ switch (type) {
98
+ case 'slide':
99
+ css = `
100
+ ::view-transition-old(root) {
101
+ animation: slide-out ${this.config.duration}ms ${this.config.easing} both;
102
+ }
103
+ ::view-transition-new(root) {
104
+ animation: slide-in ${this.config.duration}ms ${this.config.easing} both;
105
+ }
106
+ @keyframes slide-out {
107
+ from { transform: translateX(0); }
108
+ to { transform: translateX(-100%); }
109
+ }
110
+ @keyframes slide-in {
111
+ from { transform: translateX(100%); }
112
+ to { transform: translateX(0); }
113
+ }
114
+ `;
115
+ break;
116
+ case 'fade':
117
+ css = `
118
+ ::view-transition-old(root) {
119
+ animation: fade-out ${this.config.duration}ms ${this.config.easing} both;
120
+ }
121
+ ::view-transition-new(root) {
122
+ animation: fade-in ${this.config.duration}ms ${this.config.easing} both;
123
+ }
124
+ @keyframes fade-out {
125
+ from { opacity: 1; }
126
+ to { opacity: 0; }
127
+ }
128
+ @keyframes fade-in {
129
+ from { opacity: 0; }
130
+ to { opacity: 1; }
131
+ }
132
+ `;
133
+ break;
134
+ case 'custom':
135
+ if (name) {
136
+ css = `
137
+ ::view-transition-old(${name}) {
138
+ animation: custom-out ${this.config.duration}ms ${this.config.easing} both;
139
+ }
140
+ ::view-transition-new(${name}) {
141
+ animation: custom-in ${this.config.duration}ms ${this.config.easing} both;
142
+ }
143
+ @keyframes custom-out {
144
+ from { opacity: 1; transform: scale(1); }
145
+ to { opacity: 0.8; transform: scale(0.95); }
146
+ }
147
+ @keyframes custom-in {
148
+ from { opacity: 0.8; transform: scale(0.95); }
149
+ to { opacity: 1; transform: scale(1); }
150
+ }
151
+ `;
152
+ }
153
+ break;
154
+ }
155
+ style.textContent = css;
156
+ document.head.appendChild(style);
157
+ }
158
+ /**
159
+ * Clear transition styles
160
+ */
161
+ clearTransitionStyles() {
162
+ if (typeof document === 'undefined')
163
+ return;
164
+ const existingStyle = document.getElementById('pithy-view-transition-styles');
165
+ if (existingStyle) {
166
+ existingStyle.remove();
167
+ }
168
+ }
169
+ /**
170
+ * Get transition options from element attributes
171
+ * Reads data-transition and data-transition-name attributes to configure transitions.
172
+ * If no element is provided, returns default transition options from config.
173
+ * @internal Used internally by the router during navigation
174
+ */
175
+ getTransitionOptionsFromElement(element) {
176
+ // If no element provided, use default transition from config
177
+ if (!element) {
178
+ return {
179
+ type: this.config.defaultTransition,
180
+ name: undefined,
181
+ };
182
+ }
183
+ const skipTransition = element.hasAttribute('data-no-transition') ||
184
+ element.closest('[data-no-transition]') !== null;
185
+ if (skipTransition) {
186
+ return { skipTransition: true };
187
+ }
188
+ const transitionType = element.getAttribute('data-transition');
189
+ const transitionName = element.getAttribute('data-transition-name');
190
+ return {
191
+ type: transitionType || this.config.defaultTransition,
192
+ name: transitionName || undefined,
193
+ };
194
+ }
195
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"updateConfig","stability":"experimental","signature":"(config: Partial<ViewTransitionConfig>) => void"} */
196
+ /**
197
+ * Update configuration
198
+ * Allows runtime configuration changes for view transitions.
199
+ */
200
+ updateConfig(config) {
201
+ this.config = { ...this.config, ...config };
202
+ }
203
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"cleanup","stability":"experimental","signature":"() => void"} */
204
+ /**
205
+ * Cleanup transition styles and resources
206
+ * Removes injected transition styles from the document.
207
+ */
208
+ cleanup() {
209
+ this.clearTransitionStyles();
210
+ }
211
+ }
212
+ /**
213
+ * Global view transition manager instance
214
+ * Singleton instance used by the router for view transition management.
215
+ * @internal Used internally by the router; users should configure via RouterConfig
216
+ */
217
+ export const viewTransitionManager = new ViewTransitionManager();
218
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"useViewTransitions","stability":"experimental","signature":"(config?: ViewTransitionConfig) => ViewTransitionManager"} */
219
+ /**
220
+ * View transition utilities
221
+ */
222
+ export function useViewTransitions(config) {
223
+ if (config) {
224
+ viewTransitionManager.updateConfig(config);
225
+ }
226
+ return viewTransitionManager;
227
+ }
228
+ /** @codexApi {"parent":"pithy.router.view-transitions","name":"supportsViewTransitions","stability":"stable","signature":"() => boolean"} */
229
+ /**
230
+ * Check if view transitions are supported in the current environment
231
+ */
232
+ export function supportsViewTransitions() {
233
+ return typeof document !== 'undefined' && 'startViewTransition' in document;
234
+ }
235
+ //# sourceMappingURL=transitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitions.js","sourceRoot":"","sources":["../../../../src/router/features/ux/transitions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.directive-binding",
4
+ "title": "Router Directive Binding System",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import type { Router } from '../core/router';
9
+ /** @codexApi {"parent":"pithy.router.directive-binding","name":"setGlobalRouter","stability":"stable","signature":"(router: Router) => void"} */
10
+ /**
11
+ * Set the global router instance for directive binding.
12
+ * Also registers the directive binder with core and scans for unbound links.
13
+ */
14
+ export declare function setGlobalRouter(router: Router): void;
15
+ /** @codexApi {"parent":"pithy.router.directive-binding","name":"getGlobalRouter","stability":"stable","signature":"() => Router | null"} */
16
+ /**
17
+ * Get the global router instance
18
+ */
19
+ export declare function getGlobalRouter(): Router | null;
20
+ //# sourceMappingURL=directive-binder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directive-binder.d.ts","sourceRoot":"","sources":["../../../src/router/integration/directive-binder.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAiBF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AA8I7C,iJAAiJ;AACjJ;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CASpD;AAED,4IAA4I;AAC5I;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C"}
@@ -0,0 +1,139 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.directive-binding",
4
+ "title": "Router Directive Binding System",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ /**
9
+ * Router Directive Binder
10
+ *
11
+ * Handles binding of router directives (@routerOutlet, @routerLink) in templates.
12
+ * Registers with core's directive registry to integrate with template compilation.
13
+ *
14
+ * @module router/integration/directive-binder
15
+ */
16
+ import { registerDirectiveBinder } from '@pithyjs/core';
17
+ import { routerLink, routerOutlet } from './directives';
18
+ import { PREFETCH_STRATEGIES, } from '../features/prefetch';
19
+ function resolvePrefetchAttr(value) {
20
+ if (value === null)
21
+ return 'none';
22
+ if (PREFETCH_STRATEGIES.includes(value)) {
23
+ return value;
24
+ }
25
+ if (import.meta.env?.DEV) {
26
+ console.warn(`[@routerLink] invalid data-prefetch="${value}" — expected one of ${PREFETCH_STRATEGIES.join(', ')}; falling back to "none".`);
27
+ }
28
+ return 'none';
29
+ }
30
+ /**
31
+ * Global router instance - will be set by the router when it mounts
32
+ */
33
+ let globalRouter = null;
34
+ /**
35
+ * Bind existing router links that were rendered before the router was available
36
+ * Looks for @routerLink elements that don't have cleanup functions attached yet
37
+ */
38
+ function bindExistingRouterLinks(router) {
39
+ const unboundLinks = document.querySelectorAll('a[data-router-link]:not([data-router-bound])');
40
+ unboundLinks.forEach(el => {
41
+ const element = el;
42
+ // Mark as bound to avoid double-binding
43
+ element.setAttribute('data-router-bound', 'true');
44
+ const prefetchStrategy = resolvePrefetchAttr(element.getAttribute('data-prefetch'));
45
+ // Extract other router link options
46
+ const activeClass = element.getAttribute('active-class') || 'router-link-active';
47
+ const exactMatch = element.hasAttribute('exact-match');
48
+ const replace = element.hasAttribute('replace');
49
+ const options = {
50
+ activeClass,
51
+ exactMatch,
52
+ prefetch: prefetchStrategy,
53
+ replace,
54
+ };
55
+ routerLink(element, router, options);
56
+ });
57
+ }
58
+ /**
59
+ * Binds router directives (@routerOutlet, @routerLink) within the DOM tree
60
+ * This integrates the router directives into the core template compilation system
61
+ */
62
+ const bindRouterDirectives = (root, _context, disposers) => {
63
+ if (!globalRouter) {
64
+ // Router not yet initialized, skip binding
65
+ return;
66
+ }
67
+ // Type narrowing: router is non-null after the check above
68
+ const router = globalRouter;
69
+ // Find all elements with router directives
70
+ const elements = root.querySelectorAll('*');
71
+ elements.forEach(el => {
72
+ const element = el;
73
+ // Handle @routerOutlet directive
74
+ if (element.hasAttribute('data-router-outlet')) {
75
+ routerOutlet(element, router);
76
+ // Add cleanup
77
+ disposers.push(() => {
78
+ const target = element;
79
+ const cleanup = target.__routerOutletCleanup;
80
+ if (cleanup) {
81
+ cleanup();
82
+ delete target.__routerOutletCleanup;
83
+ }
84
+ });
85
+ }
86
+ // Handle @routerLink directive
87
+ if (element.hasAttribute('data-router-link') && element.tagName === 'A') {
88
+ const anchorElement = element;
89
+ // Skip if already bound (to avoid double-binding)
90
+ if (anchorElement.hasAttribute('data-router-bound')) {
91
+ return;
92
+ }
93
+ // Mark as bound to avoid double-binding
94
+ anchorElement.setAttribute('data-router-bound', 'true');
95
+ const prefetchStrategy = resolvePrefetchAttr(element.getAttribute('data-prefetch'));
96
+ // Extract other router link options
97
+ const activeClass = element.getAttribute('active-class') || 'router-link-active';
98
+ const exactMatch = element.hasAttribute('exact-match');
99
+ const replace = element.hasAttribute('replace');
100
+ const options = {
101
+ activeClass,
102
+ exactMatch,
103
+ prefetch: prefetchStrategy,
104
+ replace,
105
+ };
106
+ routerLink(anchorElement, router, options);
107
+ // Add cleanup
108
+ disposers.push(() => {
109
+ const target = anchorElement;
110
+ const cleanup = target.__routerLinkCleanup;
111
+ if (cleanup) {
112
+ cleanup();
113
+ delete target.__routerLinkCleanup;
114
+ }
115
+ });
116
+ }
117
+ });
118
+ };
119
+ /** @codexApi {"parent":"pithy.router.directive-binding","name":"setGlobalRouter","stability":"stable","signature":"(router: Router) => void"} */
120
+ /**
121
+ * Set the global router instance for directive binding.
122
+ * Also registers the directive binder with core and scans for unbound links.
123
+ */
124
+ export function setGlobalRouter(router) {
125
+ globalRouter = router;
126
+ // Register our directive binder with core (idempotent - won't double-register)
127
+ registerDirectiveBinder(bindRouterDirectives);
128
+ // Scan the DOM for any unbound router links and bind them
129
+ // This handles the case where links were rendered before the router was mounted
130
+ bindExistingRouterLinks(router);
131
+ }
132
+ /** @codexApi {"parent":"pithy.router.directive-binding","name":"getGlobalRouter","stability":"stable","signature":"() => Router | null"} */
133
+ /**
134
+ * Get the global router instance
135
+ */
136
+ export function getGlobalRouter() {
137
+ return globalRouter;
138
+ }
139
+ //# sourceMappingURL=directive-binder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directive-binder.js","sourceRoot":"","sources":["../../../src/router/integration/directive-binder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.directives",
4
+ "title": "Router Directives (@routerOutlet, @routerLink)",
5
+ "category": "directive"
6
+ }
7
+ */
8
+ import type { Router } from '../core/router';
9
+ import { type PrefetchStrategy } from '../features/prefetch';
10
+ /** @codexApi {"parent":"pithy.router.directives","name":"routerOutlet","stability":"experimental","signature":"(element: HTMLElement, router: Router) => void"} */
11
+ /**
12
+ * Router outlet directive - marks where child routes should be rendered
13
+ *
14
+ * NOTE: This directive only marks the outlet element. The actual route component
15
+ * rendering is handled by OutletManager.mountSegments() when router.mount() is called.
16
+ */
17
+ export declare function routerOutlet(element: HTMLElement, _router: Router): void;
18
+ /** @codexApi {"parent":"pithy.router.directives","name":"routerLink","stability":"stable","signature":"(element: HTMLAnchorElement, router: Router, options?: RouterLinkOptions) => void"} */
19
+ /**
20
+ * Router link directive - enhances anchor tags with client-side navigation
21
+ * Fixed to prevent URL changes when guards deny navigation
22
+ */
23
+ export declare function routerLink(element: HTMLAnchorElement, router: Router, options?: RouterLinkOptions): void;
24
+ /**
25
+ * Router link options
26
+ */
27
+ export interface RouterLinkOptions {
28
+ /** CSS class to apply when link is active */
29
+ activeClass?: string;
30
+ /** Whether to match the exact path or allow partial matches */
31
+ exactMatch?: boolean;
32
+ /** Prefetch strategy */
33
+ prefetch?: PrefetchStrategy;
34
+ /** Replace current history entry instead of pushing a new one */
35
+ replace?: boolean;
36
+ }
37
+ /** @codexApi {"parent":"pithy.router.directives","name":"cleanupRouterDirectives","stability":"experimental","signature":"(element: HTMLElement) => void"} */
38
+ /**
39
+ * Cleanup router directive subscriptions
40
+ */
41
+ export declare function cleanupRouterDirectives(element: HTMLElement): void;
42
+ //# sourceMappingURL=directives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directives.d.ts","sourceRoot":"","sources":["../../../src/router/integration/directives.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAG9B,mKAAmK;AACnK;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAUxE;AAED,8LAA8L;AAC9L;;;GAGG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,iBAAsB,GAC9B,IAAI,CAsEN;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wBAAwB;IACxB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,8JAA8J;AAC9J;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAuBlE"}