@lovrozagar/flare 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/package.json +146 -0
  4. package/scripts/download-fonts.ts +136 -0
  5. package/scripts/populate-fonts.ts +721 -0
  6. package/src/await.ts +2 -0
  7. package/src/boundaries/index.ts +99 -0
  8. package/src/broadcast/channel.ts +65 -0
  9. package/src/broadcast/context.ts +12 -0
  10. package/src/broadcast/index.ts +75 -0
  11. package/src/broadcast/provider.tsx +7 -0
  12. package/src/build-location.ts +2 -0
  13. package/src/caches/index.ts +384 -0
  14. package/src/client/index.ts +75 -0
  15. package/src/client.tsx +2 -0
  16. package/src/codegen/index.ts +41 -0
  17. package/src/components/await.tsx +140 -0
  18. package/src/components/dev-error-overlay.tsx +154 -0
  19. package/src/components/direction-script.tsx +22 -0
  20. package/src/components/index.ts +150 -0
  21. package/src/components/locale-script.tsx +26 -0
  22. package/src/components/reset-css.tsx +14 -0
  23. package/src/components/ssr-context.tsx +37 -0
  24. package/src/components/theme-script.tsx +22 -0
  25. package/src/components/view-transition-css.tsx +21 -0
  26. package/src/config/index.ts +84 -0
  27. package/src/create-client-only-fn.ts +1 -0
  28. package/src/create-isomorphic-fn.ts +2 -0
  29. package/src/create-layout.ts +1 -0
  30. package/src/create-page.ts +1 -0
  31. package/src/create-path-segment.ts +1 -0
  32. package/src/create-query-client-getter.ts +2 -0
  33. package/src/create-root-layout.ts +1 -0
  34. package/src/create-router.ts +8 -0
  35. package/src/create-server-only-fn.ts +1 -0
  36. package/src/dedupe/index.ts +151 -0
  37. package/src/defer/index.ts +82 -0
  38. package/src/direction/index.tsx +163 -0
  39. package/src/direction.ts +3 -0
  40. package/src/duration/index.ts +18 -0
  41. package/src/env-fn/index.ts +101 -0
  42. package/src/env-fn.ts +2 -0
  43. package/src/errors/index.ts +166 -0
  44. package/src/fonts/abeezee.ts +50 -0
  45. package/src/fonts/abel.ts +26 -0
  46. package/src/fonts/abril-fatface.ts +34 -0
  47. package/src/fonts/acme.ts +26 -0
  48. package/src/fonts/advent-pro.ts +92 -0
  49. package/src/fonts/alegreya-sans.ts +228 -0
  50. package/src/fonts/alegreya.ts +228 -0
  51. package/src/fonts/alex-brush.ts +42 -0
  52. package/src/fonts/alfa-slab-one.ts +42 -0
  53. package/src/fonts/alice.ts +48 -0
  54. package/src/fonts/amatic-sc.ts +94 -0
  55. package/src/fonts/amiri.ts +114 -0
  56. package/src/fonts/antic-slab.ts +26 -0
  57. package/src/fonts/anton.ts +42 -0
  58. package/src/fonts/archivo-black.ts +34 -0
  59. package/src/fonts/archivo-narrow.ts +114 -0
  60. package/src/fonts/archivo.ts +66 -0
  61. package/src/fonts/arimo.ts +256 -0
  62. package/src/fonts/arvo.ts +50 -0
  63. package/src/fonts/asap.ts +66 -0
  64. package/src/fonts/assistant.ts +64 -0
  65. package/src/fonts/baloo-2.ts +82 -0
  66. package/src/fonts/barlow-condensed.ts +114 -0
  67. package/src/fonts/barlow-semi-condensed.ts +114 -0
  68. package/src/fonts/barlow.ts +114 -0
  69. package/src/fonts/be-vietnam-pro.ts +114 -0
  70. package/src/fonts/bebas-neue.ts +34 -0
  71. package/src/fonts/besley.ts +82 -0
  72. package/src/fonts/biorhyme.ts +50 -0
  73. package/src/fonts/bitter.ts +94 -0
  74. package/src/fonts/black-ops-one.ts +49 -0
  75. package/src/fonts/bree-serif.ts +34 -0
  76. package/src/fonts/bricolage-grotesque.ts +66 -0
  77. package/src/fonts/cabin.ts +114 -0
  78. package/src/fonts/cairo.ts +66 -0
  79. package/src/fonts/cardo.ts +193 -0
  80. package/src/fonts/catamaran.ts +41 -0
  81. package/src/fonts/caveat.ts +78 -0
  82. package/src/fonts/chakra-petch.ts +142 -0
  83. package/src/fonts/chivo.ts +66 -0
  84. package/src/fonts/cinzel.ts +50 -0
  85. package/src/fonts/comfortaa.ts +109 -0
  86. package/src/fonts/commissioner.ts +64 -0
  87. package/src/fonts/component.tsx +27 -0
  88. package/src/fonts/cormorant-garamond.ts +171 -0
  89. package/src/fonts/cormorant.ts +170 -0
  90. package/src/fonts/courgette.ts +34 -0
  91. package/src/fonts/courier-prime.ts +82 -0
  92. package/src/fonts/create-font.ts +47 -0
  93. package/src/fonts/create-registry-font.ts +40 -0
  94. package/src/fonts/crete-round.ts +50 -0
  95. package/src/fonts/crimson-text.ts +114 -0
  96. package/src/fonts/css.ts +86 -0
  97. package/src/fonts/dancing-script.ts +66 -0
  98. package/src/fonts/dm-mono.ts +50 -0
  99. package/src/fonts/dm-sans.ts +50 -0
  100. package/src/fonts/dm-serif-display.ts +50 -0
  101. package/src/fonts/domine.ts +50 -0
  102. package/src/fonts/dosis.ts +66 -0
  103. package/src/fonts/eb-garamond.ts +228 -0
  104. package/src/fonts/eczar.ts +94 -0
  105. package/src/fonts/encode-sans.ts +42 -0
  106. package/src/fonts/epilogue.ts +66 -0
  107. package/src/fonts/exo-2.ts +94 -0
  108. package/src/fonts/exo.ts +66 -0
  109. package/src/fonts/figtree.ts +82 -0
  110. package/src/fonts/fira-code.ts +121 -0
  111. package/src/fonts/fira-sans-condensed.ts +228 -0
  112. package/src/fonts/fira-sans.ts +228 -0
  113. package/src/fonts/fjalla-one.ts +49 -0
  114. package/src/fonts/font-urls.gen.json +1962 -0
  115. package/src/fonts/fraunces.ts +66 -0
  116. package/src/fonts/fredoka.ts +64 -0
  117. package/src/fonts/gelasio.ts +114 -0
  118. package/src/fonts/gloria-hallelujah.ts +34 -0
  119. package/src/fonts/gothic-a1.ts +124 -0
  120. package/src/fonts/great-vibes.ts +64 -0
  121. package/src/fonts/gudea.ts +66 -0
  122. package/src/fonts/heebo.ts +57 -0
  123. package/src/fonts/hind-siliguri.ts +66 -0
  124. package/src/fonts/hind.ts +66 -0
  125. package/src/fonts/ibm-plex-mono.ts +172 -0
  126. package/src/fonts/ibm-plex-sans-arabic.ts +80 -0
  127. package/src/fonts/ibm-plex-sans.ts +199 -0
  128. package/src/fonts/ibm-plex-serif.ts +171 -0
  129. package/src/fonts/inconsolata.ts +66 -0
  130. package/src/fonts/index.ts +4 -0
  131. package/src/fonts/indie-flower.ts +34 -0
  132. package/src/fonts/instrument-sans.ts +82 -0
  133. package/src/fonts/instrument-serif.ts +50 -0
  134. package/src/fonts/inter-display.ts +52 -0
  135. package/src/fonts/inter-tight.ts +124 -0
  136. package/src/fonts/inter.ts +123 -0
  137. package/src/fonts/jetbrains-mono.ts +199 -0
  138. package/src/fonts/josefin-sans.ts +114 -0
  139. package/src/fonts/josefin-slab.ts +50 -0
  140. package/src/fonts/jost.ts +64 -0
  141. package/src/fonts/kalam.ts +66 -0
  142. package/src/fonts/kanit.ts +142 -0
  143. package/src/fonts/karla.ts +82 -0
  144. package/src/fonts/khand.ts +66 -0
  145. package/src/fonts/lato.ts +82 -0
  146. package/src/fonts/league-spartan.ts +42 -0
  147. package/src/fonts/lexend-deca.ts +42 -0
  148. package/src/fonts/lexend.ts +42 -0
  149. package/src/fonts/libre-baskerville.ts +82 -0
  150. package/src/fonts/libre-franklin.ts +95 -0
  151. package/src/fonts/lilita-one.ts +34 -0
  152. package/src/fonts/lobster-two.ts +50 -0
  153. package/src/fonts/lobster.ts +56 -0
  154. package/src/fonts/lora.ts +235 -0
  155. package/src/fonts/m-plus-rounded-1c.ts +138 -0
  156. package/src/fonts/manrope.ts +109 -0
  157. package/src/fonts/maven-pro.ts +66 -0
  158. package/src/fonts/merriweather-sans.ts +142 -0
  159. package/src/fonts/merriweather.ts +171 -0
  160. package/src/fonts/montserrat-alternates.ts +171 -0
  161. package/src/fonts/montserrat.ts +94 -0
  162. package/src/fonts/mukta.ts +66 -0
  163. package/src/fonts/mulish.ts +170 -0
  164. package/src/fonts/nanum-gothic.ts +34 -0
  165. package/src/fonts/nanum-myeongjo.ts +34 -0
  166. package/src/fonts/neuton.ts +66 -0
  167. package/src/fonts/newsreader.ts +114 -0
  168. package/src/fonts/noticia-text.ts +114 -0
  169. package/src/fonts/noto-sans-arabic.ts +58 -0
  170. package/src/fonts/noto-sans-hk.ts +49 -0
  171. package/src/fonts/noto-sans-jp.ts +49 -0
  172. package/src/fonts/noto-sans-kr.ts +49 -0
  173. package/src/fonts/noto-sans-sc.ts +49 -0
  174. package/src/fonts/noto-sans-tc.ts +49 -0
  175. package/src/fonts/noto-sans.ts +140 -0
  176. package/src/fonts/noto-serif-jp.ts +80 -0
  177. package/src/fonts/noto-serif.ts +140 -0
  178. package/src/fonts/nunito-sans.ts +170 -0
  179. package/src/fonts/nunito.ts +170 -0
  180. package/src/fonts/old-standard-tt.ts +133 -0
  181. package/src/fonts/onest.ts +48 -0
  182. package/src/fonts/open-sans.ts +340 -0
  183. package/src/fonts/orbitron.ts +34 -0
  184. package/src/fonts/oswald.ts +94 -0
  185. package/src/fonts/outfit.ts +34 -0
  186. package/src/fonts/overpass.ts +94 -0
  187. package/src/fonts/oxygen.ts +50 -0
  188. package/src/fonts/pacifico.ts +56 -0
  189. package/src/fonts/passion-one.ts +50 -0
  190. package/src/fonts/pathway-gothic-one.ts +34 -0
  191. package/src/fonts/permanent-marker.ts +26 -0
  192. package/src/fonts/philosopher.ts +172 -0
  193. package/src/fonts/play.ts +109 -0
  194. package/src/fonts/playfair-display.ts +142 -0
  195. package/src/fonts/plus-jakarta-sans.ts +142 -0
  196. package/src/fonts/poppins.ts +114 -0
  197. package/src/fonts/prompt.ts +142 -0
  198. package/src/fonts/pt-sans-narrow.ts +78 -0
  199. package/src/fonts/pt-sans.ts +138 -0
  200. package/src/fonts/pt-serif.ts +138 -0
  201. package/src/fonts/public-sans.ts +66 -0
  202. package/src/fonts/questrial.ts +42 -0
  203. package/src/fonts/quicksand.ts +66 -0
  204. package/src/fonts/rajdhani.ts +66 -0
  205. package/src/fonts/raleway.ts +94 -0
  206. package/src/fonts/recursive.ts +80 -0
  207. package/src/fonts/red-hat-display.ts +82 -0
  208. package/src/fonts/red-rose.ts +66 -0
  209. package/src/fonts/registry.gen.ts +173 -0
  210. package/src/fonts/righteous.ts +34 -0
  211. package/src/fonts/roboto-condensed.ts +124 -0
  212. package/src/fonts/roboto-flex.ts +64 -0
  213. package/src/fonts/roboto-mono.ts +199 -0
  214. package/src/fonts/roboto-slab.ts +72 -0
  215. package/src/fonts/roboto.ts +156 -0
  216. package/src/fonts/rokkitt.ts +66 -0
  217. package/src/fonts/rubik.ts +199 -0
  218. package/src/fonts/sacramento.ts +34 -0
  219. package/src/fonts/saira.ts +66 -0
  220. package/src/fonts/sarabun.ts +142 -0
  221. package/src/fonts/satisfy.ts +26 -0
  222. package/src/fonts/sawarabi-mincho.ts +41 -0
  223. package/src/fonts/shadows-into-light.ts +34 -0
  224. package/src/fonts/signika-negative.ts +66 -0
  225. package/src/fonts/signika.ts +66 -0
  226. package/src/fonts/slabo-27px.ts +34 -0
  227. package/src/fonts/sora.ts +50 -0
  228. package/src/fonts/source-code-pro.ts +228 -0
  229. package/src/fonts/source-sans-3.ts +228 -0
  230. package/src/fonts/source-serif-4.ts +199 -0
  231. package/src/fonts/space-grotesk.ts +66 -0
  232. package/src/fonts/space-mono.ts +114 -0
  233. package/src/fonts/spectral.ts +170 -0
  234. package/src/fonts/tajawal.ts +50 -0
  235. package/src/fonts/teko.ts +66 -0
  236. package/src/fonts/tenor-sans.ts +41 -0
  237. package/src/fonts/tinos.ts +256 -0
  238. package/src/fonts/titillium-web.ts +82 -0
  239. package/src/fonts/types.ts +43 -0
  240. package/src/fonts/ubuntu-condensed.ts +63 -0
  241. package/src/fonts/ubuntu-mono.ts +195 -0
  242. package/src/fonts/ubuntu.ts +195 -0
  243. package/src/fonts/unbounded.ts +94 -0
  244. package/src/fonts/unicode-ranges.gen.ts +28 -0
  245. package/src/fonts/urbanist.ts +50 -0
  246. package/src/fonts/varela-round.ts +49 -0
  247. package/src/fonts/vollkorn.ts +199 -0
  248. package/src/fonts/work-sans.ts +66 -0
  249. package/src/fonts/yanone-kaffeesatz.ts +128 -0
  250. package/src/fonts/yantramanav.ts +66 -0
  251. package/src/fonts/yellowtail.ts +34 -0
  252. package/src/fonts/young-serif.ts +34 -0
  253. package/src/fonts/zen-kaku-gothic-new.ts +64 -0
  254. package/src/fonts/zilla-slab.ts +82 -0
  255. package/src/form/index.tsx +205 -0
  256. package/src/generators/index.ts +1589 -0
  257. package/src/head-client/index.ts +649 -0
  258. package/src/history/index.ts +210 -0
  259. package/src/hooks.ts +61 -0
  260. package/src/hydrate/index.tsx +381 -0
  261. package/src/hydration/index.ts +187 -0
  262. package/src/i18n/index.ts +250 -0
  263. package/src/i18n/jsx.tsx +42 -0
  264. package/src/i18n/message-format.ts +174 -0
  265. package/src/image/index.tsx +473 -0
  266. package/src/image.ts +12 -0
  267. package/src/intercept-outlet/index.tsx +18 -0
  268. package/src/intercept-outlet.ts +2 -0
  269. package/src/internal/index.ts +143 -0
  270. package/src/internal/once-idle.ts +24 -0
  271. package/src/internal.ts +12 -0
  272. package/src/lazy/index.tsx +205 -0
  273. package/src/link/index.tsx +367 -0
  274. package/src/loader-pipeline/index.ts +639 -0
  275. package/src/locale/index.tsx +137 -0
  276. package/src/locale.ts +3 -0
  277. package/src/logger.ts +22 -0
  278. package/src/middleware/builtins/api-proxy.ts +64 -0
  279. package/src/middleware/builtins/cdn-proxy.ts +58 -0
  280. package/src/middleware/builtins/i18n.ts +256 -0
  281. package/src/middleware/builtins/keepalive.ts +24 -0
  282. package/src/middleware/builtins/markdown-negotiation.ts +141 -0
  283. package/src/middleware/builtins/static-assets.ts +32 -0
  284. package/src/middleware/index.ts +223 -0
  285. package/src/module-graph/index.ts +181 -0
  286. package/src/mount/index.ts +146 -0
  287. package/src/navigate.ts +1 -0
  288. package/src/navigation/index.ts +1278 -0
  289. package/src/navigation/types.ts +59 -0
  290. package/src/navigation-progress/index.tsx +247 -0
  291. package/src/navigation-progress.ts +1 -0
  292. package/src/ndjson-client/index.ts +376 -0
  293. package/src/ndjson-server/index.ts +284 -0
  294. package/src/outlet/index.tsx +633 -0
  295. package/src/outlet/types.ts +243 -0
  296. package/src/plugins/css-transform.ts +70 -0
  297. package/src/plugins/dev-cdn-cache.ts +454 -0
  298. package/src/plugins/dev-dashboard/client.tsx +2603 -0
  299. package/src/plugins/dev-dashboard/match-route-tree.ts +159 -0
  300. package/src/plugins/dev-dashboard/plugin.ts +404 -0
  301. package/src/plugins/dev-prerender.ts +168 -0
  302. package/src/plugins/dev-server.ts +327 -0
  303. package/src/plugins/generate-watch.ts +32 -0
  304. package/src/plugins/image-plugin.ts +171 -0
  305. package/src/plugins/index.ts +445 -0
  306. package/src/plugins/options.ts +37 -0
  307. package/src/plugins/parse-utils.ts +59 -0
  308. package/src/plugins/prerender-plugin.ts +144 -0
  309. package/src/plugins/purge.ts +242 -0
  310. package/src/plugins/server-fn.ts +641 -0
  311. package/src/plugins/service-worker.ts +225 -0
  312. package/src/plugins/solid-jsx.d.ts +12 -0
  313. package/src/plugins/sx-ast/atomic.ts +166 -0
  314. package/src/plugins/sx-ast/evaluator.ts +235 -0
  315. package/src/plugins/sx-ast/index.ts +372 -0
  316. package/src/plugins/sx-ast/parser.ts +22 -0
  317. package/src/plugins/sx-ast/rewrite.ts +763 -0
  318. package/src/plugins/sx.d.ts +14 -0
  319. package/src/plugins/tw-compile.ts +240 -0
  320. package/src/plugins/types.ts +41 -0
  321. package/src/plugins/virtual.d.ts +110 -0
  322. package/src/plugins/virtual.ts +184 -0
  323. package/src/preload/index.ts +77 -0
  324. package/src/prerender/index.ts +431 -0
  325. package/src/query-client/index.tsx +168 -0
  326. package/src/registry/index.ts +88 -0
  327. package/src/reset-css.ts +1 -0
  328. package/src/revalidation/index.ts +84 -0
  329. package/src/rewrite/index.ts +83 -0
  330. package/src/route-builder/create-layout.ts +655 -0
  331. package/src/route-builder/create-page.ts +806 -0
  332. package/src/route-builder/create-path-segment.ts +34 -0
  333. package/src/route-builder/create-root-layout.ts +608 -0
  334. package/src/route-builder/index.ts +49 -0
  335. package/src/route-builder/register.ts +242 -0
  336. package/src/route-builder/types.ts +294 -0
  337. package/src/router-config/index.ts +91 -0
  338. package/src/router-primitives/index.ts +25 -0
  339. package/src/router-primitives/location.ts +29 -0
  340. package/src/router-primitives/match-id.ts +111 -0
  341. package/src/router-primitives/paths.ts +109 -0
  342. package/src/router-primitives/tree.ts +243 -0
  343. package/src/router-primitives/types.ts +74 -0
  344. package/src/router.ts +31 -0
  345. package/src/search-engine/bing.ts +32 -0
  346. package/src/search-engine/google-jwt.ts +95 -0
  347. package/src/search-engine/google.ts +139 -0
  348. package/src/search-engine/index-now.ts +64 -0
  349. package/src/search-engine/index.ts +12 -0
  350. package/src/security/index.ts +230 -0
  351. package/src/server/index.ts +286 -0
  352. package/src/server-context/browser.ts +113 -0
  353. package/src/server-context/index.ts +217 -0
  354. package/src/server-fn/index.ts +710 -0
  355. package/src/server-fn-query.ts +169 -0
  356. package/src/server-handler/etag.ts +51 -0
  357. package/src/server-handler/headers.ts +5 -0
  358. package/src/server-handler/index.ts +1664 -0
  359. package/src/server-handler/types.ts +24 -0
  360. package/src/server-handler/validate-static-params.ts +130 -0
  361. package/src/server.ts +2 -0
  362. package/src/service-worker/template.ts +153 -0
  363. package/src/service-worker-hook/index.ts +70 -0
  364. package/src/sitemap/index.ts +231 -0
  365. package/src/ssr/critical-css.ts +150 -0
  366. package/src/ssr/head-prefix.ts +65 -0
  367. package/src/ssr/head.ts +259 -0
  368. package/src/ssr/index.tsx +879 -0
  369. package/src/state-parser/index.ts +266 -0
  370. package/src/store/filesystem.ts +131 -0
  371. package/src/store/index.ts +29 -0
  372. package/src/styles/index.ts +1200 -0
  373. package/src/styles/sx-types.ts +11 -0
  374. package/src/testing/index.ts +251 -0
  375. package/src/testing.ts +2 -0
  376. package/src/theme/index.tsx +232 -0
  377. package/src/theme.ts +3 -0
  378. package/src/tracing/index.ts +4 -0
  379. package/src/tracing/noop.ts +13 -0
  380. package/src/tracing/otel.ts +37 -0
  381. package/src/tracing/timing.ts +34 -0
  382. package/src/tracing/types.ts +9 -0
  383. package/src/url/index.ts +140 -0
  384. package/src/use-router.ts +11 -0
  385. package/src/use-suspense-query.ts +2 -0
  386. package/src/validation/index.ts +57 -0
  387. package/src/view-transition-css.ts +1 -0
