@rangojs/router 0.0.0-experimental.0f44aca1

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 (305) hide show
  1. package/AGENTS.md +5 -0
  2. package/README.md +899 -0
  3. package/dist/bin/rango.js +1601 -0
  4. package/dist/vite/index.js +5214 -0
  5. package/package.json +176 -0
  6. package/skills/breadcrumbs/SKILL.md +250 -0
  7. package/skills/cache-guide/SKILL.md +262 -0
  8. package/skills/caching/SKILL.md +220 -0
  9. package/skills/composability/SKILL.md +172 -0
  10. package/skills/debug-manifest/SKILL.md +112 -0
  11. package/skills/document-cache/SKILL.md +182 -0
  12. package/skills/fonts/SKILL.md +167 -0
  13. package/skills/hooks/SKILL.md +704 -0
  14. package/skills/host-router/SKILL.md +218 -0
  15. package/skills/intercept/SKILL.md +313 -0
  16. package/skills/layout/SKILL.md +310 -0
  17. package/skills/links/SKILL.md +239 -0
  18. package/skills/loader/SKILL.md +596 -0
  19. package/skills/middleware/SKILL.md +339 -0
  20. package/skills/mime-routes/SKILL.md +128 -0
  21. package/skills/parallel/SKILL.md +305 -0
  22. package/skills/prerender/SKILL.md +643 -0
  23. package/skills/rango/SKILL.md +118 -0
  24. package/skills/response-routes/SKILL.md +411 -0
  25. package/skills/route/SKILL.md +385 -0
  26. package/skills/router-setup/SKILL.md +439 -0
  27. package/skills/tailwind/SKILL.md +129 -0
  28. package/skills/theme/SKILL.md +79 -0
  29. package/skills/typesafety/SKILL.md +623 -0
  30. package/skills/use-cache/SKILL.md +324 -0
  31. package/src/__internal.ts +273 -0
  32. package/src/bin/rango.ts +321 -0
  33. package/src/browser/action-coordinator.ts +97 -0
  34. package/src/browser/action-response-classifier.ts +99 -0
  35. package/src/browser/event-controller.ts +899 -0
  36. package/src/browser/history-state.ts +80 -0
  37. package/src/browser/index.ts +18 -0
  38. package/src/browser/intercept-utils.ts +52 -0
  39. package/src/browser/link-interceptor.ts +141 -0
  40. package/src/browser/logging.ts +55 -0
  41. package/src/browser/merge-segment-loaders.ts +134 -0
  42. package/src/browser/navigation-bridge.ts +645 -0
  43. package/src/browser/navigation-client.ts +215 -0
  44. package/src/browser/navigation-store.ts +806 -0
  45. package/src/browser/navigation-transaction.ts +295 -0
  46. package/src/browser/network-error-handler.ts +61 -0
  47. package/src/browser/partial-update.ts +550 -0
  48. package/src/browser/prefetch/cache.ts +146 -0
  49. package/src/browser/prefetch/fetch.ts +135 -0
  50. package/src/browser/prefetch/observer.ts +65 -0
  51. package/src/browser/prefetch/policy.ts +42 -0
  52. package/src/browser/prefetch/queue.ts +88 -0
  53. package/src/browser/rango-state.ts +112 -0
  54. package/src/browser/react/Link.tsx +360 -0
  55. package/src/browser/react/NavigationProvider.tsx +386 -0
  56. package/src/browser/react/ScrollRestoration.tsx +94 -0
  57. package/src/browser/react/context.ts +59 -0
  58. package/src/browser/react/filter-segment-order.ts +11 -0
  59. package/src/browser/react/index.ts +52 -0
  60. package/src/browser/react/location-state-shared.ts +162 -0
  61. package/src/browser/react/location-state.ts +107 -0
  62. package/src/browser/react/mount-context.ts +37 -0
  63. package/src/browser/react/nonce-context.ts +23 -0
  64. package/src/browser/react/shallow-equal.ts +27 -0
  65. package/src/browser/react/use-action.ts +218 -0
  66. package/src/browser/react/use-client-cache.ts +58 -0
  67. package/src/browser/react/use-handle.ts +162 -0
  68. package/src/browser/react/use-href.tsx +40 -0
  69. package/src/browser/react/use-link-status.ts +135 -0
  70. package/src/browser/react/use-mount.ts +31 -0
  71. package/src/browser/react/use-navigation.ts +99 -0
  72. package/src/browser/react/use-params.ts +65 -0
  73. package/src/browser/react/use-pathname.ts +47 -0
  74. package/src/browser/react/use-router.ts +63 -0
  75. package/src/browser/react/use-search-params.ts +56 -0
  76. package/src/browser/react/use-segments.ts +171 -0
  77. package/src/browser/response-adapter.ts +73 -0
  78. package/src/browser/rsc-router.tsx +431 -0
  79. package/src/browser/scroll-restoration.ts +400 -0
  80. package/src/browser/segment-reconciler.ts +216 -0
  81. package/src/browser/segment-structure-assert.ts +83 -0
  82. package/src/browser/server-action-bridge.ts +667 -0
  83. package/src/browser/shallow.ts +40 -0
  84. package/src/browser/types.ts +538 -0
  85. package/src/browser/validate-redirect-origin.ts +29 -0
  86. package/src/build/generate-manifest.ts +438 -0
  87. package/src/build/generate-route-types.ts +36 -0
  88. package/src/build/index.ts +35 -0
  89. package/src/build/route-trie.ts +265 -0
  90. package/src/build/route-types/ast-helpers.ts +25 -0
  91. package/src/build/route-types/ast-route-extraction.ts +98 -0
  92. package/src/build/route-types/codegen.ts +102 -0
  93. package/src/build/route-types/include-resolution.ts +411 -0
  94. package/src/build/route-types/param-extraction.ts +48 -0
  95. package/src/build/route-types/per-module-writer.ts +128 -0
  96. package/src/build/route-types/router-processing.ts +469 -0
  97. package/src/build/route-types/scan-filter.ts +78 -0
  98. package/src/build/runtime-discovery.ts +231 -0
  99. package/src/cache/background-task.ts +34 -0
  100. package/src/cache/cache-key-utils.ts +44 -0
  101. package/src/cache/cache-policy.ts +125 -0
  102. package/src/cache/cache-runtime.ts +338 -0
  103. package/src/cache/cache-scope.ts +382 -0
  104. package/src/cache/cf/cf-cache-store.ts +540 -0
  105. package/src/cache/cf/index.ts +25 -0
  106. package/src/cache/document-cache.ts +369 -0
  107. package/src/cache/handle-capture.ts +81 -0
  108. package/src/cache/handle-snapshot.ts +41 -0
  109. package/src/cache/index.ts +43 -0
  110. package/src/cache/memory-segment-store.ts +328 -0
  111. package/src/cache/profile-registry.ts +73 -0
  112. package/src/cache/read-through-swr.ts +134 -0
  113. package/src/cache/segment-codec.ts +256 -0
  114. package/src/cache/taint.ts +98 -0
  115. package/src/cache/types.ts +342 -0
  116. package/src/client.rsc.tsx +85 -0
  117. package/src/client.tsx +601 -0
  118. package/src/component-utils.ts +76 -0
  119. package/src/components/DefaultDocument.tsx +27 -0
  120. package/src/context-var.ts +86 -0
  121. package/src/debug.ts +243 -0
  122. package/src/default-error-boundary.tsx +88 -0
  123. package/src/deps/browser.ts +8 -0
  124. package/src/deps/html-stream-client.ts +2 -0
  125. package/src/deps/html-stream-server.ts +2 -0
  126. package/src/deps/rsc.ts +10 -0
  127. package/src/deps/ssr.ts +2 -0
  128. package/src/errors.ts +365 -0
  129. package/src/handle.ts +135 -0
  130. package/src/handles/MetaTags.tsx +246 -0
  131. package/src/handles/breadcrumbs.ts +66 -0
  132. package/src/handles/index.ts +7 -0
  133. package/src/handles/meta.ts +264 -0
  134. package/src/host/cookie-handler.ts +165 -0
  135. package/src/host/errors.ts +97 -0
  136. package/src/host/index.ts +53 -0
  137. package/src/host/pattern-matcher.ts +214 -0
  138. package/src/host/router.ts +352 -0
  139. package/src/host/testing.ts +79 -0
  140. package/src/host/types.ts +146 -0
  141. package/src/host/utils.ts +25 -0
  142. package/src/href-client.ts +222 -0
  143. package/src/index.rsc.ts +233 -0
  144. package/src/index.ts +277 -0
  145. package/src/internal-debug.ts +11 -0
  146. package/src/loader.rsc.ts +89 -0
  147. package/src/loader.ts +64 -0
  148. package/src/network-error-thrower.tsx +23 -0
  149. package/src/outlet-context.ts +15 -0
  150. package/src/outlet-provider.tsx +45 -0
  151. package/src/prerender/param-hash.ts +37 -0
  152. package/src/prerender/store.ts +185 -0
  153. package/src/prerender.ts +463 -0
  154. package/src/reverse.ts +330 -0
  155. package/src/root-error-boundary.tsx +289 -0
  156. package/src/route-content-wrapper.tsx +196 -0
  157. package/src/route-definition/dsl-helpers.ts +934 -0
  158. package/src/route-definition/helper-factories.ts +200 -0
  159. package/src/route-definition/helpers-types.ts +430 -0
  160. package/src/route-definition/index.ts +52 -0
  161. package/src/route-definition/redirect.ts +93 -0
  162. package/src/route-definition.ts +1 -0
  163. package/src/route-map-builder.ts +275 -0
  164. package/src/route-name.ts +53 -0
  165. package/src/route-types.ts +259 -0
  166. package/src/router/content-negotiation.ts +116 -0
  167. package/src/router/debug-manifest.ts +72 -0
  168. package/src/router/error-handling.ts +287 -0
  169. package/src/router/find-match.ts +158 -0
  170. package/src/router/handler-context.ts +451 -0
  171. package/src/router/intercept-resolution.ts +395 -0
  172. package/src/router/lazy-includes.ts +234 -0
  173. package/src/router/loader-resolution.ts +420 -0
  174. package/src/router/logging.ts +248 -0
  175. package/src/router/manifest.ts +267 -0
  176. package/src/router/match-api.ts +620 -0
  177. package/src/router/match-context.ts +266 -0
  178. package/src/router/match-handlers.ts +440 -0
  179. package/src/router/match-middleware/background-revalidation.ts +223 -0
  180. package/src/router/match-middleware/cache-lookup.ts +634 -0
  181. package/src/router/match-middleware/cache-store.ts +295 -0
  182. package/src/router/match-middleware/index.ts +81 -0
  183. package/src/router/match-middleware/intercept-resolution.ts +306 -0
  184. package/src/router/match-middleware/segment-resolution.ts +192 -0
  185. package/src/router/match-pipelines.ts +179 -0
  186. package/src/router/match-result.ts +219 -0
  187. package/src/router/metrics.ts +282 -0
  188. package/src/router/middleware-cookies.ts +55 -0
  189. package/src/router/middleware-types.ts +222 -0
  190. package/src/router/middleware.ts +748 -0
  191. package/src/router/pattern-matching.ts +563 -0
  192. package/src/router/prerender-match.ts +402 -0
  193. package/src/router/preview-match.ts +170 -0
  194. package/src/router/revalidation.ts +289 -0
  195. package/src/router/router-context.ts +316 -0
  196. package/src/router/router-interfaces.ts +452 -0
  197. package/src/router/router-options.ts +592 -0
  198. package/src/router/router-registry.ts +24 -0
  199. package/src/router/segment-resolution/fresh.ts +570 -0
  200. package/src/router/segment-resolution/helpers.ts +263 -0
  201. package/src/router/segment-resolution/loader-cache.ts +198 -0
  202. package/src/router/segment-resolution/revalidation.ts +1239 -0
  203. package/src/router/segment-resolution/static-store.ts +67 -0
  204. package/src/router/segment-resolution.ts +21 -0
  205. package/src/router/segment-wrappers.ts +289 -0
  206. package/src/router/telemetry-otel.ts +299 -0
  207. package/src/router/telemetry.ts +300 -0
  208. package/src/router/timeout.ts +148 -0
  209. package/src/router/trie-matching.ts +239 -0
  210. package/src/router/types.ts +170 -0
  211. package/src/router.ts +1002 -0
  212. package/src/rsc/handler-context.ts +45 -0
  213. package/src/rsc/handler.ts +1089 -0
  214. package/src/rsc/helpers.ts +198 -0
  215. package/src/rsc/index.ts +36 -0
  216. package/src/rsc/loader-fetch.ts +209 -0
  217. package/src/rsc/manifest-init.ts +86 -0
  218. package/src/rsc/nonce.ts +32 -0
  219. package/src/rsc/origin-guard.ts +141 -0
  220. package/src/rsc/progressive-enhancement.ts +379 -0
  221. package/src/rsc/response-error.ts +37 -0
  222. package/src/rsc/response-route-handler.ts +347 -0
  223. package/src/rsc/rsc-rendering.ts +235 -0
  224. package/src/rsc/runtime-warnings.ts +42 -0
  225. package/src/rsc/server-action.ts +348 -0
  226. package/src/rsc/ssr-setup.ts +128 -0
  227. package/src/rsc/types.ts +263 -0
  228. package/src/search-params.ts +230 -0
  229. package/src/segment-system.tsx +454 -0
  230. package/src/server/context.ts +591 -0
  231. package/src/server/cookie-store.ts +190 -0
  232. package/src/server/fetchable-loader-store.ts +37 -0
  233. package/src/server/handle-store.ts +308 -0
  234. package/src/server/loader-registry.ts +133 -0
  235. package/src/server/request-context.ts +914 -0
  236. package/src/server/root-layout.tsx +10 -0
  237. package/src/server/tsconfig.json +14 -0
  238. package/src/server.ts +51 -0
  239. package/src/ssr/index.tsx +365 -0
  240. package/src/static-handler.ts +114 -0
  241. package/src/theme/ThemeProvider.tsx +297 -0
  242. package/src/theme/ThemeScript.tsx +61 -0
  243. package/src/theme/constants.ts +62 -0
  244. package/src/theme/index.ts +48 -0
  245. package/src/theme/theme-context.ts +44 -0
  246. package/src/theme/theme-script.ts +155 -0
  247. package/src/theme/types.ts +182 -0
  248. package/src/theme/use-theme.ts +44 -0
  249. package/src/types/boundaries.ts +158 -0
  250. package/src/types/cache-types.ts +198 -0
  251. package/src/types/error-types.ts +192 -0
  252. package/src/types/global-namespace.ts +100 -0
  253. package/src/types/handler-context.ts +687 -0
  254. package/src/types/index.ts +88 -0
  255. package/src/types/loader-types.ts +183 -0
  256. package/src/types/route-config.ts +170 -0
  257. package/src/types/route-entry.ts +102 -0
  258. package/src/types/segments.ts +148 -0
  259. package/src/types.ts +1 -0
  260. package/src/urls/include-helper.ts +197 -0
  261. package/src/urls/index.ts +53 -0
  262. package/src/urls/path-helper-types.ts +339 -0
  263. package/src/urls/path-helper.ts +329 -0
  264. package/src/urls/pattern-types.ts +95 -0
  265. package/src/urls/response-types.ts +106 -0
  266. package/src/urls/type-extraction.ts +372 -0
  267. package/src/urls/urls-function.ts +98 -0
  268. package/src/urls.ts +1 -0
  269. package/src/use-loader.tsx +354 -0
  270. package/src/vite/discovery/bundle-postprocess.ts +184 -0
  271. package/src/vite/discovery/discover-routers.ts +344 -0
  272. package/src/vite/discovery/prerender-collection.ts +385 -0
  273. package/src/vite/discovery/route-types-writer.ts +258 -0
  274. package/src/vite/discovery/self-gen-tracking.ts +47 -0
  275. package/src/vite/discovery/state.ts +110 -0
  276. package/src/vite/discovery/virtual-module-codegen.ts +203 -0
  277. package/src/vite/index.ts +16 -0
  278. package/src/vite/plugin-types.ts +131 -0
  279. package/src/vite/plugins/cjs-to-esm.ts +93 -0
  280. package/src/vite/plugins/client-ref-dedup.ts +115 -0
  281. package/src/vite/plugins/client-ref-hashing.ts +105 -0
  282. package/src/vite/plugins/expose-action-id.ts +365 -0
  283. package/src/vite/plugins/expose-id-utils.ts +287 -0
  284. package/src/vite/plugins/expose-ids/export-analysis.ts +296 -0
  285. package/src/vite/plugins/expose-ids/handler-transform.ts +179 -0
  286. package/src/vite/plugins/expose-ids/loader-transform.ts +74 -0
  287. package/src/vite/plugins/expose-ids/router-transform.ts +110 -0
  288. package/src/vite/plugins/expose-ids/types.ts +45 -0
  289. package/src/vite/plugins/expose-internal-ids.ts +569 -0
  290. package/src/vite/plugins/refresh-cmd.ts +65 -0
  291. package/src/vite/plugins/use-cache-transform.ts +323 -0
  292. package/src/vite/plugins/version-injector.ts +83 -0
  293. package/src/vite/plugins/version-plugin.ts +254 -0
  294. package/src/vite/plugins/version.d.ts +12 -0
  295. package/src/vite/plugins/virtual-entries.ts +123 -0
  296. package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
  297. package/src/vite/rango.ts +510 -0
  298. package/src/vite/router-discovery.ts +785 -0
  299. package/src/vite/utils/ast-handler-extract.ts +517 -0
  300. package/src/vite/utils/banner.ts +36 -0
  301. package/src/vite/utils/bundle-analysis.ts +137 -0
  302. package/src/vite/utils/manifest-utils.ts +70 -0
  303. package/src/vite/utils/package-resolution.ts +121 -0
  304. package/src/vite/utils/prerender-utils.ts +189 -0
  305. package/src/vite/utils/shared-utils.ts +169 -0
