@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
package/src/await.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type { AwaitProps, AwaitStatus } from "./components/index.ts";
2
+ export { Await } from "./components/index.ts";
@@ -0,0 +1,99 @@
1
+ import type { UnauthenticatedError, UnauthorizedError } from "../errors/index.ts";
2
+ import type { Location } from "../router-primitives/types.ts";
3
+
4
+ export interface ErrorRenderProps<TParams = Record<string, string>, TSearch = Record<string, string>> {
5
+ error: Error;
6
+ location: Location<TParams, TSearch>;
7
+ reset: () => void;
8
+ retry: () => void;
9
+ }
10
+
11
+ export interface NotFoundRenderProps<TParams = Record<string, string>, TSearch = Record<string, string>> {
12
+ location: Location<TParams, TSearch>;
13
+ }
14
+
15
+ export interface UnauthenticatedRenderProps<TParams = Record<string, string>, TSearch = Record<string, string>> {
16
+ error: UnauthenticatedError;
17
+ location: Location<TParams, TSearch>;
18
+ retry: () => void;
19
+ }
20
+
21
+ export interface UnauthorizedRenderProps<TParams = Record<string, string>, TSearch = Record<string, string>> {
22
+ error: UnauthorizedError;
23
+ location: Location<TParams, TSearch>;
24
+ retry: () => void;
25
+ }
26
+
27
+ export interface GlobalBoundaries {
28
+ error?: (props: ErrorRenderProps) => unknown;
29
+ notFound?: (props: NotFoundRenderProps) => unknown;
30
+ unauthenticated?: (props: UnauthenticatedRenderProps) => unknown;
31
+ unauthorized?: (props: UnauthorizedRenderProps) => unknown;
32
+ }
33
+
34
+ export type ErrorRenderFn = (props: Record<string, unknown>) => unknown;
35
+ export type NotFoundRenderFn = (props: Record<string, unknown>) => unknown;
36
+ export type UnauthenticatedRenderFn = (props: Record<string, unknown>) => unknown;
37
+ export type UnauthorizedRenderFn = (props: Record<string, unknown>) => unknown;
38
+
39
+ export interface BoundaryRoute {
40
+ errorRender?: ErrorRenderFn;
41
+ notFoundRender?: NotFoundRenderFn;
42
+ unauthenticatedRender?: UnauthenticatedRenderFn;
43
+ unauthorizedRender?: UnauthorizedRenderFn;
44
+ virtualPath: string;
45
+ }
46
+
47
+ /**
48
+ * Walk up the route chain from errorRouteIndex to find an errorRender.
49
+ * errorRender on a route catches that route's OWN errors.
50
+ */
51
+ export function findErrorBoundary(routes: BoundaryRoute[], errorRouteIndex: number): ErrorRenderFn | null {
52
+ for (let i = errorRouteIndex; i >= 0; i--) {
53
+ const route = routes[i];
54
+ if (route?.errorRender) return route.errorRender;
55
+ }
56
+ return null;
57
+ }
58
+
59
+ /**
60
+ * Walk up from the throwing route's PARENT to find a notFoundRender.
61
+ * notFoundRender catches NotFoundError from CHILD routes, not its own.
62
+ */
63
+ export function findNotFoundBoundary(routes: BoundaryRoute[], throwRouteIndex: number): NotFoundRenderFn | null {
64
+ for (let i = throwRouteIndex - 1; i >= 0; i--) {
65
+ const route = routes[i];
66
+ if (route?.notFoundRender) return route.notFoundRender;
67
+ }
68
+ return null;
69
+ }
70
+
71
+ /**
72
+ * Walk up the route chain to find an unauthenticatedRender.
73
+ * Catches UnauthenticatedError (401).
74
+ */
75
+ export function findUnauthenticatedBoundary(
76
+ routes: BoundaryRoute[],
77
+ errorRouteIndex: number,
78
+ ): UnauthenticatedRenderFn | null {
79
+ for (let i = errorRouteIndex; i >= 0; i--) {
80
+ const route = routes[i];
81
+ if (route?.unauthenticatedRender) return route.unauthenticatedRender;
82
+ }
83
+ return null;
84
+ }
85
+
86
+ /**
87
+ * Walk up the route chain to find an unauthorizedRender.
88
+ * Catches UnauthorizedError (403).
89
+ */
90
+ export function findUnauthorizedBoundary(
91
+ routes: BoundaryRoute[],
92
+ errorRouteIndex: number,
93
+ ): UnauthorizedRenderFn | null {
94
+ for (let i = errorRouteIndex; i >= 0; i--) {
95
+ const route = routes[i];
96
+ if (route?.unauthorizedRender) return route.unauthorizedRender;
97
+ }
98
+ return null;
99
+ }
@@ -0,0 +1,65 @@
1
+ export type ChannelMessage =
2
+ | { key: string; payload: unknown; type: "custom" }
3
+ | { options?: SerializedInvalidateOptions; type: "invalidate" }
4
+ | { replace?: boolean; to: string; type: "navigate" }
5
+ | { type: "locale"; value: string };
6
+
7
+ export interface SerializedInvalidateOptions {
8
+ matchId?: string;
9
+ routeId?: string;
10
+ tags?: string[];
11
+ }
12
+
13
+ export interface InternalChannel {
14
+ broadcast(msg: ChannelMessage): void;
15
+ close(): void;
16
+ onMessage(handler: (msg: ChannelMessage) => void): () => void;
17
+ }
18
+
19
+ const DISCRIMINANT = "_f";
20
+
21
+ const noopChannel: InternalChannel = {
22
+ broadcast() {},
23
+ close() {},
24
+ onMessage() {
25
+ return () => {};
26
+ },
27
+ };
28
+
29
+ export function createChannel(): InternalChannel {
30
+ if (typeof BroadcastChannel === "undefined") {
31
+ return noopChannel;
32
+ }
33
+
34
+ const bc = new BroadcastChannel("flare");
35
+ const handlers = new Set<(msg: ChannelMessage) => void>();
36
+
37
+ bc.onmessage = (e: MessageEvent) => {
38
+ const msg = e.data;
39
+ if (!msg || msg[DISCRIMINANT] !== 1 || !msg.type) return;
40
+ for (const fn of handlers) {
41
+ try {
42
+ fn(msg as ChannelMessage);
43
+ } catch {
44
+ /* handler error must not kill listener or block other handlers */
45
+ }
46
+ }
47
+ };
48
+
49
+ return {
50
+ broadcast(msg) {
51
+ try {
52
+ bc.postMessage({ ...msg, [DISCRIMINANT]: 1 });
53
+ } catch {
54
+ /* non-structuredClone-able payload — swallow */
55
+ }
56
+ },
57
+ close() {
58
+ bc.close();
59
+ },
60
+ onMessage(handler) {
61
+ handlers.add(handler);
62
+ return () => handlers.delete(handler);
63
+ },
64
+ };
65
+ }
@@ -0,0 +1,12 @@
1
+ import { createContext } from "solid-js";
2
+ import type { InternalChannel } from "./channel.ts";
3
+
4
+ export const noopChannel: InternalChannel = {
5
+ broadcast() {},
6
+ close() {},
7
+ onMessage() {
8
+ return () => {};
9
+ },
10
+ };
11
+
12
+ export const BroadcastCtx = createContext<InternalChannel>(noopChannel);
@@ -0,0 +1,75 @@
1
+ import { createSignal, onCleanup, type Setter, useContext } from "solid-js";
2
+ import type { ChannelMessage } from "./channel.ts";
3
+ import { BroadcastCtx } from "./context.ts";
4
+
5
+ export type { ChannelMessage, InternalChannel, SerializedInvalidateOptions } from "./channel.ts";
6
+ export { createChannel } from "./channel.ts";
7
+ export { BroadcastCtx } from "./context.ts";
8
+
9
+ /**
10
+ * Signal registry — same key in same tab shares one signal instance.
11
+ * BroadcastChannel fires in OTHER tabs only, so without this,
12
+ * two components using createBroadcastSignal("cart", 0) in the same tab
13
+ * would NOT share state when one calls the setter.
14
+ */
15
+ const registry = new Map<string, { refCount: number; signal: [() => unknown, (v: unknown) => void] }>();
16
+
17
+ /** @internal test-only accessor — no-ops in production builds (tree-shaken) */
18
+ export function _getRegistryForTest(): typeof registry | null {
19
+ if (process.env.NODE_ENV !== "test") return null;
20
+ return registry;
21
+ }
22
+
23
+ export function useBroadcast<T = void>(key: string, handler?: (payload: T) => void): (payload: T) => void {
24
+ const channel = useContext(BroadcastCtx);
25
+
26
+ if (handler) {
27
+ const unsubscribe = channel.onMessage((msg: ChannelMessage) => {
28
+ if (msg.type === "custom" && msg.key === key) {
29
+ handler(msg.payload as T);
30
+ }
31
+ });
32
+ onCleanup(unsubscribe);
33
+ }
34
+
35
+ return (payload: T) => {
36
+ channel.broadcast({ key, payload, type: "custom" });
37
+ };
38
+ }
39
+
40
+ export function createBroadcastSignal<T>(key: string, initialValue: T): [() => T, (value: T) => void] {
41
+ const channel = useContext(BroadcastCtx);
42
+
43
+ let entry = registry.get(key);
44
+ if (!entry) {
45
+ const [value, setValue] = createSignal<T>(initialValue);
46
+ entry = {
47
+ refCount: 0,
48
+ signal: [value, setValue as (v: unknown) => void],
49
+ };
50
+ registry.set(key, entry);
51
+ }
52
+ entry.refCount++;
53
+
54
+ const [value, setValue] = entry.signal as [() => T, Setter<T>];
55
+
56
+ const unsubscribe = channel.onMessage((msg: ChannelMessage) => {
57
+ if (msg.type === "custom" && msg.key === key) {
58
+ setValue(() => msg.payload as T);
59
+ }
60
+ });
61
+
62
+ onCleanup(() => {
63
+ unsubscribe();
64
+ const e = registry.get(key);
65
+ if (e && --e.refCount === 0) registry.delete(key);
66
+ });
67
+
68
+ return [
69
+ value,
70
+ (v: T) => {
71
+ setValue(() => v);
72
+ channel.broadcast({ key, payload: v, type: "custom" });
73
+ },
74
+ ];
75
+ }
@@ -0,0 +1,7 @@
1
+ import type { JSX } from "solid-js";
2
+ import type { InternalChannel } from "./channel.ts";
3
+ import { BroadcastCtx, noopChannel } from "./context.ts";
4
+
5
+ export function BroadcastProvider(props: { children: JSX.Element; value?: InternalChannel }): JSX.Element {
6
+ return <BroadcastCtx.Provider value={props.value ?? noopChannel}>{props.children}</BroadcastCtx.Provider>;
7
+ }
@@ -0,0 +1,2 @@
1
+ export type { Location } from "./router-primitives/index.ts";
2
+ export { buildLocation } from "./router-primitives/index.ts";
@@ -0,0 +1,384 @@
1
+ import type { HeadConfig } from "../route-builder/types.ts";
2
+
3
+ export interface CachedMatch {
4
+ data: unknown;
5
+ error?: unknown;
6
+ hasDeferred?: boolean;
7
+ headConfig?: HeadConfig;
8
+ invalid: boolean;
9
+ matchId: string;
10
+ preloaderContext?: Record<string, unknown>;
11
+ tags?: string[];
12
+ updatedAt: number;
13
+ }
14
+
15
+ export interface InvalidateOptions {
16
+ broadcast?: boolean;
17
+ filter?: (match: CachedMatch) => boolean;
18
+ matchId?: string;
19
+ routeId?: string;
20
+ tags?: string[];
21
+ }
22
+
23
+ export interface MatchCache {
24
+ clear(): void;
25
+ delete(matchId: string): void;
26
+ get(matchId: string): CachedMatch | undefined;
27
+ getAll(): CachedMatch[];
28
+ has(matchId: string): boolean;
29
+ invalidate(options?: InvalidateOptions): void;
30
+ isCached(matchId: string): boolean;
31
+ isStale(matchId: string, staleTime: number): boolean;
32
+ set(match: CachedMatch): void;
33
+ size(): number;
34
+ }
35
+
36
+ export interface PrefetchCache {
37
+ cleanup(maxAge: number): void;
38
+ clear(): void;
39
+ delete(url: string): void;
40
+ get(url: string): number | undefined;
41
+ has(url: string): boolean;
42
+ isStale(url: string, staleTime: number): boolean;
43
+ mark(url: string): void;
44
+ set(url: string, fetchedAt: number): void;
45
+ shouldPrefetch(url: string, staleTime: number): boolean;
46
+ size(): number;
47
+ }
48
+
49
+ const DEFAULT_MAX_MATCH_ENTRIES = 500;
50
+ const DEFAULT_MAX_PREFETCH_ENTRIES = 1000;
51
+
52
+ export function createMatchCache(maxSize = DEFAULT_MAX_MATCH_ENTRIES): MatchCache {
53
+ const store = new Map<string, CachedMatch>();
54
+
55
+ return {
56
+ clear() {
57
+ store.clear();
58
+ },
59
+
60
+ delete(matchId: string) {
61
+ store.delete(matchId);
62
+ },
63
+
64
+ get(matchId: string) {
65
+ return store.get(matchId);
66
+ },
67
+
68
+ getAll() {
69
+ return [...store.values()];
70
+ },
71
+
72
+ has(matchId: string) {
73
+ return store.has(matchId);
74
+ },
75
+
76
+ invalidate(options?: InvalidateOptions) {
77
+ if (!options) {
78
+ for (const entry of store.values()) {
79
+ entry.invalid = true;
80
+ }
81
+ return;
82
+ }
83
+
84
+ if (options.tags && options.tags.length > 0) {
85
+ for (const entry of store.values()) {
86
+ if (entry.tags?.some((t) => options.tags?.includes(t))) {
87
+ entry.invalid = true;
88
+ }
89
+ }
90
+ return;
91
+ }
92
+
93
+ if (options.matchId) {
94
+ const entry = store.get(options.matchId);
95
+ if (entry) {
96
+ entry.invalid = true;
97
+ }
98
+ return;
99
+ }
100
+
101
+ if (options.routeId) {
102
+ const prefix = `${options.routeId}:`;
103
+ for (const entry of store.values()) {
104
+ if (entry.matchId.startsWith(prefix)) {
105
+ entry.invalid = true;
106
+ }
107
+ }
108
+ return;
109
+ }
110
+
111
+ if (options.filter) {
112
+ for (const entry of store.values()) {
113
+ if (options.filter(entry)) {
114
+ entry.invalid = true;
115
+ }
116
+ }
117
+ }
118
+ },
119
+
120
+ isCached(matchId: string) {
121
+ const entry = store.get(matchId);
122
+ return !!entry && !entry.invalid;
123
+ },
124
+
125
+ isStale(matchId: string, staleTime: number) {
126
+ const entry = store.get(matchId);
127
+ if (!entry) return true;
128
+ if (entry.invalid) return true;
129
+ if (entry.hasDeferred) return true;
130
+ if (staleTime <= 0 || Number.isNaN(staleTime)) return true;
131
+ return Date.now() - entry.updatedAt > staleTime;
132
+ },
133
+
134
+ set(match: CachedMatch) {
135
+ /* Delete before re-insert so Map moves key to end of iteration order (LRU) */
136
+ if (store.has(match.matchId)) store.delete(match.matchId);
137
+ store.set(match.matchId, match);
138
+ if (store.size > maxSize) {
139
+ const oldest = store.keys().next().value;
140
+ if (oldest !== undefined) store.delete(oldest);
141
+ }
142
+ },
143
+
144
+ size() {
145
+ return store.size;
146
+ },
147
+ };
148
+ }
149
+
150
+ export function createPrefetchCache(maxSize = DEFAULT_MAX_PREFETCH_ENTRIES): PrefetchCache {
151
+ const store = new Map<string, number>();
152
+
153
+ return {
154
+ cleanup(maxAge: number) {
155
+ const now = Date.now();
156
+ for (const [url, fetchedAt] of store) {
157
+ if (now - fetchedAt > maxAge) {
158
+ store.delete(url);
159
+ }
160
+ }
161
+ },
162
+
163
+ clear() {
164
+ store.clear();
165
+ },
166
+
167
+ delete(url: string) {
168
+ store.delete(url);
169
+ },
170
+
171
+ get(url: string) {
172
+ return store.get(url);
173
+ },
174
+
175
+ has(url: string) {
176
+ return store.has(url);
177
+ },
178
+
179
+ isStale(url: string, staleTime: number) {
180
+ const fetchedAt = store.get(url);
181
+ if (fetchedAt === undefined) return true;
182
+ return Date.now() - fetchedAt > staleTime;
183
+ },
184
+
185
+ mark(url: string) {
186
+ if (store.has(url)) store.delete(url);
187
+ store.set(url, Date.now());
188
+ if (store.size > maxSize) {
189
+ const oldest = store.keys().next().value;
190
+ if (oldest !== undefined) store.delete(oldest);
191
+ }
192
+ },
193
+
194
+ set(url: string, fetchedAt: number) {
195
+ if (store.has(url)) store.delete(url);
196
+ store.set(url, fetchedAt);
197
+ if (store.size > maxSize) {
198
+ const oldest = store.keys().next().value;
199
+ if (oldest !== undefined) store.delete(oldest);
200
+ }
201
+ },
202
+
203
+ shouldPrefetch(url: string, staleTime: number) {
204
+ const fetchedAt = store.get(url);
205
+ if (fetchedAt === undefined) return true;
206
+ return Date.now() - fetchedAt > staleTime;
207
+ },
208
+
209
+ size() {
210
+ return store.size;
211
+ },
212
+ };
213
+ }
214
+
215
+ export interface CollectedDeferred {
216
+ key: string;
217
+ promise: Promise<unknown>;
218
+ }
219
+
220
+ /**
221
+ * Walk hydrated data tree and collect deferred markers that have a promise.
222
+ * After `hydrateLoaderData`, markers look like `{ __deferred: true, __key: string, promise: Promise }`.
223
+ */
224
+ export function collectDeferredPromises(data: unknown, seen?: WeakSet<object>): CollectedDeferred[] {
225
+ if (data === null || data === undefined || typeof data !== "object") return [];
226
+
227
+ const tracking = seen ?? new WeakSet<object>();
228
+ if (tracking.has(data as object)) return [];
229
+ tracking.add(data as object);
230
+
231
+ const obj = data as Record<string, unknown>;
232
+ if (obj["__deferred"] === true && typeof obj["__key"] === "string" && obj["promise"] instanceof Promise) {
233
+ return [{ key: obj["__key"] as string, promise: obj["promise"] as Promise<unknown> }];
234
+ }
235
+
236
+ if (Array.isArray(data)) {
237
+ return data.flatMap((item) => collectDeferredPromises(item, tracking));
238
+ }
239
+
240
+ return Object.values(obj).flatMap((val) => collectDeferredPromises(val, tracking));
241
+ }
242
+
243
+ export interface DeferredTracker {
244
+ clear(): void;
245
+ prune(activeMatchIds: Set<string>): void;
246
+ reject(matchId: string, key: string, error: Error, generation?: number): void;
247
+ resolve(matchId: string, key: string, data: unknown, generation?: number): void;
248
+ track(matchId: string, key: string, onAllResolved: (matchId: string) => void): number;
249
+ }
250
+
251
+ const PENDING = Symbol("pending");
252
+
253
+ const DEFERRED_TIMEOUT = 60_000;
254
+
255
+ interface TrackedKey {
256
+ generation: number;
257
+ value: unknown;
258
+ }
259
+
260
+ interface PendingDeferred {
261
+ keys: Map<string, TrackedKey>;
262
+ onAllResolved: (matchId: string) => void;
263
+ rejected: boolean;
264
+ trackedAt: number;
265
+ }
266
+
267
+ /**
268
+ * Walk data tree and replace deferred markers with resolved values.
269
+ * Markers: `{ __deferred: true, __key: string }` or `{ __deferred: true, __key: string, promise: ... }`
270
+ */
271
+ function replaceDeferredMarkers(data: unknown, resolved: Map<string, unknown>): unknown {
272
+ if (data === null || data === undefined || typeof data !== "object") return data;
273
+
274
+ if (Array.isArray(data)) {
275
+ return data.map((item) => replaceDeferredMarkers(item, resolved));
276
+ }
277
+
278
+ const obj = data as Record<string, unknown>;
279
+ if (obj["__deferred"] === true && typeof obj["__key"] === "string") {
280
+ const key = obj["__key"] as string;
281
+ return resolved.has(key) ? resolved.get(key) : data;
282
+ }
283
+
284
+ const result: Record<string, unknown> = Object.create(null);
285
+ for (const k of Object.keys(obj)) {
286
+ if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
287
+ result[k] = replaceDeferredMarkers(obj[k], resolved);
288
+ }
289
+ return result;
290
+ }
291
+
292
+ export function createDeferredTracker(matchCache: MatchCache): DeferredTracker {
293
+ const pending = new Map<string, PendingDeferred>();
294
+ let generationCounter = 0;
295
+
296
+ return {
297
+ clear() {
298
+ pending.clear();
299
+ },
300
+
301
+ prune(activeMatchIds: Set<string>) {
302
+ for (const id of pending.keys()) {
303
+ if (!activeMatchIds.has(id)) pending.delete(id);
304
+ }
305
+ },
306
+
307
+ reject(matchId: string, key: string, _error: Error, generation?: number) {
308
+ const entry = pending.get(matchId);
309
+ if (!entry) return;
310
+ const tracked = entry.keys.get(key);
311
+ if (!tracked) return;
312
+ if (generation !== undefined && generation !== tracked.generation) return;
313
+ entry.rejected = true;
314
+ entry.keys.delete(key);
315
+ if (entry.keys.size === 0) {
316
+ pending.delete(matchId);
317
+ }
318
+ },
319
+
320
+ resolve(matchId: string, key: string, data: unknown, generation?: number) {
321
+ const entry = pending.get(matchId);
322
+ if (!entry) return;
323
+ const tracked = entry.keys.get(key);
324
+ if (!tracked) return;
325
+ if (generation !== undefined && generation !== tracked.generation) return;
326
+
327
+ tracked.value = data;
328
+
329
+ /* Check: all tracked keys have resolved values? */
330
+ let allResolved = true;
331
+ for (const t of entry.keys.values()) {
332
+ if (t.value === PENDING) {
333
+ allResolved = false;
334
+ break;
335
+ }
336
+ }
337
+ if (!allResolved) return;
338
+
339
+ /* All resolved — update matchCache */
340
+ const cached = matchCache.get(matchId);
341
+ if (cached && !entry.rejected) {
342
+ const resolved = new Map<string, unknown>();
343
+ for (const [k, t] of entry.keys) {
344
+ resolved.set(k, t.value);
345
+ }
346
+ cached.data = replaceDeferredMarkers(cached.data, resolved);
347
+ cached.hasDeferred = false;
348
+ cached.updatedAt = Date.now();
349
+ matchCache.set(cached);
350
+ }
351
+
352
+ if (!entry.rejected) {
353
+ entry.onAllResolved(matchId);
354
+ }
355
+ pending.delete(matchId);
356
+ },
357
+
358
+ track(matchId: string, key: string, onAllResolved: (matchId: string) => void) {
359
+ const now = Date.now();
360
+ const stale: string[] = [];
361
+ for (const [id, e] of pending) {
362
+ if (now - e.trackedAt > DEFERRED_TIMEOUT) stale.push(id);
363
+ }
364
+ for (const id of stale) pending.delete(id);
365
+ generationCounter++;
366
+ const existing = pending.get(matchId);
367
+ if (existing) {
368
+ existing.keys.set(key, { generation: generationCounter, value: PENDING });
369
+ existing.onAllResolved = onAllResolved;
370
+ existing.trackedAt = now;
371
+ } else {
372
+ const entry: PendingDeferred = {
373
+ keys: new Map(),
374
+ onAllResolved,
375
+ rejected: false,
376
+ trackedAt: now,
377
+ };
378
+ entry.keys.set(key, { generation: generationCounter, value: PENDING });
379
+ pending.set(matchId, entry);
380
+ }
381
+ return generationCounter;
382
+ },
383
+ };
384
+ }