@timber-js/app 0.2.0-alpha.10 → 0.2.0-alpha.101

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 (729) hide show
  1. package/LICENSE +8 -0
  2. package/dist/_chunks/actions-BsfxK6yu.js +1061 -0
  3. package/dist/_chunks/actions-BsfxK6yu.js.map +1 -0
  4. package/dist/_chunks/build-output-helper-DXnW0qjz.js +61 -0
  5. package/dist/_chunks/build-output-helper-DXnW0qjz.js.map +1 -0
  6. package/dist/_chunks/chunk-Cfpv9whK.js +32 -0
  7. package/dist/_chunks/define-B-Q_UMOD.js +195 -0
  8. package/dist/_chunks/define-B-Q_UMOD.js.map +1 -0
  9. package/dist/_chunks/define-cookie-BjpIt4UC.js +194 -0
  10. package/dist/_chunks/define-cookie-BjpIt4UC.js.map +1 -0
  11. package/dist/_chunks/define-k32T6NL2.js +123 -0
  12. package/dist/_chunks/define-k32T6NL2.js.map +1 -0
  13. package/dist/_chunks/format-Bcn-Iv1x.js +14 -0
  14. package/dist/_chunks/format-Bcn-Iv1x.js.map +1 -0
  15. package/dist/_chunks/handler-store-B-lqaGyh.js +54 -0
  16. package/dist/_chunks/handler-store-B-lqaGyh.js.map +1 -0
  17. package/dist/_chunks/logger-0m8MsKdc.js +291 -0
  18. package/dist/_chunks/logger-0m8MsKdc.js.map +1 -0
  19. package/dist/_chunks/merge-search-params-BphMdht_.js +122 -0
  20. package/dist/_chunks/merge-search-params-BphMdht_.js.map +1 -0
  21. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-BU684ls2.js} +1 -1
  22. package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-BU684ls2.js.map} +1 -1
  23. package/dist/_chunks/navigation-root-yx917rG0.js +96 -0
  24. package/dist/_chunks/navigation-root-yx917rG0.js.map +1 -0
  25. package/dist/_chunks/registry-I2ss-lvy.js +20 -0
  26. package/dist/_chunks/registry-I2ss-lvy.js.map +1 -0
  27. package/dist/_chunks/router-ref-h3-UaCQv.js +28 -0
  28. package/dist/_chunks/router-ref-h3-UaCQv.js.map +1 -0
  29. package/dist/_chunks/schema-bridge-Cxu4l-7p.js +86 -0
  30. package/dist/_chunks/schema-bridge-Cxu4l-7p.js.map +1 -0
  31. package/dist/_chunks/segment-classify-BjfuctV2.js +137 -0
  32. package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -0
  33. package/dist/_chunks/segment-context-Dx_OizxD.js +34 -0
  34. package/dist/_chunks/segment-context-Dx_OizxD.js.map +1 -0
  35. package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-B4CdH7rE.js} +1 -1
  36. package/dist/_chunks/ssr-data-B4CdH7rE.js.map +1 -0
  37. package/dist/_chunks/stale-reload-Bab885FO.js +64 -0
  38. package/dist/_chunks/stale-reload-Bab885FO.js.map +1 -0
  39. package/dist/_chunks/tracing-C8V-YGsP.js +329 -0
  40. package/dist/_chunks/tracing-C8V-YGsP.js.map +1 -0
  41. package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-B2XTqxDR.js} +7 -20
  42. package/dist/_chunks/use-query-states-B2XTqxDR.js.map +1 -0
  43. package/dist/_chunks/use-segment-params-DlsOX1YS.js +185 -0
  44. package/dist/_chunks/use-segment-params-DlsOX1YS.js.map +1 -0
  45. package/dist/_chunks/walkers-Tg0Alwcg.js +850 -0
  46. package/dist/_chunks/walkers-Tg0Alwcg.js.map +1 -0
  47. package/dist/_chunks/{format-DviM89f0.js → warnings-Cg47l5sk.js} +6 -45
  48. package/dist/_chunks/warnings-Cg47l5sk.js.map +1 -0
  49. package/dist/adapters/build-output-helper.d.ts +28 -0
  50. package/dist/adapters/build-output-helper.d.ts.map +1 -0
  51. package/dist/adapters/cloudflare-dev.d.ts +109 -0
  52. package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
  53. package/dist/adapters/cloudflare-dev.js +73 -0
  54. package/dist/adapters/cloudflare-dev.js.map +1 -0
  55. package/dist/adapters/cloudflare-kv-cache.d.ts +64 -0
  56. package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
  57. package/dist/adapters/cloudflare-kv-cache.js +95 -0
  58. package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
  59. package/dist/adapters/cloudflare.d.ts +148 -12
  60. package/dist/adapters/cloudflare.d.ts.map +1 -1
  61. package/dist/adapters/cloudflare.js +142 -38
  62. package/dist/adapters/cloudflare.js.map +1 -1
  63. package/dist/adapters/compress-module.d.ts.map +1 -1
  64. package/dist/adapters/nitro.d.ts +17 -1
  65. package/dist/adapters/nitro.d.ts.map +1 -1
  66. package/dist/adapters/nitro.js +143 -45
  67. package/dist/adapters/nitro.js.map +1 -1
  68. package/dist/adapters/shared.d.ts +16 -0
  69. package/dist/adapters/shared.d.ts.map +1 -0
  70. package/dist/cache/cache-api.d.ts +24 -0
  71. package/dist/cache/cache-api.d.ts.map +1 -0
  72. package/dist/cache/handler-store.d.ts +31 -0
  73. package/dist/cache/handler-store.d.ts.map +1 -0
  74. package/dist/cache/index.d.ts +23 -7
  75. package/dist/cache/index.d.ts.map +1 -1
  76. package/dist/cache/index.js +150 -81
  77. package/dist/cache/index.js.map +1 -1
  78. package/dist/cache/singleflight.d.ts +18 -1
  79. package/dist/cache/singleflight.d.ts.map +1 -1
  80. package/dist/cache/sizeof.d.ts +22 -0
  81. package/dist/cache/sizeof.d.ts.map +1 -0
  82. package/dist/cache/timber-cache.d.ts +1 -1
  83. package/dist/cache/timber-cache.d.ts.map +1 -1
  84. package/dist/cli.d.ts +6 -1
  85. package/dist/cli.d.ts.map +1 -1
  86. package/dist/cli.js +8 -3
  87. package/dist/cli.js.map +1 -1
  88. package/dist/client/browser-dev.d.ts +34 -1
  89. package/dist/client/browser-dev.d.ts.map +1 -1
  90. package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
  91. package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
  92. package/dist/client/browser-entry/hmr.d.ts +21 -0
  93. package/dist/client/browser-entry/hmr.d.ts.map +1 -0
  94. package/dist/client/browser-entry/hydrate.d.ts +46 -0
  95. package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
  96. package/dist/client/browser-entry/index.d.ts +30 -0
  97. package/dist/client/browser-entry/index.d.ts.map +1 -0
  98. package/dist/client/browser-entry/post-hydration.d.ts +26 -0
  99. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
  100. package/dist/client/browser-entry/router-init.d.ts +23 -0
  101. package/dist/client/browser-entry/router-init.d.ts.map +1 -0
  102. package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
  103. package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
  104. package/dist/client/browser-entry/scroll.d.ts +19 -0
  105. package/dist/client/browser-entry/scroll.d.ts.map +1 -0
  106. package/dist/client/error-boundary.d.ts +12 -5
  107. package/dist/client/error-boundary.d.ts.map +1 -1
  108. package/dist/client/error-boundary.js +26 -5
  109. package/dist/client/error-boundary.js.map +1 -1
  110. package/dist/client/error-reconstituter.d.ts +54 -0
  111. package/dist/client/error-reconstituter.d.ts.map +1 -0
  112. package/dist/client/form.d.ts +16 -27
  113. package/dist/client/form.d.ts.map +1 -1
  114. package/dist/client/history.d.ts +19 -4
  115. package/dist/client/history.d.ts.map +1 -1
  116. package/dist/client/index.d.ts +9 -24
  117. package/dist/client/index.d.ts.map +1 -1
  118. package/dist/client/index.js +261 -1100
  119. package/dist/client/index.js.map +1 -1
  120. package/dist/client/internal.d.ts +19 -0
  121. package/dist/client/internal.d.ts.map +1 -0
  122. package/dist/client/internal.js +964 -0
  123. package/dist/client/internal.js.map +1 -0
  124. package/dist/client/link-pending-store.d.ts +63 -0
  125. package/dist/client/link-pending-store.d.ts.map +1 -0
  126. package/dist/client/link.d.ts +62 -55
  127. package/dist/client/link.d.ts.map +1 -1
  128. package/dist/client/nav-link-store.d.ts +36 -0
  129. package/dist/client/nav-link-store.d.ts.map +1 -0
  130. package/dist/client/navigation-api-types.d.ts +90 -0
  131. package/dist/client/navigation-api-types.d.ts.map +1 -0
  132. package/dist/client/navigation-api.d.ts +115 -0
  133. package/dist/client/navigation-api.d.ts.map +1 -0
  134. package/dist/client/navigation-context.d.ts +13 -2
  135. package/dist/client/navigation-context.d.ts.map +1 -1
  136. package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
  137. package/dist/client/navigation-root.d.ts.map +1 -0
  138. package/dist/client/nuqs-adapter.d.ts.map +1 -1
  139. package/dist/client/router-ref.d.ts +1 -1
  140. package/dist/client/router.d.ts +70 -4
  141. package/dist/client/router.d.ts.map +1 -1
  142. package/dist/client/rsc-fetch.d.ts +38 -3
  143. package/dist/client/rsc-fetch.d.ts.map +1 -1
  144. package/dist/client/segment-cache.d.ts +1 -1
  145. package/dist/client/segment-cache.d.ts.map +1 -1
  146. package/dist/client/segment-outlet.d.ts +63 -0
  147. package/dist/client/segment-outlet.d.ts.map +1 -0
  148. package/dist/client/ssr-data.d.ts +13 -4
  149. package/dist/client/ssr-data.d.ts.map +1 -1
  150. package/dist/client/stale-reload.d.ts +15 -0
  151. package/dist/client/stale-reload.d.ts.map +1 -1
  152. package/dist/client/state.d.ts +1 -1
  153. package/dist/client/top-loader.d.ts +5 -5
  154. package/dist/client/top-loader.d.ts.map +1 -1
  155. package/dist/client/use-cookie.d.ts +8 -0
  156. package/dist/client/use-cookie.d.ts.map +1 -1
  157. package/dist/client/use-link-status.d.ts +5 -5
  158. package/dist/client/use-link-status.d.ts.map +1 -1
  159. package/dist/client/{use-navigation-pending.d.ts → use-pending-navigation.d.ts} +4 -4
  160. package/dist/client/use-pending-navigation.d.ts.map +1 -0
  161. package/dist/client/use-query-states.d.ts +1 -1
  162. package/dist/client/use-query-states.d.ts.map +1 -1
  163. package/dist/client/use-router.d.ts +1 -1
  164. package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +7 -5
  165. package/dist/client/use-segment-params.d.ts.map +1 -0
  166. package/dist/codec.d.ts +33 -0
  167. package/dist/codec.d.ts.map +1 -0
  168. package/dist/codec.js +2 -0
  169. package/dist/config-types.d.ts +294 -0
  170. package/dist/config-types.d.ts.map +1 -0
  171. package/dist/config-validation.d.ts +51 -0
  172. package/dist/config-validation.d.ts.map +1 -0
  173. package/dist/content/index.d.ts +1 -10
  174. package/dist/content/index.d.ts.map +1 -1
  175. package/dist/content/index.js +0 -2
  176. package/dist/cookies/define-cookie.d.ts +98 -25
  177. package/dist/cookies/define-cookie.d.ts.map +1 -1
  178. package/dist/cookies/index.d.ts +2 -1
  179. package/dist/cookies/index.d.ts.map +1 -1
  180. package/dist/cookies/index.js +36 -72
  181. package/dist/cookies/index.js.map +1 -1
  182. package/dist/cookies/json-cookie.d.ts +64 -0
  183. package/dist/cookies/json-cookie.d.ts.map +1 -0
  184. package/dist/cookies/validation.d.ts +46 -0
  185. package/dist/cookies/validation.d.ts.map +1 -0
  186. package/dist/dev-tools/404-page.d.ts +46 -0
  187. package/dist/dev-tools/404-page.d.ts.map +1 -0
  188. package/dist/dev-tools/browser-logs.d.ts +84 -0
  189. package/dist/dev-tools/browser-logs.d.ts.map +1 -0
  190. package/dist/dev-tools/error-page.d.ts +58 -0
  191. package/dist/dev-tools/error-page.d.ts.map +1 -0
  192. package/dist/dev-tools/holding-server.d.ts +54 -0
  193. package/dist/dev-tools/holding-server.d.ts.map +1 -0
  194. package/dist/dev-tools/index.d.ts +31 -0
  195. package/dist/dev-tools/index.d.ts.map +1 -0
  196. package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
  197. package/dist/dev-tools/instrumentation.d.ts.map +1 -0
  198. package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
  199. package/dist/dev-tools/logger.d.ts.map +1 -0
  200. package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
  201. package/dist/dev-tools/logs.d.ts.map +1 -0
  202. package/dist/dev-tools/overlay.d.ts +91 -0
  203. package/dist/dev-tools/overlay.d.ts.map +1 -0
  204. package/dist/dev-tools/stack-classifier.d.ts +34 -0
  205. package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
  206. package/dist/dev-tools/terminal.d.ts +28 -0
  207. package/dist/dev-tools/terminal.d.ts.map +1 -0
  208. package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +2 -22
  209. package/dist/dev-tools/warnings.d.ts.map +1 -0
  210. package/dist/fonts/ast.d.ts +98 -6
  211. package/dist/fonts/ast.d.ts.map +1 -1
  212. package/dist/fonts/bundle.d.ts +48 -0
  213. package/dist/fonts/bundle.d.ts.map +1 -0
  214. package/dist/fonts/css.d.ts +1 -0
  215. package/dist/fonts/css.d.ts.map +1 -1
  216. package/dist/fonts/dev-middleware.d.ts +22 -0
  217. package/dist/fonts/dev-middleware.d.ts.map +1 -0
  218. package/dist/fonts/local.d.ts +1 -1
  219. package/dist/fonts/pipeline.d.ts +167 -0
  220. package/dist/fonts/pipeline.d.ts.map +1 -0
  221. package/dist/fonts/transform.d.ts +78 -0
  222. package/dist/fonts/transform.d.ts.map +1 -0
  223. package/dist/fonts/types.d.ts +45 -1
  224. package/dist/fonts/types.d.ts.map +1 -1
  225. package/dist/fonts/virtual-modules.d.ts +103 -0
  226. package/dist/fonts/virtual-modules.d.ts.map +1 -0
  227. package/dist/index.d.ts +46 -190
  228. package/dist/index.d.ts.map +1 -1
  229. package/dist/index.js +5348 -13285
  230. package/dist/index.js.map +1 -1
  231. package/dist/plugin-context.d.ts +107 -0
  232. package/dist/plugin-context.d.ts.map +1 -0
  233. package/dist/plugins/adapter-build.d.ts +1 -1
  234. package/dist/plugins/adapter-build.d.ts.map +1 -1
  235. package/dist/plugins/build-manifest.d.ts +2 -2
  236. package/dist/plugins/build-manifest.d.ts.map +1 -1
  237. package/dist/plugins/build-report.d.ts +9 -7
  238. package/dist/plugins/build-report.d.ts.map +1 -1
  239. package/dist/plugins/client-chunks.d.ts +32 -0
  240. package/dist/plugins/client-chunks.d.ts.map +1 -0
  241. package/dist/plugins/content.d.ts +1 -1
  242. package/dist/plugins/content.d.ts.map +1 -1
  243. package/dist/plugins/dev-server.d.ts +1 -1
  244. package/dist/plugins/dev-server.d.ts.map +1 -1
  245. package/dist/plugins/entries.d.ts +1 -1
  246. package/dist/plugins/entries.d.ts.map +1 -1
  247. package/dist/plugins/fonts.d.ts +17 -73
  248. package/dist/plugins/fonts.d.ts.map +1 -1
  249. package/dist/plugins/mdx.d.ts +1 -1
  250. package/dist/plugins/mdx.d.ts.map +1 -1
  251. package/dist/plugins/routing.d.ts +1 -1
  252. package/dist/plugins/routing.d.ts.map +1 -1
  253. package/dist/plugins/server-bundle.d.ts.map +1 -1
  254. package/dist/plugins/shims.d.ts +6 -5
  255. package/dist/plugins/shims.d.ts.map +1 -1
  256. package/dist/plugins/static-build.d.ts +5 -26
  257. package/dist/plugins/static-build.d.ts.map +1 -1
  258. package/dist/routing/codegen-shared.d.ts +55 -0
  259. package/dist/routing/codegen-shared.d.ts.map +1 -0
  260. package/dist/routing/codegen-types.d.ts +52 -0
  261. package/dist/routing/codegen-types.d.ts.map +1 -0
  262. package/dist/routing/codegen.d.ts +2 -2
  263. package/dist/routing/codegen.d.ts.map +1 -1
  264. package/dist/routing/convention-lint.d.ts +41 -0
  265. package/dist/routing/convention-lint.d.ts.map +1 -0
  266. package/dist/routing/index.d.ts +5 -1
  267. package/dist/routing/index.d.ts.map +1 -1
  268. package/dist/routing/index.js +3 -2
  269. package/dist/routing/link-codegen.d.ts +90 -0
  270. package/dist/routing/link-codegen.d.ts.map +1 -0
  271. package/dist/routing/scanner.d.ts +1 -10
  272. package/dist/routing/scanner.d.ts.map +1 -1
  273. package/dist/routing/segment-classify.d.ts +75 -0
  274. package/dist/routing/segment-classify.d.ts.map +1 -0
  275. package/dist/routing/types.d.ts +77 -25
  276. package/dist/routing/types.d.ts.map +1 -1
  277. package/dist/routing/walkers.d.ts +51 -0
  278. package/dist/routing/walkers.d.ts.map +1 -0
  279. package/dist/rsc-runtime/rsc.d.ts +1 -1
  280. package/dist/rsc-runtime/rsc.d.ts.map +1 -1
  281. package/dist/rsc-runtime/ssr.d.ts +12 -0
  282. package/dist/rsc-runtime/ssr.d.ts.map +1 -1
  283. package/dist/schema-bridge.d.ts +76 -0
  284. package/dist/schema-bridge.d.ts.map +1 -0
  285. package/dist/search-params/define.d.ts +157 -0
  286. package/dist/search-params/define.d.ts.map +1 -0
  287. package/dist/search-params/index.d.ts +4 -7
  288. package/dist/search-params/index.d.ts.map +1 -1
  289. package/dist/search-params/index.js +34 -441
  290. package/dist/search-params/index.js.map +1 -1
  291. package/dist/search-params/registry.d.ts +2 -2
  292. package/dist/search-params/registry.d.ts.map +1 -1
  293. package/dist/search-params/wrappers.d.ts +53 -0
  294. package/dist/search-params/wrappers.d.ts.map +1 -0
  295. package/dist/segment-params/define.d.ts +95 -0
  296. package/dist/segment-params/define.d.ts.map +1 -0
  297. package/dist/segment-params/index.d.ts +3 -0
  298. package/dist/segment-params/index.d.ts.map +1 -0
  299. package/dist/segment-params/index.js +2 -0
  300. package/dist/server/access-gate.d.ts +8 -3
  301. package/dist/server/access-gate.d.ts.map +1 -1
  302. package/dist/server/action-client.d.ts +41 -6
  303. package/dist/server/action-client.d.ts.map +1 -1
  304. package/dist/server/action-encryption.d.ts +76 -0
  305. package/dist/server/action-encryption.d.ts.map +1 -0
  306. package/dist/server/action-handler.d.ts +35 -1
  307. package/dist/server/action-handler.d.ts.map +1 -1
  308. package/dist/server/actions.d.ts +3 -6
  309. package/dist/server/actions.d.ts.map +1 -1
  310. package/dist/server/als-registry.d.ts +33 -5
  311. package/dist/server/als-registry.d.ts.map +1 -1
  312. package/dist/server/asset-headers.d.ts +1 -15
  313. package/dist/server/asset-headers.d.ts.map +1 -1
  314. package/dist/server/build-manifest.d.ts +2 -2
  315. package/dist/server/build-manifest.d.ts.map +1 -1
  316. package/dist/server/cookie-context.d.ts +170 -0
  317. package/dist/server/cookie-context.d.ts.map +1 -0
  318. package/dist/server/cookie-parsing.d.ts +51 -0
  319. package/dist/server/cookie-parsing.d.ts.map +1 -0
  320. package/dist/server/debug.d.ts +1 -1
  321. package/dist/server/default-logger.d.ts +22 -0
  322. package/dist/server/default-logger.d.ts.map +1 -0
  323. package/dist/server/deny-boundary.d.ts +90 -0
  324. package/dist/server/deny-boundary.d.ts.map +1 -0
  325. package/dist/server/deny-renderer.d.ts.map +1 -1
  326. package/dist/server/dev-source-map.d.ts +22 -0
  327. package/dist/server/dev-source-map.d.ts.map +1 -0
  328. package/dist/server/early-hints-sender.d.ts.map +1 -1
  329. package/dist/server/early-hints.d.ts +13 -5
  330. package/dist/server/early-hints.d.ts.map +1 -1
  331. package/dist/server/error-boundary-wrapper.d.ts +7 -1
  332. package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
  333. package/dist/server/fallback-error.d.ts +12 -7
  334. package/dist/server/fallback-error.d.ts.map +1 -1
  335. package/dist/server/flight-injection-state.d.ts +66 -0
  336. package/dist/server/flight-injection-state.d.ts.map +1 -0
  337. package/dist/server/flight-scripts.d.ts +42 -0
  338. package/dist/server/flight-scripts.d.ts.map +1 -0
  339. package/dist/server/flush.d.ts.map +1 -1
  340. package/dist/server/form-data.d.ts +29 -0
  341. package/dist/server/form-data.d.ts.map +1 -1
  342. package/dist/server/html-injector-core.d.ts +212 -0
  343. package/dist/server/html-injector-core.d.ts.map +1 -0
  344. package/dist/server/html-injectors.d.ts +81 -41
  345. package/dist/server/html-injectors.d.ts.map +1 -1
  346. package/dist/server/index.d.ts +9 -46
  347. package/dist/server/index.d.ts.map +1 -1
  348. package/dist/server/index.js +155 -2905
  349. package/dist/server/index.js.map +1 -1
  350. package/dist/server/internal.d.ts +48 -0
  351. package/dist/server/internal.d.ts.map +1 -0
  352. package/dist/server/internal.js +2900 -0
  353. package/dist/server/internal.js.map +1 -0
  354. package/dist/server/logger.d.ts +39 -7
  355. package/dist/server/logger.d.ts.map +1 -1
  356. package/dist/server/middleware-runner.d.ts +36 -4
  357. package/dist/server/middleware-runner.d.ts.map +1 -1
  358. package/dist/server/node-stream-transforms.d.ts +110 -0
  359. package/dist/server/node-stream-transforms.d.ts.map +1 -0
  360. package/dist/server/param-coercion.d.ts +26 -0
  361. package/dist/server/param-coercion.d.ts.map +1 -0
  362. package/dist/server/pipeline-helpers.d.ts +95 -0
  363. package/dist/server/pipeline-helpers.d.ts.map +1 -0
  364. package/dist/server/pipeline-interception.d.ts +1 -1
  365. package/dist/server/pipeline-interception.d.ts.map +1 -1
  366. package/dist/server/pipeline-metadata.d.ts +6 -0
  367. package/dist/server/pipeline-metadata.d.ts.map +1 -1
  368. package/dist/server/pipeline-outcome.d.ts +49 -0
  369. package/dist/server/pipeline-outcome.d.ts.map +1 -0
  370. package/dist/server/pipeline-phases.d.ts +52 -0
  371. package/dist/server/pipeline-phases.d.ts.map +1 -0
  372. package/dist/server/pipeline.d.ts +93 -23
  373. package/dist/server/pipeline.d.ts.map +1 -1
  374. package/dist/server/port-resolution.d.ts +117 -0
  375. package/dist/server/port-resolution.d.ts.map +1 -0
  376. package/dist/server/primitives.d.ts +69 -18
  377. package/dist/server/primitives.d.ts.map +1 -1
  378. package/dist/server/render-timeout.d.ts +51 -0
  379. package/dist/server/render-timeout.d.ts.map +1 -0
  380. package/dist/server/request-context.d.ts +41 -109
  381. package/dist/server/request-context.d.ts.map +1 -1
  382. package/dist/server/route-element-builder.d.ts +27 -1
  383. package/dist/server/route-element-builder.d.ts.map +1 -1
  384. package/dist/server/route-handler.d.ts.map +1 -1
  385. package/dist/server/route-matcher.d.ts +21 -34
  386. package/dist/server/route-matcher.d.ts.map +1 -1
  387. package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
  388. package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
  389. package/dist/server/rsc-entry/api-handler.d.ts +2 -2
  390. package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
  391. package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
  392. package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
  393. package/dist/server/rsc-entry/helpers.d.ts +49 -6
  394. package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
  395. package/dist/server/rsc-entry/index.d.ts +20 -3
  396. package/dist/server/rsc-entry/index.d.ts.map +1 -1
  397. package/dist/server/rsc-entry/render-route.d.ts +50 -0
  398. package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
  399. package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
  400. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  401. package/dist/server/rsc-entry/rsc-stream.d.ts +14 -1
  402. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  403. package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
  404. package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
  405. package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
  406. package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
  407. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
  408. package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
  409. package/dist/server/safe-load.d.ts +46 -0
  410. package/dist/server/safe-load.d.ts.map +1 -0
  411. package/dist/server/sensitive-fields.d.ts +74 -0
  412. package/dist/server/sensitive-fields.d.ts.map +1 -0
  413. package/dist/server/sitemap-generator.d.ts +129 -0
  414. package/dist/server/sitemap-generator.d.ts.map +1 -0
  415. package/dist/server/sitemap-handler.d.ts +22 -0
  416. package/dist/server/sitemap-handler.d.ts.map +1 -0
  417. package/dist/server/slot-resolver.d.ts +1 -1
  418. package/dist/server/slot-resolver.d.ts.map +1 -1
  419. package/dist/server/ssr-entry.d.ts +23 -0
  420. package/dist/server/ssr-entry.d.ts.map +1 -1
  421. package/dist/server/ssr-render.d.ts +39 -21
  422. package/dist/server/ssr-render.d.ts.map +1 -1
  423. package/dist/server/ssr-wrappers.d.ts +50 -0
  424. package/dist/server/ssr-wrappers.d.ts.map +1 -0
  425. package/dist/server/state-tree-diff.d.ts.map +1 -1
  426. package/dist/server/status-code-resolver.d.ts +16 -11
  427. package/dist/server/status-code-resolver.d.ts.map +1 -1
  428. package/dist/server/stream-utils.d.ts +36 -0
  429. package/dist/server/stream-utils.d.ts.map +1 -0
  430. package/dist/server/tracing.d.ts +5 -5
  431. package/dist/server/tracing.d.ts.map +1 -1
  432. package/dist/server/tree-builder.d.ts +62 -30
  433. package/dist/server/tree-builder.d.ts.map +1 -1
  434. package/dist/server/types.d.ts +49 -4
  435. package/dist/server/types.d.ts.map +1 -1
  436. package/dist/server/utils/escape-html.d.ts +14 -0
  437. package/dist/server/utils/escape-html.d.ts.map +1 -0
  438. package/dist/server/version-skew.d.ts +61 -0
  439. package/dist/server/version-skew.d.ts.map +1 -0
  440. package/dist/shared/merge-search-params.d.ts +22 -0
  441. package/dist/shared/merge-search-params.d.ts.map +1 -0
  442. package/dist/shims/font-google.d.ts +1 -1
  443. package/dist/shims/font-google.d.ts.map +1 -1
  444. package/dist/shims/font-google.js +42 -0
  445. package/dist/shims/font-google.js.map +1 -0
  446. package/dist/shims/font-local.d.ts +26 -0
  447. package/dist/shims/font-local.d.ts.map +1 -0
  448. package/dist/shims/font-local.js +20 -0
  449. package/dist/shims/font-local.js.map +1 -0
  450. package/dist/shims/headers.d.ts +2 -1
  451. package/dist/shims/headers.d.ts.map +1 -1
  452. package/dist/shims/navigation-client.d.ts +3 -1
  453. package/dist/shims/navigation-client.d.ts.map +1 -1
  454. package/dist/shims/navigation.d.ts +11 -5
  455. package/dist/shims/navigation.d.ts.map +1 -1
  456. package/dist/utils/state-machine.d.ts +80 -0
  457. package/dist/utils/state-machine.d.ts.map +1 -0
  458. package/package.json +57 -22
  459. package/src/adapters/build-output-helper.ts +77 -0
  460. package/src/adapters/cloudflare-dev.ts +177 -0
  461. package/src/adapters/cloudflare-kv-cache.ts +142 -0
  462. package/src/adapters/cloudflare.ts +350 -76
  463. package/src/adapters/compress-module.ts +24 -4
  464. package/src/adapters/nitro.ts +142 -59
  465. package/src/adapters/shared.ts +40 -0
  466. package/src/adapters/wrangler.d.ts +7 -0
  467. package/src/cache/cache-api.ts +38 -0
  468. package/src/cache/handler-store.ts +68 -0
  469. package/src/cache/index.ts +81 -18
  470. package/src/cache/singleflight.ts +62 -4
  471. package/src/cache/sizeof.ts +31 -0
  472. package/src/cache/timber-cache.ts +25 -20
  473. package/src/cli.ts +16 -6
  474. package/src/client/browser-dev.ts +153 -1
  475. package/src/client/browser-entry/action-dispatch.ts +116 -0
  476. package/src/client/browser-entry/hmr.ts +81 -0
  477. package/src/client/browser-entry/hydrate.ts +145 -0
  478. package/src/client/browser-entry/index.ts +143 -0
  479. package/src/client/browser-entry/post-hydration.ts +119 -0
  480. package/src/client/browser-entry/router-init.ts +193 -0
  481. package/src/client/browser-entry/rsc-stream.ts +157 -0
  482. package/src/client/browser-entry/scroll.ts +27 -0
  483. package/src/client/error-boundary.tsx +97 -20
  484. package/src/client/error-reconstituter.tsx +65 -0
  485. package/src/client/form.tsx +31 -32
  486. package/src/client/history.ts +26 -4
  487. package/src/client/index.ts +77 -43
  488. package/src/client/internal.ts +58 -0
  489. package/src/client/link-pending-store.ts +111 -0
  490. package/src/client/link.tsx +342 -113
  491. package/src/client/nav-link-store.ts +47 -0
  492. package/src/client/navigation-api-types.ts +112 -0
  493. package/src/client/navigation-api.ts +332 -0
  494. package/src/client/navigation-context.ts +31 -6
  495. package/src/client/navigation-root.tsx +342 -0
  496. package/src/client/nuqs-adapter.tsx +16 -3
  497. package/src/client/router-ref.ts +1 -1
  498. package/src/client/router.ts +300 -73
  499. package/src/client/rsc-fetch.ts +112 -8
  500. package/src/client/segment-cache.ts +1 -1
  501. package/src/client/segment-outlet.tsx +86 -0
  502. package/src/client/ssr-data.ts +13 -5
  503. package/src/client/stale-reload.ts +72 -3
  504. package/src/client/state.ts +2 -2
  505. package/src/client/top-loader.tsx +18 -6
  506. package/src/client/use-cookie.ts +29 -0
  507. package/src/client/use-link-status.ts +7 -7
  508. package/src/client/{use-navigation-pending.ts → use-pending-navigation.ts} +6 -6
  509. package/src/client/use-query-states.ts +9 -3
  510. package/src/client/use-router.ts +1 -1
  511. package/src/client/{use-params.ts → use-segment-params.ts} +7 -5
  512. package/src/codec.ts +45 -0
  513. package/src/config-types.ts +292 -0
  514. package/src/config-validation.ts +303 -0
  515. package/src/content/index.ts +5 -13
  516. package/src/cookies/define-cookie.ts +301 -55
  517. package/src/cookies/index.ts +12 -1
  518. package/src/cookies/json-cookie.ts +105 -0
  519. package/src/cookies/validation.ts +134 -0
  520. package/src/dev-tools/404-page.ts +387 -0
  521. package/src/dev-tools/browser-logs.ts +288 -0
  522. package/src/dev-tools/error-page.ts +509 -0
  523. package/src/dev-tools/holding-server.ts +187 -0
  524. package/src/dev-tools/index.ts +90 -0
  525. package/src/dev-tools/instrumentation.ts +176 -0
  526. package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +3 -3
  527. package/src/dev-tools/overlay.ts +456 -0
  528. package/src/dev-tools/stack-classifier.ts +75 -0
  529. package/src/dev-tools/terminal.ts +183 -0
  530. package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
  531. package/src/fonts/ast.ts +488 -16
  532. package/src/fonts/bundle.ts +142 -0
  533. package/src/fonts/css.ts +2 -1
  534. package/src/fonts/dev-middleware.ts +74 -0
  535. package/src/fonts/local.ts +1 -1
  536. package/src/fonts/pipeline.ts +314 -0
  537. package/src/fonts/transform.ts +317 -0
  538. package/src/fonts/types.ts +50 -1
  539. package/src/fonts/virtual-modules.ts +227 -0
  540. package/src/index.ts +390 -358
  541. package/src/plugin-context.ts +240 -0
  542. package/src/plugins/adapter-build.ts +12 -4
  543. package/src/plugins/build-manifest.ts +13 -2
  544. package/src/plugins/build-report.ts +16 -25
  545. package/src/plugins/client-chunks.ts +65 -0
  546. package/src/plugins/content.ts +1 -1
  547. package/src/plugins/dev-server.ts +162 -30
  548. package/src/plugins/entries.ts +111 -10
  549. package/src/plugins/fonts.ts +155 -654
  550. package/src/plugins/mdx.ts +43 -10
  551. package/src/plugins/routing.ts +217 -44
  552. package/src/plugins/server-bundle.ts +32 -1
  553. package/src/plugins/shims.ts +136 -35
  554. package/src/plugins/static-build.ts +15 -89
  555. package/src/routing/codegen-shared.ts +98 -0
  556. package/src/routing/codegen-types.ts +53 -0
  557. package/src/routing/codegen.ts +143 -176
  558. package/src/routing/convention-lint.ts +357 -0
  559. package/src/routing/index.ts +5 -1
  560. package/src/routing/interception.ts +1 -1
  561. package/src/routing/link-codegen.ts +294 -0
  562. package/src/routing/scanner.ts +107 -110
  563. package/src/routing/segment-classify.ts +188 -0
  564. package/src/routing/types.ts +78 -25
  565. package/src/routing/walkers.ts +90 -0
  566. package/src/rsc-runtime/rsc.ts +2 -0
  567. package/src/rsc-runtime/ssr.ts +50 -0
  568. package/src/rsc-runtime/vendor-types.d.ts +7 -0
  569. package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
  570. package/src/search-params/define.ts +538 -0
  571. package/src/search-params/index.ts +14 -20
  572. package/src/search-params/registry.ts +2 -2
  573. package/src/search-params/wrappers.ts +92 -0
  574. package/src/segment-params/define.ts +332 -0
  575. package/src/segment-params/index.ts +9 -0
  576. package/src/server/access-gate.tsx +76 -34
  577. package/src/server/action-client.ts +88 -15
  578. package/src/server/action-encryption.ts +144 -0
  579. package/src/server/action-handler.ts +112 -14
  580. package/src/server/actions.ts +10 -9
  581. package/src/server/als-registry.ts +35 -7
  582. package/src/server/asset-headers.ts +8 -34
  583. package/src/server/build-manifest.ts +10 -4
  584. package/src/server/compress.ts +25 -7
  585. package/src/server/cookie-context.ts +468 -0
  586. package/src/server/cookie-parsing.ts +135 -0
  587. package/src/server/debug.ts +1 -1
  588. package/src/server/default-logger.ts +99 -0
  589. package/src/server/deny-boundary.ts +218 -0
  590. package/src/server/deny-renderer.ts +31 -50
  591. package/src/server/dev-source-map.ts +31 -0
  592. package/src/server/early-hints-sender.ts +3 -2
  593. package/src/server/early-hints.ts +36 -15
  594. package/src/server/error-boundary-wrapper.ts +74 -22
  595. package/src/server/fallback-error.ts +74 -102
  596. package/src/server/flight-injection-state.ts +113 -0
  597. package/src/server/flight-scripts.ts +62 -0
  598. package/src/server/flush.ts +2 -1
  599. package/src/server/form-data.ts +76 -0
  600. package/src/server/html-injector-core.ts +403 -0
  601. package/src/server/html-injectors.ts +244 -223
  602. package/src/server/index.ts +31 -184
  603. package/src/server/internal.ts +176 -0
  604. package/src/server/logger.ts +67 -36
  605. package/src/server/middleware-runner.ts +75 -4
  606. package/src/server/node-stream-transforms.ts +369 -0
  607. package/src/server/param-coercion.ts +76 -0
  608. package/src/server/pipeline-helpers.ts +204 -0
  609. package/src/server/pipeline-interception.ts +17 -16
  610. package/src/server/pipeline-metadata.ts +13 -0
  611. package/src/server/pipeline-outcome.ts +167 -0
  612. package/src/server/pipeline-phases.ts +409 -0
  613. package/src/server/pipeline.ts +128 -394
  614. package/src/server/port-resolution.ts +215 -0
  615. package/src/server/primitives.ts +111 -28
  616. package/src/server/render-timeout.ts +108 -0
  617. package/src/server/request-context.ts +94 -338
  618. package/src/server/route-element-builder.ts +288 -192
  619. package/src/server/route-handler.ts +24 -4
  620. package/src/server/route-matcher.ts +44 -65
  621. package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
  622. package/src/server/rsc-entry/api-handler.ts +16 -17
  623. package/src/server/rsc-entry/error-renderer.ts +305 -89
  624. package/src/server/rsc-entry/helpers.ts +136 -12
  625. package/src/server/rsc-entry/index.ts +312 -341
  626. package/src/server/rsc-entry/render-route.ts +304 -0
  627. package/src/server/rsc-entry/rsc-payload.ts +65 -18
  628. package/src/server/rsc-entry/rsc-stream.ts +81 -13
  629. package/src/server/rsc-entry/ssr-bridge.ts +14 -5
  630. package/src/server/rsc-entry/ssr-renderer.ts +171 -38
  631. package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
  632. package/src/server/safe-load.ts +60 -0
  633. package/src/server/sensitive-fields.ts +230 -0
  634. package/src/server/sitemap-generator.ts +338 -0
  635. package/src/server/sitemap-handler.ts +126 -0
  636. package/src/server/slot-resolver.ts +245 -230
  637. package/src/server/ssr-entry.ts +215 -32
  638. package/src/server/ssr-render.ts +289 -67
  639. package/src/server/ssr-wrappers.tsx +139 -0
  640. package/src/server/state-tree-diff.ts +4 -1
  641. package/src/server/status-code-resolver.ts +112 -128
  642. package/src/server/stream-utils.ts +213 -0
  643. package/src/server/tracing.ts +21 -10
  644. package/src/server/tree-builder.ts +202 -90
  645. package/src/server/types.ts +55 -6
  646. package/src/server/utils/escape-html.ts +20 -0
  647. package/src/server/version-skew.ts +104 -0
  648. package/src/shared/merge-search-params.ts +55 -0
  649. package/src/shims/font-google.ts +1 -1
  650. package/src/shims/font-local.ts +34 -0
  651. package/src/shims/headers.ts +5 -1
  652. package/src/shims/navigation-client.ts +4 -3
  653. package/src/shims/navigation.ts +14 -7
  654. package/src/utils/state-machine.ts +111 -0
  655. package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
  656. package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
  657. package/dist/_chunks/debug-gwlJkDuf.js +0 -108
  658. package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
  659. package/dist/_chunks/format-DviM89f0.js.map +0 -1
  660. package/dist/_chunks/interception-BOoWmLUA.js +0 -676
  661. package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
  662. package/dist/_chunks/request-context-DIkVh_jG.js +0 -330
  663. package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
  664. package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
  665. package/dist/_chunks/tracing-CemImE6h.js +0 -187
  666. package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
  667. package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
  668. package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
  669. package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
  670. package/dist/cache/register-cached-function.d.ts +0 -17
  671. package/dist/cache/register-cached-function.d.ts.map +0 -1
  672. package/dist/client/browser-entry.d.ts +0 -21
  673. package/dist/client/browser-entry.d.ts.map +0 -1
  674. package/dist/client/link-status-provider.d.ts +0 -11
  675. package/dist/client/link-status-provider.d.ts.map +0 -1
  676. package/dist/client/transition-root.d.ts.map +0 -1
  677. package/dist/client/use-navigation-pending.d.ts.map +0 -1
  678. package/dist/client/use-params.d.ts.map +0 -1
  679. package/dist/plugins/cache-transform.d.ts +0 -36
  680. package/dist/plugins/cache-transform.d.ts.map +0 -1
  681. package/dist/plugins/dev-error-overlay.d.ts +0 -60
  682. package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
  683. package/dist/plugins/dev-logs.d.ts.map +0 -1
  684. package/dist/plugins/dynamic-transform.d.ts +0 -72
  685. package/dist/plugins/dynamic-transform.d.ts.map +0 -1
  686. package/dist/plugins/server-action-exports.d.ts +0 -26
  687. package/dist/plugins/server-action-exports.d.ts.map +0 -1
  688. package/dist/routing/status-file-lint.d.ts +0 -33
  689. package/dist/routing/status-file-lint.d.ts.map +0 -1
  690. package/dist/search-params/analyze.d.ts +0 -54
  691. package/dist/search-params/analyze.d.ts.map +0 -1
  692. package/dist/search-params/builtin-codecs.d.ts +0 -105
  693. package/dist/search-params/builtin-codecs.d.ts.map +0 -1
  694. package/dist/search-params/codecs.d.ts +0 -53
  695. package/dist/search-params/codecs.d.ts.map +0 -1
  696. package/dist/search-params/create.d.ts +0 -106
  697. package/dist/search-params/create.d.ts.map +0 -1
  698. package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
  699. package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
  700. package/dist/server/dev-logger.d.ts.map +0 -1
  701. package/dist/server/dev-span-processor.d.ts.map +0 -1
  702. package/dist/server/dev-warnings.d.ts.map +0 -1
  703. package/dist/server/manifest-status-resolver.d.ts +0 -58
  704. package/dist/server/manifest-status-resolver.d.ts.map +0 -1
  705. package/dist/server/prerender.d.ts +0 -77
  706. package/dist/server/prerender.d.ts.map +0 -1
  707. package/dist/server/response-cache.d.ts +0 -54
  708. package/dist/server/response-cache.d.ts.map +0 -1
  709. package/dist/utils/directive-parser.d.ts +0 -70
  710. package/dist/utils/directive-parser.d.ts.map +0 -1
  711. package/src/cache/register-cached-function.ts +0 -103
  712. package/src/client/browser-entry.ts +0 -678
  713. package/src/client/link-status-provider.tsx +0 -30
  714. package/src/client/transition-root.tsx +0 -166
  715. package/src/plugins/cache-transform.ts +0 -199
  716. package/src/plugins/dev-error-overlay.ts +0 -230
  717. package/src/plugins/dynamic-transform.ts +0 -161
  718. package/src/plugins/server-action-exports.ts +0 -220
  719. package/src/routing/status-file-lint.ts +0 -112
  720. package/src/search-params/analyze.ts +0 -192
  721. package/src/search-params/builtin-codecs.ts +0 -228
  722. package/src/search-params/create.ts +0 -321
  723. package/src/server/dev-fetch-instrumentation.ts +0 -96
  724. package/src/server/dev-span-processor.ts +0 -78
  725. package/src/server/manifest-status-resolver.ts +0 -215
  726. package/src/server/prerender.ts +0 -139
  727. package/src/server/response-cache.ts +0 -410
  728. package/src/utils/directive-parser.ts +0 -529
  729. /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
