@timber-js/app 0.2.0-alpha.158 → 0.2.0-alpha.159

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 (286) hide show
  1. package/dist/_chunks/{actions-BA5tIpVu.js → actions-CBbP1hHO.js} +3 -3
  2. package/dist/_chunks/{actions-BA5tIpVu.js.map → actions-CBbP1hHO.js.map} +1 -1
  3. package/dist/_chunks/{build-output-helper-C8q4Zpf5.js → build-output-helper-DF5uScqS.js} +4 -1
  4. package/dist/_chunks/{build-output-helper-C8q4Zpf5.js.map → build-output-helper-DF5uScqS.js.map} +1 -1
  5. package/dist/_chunks/cache-api-DsWEYwVZ.js +1120 -0
  6. package/dist/_chunks/cache-api-DsWEYwVZ.js.map +1 -0
  7. package/dist/_chunks/{cli-schema-sync-DcmQrzJG.js → cli-schema-sync-Bivx4Rn7.js} +4 -3
  8. package/dist/_chunks/{cli-schema-sync-DcmQrzJG.js.map → cli-schema-sync-Bivx4Rn7.js.map} +1 -1
  9. package/dist/_chunks/dist-BA3u1z3W.js +423 -0
  10. package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
  11. package/dist/_chunks/{logger-C5v1IMuh.js → logger-CrRmZMlo.js} +81 -56
  12. package/dist/_chunks/logger-CrRmZMlo.js.map +1 -0
  13. package/dist/_chunks/{plugin-context-DUl3dnCF.js → plugin-context-DeAxFRMq.js} +3 -36
  14. package/dist/_chunks/plugin-context-DeAxFRMq.js.map +1 -0
  15. package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
  16. package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
  17. package/dist/_chunks/{walkers-D5jCGPum.js → walkers-DXbJkeCY.js} +217 -19
  18. package/dist/_chunks/walkers-DXbJkeCY.js.map +1 -0
  19. package/dist/adapters/build-output-helper.d.ts.map +1 -1
  20. package/dist/adapters/cloudflare.d.ts +28 -0
  21. package/dist/adapters/cloudflare.d.ts.map +1 -1
  22. package/dist/adapters/cloudflare.js +143 -9
  23. package/dist/adapters/cloudflare.js.map +1 -1
  24. package/dist/adapters/nitro.js +1 -1
  25. package/dist/cache/cache-api.d.ts +2 -0
  26. package/dist/cache/cache-api.d.ts.map +1 -1
  27. package/dist/cache/handler-store.d.ts +2 -0
  28. package/dist/cache/handler-store.d.ts.map +1 -1
  29. package/dist/cache/index.d.ts +2 -0
  30. package/dist/cache/index.d.ts.map +1 -1
  31. package/dist/cache/index.js +3 -186
  32. package/dist/cache/redis-handler.d.ts +17 -5
  33. package/dist/cache/redis-handler.d.ts.map +1 -1
  34. package/dist/cache/singleflight.d.ts +1 -1
  35. package/dist/cache/singleflight.d.ts.map +1 -1
  36. package/dist/cache/store.d.ts +53 -0
  37. package/dist/cache/store.d.ts.map +1 -0
  38. package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
  39. package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
  40. package/dist/cache/stores/cloudflare-kv.js +29 -0
  41. package/dist/cache/stores/cloudflare-kv.js.map +1 -0
  42. package/dist/cache/stores/memory.d.ts +42 -0
  43. package/dist/cache/stores/memory.d.ts.map +1 -0
  44. package/dist/cache/stores/memory.js +90 -0
  45. package/dist/cache/stores/memory.js.map +1 -0
  46. package/dist/cache/stores/redis.d.ts +69 -0
  47. package/dist/cache/stores/redis.d.ts.map +1 -0
  48. package/dist/cache/stores/redis.js +35 -0
  49. package/dist/cache/stores/redis.js.map +1 -0
  50. package/dist/cache/stores/vercel.d.ts +36 -0
  51. package/dist/cache/stores/vercel.d.ts.map +1 -0
  52. package/dist/cache/stores/vercel.js +33 -0
  53. package/dist/cache/stores/vercel.js.map +1 -0
  54. package/dist/cache/tag-aware-handler.d.ts +51 -0
  55. package/dist/cache/tag-aware-handler.d.ts.map +1 -0
  56. package/dist/cache/timber-cache.d.ts.map +1 -1
  57. package/dist/cdn/cloudflare-purge.d.ts +23 -0
  58. package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
  59. package/dist/cdn/fastly-purge.d.ts +25 -0
  60. package/dist/cdn/fastly-purge.d.ts.map +1 -0
  61. package/dist/cdn/headers.d.ts +82 -0
  62. package/dist/cdn/headers.d.ts.map +1 -0
  63. package/dist/cdn/index.d.ts +5 -0
  64. package/dist/cdn/index.d.ts.map +1 -0
  65. package/dist/cdn/purge-store.d.ts +23 -0
  66. package/dist/cdn/purge-store.d.ts.map +1 -0
  67. package/dist/cli.js +2 -2
  68. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
  69. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  70. package/dist/client/browser-entry/router-init.d.ts.map +1 -1
  71. package/dist/client/history.d.ts +0 -3
  72. package/dist/client/history.d.ts.map +1 -1
  73. package/dist/client/index.js +0 -1
  74. package/dist/client/index.js.map +1 -1
  75. package/dist/client/internal.js +11 -86
  76. package/dist/client/internal.js.map +1 -1
  77. package/dist/client/navigation-api.d.ts +1 -3
  78. package/dist/client/navigation-api.d.ts.map +1 -1
  79. package/dist/client/router.d.ts +1 -4
  80. package/dist/client/router.d.ts.map +1 -1
  81. package/dist/client/rsc-fetch.d.ts +1 -11
  82. package/dist/client/rsc-fetch.d.ts.map +1 -1
  83. package/dist/client/segment-cache.d.ts +1 -3
  84. package/dist/client/segment-cache.d.ts.map +1 -1
  85. package/dist/client/use-cookie.d.ts.map +1 -1
  86. package/dist/config-types.d.ts +3 -1
  87. package/dist/config-types.d.ts.map +1 -1
  88. package/dist/config-validation.d.ts.map +1 -1
  89. package/dist/cookies/index.js +15 -11
  90. package/dist/cookies/index.js.map +1 -1
  91. package/dist/dev-tools/browser-logs.d.ts +28 -72
  92. package/dist/dev-tools/browser-logs.d.ts.map +1 -1
  93. package/dist/dev-tools/index.d.ts +1 -1
  94. package/dist/dev-tools/index.d.ts.map +1 -1
  95. package/dist/dev-tools/logger.d.ts.map +1 -1
  96. package/dist/dev-tools/terminal.d.ts.map +1 -1
  97. package/dist/fonts/transform.d.ts +4 -0
  98. package/dist/fonts/transform.d.ts.map +1 -1
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +1269 -359
  101. package/dist/index.js.map +1 -1
  102. package/dist/plugin-context.d.ts +36 -0
  103. package/dist/plugin-context.d.ts.map +1 -1
  104. package/dist/plugins/build-report.d.ts +21 -0
  105. package/dist/plugins/build-report.d.ts.map +1 -1
  106. package/dist/plugins/cache.d.ts +5 -14
  107. package/dist/plugins/cache.d.ts.map +1 -1
  108. package/dist/plugins/callsite-ast.d.ts +95 -0
  109. package/dist/plugins/callsite-ast.d.ts.map +1 -0
  110. package/dist/plugins/callsite-jsx.d.ts +35 -0
  111. package/dist/plugins/callsite-jsx.d.ts.map +1 -0
  112. package/dist/plugins/entries.d.ts.map +1 -1
  113. package/dist/plugins/fonts.d.ts.map +1 -1
  114. package/dist/plugins/prebuilt-capture.d.ts +60 -0
  115. package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
  116. package/dist/plugins/prebuilt.d.ts +82 -0
  117. package/dist/plugins/prebuilt.d.ts.map +1 -0
  118. package/dist/plugins/prerender-sugar.d.ts +42 -0
  119. package/dist/plugins/prerender-sugar.d.ts.map +1 -0
  120. package/dist/plugins/server-bundle.d.ts.map +1 -1
  121. package/dist/plugins/shims.d.ts.map +1 -1
  122. package/dist/plugins/static-build.d.ts.map +1 -1
  123. package/dist/routing/convention-lint.d.ts.map +1 -1
  124. package/dist/routing/export-detect.d.ts +56 -0
  125. package/dist/routing/export-detect.d.ts.map +1 -0
  126. package/dist/routing/index.js +2 -2
  127. package/dist/routing/manifest-codegen.d.ts.map +1 -1
  128. package/dist/rsc-runtime/rsc.d.ts +1 -1
  129. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  130. package/dist/server/action-handler.d.ts.map +1 -1
  131. package/dist/server/actions.d.ts +0 -3
  132. package/dist/server/actions.d.ts.map +1 -1
  133. package/dist/server/als-registry.d.ts +7 -0
  134. package/dist/server/als-registry.d.ts.map +1 -1
  135. package/dist/server/cookie-parsing.d.ts +15 -1
  136. package/dist/server/cookie-parsing.d.ts.map +1 -1
  137. package/dist/server/deny-renderer.d.ts.map +1 -1
  138. package/dist/server/html-injectors.d.ts +1 -0
  139. package/dist/server/html-injectors.d.ts.map +1 -1
  140. package/dist/server/index.js +2 -2
  141. package/dist/server/internal.d.ts +6 -1
  142. package/dist/server/internal.d.ts.map +1 -1
  143. package/dist/server/internal.js +563 -74
  144. package/dist/server/internal.js.map +1 -1
  145. package/dist/server/prebuilt/cache-key.d.ts +58 -0
  146. package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
  147. package/dist/server/prebuilt/capture-state.d.ts +57 -0
  148. package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
  149. package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
  150. package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
  151. package/dist/server/prebuilt/overlay.d.ts +100 -0
  152. package/dist/server/prebuilt/overlay.d.ts.map +1 -0
  153. package/dist/server/prebuilt/payload-source.d.ts +75 -0
  154. package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
  155. package/dist/server/prebuilt/synthetic-store.d.ts +64 -0
  156. package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
  157. package/dist/server/prebuilt-builder.d.ts +110 -0
  158. package/dist/server/prebuilt-builder.d.ts.map +1 -0
  159. package/dist/server/prebuilt-runtime.d.ts +101 -0
  160. package/dist/server/prebuilt-runtime.d.ts.map +1 -0
  161. package/dist/server/route-element-builder.d.ts +10 -8
  162. package/dist/server/route-element-builder.d.ts.map +1 -1
  163. package/dist/server/rsc-entry/helpers.d.ts +0 -5
  164. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  165. package/dist/server/rsc-entry/index.d.ts +10 -0
  166. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  167. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  168. package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
  169. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -4
  170. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  171. package/dist/server/sitemap-generator.d.ts +6 -6
  172. package/dist/server/sitemap-generator.d.ts.map +1 -1
  173. package/dist/server/tracing.d.ts +37 -3
  174. package/dist/server/tracing.d.ts.map +1 -1
  175. package/docs/api/32-api-cache.mdx +10 -4
  176. package/docs/learn/00-introduction.mdx +8 -13
  177. package/docs/learn/02-pages-and-layouts.mdx +9 -0
  178. package/docs/learn/06-forms-and-actions.mdx +0 -4
  179. package/docs/learn/07-typed-routes.mdx +127 -0
  180. package/docs/learn/09-caching.mdx +12 -1
  181. package/docs/learn/10-middleware.mdx +1 -0
  182. package/docs/learn/11-error-handling.mdx +9 -0
  183. package/docs/learn/13-configuration.mdx +28 -0
  184. package/docs/learn/14-deploying.mdx +52 -0
  185. package/docs/more/06-instrumentation.mdx +27 -1
  186. package/docs/more/07-security.mdx +8 -2
  187. package/docs/more/08-developer-experience.mdx +134 -0
  188. package/package.json +31 -2
  189. package/src/adapters/build-output-helper.ts +10 -0
  190. package/src/adapters/cloudflare.ts +178 -4
  191. package/src/cache/cache-api.ts +60 -0
  192. package/src/cache/handler-store.ts +8 -0
  193. package/src/cache/index.ts +4 -0
  194. package/src/cache/redis-handler.ts +25 -13
  195. package/src/cache/singleflight.ts +11 -11
  196. package/src/cache/store.ts +71 -0
  197. package/src/cache/stores/cloudflare-kv.ts +52 -0
  198. package/src/cache/stores/memory.ts +125 -0
  199. package/src/cache/stores/redis.ts +97 -0
  200. package/src/cache/stores/vercel.ts +59 -0
  201. package/src/cache/tag-aware-handler.ts +233 -0
  202. package/src/cache/timber-cache.ts +17 -7
  203. package/src/cdn/cloudflare-purge.ts +50 -0
  204. package/src/cdn/fastly-purge.ts +63 -0
  205. package/src/cdn/headers.ts +127 -0
  206. package/src/cdn/index.ts +16 -0
  207. package/src/cdn/purge-store.ts +34 -0
  208. package/src/client/browser-entry/action-dispatch.ts +1 -10
  209. package/src/client/browser-entry/post-hydration.ts +0 -1
  210. package/src/client/browser-entry/router-init.ts +0 -5
  211. package/src/client/history.ts +0 -4
  212. package/src/client/navigation-api.ts +5 -11
  213. package/src/client/router.ts +9 -43
  214. package/src/client/rsc-fetch.ts +5 -27
  215. package/src/client/segment-cache.ts +1 -4
  216. package/src/client/use-cookie.ts +18 -12
  217. package/src/config-types.ts +3 -1
  218. package/src/config-validation.ts +1 -0
  219. package/src/dev-tools/browser-logs.ts +37 -273
  220. package/src/dev-tools/index.ts +2 -2
  221. package/src/dev-tools/instrumentation.ts +1 -1
  222. package/src/dev-tools/logger.ts +33 -51
  223. package/src/dev-tools/terminal.ts +21 -22
  224. package/src/fonts/transform.ts +4 -43
  225. package/src/index.ts +16 -3
  226. package/src/plugin-context.ts +36 -0
  227. package/src/plugins/build-report.ts +133 -1
  228. package/src/plugins/cache.ts +32 -131
  229. package/src/plugins/callsite-ast.ts +167 -0
  230. package/src/plugins/callsite-jsx.ts +243 -0
  231. package/src/plugins/entries.ts +23 -4
  232. package/src/plugins/fonts.ts +16 -2
  233. package/src/plugins/prebuilt-capture.ts +208 -0
  234. package/src/plugins/prebuilt.ts +673 -0
  235. package/src/plugins/prerender-sugar.ts +329 -0
  236. package/src/plugins/server-bundle.ts +12 -0
  237. package/src/plugins/shims.ts +9 -0
  238. package/src/plugins/static-build.ts +0 -1
  239. package/src/routing/codegen.ts +1 -21
  240. package/src/routing/convention-lint.ts +85 -49
  241. package/src/routing/export-detect.ts +304 -0
  242. package/src/routing/manifest-codegen.ts +2 -11
  243. package/src/rsc-runtime/rsc.ts +7 -0
  244. package/src/server/action-handler.ts +11 -27
  245. package/src/server/actions.ts +3 -4
  246. package/src/server/als-registry.ts +7 -0
  247. package/src/server/cookie-parsing.ts +75 -59
  248. package/src/server/deny-renderer.ts +7 -15
  249. package/src/server/html-injectors.ts +11 -3
  250. package/src/server/internal.ts +17 -1
  251. package/src/server/prebuilt/cache-key.ts +224 -0
  252. package/src/server/prebuilt/capture-state.ts +89 -0
  253. package/src/server/prebuilt/manifest-tag-index.ts +46 -0
  254. package/src/server/prebuilt/overlay.ts +256 -0
  255. package/src/server/prebuilt/payload-source.ts +192 -0
  256. package/src/server/prebuilt/synthetic-store.ts +108 -0
  257. package/src/server/prebuilt-builder.ts +640 -0
  258. package/src/server/prebuilt-runtime.ts +706 -0
  259. package/src/server/route-element-builder.ts +40 -12
  260. package/src/server/rsc-entry/helpers.ts +0 -17
  261. package/src/server/rsc-entry/index.ts +83 -0
  262. package/src/server/rsc-entry/render-route.ts +6 -33
  263. package/src/server/rsc-entry/revalidate-renderer.ts +16 -11
  264. package/src/server/rsc-entry/rsc-payload.ts +5 -11
  265. package/src/server/sitemap-generator.ts +16 -10
  266. package/src/server/tracing.ts +88 -3
  267. package/dist/_chunks/cache-api-Cbyh3RW4.js +0 -401
  268. package/dist/_chunks/cache-api-Cbyh3RW4.js.map +0 -1
  269. package/dist/_chunks/logger-C5v1IMuh.js.map +0 -1
  270. package/dist/_chunks/plugin-context-DUl3dnCF.js.map +0 -1
  271. package/dist/_chunks/validation-CnKhGJsp.js +0 -113
  272. package/dist/_chunks/validation-CnKhGJsp.js.map +0 -1
  273. package/dist/_chunks/walkers-D5jCGPum.js.map +0 -1
  274. package/dist/cache/index.js.map +0 -1
  275. package/dist/client/head.d.ts +0 -16
  276. package/dist/client/head.d.ts.map +0 -1
  277. package/dist/client/navigation-api-types.d.ts +0 -90
  278. package/dist/client/navigation-api-types.d.ts.map +0 -1
  279. package/dist/server/client-module-map.d.ts +0 -47
  280. package/dist/server/client-module-map.d.ts.map +0 -1
  281. package/dist/shared/head-header.d.ts +0 -54
  282. package/dist/shared/head-header.d.ts.map +0 -1
  283. package/src/client/head.ts +0 -61
  284. package/src/client/navigation-api-types.ts +0 -112
  285. package/src/server/client-module-map.ts +0 -58
  286. package/src/shared/head-header.ts +0 -69
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Component cache-key hashing for prebuilt (cache.component) entries.
3
+ *
4
+ * Key: `sha256(canonicalJson({ props, params })).slice(0, 16)` — see
5
+ * design/44-render-at-build-time.md §Cache Key. Both the request-time
6
+ * lookup (prebuilt-runtime.ts) and the post-build capture pass (TIM-1119)
7
+ * MUST use this exact function, or build artifacts become unaddressable.
8
+ *
9
+ * THE IDENTITY CONTRACT (design/44 §Cache Key): cache identity is **JSON
10
+ * value semantics** — two inputs are the same entry iff they are the same
11
+ * JSON value. This is an ALLOWLIST, not a denylist: a value participates
12
+ * in caching iff it is plain JSON data — null, boolean, finite number,
13
+ * string, dense array, or a plain `Object.prototype` object with only
14
+ * enumerable string-keyed data properties — plus `undefined` and `-0`,
15
+ * which hash as distinct sentinels because flight preserves them. Every
16
+ * value outside that domain (functions, symbols, bigints, accessors,
17
+ * hidden or symbol-keyed properties, non-`Object.prototype` prototypes
18
+ * including null, aliased references, sparse arrays, cycles, non-finite
19
+ * numbers) is UNKEYABLE by definition: `computeComponentCacheKey` returns
20
+ * null and the caller renders live — slower, never wrong.
21
+ *
22
+ * The line between rejected and declared-out-of-domain: values are
23
+ * REJECTED when the JSON projection itself would be ambiguous or lossy
24
+ * (hidden/symbol/non-enumerable properties, accessors, exotic
25
+ * prototypes). Observable state that leaves the projection intact — key
26
+ * order, reference identity, descriptor metadata (writable/configurable,
27
+ * frozen/sealed/extensible), proxy behavior — is DECLARED outside
28
+ * cache.component's supported input domain rather than rejected:
29
+ * key-order insensitivity is required for determinism, and rejecting
30
+ * frozen objects would unkey ubiquitous legitimate inputs
31
+ * (Object.freeze'd config props) to defend against components that
32
+ * render differently based on property attributes.
33
+ *
34
+ * Two hard rules for this walk itself: it must be TOTAL (never throw
35
+ * anything but UnkeyableValueError) and SIDE-EFFECT-FREE (descriptor
36
+ * reads only; never invoke user code such as getters).
37
+ *
38
+ * Object keys sort recursively so `{a, b}` and `{b, a}` hash identically
39
+ * (design/13-security.md checklist #14 — cache key determinism; key order
40
+ * is deliberately NOT part of identity).
41
+ */
42
+ /**
43
+ * Canonicalize a single value, or null if it is unkeyable. The ONE
44
+ * definition of "faithfully comparable" — every prebuilt code path that
45
+ * needs value equality (cache keys, slot-param divergence) goes through
46
+ * this, so the unkeyable rules (accessors, hidden props, aliases,
47
+ * bigints, …) live in exactly one place.
48
+ */
49
+ export declare function tryCanonicalize(value: unknown): string | null;
50
+ /**
51
+ * Compute the cache-entry hash for a component render:
52
+ * `sha256({props, params}).slice(0, 16)` over canonical JSON.
53
+ *
54
+ * Returns null when props (or params) contain unkeyable values — the
55
+ * caller must fall back to dynamic rendering.
56
+ */
57
+ export declare function computeComponentCacheKey(props: Record<string, unknown>, params: Record<string, string | string[]>): string | null;
58
+ //# sourceMappingURL=cache-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-key.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/cache-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAwGH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAM7D;AAsBD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GACxC,MAAM,GAAG,IAAI,CAkCf"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Build-time capture state — the channel between the post-build capture
3
+ * pass (server/prebuilt-builder.ts) and the `__prebuilt` wrapper
4
+ * (server/prebuilt-runtime.ts).
5
+ *
6
+ * During capture, a wrapped component's subtree may render OTHER wrapped
7
+ * components. With no payload source registered (the capture pass runs
8
+ * before artifacts exist), those inner wrappers render live and their
9
+ * output is baked flat into the outer entry — the nesting clamp of
10
+ * design/45-cache-lifetimes.md §Nesting Semantics (TIM-1136). The capture
11
+ * pass is the designated detection point for that clamp, so the wrapper
12
+ * reports every render that happens while a capture is active:
13
+ *
14
+ * - **Cycle**: the inner wrapper IS the component being captured (directly
15
+ * or transitively — the transitive case still renders the outer's own
16
+ * wrapper, so the identity check catches both). Left alone this recurses
17
+ * until the render times out; instead the wrapper throws
18
+ * `PrebuiltCaptureCycleError`, failing that entry with an error naming
19
+ * the cycle while the build continues (doc 44 skip-and-report policy).
20
+ * - **Nesting**: any other wrapper render is recorded as an (outer, inner)
21
+ * pair. The builder warns after the entry completes when the inner
22
+ * declares a refresh channel the outer cannot honor (doc 45 clamp rule).
23
+ *
24
+ * Captures run strictly sequentially (one entry at a time), so a single
25
+ * module-level slot is sufficient — there is never a second active capture
26
+ * to confuse renders between. At request time `active` is null and
27
+ * `noteWrapperRender` is a single null-check.
28
+ */
29
+ import type { PrebuiltComponentOptions } from '../prebuilt-runtime.js';
30
+ /** A wrapped component that rendered inside an active capture. */
31
+ export interface NestedWrapperRender {
32
+ innerId: string;
33
+ options: PrebuiltComponentOptions;
34
+ }
35
+ /** Thrown by the wrapper when a capture renders its own component. */
36
+ export declare class PrebuiltCaptureCycleError extends Error {
37
+ constructor(componentId: string);
38
+ }
39
+ /**
40
+ * Mark a capture as active. The builder calls this immediately before
41
+ * rendering an entry and MUST pair it with `endCapture()` in a finally.
42
+ */
43
+ export declare function beginCapture(outerId: string): void;
44
+ /**
45
+ * End the active capture and return the wrapped components that rendered
46
+ * inside it (first options object wins per inner ID).
47
+ */
48
+ export declare function endCapture(): NestedWrapperRender[];
49
+ /** Whether a build-time capture is currently rendering. */
50
+ export declare function isCaptureActive(): boolean;
51
+ /**
52
+ * Called by the `__prebuilt` wrapper on every render. No-op unless a
53
+ * capture is active. Throws `PrebuiltCaptureCycleError` when the wrapper
54
+ * belongs to the component currently being captured.
55
+ */
56
+ export declare function noteWrapperRender(innerId: string, options: PrebuiltComponentOptions): void;
57
+ //# sourceMappingURL=capture-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-state.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/capture-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAEvE,kEAAkE;AAClE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAED,sEAAsE;AACtE,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,WAAW,EAAE,MAAM;CAQhC;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,mBAAmB,EAAE,CAKlD;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAQ1F"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Manifest tag index — maps tags to seed cache keys for tombstone writes.
3
+ *
4
+ * When `revalidateTag(tag)` fires, the framework must write tombstones for
5
+ * every build-seed entry carrying that tag. The manifest records tags per
6
+ * entry; this module inverts the index at startup so the lookup is O(1) per
7
+ * tag instead of a full manifest scan per invalidation.
8
+ *
9
+ * The index is built lazily on first access and cached for the process
10
+ * lifetime — the manifest is immutable within a deploy.
11
+ *
12
+ * See design/45-cache-lifetimes.md §ISR mechanics.
13
+ */
14
+ import type { PrebuiltManifest } from './payload-source.js';
15
+ export interface SeedKeyInfo {
16
+ componentId: string;
17
+ cacheKey: string;
18
+ }
19
+ /**
20
+ * Build the inverted tag → seed key index from the manifest.
21
+ *
22
+ * Returns a Map where each tag maps to the set of (componentId, cacheKey)
23
+ * pairs whose manifest entries carry that tag. Only entries with non-empty
24
+ * `tags` arrays participate.
25
+ */
26
+ export declare function buildTagIndex(manifest: PrebuiltManifest): Map<string, SeedKeyInfo[]>;
27
+ //# sourceMappingURL=manifest-tag-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-tag-index.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/manifest-tag-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAiBpF"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Component cache overlay — runtime CacheHandler layer for ISR.
3
+ *
4
+ * Sits in front of the immutable build artifact (`.flight` files) and
5
+ * stores replacement payloads and tombstones via the configured
6
+ * CacheHandler. Overlay entries are per-deploy namespaced:
7
+ * `timber:c:{deploymentId}:{componentId}:{hash}`
8
+ *
9
+ * The CacheHandler contract is untouched — tombstones and the tag index
10
+ * live above the interface as value conventions. Redis, KV, and custom
11
+ * handlers work unmodified.
12
+ *
13
+ * See design/45-cache-lifetimes.md §ISR mechanics.
14
+ */
15
+ import { type SeedKeyInfo } from './manifest-tag-index.js';
16
+ import type { PrebuiltManifest } from './payload-source.js';
17
+ /**
18
+ * A cached component flight payload stored in the overlay.
19
+ * The `_t` discriminant distinguishes this from a tombstone.
20
+ */
21
+ export interface ComponentOverlayRecord {
22
+ _t: 'co';
23
+ /** Base64-encoded flight payload bytes. */
24
+ p: string;
25
+ /** Logical freshness deadline (Date.now() + ttl * 1000). */
26
+ fu: number;
27
+ /** Whether a build-artifact seed exists for this key. */
28
+ s: boolean;
29
+ }
30
+ /**
31
+ * A tombstone marking a build seed as invalidated.
32
+ * Written by revalidateTag for seeds carrying the invalidated tag.
33
+ */
34
+ export interface ComponentTombstoneRecord {
35
+ _t: 'ct';
36
+ }
37
+ export declare function isOverlayRecord(v: unknown): v is ComponentOverlayRecord;
38
+ export declare function isTombstone(v: unknown): v is ComponentTombstoneRecord;
39
+ export declare function overlayKey(componentId: string, cacheKey: string): string;
40
+ export interface OverlayLookupResult {
41
+ kind: 'fresh' | 'stale' | 'tombstone';
42
+ /** The overlay value (null for tombstones). */
43
+ record: ComponentOverlayRecord | null;
44
+ /** Raw flight payload bytes (decoded from base64). Null for tombstones. */
45
+ payload: Uint8Array | null;
46
+ }
47
+ /**
48
+ * Look up an overlay entry in the cache handler.
49
+ * Returns null on a clean miss (no overlay entry at all).
50
+ */
51
+ export declare function lookupOverlay(componentId: string, cacheKey: string): Promise<OverlayLookupResult | null>;
52
+ /**
53
+ * Resolve the effective TTL for a component's runtime lifetime.
54
+ * Tag-only entries (no explicit ttl) get the ceiling TTL (design/45
55
+ * §Tag-only entries carry a ceiling TTL).
56
+ */
57
+ export declare function effectiveTtl(ttl: number | undefined): number;
58
+ /**
59
+ * Store a component flight payload in the overlay.
60
+ */
61
+ export declare function storeOverlayEntry(componentId: string, cacheKey: string, payloadBytes: Uint8Array, opts: {
62
+ ttl?: number;
63
+ tags: string[];
64
+ hasSeed: boolean;
65
+ }): Promise<void>;
66
+ /**
67
+ * Initialize the tag index from the prebuilt manifest. Called once when the
68
+ * manifest is loaded. Without a manifest (no prebuilt components), this is
69
+ * never called and revalidateTag skips the tombstone path entirely.
70
+ */
71
+ export declare function initTagIndex(manifest: PrebuiltManifest): void;
72
+ /**
73
+ * Get the tag index, if initialized.
74
+ * @internal — exported for testing.
75
+ */
76
+ export declare function getTagIndex(): Map<string, SeedKeyInfo[]> | null;
77
+ /**
78
+ * Reset the tag index (for tests).
79
+ * @internal
80
+ */
81
+ export declare function resetTagIndex(): void;
82
+ /**
83
+ * Write tombstones for all seed entries carrying the given tag.
84
+ * Called from cache.invalidate (cache-api.ts) AFTER the handler's own
85
+ * invalidation clears overlay entries.
86
+ *
87
+ * The tombstone prevents the immutable seed from being served after
88
+ * invalidation — without it, a handler.invalidate that clears the overlay
89
+ * would expose the (now-stale) build artifact on the next request.
90
+ *
91
+ * Ensures the manifest is loaded first so cold-process actions that
92
+ * invalidate before any page render still write tombstones.
93
+ */
94
+ export declare function writeTombstonesForTag(tag: string): Promise<void>;
95
+ /**
96
+ * Reset the diagnostic flag (for tests).
97
+ * @internal
98
+ */
99
+ export declare function resetIsrDiagnostic(): void;
100
+ //# sourceMappingURL=overlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAW5D;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,IAAI,CAAC;IACT,2CAA2C;IAC3C,CAAC,EAAE,MAAM,CAAC;IACV,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,yDAAyD;IACzD,CAAC,EAAE,OAAO,CAAC;CACZ;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,IAAI,CAAC;CACV;AAID,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,sBAAsB,CAEvE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,wBAAwB,CAErE;AAID,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGxE;AAID,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC;IACtC,+CAA+C;IAC/C,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACtC,2EAA2E;IAC3E,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAoBrC;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE5D;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,UAAU,EACxB,IAAI,EAAE;IACJ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CAcf;AAMD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAG7D;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,CAE/D;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtE;AA8BD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Prebuilt payload source — the adapter seam through which the runtime
3
+ * reads build-time flight artifacts (`.timber/dist/prebuilt/`).
4
+ *
5
+ * The runtime never touches the filesystem directly: adapters register a
6
+ * source at startup (Node: fs reads; Cloudflare: the assets binding —
7
+ * design/44-render-at-build-time.md §Adapter Integration). Artifacts are
8
+ * produced by the post-build capture pass (TIM-1119, prebuilt-builder.ts);
9
+ * adapter registration of the source is TIM-1122. Until a source is
10
+ * registered (adapter not wired yet, dev mode, no artifacts built), every
11
+ * lookup misses and cache.component wrappers render live — the designed
12
+ * dynamic-fallback behavior.
13
+ *
14
+ * Phase 3 (design/45 runtime tier) inserts the CacheHandler overlay lookup
15
+ * in front of `lookupPrebuiltPayload` — overlay first, then artifact. The
16
+ * single-lookup-function shape here is that seam.
17
+ */
18
+ export interface PrebuiltManifestEntry {
19
+ /** Segment params this entry was captured under. */
20
+ params: Record<string, string | string[]>;
21
+ /** Payload path relative to the prebuilt/ directory. */
22
+ file: string;
23
+ /** Payload size in bytes (build report / diagnostics). */
24
+ bytes?: number;
25
+ /** Runtime invalidation tags (design/45 ISR tier). */
26
+ tags?: string[];
27
+ /** Epoch ms when this entry was captured (seed freshness for ISR). */
28
+ buildTimestamp?: number;
29
+ }
30
+ export interface PrebuiltManifest {
31
+ [componentId: string]: {
32
+ entries: Record<string, PrebuiltManifestEntry>;
33
+ };
34
+ }
35
+ export interface PrebuiltPayloadSource {
36
+ /** Load prebuilt/manifest.json. Null when no artifacts exist. */
37
+ loadManifest(): Promise<PrebuiltManifest | null>;
38
+ /** Read a `.flight` payload by manifest file path. Null when missing. */
39
+ readPayload(file: string): Promise<Uint8Array | null>;
40
+ }
41
+ /**
42
+ * Register the payload source. Called once at server startup by the
43
+ * adapter/entry wiring (TIM-1122); tests inject fakes. Passing null
44
+ * unregisters (and drops the memoized manifest).
45
+ */
46
+ export declare function setPrebuiltPayloadSource(next: PrebuiltPayloadSource | null): void;
47
+ /**
48
+ * Whether a source is registered — the gate for both marker emission and
49
+ * splice-transform installation. False means zero prebuilt overhead.
50
+ */
51
+ export declare function hasPrebuiltPayloadSource(): boolean;
52
+ /**
53
+ * Ensure the manifest is loaded (and the tag index initialized). No-op
54
+ * when no source is registered. Used by the tombstone path to avoid
55
+ * skipping tombstones on cold processes where the first request is an
56
+ * action rather than a page render.
57
+ */
58
+ export declare function ensureManifestLoaded(): Promise<void>;
59
+ /**
60
+ * Look up a manifest entry (metadata only, no payload read).
61
+ * Used by the overlay to check seed existence and freshness.
62
+ */
63
+ export declare function getManifestEntry(componentId: string, cacheKey: string): Promise<PrebuiltManifestEntry | null>;
64
+ /**
65
+ * Look up a cached payload: manifest entry → payload bytes.
66
+ * Null on any miss or read failure — callers fall back to live render.
67
+ *
68
+ * The manifest is loaded once and memoized (design/44 §manifest.json:
69
+ * loaded at startup, held in memory; payloads read on demand). A failed
70
+ * manifest load is memoized as null rather than retried per-request — a
71
+ * broken artifact should degrade to dynamic rendering, not add a failing
72
+ * read to every request.
73
+ */
74
+ export declare function lookupPrebuiltPayload(componentId: string, cacheKey: string): Promise<Uint8Array | null>;
75
+ //# sourceMappingURL=payload-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload-source.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/payload-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,WAAW,EAAE,MAAM,GAAG;QACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;KAChD,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,YAAY,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACjD,yEAAyE;IACzE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;CACvD;AAsED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAIjF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAElD;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAKvC;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAmB5B"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Synthetic ALS store for build-time capture (design/44 §Param Injection).
3
+ *
4
+ * Each param combo renders inside a `RequestContextStore` that provides
5
+ * segment params and NOTHING else. Every per-request API is a hard error,
6
+ * never a silent empty value — a component that branches on a header
7
+ * (locale, experiment, auth state) must fail the build, not bake the
8
+ * "header absent" branch into the cache for every future request:
9
+ *
10
+ * - `segmentParams.get()` works — reads from this store
11
+ * - `cookies()` / `headers()` / `searchParams` throw `BuildTimeContextError`
12
+ *
13
+ * The enforcement lives in the store's own fields (recording accessors)
14
+ * rather than in request-context.ts / cookie-context.ts, so the request
15
+ * path pays nothing and those modules stay untouched. The per-request
16
+ * fields — `headers`, `parsedCookies`, `searchParams` — are getters that
17
+ * record a violation and throw, so the CALL itself (`getHeaders()`,
18
+ * `getCookieJar()`, `getSearchParams()`) is the build error, not some
19
+ * later member read; merely obtaining and passing the object around is
20
+ * already outside the build-time contract (codex P2 round 5 on PR #836).
21
+ * `mutableContext` gets the same treatment because cookie MUTATORS reach
22
+ * it (via cookie-context's assertMutable, its only reader) before any
23
+ * other store field (codex P2 round 4).
24
+ *
25
+ * Every violation is recorded in a side channel BEFORE the throw — a
26
+ * component that catches the error (`try { headers() } catch { fallback }`)
27
+ * still fails its entry; accepting that render would silently bake the
28
+ * request-dependent fallback branch into the payload (codex P1 on PR #836).
29
+ * The capture pass checks the side channel after every render.
30
+ *
31
+ * This is safe precisely because capture renders the bare component
32
+ * element — no pipeline, no SSR bridge, no action machinery — so the only
33
+ * code that can reach these fields during a capture is the component
34
+ * itself (via the public accessors).
35
+ */
36
+ import type { RequestContextStore } from '../als-registry.js';
37
+ /**
38
+ * Thrown when a prerendered component touches per-request context at
39
+ * build time. The capture pass treats this as a HARD build error —
40
+ * it indicates a design mistake, not transient bad data (design/44
41
+ * §Build-Phase Error Handling).
42
+ */
43
+ export declare class BuildTimeContextError extends Error {
44
+ /** The per-request API that was called (e.g. "cookies()"). */
45
+ readonly api: string;
46
+ constructor(componentId: string, api: string);
47
+ }
48
+ /** A synthetic store plus the side channel its accessors report into. */
49
+ export interface BuildTimeStoreHandle {
50
+ store: RequestContextStore;
51
+ /**
52
+ * Every per-request API access during the render, recorded even when
53
+ * the accompanying throw was caught by user code. Non-empty after the
54
+ * render ⇒ the entry must fail as a hard build error.
55
+ */
56
+ violations: BuildTimeContextError[];
57
+ }
58
+ /**
59
+ * Create the synthetic per-combo store. `segmentParams` must already be
60
+ * coerced through the route's codecs — cache-key parity with request time
61
+ * depends on hashing the exact record `coerceSegmentParams` produces.
62
+ */
63
+ export declare function createBuildTimeStore(componentId: string, segmentParams: Record<string, string | string[]>): BuildTimeStoreHandle;
64
+ //# sourceMappingURL=synthetic-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthetic-store.d.ts","sourceRoot":"","sources":["../../../src/server/prebuilt/synthetic-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,8DAA8D;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAET,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CAW7C;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,mBAAmB,CAAC;IAC3B;;;;OAIG;IACH,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAC/C,oBAAoB,CA2BtB"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Prebuilt payload capture — the post-build half of cache.component
3
+ * (TIM-1119, design/44-render-at-build-time.md §Build Phase).
4
+ *
5
+ * Runs AFTER Vite's 5-step build sequence, INSIDE the built RSC bundle:
6
+ * the component registry, the ALS instances, and the flight renderer are
7
+ * module instances in the bundle's graph, so the capture pass must share
8
+ * that graph — `server/rsc-entry/index.ts` re-exports this module's
9
+ * entry point as `__timber_capturePrebuilt`, and the timber-prebuilt
10
+ * plugin imports the built `rsc/index.js` and calls it.
11
+ *
12
+ * Per candidate route (a page with prebuilt components attributed by the
13
+ * build-time module-graph walk):
14
+ *
15
+ * 1. Load the page module (+ layout-chain modules that declare prebuilt
16
+ * components) — module evaluation registers `__prebuilt` components.
17
+ * 2. Enumerate param combos: `generateStaticSegmentParams()` for dynamic
18
+ * routes, the single empty combo for static routes.
19
+ * 3. Per combo, reconstruct the URL and run the REAL request-time pair —
20
+ * `matchRoute` + `coerceSegmentParams` — so codec-coerced params hash
21
+ * byte-identically to a live request. `computeComponentCacheKey` is
22
+ * the single shared implementation (design/44 §Cache Key).
23
+ * 4. Render each registered component in isolation under a synthetic ALS
24
+ * store (segment params only; cookies/headers/searchParams are hard
25
+ * errors — synthetic-store.ts), fully drain the flight stream, and
26
+ * smoke-revive the captured bytes once before accepting them.
27
+ * 5. Hand each payload to the caller's sink. Persistence (atomic file
28
+ * writes, manifest.json) is the PLUGIN's job on the Node side —
29
+ * keeping node:fs out of the server bundle, which must also run on
30
+ * Cloudflare Workers.
31
+ *
32
+ * No payload source is registered while this runs, so wrappers rendered
33
+ * inside a captured subtree always miss and render live — inner output is
34
+ * baked flat into the outer entry, which is exactly the nesting clamp of
35
+ * design/45 §Nesting Semantics. The capture pass detects and reports the
36
+ * clamp (and fails cyclic entries) via capture-state.ts.
37
+ *
38
+ * Error policy (design/44 §Build-Phase Error Handling):
39
+ * - `BuildTimeContextError` (cookies/headers/searchParams at build time)
40
+ * → HARD error; the caller must fail the build.
41
+ * - Anything else (bad data, deny(), cycles, timeouts, revival failures)
42
+ * → skip that entry, warn, keep building.
43
+ */
44
+ import type { ManifestRoot } from './route-matcher.js';
45
+ /** One captured flight payload, ready for the caller's persistence sink. */
46
+ export interface CapturedEntry {
47
+ componentId: string;
48
+ /** `computeComponentCacheKey(callSiteProps, coercedParams)` — names the .flight file. */
49
+ cacheKey: string;
50
+ /** The raw param combo (JSON-safe) — manifest metadata, not the hash input. */
51
+ params: Record<string, string | string[]>;
52
+ /** Call-site props used for this entry (empty object for zero-prop usages). */
53
+ props?: Record<string, unknown>;
54
+ bytes: Uint8Array;
55
+ /** Resolved tags from callsite options — static or function-form, evaluated at capture time. */
56
+ tags?: string[];
57
+ }
58
+ /** A per-entry problem — either a skip (build continues) or a hard error. */
59
+ export interface CaptureIssue {
60
+ componentId: string;
61
+ routeUrlPath: string;
62
+ params: Record<string, string | string[]>;
63
+ message: string;
64
+ }
65
+ export interface CaptureSummary {
66
+ /** Entries captured, smoke-revived, and accepted by the sink. */
67
+ captured: number;
68
+ /** Skipped entries — reported, build continues (design/44 policy). */
69
+ skipped: CaptureIssue[];
70
+ /** Dynamic-context violations — the caller MUST fail the build. */
71
+ hardErrors: CaptureIssue[];
72
+ /** Nesting-clamp warnings emitted (design/45 §Nesting Semantics). */
73
+ nestingWarnings: number;
74
+ }
75
+ export interface CaptureOptions {
76
+ /**
77
+ * Route file path (page or layout, absolute) → prebuilt component IDs
78
+ * transitively reachable from it. Computed by the timber-prebuilt
79
+ * plugin's RSC module-graph walk at generateBundle time.
80
+ */
81
+ fileComponentMap: Record<string, string[]>;
82
+ /**
83
+ * Component ID → array of distinct static call-site prop objects captured
84
+ * from JSX usage sites (design/44 §Props Derivation). Each entry renders
85
+ * one payload per (props, params) combination. Components with no captured
86
+ * props (zero-prop usages) render with `{}` — the pre-TIM-1142 behavior.
87
+ */
88
+ callSiteProps?: Record<string, Record<string, unknown>[]>;
89
+ /**
90
+ * Persistence sink, called once per accepted payload. Throws propagate
91
+ * and abort the capture — a failed artifact write is an infrastructure
92
+ * failure, not a per-entry data problem.
93
+ */
94
+ onEntry: (entry: CapturedEntry) => Promise<void>;
95
+ /**
96
+ * Per-entry ceiling on render + drain. A component that hangs (stalled
97
+ * fetch, unbounded recursion the cycle guard can't see) fails its entry
98
+ * instead of hanging the whole build — the A2 stream-read rule from
99
+ * design/13-security.md applied to the build process.
100
+ */
101
+ renderTimeoutMs?: number;
102
+ /** Progress/warning logger. Defaults to console.warn. */
103
+ log?: (message: string) => void;
104
+ }
105
+ /**
106
+ * Capture flight payloads for every attributed, registered, prerender-tier
107
+ * component across the route manifest. See module docblock for the flow.
108
+ */
109
+ export declare function capturePrebuiltPayloads(manifest: ManifestRoot, options: CaptureOptions): Promise<CaptureSummary>;
110
+ //# sourceMappingURL=prebuilt-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prebuilt-builder.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAsBH,OAAO,KAAK,EAAgB,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAO1F,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,mEAAmE;IACnE,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,qEAAqE;IACrE,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D;;;;OAIG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yDAAyD;IACzD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAmSD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC,CAgNzB"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Prebuilt component runtime — registration target for the timber-prebuilt
3
+ * transform (plugins/prebuilt.ts) and the request-time half of
4
+ * cache.component (TIM-1140).
5
+ *
6
+ * `cache.component(fn, opts)` call sites are rewritten at build time to
7
+ * `__prebuilt(stableId, fn, opts)` (production) or `__prebuiltDev(name, fn)`
8
+ * (dev). Both are exported via #server-internal — they are framework
9
+ * plumbing, never called by user code directly.
10
+ *
11
+ * Cache hits are served by FLIGHT REVIVAL: the cached `.flight` payload is
12
+ * decoded back into React elements inside the RSC environment with
13
+ * `createFromReadableStream` (the flight client running in the flight
14
+ * server — plugin-rsc wires the server-decode manifest so client
15
+ * references revive as re-serializable reference proxies). The revived
16
+ * element is returned from the wrapper and the outer render re-serializes
17
+ * it like any other subtree. This is the same mechanism as Next.js
18
+ * `"use cache"` (next/src/server/use-cache/use-cache-wrapper.ts).
19
+ *
20
+ * What a hit skips: all user work — data fetching, MDX compilation, the
21
+ * component function itself never runs. What it re-pays: React
22
+ * re-serializes the already-resolved tree (cost proportional to payload
23
+ * size, not to data latency). The alternative — splicing raw payload bytes
24
+ * into the outer stream — avoids re-serialization but requires byte-level
25
+ * coupling to the flight wire format (row framing, ID rebasing, marker
26
+ * detection); it was implemented and reviewed on PR #835 and deliberately
27
+ * replaced by revival. See design/44-render-at-build-time.md
28
+ * §Request-Time Injection.
29
+ *
30
+ * Misses render the original component live via the wrapper's own closure,
31
+ * inside the React pass — segment params from ALS, deny()/redirect()
32
+ * signals, Suspense, and error boundaries behave exactly as an unwrapped
33
+ * component. `fallbackOnMissingSegmentParams: false` throws instead.
34
+ */
35
+ /**
36
+ * Set the timeout for component re-render captures. Called at boot from
37
+ * the RSC entry with renderTimeoutMs from timber.config.ts.
38
+ */
39
+ export declare function setComponentRefreshTimeout(timeoutMs: number): void;
40
+ /**
41
+ * Options captured from the `cache.component(fn, opts)` call site.
42
+ *
43
+ * `prerender`/`ttl`/`tags` (design/45) are carried through untouched — the
44
+ * build phase (TIM-1119) and runtime overlay (design/45 phase 3) consume
45
+ * them.
46
+ */
47
+ export interface PrebuiltComponentOptions {
48
+ /** Populate the cache at build time via generateStaticSegmentParams. */
49
+ prerender?: boolean;
50
+ /** Runtime freshness window, seconds (design/45 runtime tier). */
51
+ ttl?: number;
52
+ /** Runtime invalidation tags (design/45 runtime tier). */
53
+ tags?: string[] | ((props: Record<string, unknown>) => string[]);
54
+ /** Serve stale while a background re-render refreshes (design/45 §SWR). */
55
+ staleWhileRevalidate?: boolean;
56
+ /**
57
+ * On a cache miss, render the component live (default: true). When false,
58
+ * a miss throws instead — for sites that must never render unknown params
59
+ * dynamically. See design/44 §fallbackOnMissingSegmentParams.
60
+ */
61
+ fallbackOnMissingSegmentParams?: boolean;
62
+ }
63
+ /** An async server component: props in, renderable out. */
64
+ type ServerComponent = (props: any) => unknown;
65
+ export interface PrebuiltRegistration {
66
+ id: string;
67
+ component: ServerComponent;
68
+ options: PrebuiltComponentOptions;
69
+ }
70
+ interface RscFunctions {
71
+ createFromReadableStream: (stream: ReadableStream<Uint8Array>) => Promise<unknown>;
72
+ renderToReadableStream: (element: unknown, options?: {
73
+ onError?: (error: unknown) => string;
74
+ }) => ReadableStream<Uint8Array>;
75
+ }
76
+ /**
77
+ * Wire the RSC flight client/server functions. Called once at server
78
+ * startup from the RSC entry module.
79
+ */
80
+ export declare function setRscFunctions(fns: RscFunctions): void;
81
+ export declare const keyDisciplineWarned: Set<string>;
82
+ /**
83
+ * Production wrapper injected by the timber-prebuilt transform. Registers
84
+ * the component under its stable ID and returns a wrapper component that
85
+ * either revives the cached payload (hit) or renders the original
86
+ * component live (miss).
87
+ */
88
+ export declare function __prebuilt<C extends ServerComponent>(id: string, component: C, options?: PrebuiltComponentOptions): C;
89
+ /** Look up a registration by stable component ID. */
90
+ export declare function getPrebuiltRegistration(id: string): PrebuiltRegistration | undefined;
91
+ /** All registrations, for the post-build capture pass (TIM-1119). */
92
+ export declare function getPrebuiltRegistry(): ReadonlyMap<string, PrebuiltRegistration>;
93
+ /**
94
+ * Dev-mode wrapper injected by the timber-prebuilt transform: a no-op that
95
+ * renders the component dynamically on every request, logging once per
96
+ * component on first render so the production behavior difference is visible.
97
+ * See design/44 §Dev Mode.
98
+ */
99
+ export declare function __prebuiltDev<C extends ServerComponent>(name: string, component: C, _options?: PrebuiltComponentOptions): C;
100
+ export {};
101
+ //# sourceMappingURL=prebuilt-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prebuilt-runtime.d.ts","sourceRoot":"","sources":["../../src/server/prebuilt-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAiCH;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGlE;AAID;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IACjE,2EAA2E;IAC3E,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED,2DAA2D;AAE3D,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC;AAY/C,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,eAAe,CAAC;IAC3B,OAAO,EAAE,wBAAwB,CAAC;CACnC;AA8ED,UAAU,YAAY;IACpB,wBAAwB,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACnF,sBAAsB,EAAE,CACtB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;KAAE,KAC/C,cAAc,CAAC,UAAU,CAAC,CAAC;CACjC;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAEvD;AAmCD,eAAO,MAAM,mBAAmB,aAAoB,CAAC;AAoXrD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,eAAe,EAClD,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,CAAC,EACZ,OAAO,GAAE,wBAA6B,GACrC,CAAC,CAyCH;AAED,qDAAqD;AACrD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAEpF;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE/E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,eAAe,EACrD,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,CAAC,EACZ,QAAQ,CAAC,EAAE,wBAAwB,GAClC,CAAC,CAYH"}