@@ -0,0 +1,286 @@
1
+ import {
2
+ compilePattern,
3
+ type FlareMiddleware,
4
+ isPathMatcher,
5
+ type MiddlewareEntry,
6
+ type PathMatcher,
7
+ } from "../middleware/index.ts";
8
+ import type { MountConfig } from "../mount/index.ts";
9
+ import type { MarkedRouterConfig } from "../router-config/index.ts";
10
+ import type { SecurityConfig } from "../security/index.ts";
11
+ import type {
12
+ HandlerCacheConfig,
13
+ ServerHandler,
14
+ ServerHandlerConfig,
15
+ SitemapSubmitConfig,
16
+ StaticParamsMap,
17
+ TracingConfig,
18
+ } from "../server-handler/index.ts";
19
+
20
+ export type { SecurityConfig } from "../security/index.ts";
21
+ export { background } from "@lovrozagar/flare/server-context";
22
+ export type { CdnPurgeAdapter, HandlerCacheConfig } from "../server-handler/index.ts";
23
+
24
+ /* ── Types ─────────────────────────────────────────────────────────────── */
25
+
26
+ export interface KeepaliveConfig {
27
+ handler?: (ctx: import("../middleware").MiddlewareContext) => Promise<void> | void;
28
+ interval: number;
29
+ }
30
+
31
+ export type MountTarget =
32
+ | {
33
+ fetch: (
34
+ request: Request,
35
+ env: unknown,
36
+ ctx: { waitUntil(p: Promise<unknown>): void },
37
+ ) => Response | Promise<Response>;
38
+ }
39
+ | ((request: Request, env: unknown, ctx: { waitUntil(p: Promise<unknown>): void }) => Response | Promise<Response>);
40
+
41
+ export interface ServerBuilder<TExcluded extends string = never> {
42
+ authenticateFn: "authenticateFn" extends TExcluded
43
+ ? never
44
+ : <TAuth>(
45
+ fn: (ctx: {
46
+ callerData?: unknown[];
47
+ env: unknown;
48
+ request: Request;
49
+ serverContext: Record<string, unknown>;
50
+ url: URL;
51
+ }) => TAuth | null | Promise<TAuth | null>,
52
+ ) => ServerBuilder<TExcluded | "authenticateFn">;
53
+ cache: "cache" extends TExcluded ? never : (config: HandlerCacheConfig) => ServerBuilder<TExcluded | "cache">;
54
+ fetch(request: Request, env?: unknown, ctx?: { waitUntil?: (p: Promise<unknown>) => void }): Promise<Response>;
55
+ getStaticParams(): Promise<StaticParamsMap>;
56
+ keepalive: "keepalive" extends TExcluded
57
+ ? never
58
+ : (config: KeepaliveConfig) => ServerBuilder<TExcluded | "keepalive">;
59
+ mount(prefix: string, target: MountTarget): ServerBuilder<TExcluded>;
60
+ security: "security" extends TExcluded
61
+ ? never
62
+ : (
63
+ config:
64
+ | SecurityConfig
65
+ | ((ctx: {
66
+ env: unknown;
67
+ nonce: string;
68
+ request: Request;
69
+ serverContext: Record<string, unknown>;
70
+ }) => SecurityConfig),
71
+ ) => ServerBuilder<TExcluded | "security">;
72
+ serverContext: "serverContext" extends TExcluded
73
+ ? never
74
+ : <T extends Record<string, unknown>>(
75
+ fn: (ctx: { env: unknown; request: Request }) => T | Promise<T>,
76
+ ) => ServerBuilder<TExcluded | "serverContext">;
77
+ sitemap: "sitemap" extends TExcluded ? never : (config: SitemapSubmitConfig) => ServerBuilder<TExcluded | "sitemap">;
78
+ tracing: "tracing" extends TExcluded ? never : (config: TracingConfig) => ServerBuilder<TExcluded | "tracing">;
79
+ use(...args: (FlareMiddleware | PathMatcher | string)[]): ServerBuilder<TExcluded>;
80
+ }
81
+
82
+ /* Internal implementation type — no exclusion tracking */
83
+ interface ServerBuilderImpl {
84
+ authenticateFn(fn: ServerHandlerConfig["authenticateFn"]): ServerBuilderImpl;
85
+ cache(config: HandlerCacheConfig): ServerBuilderImpl;
86
+ fetch(request: Request, env?: unknown, ctx?: { waitUntil?: (p: Promise<unknown>) => void }): Promise<Response>;
87
+ getStaticParams(): Promise<StaticParamsMap>;
88
+ keepalive(config: KeepaliveConfig): ServerBuilderImpl;
89
+ mount(prefix: string, target: MountTarget): ServerBuilderImpl;
90
+ security(
91
+ config:
92
+ | SecurityConfig
93
+ | ((ctx: {
94
+ env: unknown;
95
+ nonce: string;
96
+ request: Request;
97
+ serverContext: Record<string, unknown>;
98
+ }) => SecurityConfig),
99
+ ): ServerBuilderImpl;
100
+ serverContext(
101
+ fn: (ctx: { env: unknown; request: Request }) => Record<string, unknown> | Promise<Record<string, unknown>>,
102
+ ): ServerBuilderImpl;
103
+ sitemap(config: SitemapSubmitConfig): ServerBuilderImpl;
104
+ tracing(config: TracingConfig): ServerBuilderImpl;
105
+ use(...args: (FlareMiddleware | PathMatcher | string)[]): ServerBuilderImpl;
106
+ }
107
+
108
+ /* ── Builder ───────────────────────────────────────────────────────────── */
109
+
110
+ const KEEPALIVE_PATH = "/_flare/keepalive";
111
+
112
+ /*
113
+ * server-handler/index.ts imports virtual modules (virtual:flare-client-entry, etc.)
114
+ * that only exist inside Vite's module graph. Lazy-importing it in fetch() keeps the
115
+ * builder module free of those dependencies at evaluation time — this is the correct
116
+ * boundary: config collection is static, handler creation is runtime.
117
+ */
118
+ let resolvedCreateServerHandler: typeof import("../server-handler").createServerHandler | undefined;
119
+
120
+ async function getCreateServerHandler() {
121
+ if (!resolvedCreateServerHandler) {
122
+ const mod = await import("../server-handler");
123
+ resolvedCreateServerHandler = mod.createServerHandler;
124
+ }
125
+ return resolvedCreateServerHandler;
126
+ }
127
+
128
+ function normalizeMountTarget(target: MountTarget): MountConfig["fetch"] {
129
+ if (typeof target === "function") return target;
130
+ return (req, env, ctx) => target.fetch(req, env, ctx);
131
+ }
132
+
133
+ /**
134
+ * Cloudflare ExecutionContext.waitUntil must be invoked as a method.
135
+ * Passing the extracted function loses `this` and throws Illegal invocation,
136
+ * which previously turned a finished SSR into a 500.
137
+ */
138
+ function bindWaitUntil(ctx?: {
139
+ waitUntil?: (p: Promise<unknown>) => void;
140
+ }): ((p: Promise<unknown>) => void) | undefined {
141
+ if (!ctx?.waitUntil) return undefined;
142
+ return (p) => {
143
+ ctx.waitUntil!(p);
144
+ };
145
+ }
146
+
147
+ export function createServer(router: MarkedRouterConfig): ServerBuilder {
148
+ const middlewareEntries: MiddlewareEntry[] = [];
149
+ const mountConfigs: MountConfig[] = [];
150
+ let authenticateFn: ServerHandlerConfig["authenticateFn"];
151
+ let serverContextFn: ServerHandlerConfig["serverContext"];
152
+ let cacheConfig: HandlerCacheConfig | undefined;
153
+ let keepaliveConfig: KeepaliveConfig | undefined;
154
+ let securityCfg: ServerHandlerConfig["securityConfig"];
155
+ let sitemapConfig: SitemapSubmitConfig | undefined;
156
+ let tracingConfig: TracingConfig | undefined;
157
+
158
+ type ResolvedHandler = ServerHandler & {
159
+ getStaticParams(): Promise<StaticParamsMap>;
160
+ };
161
+
162
+ let cachedHandler: ResolvedHandler | undefined;
163
+ let handlerConfig: ServerHandlerConfig | undefined;
164
+
165
+ async function getHandler(waitUntil?: (p: Promise<unknown>) => void): Promise<ResolvedHandler> {
166
+ if (cachedHandler && handlerConfig) {
167
+ handlerConfig.waitUntil = waitUntil;
168
+ return cachedHandler;
169
+ }
170
+
171
+ const allEntries = [...middlewareEntries];
172
+
173
+ if (keepaliveConfig) {
174
+ const { handler: keepaliveHandler } = keepaliveConfig;
175
+ const keepaliveMw: FlareMiddleware = async (ctx) => {
176
+ if (ctx.url.pathname !== KEEPALIVE_PATH || ctx.request.method !== "GET") {
177
+ return ctx.next();
178
+ }
179
+ if (keepaliveHandler) {
180
+ try {
181
+ await keepaliveHandler(ctx);
182
+ } catch {
183
+ /* swallow keepalive handler errors */
184
+ }
185
+ }
186
+ return ctx.bypass(new Response(null, { status: 204 }));
187
+ };
188
+ allEntries.unshift({ middlewares: [keepaliveMw] });
189
+ }
190
+
191
+ /* Inject keepalive interval into router so it serializes to client via FlareState */
192
+ const routerWithKeepalive = keepaliveConfig
193
+ ? Object.assign({}, router, { keepalive: keepaliveConfig.interval })
194
+ : router;
195
+
196
+ const config: ServerHandlerConfig = {
197
+ authenticateFn,
198
+ cache: cacheConfig,
199
+ middlewareEntries: allEntries,
200
+ mount: mountConfigs.length > 0 ? mountConfigs : undefined,
201
+ router: routerWithKeepalive,
202
+ securityConfig: securityCfg,
203
+ serverContext: serverContextFn,
204
+ sitemap: sitemapConfig,
205
+ tracing: tracingConfig,
206
+ waitUntil,
207
+ };
208
+
209
+ const create = await getCreateServerHandler();
210
+ handlerConfig = config;
211
+ cachedHandler = create(config);
212
+ return cachedHandler;
213
+ }
214
+
215
+ const builder: ServerBuilderImpl = {
216
+ authenticateFn(fn) {
217
+ authenticateFn = fn;
218
+ return builder;
219
+ },
220
+ cache(config) {
221
+ cacheConfig = config;
222
+ return builder;
223
+ },
224
+ async fetch(request, env, ctx) {
225
+ const h = await getHandler(bindWaitUntil(ctx));
226
+ return h.fetch(request, env);
227
+ },
228
+ async getStaticParams() {
229
+ const h = await getHandler();
230
+ return h.getStaticParams();
231
+ },
232
+ keepalive(config) {
233
+ keepaliveConfig = config;
234
+ return builder;
235
+ },
236
+ mount(prefix, target) {
237
+ mountConfigs.push({
238
+ fetch: normalizeMountTarget(target),
239
+ prefix,
240
+ });
241
+ return builder;
242
+ },
243
+ security(config) {
244
+ securityCfg = config;
245
+ return builder;
246
+ },
247
+ serverContext(fn) {
248
+ serverContextFn = fn;
249
+ return builder;
250
+ },
251
+ sitemap(config) {
252
+ sitemapConfig = config;
253
+ return builder;
254
+ },
255
+ tracing(config) {
256
+ tracingConfig = config;
257
+ return builder;
258
+ },
259
+ use(...args) {
260
+ const matchers: Array<(path: string) => boolean> = [];
261
+ const middlewares: FlareMiddleware[] = [];
262
+
263
+ for (const arg of args) {
264
+ if (typeof arg === "string") {
265
+ matchers.push(compilePattern(arg));
266
+ } else if (isPathMatcher(arg)) {
267
+ matchers.push(arg);
268
+ } else {
269
+ middlewares.push(arg);
270
+ }
271
+ }
272
+
273
+ if (middlewares.length > 0) {
274
+ const entry: MiddlewareEntry = { middlewares };
275
+ if (matchers.length > 0) {
276
+ entry.matchers = matchers;
277
+ }
278
+ middlewareEntries.push(entry);
279
+ }
280
+
281
+ return builder;
282
+ },
283
+ };
284
+
285
+ return builder as ServerBuilder;
286
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Browser stub for `flare/server-context`. Resolved via package.json `exports.browser`
3
+ * condition. Server-context wraps `node:async_hooks` AsyncLocalStorage — Node-only API. Vite's
4
+ * browser shim throws on `node:*` import access, so the real module cannot load on the client
5
+ * even when its functions are unreachable. This stub exposes the same surface with throwing
6
+ * implementations + no Node imports, keeping `node:async_hooks` out of the client bundle entirely.
7
+ *
8
+ * If any of these functions actually run in the browser, that is a real bug in the consumer —
9
+ * they should be guarded by `import.meta.env.SSR` or live inside a stripped server-fn handler.
10
+ */
11
+
12
+ import type { CdnPurgeAdapter } from "../revalidation/index.ts";
13
+ import type { FlareStore } from "../store/index.ts";
14
+
15
+ export interface ServerLogEntry {
16
+ a: unknown[];
17
+ l: "error" | "log" | "warn";
18
+ s?: string;
19
+ }
20
+
21
+ export interface ServerRequestContextStore {
22
+ get<T>(key: string): T | undefined;
23
+ set<K extends string, V>(key: K, value: V): void;
24
+ }
25
+
26
+ export interface RunWithServerContextOptions {
27
+ cdnPurgeAdapter?: CdnPurgeAdapter;
28
+ isDev?: boolean;
29
+ nonce: string;
30
+ request: Request;
31
+ serverContext?: Record<string, unknown>;
32
+ store?: FlareStore;
33
+ waitUntil?: (promise: Promise<unknown>) => void;
34
+ }
35
+
36
+ const ERR =
37
+ "Flare server-context API called in the browser. Move call into a server-fn handler or guard with import.meta.env.SSR.";
38
+
39
+ function unreachable(): never {
40
+ throw new Error(ERR);
41
+ }
42
+
43
+ export function generateNonce(): string {
44
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
45
+ let hex = "";
46
+ for (const b of bytes) {
47
+ hex += b.toString(16).padStart(2, "0");
48
+ }
49
+ return hex;
50
+ }
51
+
52
+ export function runWithServerContext<T>(_opts: RunWithServerContextOptions, _cb: () => T): T {
53
+ return unreachable();
54
+ }
55
+
56
+ export function getServerNonce(): string {
57
+ return "";
58
+ }
59
+
60
+ export function setServerNonce(_nonce: string): void {
61
+ unreachable();
62
+ }
63
+
64
+ export function getServerRequest(): Request {
65
+ return unreachable();
66
+ }
67
+
68
+ export function getServerRequestContext(): ServerRequestContextStore {
69
+ return unreachable();
70
+ }
71
+
72
+ export function getServerContext<T extends Record<string, unknown> = Record<string, unknown>>(): T {
73
+ return unreachable() as T;
74
+ }
75
+
76
+ export function getRevalidationContext(): {
77
+ cdnPurgeAdapter?: CdnPurgeAdapter;
78
+ store?: FlareStore;
79
+ } {
80
+ return {};
81
+ }
82
+
83
+ export function addRevalidatedTags(_tags: string[]): void {
84
+ /* no-op on browser — revalidation is server-only */
85
+ }
86
+
87
+ export function getRevalidatedTags(): string[] {
88
+ return [];
89
+ }
90
+
91
+ export function serverLog(_level: "error" | "log" | "warn", ..._args: unknown[]): void {
92
+ /* no-op on browser */
93
+ }
94
+
95
+ export function getServerLogs(): ServerLogEntry[] {
96
+ return [];
97
+ }
98
+
99
+ export function background(_promise: Promise<unknown>): void {
100
+ /* no-op on browser */
101
+ }
102
+
103
+ export interface FormActionContext {
104
+ [key: string]: unknown;
105
+ }
106
+
107
+ export function setFormActionContext(_fnId: string, _ctx: FormActionContext): void {
108
+ unreachable();
109
+ }
110
+
111
+ export function getFormActionContext(_fnId: string): FormActionContext | undefined {
112
+ return undefined;
113
+ }
@@ -0,0 +1,217 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import type { CdnPurgeAdapter } from "../revalidation/index.ts";
3
+ import type { FlareStore } from "../store/index.ts";
4
+
5
+ export interface ServerLogEntry {
6
+ a: unknown[];
7
+ l: "error" | "log" | "warn";
8
+ /** Server-side source location (dev only) */
9
+ s?: string;
10
+ }
11
+
12
+ interface ServerContextValue {
13
+ cdnPurgeAdapter?: CdnPurgeAdapter;
14
+ isDev?: boolean;
15
+ nonce: string;
16
+ request: Request;
17
+ requestStore: Map<string, unknown>;
18
+ serverContext: Record<string, unknown>;
19
+ store?: FlareStore;
20
+ waitUntil?: (promise: Promise<unknown>) => void;
21
+ }
22
+
23
+ export interface ServerRequestContextStore {
24
+ get<T>(key: string): T | undefined;
25
+ set<K extends string, V>(key: K, value: V): void;
26
+ }
27
+
28
+ let storage: AsyncLocalStorage<ServerContextValue> | undefined;
29
+
30
+ function getStorage(): AsyncLocalStorage<ServerContextValue> {
31
+ if (!storage) {
32
+ storage = new AsyncLocalStorage<ServerContextValue>();
33
+ }
34
+ return storage;
35
+ }
36
+
37
+ function getContext(): ServerContextValue {
38
+ const ctx = getStorage().getStore();
39
+ if (!ctx) {
40
+ throw new Error(
41
+ "getServerContext() called outside request context. Must be called during request handling (route handler, middleware, or server function).",
42
+ );
43
+ }
44
+ return ctx;
45
+ }
46
+
47
+ export function generateNonce(): string {
48
+ const bytes = crypto.getRandomValues(new Uint8Array(16));
49
+ let hex = "";
50
+ for (const b of bytes) {
51
+ hex += b.toString(16).padStart(2, "0");
52
+ }
53
+ return hex;
54
+ }
55
+
56
+ export interface RunWithServerContextOptions {
57
+ cdnPurgeAdapter?: CdnPurgeAdapter;
58
+ isDev?: boolean;
59
+ nonce: string;
60
+ request: Request;
61
+ serverContext?: Record<string, unknown>;
62
+ store?: FlareStore;
63
+ waitUntil?: (promise: Promise<unknown>) => void;
64
+ }
65
+
66
+ export function runWithServerContext<T>(options: RunWithServerContextOptions, callback: () => T): T {
67
+ const value: ServerContextValue = {
68
+ cdnPurgeAdapter: options.cdnPurgeAdapter,
69
+ isDev: options.isDev,
70
+ nonce: options.nonce,
71
+ request: options.request,
72
+ requestStore: new Map(),
73
+ serverContext: options.serverContext ?? {},
74
+ store: options.store,
75
+ waitUntil: options.waitUntil,
76
+ };
77
+ return getStorage().run(value, callback);
78
+ }
79
+
80
+ export function getServerNonce(): string {
81
+ return getContext().nonce;
82
+ }
83
+
84
+ export function setServerNonce(nonce: string): void {
85
+ getContext().nonce = nonce;
86
+ }
87
+
88
+ export function getServerRequest(): Request {
89
+ return getContext().request;
90
+ }
91
+
92
+ export function getServerRequestContext(): ServerRequestContextStore {
93
+ const ctx = getContext();
94
+ return {
95
+ get<T>(key: string): T | undefined {
96
+ return ctx.requestStore.get(key) as T | undefined;
97
+ },
98
+ set<K extends string, V>(key: K, value: V): void {
99
+ ctx.requestStore.set(key, value);
100
+ },
101
+ };
102
+ }
103
+
104
+ const EMPTY_CONTEXT: Record<string, unknown> = Object.freeze(Object.create(null));
105
+
106
+ export function getServerContext<T extends Record<string, unknown> = Record<string, unknown>>(): T {
107
+ const ctx = getStorage().getStore();
108
+ if (!ctx) return EMPTY_CONTEXT as T;
109
+ return ctx.serverContext as T;
110
+ }
111
+
112
+ export function getRevalidationContext(): {
113
+ cdnPurgeAdapter?: CdnPurgeAdapter;
114
+ store?: FlareStore;
115
+ } {
116
+ const ctx = getStorage().getStore();
117
+ if (!ctx) return {};
118
+ return {
119
+ cdnPurgeAdapter: ctx.cdnPurgeAdapter,
120
+ store: ctx.store,
121
+ };
122
+ }
123
+
124
+ const REVALIDATED_TAGS_KEY = "__flare_revalidated_tags";
125
+
126
+ export function addRevalidatedTags(tags: string[]): void {
127
+ const ctx = getStorage().getStore();
128
+ if (!ctx) return;
129
+ const existing = (ctx.requestStore.get(REVALIDATED_TAGS_KEY) as string[] | undefined) ?? [];
130
+ const merged = new Set(existing);
131
+ for (const tag of tags) {
132
+ merged.add(tag);
133
+ }
134
+ ctx.requestStore.set(REVALIDATED_TAGS_KEY, [...merged]);
135
+ }
136
+
137
+ export function getRevalidatedTags(): string[] {
138
+ const ctx = getStorage().getStore();
139
+ if (!ctx) return [];
140
+ return (ctx.requestStore.get(REVALIDATED_TAGS_KEY) as string[] | undefined) ?? [];
141
+ }
142
+
143
+ const SERVER_LOGS_KEY = "__flare_server_logs";
144
+ const MAX_SERVER_LOGS = 1000;
145
+
146
+ const CALLER_RE = /\((.+):(\d+):\d+\)|at\s+(.+):(\d+):\d+/;
147
+
148
+ function parseCallerLocation(): string | undefined {
149
+ const stack = new Error().stack;
150
+ if (!stack) return undefined;
151
+ /* Frame 0 = Error, 1 = parseCallerLocation, 2 = serverLog, 3 = ctx.log/warn/error wrapper, 4 = user code */
152
+ const frame = stack.split("\n")[4];
153
+ if (!frame) return undefined;
154
+ const m = CALLER_RE.exec(frame);
155
+ if (!m) return undefined;
156
+ const file = m[1] ?? m[3] ?? "";
157
+ const line = m[2] ?? m[4] ?? "";
158
+ /* Strip to relative path from src/ or routes/ */
159
+ const srcIdx = file.lastIndexOf("/src/");
160
+ const short = srcIdx >= 0 ? file.slice(srcIdx + 1) : file.split("/").slice(-2).join("/");
161
+ return `${short}:${line}`;
162
+ }
163
+
164
+ export function serverLog(level: "error" | "log" | "warn", ...args: unknown[]): void {
165
+ const ctx = getStorage().getStore();
166
+ if (!ctx) return;
167
+ const logs = (ctx.requestStore.get(SERVER_LOGS_KEY) as ServerLogEntry[] | undefined) ?? [];
168
+ if (logs.length >= MAX_SERVER_LOGS) return;
169
+ const entry: ServerLogEntry = { a: args, l: level };
170
+ if (ctx.isDev) {
171
+ const loc = parseCallerLocation();
172
+ if (loc) entry.s = loc;
173
+ }
174
+ logs.push(entry);
175
+ ctx.requestStore.set(SERVER_LOGS_KEY, logs);
176
+ }
177
+
178
+ export function getServerLogs(): ServerLogEntry[] {
179
+ const ctx = getStorage().getStore();
180
+ if (!ctx) return [];
181
+ return (ctx.requestStore.get(SERVER_LOGS_KEY) as ServerLogEntry[] | undefined) ?? [];
182
+ }
183
+
184
+ /* ── Form action context (PE POST error re-render) ─────────────────── */
185
+
186
+ export interface FormActionContext {
187
+ fieldErrors: Record<string, string[]>;
188
+ formErrors: string[];
189
+ message: string;
190
+ values: Record<string, unknown>;
191
+ }
192
+
193
+ export function setFormActionContext(fnId: string, ctx: FormActionContext): void {
194
+ const store = getStorage().getStore();
195
+ if (!store) return;
196
+ store.requestStore.set(`__flare_form:${fnId}`, ctx);
197
+ }
198
+
199
+ export function getFormActionContext(fnId: string): FormActionContext | undefined {
200
+ const store = getStorage().getStore();
201
+ if (!store) return undefined;
202
+ return store.requestStore.get(`__flare_form:${fnId}`) as FormActionContext | undefined;
203
+ }
204
+
205
+ export function background(promise: Promise<unknown>): void {
206
+ const ctx = getContext();
207
+ if (ctx.waitUntil) {
208
+ try {
209
+ ctx.waitUntil(promise);
210
+ return;
211
+ } catch {
212
+ /* Cloudflare's waitUntil is a method. An extracted unbound fn throws
213
+ Illegal invocation — never fail the request for bookkeeping. */
214
+ }
215
+ }
216
+ promise.catch(() => {});
217
+ }