package/src/fonts/ast.ts CHANGED
@@ -1,15 +1,22 @@
1
1
  /**
2
- * Acorn-based AST utilities for extracting static font configs from source code.
2
+ * AST utilities for extracting static font configs from source code.
3
+ * Uses OXC via Vite's `parseAst` — handles JS/JSX/TS/TSX natively.
3
4
  *
4
- * Replaces the fragile regex-based extraction in fonts.ts and local.ts.
5
- * Uses acorn (already a Vite dependency) for robust parsing that handles
6
- * comments, trailing commas, multi-line configs, and other edge cases
7
- * the regex approach missed.
5
+ * Provides two tiers of API:
6
+ *
7
+ * 1. **Source-text helpers** (`extractFontConfigAst`, `extractLocalFontConfigAst`,
8
+ * `detectDynamicFontCallAst`) — parse a snippet and return extracted config.
9
+ * Still used by tests and callers that have only a string.
10
+ *
11
+ * 2. **AST-node helpers** (`extractGoogleFontConfigFromNode`,
12
+ * `extractLocalFontConfigFromNode`, `findFontCallSites`) — operate on
13
+ * nodes from an already-parsed Program so the transform hook can share
14
+ * one parse with all analysis steps.
8
15
  *
9
16
  * Design doc: 24-fonts.md §"Step 1: Static Analysis"
10
17
  */