@@ -0,0 +1,324 @@
1
+ ---
2
+ name: use-cache
3
+ description: Function-level caching with "use cache" directive for RSC data functions and components
4
+ argument-hint: [profile-name]
5
+ ---
6
+
7
+ # "use cache" Directive
8
+
9
+ Function-level caching for async server functions and RSC components. Caches
10
+ return values with TTL + stale-while-revalidate. Complementary to the route-level
11
+ `cache()` DSL and build-time `Static()`/`Prerender()`.
12
+
13
+ ## Basic Usage
14
+
15
+ ### File-level (all exports cached with default profile)
16
+
17
+ ```typescript
18
+ "use cache";
19
+
20
+ export async function getProducts() {
21
+ return await db.query("SELECT * FROM products");
22
+ }
23
+
24
+ export async function getCategories() {
25
+ return await db.query("SELECT * FROM categories");
26
+ }
27
+ ```
28
+
29
+ ### Function-level (per-function profile)
30
+
31
+ ```typescript
32
+ export async function getProducts() {
33
+ "use cache: short";
34
+ return await db.query("SELECT * FROM products");
35
+ }
36
+
37
+ export async function getCategories() {
38
+ "use cache: long";
39
+ return await db.query("SELECT * FROM categories");
40
+ }
41
+ ```
42
+
43
+ ### RSC component
44
+
45
+ ```typescript
46
+ export async function ProductCard({ id }: { id: string }) {
47
+ "use cache: products"
48
+ const product = await db.query('SELECT * FROM products WHERE id = ?', [id]);
49
+ return <div>{product.name}</div>;
50
+ }
51
+ ```
52
+
53
+ ## Named Cache Profiles
54
+
55
+ Define profiles in createRouter. Profile names map to `"use cache: <name>"` and
56
+ `cache('<name>')` in the DSL.
57
+
58
+ ```typescript
59
+ createRouter({
60
+ cacheProfiles: {
61
+ default: { ttl: 900, swr: 1800 },
62
+ short: { ttl: 60, swr: 120 },
63
+ long: { ttl: 3600, swr: 7200 },
64
+ products: { ttl: 300, swr: 600, tags: ["products"] },
65
+ },
66
+ });
67
+ ```
68
+
69
+ - `"use cache"` (no name) resolves to `default`.
70
+ - `"use cache: short"` resolves to the `short` profile.
71
+ - Unknown profile names throw at build/boot time.
72
+
73
+ ## Cache Key
74
+
75
+ ```
76
+ use-cache:{functionId}:{serializedArgs}
77
+ ```
78
+
79
+ - `functionId` -- stable ID from Vite transform (module path + export name).
80
+ - `serializedArgs` -- non-tainted arguments serialized via RSC `encodeReply()`.
81
+
82
+ Different functions always produce different cache keys, even for the same route.
83
+ This is important for intercepted routes -- the path handler and intercept handler
84
+ each have their own `functionId` and therefore their own cache entries.
85
+
86
+ ## Tainted Arguments (ctx, env, req)
87
+
88
+ Request-scoped objects are branded with `Symbol.for('rango:nocache')` at creation.
89
+ When detected:
90
+
91
+ 1. **Excluded from cache key** -- request-scoped, not meaningful for keying.
92
+ 2. **Handle data captured on miss** -- side effects via `ctx.use(Handle)` are recorded.
93
+ 3. **Handle data replayed on hit** -- restored into the current request's HandleStore.
94
+
95
+ ```typescript
96
+ export async function getProductData(ctx) {
97
+ "use cache: short";
98
+ const breadcrumb = ctx.use(Breadcrumbs);
99
+ breadcrumb({ label: "Products", href: "/products" });
100
+ return await db.query("SELECT * FROM products");
101
+ }
102
+ // On hit: return value restored, breadcrumb replayed.
103
+ ```
104
+
105
+ ## Request-Scoped Guards
106
+
107
+ ### Read Guards
108
+
109
+ `cookies()` and `headers()` **throw** inside a `"use cache"` function because
110
+ per-request values (cookies, headers) are not reflected in the cache key. Without
111
+ this guard, one user's data would be served to another.
112
+
113
+ Extract the value before the cached function and pass it as an argument:
114
+
115
+ ```typescript
116
+ const locale = cookies().get("locale")?.value ?? "en";
117
+ const data = await getCachedData(locale); // locale is now in the cache key
118
+ ```
119
+
120
+ ### Side-Effect Guards
121
+
122
+ These ctx methods **throw** inside a `"use cache"` function because their effects
123
+ are lost on cache hit (the function body is skipped):
124
+
125
+ - `ctx.set()` / `ctx.get()` for passing values to children
126
+ - `ctx.header()`
127
+ - `ctx.setTheme()`
128
+ - `ctx.setLocationState()`
129
+ - `ctx.onResponse()`
130
+
131
+ The error message recommends two alternatives:
132
+
133
+ 1. Extract the data fetch into a separate cached function and call ctx methods outside it.
134
+ 2. Use the route-level `cache()` DSL which caches all segments together.
135
+
136
+ **`ctx.use(Handle)` is NOT guarded** -- handle push is captured on miss and replayed
137
+ on hit. This is the correct way to pass data from cached functions.
138
+
139
+ ### Pattern: Separate cached function from ctx side effects
140
+
141
+ ```typescript
142
+ // Cached data fetch (pure)
143
+ async function getNavData() {
144
+ "use cache: short"
145
+ return await db.query('SELECT * FROM nav_items');
146
+ }
147
+
148
+ // Handler (uncached, calls ctx methods freely)
149
+ async function NavLayout(ctx) {
150
+ const navData = await getNavData();
151
+ ctx.set("navItems", navData); // Works -- outside "use cache"
152
+ return <Nav items={navData}><Outlet /></Nav>;
153
+ }
154
+ ```
155
+
156
+ ## Misuse Guards
157
+
158
+ ### Cannot use as middleware
159
+
160
+ Cached functions cannot be passed to `middleware()`. Middleware runs on every
161
+ request (onion model) and must not be cached.
162
+
163
+ ```typescript
164
+ // WRONG -- throws at boot time
165
+ middleware(cachedFn);
166
+
167
+ // RIGHT -- call cached function inside middleware
168
+ middleware(async (ctx, next) => {
169
+ const data = await getCachedData();
170
+ ctx.set("data", data);
171
+ await next();
172
+ });
173
+ ```
174
+
175
+ ### Cannot use as Static() handler
176
+
177
+ Static handlers render once at build time. `"use cache"` is redundant.
178
+
179
+ ```typescript
180
+ // WRONG -- throws at boot time
181
+ export const Page = Static(cachedFn);
182
+
183
+ // RIGHT -- remove "use cache", Static already caches
184
+ export const Page = Static(async (ctx) => {
185
+ return <div>Built once</div>;
186
+ });
187
+ ```
188
+
189
+ ### Cannot use as Prerender() handler or getParams
190
+
191
+ Prerender handlers render at build time. `"use cache"` is redundant.
192
+
193
+ ```typescript
194
+ // WRONG -- throws at boot time (handler)
195
+ export const Page = Prerender(getParams, cachedFn);
196
+
197
+ // WRONG -- throws at boot time (getParams)
198
+ export const Page = Prerender(cachedGetParams, handler);
199
+
200
+ // RIGHT -- remove "use cache"
201
+ export const Page = Prerender(
202
+ async () => [{ slug: "a" }],
203
+ async (ctx) => <Page slug={ctx.params.slug} />,
204
+ );
205
+ ```
206
+
207
+ ## Performance: waitUntil
208
+
209
+ On cache miss, the function executes and the result is serialized inline (blocking).
210
+ The cache **store write** (`setItem`) is deferred to `waitUntil` and does NOT block
211
+ the response.
212
+
213
+ On stale hit, stale data is returned immediately. Background revalidation (re-execute
214
+
215
+ - store) runs entirely inside `waitUntil`.
216
+
217
+ | Phase | Blocks response? |
218
+ | ------------------------------------ | ---------------- |
219
+ | Function execution (miss) | Yes |
220
+ | Result serialization (miss) | Yes |
221
+ | Cache store write (miss) | No (waitUntil) |
222
+ | Stale value return (stale hit) | No (immediate) |
223
+ | Background revalidation (stale) | No (waitUntil) |
224
+ | Cache lookup + deserialization (hit) | Yes (fast) |
225
+
226
+ ## Using with Loaders
227
+
228
+ `"use cache"` works inside loaders. The loader runs every request, but the inner
229
+ cached function returns cached data:
230
+
231
+ ```typescript
232
+ // Cached data function
233
+ export async function getProductData(slug: string) {
234
+ "use cache";
235
+ return await db.query("SELECT * FROM products WHERE slug = ?", [slug]);
236
+ }
237
+
238
+ // Loader runs every request, but inner call is cached
239
+ export const ProductLoader = createLoader(async (ctx) => {
240
+ return getProductData(ctx.params.slug);
241
+ });
242
+ ```
243
+
244
+ ## Using with Intercepted Routes
245
+
246
+ Path handlers and intercept handlers have different `functionId` values from the
247
+ Vite transform, so they naturally get distinct cache entries even for the same URL:
248
+
249
+ ```typescript
250
+ // Path handler -- cached separately
251
+ path("/product/:id", async (ctx) => {
252
+ "use cache"
253
+ return <FullProductPage id={ctx.params.id} />;
254
+ }),
255
+
256
+ // Intercept handler -- cached separately (different functionId)
257
+ intercept("@modal", ".product", async (ctx) => {
258
+ "use cache"
259
+ return <ProductModal id={ctx.params.id} />;
260
+ }),
261
+ ```
262
+
263
+ ## Vite Transform
264
+
265
+ The `rango:use-cache` Vite plugin detects the directive and wraps exports with
266
+ `registerCachedFunction()`:
267
+
268
+ ```typescript
269
+ // Input
270
+ "use cache"
271
+ export async function getProducts() { ... }
272
+
273
+ // Output
274
+ import { registerCachedFunction } from '@rangojs/router/cache-runtime';
275
+ export const getProducts = registerCachedFunction(
276
+ async function getProducts() { ... },
277
+ "src/data/products.ts#getProducts",
278
+ "default"
279
+ );
280
+ ```
281
+
282
+ Function-level directives are hoisted:
283
+
284
+ ```typescript
285
+ // Input
286
+ export async function getProducts() {
287
+ "use cache: short";
288
+ return await db.query("...");
289
+ }
290
+
291
+ // Output
292
+ const __rango_cached_getProducts = registerCachedFunction(
293
+ async function getProducts() {
294
+ return await db.query("...");
295
+ },
296
+ "src/data/products.ts#getProducts",
297
+ "short",
298
+ );
299
+ export async function getProducts() {
300
+ return __rango_cached_getProducts();
301
+ }
302
+ ```
303
+
304
+ ## Backing Store
305
+
306
+ Writes to the same `SegmentCacheStore` as `cache()` DSL, `Static()`, and `Prerender()`.
307
+ One store, one configuration, one invalidation API. Tag-based invalidation
308
+ (`revalidateTag`) works across all mechanisms.
309
+
310
+ ## Interaction with Other Caching
311
+
312
+ | Mechanism | Granularity | When | Use case |
313
+ | ------------------ | ------------------ | ---------- | ----------------------------------------------- |
314
+ | `"use cache"` | Function/component | Runtime | Cache individual data fetches or components |
315
+ | `cache()` DSL | Route segment | Runtime | Cache entire route subtrees with children |
316
+ | `cache('profile')` | Route segment | Runtime | Same as cache() with a named profile |
317
+ | `Static()` | Route segment | Build-time | Render once, never re-render |
318
+ | `Prerender()` | Route segment | Build-time | Pre-render known params, optional live fallback |
319
+
320
+ ## Dev Mode
321
+
322
+ In development, the Vite transform still wraps functions, but the cache store is
323
+ a `MemorySegmentCacheStore` that works locally. Functions cache normally in dev
324
+ for testing cache behavior.
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Internal Types - Implementation Details
3
+ *
4
+ * @internal
5
+ * These types are for internal use only and should not be relied upon by consumers.
6
+ * They may change without notice between versions.
7
+ *
8
+ * If you find yourself needing these types, please open an issue to discuss
9
+ * adding them to the public API.
10
+ */
11
+
12
+ // ============================================================================
13
+ // Segment Resolution (Internal)
14
+ // ============================================================================
15
+
16
+ /**
17
+ * @internal
18
+ * Internal representation of a resolved route segment.
19
+ * Used during route matching and rendering pipeline.
20
+ */
21
+ export type { ResolvedSegment, SegmentMetadata } from "./types.js";
22
+
23
+ /**
24
+ * @internal
25
+ * Internal match result from route resolution.
26
+ */
27
+ export type { MatchResult, SlotState } from "./types.js";
28
+
29
+ // ============================================================================
30
+ // Intercept System (Internal)
31
+ // ============================================================================
32
+
33
+ /**
34
+ * @internal
35
+ * Context for intercept route selection.
36
+ */
37
+ export type {
38
+ InterceptSelectorContext,
39
+ InterceptSegmentsState,
40
+ InterceptWhenFn,
41
+ } from "./server/context.js";
42
+
43
+ // ============================================================================
44
+ // Browser State (Internal)
45
+ // ============================================================================
46
+
47
+ /**
48
+ * @internal
49
+ * RSC protocol payload structure.
50
+ */
51
+ export type { RscPayload, ReactFormState } from "./rsc/types.js";
52
+
53
+ /**
54
+ * @internal
55
+ * Internal navigation store interface.
56
+ */
57
+ export type {
58
+ NavigationStore,
59
+ NavigationBridge,
60
+ RscMetadata,
61
+ ActionResult,
62
+ InflightAction,
63
+ NavigationState,
64
+ TrackedActionState,
65
+ ActionStateListener,
66
+ SegmentCache,
67
+ SegmentState,
68
+ NavigationUpdate,
69
+ } from "./browser/types.js";
70
+
71
+ // ============================================================================
72
+ // Handle System (Internal)
73
+ // ============================================================================
74
+
75
+ /**
76
+ * @internal
77
+ * Internal handle storage mechanism.
78
+ */
79
+ export type { HandleStore, HandleData } from "./server/handle-store.js";
80
+
81
+ /**
82
+ * @internal
83
+ * Segment handle data in cache.
84
+ */
85
+ export type { SegmentHandleData } from "./cache/types.js";
86
+
87
+ // ============================================================================
88
+ // Cache Internals
89
+ // ============================================================================
90
+
91
+ /**
92
+ * @internal
93
+ * Internal cache entry data structure.
94
+ */
95
+ export type {
96
+ CachedEntryData,
97
+ CachedEntryResult,
98
+ CacheGetResult,
99
+ SerializedSegmentData,
100
+ CacheDefaults,
101
+ } from "./cache/types.js";
102
+
103
+ // ============================================================================
104
+ // Router Context (Internal)
105
+ // ============================================================================
106
+
107
+ /**
108
+ * @internal
109
+ * Router context for AsyncLocalStorage.
110
+ */
111
+ export type {
112
+ RouterContext,
113
+ RevalidationContext,
114
+ InterceptResult,
115
+ } from "./router/router-context.js";
116
+
117
+ // ============================================================================
118
+ // Match Pipeline (Internal)
119
+ // ============================================================================
120
+
121
+ /**
122
+ * @internal
123
+ * Route match context during pipeline processing.
124
+ */
125
+ export type {
126
+ MatchContext,
127
+ MatchPipelineState,
128
+ } from "./router/match-context.js";
129
+
130
+ /**
131
+ * @internal
132
+ * Pattern matching result.
133
+ */
134
+ export type { RouteMatchResult } from "./router/pattern-matching.js";
135
+
136
+ // ============================================================================
137
+ // Server Context (Internal)
138
+ // ============================================================================
139
+
140
+ /**
141
+ * @internal
142
+ * Entry data during route traversal.
143
+ */
144
+ export type {
145
+ EntryData,
146
+ InterceptEntry,
147
+ MetricsStore,
148
+ PerformanceMetric,
149
+ EntryCacheConfig,
150
+ EntryPropCommon,
151
+ EntryPropDatas,
152
+ LoaderEntry,
153
+ EntryPropSegments,
154
+ } from "./server/context.js";
155
+
156
+ // ============================================================================
157
+ // Handler Context (Internal)
158
+ // ============================================================================
159
+
160
+ /**
161
+ * @internal
162
+ * Internal handler context with additional props for router internals.
163
+ * Includes `_currentSegmentId` and `_responseType`.
164
+ */
165
+ export type { InternalHandlerContext } from "./types.js";
166
+
167
+ // ============================================================================
168
+ // Rendering (Internal)
169
+ // ============================================================================
170
+
171
+ /**
172
+ * @internal
173
+ * Builds React element trees from route segments.
174
+ */
175
+ export { renderSegments } from "./segment-system.js";
176
+
177
+ // ============================================================================
178
+ // Error Utilities (Internal)
179
+ // ============================================================================
180
+
181
+ /**
182
+ * @internal
183
+ * Error sanitization and network error utilities.
184
+ */
185
+ export { sanitizeError, NetworkError, isNetworkError } from "./errors.js";
186
+
187
+ // ============================================================================
188
+ // Type Utilities (Internal)
189
+ // ============================================================================
190
+
191
+ /**
192
+ * @internal
193
+ * Scoped view of GeneratedRouteMap for Handler<"localName", ScopedRouteMap<"prefix">>.
194
+ */
195
+ export type { ScopedRouteMap } from "./types.js";
196
+
197
+ /**
198
+ * @internal
199
+ * Type-level utilities for reverse URL generation.
200
+ */
201
+ export type { MergeRoutes, SanitizePrefix } from "./reverse.js";
202
+
203
+ /**
204
+ * @internal
205
+ * Individual telemetry event types.
206
+ */
207
+ export type {
208
+ RequestStartEvent,
209
+ RequestEndEvent,
210
+ RequestErrorEvent,
211
+ RequestTimeoutEvent,
212
+ LoaderStartEvent,
213
+ LoaderEndEvent,
214
+ LoaderErrorEvent,
215
+ HandlerErrorEvent,
216
+ CacheDecisionEvent,
217
+ RevalidationDecisionEvent,
218
+ } from "./router/telemetry.js";
219
+
220
+ // ============================================================================
221
+ // Pre-render / Static Handler Guards (Internal)
222
+ // ============================================================================
223
+
224
+ /**
225
+ * @internal
226
+ * Type guard for prerender handler definitions.
227
+ */
228
+ export { isPrerenderHandler } from "./prerender.js";
229
+
230
+ /**
231
+ * @internal
232
+ * Type guard for static handler definitions.
233
+ */
234
+ export { isStaticHandler } from "./static-handler.js";
235
+
236
+ // ============================================================================
237
+ // URL Pattern Internals
238
+ // ============================================================================
239
+
240
+ /**
241
+ * @internal
242
+ * Sentinel used to tag response-type route entries.
243
+ */
244
+ export { RESPONSE_TYPE } from "./urls.js";
245
+
246
+ // ============================================================================
247
+ // Route Match Debug (Internal)
248
+ // ============================================================================
249
+
250
+ /**
251
+ * @internal
252
+ * Debug utilities for route matching performance analysis.
253
+ */
254
+ export {
255
+ enableMatchDebug,
256
+ getMatchDebugStats,
257
+ } from "./router/pattern-matching.js";
258
+
259
+ // ============================================================================
260
+ // Debug Utilities (Internal)
261
+ // ============================================================================
262
+
263
+ /**
264
+ * @internal
265
+ * Debug utilities for manifest inspection and comparison.
266
+ */
267
+ export {
268
+ serializeManifest,
269
+ compareManifests,
270
+ formatManifestDiff,
271
+ type SerializedEntry,
272
+ type SerializedManifest,
273
+ } from "./debug.js";