@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,60 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader.cache",
4
+ "title": "Resource Cache with TTL and Caching Policies",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import type { NavigationId } from '../../core/types';
9
+ import type { CacheOptions } from './index';
10
+ /**
11
+ * Cache key for resource cache
12
+ */
13
+ export interface CacheKey {
14
+ /** Route ID */
15
+ routeId: string;
16
+ /** Serialized params */
17
+ params: string;
18
+ /** Serialized query (for cache key) */
19
+ queryKey: string;
20
+ }
21
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"ResourceCache","stability":"stable","signature":"class ResourceCache"} */
22
+ /**
23
+ * Resource cache with TTL and size limits
24
+ * Implements enhanced prefetch policy & cache layer from architectural improvements
25
+ */
26
+ export declare class ResourceCache {
27
+ private cache;
28
+ private maxSize;
29
+ private defaultTTL;
30
+ /**
31
+ * Create a new resource cache
32
+ * @param maxSize - Maximum number of entries (default: 100)
33
+ * @param defaultTTL - Default time-to-live in milliseconds (default: 300000 = 5 minutes)
34
+ */
35
+ constructor(maxSize?: number, defaultTTL?: number);
36
+ /**
37
+ * Generate cache key from route and parameters
38
+ */
39
+ private generateKey;
40
+ /**
41
+ * Check if cache entry is still valid
42
+ */
43
+ private isValid;
44
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"get","stability":"stable","signature":"<T>(key: CacheKey) => T | null"} */
45
+ /**
46
+ * Get cached data if valid
47
+ */
48
+ get<T>(key: CacheKey): T | null;
49
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"set","stability":"stable","signature":"<T>(key: CacheKey, data: T, navId: NavigationId, options?: CacheOptions) => void"} */
50
+ /**
51
+ * Set cached data with TTL
52
+ */
53
+ set<T>(key: CacheKey, data: T, navId: NavigationId, options?: CacheOptions): void;
54
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"clear","stability":"stable","signature":"() => void"} */
55
+ /**
56
+ * Clear all cached data
57
+ */
58
+ clear(): void;
59
+ }
60
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/router/features/loaders/cache.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAgB5C;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,eAAe;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qIAAqI;AACrI;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;OAIG;gBACS,OAAO,SAAM,EAAE,UAAU,SAAS;IAK9C;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf,sIAAsI;IACtI;;OAEG;IACI,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,CAAC,GAAG,IAAI;IActC,wLAAwL;IACxL;;OAEG;IACI,GAAG,CAAC,CAAC,EACV,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,YAAiB,GACzB,IAAI;IAoBP,oHAAoH;IACpH;;OAEG;IACI,KAAK,IAAI,IAAI;CAGrB"}
@@ -0,0 +1,80 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader.cache",
4
+ "title": "Resource Cache with TTL and Caching Policies",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"ResourceCache","stability":"stable","signature":"class ResourceCache"} */
9
+ /**
10
+ * Resource cache with TTL and size limits
11
+ * Implements enhanced prefetch policy & cache layer from architectural improvements
12
+ */
13
+ export class ResourceCache {
14
+ /**
15
+ * Create a new resource cache
16
+ * @param maxSize - Maximum number of entries (default: 100)
17
+ * @param defaultTTL - Default time-to-live in milliseconds (default: 300000 = 5 minutes)
18
+ */
19
+ constructor(maxSize = 100, defaultTTL = 300000) {
20
+ this.cache = new Map();
21
+ this.maxSize = maxSize;
22
+ this.defaultTTL = defaultTTL;
23
+ }
24
+ /**
25
+ * Generate cache key from route and parameters
26
+ */
27
+ generateKey(key) {
28
+ return `${key.routeId}:${key.params}:${key.queryKey}`;
29
+ }
30
+ /**
31
+ * Check if cache entry is still valid
32
+ */
33
+ isValid(entry) {
34
+ return Date.now() - entry.cachedAt < entry.ttl;
35
+ }
36
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"get","stability":"stable","signature":"<T>(key: CacheKey) => T | null"} */
37
+ /**
38
+ * Get cached data if valid
39
+ */
40
+ get(key) {
41
+ const cacheKey = this.generateKey(key);
42
+ const entry = this.cache.get(cacheKey);
43
+ if (!entry || !this.isValid(entry)) {
44
+ if (entry) {
45
+ this.cache.delete(cacheKey);
46
+ }
47
+ return null;
48
+ }
49
+ return entry.data;
50
+ }
51
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"set","stability":"stable","signature":"<T>(key: CacheKey, data: T, navId: NavigationId, options?: CacheOptions) => void"} */
52
+ /**
53
+ * Set cached data with TTL
54
+ */
55
+ set(key, data, navId, options = {}) {
56
+ const cacheKey = this.generateKey(key);
57
+ const ttl = options.ttl || this.defaultTTL;
58
+ // Enforce size limit by removing oldest entries
59
+ if (this.cache.size >= this.maxSize) {
60
+ const oldestKey = this.cache.keys().next().value;
61
+ if (oldestKey) {
62
+ this.cache.delete(oldestKey);
63
+ }
64
+ }
65
+ this.cache.set(cacheKey, {
66
+ data,
67
+ cachedAt: Date.now(),
68
+ ttl,
69
+ navId,
70
+ });
71
+ }
72
+ /** @codexApi {"parent":"pithy.router.loader.cache","name":"clear","stability":"stable","signature":"() => void"} */
73
+ /**
74
+ * Clear all cached data
75
+ */
76
+ clear() {
77
+ this.cache.clear();
78
+ }
79
+ }
80
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../../src/router/features/loaders/cache.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AA+BF,qIAAqI;AACrI;;;GAGG;AACH,MAAM,OAAO,aAAa;IAKxB;;;;OAIG;IACH,YAAY,OAAO,GAAG,GAAG,EAAE,UAAU,GAAG,MAAM;QATtC,UAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;QAU5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,GAAa;QAC/B,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACK,OAAO,CAAC,KAAiB;QAC/B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC;IACjD,CAAC;IAED,sIAAsI;IACtI;;OAEG;IACI,GAAG,CAAI,GAAa;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,IAAS,CAAC;IACzB,CAAC;IAED,wLAAwL;IACxL;;OAEG;IACI,GAAG,CACR,GAAa,EACb,IAAO,EACP,KAAmB,EACnB,UAAwB,EAAE;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC;QAE3C,gDAAgD;QAChD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YACjD,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE;YACvB,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;YACpB,GAAG;YACH,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,oHAAoH;IACpH;;OAEG;IACI,KAAK;QACV,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader.engine",
4
+ "title": "Pure Loader Execution Engine Utilities",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import type { QueryParams } from '../../core/types';
9
+ import { combineAbortSignals } from '../../core/utils';
10
+ /** @codexApi {"parent":"pithy.router.loader.engine","name":"generateQueryKey","stability":"stable","signature":"(query: QueryParams) => string"} */
11
+ /**
12
+ * Generate query key for caching (stable sort for consistent keys)
13
+ * Pure function extracted from LoaderManager
14
+ */
15
+ export declare function generateQueryKey(query: QueryParams): string;
16
+ export { combineAbortSignals };
17
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../src/router/features/loaders/engine.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,oJAAoJ;AACpJ;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAU3D;AAGD,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader.engine",
4
+ "title": "Pure Loader Execution Engine Utilities",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import { combineAbortSignals } from '../../core/utils';
9
+ /** @codexApi {"parent":"pithy.router.loader.engine","name":"generateQueryKey","stability":"stable","signature":"(query: QueryParams) => string"} */
10
+ /**
11
+ * Generate query key for caching (stable sort for consistent keys)
12
+ * Pure function extracted from LoaderManager
13
+ */
14
+ export function generateQueryKey(query) {
15
+ const keys = Object.keys(query).sort();
16
+ const pairs = keys.map(key => {
17
+ const value = query[key];
18
+ if (Array.isArray(value)) {
19
+ return `${key}=${value.sort().join(',')}`;
20
+ }
21
+ return `${key}=${value}`;
22
+ });
23
+ return pairs.join('&');
24
+ }
25
+ // Re-export combineAbortSignals for backward compatibility
26
+ export { combineAbortSignals };
27
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../../src/router/features/loaders/engine.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAGF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,oJAAoJ;AACpJ;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,2DAA2D;AAC3D,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,49 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader",
4
+ "title": "Route Loader System with ResourceCache",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import type { LoaderContext, LoaderFunction, ResourceState, CacheStrategy, RouteCacheOptions } from '../../core/types';
9
+ import { ResourceCache } from './cache';
10
+ export type { LoaderContext, LoaderFunction, ResourceState, CacheStrategy, RouteCacheOptions, };
11
+ /** @codexApi {"parent":"pithy.router.loader","name":"CacheOptions","stability":"stable","signature":"interface CacheOptions","description":"Cache configuration with TTL and strategy for route loaders"} */
12
+ /**
13
+ * Cache configuration options for route loaders
14
+ * Controls caching behavior with TTL and strategy settings
15
+ */
16
+ export interface CacheOptions {
17
+ /** Time-to-live in milliseconds */
18
+ ttl?: number;
19
+ /** Cache strategy */
20
+ strategy?: CacheStrategy;
21
+ }
22
+ export { ResourceCache, type CacheKey } from './cache';
23
+ /** @codexApi {"parent":"pithy.router.loader","name":"LoaderManager","stability":"stable","signature":"class LoaderManager","description":"Manages route loaders with caching and cancellation support"} */
24
+ /**
25
+ * Loader manager for handling route loaders with caching and cancellation
26
+ */
27
+ export declare class LoaderManager {
28
+ private activeLoaders;
29
+ /** @codexApi {"parent":"pithy.router.loader","name":"executeLoader","stability":"stable","signature":"<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions) => Promise<T>","description":"Execute a loader with caching and cancellation support"} */
30
+ /**
31
+ * Execute a loader with caching and cancellation support
32
+ */
33
+ executeLoader<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions): Promise<T>;
34
+ /**
35
+ * Revalidate cached data in background for stale-while-revalidate
36
+ */
37
+ private revalidateInBackground;
38
+ }
39
+ /** @codexApi {"parent":"pithy.router.loader","name":"executeRouteLoader","stability":"stable","signature":"<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions) => Promise<T>","description":"Execute a route loader with caching and cancellation via global manager"} */
40
+ /**
41
+ * Execute a route loader with caching and cancellation
42
+ */
43
+ export declare function executeRouteLoader<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions): Promise<T>;
44
+ /** @codexApi {"parent":"pithy.router.loader","name":"getResourceCache","stability":"stable","signature":"() => ResourceCache","description":"Get the global resource cache instance"} */
45
+ /**
46
+ * Get the global resource cache
47
+ */
48
+ export declare function getResourceCache(): ResourceCache;
49
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/router/features/loaders/index.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAiB,MAAM,SAAS,CAAC;AAGvD,YAAY,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,iBAAiB,GAClB,CAAC;AAEF,6MAA6M;AAC7M;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAGD,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAOvD,2MAA2M;AAC3M;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,aAAa,CAAsC;IAE3D,gSAAgS;IAChS;;OAEG;IACU,aAAa,CAAC,CAAC,EAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC;IAiEb;;OAEG;YACW,sBAAsB;CAiBrC;AAOD,sTAAsT;AACtT;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EACzB,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED,yLAAyL;AACzL;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD"}
@@ -0,0 +1,112 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.loader",
4
+ "title": "Route Loader System with ResourceCache",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import { generateQueryKey, combineAbortSignals } from './engine';
9
+ import { ResourceCache } from './cache';
10
+ // Re-export ResourceCache and CacheKey from cache module
11
+ export { ResourceCache } from './cache';
12
+ /**
13
+ * Global resource cache instance
14
+ */
15
+ const globalResourceCache = new ResourceCache();
16
+ /** @codexApi {"parent":"pithy.router.loader","name":"LoaderManager","stability":"stable","signature":"class LoaderManager","description":"Manages route loaders with caching and cancellation support"} */
17
+ /**
18
+ * Loader manager for handling route loaders with caching and cancellation
19
+ */
20
+ export class LoaderManager {
21
+ constructor() {
22
+ this.activeLoaders = new Map();
23
+ }
24
+ /** @codexApi {"parent":"pithy.router.loader","name":"executeLoader","stability":"stable","signature":"<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions) => Promise<T>","description":"Execute a loader with caching and cancellation support"} */
25
+ /**
26
+ * Execute a loader with caching and cancellation support
27
+ */
28
+ async executeLoader(routeId, loader, context, options = {}) {
29
+ const { params, query, signal, navId } = context;
30
+ // Generate cache key
31
+ const cacheKey = {
32
+ routeId,
33
+ params: JSON.stringify(params),
34
+ queryKey: generateQueryKey(query),
35
+ };
36
+ // Check cache first (unless no-store)
37
+ if (options.strategy !== 'no-store') {
38
+ const cached = globalResourceCache.get(cacheKey);
39
+ if (cached !== null) {
40
+ // For stale-while-revalidate, return cached data but revalidate in background
41
+ if (options.strategy === 'swr') {
42
+ this.revalidateInBackground(routeId, loader, context, cacheKey, options);
43
+ }
44
+ return cached;
45
+ }
46
+ }
47
+ // Cancel any existing loader for this route
48
+ const existingController = this.activeLoaders.get(routeId);
49
+ if (existingController) {
50
+ existingController.abort();
51
+ }
52
+ // Create new abort controller for this loader
53
+ const loaderController = new AbortController();
54
+ this.activeLoaders.set(routeId, loaderController);
55
+ // Chain abort signals
56
+ const combinedSignal = combineAbortSignals([
57
+ signal,
58
+ loaderController.signal,
59
+ ]);
60
+ try {
61
+ // Execute loader with combined abort signal
62
+ const loaderContext = {
63
+ ...context,
64
+ signal: combinedSignal,
65
+ };
66
+ const result = await Promise.resolve(loader(loaderContext));
67
+ // Cache result if successful and not aborted
68
+ if (!combinedSignal.aborted && options.strategy !== 'no-store') {
69
+ globalResourceCache.set(cacheKey, result, navId, options);
70
+ }
71
+ return result;
72
+ }
73
+ finally {
74
+ // Clean up active loader
75
+ this.activeLoaders.delete(routeId);
76
+ }
77
+ }
78
+ /**
79
+ * Revalidate cached data in background for stale-while-revalidate
80
+ */
81
+ async revalidateInBackground(routeId, loader, context, cacheKey, options) {
82
+ try {
83
+ const result = await Promise.resolve(loader(context));
84
+ if (!context.signal.aborted) {
85
+ globalResourceCache.set(cacheKey, result, context.navId, options);
86
+ }
87
+ }
88
+ catch (error) {
89
+ // Silently fail background revalidation
90
+ console.warn('Background revalidation failed:', error);
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Global loader manager instance
96
+ */
97
+ const globalLoaderManager = new LoaderManager();
98
+ /** @codexApi {"parent":"pithy.router.loader","name":"executeRouteLoader","stability":"stable","signature":"<T>(routeId: string, loader: LoaderFunction<T>, context: LoaderContext, options?: CacheOptions) => Promise<T>","description":"Execute a route loader with caching and cancellation via global manager"} */
99
+ /**
100
+ * Execute a route loader with caching and cancellation
101
+ */
102
+ export async function executeRouteLoader(routeId, loader, context, options) {
103
+ return globalLoaderManager.executeLoader(routeId, loader, context, options);
104
+ }
105
+ /** @codexApi {"parent":"pithy.router.loader","name":"getResourceCache","stability":"stable","signature":"() => ResourceCache","description":"Get the global resource cache instance"} */
106
+ /**
107
+ * Get the global resource cache
108
+ */
109
+ export function getResourceCache() {
110
+ return globalResourceCache;
111
+ }
112
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/router/features/loaders/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /** @codex
2
+ {
3
+ "id": "pithy.router.features.loading-ui",
4
+ "title": "Loading UI Manager - Atomic Swap and Overlay Loading States",
5
+ "category": "runtime"
6
+ }
7
+ */
8
+ import type { NavigationId, RouteNode } from '../core/types';
9
+ /**
10
+ * Loading UI Manager
11
+ * Handles atomic swap, overlay, and progress-only loading policies
12
+ *
13
+ * Supports two loading strategies:
14
+ * 1. Atomic Swap - Replace entire outlet content with loading UI
15
+ * 2. Overlay - Show loading UI on top of existing content
16
+ *
17
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"LoadingUIManager","stability":"stable","signature":"class LoadingUIManager"}
18
+ */
19
+ export declare class LoadingUIManager {
20
+ private outletSnapshot;
21
+ private mountedElement;
22
+ /**
23
+ * Set the mounted element (outlet)
24
+ */
25
+ setMountedElement(element: HTMLElement | null): void;
26
+ /**
27
+ * Show atomic loading UI (replace outlet content)
28
+ * Creates a container with router-loading-atomic class that replaces all outlet content
29
+ *
30
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"showAtomic","stability":"stable","signature":"async showAtomic(pattern: string, navId: NavigationId, outlet: HTMLElement, routes: RouteNode[]): Promise<void>"}
31
+ */
32
+ showAtomic(pattern: string, navId: NavigationId, outlet: HTMLElement, routes: RouteNode[]): Promise<void>;
33
+ /**
34
+ * Show custom overlay loading UI with route-specific content
35
+ *
36
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"showCustomOverlay","stability":"stable","signature":"async showCustomOverlay(pattern: string, navId: NavigationId, outlet: HTMLElement, routes: RouteNode[]): Promise<void>"}
37
+ */
38
+ showCustomOverlay(pattern: string, navId: NavigationId, outlet: HTMLElement, routes: RouteNode[]): Promise<void>;
39
+ /**
40
+ * Internal helper to mount an overlay with content
41
+ * Consolidates overlay creation logic
42
+ */
43
+ private mountOverlay;
44
+ /**
45
+ * Remove loading overlay from outlet
46
+ *
47
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"removeOverlay","stability":"stable","signature":"removeOverlay(outlet: HTMLElement): void"}
48
+ */
49
+ removeOverlay(outlet: HTMLElement): void;
50
+ /**
51
+ * Clear all loading UI from outlet (handles both overlays and atomic swap loading)
52
+ *
53
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"clearAll","stability":"stable","signature":"clearAll(): void"}
54
+ */
55
+ clearAll(): void;
56
+ /**
57
+ * Build default loading content (spinner + "Loading..." text)
58
+ *
59
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"buildDefault","stability":"stable","signature":"buildDefault(): HTMLElement"}
60
+ */
61
+ buildDefault(): HTMLElement;
62
+ /**
63
+ * Build loading content for a specific route (supports many export shapes)
64
+ *
65
+ * @codexApi {"parent":"pithy.router.features.loading-ui","name":"buildForRoute","stability":"stable","signature":"async buildForRoute(pattern: string, routes: RouteNode[]): Promise<HTMLElement>"}
66
+ */
67
+ buildForRoute(pattern: string, routes: RouteNode[]): Promise<HTMLElement>;
68
+ }
69
+ //# sourceMappingURL=loading-ui-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loading-ui-manager.d.ts","sourceRoot":"","sources":["../../../src/router/features/loading-ui-manager.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAY,MAAM,eAAe,CAAC;AAKvE;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,cAAc,CAA4B;IAElD;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAIpD;;;;;OAKG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC;IAiBhB;;;;OAIG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC;IAMhB;;;OAGG;IACH,OAAO,CAAC,YAAY;IA2CpB;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAOxC;;;;OAIG;IACH,QAAQ,IAAI,IAAI;IAoBhB;;;;OAIG;IACH,YAAY,IAAI,WAAW;IA+B3B;;;;OAIG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,EAAE,GAClB,OAAO,CAAC,WAAW,CAAC;CA4CxB"}