11
18
 
12
- import { parse } from 'acorn';
19
+ import { parseAst as viteParseAst } from 'vite';
13
20
  import type { GoogleFontConfig } from './types.js';
14
21
  import type { LocalFontConfig, LocalFontSrc } from './types.js';
15
22
 
@@ -46,20 +53,34 @@ interface IdentifierNode extends AstNode {
46
53
  name: string;
47
54
  }
48
55
 
56
+ // ── Offset → line/column helper ──────────────────────────────────────────────
57
+
58
+ /** Convert a 0-based byte offset into a 1-based line and 0-based column. */
59
+ function offsetToLineColumn(source: string, offset: number): { line: number; column: number } {
60
+ let line = 1;
61
+ let lastNewline = -1;
62
+ for (let i = 0; i < offset; i++) {
63
+ if (source[i] === '\n') {
64
+ line++;
65
+ lastNewline = i;
66
+ }
67
+ }
68
+ return { line, column: offset - lastNewline - 1 };
69
+ }
70
+
49
71
  // ── Core AST extraction helpers ──────────────────────────────────────────────
50
72
 
51
73
  /**
52
74
  * Parse a JavaScript expression string into an AST node.
53
75
  *
54
- * Wraps the expression in parens so acorn treats it as an expression statement.
76
+ * Wraps the expression in parens so OXC (via vite.parseAst) treats it as an expression statement.
55
77
  * Returns null if parsing fails.
56
78
  */
