@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,655 @@
1
+ import type { JSX } from "solid-js";
2
+ import type { FlareRouter } from "../outlet/types.ts";
3
+ import type { Location } from "../router-primitives/index.ts";
4
+ import type {
5
+ ExtractPathParams,
6
+ ParentAuthResolution,
7
+ ParentPreloaderContext,
8
+ ResolvedAuth,
9
+ ResolvedEnv,
10
+ ResolvedQueryClient,
11
+ ResolvedServerContext,
12
+ } from "./register.ts";
13
+ import {
14
+ type AuthenticateMode,
15
+ BUILDER_MARKER,
16
+ type CacheConfig,
17
+ type DeferFn,
18
+ type EffectsConfig,
19
+ type HeadConfig,
20
+ type HeadOptions,
21
+ type InputConfig,
22
+ type LoaderCause,
23
+ type ParamsValidator,
24
+ type ResponseHeaders,
25
+ type SearchParamsValidator,
26
+ type ServerThrowHelpers,
27
+ type ServerUrlHelpers,
28
+ } from "./types.ts";
29
+
30
+ /* ── callback context types ─────────────────────────────────────── */
31
+
32
+ export interface LayoutAuthorizeContext<TParams, TSearch, TAuth extends AuthenticateMode, TPreloaderContext>
33
+ extends ServerThrowHelpers, ServerUrlHelpers {
34
+ abortController: AbortController;
35
+ auth: ResolvedAuth<TAuth>;
36
+ env: ResolvedEnv;
37
+ locale: () => string;
38
+ location: Location<TParams, TSearch>;
39
+ preloaderContext: TPreloaderContext;
40
+ request: Request;
41
+ serverContext: ResolvedServerContext;
42
+ }
43
+
44
+ export interface LayoutPreloaderContext<TParams, TSearch, TAuth extends AuthenticateMode, TPreloaderContext>
45
+ extends ServerThrowHelpers, ServerUrlHelpers {
46
+ abortController: AbortController;
47
+ auth: ResolvedAuth<TAuth>;
48
+ env: ResolvedEnv;
49
+ locale: () => string;
50
+ location: Location<TParams, TSearch>;
51
+ preloaderContext: TPreloaderContext;
52
+ request: Request;
53
+ serverContext: ResolvedServerContext;
54
+ }
55
+
56
+ export type LayoutLoaderContext<
57
+ TParams,
58
+ TSearch,
59
+ TAuth extends AuthenticateMode,
60
+ TPreloaderContext,
61
+ > = ServerThrowHelpers &
62
+ ServerUrlHelpers &
63
+ ResolvedQueryClient & {
64
+ abortController: AbortController;
65
+ auth: ResolvedAuth<TAuth>;
66
+ cause: LoaderCause;
67
+ defer: DeferFn;
68
+ deps: unknown[];
69
+ env: ResolvedEnv;
70
+ locale: () => string;
71
+ location: Location<TParams, TSearch>;
72
+ prefetch: boolean;
73
+ preloaderContext: TPreloaderContext;
74
+ request: Request;
75
+ serverContext: ResolvedServerContext;
76
+ };
77
+
78
+ export interface LayoutHeadContext<TParams, TSearch, TPreloaderContext, TLoaderData> extends ServerUrlHelpers {
79
+ cause: LoaderCause;
80
+ loaderData: TLoaderData;
81
+ location: Location<TParams, TSearch>;
82
+ parentHead: HeadConfig | undefined;
83
+ prefetch: boolean;
84
+ preloaderContext: TPreloaderContext;
85
+ serverContext: ResolvedServerContext;
86
+ }
87
+
88
+ export interface LayoutHeadersContext<TParams, TSearch, TPreloaderContext, TLoaderData> extends ServerUrlHelpers {
89
+ cause: LoaderCause;
90
+ env: ResolvedEnv;
91
+ loaderData: TLoaderData;
92
+ location: Location<TParams, TSearch>;
93
+ parentHeaders: ResponseHeaders | undefined;
94
+ prefetch: boolean;
95
+ preloaderContext: TPreloaderContext;
96
+ request: Request;
97
+ serverContext: ResolvedServerContext;
98
+ }
99
+
100
+ export interface LayoutRenderProps<TParams, TSearch, TPreloaderContext, TLoaderData> {
101
+ children: JSX.Element;
102
+ loaderData: TLoaderData;
103
+ location: Location<TParams, TSearch>;
104
+ preloaderContext: TPreloaderContext;
105
+ router: FlareRouter;
106
+ }
107
+
108
+ export interface LayoutErrorRenderProps<TParams, TSearch> {
109
+ error: Error;
110
+ location: Location<TParams, TSearch>;
111
+ reset: () => void;
112
+ retry: () => void;
113
+ }
114
+
115
+ export interface LayoutNotFoundRenderProps<TParams, TSearch> {
116
+ location: Location<TParams, TSearch>;
117
+ }
118
+
119
+ export interface LayoutUnauthenticatedRenderProps<TParams, TSearch> {
120
+ error: Error;
121
+ location: Location<TParams, TSearch>;
122
+ retry: () => void;
123
+ }
124
+
125
+ export interface LayoutUnauthorizedRenderProps<TParams, TSearch> {
126
+ error: Error;
127
+ location: Location<TParams, TSearch>;
128
+ retry: () => void;
129
+ }
130
+
131
+ /* ── result type ────────────────────────────────────────────────── */
132
+
133
+ export interface LayoutResult<
134
+ TPath extends string,
135
+ TParams,
136
+ TSearch,
137
+ TAuth extends AuthenticateMode,
138
+ TPreloaderContext,
139
+ TLoaderData,
140
+ > {
141
+ _type: "layout";
142
+ authenticate?: unknown[];
143
+ authenticateMode?: AuthenticateMode;
144
+ authorize?: (ctx: LayoutAuthorizeContext<TParams, TSearch, TAuth, TPreloaderContext>) => boolean | Promise<boolean>;
145
+ effectsConfig?: EffectsConfig<TParams, TSearch>;
146
+ errorRender?: (props: LayoutErrorRenderProps<TParams, TSearch>) => unknown;
147
+ head?: (ctx: LayoutHeadContext<TParams, TSearch, TPreloaderContext, TLoaderData>) => HeadConfig;
148
+ headReplace?: boolean;
149
+ headers?: (ctx: LayoutHeadersContext<TParams, TSearch, TPreloaderContext, TLoaderData>) => ResponseHeaders;
150
+ inputConfig?: InputConfig<TParams, TSearch>;
151
+ loader?: (ctx: LayoutLoaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => Promise<TLoaderData> | TLoaderData;
152
+ notFoundRender?: (props: LayoutNotFoundRenderProps<TParams, TSearch>) => unknown;
153
+ cache?: CacheConfig<TPath>;
154
+ preloader?: (ctx: LayoutPreloaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => unknown;
155
+ render: (props: LayoutRenderProps<TParams, TSearch, TPreloaderContext, TLoaderData>) => unknown;
156
+ unauthenticatedRender?: (props: LayoutUnauthenticatedRenderProps<TParams, TSearch>) => unknown;
157
+ unauthorizedRender?: (props: LayoutUnauthorizedRenderProps<TParams, TSearch>) => unknown;
158
+ virtualPath: TPath;
159
+ }
160
+
161
+ /* ── internal builder state ─────────────────────────────────────── */
162
+
163
+ interface BuilderStateInternal {
164
+ authenticate?: unknown[];
165
+ authenticateMode?: AuthenticateMode;
166
+ authorize?: unknown;
167
+ cache?: unknown;
168
+ effectsConfig?: unknown;
169
+ head?: unknown;
170
+ headReplace?: boolean;
171
+ headers?: unknown;
172
+ inputConfig?: unknown;
173
+ loader?: unknown;
174
+ preloader?: unknown;
175
+ virtualPath: string;
176
+ }
177
+
178
+ /* ── progressive builder interfaces ─────────────────────────────── */
179
+
180
+ /* after render: boundary methods (any order, each at most once) */
181
+ interface LayoutBoundaryPropsMap<TParams, TSearch> {
182
+ errorRender: LayoutErrorRenderProps<TParams, TSearch>;
183
+ notFoundRender: LayoutNotFoundRenderProps<TParams, TSearch>;
184
+ unauthenticatedRender: LayoutUnauthenticatedRenderProps<TParams, TSearch>;
185
+ unauthorizedRender: LayoutUnauthorizedRenderProps<TParams, TSearch>;
186
+ }
187
+
188
+ type LayoutAfterRender<
189
+ TPath extends string,
190
+ TParams,
191
+ TSearch,
192
+ TAuth extends AuthenticateMode,
193
+ TPreloaderContext,
194
+ TLoaderData,
195
+ TSet extends keyof LayoutBoundaryPropsMap<TParams, TSearch> = never,
196
+ > = {
197
+ [K in Exclude<keyof LayoutBoundaryPropsMap<TParams, TSearch>, TSet>]: (
198
+ fn: (props: LayoutBoundaryPropsMap<TParams, TSearch>[K]) => unknown,
199
+ ) => LayoutResult<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> &
200
+ LayoutAfterRender<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData, TSet | K>;
201
+ };
202
+
203
+ /* L1: render only */
204
+ interface LayoutBuilderRenderOnly<
205
+ TPath extends string,
206
+ TParams,
207
+ TSearch,
208
+ TAuth extends AuthenticateMode,
209
+ TPreloaderContext,
210
+ TLoaderData,
211
+ > {
212
+ render(
213
+ fn: (props: LayoutRenderProps<TParams, TSearch, TPreloaderContext, TLoaderData>) => unknown,
214
+ ): LayoutResult<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> &
215
+ LayoutAfterRender<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>;
216
+ }
217
+
218
+ /* L2: + headers */
219
+ interface LayoutBuilderWithHeaders<
220
+ TPath extends string,
221
+ TParams,
222
+ TSearch,
223
+ TAuth extends AuthenticateMode,
224
+ TPreloaderContext,
225
+ TLoaderData,
226
+ > extends LayoutBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
227
+ headers(
228
+ fn: (ctx: LayoutHeadersContext<TParams, TSearch, TPreloaderContext, TLoaderData>) => ResponseHeaders,
229
+ ): LayoutBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>;
230
+ }
231
+
232
+ /* L3: + head */
233
+ interface LayoutBuilderWithHead<
234
+ TPath extends string,
235
+ TParams,
236
+ TSearch,
237
+ TAuth extends AuthenticateMode,
238
+ TPreloaderContext,
239
+ TLoaderData,
240
+ > extends LayoutBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
241
+ head(
242
+ fn: (ctx: LayoutHeadContext<TParams, TSearch, TPreloaderContext, TLoaderData>) => HeadConfig,
243
+ options?: HeadOptions,
244
+ ): LayoutBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>;
245
+ }
246
+
247
+ /* L4: loader + head/headers/render with void (no .response on layouts) */
248
+ interface LayoutBuilderWithLoader<
249
+ TPath extends string,
250
+ TParams,
251
+ TSearch,
252
+ TAuth extends AuthenticateMode,
253
+ TPreloaderContext,
254
+ > {
255
+ head(
256
+ fn: (ctx: LayoutHeadContext<TParams, TSearch, TPreloaderContext, void>) => HeadConfig,
257
+ options?: HeadOptions,
258
+ ): LayoutBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>;
259
+ headers(
260
+ fn: (ctx: LayoutHeadersContext<TParams, TSearch, TPreloaderContext, void>) => ResponseHeaders,
261
+ ): LayoutBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>;
262
+ loader<T>(
263
+ fn: (ctx: LayoutLoaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => Promise<T> | T,
264
+ ): LayoutBuilderWithHead<TPath, TParams, TSearch, TAuth, TPreloaderContext, Awaited<T>>;
265
+ render(
266
+ fn: (props: LayoutRenderProps<TParams, TSearch, TPreloaderContext, void>) => unknown,
267
+ ): LayoutResult<TPath, TParams, TSearch, TAuth, TPreloaderContext, void> &
268
+ LayoutAfterRender<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>;
269
+ }
270
+
271
+ /* L5: + preloader */
272
+ interface LayoutBuilderWithPreloader<
273
+ TPath extends string,
274
+ TParams,
275
+ TSearch,
276
+ TAuth extends AuthenticateMode,
277
+ TPreloaderContext,
278
+ > extends LayoutBuilderWithLoader<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
279
+ preloader<T extends Record<string, unknown>>(
280
+ fn: (ctx: LayoutPreloaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => Promise<T> | T,
281
+ ): LayoutBuilderWithLoader<TPath, TParams, TSearch, TAuth, TPreloaderContext & Awaited<T>>;
282
+ }
283
+
284
+ /* L6: + effects */
285
+ interface LayoutBuilderAfterAuthorize<
286
+ TPath extends string,
287
+ TParams,
288
+ TSearch,
289
+ TAuth extends AuthenticateMode,
290
+ TPreloaderContext,
291
+ > extends LayoutBuilderWithPreloader<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
292
+ effects(
293
+ config: EffectsConfig<TParams, TSearch>,
294
+ ): LayoutBuilderWithPreloader<TPath, TParams, TSearch, TAuth, TPreloaderContext>;
295
+ }
296
+
297
+ /* L7: + authorize */
298
+ interface LayoutBuilderAfterAuthenticate<
299
+ TPath extends string,
300
+ TParams,
301
+ TSearch,
302
+ TAuth extends AuthenticateMode,
303
+ TPreloaderContext,
304
+ > extends LayoutBuilderAfterAuthorize<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
305
+ authorize(
306
+ fn: (ctx: LayoutAuthorizeContext<TParams, TSearch, TAuth, TPreloaderContext>) => boolean | Promise<boolean>,
307
+ ): LayoutBuilderAfterAuthorize<TPath, TParams, TSearch, TAuth, TPreloaderContext>;
308
+ }
309
+
310
+ /* L8: + authenticate */
311
+ interface LayoutBuilderAfterInput<
312
+ TPath extends string,
313
+ TParams,
314
+ TSearch,
315
+ TAuth extends AuthenticateMode,
316
+ TPreloaderContext,
317
+ > extends LayoutBuilderAfterAuthenticate<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
318
+ authenticate(...args: unknown[]): LayoutBuilderAfterAuthenticate<TPath, TParams, TSearch, true, TPreloaderContext>;
319
+ authenticateOptional(
320
+ ...args: unknown[]
321
+ ): LayoutBuilderAfterAuthenticate<TPath, TParams, TSearch, "optional", TPreloaderContext>;
322
+ }
323
+
324
+ /* L9: + input */
325
+ interface LayoutBuilderAfterCache<
326
+ TPath extends string,
327
+ TAuth extends AuthenticateMode,
328
+ TPreloaderContext,
329
+ > extends LayoutBuilderAfterInput<TPath, ExtractPathParams<TPath>, Record<string, string>, TAuth, TPreloaderContext> {
330
+ input<TNewParams = ExtractPathParams<TPath>, TNewSearch = Record<string, string>>(config: {
331
+ params?: ParamsValidator<TNewParams>;
332
+ searchParams?: SearchParamsValidator<TNewSearch>;
333
+ }): LayoutBuilderAfterInput<TPath, TNewParams, TNewSearch, TAuth, TPreloaderContext>;
334
+ }
335
+
336
+ /* L10: initial */
337
+ export interface LayoutBuilderInitial<
338
+ TPath extends string,
339
+ TAuth extends AuthenticateMode = false,
340
+ TPreloaderContext = {},
341
+ > extends LayoutBuilderAfterCache<TPath, TAuth, TPreloaderContext> {
342
+ cache(config: CacheConfig<TPath>): LayoutBuilderAfterCache<TPath, TAuth, TPreloaderContext>;
343
+ }
344
+
345
+ /* ── factory functions ──────────────────────────────────────────── */
346
+
347
+ type LayoutResultFull<
348
+ TPath extends string,
349
+ TParams,
350
+ TSearch,
351
+ TAuth extends AuthenticateMode,
352
+ TPreloaderContext,
353
+ TLoaderData,
354
+ > = LayoutResult<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> &
355
+ LayoutAfterRender<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>;
356
+
357
+ function createResultWithBoundaries<
358
+ TPath extends string,
359
+ TParams,
360
+ TSearch,
361
+ TAuth extends AuthenticateMode,
362
+ TPreloaderContext,
363
+ TLoaderData,
364
+ >(
365
+ state: BuilderStateInternal,
366
+ renderFn: (props: LayoutRenderProps<TParams, TSearch, TPreloaderContext, TLoaderData>) => unknown,
367
+ errorFn?: (props: LayoutErrorRenderProps<TParams, TSearch>) => unknown,
368
+ notFoundFn?: (props: LayoutNotFoundRenderProps<TParams, TSearch>) => unknown,
369
+ unauthenticatedFn?: (props: LayoutUnauthenticatedRenderProps<TParams, TSearch>) => unknown,
370
+ unauthorizedFn?: (props: LayoutUnauthorizedRenderProps<TParams, TSearch>) => unknown,
371
+ ): LayoutResultFull<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
372
+ function boundarySlot<TProps>(
373
+ existing: ((props: TProps) => unknown) | undefined,
374
+ make: () => (fn: (props: TProps) => unknown) => unknown,
375
+ ): unknown {
376
+ if (existing) return existing;
377
+ const builder = make();
378
+ Object.defineProperty(builder, BUILDER_MARKER, { value: true });
379
+ return builder;
380
+ }
381
+
382
+ return {
383
+ _type: "layout" as const,
384
+ authenticate: state.authenticate,
385
+ authenticateMode: state.authenticateMode,
386
+ authorize: state.authorize,
387
+ cache: state.cache,
388
+ effectsConfig: state.effectsConfig,
389
+ errorRender: boundarySlot(
390
+ errorFn,
391
+ () => (fn) =>
392
+ createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(
393
+ state,
394
+ renderFn,
395
+ fn,
396
+ notFoundFn,
397
+ unauthenticatedFn,
398
+ unauthorizedFn,
399
+ ),
400
+ ),
401
+ head: state.head,
402
+ headReplace: state.headReplace,
403
+ headers: state.headers,
404
+ inputConfig: state.inputConfig,
405
+ loader: state.loader,
406
+ notFoundRender: boundarySlot(
407
+ notFoundFn,
408
+ () => (fn) =>
409
+ createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(
410
+ state,
411
+ renderFn,
412
+ errorFn,
413
+ fn,
414
+ unauthenticatedFn,
415
+ unauthorizedFn,
416
+ ),
417
+ ),
418
+ preloader: state.preloader,
419
+ render: renderFn,
420
+ unauthenticatedRender: boundarySlot(
421
+ unauthenticatedFn,
422
+ () => (fn) =>
423
+ createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(
424
+ state,
425
+ renderFn,
426
+ errorFn,
427
+ notFoundFn,
428
+ fn,
429
+ unauthorizedFn,
430
+ ),
431
+ ),
432
+ unauthorizedRender: boundarySlot(
433
+ unauthorizedFn,
434
+ () => (fn) =>
435
+ createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(
436
+ state,
437
+ renderFn,
438
+ errorFn,
439
+ notFoundFn,
440
+ unauthenticatedFn,
441
+ fn,
442
+ ),
443
+ ),
444
+ virtualPath: state.virtualPath,
445
+ } as LayoutResultFull<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>;
446
+ }
447
+
448
+ function createBuilderRenderOnly<
449
+ TPath extends string,
450
+ TParams,
451
+ TSearch,
452
+ TAuth extends AuthenticateMode,
453
+ TPreloaderContext,
454
+ TLoaderData,
455
+ >(
456
+ state: BuilderStateInternal,
457
+ ): LayoutBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
458
+ return {
459
+ render(fn) {
460
+ return createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(state, fn);
461
+ },
462
+ };
463
+ }
464
+
465
+ function createBuilderWithHeaders<
466
+ TPath extends string,
467
+ TParams,
468
+ TSearch,
469
+ TAuth extends AuthenticateMode,
470
+ TPreloaderContext,
471
+ TLoaderData,
472
+ >(
473
+ state: BuilderStateInternal,
474
+ ): LayoutBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
475
+ return {
476
+ ...createBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(state),
477
+ headers(fn) {
478
+ return createBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>({
479
+ ...state,
480
+ headers: fn,
481
+ });
482
+ },
483
+ };
484
+ }
485
+
486
+ function createBuilderWithHead<
487
+ TPath extends string,
488
+ TParams,
489
+ TSearch,
490
+ TAuth extends AuthenticateMode,
491
+ TPreloaderContext,
492
+ TLoaderData,
493
+ >(state: BuilderStateInternal): LayoutBuilderWithHead<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData> {
494
+ return {
495
+ ...createBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>(state),
496
+ head(fn, options) {
497
+ return createBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, TLoaderData>({
498
+ ...state,
499
+ head: fn,
500
+ headReplace: options?.replace,
501
+ });
502
+ },
503
+ };
504
+ }
505
+
506
+ function createBuilderWithLoader<
507
+ TPath extends string,
508
+ TParams,
509
+ TSearch,
510
+ TAuth extends AuthenticateMode,
511
+ TPreloaderContext,
512
+ >(state: BuilderStateInternal): LayoutBuilderWithLoader<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
513
+ return {
514
+ head(fn, options) {
515
+ return createBuilderWithHeaders<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>({
516
+ ...state,
517
+ head: fn,
518
+ headReplace: options?.replace,
519
+ });
520
+ },
521
+ headers(fn) {
522
+ return createBuilderRenderOnly<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>({
523
+ ...state,
524
+ headers: fn,
525
+ });
526
+ },
527
+ loader<T>(fn: (ctx: LayoutLoaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => Promise<T> | T) {
528
+ return createBuilderWithHead<TPath, TParams, TSearch, TAuth, TPreloaderContext, Awaited<T>>({
529
+ ...state,
530
+ loader: fn,
531
+ });
532
+ },
533
+ render(fn) {
534
+ return createResultWithBoundaries<TPath, TParams, TSearch, TAuth, TPreloaderContext, void>(state, fn);
535
+ },
536
+ };
537
+ }
538
+
539
+ function createBuilderWithPreloader<
540
+ TPath extends string,
541
+ TParams,
542
+ TSearch,
543
+ TAuth extends AuthenticateMode,
544
+ TPreloaderContext,
545
+ >(state: BuilderStateInternal): LayoutBuilderWithPreloader<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
546
+ return {
547
+ ...createBuilderWithLoader<TPath, TParams, TSearch, TAuth, TPreloaderContext>(state),
548
+ preloader<T extends Record<string, unknown>>(
549
+ fn: (ctx: LayoutPreloaderContext<TParams, TSearch, TAuth, TPreloaderContext>) => Promise<T> | T,
550
+ ) {
551
+ return createBuilderWithLoader<TPath, TParams, TSearch, TAuth, TPreloaderContext & Awaited<T>>({
552
+ ...state,
553
+ preloader: fn,
554
+ });
555
+ },
556
+ };
557
+ }
558
+
559
+ function createBuilderAfterAuthorize<
560
+ TPath extends string,
561
+ TParams,
562
+ TSearch,
563
+ TAuth extends AuthenticateMode,
564
+ TPreloaderContext,
565
+ >(state: BuilderStateInternal): LayoutBuilderAfterAuthorize<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
566
+ return {
567
+ ...createBuilderWithPreloader<TPath, TParams, TSearch, TAuth, TPreloaderContext>(state),
568
+ effects(config) {
569
+ return createBuilderWithPreloader<TPath, TParams, TSearch, TAuth, TPreloaderContext>({
570
+ ...state,
571
+ effectsConfig: config,
572
+ });
573
+ },
574
+ };
575
+ }
576
+
577
+ function createBuilderAfterAuthenticate<
578
+ TPath extends string,
579
+ TParams,
580
+ TSearch,
581
+ TAuth extends AuthenticateMode,
582
+ TPreloaderContext,
583
+ >(state: BuilderStateInternal): LayoutBuilderAfterAuthenticate<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
584
+ return {
585
+ ...createBuilderAfterAuthorize<TPath, TParams, TSearch, TAuth, TPreloaderContext>(state),
586
+ authorize(fn) {
587
+ return createBuilderAfterAuthorize<TPath, TParams, TSearch, TAuth, TPreloaderContext>({
588
+ ...state,
589
+ authorize: fn,
590
+ });
591
+ },
592
+ };
593
+ }
594
+
595
+ function createBuilderAfterInput<
596
+ TPath extends string,
597
+ TParams,
598
+ TSearch,
599
+ TAuth extends AuthenticateMode,
600
+ TPreloaderContext,
601
+ >(state: BuilderStateInternal): LayoutBuilderAfterInput<TPath, TParams, TSearch, TAuth, TPreloaderContext> {
602
+ return {
603
+ ...createBuilderAfterAuthenticate<TPath, TParams, TSearch, TAuth, TPreloaderContext>(state),
604
+ authenticate(...args: unknown[]) {
605
+ return createBuilderAfterAuthenticate<TPath, TParams, TSearch, true, TPreloaderContext>({
606
+ ...state,
607
+ authenticate: args,
608
+ authenticateMode: true,
609
+ });
610
+ },
611
+ authenticateOptional(...args: unknown[]) {
612
+ return createBuilderAfterAuthenticate<TPath, TParams, TSearch, "optional", TPreloaderContext>({
613
+ ...state,
614
+ authenticate: args,
615
+ authenticateMode: "optional",
616
+ });
617
+ },
618
+ };
619
+ }
620
+
621
+ function createBuilderAfterCache<TPath extends string, TAuth extends AuthenticateMode, TPreloaderContext>(
622
+ state: BuilderStateInternal,
623
+ ): LayoutBuilderAfterCache<TPath, TAuth, TPreloaderContext> {
624
+ return {
625
+ ...createBuilderAfterInput<TPath, ExtractPathParams<TPath>, Record<string, string>, TAuth, TPreloaderContext>(
626
+ state,
627
+ ),
628
+ input<TNewParams = ExtractPathParams<TPath>, TNewSearch = Record<string, string>>(config: {
629
+ params?: ParamsValidator<TNewParams>;
630
+ searchParams?: SearchParamsValidator<TNewSearch>;
631
+ }) {
632
+ return createBuilderAfterInput<TPath, TNewParams, TNewSearch, TAuth, TPreloaderContext>({
633
+ ...state,
634
+ inputConfig: config,
635
+ });
636
+ },
637
+ };
638
+ }
639
+
640
+ /* ── public API ─────────────────────────────────────────────────── */
641
+
642
+ export function createLayout<TPath extends string>(
643
+ virtualPath: TPath,
644
+ ): LayoutBuilderInitial<TPath, ParentAuthResolution<TPath>, ParentPreloaderContext<TPath>> {
645
+ const state: BuilderStateInternal = { virtualPath };
646
+ return {
647
+ ...createBuilderAfterCache<TPath, ParentAuthResolution<TPath>, ParentPreloaderContext<TPath>>(state),
648
+ cache(config) {
649
+ return createBuilderAfterCache<TPath, ParentAuthResolution<TPath>, ParentPreloaderContext<TPath>>({
650
+ ...state,
651
+ cache: config,
652
+ });
653
+ },
654
+ };
655
+ }