@timber-js/app 0.2.0-alpha.19 → 0.2.0-alpha.190
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.
- package/LICENSE +8 -0
- package/agent-skill.md +344 -0
- package/dist/_chunks/actions-35jnMdeJ.js +318 -0
- package/dist/_chunks/actions-35jnMdeJ.js.map +1 -0
- package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
- package/dist/_chunks/base-path-DaQrzbez.js +80 -0
- package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js +86 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js +369 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +1 -0
- package/dist/_chunks/cache-api-DjNrIWRR.js +1196 -0
- package/dist/_chunks/cache-api-DjNrIWRR.js.map +1 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js +256 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js +298 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js.map +1 -0
- package/dist/_chunks/cloudflare-CGP6BZKO.js +1284 -0
- package/dist/_chunks/cloudflare-CGP6BZKO.js.map +1 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
- package/dist/_chunks/convention-lint-kXsgc_-7.js +784 -0
- package/dist/_chunks/convention-lint-kXsgc_-7.js.map +1 -0
- package/dist/_chunks/dist-BA3u1z3W.js +423 -0
- package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js +353 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js +41 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js +454 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js.map +1 -0
- package/dist/_chunks/format-CfwjgPz9.js +14 -0
- package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
- package/dist/_chunks/href-validation-CMc5JRls.js +141 -0
- package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js +63 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +1 -0
- package/dist/_chunks/logger-D8xJZXIN.js +1451 -0
- package/dist/_chunks/logger-D8xJZXIN.js.map +1 -0
- package/dist/_chunks/mdx-file-C005ay-P.js +25 -0
- package/dist/_chunks/mdx-file-C005ay-P.js.map +1 -0
- package/dist/_chunks/plugin-context-rCinWLiE.js +321 -0
- package/dist/_chunks/plugin-context-rCinWLiE.js.map +1 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js +50 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -0
- package/dist/_chunks/router-ref-DuYuV_0Q.js +28 -0
- package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js +243 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js.map +1 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js +40 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js.map +1 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js +46 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js.map +1 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js +1564 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js.map +1 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js +199 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js +197 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js +97 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js.map +1 -0
- package/dist/_chunks/segment-keys-BawYuNFO.js +307 -0
- package/dist/_chunks/segment-keys-BawYuNFO.js.map +1 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js +76 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-14MXm7Pj.js} +17 -2
- package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js +226 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js +398 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -0
- package/dist/_chunks/walkers-RzN6AFjr.js +141 -0
- package/dist/_chunks/walkers-RzN6AFjr.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +72 -0
- package/dist/adapters/build-output-helper.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts +65 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +124 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +199 -21
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -188
- package/dist/adapters/compress-module.d.ts +17 -4
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +64 -0
- package/dist/adapters/fs-identity.d.ts.map +1 -0
- package/dist/adapters/nitro.d.ts +55 -3
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +287 -171
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +62 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +28 -6
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cache/cache-api.d.ts +48 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/fast-hash.d.ts +5 -0
- package/dist/cache/fast-hash.d.ts.map +1 -1
- package/dist/cache/handler-store.d.ts +33 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +31 -8
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -326
- package/dist/cache/invalidation-epoch.d.ts +43 -0
- package/dist/cache/invalidation-epoch.d.ts.map +1 -0
- package/dist/cache/json-lossy-check.d.ts +11 -0
- package/dist/cache/json-lossy-check.d.ts.map +1 -0
- package/dist/cache/redis-handler.d.ts +140 -8
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +19 -2
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/stable-stringify.d.ts +9 -0
- package/dist/cache/stable-stringify.d.ts.map +1 -1
- package/dist/cache/store.d.ts +53 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.js +29 -0
- package/dist/cache/stores/cloudflare-kv.js.map +1 -0
- package/dist/cache/stores/memory.d.ts +42 -0
- package/dist/cache/stores/memory.d.ts.map +1 -0
- package/dist/cache/stores/memory.js +90 -0
- package/dist/cache/stores/memory.js.map +1 -0
- package/dist/cache/stores/redis.d.ts +69 -0
- package/dist/cache/stores/redis.d.ts.map +1 -0
- package/dist/cache/stores/redis.js +35 -0
- package/dist/cache/stores/redis.js.map +1 -0
- package/dist/cache/stores/vercel.d.ts +36 -0
- package/dist/cache/stores/vercel.d.ts.map +1 -0
- package/dist/cache/stores/vercel.js +33 -0
- package/dist/cache/stores/vercel.js.map +1 -0
- package/dist/cache/tag-aware-handler.d.ts +52 -0
- package/dist/cache/tag-aware-handler.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +20 -10
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts +23 -0
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
- package/dist/cdn/cloudflare-purge.js +30 -0
- package/dist/cdn/cloudflare-purge.js.map +1 -0
- package/dist/cdn/fastly-purge.d.ts +25 -0
- package/dist/cdn/fastly-purge.d.ts.map +1 -0
- package/dist/cdn/fastly-purge.js +33 -0
- package/dist/cdn/fastly-purge.js.map +1 -0
- package/dist/cdn/headers.d.ts +97 -0
- package/dist/cdn/headers.d.ts.map +1 -0
- package/dist/cdn/index.d.ts +5 -0
- package/dist/cdn/index.d.ts.map +1 -0
- package/dist/cdn/index.js +94 -0
- package/dist/cdn/index.js.map +1 -0
- package/dist/cdn/purge-store.d.ts +23 -0
- package/dist/cdn/purge-store.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.d.ts +16 -0
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.js +35 -0
- package/dist/cdn/workers-cache-purge.js.map +1 -0
- package/dist/cli-check.d.ts +153 -0
- package/dist/cli-check.d.ts.map +1 -0
- package/dist/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +66 -7
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +151 -47
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +37 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +57 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +29 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +29 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +30 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +32 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +28 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +19 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -125
- package/dist/client/error-reconstituter.d.ts +61 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +16 -27
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +29 -7
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +11 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +186 -1134
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +20 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +1624 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link.d.ts +63 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-api.d.ts +121 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-commit.d.ts +87 -0
- package/dist/client/navigation-commit.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +38 -20
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +159 -0
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts +1 -1
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +81 -0
- package/dist/client/params-context.d.ts.map +1 -0
- package/dist/client/router-effects.d.ts +129 -0
- package/dist/client/router-effects.d.ts.map +1 -0
- package/dist/client/router-lifecycle.d.ts +55 -0
- package/dist/client/router-lifecycle.d.ts.map +1 -0
- package/dist/client/router-pipeline.d.ts +84 -0
- package/dist/client/router-pipeline.d.ts.map +1 -0
- package/dist/client/router-ref.d.ts +2 -2
- package/dist/client/router-ref.d.ts.map +1 -1
- package/dist/client/router-skew.d.ts +21 -0
- package/dist/client/router-skew.d.ts.map +1 -0
- package/dist/client/router-types.d.ts +207 -0
- package/dist/client/router-types.d.ts.map +1 -0
- package/dist/client/router.d.ts +1 -97
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +113 -26
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +107 -25
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +57 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/segment-update-context.d.ts +21 -0
- package/dist/client/segment-update-context.d.ts.map +1 -0
- package/dist/client/shallow-url.d.ts +10 -0
- package/dist/client/shallow-url.d.ts.map +1 -0
- package/dist/client/slot-context.d.ts +31 -0
- package/dist/client/slot-context.d.ts.map +1 -0
- package/dist/client/slot-outlet.d.ts +16 -0
- package/dist/client/slot-outlet.d.ts.map +1 -0
- package/dist/client/slot-provider.d.ts +25 -0
- package/dist/client/slot-provider.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +19 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-client.d.ts +69 -0
- package/dist/client/stale-client.d.ts.map +1 -0
- package/dist/client/state.d.ts +11 -2
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +7 -6
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/unload-guard.d.ts +5 -0
- package/dist/client/unload-guard.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts +12 -0
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts.map +1 -1
- package/dist/client/use-pending-navigation.d.ts +23 -0
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +10 -4
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +2 -2
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +12 -5
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +26 -14
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +69 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +76 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +284 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +58 -25
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -1
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +257 -36
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +64 -0
- package/dist/cookies/json-cookie.d.ts.map +1 -0
- package/dist/cookies/validation.d.ts +34 -0
- package/dist/cookies/validation.d.ts.map +1 -0
- package/dist/dev-tools/404-page.d.ts +50 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +40 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/dev-page-shell.d.ts +78 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +32 -0
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/dev-tools/holding-server.d.ts +54 -0
- package/dist/dev-tools/holding-server.d.ts.map +1 -0
- package/dist/dev-tools/hydration-overlay.d.ts +11 -0
- package/dist/dev-tools/hydration-overlay.d.ts.map +1 -0
- package/dist/dev-tools/index.d.ts +31 -0
- package/dist/dev-tools/index.d.ts.map +1 -0
- package/dist/dev-tools/instrumentation.d.ts +59 -0
- package/dist/dev-tools/instrumentation.d.ts.map +1 -0
- package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
- package/dist/dev-tools/logger.d.ts.map +1 -0
- package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +17 -3
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/dev-tools/overlay.d.ts +91 -0
- package/dist/dev-tools/overlay.d.ts.map +1 -0
- package/dist/dev-tools/stack-classifier.d.ts +34 -0
- package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
- package/dist/dev-tools/terminal.d.ts +28 -0
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/fonts/ast-walk.d.ts +68 -0
- package/dist/fonts/ast-walk.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +110 -6
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +50 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/fallbacks.d.ts +0 -7
- package/dist/fonts/fallbacks.d.ts.map +1 -1
- package/dist/fonts/google.d.ts +4 -2
- package/dist/fonts/google.d.ts.map +1 -1
- package/dist/fonts/local.d.ts +4 -4
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/fonts/paths.d.ts +43 -0
- package/dist/fonts/paths.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +177 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +82 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +47 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +77 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +50 -181
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9805 -14134
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +81 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +34 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- package/dist/plugin-context.d.ts +276 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +21 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +7 -3
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +47 -10
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +64 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/callsite-ast.d.ts +117 -0
- package/dist/plugins/callsite-ast.d.ts.map +1 -0
- package/dist/plugins/callsite-jsx.d.ts +35 -0
- package/dist/plugins/callsite-jsx.d.ts.map +1 -0
- package/dist/plugins/chunks.d.ts +11 -4
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +40 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/cloudflare-wasm.d.ts +21 -0
- package/dist/plugins/cloudflare-wasm.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +17 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +28 -4
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +16 -73
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/prebuilt-capture.d.ts +60 -0
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts +40 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts.map +1 -0
- package/dist/plugins/prebuilt.d.ts +82 -0
- package/dist/plugins/prebuilt.d.ts.map +1 -0
- package/dist/plugins/prerender-sugar.d.ts +42 -0
- package/dist/plugins/prerender-sugar.d.ts.map +1 -0
- package/dist/plugins/request-dep/analysis.d.ts +106 -0
- package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
- package/dist/plugins/request-dep/index.d.ts +75 -0
- package/dist/plugins/request-dep/index.d.ts.map +1 -0
- package/dist/plugins/request-dep/origin.d.ts +61 -0
- package/dist/plugins/request-dep/origin.d.ts.map +1 -0
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +29 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +218 -21
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +26 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +61 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen-write.d.ts +51 -0
- package/dist/routing/codegen-write.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +7 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/collision-probe.d.ts +104 -0
- package/dist/routing/collision-probe.d.ts.map +1 -0
- package/dist/routing/collision-spaces.d.ts +26 -0
- package/dist/routing/collision-spaces.d.ts.map +1 -0
- package/dist/routing/convention-lint.d.ts +55 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/export-detect.d.ts +72 -0
- package/dist/routing/export-detect.d.ts.map +1 -0
- package/dist/routing/file-cache.d.ts +8 -0
- package/dist/routing/file-cache.d.ts.map +1 -0
- package/dist/routing/index.d.ts +7 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +5 -2
- package/dist/routing/interception.d.ts +234 -10
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +105 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/manifest-codegen.d.ts +26 -0
- package/dist/routing/manifest-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts +1 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +35 -0
- package/dist/routing/schema-validation.d.ts.map +1 -0
- package/dist/routing/segment-classify.d.ts +114 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/segment-codegen.d.ts +38 -0
- package/dist/routing/segment-codegen.d.ts.map +1 -0
- package/dist/routing/segment-keys.d.ts +117 -0
- package/dist/routing/segment-keys.d.ts.map +1 -0
- package/dist/routing/slot-placement.d.ts +48 -0
- package/dist/routing/slot-placement.d.ts.map +1 -0
- package/dist/routing/types.d.ts +74 -26
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +57 -0
- package/dist/routing/walkers.d.ts.map +1 -0
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +145 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +262 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +3 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +179 -360
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/parse-total.d.ts +81 -0
- package/dist/search-params/parse-total.d.ts.map +1 -0
- package/dist/search-params/serialize-equal.d.ts +9 -0
- package/dist/search-params/serialize-equal.d.ts.map +1 -0
- package/dist/search-params/wrappers.d.ts +76 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/server/access-gate.d.ts +26 -10
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +42 -7
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts +35 -1
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +12 -33
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +110 -11
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +8 -18
- package/dist/server/asset-headers.d.ts.map +1 -1
- package/dist/server/body-limits.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +25 -30
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/canonicalize.d.ts +10 -0
- package/dist/server/canonicalize.d.ts.map +1 -1
- package/dist/server/chain-url-parts.d.ts +81 -0
- package/dist/server/chain-url-parts.d.ts.map +1 -0
- package/dist/server/children-interception.d.ts +49 -0
- package/dist/server/children-interception.d.ts.map +1 -0
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/compress.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +170 -0
- package/dist/server/cookie-context.d.ts.map +1 -0
- package/dist/server/cookie-parsing.d.ts +65 -0
- package/dist/server/cookie-parsing.d.ts.map +1 -0
- package/dist/server/csrf.d.ts +3 -2
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/default-status-page.d.ts +45 -0
- package/dist/server/default-status-page.d.ts.map +1 -0
- package/dist/server/deny-boundary.d.ts +247 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +16 -5
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/early-hints-sender.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -11
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +86 -10
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +12 -7
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/form-data.d.ts +41 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +35 -0
- package/dist/server/head-response.d.ts.map +1 -0
- package/dist/server/html-injector-core.d.ts +242 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +82 -41
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +10 -47
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +183 -2906
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +51 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +4154 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +39 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/metadata-collector.d.ts +52 -0
- package/dist/server/metadata-collector.d.ts.map +1 -0
- package/dist/server/metadata-routes.d.ts +60 -11
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/metadata.d.ts +8 -0
- package/dist/server/metadata.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +119 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +70 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +77 -0
- package/dist/server/pipeline-helpers.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +59 -9
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +49 -0
- package/dist/server/pipeline-outcome.d.ts.map +1 -0
- package/dist/server/pipeline-phases.d.ts +59 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +151 -19
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/port-resolution.d.ts +117 -0
- package/dist/server/port-resolution.d.ts.map +1 -0
- package/dist/server/prebuilt/cache-key.d.ts +62 -0
- package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +57 -0
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
- package/dist/server/prebuilt/key-discipline.d.ts +23 -0
- package/dist/server/prebuilt/key-discipline.d.ts.map +1 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
- package/dist/server/prebuilt/overlay.d.ts +100 -0
- package/dist/server/prebuilt/overlay.d.ts.map +1 -0
- package/dist/server/prebuilt/payload-source.d.ts +78 -0
- package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +99 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -0
- package/dist/server/prebuilt/synthetic-store.d.ts +66 -0
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
- package/dist/server/prebuilt-builder.d.ts +120 -0
- package/dist/server/prebuilt-builder.d.ts.map +1 -0
- package/dist/server/prebuilt-runtime.d.ts +111 -0
- package/dist/server/prebuilt-runtime.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +100 -44
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/publish-params.d.ts +33 -0
- package/dist/server/publish-params.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/render-utils.d.ts +25 -0
- package/dist/server/render-utils.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +109 -106
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-dep.d.ts +15 -0
- package/dist/server/request-dep.d.ts.map +1 -0
- package/dist/server/route-element-builder.d.ts +74 -27
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +38 -36
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-cache-key-guard.d.ts +78 -0
- package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
- package/dist/server/rsc-entry/api-handler.d.ts +12 -3
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +29 -0
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -0
- package/dist/server/rsc-entry/error-renderer.d.ts +38 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +59 -42
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +39 -6
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +51 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
- package/dist/server/rsc-entry/rsc-payload.d.ts +5 -6
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +40 -3
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +36 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +89 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/skippable-prefix.d.ts +26 -0
- package/dist/server/skippable-prefix.d.ts.map +1 -0
- package/dist/server/slot-interception.d.ts +80 -0
- package/dist/server/slot-interception.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +139 -5
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +138 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +1 -43
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +64 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +61 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/state-tree-diff.d.ts +44 -9
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/static-generator.d.ts +112 -0
- package/dist/server/static-generator.d.ts.map +1 -0
- package/dist/server/static-not-found.d.ts +52 -0
- package/dist/server/static-not-found.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +26 -15
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +47 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +44 -9
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +66 -42
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +49 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/dist/server/types.d.ts +76 -6
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/element-type.d.ts +40 -0
- package/dist/server/utils/element-type.d.ts.map +1 -0
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- package/dist/server/utils/mdx-file.d.ts +15 -0
- package/dist/server/utils/mdx-file.d.ts.map +1 -0
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/server/workers-cache-bridge.d.ts +26 -0
- package/dist/server/workers-cache-bridge.d.ts.map +1 -0
- package/dist/shared/als-slots.d.ts +41 -0
- package/dist/shared/als-slots.d.ts.map +1 -0
- package/dist/shared/base-path.d.ts +56 -0
- package/dist/shared/base-path.d.ts.map +1 -0
- package/dist/shared/href-validation.d.ts +49 -0
- package/dist/shared/href-validation.d.ts.map +1 -0
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shared/param-value.d.ts +80 -0
- package/dist/shared/param-value.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +108 -0
- package/dist/shared/payload-root.d.ts.map +1 -0
- package/dist/shared/redirect-type.d.ts +17 -0
- package/dist/shared/redirect-type.d.ts.map +1 -0
- package/dist/shared/rsc-cache-key.d.ts +163 -0
- package/dist/shared/rsc-cache-key.d.ts.map +1 -0
- package/dist/shared/rsc-error-envelope.d.ts +25 -0
- package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
- package/dist/shared/rsc-manifest.d.ts +28 -0
- package/dist/shared/rsc-manifest.d.ts.map +1 -0
- package/dist/shared/rsc-media-type.d.ts +40 -0
- package/dist/shared/rsc-media-type.d.ts.map +1 -0
- package/dist/shared/rsc-payload-path.d.ts +42 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -0
- package/dist/shared/segment-info.d.ts +66 -0
- package/dist/shared/segment-info.d.ts.map +1 -0
- package/dist/shared/slot-params.d.ts +51 -0
- package/dist/shared/slot-params.d.ts.map +1 -0
- package/dist/shared/static-platform-files.d.ts +71 -0
- package/dist/shared/static-platform-files.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/headers.d.ts +53 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/image.d.ts +120 -120
- package/dist/shims/image.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +25 -12
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +10 -5
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +233 -0
- package/docs/api/31-api-client.mdx +163 -0
- package/docs/api/32-api-cache.mdx +311 -0
- package/docs/api/33-api-search-params.mdx +176 -0
- package/docs/api/34-api-config.mdx +325 -0
- package/docs/api/35-api-typescript.mdx +170 -0
- package/docs/api/36-cli.mdx +170 -0
- package/docs/learn/00-introduction.mdx +109 -0
- package/docs/learn/01-quick-start.mdx +94 -0
- package/docs/learn/02-pages-and-layouts.mdx +147 -0
- package/docs/learn/03-fetching-data.mdx +211 -0
- package/docs/learn/03b-access-control.mdx +130 -0
- package/docs/learn/04-loading-states.mdx +67 -0
- package/docs/learn/04b-the-flush-point.mdx +115 -0
- package/docs/learn/05-typed-params.mdx +275 -0
- package/docs/learn/06-forms-and-actions.mdx +146 -0
- package/docs/learn/07-typed-routes.mdx +132 -0
- package/docs/learn/08-streaming.mdx +146 -0
- package/docs/learn/09-caching.mdx +252 -0
- package/docs/learn/10-middleware.mdx +157 -0
- package/docs/learn/11-error-handling.mdx +173 -0
- package/docs/learn/12-client-navigation.mdx +176 -0
- package/docs/learn/13-configuration.mdx +166 -0
- package/docs/learn/14-deploying.mdx +287 -0
- package/docs/more/01-advanced-routing.mdx +343 -0
- package/docs/more/02-advanced-forms.mdx +137 -0
- package/docs/more/03-coming-from-nextjs.mdx +186 -0
- package/docs/more/04-metadata-and-fonts.mdx +193 -0
- package/docs/more/04b-mdx.mdx +209 -0
- package/docs/more/05-content-collections.mdx +90 -0
- package/docs/more/06-instrumentation.mdx +214 -0
- package/docs/more/07-security.mdx +129 -0
- package/docs/more/08-developer-experience.mdx +134 -0
- package/docs/more/40-why-timber.mdx +50 -0
- package/docs/more/41-timber-vs-nextjs.mdx +81 -0
- package/docs/more/42-timber-vs-others.mdx +68 -0
- package/docs/more/50-ai-agent-instructions.mdx +171 -0
- package/llms.txt +55 -0
- package/package.json +108 -26
- package/src/adapters/build-output-helper.ts +351 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +204 -0
- package/src/adapters/cloudflare.ts +740 -129
- package/src/adapters/compress-module.ts +101 -88
- package/src/adapters/fs-identity.ts +156 -0
- package/src/adapters/nitro.ts +320 -120
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +274 -0
- package/src/adapters/types.ts +28 -7
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +107 -0
- package/src/cache/fast-hash.ts +5 -0
- package/src/cache/handler-store.ts +76 -0
- package/src/cache/index.ts +114 -21
- package/src/cache/invalidation-epoch.ts +93 -0
- package/src/cache/json-lossy-check.ts +75 -0
- package/src/cache/redis-handler.ts +197 -19
- package/src/cache/singleflight.ts +64 -6
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/stable-stringify.ts +65 -2
- package/src/cache/store.ts +71 -0
- package/src/cache/stores/cloudflare-kv.ts +52 -0
- package/src/cache/stores/memory.ts +125 -0
- package/src/cache/stores/redis.ts +97 -0
- package/src/cache/stores/vercel.ts +59 -0
- package/src/cache/tag-aware-handler.ts +237 -0
- package/src/cache/timber-cache.ts +161 -36
- package/src/cdn/cloudflare-purge.ts +50 -0
- package/src/cdn/fastly-purge.ts +63 -0
- package/src/cdn/headers.ts +153 -0
- package/src/cdn/index.ts +17 -0
- package/src/cdn/purge-store.ts +34 -0
- package/src/cdn/workers-cache-purge.ts +30 -0
- package/src/cli-check.ts +458 -0
- package/src/cli-schema-sync.ts +401 -0
- package/src/cli.ts +221 -53
- package/src/client/browser-dev.ts +156 -1
- package/src/client/browser-entry/action-dispatch.ts +130 -0
- package/src/client/browser-entry/hmr.ts +70 -0
- package/src/client/browser-entry/hydrate.ts +198 -0
- package/src/client/browser-entry/index.ts +121 -0
- package/src/client/browser-entry/post-hydration.ts +122 -0
- package/src/client/browser-entry/router-init.ts +342 -0
- package/src/client/browser-entry/rsc-stream.ts +166 -0
- package/src/client/browser-entry/scroll.ts +50 -0
- package/src/client/error-boundary.tsx +210 -36
- package/src/client/error-reconstituter.tsx +79 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +29 -7
- package/src/client/index.ts +78 -45
- package/src/client/internal.ts +59 -0
- package/src/client/link.tsx +397 -150
- package/src/client/navigation-api.ts +345 -0
- package/src/client/navigation-commit.ts +197 -0
- package/src/client/navigation-context.ts +43 -62
- package/src/client/navigation-root.tsx +580 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/params-context.ts +192 -0
- package/src/client/router-effects.ts +231 -0
- package/src/client/router-lifecycle.ts +288 -0
- package/src/client/router-pipeline.ts +393 -0
- package/src/client/router-ref.ts +2 -2
- package/src/client/router-skew.ts +30 -0
- package/src/client/router-types.ts +230 -0
- package/src/client/router.ts +339 -410
- package/src/client/rsc-fetch.ts +530 -73
- package/src/client/segment-cache.ts +224 -38
- package/src/client/segment-outlet.tsx +141 -0
- package/src/client/segment-update-context.ts +42 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/slot-context.ts +50 -0
- package/src/client/slot-outlet.tsx +22 -0
- package/src/client/slot-provider.tsx +32 -0
- package/src/client/ssr-data.ts +19 -5
- package/src/client/stale-client.ts +191 -0
- package/src/client/state.ts +16 -3
- package/src/client/top-loader.tsx +13 -10
- package/src/client/unload-guard.ts +34 -2
- package/src/client/use-cookie.ts +69 -17
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-pathname.ts +1 -0
- package/src/client/use-pending-navigation.ts +40 -0
- package/src/client/use-query-states.ts +206 -36
- package/src/client/use-router.ts +5 -2
- package/src/client/use-search-params.ts +31 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +49 -23
- package/src/codec.ts +149 -0
- package/src/config-types.ts +282 -0
- package/src/config-validation.ts +330 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +222 -53
- package/src/cookies/index.ts +12 -1
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +192 -0
- package/src/dev-tools/404-page.ts +286 -0
- package/src/dev-tools/browser-logs.ts +55 -0
- package/src/dev-tools/dev-page-shell.ts +260 -0
- package/src/dev-tools/error-page.ts +331 -0
- package/src/dev-tools/holding-server.ts +187 -0
- package/src/dev-tools/hydration-overlay.ts +158 -0
- package/src/dev-tools/index.ts +83 -0
- package/src/dev-tools/instrumentation.ts +213 -0
- package/src/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +122 -26
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +182 -0
- package/src/fonts/ast-walk.ts +235 -0
- package/src/fonts/ast.ts +477 -126
- package/src/fonts/bundle.ts +138 -0
- package/src/fonts/dev-middleware.ts +85 -0
- package/src/fonts/fallbacks.ts +0 -23
- package/src/fonts/google.ts +100 -18
- package/src/fonts/local.ts +9 -8
- package/src/fonts/paths.ts +58 -0
- package/src/fonts/pipeline.ts +348 -0
- package/src/fonts/transform.ts +311 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +179 -0
- package/src/index.ts +468 -353
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +115 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +84 -0
- package/src/plugin-context.ts +503 -0
- package/src/plugins/adapter-build.ts +229 -7
- package/src/plugins/build-manifest.ts +201 -26
- package/src/plugins/build-report.ts +259 -47
- package/src/plugins/cache.ts +243 -0
- package/src/plugins/callsite-ast.ts +472 -0
- package/src/plugins/callsite-jsx.ts +243 -0
- package/src/plugins/chunks.ts +74 -5
- package/src/plugins/client-chunks.ts +185 -0
- package/src/plugins/cloudflare-wasm.ts +141 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +284 -94
- package/src/plugins/entries.ts +138 -16
- package/src/plugins/fonts.ts +228 -660
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/prebuilt-capture.ts +217 -0
- package/src/plugins/prebuilt-options-analysis.ts +175 -0
- package/src/plugins/prebuilt.ts +655 -0
- package/src/plugins/prerender-sugar.ts +328 -0
- package/src/plugins/request-dep/analysis.ts +447 -0
- package/src/plugins/request-dep/index.ts +376 -0
- package/src/plugins/request-dep/origin.ts +310 -0
- package/src/plugins/routing.ts +268 -277
- package/src/plugins/server-bundle.ts +89 -12
- package/src/plugins/shims.ts +240 -64
- package/src/plugins/static-build.ts +704 -66
- package/src/routing/codegen-shared.ts +39 -0
- package/src/routing/codegen-types.ts +62 -0
- package/src/routing/codegen-write.ts +139 -0
- package/src/routing/codegen.ts +339 -231
- package/src/routing/collision-probe.ts +438 -0
- package/src/routing/collision-spaces.ts +281 -0
- package/src/routing/convention-lint.ts +493 -0
- package/src/routing/export-detect.ts +448 -0
- package/src/routing/file-cache.ts +23 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +894 -67
- package/src/routing/link-codegen.ts +280 -0
- package/src/routing/manifest-codegen.ts +226 -0
- package/src/routing/scanner.ts +368 -218
- package/src/routing/schema-validation.ts +155 -0
- package/src/routing/segment-classify.ts +280 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/segment-keys.ts +183 -0
- package/src/routing/slot-placement.ts +97 -0
- package/src/routing/types.ts +75 -26
- package/src/routing/walkers.ts +98 -0
- package/src/rsc-runtime/rsc.ts +9 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/schema-bridge.ts +380 -0
- package/src/search-params/define.ts +677 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/parse-total.ts +91 -0
- package/src/search-params/serialize-equal.ts +14 -0
- package/src/search-params/wrappers.ts +150 -0
- package/src/server/access-gate.tsx +121 -51
- package/src/server/action-client.ts +120 -29
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +127 -38
- package/src/server/actions.ts +54 -57
- package/src/server/als-registry.ts +154 -20
- package/src/server/asset-headers.ts +15 -37
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +33 -57
- package/src/server/canonicalize.ts +6 -3
- package/src/server/chain-url-parts.ts +162 -0
- package/src/server/children-interception.ts +115 -0
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +43 -8
- package/src/server/cookie-context.ts +484 -0
- package/src/server/cookie-parsing.ts +163 -0
- package/src/server/csrf.ts +39 -6
- package/src/server/default-logger.ts +99 -0
- package/src/server/default-status-page.ts +127 -0
- package/src/server/deny-boundary.ts +516 -0
- package/src/server/deny-renderer.ts +181 -101
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/early-hints.ts +37 -27
- package/src/server/error-boundary-wrapper.ts +170 -44
- package/src/server/fallback-error.ts +79 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/form-data.ts +124 -12
- package/src/server/head-response.ts +54 -0
- package/src/server/html-injector-core.ts +495 -0
- package/src/server/html-injectors.ts +271 -254
- package/src/server/index.ts +29 -185
- package/src/server/internal.ts +181 -0
- package/src/server/logger.ts +72 -36
- package/src/server/metadata-collector.ts +115 -0
- package/src/server/metadata-routes.ts +205 -24
- package/src/server/metadata.ts +21 -0
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +336 -0
- package/src/server/param-coercion.ts +189 -0
- package/src/server/pipeline-helpers.ts +159 -0
- package/src/server/pipeline-interception.ts +109 -33
- package/src/server/pipeline-metadata.ts +14 -0
- package/src/server/pipeline-outcome.ts +196 -0
- package/src/server/pipeline-phases.ts +597 -0
- package/src/server/pipeline.ts +321 -382
- package/src/server/port-resolution.ts +215 -0
- package/src/server/prebuilt/cache-key.ts +298 -0
- package/src/server/prebuilt/capture-state.ts +89 -0
- package/src/server/prebuilt/key-discipline.ts +53 -0
- package/src/server/prebuilt/manifest-tag-index.ts +46 -0
- package/src/server/prebuilt/overlay.ts +256 -0
- package/src/server/prebuilt/payload-source.ts +201 -0
- package/src/server/prebuilt/slots.ts +190 -0
- package/src/server/prebuilt/synthetic-store.ts +121 -0
- package/src/server/prebuilt-builder.ts +803 -0
- package/src/server/prebuilt-runtime.ts +815 -0
- package/src/server/primitives.ts +174 -90
- package/src/server/publish-params.ts +42 -0
- package/src/server/render-timeout.ts +108 -0
- package/src/server/render-utils.ts +31 -0
- package/src/server/request-context.ts +245 -333
- package/src/server/request-dep.ts +37 -0
- package/src/server/route-element-builder.ts +687 -307
- package/src/server/route-handler.ts +39 -12
- package/src/server/route-matcher.ts +162 -269
- package/src/server/rsc-cache-key-guard.ts +164 -0
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +67 -32
- package/src/server/rsc-entry/deny-fallback.ts +93 -0
- package/src/server/rsc-entry/error-renderer.ts +370 -94
- package/src/server/rsc-entry/helpers.ts +226 -95
- package/src/server/rsc-entry/index.ts +357 -330
- package/src/server/rsc-entry/render-route.ts +308 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +350 -0
- package/src/server/rsc-entry/rsc-payload.ts +188 -55
- package/src/server/rsc-entry/rsc-stream.ts +122 -18
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +299 -80
- package/src/server/rsc-entry/wrap-action-dispatch.ts +186 -0
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/server-only-guard-noop.js +3 -0
- package/src/server/sitemap-generator.ts +339 -0
- package/src/server/sitemap-handler.ts +157 -0
- package/src/server/skippable-prefix.ts +74 -0
- package/src/server/slot-interception.ts +168 -0
- package/src/server/slot-resolver.ts +677 -294
- package/src/server/ssr-bridge-types.ts +142 -0
- package/src/server/ssr-entry.ts +216 -78
- package/src/server/ssr-render.ts +345 -82
- package/src/server/ssr-wrappers.tsx +142 -0
- package/src/server/state-tree-diff.ts +85 -30
- package/src/server/static-generator.ts +715 -0
- package/src/server/static-not-found.ts +134 -0
- package/src/server/status-code-resolver.ts +107 -148
- package/src/server/stream-utils.ts +288 -0
- package/src/server/tracing.ts +126 -14
- package/src/server/tree-builder.ts +99 -168
- package/src/server/tree-match.ts +262 -0
- package/src/server/types.ts +83 -9
- package/src/server/utils/element-type.ts +72 -0
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/utils/mdx-file.ts +22 -0
- package/src/server/version-skew.ts +104 -0
- package/src/server/workers-cache-bridge.ts +33 -0
- package/src/shared/als-slots.ts +72 -0
- package/src/shared/base-path.ts +80 -0
- package/src/shared/href-validation.ts +159 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shared/param-value.ts +244 -0
- package/src/shared/payload-root.ts +151 -0
- package/src/shared/redirect-type.ts +17 -0
- package/src/shared/rsc-cache-key.ts +269 -0
- package/src/shared/rsc-error-envelope.ts +31 -0
- package/src/shared/rsc-manifest.ts +29 -0
- package/src/shared/rsc-media-type.ts +43 -0
- package/src/shared/rsc-payload-path.ts +45 -0
- package/src/shared/segment-info.ts +67 -0
- package/src/shared/slot-params.ts +111 -0
- package/src/shared/static-platform-files.ts +75 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +122 -1
- package/src/shims/navigation-client.ts +36 -32
- package/src/shims/navigation.ts +10 -7
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-B3Gypr3D.js +0 -108
- package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
- package/dist/_chunks/format-RyoGQL74.js +0 -164
- package/dist/_chunks/format-RyoGQL74.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js +0 -676
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/metadata-routes-Cjmvi3rQ.js +0 -153
- package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
- package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
- package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js +0 -187
- package/dist/_chunks/tracing-CemImE6h.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js +0 -109
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/adapters/cloudflare.js.map +0 -1
- package/dist/cache/index.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.map +0 -1
- package/dist/client/error-boundary.js.map +0 -1
- package/dist/client/head.d.ts +0 -16
- package/dist/client/head.d.ts.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/segment-merger.d.ts +0 -119
- package/dist/client/segment-merger.d.ts.map +0 -1
- package/dist/client/stale-reload.d.ts +0 -44
- package/dist/client/stale-reload.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts +0 -74
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts +0 -26
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/client/use-params.d.ts.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dev-error-overlay.d.ts +0 -60
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-logs.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/plugins/server-action-exports.d.ts +0 -26
- package/dist/plugins/server-action-exports.d.ts.map +0 -1
- package/dist/routing/status-file-lint.d.ts +0 -33
- package/dist/routing/status-file-lint.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/search-params/registry.d.ts +0 -20
- package/dist/search-params/registry.d.ts.map +0 -1
- package/dist/server/client-module-map.d.ts +0 -47
- package/dist/server/client-module-map.d.ts.map +0 -1
- package/dist/server/dev-fetch-instrumentation.d.ts +0 -22
- package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
- package/dist/server/dev-logger.d.ts.map +0 -1
- package/dist/server/dev-span-processor.d.ts +0 -29
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts +0 -129
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/flush.d.ts +0 -74
- package/dist/server/flush.d.ts.map +0 -1
- package/dist/server/manifest-status-resolver.d.ts +0 -58
- package/dist/server/manifest-status-resolver.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/utils/directive-parser.d.ts +0 -70
- package/dist/utils/directive-parser.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/head.ts +0 -61
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/segment-merger.ts +0 -339
- package/src/client/stale-reload.ts +0 -87
- package/src/client/transition-root.tsx +0 -166
- package/src/client/use-navigation-pending.ts +0 -38
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dev-error-overlay.ts +0 -230
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/plugins/server-action-exports.ts +0 -220
- package/src/routing/status-file-lint.ts +0 -112
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/codecs.ts +0 -153
- package/src/search-params/create.ts +0 -321
- package/src/search-params/registry.ts +0 -31
- package/src/server/client-module-map.ts +0 -58
- package/src/server/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/dev-warnings.ts +0 -283
- package/src/server/flush.ts +0 -182
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/utils/directive-parser.ts +0 -529
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'You Might Not Need A loading.tsx'
|
|
3
|
+
description: 'When timber commits the HTTP status code and why it matters.'
|
|
4
|
+
slug: 'loading-states'
|
|
5
|
+
notAI: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# You Might Not Need A `loading.tsx`
|
|
9
|
+
|
|
10
|
+
Most React frameworks push you towards building page-level skeletons or loading states. Though it's entirely trivial to build out that experience with timber, we nudge you away from that for several reasons.
|
|
11
|
+
|
|
12
|
+
This is not referring to loading states on things like mutations (like submitting a form) or other actions. This is referring to initial (server) or secondary (client) page loading.
|
|
13
|
+
|
|
14
|
+
This is how we as frontend engineers make browsing the web a less anxiety-inducing experience.
|
|
15
|
+
|
|
16
|
+
### Loading States Are an Extra Class of UI to Maintain
|
|
17
|
+
|
|
18
|
+
You have to design loading states. Decide between spinners and skeletons, and then mimic your UI in the skeleton.
|
|
19
|
+
|
|
20
|
+
### Loading States Cause Content Layout Shift
|
|
21
|
+
|
|
22
|
+
Loading states are fixed and content is most often dynamic both in size (think text length) and count (think number of rows). So even if you work incredibly hard to avoid major CLS, you'll invariably end up with CLS somewhere.
|
|
23
|
+
|
|
24
|
+
### Loading States Are a Flash of UI
|
|
25
|
+
|
|
26
|
+
Loading states are inherently temporary, so this adds flashes of content. This causes anxiety as the page spasms before finally reaching an undetermined final state. The user is left in a daze wondering if the page is finally ready.
|
|
27
|
+
|
|
28
|
+
Every possible "finite state" of UI is another that you and the user have to keep in context. You'll be _surprised_ how much simpler a website feels when a page has one major representation, vs several.
|
|
29
|
+
|
|
30
|
+
### Loading States Hide Prior Context
|
|
31
|
+
|
|
32
|
+
Go to an old PHP site and click a URL. The _browser_ shows a loading state, but the prior page remains visible. The new page only becomes visible once it is ready. There's little advantage to hiding the past context while the user waits for the new context to load.
|
|
33
|
+
|
|
34
|
+
### timber Includes a Global Route-Based Loading State
|
|
35
|
+
|
|
36
|
+
On every route change, timber triggers a global page-level toploader loading state. If you want to add a secondary loading state that dims the prior content, you can easily do so.
|
|
37
|
+
|
|
38
|
+
### Loading States Break JavaScript Disabled Requests
|
|
39
|
+
|
|
40
|
+
`curl` a page with a `loading.tsx` and you'll get back a shell, not the content. Though people downsell the cost, it genuinely does hinder both SEO and agentic requests.
|
|
41
|
+
|
|
42
|
+
Leaning on the web as intended is always better than assuming _all_ consumers have JavaScript enabled. Plus, sticking JavaScript in between your _hot_ rendering path is _inherently_ slower. It's just not necessary when you adopt a comprehensive web architecture like React Server Components.
|
|
43
|
+
|
|
44
|
+
### Loading States Break Status Codes
|
|
45
|
+
|
|
46
|
+
Loading states flush before the content is even fetched. This feels _faster_, but you are flushing before you know if the user is authenticated, the data exists, or any other class of issue. By flushing immediately, you are forced to send a 200 and lean on JavaScript-injected meta tags to signify errors.
|
|
47
|
+
|
|
48
|
+
This breaks the contract of the web for any consumer that isn't a human. Use real status codes, you will gain downstream benefits from doing so.
|
|
49
|
+
|
|
50
|
+
### Most Loading States Paper Over a Bad Data Architecture
|
|
51
|
+
|
|
52
|
+
People often use loading states because their database is poorly optimized, or 50ms away from their rendering server, or otherwise. With a well designed data infrastructure, you can often fetch your data plenty fast to render your entire page in < 100ms.
|
|
53
|
+
|
|
54
|
+
And when you can't, you can stream and flush those rare pages trivially.
|
|
55
|
+
|
|
56
|
+
### Loading States Still Have Value, but More-So as Opt-In Secondary or Tertiary Content
|
|
57
|
+
|
|
58
|
+
To add a loading state as a small sub-section of a page is trivial – just wrap your component in `<Suspense>` and you can defer slower, lower priority content.
|
|
59
|
+
|
|
60
|
+
If you decide you want a full page level loading state, you can wrap your layout or page in `<Suspense>` on a case by case basis. No `loading.tsx` needed.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
--------
|
|
64
|
+
|
|
65
|
+
A `loading.tsx` forces your flush point up ever so slightly, but you give up all the things above. Instead, timber asks you to place `<Suspense>` boundaries yourself – thereby _explicitly_ opting into the flush point.
|
|
66
|
+
|
|
67
|
+
Now you get a calm, performant website that doesn't have immense content-layout-shift, doesn't hide prior content during loading, and can return proper status codes. The `loading.tsx` seems innocent enough, but its cost both cognitively and architecturally is high.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'The Flush Point'
|
|
3
|
+
description: 'When timber commits the HTTP status code and why it matters.'
|
|
4
|
+
slug: 'the-flush-point'
|
|
5
|
+
# notAI: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# The Flush Point
|
|
9
|
+
|
|
10
|
+
The flush point is when the framework sends the first byte of HTML to the browser and commits the HTTP status code. In a traditional PHP website, this happens all at once.
|
|
11
|
+
|
|
12
|
+
But modern web frameworks, and notably react server components, have embraced a streaming architecture. Allowing you to send content _after_ the flush point.
|
|
13
|
+
|
|
14
|
+
While this is ultimately incredibly powerful, it brings forth confusion because contextually, code can have different side effects depending on _when_ you call it.
|
|
15
|
+
|
|
16
|
+
On a next.js app, if I call `notFound()` inside of a `page.tsx` that has a sibling `loading.tsx` – my status code will return `200`. By obfuscating the flush point, we've actually just made developer clarity murky.
|
|
17
|
+
|
|
18
|
+
So timber works differently. At no point does timber flush early, unless _you_ (the developer), choose to place a `<Suspense>` boundary. Often this will end up being below your `page.tsx` level, so you'll still have access to controlling and sending proper status codes.
|
|
19
|
+
|
|
20
|
+
------
|
|
21
|
+
|
|
22
|
+
AI below..
|
|
23
|
+
|
|
24
|
+
## The Problem
|
|
25
|
+
|
|
26
|
+
Most streaming frameworks send a `200 OK` immediately and figure out the real outcome later:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Request → 200 OK → ... render ... → oh, it's a 404
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
By the time the server discovers the page doesn't exist, the status code is already sent. The client sees `200`. Search engines see `200`. CDNs cache it as `200`.
|
|
33
|
+
|
|
34
|
+
This breaks search engines (deleted pages never deindex), CDNs (404s get cached as successes), monitoring (zero errors while users see broken pages), and `curl`/scripts (`curl -f` won't detect the failure).
|
|
35
|
+
|
|
36
|
+
## timber's Solution
|
|
37
|
+
|
|
38
|
+
timber holds the response until it knows the real outcome:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Request arrives
|
|
42
|
+
→ Route matched
|
|
43
|
+
→ proxy.ts runs
|
|
44
|
+
→ middleware.ts runs
|
|
45
|
+
→ access.ts runs
|
|
46
|
+
→ React shell renders (onShellReady)
|
|
47
|
+
→ ✓ Status code committed ← flush point
|
|
48
|
+
→ Shell HTML sent to browser
|
|
49
|
+
→ Suspense boundaries stream in
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The status code commits when **all three** conditions are met:
|
|
53
|
+
|
|
54
|
+
1. Middleware completed without returning a response
|
|
55
|
+
2. All access checks passed (or denied with a real status code)
|
|
56
|
+
3. React's `onShellReady` fired — the synchronous shell rendered without error
|
|
57
|
+
|
|
58
|
+
A missing page returns a real `404`. A failed auth check returns a real `403`. A redirect returns a real `302`. The HTTP layer tells the truth.
|
|
59
|
+
|
|
60
|
+
## Before and After the Flush
|
|
61
|
+
|
|
62
|
+
**Before the flush** (blocking):
|
|
63
|
+
|
|
64
|
+
- `proxy.ts` — global request processing
|
|
65
|
+
- `middleware.ts` — route-level request processing
|
|
66
|
+
- `access.ts` — authorization gates
|
|
67
|
+
- Synchronous component rendering (the shell)
|
|
68
|
+
|
|
69
|
+
**After the flush** (streaming):
|
|
70
|
+
|
|
71
|
+
- `<Suspense>` boundaries resolve and stream in
|
|
72
|
+
- Slow data loads complete
|
|
73
|
+
- The page progressively fills in
|
|
74
|
+
|
|
75
|
+
``` leading="none"
|
|
76
|
+
┌─────── flush point
|
|
77
|
+
│
|
|
78
|
+
▼
|
|
79
|
+
├────────┤──────────────────────────┤
|
|
80
|
+
blocking streaming
|
|
81
|
+
(shell) (suspense boundaries)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Everything before the flush determines the status code. Everything after streams progressively. You control the boundary by choosing what goes inside `<Suspense>` and what doesn't.
|
|
85
|
+
|
|
86
|
+
## Pages Work Without JavaScript
|
|
87
|
+
|
|
88
|
+
Because timber holds the flush until the shell is complete, the browser receives a fully-formed HTML document. Content is visible, links work as standard `<a>` tags, and forms submit as standard POSTs. JavaScript adds client-side navigation, interactive components, and streaming updates — but the page works without it.
|
|
89
|
+
|
|
90
|
+
This isn't a special mode. It's how timber works by default.
|
|
91
|
+
|
|
92
|
+
## Early Hints
|
|
93
|
+
|
|
94
|
+
timber doesn't make you wait for assets while the shell renders. At route-match time — before middleware runs — timber sends `103 Early Hints` with CSS, JS, and font URLs. The browser starts downloading assets while the server is still working:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
103 Early Hints
|
|
98
|
+
Link: </styles/main.css>; rel=preload; as=style
|
|
99
|
+
Link: </chunks/page-abc.js>; rel=modulepreload
|
|
100
|
+
|
|
101
|
+
... middleware runs, shell renders ...
|
|
102
|
+
|
|
103
|
+
200 OK
|
|
104
|
+
<html>...
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
You get the correctness of a held flush with the performance of early resource loading.
|
|
108
|
+
|
|
109
|
+
## How to Think About It
|
|
110
|
+
|
|
111
|
+
Primary content — the data that defines whether a page exists, who can see it, and what it contains — should load before the flush. Put it in your components directly.
|
|
112
|
+
|
|
113
|
+
Secondary content — recommendations, activity feeds, analytics widgets — can load after the flush. Wrap it in `<Suspense>`.
|
|
114
|
+
|
|
115
|
+
The flush point is the dividing line between "what the page _is_" and "what the page _also shows_."
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Typed Params'
|
|
3
|
+
description: 'Codecs, segment params, search params, and cookies — typed values that cross boundaries.'
|
|
4
|
+
slug: 'typed-params'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Typed Params
|
|
8
|
+
|
|
9
|
+
Values that cross boundaries — URL path segments, query strings, cookies — arrive as strings. timber provides a unified system for parsing them into typed values using **codecs**.
|
|
10
|
+
|
|
11
|
+
## Codecs
|
|
12
|
+
|
|
13
|
+
A codec converts between string values and typed values:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
interface Codec<T> {
|
|
17
|
+
parse(value: string | string[] | undefined): T;
|
|
18
|
+
serialize(value: T): string | string[] | null; // string[] for repeated keys
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Any object with `parse` and `serialize` is a valid codec. You can use Zod schemas, [nuqs](https://nuqs.47ng.com/) parsers, or write your own. Standard Schema objects (Zod, Valibot, ArkType) are auto-detected — no wrapper needed.
|
|
23
|
+
|
|
24
|
+
## Segment Params
|
|
25
|
+
|
|
26
|
+
Dynamic segments (`[id]`, `[slug]`) capture raw strings from the URL. Define codecs in a global `app/schema.ts` to coerce them into typed values:
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
```ts title="app/schema.ts" id="schema"
|
|
30
|
+
import { defineSchema } from '@timber-js/app/params';
|
|
31
|
+
import { codec } from '@timber-js/app/codec';
|
|
32
|
+
import { z } from 'zod/v4';
|
|
33
|
+
|
|
34
|
+
export default defineSchema({
|
|
35
|
+
segmentParams: {
|
|
36
|
+
'[id]': z.coerce.number().int().positive(),
|
|
37
|
+
'[artistSlug]': codec.string,
|
|
38
|
+
'[year]': codec.integer,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<Callout variant="tip" title="Auto-generated Schema Sync">
|
|
44
|
+
You can auto-generate this file at any time (or any incremental updates) by running `npx timber schema sync`.
|
|
45
|
+
</Callout>
|
|
46
|
+
|
|
47
|
+
Each key uses the bracket syntax from the filesystem (`[id]`, `[...slug]`, `[[...slug]]`). A dynamic segment with no key here defaults to `string`. Invalid values produce a **404** — if `/products/abc` can't parse `abc` as a positive integer, the resource doesn't exist.
|
|
48
|
+
|
|
49
|
+
Each dynamic segment gets one codec. If you want two different schemas for a dynamic segment, give it another name. For example: if you want `[id]` to be `number` in one place, but `uuid` in another – rename the latter to `[uuid]`.
|
|
50
|
+
|
|
51
|
+
Every dynamic segment key must be unique across segment types (dynamic, catch-all, optional-catch-all). That means `[id]` and `[...id]` will throw a build error. That way, we can be sure `const { id } = getSegmentParams();` is either a flat or array value. Change the latter to `[...ids]` to fix it.
|
|
52
|
+
|
|
53
|
+
### Type Narrowing with `$segment`
|
|
54
|
+
|
|
55
|
+
Each route directory gets a generated `./$segment` virtual module that exports `SEGMENT_PATH` — a string literal typed to the segment's tree path. Import it and pass it to `getSegmentParams()` for exact types:
|
|
56
|
+
|
|
57
|
+
```tsx title="app/products/[id]/page.tsx" use="schema"
|
|
58
|
+
import { SEGMENT_PATH } from './$segment';
|
|
59
|
+
import { getSegmentParams } from '@timber-js/app/server';
|
|
60
|
+
|
|
61
|
+
export default async function ProductPage() {
|
|
62
|
+
const { id } = getSegmentParams(SEGMENT_PATH); // id: number — narrowed!
|
|
63
|
+
const product = await getProduct(id);
|
|
64
|
+
// ...
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Without `SEGMENT_PATH`, `getSegmentParams()` returns `Partial<AllSegmentParams>` — all params optional, honest types. With `SEGMENT_PATH`, you get exact types for the current route depth.
|
|
69
|
+
|
|
70
|
+
Coercion runs **after route matching, before middleware**. Middleware and access checks receive already-typed params.
|
|
71
|
+
|
|
72
|
+
### Client Usage
|
|
73
|
+
|
|
74
|
+
Use `useSegmentParams()` with the same `SEGMENT_PATH` pattern in client components:
|
|
75
|
+
|
|
76
|
+
```tsx title="app/products/[id]/breadcrumb.tsx" use="schema"
|
|
77
|
+
'use client';
|
|
78
|
+
import { SEGMENT_PATH } from './$segment';
|
|
79
|
+
import { useSegmentParams } from '@timber-js/app/client';
|
|
80
|
+
|
|
81
|
+
export function ProductBreadcrumb() {
|
|
82
|
+
const { id } = useSegmentParams(SEGMENT_PATH);
|
|
83
|
+
return <span>Product {id}</span>;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`SEGMENT_PATH` flows from server → client via RSC serialization — it's just a string.
|
|
88
|
+
|
|
89
|
+
### Shared Components
|
|
90
|
+
|
|
91
|
+
Pass `SEGMENT_PATH` as a prop for type-safe shared components:
|
|
92
|
+
|
|
93
|
+
```tsx title="components/year-header.tsx"
|
|
94
|
+
import { getSegmentParams } from '@timber-js/app/server';
|
|
95
|
+
|
|
96
|
+
export function YearHeader({ segmentPath }: { segmentPath: string }) {
|
|
97
|
+
const { artistSlug, year } = getSegmentParams(segmentPath);
|
|
98
|
+
return <h1>{artistSlug} — {year}</h1>;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Without Type Narrowing
|
|
103
|
+
|
|
104
|
+
Omit the argument to get all params as optional:
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { getSegmentParams } from '@timber-js/app/server';
|
|
108
|
+
|
|
109
|
+
const params = getSegmentParams();
|
|
110
|
+
// ^ Partial<AllSegmentParams> — all optional, honest types
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Search Params
|
|
114
|
+
|
|
115
|
+
Declare typed search params with `defineSearchParams` in any module, then import it where you need it. Unlike segment params, there is no convention file and nothing is scanned:
|
|
116
|
+
|
|
117
|
+
```ts title="app/products/search-params.ts" id="search-params"
|
|
118
|
+
import { defineSearchParams, withDefault } from '@timber-js/app/search-params';
|
|
119
|
+
import { parseAsInteger } from 'nuqs';
|
|
120
|
+
import { z } from 'zod/v4';
|
|
121
|
+
|
|
122
|
+
export const searchParams = defineSearchParams({
|
|
123
|
+
page: withDefault(parseAsInteger, 1),
|
|
124
|
+
sort: z.enum(['price', 'name', 'date']).default('date'),
|
|
125
|
+
q: z.string().optional(),
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Server Usage
|
|
130
|
+
|
|
131
|
+
```tsx title="app/products/page.tsx" use="search-params"
|
|
132
|
+
import { searchParams } from './search-params';
|
|
133
|
+
|
|
134
|
+
export default async function ProductsPage() {
|
|
135
|
+
const { page, sort, q } = searchParams.get();
|
|
136
|
+
const products = await getProducts({ page, sort, query: q });
|
|
137
|
+
return <ProductList products={products} />;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Client Usage
|
|
142
|
+
|
|
143
|
+
```tsx title="app/products/filters.tsx" use="search-params"
|
|
144
|
+
'use client';
|
|
145
|
+
import { searchParams } from './search-params';
|
|
146
|
+
|
|
147
|
+
export function ProductFilters() {
|
|
148
|
+
const [params, setParams] = searchParams.useQueryStates();
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div>
|
|
152
|
+
<input
|
|
153
|
+
value={params.q ?? ''}
|
|
154
|
+
onChange={(e) => setParams({ q: e.target.value })}
|
|
155
|
+
/>
|
|
156
|
+
<select
|
|
157
|
+
value={params.sort}
|
|
158
|
+
onChange={(e) => setParams({ sort: e.target.value })}
|
|
159
|
+
>
|
|
160
|
+
<option value="date">Date</option>
|
|
161
|
+
<option value="price">Price</option>
|
|
162
|
+
<option value="name">Name</option>
|
|
163
|
+
</select>
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
By default, `.useQueryStates()` triggers an RSC navigation when params change. Set `shallow: true` to update the URL without a server roundtrip.
|
|
170
|
+
|
|
171
|
+
## Cookies
|
|
172
|
+
|
|
173
|
+
Define typed cookies with `defineCookie()`:
|
|
174
|
+
|
|
175
|
+
```ts title="lib/cookies.ts"
|
|
176
|
+
import { defineCookie } from '@timber-js/app/cookies';
|
|
177
|
+
import { z } from 'zod/v4';
|
|
178
|
+
|
|
179
|
+
export const themeCookie = defineCookie('theme', {
|
|
180
|
+
codec: z.enum(['light', 'dark', 'system']).default('system'),
|
|
181
|
+
httpOnly: false,
|
|
182
|
+
maxAge: 60 * 60 * 24 * 365,
|
|
183
|
+
});
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Server:
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
const theme = await themeCookie.getCookie(); // 'light' | 'dark' | 'system'
|
|
190
|
+
await themeCookie.setCookie('dark'); // before flush only
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Client:
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
'use client';
|
|
197
|
+
import { themeCookie } from '../lib/cookies';
|
|
198
|
+
|
|
199
|
+
export function ThemeToggle() {
|
|
200
|
+
const [theme, setTheme] = themeCookie.useCookie();
|
|
201
|
+
return (
|
|
202
|
+
<select value={theme} onChange={(e) => setTheme(e.target.value as typeof theme)}>
|
|
203
|
+
<option value="light">Light</option>
|
|
204
|
+
<option value="dark">Dark</option>
|
|
205
|
+
<option value="system">System</option>
|
|
206
|
+
</select>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
{/* ## Built-in Codecs
|
|
212
|
+
|
|
213
|
+
timber ships zero-dependency codecs for common types:
|
|
214
|
+
|
|
215
|
+
| Codec | Type | Example |
|
|
216
|
+
| --------------------------- | ----------------- | ------------------------- |
|
|
217
|
+
| `parseAsString` | `string \| null` | `?q=shoes` → `'shoes'` |
|
|
218
|
+
| `parseAsInteger` | `number \| null` | `?page=2` → `2` |
|
|
219
|
+
| `parseAsFloat` | `number \| null` | `?price=9.99` → `9.99` |
|
|
220
|
+
| `parseAsBoolean` | `boolean \| null` | `?debug=true` → `true` |
|
|
221
|
+
| `parseAsStringEnum(values)` | `T \| null` | `?sort=price` → `'price'` |
|
|
222
|
+
|
|
223
|
+
For segment params, use the `codec` namespace:
|
|
224
|
+
|
|
225
|
+
| Codec | Type | Description |
|
|
226
|
+
| ------------------ | ----------------------- | ------------------------ |
|
|
227
|
+
| `codec.string` | `string` | Default (no-op passthrough) |
|
|
228
|
+
| `codec.integer` | `number` | Integer coercion |
|
|
229
|
+
| `codec.slug` | `string` | URL-safe slug |
|
|
230
|
+
| `codec.stringArray` | `string[]` | For catch-all segments |
|
|
231
|
+
| `codec.catchAll(inner)` | `T[]` | Wraps scalar codec for catch-all segments |
|
|
232
|
+
| `codec.optionalCatchAll(inner)` | `T[] \| undefined` | Wraps scalar codec for optional catch-all segments |
|
|
233
|
+
|
|
234
|
+
Use `withDefault()` to get a non-nullable type for search params. [nuqs](https://nuqs.47ng.com/) parsers all work as codecs: an absent param is `null` and a repeated one takes the first value. Note that `parseAsArrayOf` reads a comma-separated list from a single key — for repeated keys (`?ids=1&ids=2`) use an array schema, e.g. `z.array(z.string()).default([])`. */}
|
|
235
|
+
|
|
236
|
+
## Composition
|
|
237
|
+
|
|
238
|
+
Compose codec maps via plain object spread:
|
|
239
|
+
|
|
240
|
+
```ts title="lib/search-params/pagination.ts"
|
|
241
|
+
import { withDefault } from '@timber-js/app/search-params';
|
|
242
|
+
import { parseAsInteger } from 'nuqs';
|
|
243
|
+
|
|
244
|
+
export const pagination = {
|
|
245
|
+
page: withDefault(parseAsInteger, 1),
|
|
246
|
+
pageSize: withDefault(parseAsInteger, 20),
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
```ts title="app/products/search-params.ts"
|
|
251
|
+
import { defineSearchParams } from '@timber-js/app/search-params';
|
|
252
|
+
import { pagination } from '@/lib/search-params/pagination';
|
|
253
|
+
import { z } from 'zod/v4';
|
|
254
|
+
|
|
255
|
+
export const searchParams = defineSearchParams({
|
|
256
|
+
...pagination,
|
|
257
|
+
sort: z.enum(['asc', 'desc']).default('asc'),
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## URL Key Aliasing
|
|
262
|
+
|
|
263
|
+
Map a property name to a different URL key with `withUrlKey`:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { defineSearchParams, withUrlKey } from '@timber-js/app/search-params';
|
|
267
|
+
import { z } from 'zod/v4';
|
|
268
|
+
|
|
269
|
+
export const searchParams = defineSearchParams({
|
|
270
|
+
query: withUrlKey(z.string().nullable().default(null), 'q'),
|
|
271
|
+
});
|
|
272
|
+
// ?q=shoes → { query: 'shoes' }
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
For the full codec protocol, array codecs, and custom codec guidelines, see the [API: Search Params](/docs/api-params) reference.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: 'Forms and Actions'
|
|
3
|
+
description: 'Server actions with validation, progressive enhancement, and forms that work without JavaScript.'
|
|
4
|
+
slug: 'forms-and-actions'
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Forms and Actions
|
|
8
|
+
|
|
9
|
+
Forms in timber.js work without JavaScript. They submit to the server, validate, and return a result. When JavaScript is available, they enhance with client-side state and pending UI.
|
|
10
|
+
|
|
11
|
+
## Action Clients
|
|
12
|
+
|
|
13
|
+
Define reusable action middleware with `createActionClient`:
|
|
14
|
+
|
|
15
|
+
```ts title="lib/action.ts"
|
|
16
|
+
import { createActionClient, ActionError } from '@timber-js/app/server';
|
|
17
|
+
import { getUser } from '@/lib/auth';
|
|
18
|
+
|
|
19
|
+
export const action = createActionClient({
|
|
20
|
+
middleware: async () => {
|
|
21
|
+
const user = await getUser();
|
|
22
|
+
if (!user) throw new ActionError('UNAUTHORIZED');
|
|
23
|
+
return { user };
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Defining Actions
|
|
29
|
+
|
|
30
|
+
```ts title="app/todos/actions.ts"
|
|
31
|
+
'use server';
|
|
32
|
+
|
|
33
|
+
import { z } from 'zod/v4';
|
|
34
|
+
import { action } from '@/lib/action';
|
|
35
|
+
import { revalidatePath } from '@timber-js/app/server';
|
|
36
|
+
|
|
37
|
+
declare const db: { todos: { create(data: { title: string; userId: string }): Promise<void> } };
|
|
38
|
+
|
|
39
|
+
export const createTodo = action
|
|
40
|
+
.schema(z.object({ title: z.string().min(1) }))
|
|
41
|
+
.action(async ({ input, ctx }) => {
|
|
42
|
+
await db.todos.create({ ...input, userId: ctx.user.id });
|
|
43
|
+
return revalidatePath('/todos');
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The `.schema()` method accepts any Standard Schema-compatible validator — Zod, Valibot, or ArkType. Validation errors are returned to the client automatically.
|
|
48
|
+
|
|
49
|
+
## Using Actions in Forms
|
|
50
|
+
|
|
51
|
+
```tsx title="app/todos/todo-form.tsx"
|
|
52
|
+
'use client';
|
|
53
|
+
|
|
54
|
+
import { useActionState } from '@timber-js/app/client';
|
|
55
|
+
import { createTodo } from './actions';
|
|
56
|
+
|
|
57
|
+
export default function TodoForm() {
|
|
58
|
+
const [state, action, pending, errors] = useActionState(createTodo, null);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<form action={action}>
|
|
62
|
+
<div>
|
|
63
|
+
<input name="title" required />
|
|
64
|
+
{errors.getFieldError('title') && (
|
|
65
|
+
<p className="text-red-600">{errors.getFieldError('title')}</p>
|
|
66
|
+
)}
|
|
67
|
+
</div>
|
|
68
|
+
{errors.serverError && (
|
|
69
|
+
<p className="text-red-600">Something went wrong. Please try again.</p>
|
|
70
|
+
)}
|
|
71
|
+
<button type="submit" disabled={pending}>
|
|
72
|
+
{pending ? 'Adding...' : 'Add Todo'}
|
|
73
|
+
</button>
|
|
74
|
+
</form>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Without JS, this submits as a standard form POST. With JS, `useActionState` handles pending state and error display.
|
|
80
|
+
|
|
81
|
+
### Form Errors
|
|
82
|
+
|
|
83
|
+
`useActionState` from `@timber-js/app/client` returns a 4-tuple where the 4th element is auto-derived form errors:
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
const [state, action, pending, errors] = useActionState(myAction, null);
|
|
87
|
+
|
|
88
|
+
errors.fieldErrors; // Record<string, string[]>
|
|
89
|
+
errors.formErrors; // string[] (form-level errors)
|
|
90
|
+
errors.serverError; // { code: string; data?: Record<string, unknown> } | null
|
|
91
|
+
errors.hasErrors; // boolean
|
|
92
|
+
errors.getFieldError('title'); // string | null (first error for field)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## After Mutation
|
|
96
|
+
|
|
97
|
+
| Pattern | When to use |
|
|
98
|
+
| ------------------------- | ------------------------------------------------ |
|
|
99
|
+
| `redirect('/path')` | User should land somewhere new |
|
|
100
|
+
| `revalidatePath('/path')` | Current page needs fresh data |
|
|
101
|
+
| `useOptimistic` | Instant UI update, action confirms in background |
|
|
102
|
+
|
|
103
|
+
## Forms Without JavaScript
|
|
104
|
+
|
|
105
|
+
When JavaScript is disabled and a server action returns validation errors, timber re-renders the page instead of redirecting. The errors and submitted values are available via `getFormFlash()`:
|
|
106
|
+
|
|
107
|
+
```tsx title="app/todos/page.tsx"
|
|
108
|
+
import { getFormFlash } from '@timber-js/app/server';
|
|
109
|
+
import { TodoForm } from './todo-form';
|
|
110
|
+
|
|
111
|
+
export default async function TodosPage() {
|
|
112
|
+
const flash = getFormFlash();
|
|
113
|
+
return <TodoForm flash={flash} />;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```tsx title="app/todos/todo-form.tsx"
|
|
118
|
+
'use client';
|
|
119
|
+
|
|
120
|
+
import { useActionState } from '@timber-js/app/client';
|
|
121
|
+
import { createTodo } from './actions';
|
|
122
|
+
import type { FormFlashData } from '@timber-js/app/server';
|
|
123
|
+
|
|
124
|
+
export function TodoForm({ flash }: { flash?: FormFlashData | null }) {
|
|
125
|
+
const [state, action, pending, errors] = useActionState(createTodo, null);
|
|
126
|
+
|
|
127
|
+
const fieldError = (field: string) =>
|
|
128
|
+
errors.getFieldError(field) ?? flash?.validationErrors?.[field]?.[0];
|
|
129
|
+
const defaultValue = (field: string) =>
|
|
130
|
+
(flash?.submittedValues?.[field] as string) ?? '';
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<form action={action}>
|
|
134
|
+
<input name="title" defaultValue={defaultValue('title')} />
|
|
135
|
+
{fieldError('title') && <p className="text-red-600">{fieldError('title')}</p>}
|
|
136
|
+
<button type="submit" disabled={pending}>
|
|
137
|
+
{pending ? 'Adding...' : 'Add Todo'}
|
|
138
|
+
</button>
|
|
139
|
+
</form>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Flash data is server-side only — stored in AsyncLocalStorage for the duration of the re-render. Sensitive fields (password, apiKey, cvv, etc.) are automatically stripped from `submittedValues`.
|
|
145
|
+
|
|
146
|
+
For advanced topics — coercion helpers, `parseFormData`, sensitive field stripping configuration, and the full end-to-end example — see [Advanced Forms](/docs/advanced-forms).
|