57
79
  function parseExpression(source: string): AstNode | null {
58
80
  try {
59
- const ast = parse(`(${source})`, {
60
- ecmaVersion: 'latest',
61
- sourceType: 'module',
62
- }) as unknown as { body: Array<{ expression: AstNode }> };
81
+ const ast = viteParseAst(`(${source})`, { lang: 'tsx' }) as unknown as {
82
+ body: Array<{ expression: AstNode }>;
83
+ };
63
84
  return ast.body[0]?.expression ?? null;
64
85
  } catch {
65
86
  return null;
@@ -293,7 +314,7 @@ export function extractLocalFontConfigAst(callSource: string): LocalFontConfig |
293
314
  * Detect if source code contains dynamic/computed font function calls
294
315
  * that cannot be statically analyzed.
295
316
  *
296
- * Uses acorn to parse the full source and inspect CallExpression nodes.
317
+ * Uses OXC (via vite.parseAst) to parse the full source and inspect CallExpression nodes.
297
318
  * Returns the offending expression string if found, null if all calls are static.
298
319
  */
299
320
  export function detectDynamicFontCallAst(source: string, importedNames: string[]): string | null {
@@ -301,10 +322,7 @@ export function detectDynamicFontCallAst(source: string, importedNames: string[]
301
322
 
302
323
  let ast;
303
324
  try {
304
- ast = parse(source, {
305
- ecmaVersion: 'latest',
306
- sourceType: 'module',
307
- }) as unknown as { body: AstNode[] };
325
+ ast = viteParseAst(source, { lang: 'tsx' }) as unknown as { body: AstNode[] };
308
326
  } catch {
309
327
  // If we can't parse the source at all, fall back to no detection
310
328
  return null;
@@ -357,3 +375,457 @@ function walkForDynamicCalls(node: AstNode, names: Set<string>, source: string):
357
375
 
358
376
  return null;
359
377
  }
378
+
379
+ // ── AST-node-level config extraction ─────────────────────────────────────────
380
+ //
381
+ // These work on an already-parsed ObjectExpression node so the transform
382
+ // hook can share one OXC (via vite.parseAst) parse of the full source file with all analysis
383
+ // steps (TIM-827).
384
+
385
+ /**
386
+ * Extract a GoogleFontConfig from an ObjectExpression AST node.
387
+ *
388
+ * This is the node-level equivalent of `extractFontConfigAst` — it skips
389
+ * the parse step because the caller already has a parsed Program.
390
+ */
391
+ export function extractGoogleFontConfigFromNode(node: AstNode): GoogleFontConfig | null {
392
+ if (node.type !== 'ObjectExpression') return null;
393
+ return extractGoogleConfig(node as ObjectExpressionNode);
394
+ }
395
+
396
+ /**
397
+ * Extract a LocalFontConfig from an ObjectExpression AST node.
398
+ */
399
+ export function extractLocalFontConfigFromNode(node: AstNode): LocalFontConfig | null {
400
+ if (node.type !== 'ObjectExpression') return null;
401
+ return extractLocalConfig(node as ObjectExpressionNode);
402
+ }
403
+
404
+ /** Shared implementation for GoogleFontConfig extraction from an object node. */
405
+ function extractGoogleConfig(objNode: ObjectExpressionNode): GoogleFontConfig {
406
+ const props = objectProperties(objNode);
407
+ const config: GoogleFontConfig = {};
408
+
409
+ const subsetsNode = props.get('subsets');
410
+ if (subsetsNode) {
411
+ const arr = extractStringArray(subsetsNode);
412
+ if (arr) config.subsets = arr;
413
+ }
414
+
415
+ const weightNode = props.get('weight');
416
+ if (weightNode) {
417
+ const arr = extractStringArray(weightNode);
418
+ if (arr) {
419
+ config.weight = arr;
420
+ } else {
421
+ const s = extractString(weightNode);
422
+ if (s !== undefined) config.weight = s;
423
+ }
424
+ }
425
+
426
+ const displayNode = props.get('display');
427
+ if (displayNode) {
428
+ const s = extractString(displayNode);
429
+ if (s !== undefined) config.display = s as GoogleFontConfig['display'];
430
+ }
431
+
432
+ const variableNode = props.get('variable');
433
+ if (variableNode) {
434
+ const s = extractString(variableNode);
435
+ if (s !== undefined) config.variable = s;
436
+ }
437
+
438
+ const styleNode = props.get('style');
439
+ if (styleNode) {
440
+ const arr = extractStringArray(styleNode);
441
+ if (arr) {
442
+ config.style = arr;
443
+ } else {
444
+ const s = extractString(styleNode);
445
+ if (s !== undefined) config.style = s;
446
+ }
447
+ }
448
+
449
+ const preloadNode = props.get('preload');
450
+ if (preloadNode) {
451
+ const b = extractBoolean(preloadNode);
452
+ if (b !== undefined) config.preload = b;
453
+ }
454
+
455
+ return config;
456
+ }
457
+
458
+ /** Shared implementation for LocalFontConfig extraction from an object node. */
459
+ function extractLocalConfig(objNode: ObjectExpressionNode): LocalFontConfig | null {
460
+ const props = objectProperties(objNode);
461
+
462
+ const displayNode = props.get('display');
463
+ const display = displayNode
464
+ ? (extractString(displayNode) as LocalFontConfig['display'])
465
+ : undefined;
466
+
467
+ const variableNode = props.get('variable');
468
+ const variable = variableNode ? extractString(variableNode) : undefined;
469
+
470
+ const familyNode = props.get('family');
471
+ const family = familyNode ? extractString(familyNode) : undefined;
472
+
473
+ const srcNode = props.get('src');
474
+ if (!srcNode) return null;
475
+
476
+ const srcString = extractString(srcNode);
477
+ if (srcString !== undefined) {
478
+ return { src: srcString, display, variable, family };
479
+ }
480
+
481
+ if (srcNode.type === 'ArrayExpression') {
482
+ const arr = srcNode as ArrayExpressionNode;
483
+ const entries: LocalFontSrc[] = [];
484
+ for (const elem of arr.elements) {
485
+ const entry = extractLocalFontSrcEntry(elem);
486
+ if (!entry) return null;
487
+ entries.push(entry);
488
+ }
489
+ if (entries.length === 0) return null;
490
+ return { src: entries, display, variable, family };
491
+ }
492
+
493
+ return null;
494
+ }
495
+
496
+ // ── Font module specifiers ───────────────────────────────────────────────────
497
+
498
+ const GOOGLE_FONT_SOURCES = new Set([
499
+ '@timber/fonts/google',
500
+ '@timber-js/app/fonts/google',
501
+ 'next/font/google',
502
+ ]);
503
+
504
+ const LOCAL_FONT_SOURCES = new Set([
505
+ '@timber/fonts/local',
506
+ '@timber-js/app/fonts/local',
507
+ 'next/font/local',
508
+ ]);
509
+
510
+ // ── Parsed source types ──────────────────────────────────────────────────────
511
+
512
+ /** A font import binding discovered from an ImportDeclaration. */
513
+ export interface FontBinding {
514
+ /** The local name used in the module (after `as`, if present). */
515
+ localName: string;
516
+ /**
517
+ * The original exported name (before `as`). For Google fonts this is
518
+ * the PascalCase_With_Underscores name that maps to the family. For
519
+ * local fonts (`default` import), this is `'default'`.
520
+ */
521
+ importedName: string;
522
+ /** `'google'` or `'local'`. */
523
+ provider: 'google' | 'local';
524
+ /** The AST node of the ImportDeclaration (for removal via magic-string). */
525
+ importNode: AstNode & { start: number; end: number };
526
+ }
527
+
528
+ /** A font function call site discovered from a CallExpression. */
529
+ export interface FontCallSite {
530
+ /** The binding that this call references. */
531
+ binding: FontBinding;
532
+ /**
533
+ * The variable name this call is assigned to, if the call appears in a
534
+ * VariableDeclarator. `null` for bare expression statements.
535
+ */
536
+ assignedName: string | null;
537
+ /** The first argument AST node (expected to be an ObjectExpression). */
538
+ configNode: AstNode;
539
+ /**
540
+ * The outermost AST node to replace. For a VariableDeclaration with a
541
+ * single declarator this is the full declaration; for a bare expression
542
+ * statement it is the ExpressionStatement. The transform replaces
543
+ * `source[replaceStart..replaceEnd]`.
544
+ */
545
+ replaceStart: number;
546
+ replaceEnd: number;
547
+ /** Line number (1-based) of the call for error messages. */
548
+ line: number;
549
+ /** Column (0-based) of the call for error messages. */
550
+ column: number;
551
+ }
552
+
553
+ /** Result of `findFontCallSites` — everything the transform needs. */
554
+ export interface FontAnalysis {
555
+ bindings: FontBinding[];
556
+ callSites: FontCallSite[];
557
+ /** Import nodes that should be removed (deduplicated). */
558
+ importNodesToRemove: Array<{ start: number; end: number }>;
559
+ /** First dynamic call expression text, or `null`. */
560
+ dynamicCall: string | null;
561
+ /**
562
+ * Font calls found in nested scopes (functions, if-blocks, etc.).
563
+ * These are errors — font calls must be module-level.
564
+ */
565
+ nestedCalls: Array<{ name: string; line: number; column: number }>;
566
+ }
567
+
568
+ interface PositionedNode extends AstNode {
569
+ start: number;
570
+ end: number;
571
+ }
572
+
573
+ interface ImportDeclarationNode extends PositionedNode {
574
+ type: 'ImportDeclaration';
575
+ source: LiteralNode & { value: string };
576
+ specifiers: Array<
577
+ PositionedNode & {
578
+ type: string;
579
+ local: IdentifierNode;
580
+ imported?: IdentifierNode;
581
+ }
582
+ >;
583
+ }
584
+
585
+ interface CallExpressionNode extends PositionedNode {
586
+ type: 'CallExpression';
587
+ callee: AstNode;
588
+ arguments: PositionedNode[];
589
+ }
590
+
591
+ interface VariableDeclaratorNode extends PositionedNode {
592
+ type: 'VariableDeclarator';
593
+ id: AstNode;
594
+ init: AstNode | null;
595
+ }
596
+
597
+ interface VariableDeclarationNode extends PositionedNode {
598
+ type: 'VariableDeclaration';
599
+ declarations: VariableDeclaratorNode[];
600
+ }
601
+
602
+ interface ExpressionStatementNode extends PositionedNode {
603
+ type: 'ExpressionStatement';
604
+ expression: AstNode;
605
+ }
606
+
607
+ interface ProgramNode extends PositionedNode {
608
+ type: 'Program';
609
+ body: PositionedNode[];
610
+ }
611
+
612
+ /**
613
+ * Parse a full source file and find all font imports and call sites.
614
+ *
615
+ * Returns `null` if the source has no font-related imports.
616
+ */
617
+ export function findFontCallSites(source: string): FontAnalysis | null {
618
+ let program: ProgramNode;
619
+ try {
620
+ program = viteParseAst(source, { lang: 'tsx' }) as unknown as ProgramNode;
621
+ } catch {
622
+ return null;
623
+ }
624
+
625
+ // Step 1: Find all font import declarations and build the bindings list.
626
+ const bindings: FontBinding[] = [];
627
+ const importNodesToRemove: Array<{ start: number; end: number }> = [];
628
+
629
+ for (const stmt of program.body) {
630
+ if (stmt.type !== 'ImportDeclaration') continue;
631
+ const importDecl = stmt as unknown as ImportDeclarationNode;
632
+ const specSource = importDecl.source.value;
633
+
634
+ let provider: 'google' | 'local' | null = null;
635
+ if (GOOGLE_FONT_SOURCES.has(specSource)) provider = 'google';
636
+ else if (LOCAL_FONT_SOURCES.has(specSource)) provider = 'local';
637
+ if (!provider) continue;
638
+
639
+ for (const spec of importDecl.specifiers) {
640
+ if (spec.type === 'ImportSpecifier' && provider === 'google') {
641
+ bindings.push({
642
+ localName: spec.local.name,
643
+ importedName: spec.imported?.name ?? spec.local.name,
644
+ provider,
645
+ importNode: importDecl,
646
+ });
647
+ } else if (spec.type === 'ImportDefaultSpecifier' && provider === 'local') {
648
+ bindings.push({
649
+ localName: spec.local.name,
650
+ importedName: 'default',
651
+ provider,
652
+ importNode: importDecl,
653
+ });
654
+ }
655
+ // ImportNamespaceSpecifier (`import * as fonts from ...`) is not
656
+ // currently supported — the old regex didn't handle it either.
657
+ // If we add it later, we'd need to also handle `fonts.Inter(...)`
658
+ // member expressions in the call-site walk.
659
+ }
660
+
661
+ importNodesToRemove.push({ start: importDecl.start, end: importDecl.end });
662
+ }
663
+
664
+ if (bindings.length === 0) return null;
665
+
666
+ // Step 2: Walk the AST for CallExpression nodes whose callee is a font binding.
667
+ const bindingsByName = new Map(bindings.map((b) => [b.localName, b]));
668
+ const callSites: FontCallSite[] = [];
669
+ let dynamicCall: string | null = null;
670
+
671
+ for (const stmt of program.body) {
672
+ // VariableDeclaration: `const inter = Inter({ ... })`
673
+ if (stmt.type === 'VariableDeclaration') {
674
+ const varDecl = stmt as unknown as VariableDeclarationNode;
675
+ for (const declarator of varDecl.declarations) {
676
+ if (!declarator.init || declarator.init.type !== 'CallExpression') continue;
677
+ const call = declarator.init as unknown as CallExpressionNode;
678
+ const site = matchCallExpression(call, bindingsByName, source);
679
+ if (!site) continue;
680
+
681
+ if (site === 'dynamic') {
682
+ if (!dynamicCall) {
683
+ const calleeName = (call.callee as IdentifierNode).name;
684
+ const argStart = call.arguments[0].start;
685
+ const argEnd = call.arguments[0].end;
686
+ dynamicCall = `${calleeName}(${source.slice(argStart, argEnd)})`;
687
+ }
688
+ continue;
689
+ }
690
+
691
+ const assignedName =
692
+ declarator.id.type === 'Identifier' ? (declarator.id as IdentifierNode).name : null;
693
+
694
+ const { line, column } = offsetToLineColumn(source, call.start);
695
+ callSites.push({
696
+ binding: site.binding,
697
+ assignedName,
698
+ configNode: site.configNode,
699
+ replaceStart: call.start,
700
+ replaceEnd: call.end,
701
+ line,
702
+ column,
703
+ });
704
+ }
705
+ }
706
+
707
+ // ExpressionStatement: `Inter({ ... })` as a bare call
708
+ if (stmt.type === 'ExpressionStatement') {
709
+ const exprStmt = stmt as unknown as ExpressionStatementNode;
710
+ if (exprStmt.expression.type === 'CallExpression') {
711
+ const call = exprStmt.expression as unknown as CallExpressionNode;
712
+ const site = matchCallExpression(call, bindingsByName, source);
713
+ if (site && site !== 'dynamic') {
714
+ const { line, column } = offsetToLineColumn(source, call.start);
715
+ callSites.push({
716
+ binding: site.binding,
717
+ assignedName: null,
718
+ configNode: site.configNode,
719
+ replaceStart: (exprStmt as PositionedNode).start,
720
+ replaceEnd: (exprStmt as PositionedNode).end,
721
+ line,
722
+ column,
723
+ });
724
+ } else if (site === 'dynamic' && !dynamicCall) {
725
+ const calleeName = (call.callee as IdentifierNode).name;
726
+ const argStart = call.arguments[0].start;
727
+ const argEnd = call.arguments[0].end;
728
+ dynamicCall = `${calleeName}(${source.slice(argStart, argEnd)})`;
729
+ }
730
+ }
731
+ }
732
+ }
733
+
734
+ // Step 3: Walk nested scopes to find font calls that aren't module-level.
735
+ // Font calls must be at module scope (same constraint as Next.js).
736
+ // If the import is removed but a nested call remains, it's a ReferenceError.
737
+ const nestedCalls: Array<{ name: string; line: number; column: number }> = [];
738
+ for (const stmt of program.body) {
739
+ if (stmt.type === 'ImportDeclaration') continue;
740
+ walkForNestedFontCalls(stmt as AstNode, bindingsByName, source, nestedCalls, false);
741
+ }
742
+
743
+ return { bindings, callSites, importNodesToRemove, dynamicCall, nestedCalls };
744
+ }
745
+
746
+ /**
747
+ * Recursively walk an AST node looking for font CallExpressions in nested
748
+ * scopes (function bodies, if-blocks, loops, etc.). Font calls must be
749
+ * module-level; nested calls are collected as errors.
750
+ *
751
+ * `isNested` tracks whether we've descended past the top-level statement.
752
+ * Top-level VariableDeclarations and ExpressionStatements are already
753
+ * handled by the main loop in `findFontCallSites`, so we only flag calls
754
+ * found deeper.
755
+ */
756
+ function walkForNestedFontCalls(
757
+ node: AstNode,
758
+ bindings: Map<string, FontBinding>,
759
+ source: string,
760
+ out: Array<{ name: string; line: number; column: number }>,
761
+ isNested: boolean
762
+ ): void {
763
+ if (!node || typeof node !== 'object') return;
764
+
765
+ if (node.type === 'CallExpression') {
766
+ const callee = node.callee as AstNode;
767
+ if (isNested && callee.type === 'Identifier' && bindings.has((callee as IdentifierNode).name)) {
768
+ const pos = offsetToLineColumn(source, (node as PositionedNode).start);
769
+ out.push({ name: (callee as IdentifierNode).name, line: pos.line, column: pos.column });
770
+ return; // Don't recurse into this call's children
771
+ }
772
+ }
773
+
774
+ // These node types introduce a nested scope — any font call inside is an error.
775
+ const scopeTypes = new Set([
776
+ 'FunctionDeclaration',
777
+ 'FunctionExpression',
778
+ 'ArrowFunctionExpression',
779
+ 'IfStatement',
780
+ 'ForStatement',
781
+ 'ForInStatement',
782
+ 'ForOfStatement',
783
+ 'WhileStatement',
784
+ 'DoWhileStatement',
785
+ 'SwitchStatement',
786
+ 'TryStatement',
787
+ 'BlockStatement',
788
+ 'ClassDeclaration',
789
+ 'ClassExpression',
790
+ ]);
791
+ const enterNested = isNested || scopeTypes.has(node.type);
792
+
793
+ for (const key of Object.keys(node)) {
794
+ if (key === 'type') continue;
795
+ const child = node[key];
796
+ if (Array.isArray(child)) {
797
+ for (const item of child) {
798
+ if (item && typeof item === 'object' && (item as AstNode).type) {
799
+ walkForNestedFontCalls(item as AstNode, bindings, source, out, enterNested);
800
+ }
801
+ }
802
+ } else if (child && typeof child === 'object' && (child as AstNode).type) {
803
+ walkForNestedFontCalls(child as AstNode, bindings, source, out, enterNested);
804
+ }
805
+ }
806
+ }
807
+
808
+ /**
809
+ * Match a CallExpression against the font bindings map.
810
+ *
811
+ * Returns the binding + config node if the call is a static font call,
812
+ * `'dynamic'` if it's a font call with a non-object argument, or `null`
813
+ * if the callee doesn't match any font binding.
814
+ */
815
+ function matchCallExpression(
816
+ call: CallExpressionNode,
817
+ bindings: Map<string, FontBinding>,
818
+ _source: string
819
+ ): { binding: FontBinding; configNode: AstNode } | 'dynamic' | null {
820
+ if (call.callee.type !== 'Identifier') return null;
821
+ const calleeName = (call.callee as IdentifierNode).name;
822
+ const binding = bindings.get(calleeName);
823
+ if (!binding) return null;
824
+
825
+ const args = call.arguments;
826
+ if (args.length === 0 || args[0].type !== 'ObjectExpression') {
827
+ return 'dynamic';
828
+ }
829
+
830
+ return { binding, configNode: args[0] };
831
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Build-output emission for the timber-fonts plugin.
3
+ *
4
+ * Splits the `generateBundle` hook into pure helpers so the plugin shell
5
+ * can stay focused on Vite wiring. The functions here are deliberately
6
+ * Rollup-agnostic — they take an `EmitFile` callback so the plugin can
7
+ * pass `this.emitFile` from the `generateBundle` context.
8
+ *
9
+ * Design doc: 24-fonts.md
10
+ */
11
+
12
+ import { readFileSync, existsSync } from 'node:fs';
13
+ import { resolve, normalize } from 'node:path';
14
+ import type { ManifestFontEntry, BuildManifest } from '../server/build-manifest.js';
15
+
16
+ /**
17
+ * Minimal shape of the asset descriptor accepted by Rollup's `emitFile`.
18
+ * Declared inline rather than importing from `rollup` to keep `bundle.ts`
19
+ * Rollup-agnostic and avoid pulling the type into the build graph.
20
+ */
21
+ interface EmittedAsset {
22
+ type: 'asset';
23
+ fileName: string;
24
+ source: string | Uint8Array;
25
+ }
26
+ import type { FontPipeline } from './pipeline.js';
27
+ import type { CachedFont } from './google.js';
28
+ import { inferFontFormat } from './local.js';
29
+
30
+ type EmitFile = (asset: EmittedAsset) => string;
31
+ type EmitWarning = (msg: string) => void;
32
+
33
+ /** Group cached Google Font binaries by lowercase family name. */
34
+ export function groupCachedFontsByFamily(
35
+ cachedFonts: readonly CachedFont[]
36
+ ): Map<string, CachedFont[]> {
37
+ const cachedByFamily = new Map<string, CachedFont[]>();
38
+ for (const cf of cachedFonts) {
39
+ const key = cf.face.family.toLowerCase();
40
+ const arr = cachedByFamily.get(key) ?? [];
41
+ arr.push(cf);
42
+ cachedByFamily.set(key, arr);
43
+ }
44
+ return cachedByFamily;
45
+ }
46
+
47
+ /**
48
+ * Emit cached Google Font binaries and local font files into the build
49
+ * output under `_timber/fonts/`. Local files missing on disk produce a
50
+ * warning rather than an error so the build still succeeds.
51
+ *
52
+ * Cached Google Font binaries are deduplicated by `hashedFilename` so
53
+ * each unique file is written exactly once even when multiple font
54
+ * entries share a family (and therefore share `CachedFont` references).
55
+ */
56
+ export function emitFontAssets(
57
+ pipeline: FontPipeline,
58
+ emitFile: EmitFile,
59
+ warn: EmitWarning
60
+ ): void {
61
+ // Cached Google Font binaries (content-hashed, deduped by filename)
62
+ for (const cf of pipeline.uniqueCachedFiles()) {
63
+ emitFile({
64
+ type: 'asset',
65
+ fileName: `_timber/fonts/${cf.hashedFilename}`,
66
+ source: cf.data,
67
+ });
68
+ }
69
+
70
+ // Local font files (emitted by basename)
71
+ for (const font of pipeline.fonts()) {
72
+ if (font.provider !== 'local' || !font.localSources) continue;
73
+ for (const src of font.localSources) {
74
+ const absolutePath = normalize(resolve(src.path));
75
+ if (!existsSync(absolutePath)) {
76
+ warn(`Local font file not found: ${absolutePath}`);
77
+ continue;
78
+ }
79
+ const basename = src.path.split('/').pop() ?? src.path;
80
+ const data = readFileSync(absolutePath);
81
+ emitFile({
82
+ type: 'asset',
83
+ fileName: `_timber/fonts/${basename}`,
84
+ source: data,
85
+ });
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Populate `buildManifest.fonts` with `ManifestFontEntry[]` keyed by the
92
+ * importer module path (relative to the project root, matching how Vite's
93
+ * `manifest.json` keys css/js).
94
+ *
95
+ * Google fonts use the content-hashed filenames produced during
96
+ * `buildStart`. Local fonts use the source basename.
97
+ */
98
+ export function writeFontManifest(
99
+ pipeline: FontPipeline,
100
+ buildManifest: BuildManifest,
101
+ rootDir: string
102
+ ): void {
103
+ const fontsByImporter = new Map<string, ManifestFontEntry[]>();
104
+
105
+ for (const entry of pipeline.entries()) {
106
+ const manifestEntries = fontsByImporter.get(entry.importer) ?? [];
107
+
108
+ if (entry.provider === 'local' && entry.localSources) {
109
+ for (const src of entry.localSources) {
110
+ const filename = src.path.split('/').pop() ?? src.path;
111
+ const format = inferFontFormat(src.path);
112
+ manifestEntries.push({
113
+ href: `/_timber/fonts/${filename}`,
114
+ format,
115
+ crossOrigin: 'anonymous',
116
+ });
117
+ }
118
+ } else if (entry.cachedFiles) {
119
+ // Google fonts: use the per-entry cached files attached during
120
+ // buildStart. Each entry owns its own cached binaries (TIM-829),
121
+ // so we no longer need a family-grouped lookup.
122
+ for (const cf of entry.cachedFiles) {
123
+ manifestEntries.push({
124
+ href: `/_timber/fonts/${cf.hashedFilename}`,
125
+ format: 'woff2',
126
+ crossOrigin: 'anonymous',
127
+ });
128
+ }
129
+ }
130
+
131
+ fontsByImporter.set(entry.importer, manifestEntries);
132
+ }
133
+
134
+ // Normalize importer paths to be relative to project root (matching how
135
+ // Vite's manifest.json keys work for css/js).
136
+ for (const [importer, entries] of fontsByImporter) {
137
+ const relativePath = importer.startsWith(rootDir)
138
+ ? importer.slice(rootDir.length + 1)
139
+ : importer;
140
+ buildManifest.fonts[relativePath] = entries;
141
+ }
142
+ }
package/src/fonts/css.ts CHANGED
@@ -39,6 +39,7 @@ export function generateFontFaces(descriptors: FontFaceDescriptor[]): string {
39
39
  * ```css
40
40
  * .timber-font-inter {
41
41
  * --font-sans: 'Inter', 'Inter Fallback', system-ui, sans-serif;
42
+ * font-family: 'Inter', 'Inter Fallback', system-ui, sans-serif;
42
43
  * }
43
44
  * ```
44
45
  */
@@ -47,7 +48,7 @@ export function generateVariableClass(
47
48
  variable: string,
48
49
  fontFamily: string
49
50
  ): string {
50
- return `.${className} {\n ${variable}: ${fontFamily};\n}`;
51
+ return `.${className} {\n ${variable}: ${fontFamily};\n font-family: ${fontFamily};\n}`;
51
52
  }
52
53
 
53
54
  /**