@timber-js/app 0.2.0-alpha.17 → 0.2.0-alpha.170
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-O_LsyCE4.js +317 -0
- package/dist/_chunks/actions-O_LsyCE4.js.map +1 -0
- package/dist/_chunks/build-output-helper-DF5uScqS.js +158 -0
- package/dist/_chunks/build-output-helper-DF5uScqS.js.map +1 -0
- package/dist/_chunks/cache-api-B-lhk9p4.js +1202 -0
- package/dist/_chunks/cache-api-B-lhk9p4.js.map +1 -0
- package/dist/_chunks/canonicalize-Du3o_ptW.js +247 -0
- package/dist/_chunks/canonicalize-Du3o_ptW.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-B5FDplGI.js +688 -0
- package/dist/_chunks/cli-schema-sync-B5FDplGI.js.map +1 -0
- package/dist/_chunks/cloudflare-AHoWYTYr.js +1188 -0
- package/dist/_chunks/cloudflare-AHoWYTYr.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/define-COtkxMRT.js +191 -0
- package/dist/_chunks/define-COtkxMRT.js.map +1 -0
- package/dist/_chunks/define-c4au4I9R.js +82 -0
- package/dist/_chunks/define-c4au4I9R.js.map +1 -0
- package/dist/_chunks/dist-BA3u1z3W.js +423 -0
- package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js +36 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +1 -0
- package/dist/_chunks/format-CfwjgPz9.js +14 -0
- package/dist/_chunks/format-CfwjgPz9.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-AWfuX-KJ.js +1468 -0
- package/dist/_chunks/logger-AWfuX-KJ.js.map +1 -0
- package/dist/_chunks/navigation-root-bUDZLw74.js +124 -0
- package/dist/_chunks/navigation-root-bUDZLw74.js.map +1 -0
- package/dist/_chunks/plugin-context---kTF5v8.js +315 -0
- package/dist/_chunks/plugin-context---kTF5v8.js.map +1 -0
- package/dist/_chunks/registry-DbJPKoBp.js +20 -0
- package/dist/_chunks/registry-DbJPKoBp.js.map +1 -0
- package/dist/_chunks/resolve-schema-Dz3fcFUo.js +50 -0
- package/dist/_chunks/resolve-schema-Dz3fcFUo.js.map +1 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js +28 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js.map +1 -0
- package/dist/_chunks/schema-bridge-DT_Tn0Xf.js +119 -0
- package/dist/_chunks/schema-bridge-DT_Tn0Xf.js.map +1 -0
- package/dist/_chunks/segment-classify-Byy425ng.js +176 -0
- package/dist/_chunks/segment-classify-Byy425ng.js.map +1 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js +34 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js.map +1 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BOWsq18U.js} +1 -1
- package/dist/_chunks/ssr-data-BOWsq18U.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-DFvWd-EA.js} +71 -26
- package/dist/_chunks/use-query-states-DFvWd-EA.js.map +1 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js +151 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +1 -0
- package/dist/_chunks/walkers-DCoE-LJf.js +1002 -0
- package/dist/_chunks/walkers-DCoE-LJf.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +29 -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 +189 -21
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -188
- package/dist/adapters/compress-module.d.ts +5 -4
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +41 -3
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +224 -172
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +6 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +2 -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/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/fastly-purge.d.ts +25 -0
- package/dist/cdn/fastly-purge.d.ts.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/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/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +34 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +109 -34
- 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 +46 -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 +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +27 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -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/child-segment-context.d.ts +22 -0
- package/dist/client/child-segment-context.d.ts.map +1 -0
- package/dist/client/child-segment-outlet.d.ts +18 -0
- package/dist/client/child-segment-outlet.d.ts.map +1 -0
- package/dist/client/child-segment-provider.d.ts +21 -0
- package/dist/client/child-segment-provider.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +47 -10
- package/dist/client/error-boundary.js.map +1 -1
- 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 +21 -6
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +10 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +185 -1134
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +19 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +849 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link.d.ts +69 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-api.d.ts +120 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +3 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +119 -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/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +93 -14
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +47 -14
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +4 -4
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +49 -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 +29 -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 +20 -0
- package/dist/client/slot-provider.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.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 +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- 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} +8 -6
- 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 +46 -180
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8506 -13599
- 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 +217 -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 +43 -7
- 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/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 +5 -26
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +67 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +64 -0
- package/dist/routing/codegen-types.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/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/export-detect.d.ts +56 -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 +4 -2
- package/dist/routing/interception.d.ts +0 -5
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/manifest-codegen.d.ts +32 -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 +81 -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/types.d.ts +81 -25
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +51 -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 +91 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +188 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +34 -441
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +89 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +8 -3
- 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 +6 -30
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +93 -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 +6 -29
- 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/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- 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/deny-boundary.d.ts +117 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +2 -2
- 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 +7 -1
- 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/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 +11 -47
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +182 -2906
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +49 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +3945 -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-routes.d.ts +47 -11
- package/dist/server/metadata-routes.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 +54 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +95 -0
- package/dist/server/pipeline-helpers.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- 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 +140 -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 +74 -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 +88 -43
- package/dist/server/primitives.d.ts.map +1 -1
- 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 +62 -107
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +55 -25
- 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 +25 -36
- package/dist/server/route-matcher.d.ts.map +1 -1
- 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 +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +51 -28
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +28 -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 +25 -1
- 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 +34 -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/slot-resolver.d.ts +7 -5
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +121 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +2 -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 +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/state-tree-diff.d.ts +36 -6
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/status-code-resolver.d.ts +22 -11
- 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 +62 -30
- 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 +71 -6
- package/dist/server/types.d.ts.map +1 -1
- 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/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/redirect-type.d.ts +17 -0
- package/dist/shared/redirect-type.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 +35 -11
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +11 -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 +161 -0
- package/docs/api/32-api-cache.mdx +311 -0
- package/docs/api/33-api-search-params.mdx +154 -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 +143 -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 +127 -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 +156 -0
- package/docs/learn/12-client-navigation.mdx +176 -0
- package/docs/learn/13-configuration.mdx +162 -0
- package/docs/learn/14-deploying.mdx +264 -0
- package/docs/more/01-advanced-routing.mdx +173 -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 +169 -0
- package/llms.txt +55 -0
- package/package.json +105 -26
- package/src/adapters/build-output-helper.ts +199 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +204 -0
- package/src/adapters/cloudflare.ts +620 -129
- package/src/adapters/compress-module.ts +27 -92
- package/src/adapters/nitro.ts +266 -122
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +68 -0
- package/src/adapters/types.ts +2 -7
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +107 -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-schema-sync.ts +401 -0
- package/src/cli.ts +157 -34
- package/src/client/browser-dev.ts +156 -1
- package/src/client/browser-entry/action-dispatch.ts +124 -0
- package/src/client/browser-entry/hmr.ts +70 -0
- package/src/client/browser-entry/hydrate.ts +187 -0
- package/src/client/browser-entry/index.ts +113 -0
- package/src/client/browser-entry/post-hydration.ts +110 -0
- package/src/client/browser-entry/router-init.ts +289 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +50 -0
- package/src/client/child-segment-context.ts +40 -0
- package/src/client/child-segment-outlet.tsx +25 -0
- package/src/client/child-segment-provider.tsx +27 -0
- package/src/client/error-boundary.tsx +127 -22
- package/src/client/error-reconstituter.tsx +79 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +21 -6
- package/src/client/index.ts +67 -45
- package/src/client/internal.ts +58 -0
- package/src/client/link.tsx +349 -150
- package/src/client/navigation-api.ts +341 -0
- package/src/client/navigation-context.ts +15 -7
- package/src/client/navigation-root.tsx +355 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +538 -206
- package/src/client/rsc-fetch.ts +214 -33
- package/src/client/segment-cache.ts +11 -12
- package/src/client/segment-outlet.tsx +77 -0
- package/src/client/segment-update-context.ts +42 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/slot-context.ts +48 -0
- package/src/client/slot-outlet.tsx +22 -0
- package/src/client/slot-provider.tsx +25 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/state.ts +2 -2
- package/src/client/top-loader.tsx +11 -9
- package/src/client/use-cookie.ts +60 -15
- 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 +108 -10
- package/src/client/use-router.ts +4 -1
- package/src/client/use-search-params.ts +31 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +9 -6
- 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 +217 -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 +63 -8
- 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 +444 -352
- 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 +432 -0
- package/src/plugins/adapter-build.ts +220 -7
- package/src/plugins/build-manifest.ts +168 -23
- package/src/plugins/build-report.ts +253 -35
- 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 +134 -16
- package/src/plugins/fonts.ts +225 -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/routing.ts +237 -241
- package/src/plugins/server-bundle.ts +89 -12
- package/src/plugins/shims.ts +241 -64
- package/src/plugins/static-build.ts +15 -90
- package/src/routing/codegen-shared.ts +115 -0
- package/src/routing/codegen-types.ts +65 -0
- package/src/routing/codegen.ts +372 -178
- package/src/routing/convention-lint.ts +394 -0
- package/src/routing/export-detect.ts +304 -0
- package/src/routing/file-cache.ts +23 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +3 -22
- package/src/routing/link-codegen.ts +313 -0
- package/src/routing/manifest-codegen.ts +287 -0
- package/src/routing/scanner.ts +338 -189
- package/src/routing/schema-validation.ts +155 -0
- package/src/routing/segment-classify.ts +223 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/types.ts +82 -25
- package/src/routing/walkers.ts +90 -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 +253 -0
- package/src/search-params/define.ts +576 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +101 -0
- package/src/segment-params/define.ts +249 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +84 -34
- package/src/server/action-client.ts +120 -29
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +123 -33
- package/src/server/actions.ts +48 -54
- package/src/server/als-registry.ts +137 -20
- package/src/server/asset-headers.ts +15 -37
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +13 -56
- package/src/server/canonicalize.ts +6 -3
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +34 -7
- 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/deny-boundary.ts +314 -0
- package/src/server/deny-renderer.ts +85 -77
- 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 +61 -22
- 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/html-injector-core.ts +495 -0
- package/src/server/html-injectors.ts +271 -254
- package/src/server/index.ts +31 -185
- package/src/server/internal.ts +181 -0
- package/src/server/logger.ts +72 -36
- package/src/server/metadata-routes.ts +110 -24
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +336 -0
- package/src/server/param-coercion.ts +207 -0
- package/src/server/pipeline-helpers.ts +204 -0
- package/src/server/pipeline-interception.ts +45 -18
- package/src/server/pipeline-metadata.ts +14 -0
- package/src/server/pipeline-outcome.ts +197 -0
- package/src/server/pipeline-phases.ts +545 -0
- package/src/server/pipeline.ts +274 -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 +167 -0
- package/src/server/prebuilt/synthetic-store.ts +121 -0
- package/src/server/prebuilt-builder.ts +808 -0
- package/src/server/prebuilt-runtime.ts +815 -0
- package/src/server/primitives.ts +160 -83
- package/src/server/render-timeout.ts +108 -0
- package/src/server/render-utils.ts +31 -0
- package/src/server/request-context.ts +168 -337
- package/src/server/route-element-builder.ts +661 -278
- package/src/server/route-handler.ts +31 -4
- package/src/server/route-matcher.ts +158 -277
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +69 -32
- package/src/server/rsc-entry/deny-fallback.ts +92 -0
- package/src/server/rsc-entry/error-renderer.ts +306 -89
- package/src/server/rsc-entry/helpers.ts +165 -79
- package/src/server/rsc-entry/index.ts +332 -341
- package/src/server/rsc-entry/render-route.ts +292 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +349 -0
- package/src/server/rsc-entry/rsc-payload.ts +95 -39
- package/src/server/rsc-entry/rsc-stream.ts +93 -13
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +273 -43
- 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 +345 -0
- package/src/server/sitemap-handler.ts +157 -0
- package/src/server/slot-resolver.ts +264 -257
- package/src/server/ssr-bridge-types.ts +124 -0
- package/src/server/ssr-entry.ts +206 -78
- package/src/server/ssr-render.ts +345 -82
- package/src/server/ssr-wrappers.tsx +141 -0
- package/src/server/state-tree-diff.ts +76 -24
- package/src/server/status-code-resolver.ts +115 -130
- package/src/server/stream-utils.ts +288 -0
- package/src/server/tracing.ts +126 -14
- package/src/server/tree-builder.ts +204 -90
- package/src/server/tree-match.ts +262 -0
- package/src/server/types.ts +78 -9
- 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/href-validation.ts +159 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shared/redirect-type.ts +17 -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 +51 -29
- package/src/shims/navigation.ts +14 -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.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/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/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/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
package/src/client/rsc-fetch.ts
CHANGED
|
@@ -12,18 +12,24 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { SegmentInfo } from './segment-cache';
|
|
15
|
-
import type { HeadElement } from './head';
|
|
16
15
|
import type { RouterDeps } from './router';
|
|
17
16
|
|
|
18
17
|
// ─── Types ───────────────────────────────────────────────────────
|
|
19
18
|
|
|
20
|
-
/** Result of fetching an RSC payload — includes
|
|
19
|
+
/** Result of fetching an RSC payload — includes segment metadata. */
|
|
21
20
|
export interface FetchResult {
|
|
22
21
|
payload: unknown;
|
|
23
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Promise that settles when the RSC decode completes or fails.
|
|
24
|
+
* The payload thenable is NOT awaited before returning (for streaming),
|
|
25
|
+
* so callers must monitor this to catch async decode errors
|
|
26
|
+
* (truncated streams, Flight parse failures) that would otherwise
|
|
27
|
+
* become unhandled rejections.
|
|
28
|
+
*/
|
|
29
|
+
decodePromise: Promise<void> | null;
|
|
24
30
|
/** Segment metadata from X-Timber-Segments header for populating the segment cache. */
|
|
25
31
|
segmentInfo: SegmentInfo[] | null;
|
|
26
|
-
/** Route params from X-Timber-Params header for populating
|
|
32
|
+
/** Route params from X-Timber-Params header for populating useSegmentParams(). */
|
|
27
33
|
params: Record<string, string | string[]> | null;
|
|
28
34
|
/** Segment paths that were skipped by the server (for client-side merging). */
|
|
29
35
|
skippedSegments: string[] | null;
|
|
@@ -52,12 +58,54 @@ function generateCacheBustId(): string {
|
|
|
52
58
|
* Append a `_rsc=<id>` query parameter to the URL.
|
|
53
59
|
* Follows Next.js's pattern — prevents CDN/browser from serving cached HTML
|
|
54
60
|
* for RSC navigation requests and signals that this is an RSC fetch.
|
|
61
|
+
*
|
|
62
|
+
* Strips any #fragment before appending — fragments are client-only and
|
|
63
|
+
* fetch() discards them, so _rsc would land inside the hash and be lost.
|
|
55
64
|
*/
|
|
56
65
|
function appendRscParam(url: string): string {
|
|
57
|
-
const
|
|
58
|
-
|
|
66
|
+
const hashIndex = url.indexOf('#');
|
|
67
|
+
const urlWithoutHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
68
|
+
const separator = urlWithoutHash.includes('?') ? '&' : '?';
|
|
69
|
+
return `${urlWithoutHash}${separator}_rsc=${generateCacheBustId()}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── Deployment ID ───────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The client's deployment ID, set at bootstrap from the runtime config.
|
|
76
|
+
* Sent with every RSC/action request for version skew detection.
|
|
77
|
+
* Null in dev mode. See TIM-446.
|
|
78
|
+
*/
|
|
79
|
+
let clientDeploymentId: string | null = null;
|
|
80
|
+
|
|
81
|
+
/** Set the client deployment ID. Called once at bootstrap. */
|
|
82
|
+
export function setClientDeploymentId(id: string | null): void {
|
|
83
|
+
clientDeploymentId = id;
|
|
59
84
|
}
|
|
60
85
|
|
|
86
|
+
/** Get the client deployment ID. */
|
|
87
|
+
export function getClientDeploymentId(): string | null {
|
|
88
|
+
return clientDeploymentId;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ─── Reload Signal ───────────────────────────────────────────────
|
|
92
|
+
|
|
93
|
+
/** Header name used by the server to signal a version skew reload. */
|
|
94
|
+
export const RELOAD_HEADER = 'X-Timber-Reload';
|
|
95
|
+
|
|
96
|
+
/** Header name for the client's deployment ID. */
|
|
97
|
+
export const DEPLOYMENT_ID_HEADER = 'X-Timber-Deployment-Id';
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Check if a response signals a version skew reload.
|
|
101
|
+
* Triggers a full page reload if the server indicates the client is stale.
|
|
102
|
+
*/
|
|
103
|
+
export function checkReloadSignal(response: Response): boolean {
|
|
104
|
+
return response.headers.get(RELOAD_HEADER) === '1';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ─── Header Builder ──────────────────────────────────────────────
|
|
108
|
+
|
|
61
109
|
export function buildRscHeaders(
|
|
62
110
|
stateTree: { segments: string[] } | undefined,
|
|
63
111
|
currentUrl?: string
|
|
@@ -75,22 +123,26 @@ export function buildRscHeaders(
|
|
|
75
123
|
if (currentUrl) {
|
|
76
124
|
headers['X-Timber-URL'] = currentUrl;
|
|
77
125
|
}
|
|
126
|
+
// Send deployment ID for version skew detection (TIM-446).
|
|
127
|
+
// The server compares this against the current build's ID.
|
|
128
|
+
// On mismatch, the server signals a reload instead of returning
|
|
129
|
+
// an RSC payload with mismatched module references.
|
|
130
|
+
if (clientDeploymentId) {
|
|
131
|
+
headers[DEPLOYMENT_ID_HEADER] = clientDeploymentId;
|
|
132
|
+
}
|
|
78
133
|
return headers;
|
|
79
134
|
}
|
|
80
135
|
|
|
81
136
|
// ─── Response Header Extraction ──────────────────────────────────
|
|
82
137
|
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return JSON.parse(decodeURIComponent(header));
|
|
92
|
-
} catch {
|
|
93
|
-
return null;
|
|
138
|
+
/** Dev-only warning for malformed framework headers. Tree-shaken in production. */
|
|
139
|
+
function warnMalformedHeader(headerName: string, raw: string): void {
|
|
140
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
141
|
+
const preview = raw.length > 200 ? raw.slice(0, 200) + '…' : raw;
|
|
142
|
+
console.warn(
|
|
143
|
+
`[timber] Malformed ${headerName} header \u2014 JSON.parse failed. ` +
|
|
144
|
+
`This indicates a framework bug or header corruption. Raw (first 200 chars): ${preview}`
|
|
145
|
+
);
|
|
94
146
|
}
|
|
95
147
|
}
|
|
96
148
|
|
|
@@ -108,6 +160,7 @@ export function extractSegmentInfo(response: Response): SegmentInfo[] | null {
|
|
|
108
160
|
try {
|
|
109
161
|
return JSON.parse(header);
|
|
110
162
|
} catch {
|
|
163
|
+
warnMalformedHeader('X-Timber-Segments', header);
|
|
111
164
|
return null;
|
|
112
165
|
}
|
|
113
166
|
}
|
|
@@ -127,6 +180,7 @@ export function extractSkippedSegments(response: Response): string[] | null {
|
|
|
127
180
|
const parsed = JSON.parse(header);
|
|
128
181
|
return Array.isArray(parsed) ? parsed : null;
|
|
129
182
|
} catch {
|
|
183
|
+
warnMalformedHeader('X-Timber-Skipped-Segments', header);
|
|
130
184
|
return null;
|
|
131
185
|
}
|
|
132
186
|
}
|
|
@@ -135,7 +189,7 @@ export function extractSkippedSegments(response: Response): string[] | null {
|
|
|
135
189
|
* Extract route params from the X-Timber-Params response header.
|
|
136
190
|
* Returns null if the header is missing or malformed.
|
|
137
191
|
*
|
|
138
|
-
* Used to populate
|
|
192
|
+
* Used to populate useSegmentParams() after client-side navigation.
|
|
139
193
|
*/
|
|
140
194
|
export function extractParams(response: Response): Record<string, string | string[]> | null {
|
|
141
195
|
const header = response.headers.get('X-Timber-Params');
|
|
@@ -143,6 +197,7 @@ export function extractParams(response: Response): Record<string, string | strin
|
|
|
143
197
|
try {
|
|
144
198
|
return JSON.parse(header);
|
|
145
199
|
} catch {
|
|
200
|
+
warnMalformedHeader('X-Timber-Params', header);
|
|
146
201
|
return null;
|
|
147
202
|
}
|
|
148
203
|
}
|
|
@@ -161,21 +216,97 @@ export class RedirectError extends Error {
|
|
|
161
216
|
}
|
|
162
217
|
}
|
|
163
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Thrown when the server signals a version skew (X-Timber-Reload header).
|
|
221
|
+
* Caught in navigate() to trigger a full page reload.
|
|
222
|
+
* See TIM-446.
|
|
223
|
+
*/
|
|
224
|
+
export class VersionSkewError extends Error {
|
|
225
|
+
constructor() {
|
|
226
|
+
super('Version skew detected — server has been redeployed');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Thrown when the server returns an error for an RSC payload request.
|
|
232
|
+
* The server sends X-Timber-Error header and a JSON body instead of a
|
|
233
|
+
* broken RSC stream for any RenderError (4xx or 5xx). Caught in
|
|
234
|
+
* navigate() to trigger a hard navigation so the server can render
|
|
235
|
+
* the error page as HTML.
|
|
236
|
+
*
|
|
237
|
+
* See design/10-error-handling.md §"Error Page Rendering for Client Navigation"
|
|
238
|
+
*/
|
|
239
|
+
export class ServerErrorResponse extends Error {
|
|
240
|
+
readonly status: number;
|
|
241
|
+
readonly url: string;
|
|
242
|
+
constructor(status: number, url: string) {
|
|
243
|
+
super(`Server error ${status} during navigation to ${url}`);
|
|
244
|
+
this.status = status;
|
|
245
|
+
this.url = url;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ─── Stream Completion Tracking ───────────────────────────────────
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Wrap a response body stream to track when it's fully consumed.
|
|
253
|
+
* Returns a new body that passes all chunks through unchanged, plus
|
|
254
|
+
* a `done` promise that resolves when the last chunk is read (or
|
|
255
|
+
* rejects if the stream errors).
|
|
256
|
+
*
|
|
257
|
+
* Used to keep React transitions open for the full RSC stream
|
|
258
|
+
* duration — createFromFetch's thenable resolves on shell arrival,
|
|
259
|
+
* but we need stream completion for useOptimistic pending state.
|
|
260
|
+
*/
|
|
261
|
+
function trackStreamCompletion(body: ReadableStream<Uint8Array>): {
|
|
262
|
+
body: ReadableStream<Uint8Array>;
|
|
263
|
+
done: Promise<void>;
|
|
264
|
+
} {
|
|
265
|
+
let resolveDone!: () => void;
|
|
266
|
+
let rejectDone!: (e: unknown) => void;
|
|
267
|
+
const done = new Promise<void>((res, rej) => {
|
|
268
|
+
resolveDone = res;
|
|
269
|
+
rejectDone = rej;
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const reader = body.getReader();
|
|
273
|
+
const tracked = new ReadableStream<Uint8Array>({
|
|
274
|
+
async pull(controller) {
|
|
275
|
+
try {
|
|
276
|
+
const result = await reader.read();
|
|
277
|
+
if (result.done) {
|
|
278
|
+
controller.close();
|
|
279
|
+
resolveDone();
|
|
280
|
+
} else {
|
|
281
|
+
controller.enqueue(result.value);
|
|
282
|
+
}
|
|
283
|
+
} catch (error) {
|
|
284
|
+
controller.error(error);
|
|
285
|
+
rejectDone(error);
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
cancel(reason) {
|
|
289
|
+
reader.cancel(reason);
|
|
290
|
+
resolveDone();
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
return { body: tracked, done };
|
|
295
|
+
}
|
|
296
|
+
|
|
164
297
|
// ─── Fetch ───────────────────────────────────────────────────────
|
|
165
298
|
|
|
166
299
|
/**
|
|
167
300
|
* Fetch an RSC payload from the server. If a decodeRsc function is provided,
|
|
168
301
|
* the response is decoded into a React element tree via createFromFetch.
|
|
169
302
|
* Otherwise, the raw response text is returned (test mode).
|
|
170
|
-
*
|
|
171
|
-
* Also extracts head elements from the X-Timber-Head response header
|
|
172
|
-
* so the client can update document.title and <meta> tags after navigation.
|
|
173
303
|
*/
|
|
174
304
|
export async function fetchRscPayload(
|
|
175
305
|
url: string,
|
|
176
306
|
deps: RouterDeps,
|
|
177
307
|
stateTree?: { segments: string[] },
|
|
178
|
-
currentUrl?: string
|
|
308
|
+
currentUrl?: string,
|
|
309
|
+
signal?: AbortSignal
|
|
179
310
|
): Promise<FetchResult> {
|
|
180
311
|
const rscUrl = appendRscParam(url);
|
|
181
312
|
const headers = buildRscHeaders(stateTree, currentUrl);
|
|
@@ -184,14 +315,24 @@ export async function fetchRscPayload(
|
|
|
184
315
|
// createFromFetch takes a Promise<Response> and progressively parses
|
|
185
316
|
// the RSC Flight stream as chunks arrive.
|
|
186
317
|
//
|
|
187
|
-
// Intercept the response to read
|
|
318
|
+
// Intercept the response to read segment metadata before createFromFetch
|
|
188
319
|
// consumes the body. Reading headers does NOT consume the body stream.
|
|
189
|
-
const fetchPromise = deps.fetch(rscUrl, { headers, redirect: 'manual' });
|
|
190
|
-
let headElements: HeadElement[] | null = null;
|
|
320
|
+
const fetchPromise = deps.fetch(rscUrl, { headers, redirect: 'manual', signal });
|
|
191
321
|
let segmentInfo: SegmentInfo[] | null = null;
|
|
192
322
|
let params: Record<string, string | string[]> | null = null;
|
|
193
323
|
let skippedSegments: string[] | null = null;
|
|
324
|
+
// Track when the full RSC body stream is consumed (not just shell).
|
|
325
|
+
// Initialized to resolved for bodyless responses; overwritten when
|
|
326
|
+
// the response has a body.
|
|
327
|
+
let streamDone: Promise<void> = Promise.resolve();
|
|
328
|
+
|
|
194
329
|
const wrappedPromise = fetchPromise.then((response) => {
|
|
330
|
+
// Version skew detection (TIM-446): if the server signals a reload,
|
|
331
|
+
// throw VersionSkewError so the caller (router navigate) can trigger
|
|
332
|
+
// a full page reload.
|
|
333
|
+
if (checkReloadSignal(response)) {
|
|
334
|
+
throw new VersionSkewError();
|
|
335
|
+
}
|
|
195
336
|
// Detect server-side redirects. The server returns 204 + X-Timber-Redirect
|
|
196
337
|
// for RSC payload requests instead of a raw 302, because fetch with
|
|
197
338
|
// redirect: "manual" turns 302s into opaque redirects (status 0, null body)
|
|
@@ -202,21 +343,61 @@ export async function fetchRscPayload(
|
|
|
202
343
|
if (redirectLocation) {
|
|
203
344
|
throw new RedirectError(redirectLocation);
|
|
204
345
|
}
|
|
205
|
-
|
|
346
|
+
// Detect server error responses. The server returns X-Timber-Error header
|
|
347
|
+
// with a JSON body instead of a broken RSC stream for any RenderError
|
|
348
|
+
// (4xx or 5xx). Hard-navigate so the server renders the error page as HTML.
|
|
349
|
+
// See design/10-error-handling.md §"Error Page Rendering for Client Navigation"
|
|
350
|
+
if (response.headers.get('X-Timber-Error') === '1') {
|
|
351
|
+
throw new ServerErrorResponse(response.status, url);
|
|
352
|
+
}
|
|
353
|
+
// Metadata (<title>/<meta>/<link>) now rides the RSC Flight payload
|
|
354
|
+
// as React elements — React 19 Float handles them. See TIM-1151.
|
|
206
355
|
segmentInfo = extractSegmentInfo(response);
|
|
207
356
|
params = extractParams(response);
|
|
208
357
|
skippedSegments = extractSkippedSegments(response);
|
|
358
|
+
|
|
359
|
+
// Wrap the body to track full stream consumption. createFromFetch's
|
|
360
|
+
// thenable resolves when the root model (shell) arrives, but we need
|
|
361
|
+
// to know when ALL chunks are read so the React transition stays
|
|
362
|
+
// open for the full streaming duration (keeps useOptimistic alive).
|
|
363
|
+
if (response.body) {
|
|
364
|
+
const tracked = trackStreamCompletion(response.body);
|
|
365
|
+
streamDone = tracked.done;
|
|
366
|
+
streamDone.catch(() => {}); // prevent unhandled rejection
|
|
367
|
+
return new Response(tracked.body, {
|
|
368
|
+
headers: response.headers,
|
|
369
|
+
status: response.status,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
209
372
|
return response;
|
|
210
373
|
});
|
|
211
|
-
// Await so
|
|
212
|
-
// Also await the decoded payload — createFromFetch returns a thenable
|
|
213
|
-
// that resolves to the React element tree.
|
|
374
|
+
// Await headers so segmentInfo/params are populated.
|
|
214
375
|
await wrappedPromise;
|
|
215
|
-
|
|
216
|
-
|
|
376
|
+
// Start decoding but do NOT await — return the in-progress thenable.
|
|
377
|
+
// React can render a Flight thenable directly: it suspends on unresolved
|
|
378
|
+
// parts and progressively renders as chunks arrive, spreading work across
|
|
379
|
+
// frames instead of blocking the main thread in one burst.
|
|
380
|
+
const payload = deps.decodeRsc(wrappedPromise);
|
|
381
|
+
// Combine stream completion with payload error propagation.
|
|
382
|
+
// streamDone keeps the transition open for the full RSC stream
|
|
383
|
+
// duration (useOptimistic pending state). payloadError propagates
|
|
384
|
+
// decode failures (stale client references, Flight parse errors)
|
|
385
|
+
// so the router's catch block can trigger recovery (stale reload).
|
|
386
|
+
const payloadError = new Promise<void>((_, reject) => {
|
|
387
|
+
Promise.resolve(payload).then(() => {}, reject);
|
|
388
|
+
});
|
|
389
|
+
payloadError.catch(() => {});
|
|
390
|
+
const decodePromise = Promise.race([streamDone, payloadError]);
|
|
391
|
+
return {
|
|
392
|
+
payload,
|
|
393
|
+
decodePromise,
|
|
394
|
+
segmentInfo,
|
|
395
|
+
params,
|
|
396
|
+
skippedSegments,
|
|
397
|
+
};
|
|
217
398
|
}
|
|
218
399
|
// Test/fallback path: return raw text
|
|
219
|
-
const response = await deps.fetch(rscUrl, { headers, redirect: 'manual' });
|
|
400
|
+
const response = await deps.fetch(rscUrl, { headers, redirect: 'manual', signal });
|
|
220
401
|
// Check for redirect in test path too
|
|
221
402
|
if (response.status >= 300 && response.status < 400) {
|
|
222
403
|
const location = response.headers.get('Location');
|
|
@@ -226,7 +407,7 @@ export async function fetchRscPayload(
|
|
|
226
407
|
}
|
|
227
408
|
return {
|
|
228
409
|
payload: await response.text(),
|
|
229
|
-
|
|
410
|
+
decodePromise: null,
|
|
230
411
|
segmentInfo: extractSegmentInfo(response),
|
|
231
412
|
params: extractParams(response),
|
|
232
413
|
skippedSegments: extractSkippedSegments(response),
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
// Segment Cache — stores the mounted segment tree and prefetched payloads
|
|
2
2
|
// See design/19-client-navigation.md for architecture details.
|
|
3
3
|
|
|
4
|
-
import type { HeadElement } from './head';
|
|
5
|
-
|
|
6
4
|
// ─── Types ───────────────────────────────────────────────────────
|
|
7
5
|
|
|
8
|
-
/** A prefetched RSC result with optional
|
|
6
|
+
/** A prefetched RSC result with optional segment metadata. */
|
|
9
7
|
export interface PrefetchResult {
|
|
10
8
|
payload: unknown;
|
|
11
|
-
headElements: HeadElement[] | null;
|
|
12
9
|
/** Segment metadata from X-Timber-Segments header for populating the segment cache. */
|
|
13
10
|
segmentInfo?: SegmentInfo[] | null;
|
|
14
|
-
/** Route params from X-Timber-Params header for populating
|
|
11
|
+
/** Route params from X-Timber-Params header for populating useSegmentParams(). */
|
|
15
12
|
params?: Record<string, string | string[]> | null;
|
|
16
13
|
/** Segment paths skipped by the server (for client-side merging). */
|
|
17
14
|
skippedSegments?: string[] | null;
|
|
@@ -111,6 +108,8 @@ function collectSyncSegments(
|
|
|
111
108
|
*/
|
|
112
109
|
export interface SegmentInfo {
|
|
113
110
|
path: string;
|
|
111
|
+
/** Outlet key — includes route group name when applicable (e.g., "/(marketing)"). */
|
|
112
|
+
segmentId?: string;
|
|
114
113
|
isAsync: boolean;
|
|
115
114
|
}
|
|
116
115
|
|
|
@@ -129,16 +128,16 @@ export function buildSegmentTree(segments: SegmentInfo[]): SegmentNode | undefin
|
|
|
129
128
|
// Need at least a root segment to build a tree
|
|
130
129
|
if (segments.length === 0) return undefined;
|
|
131
130
|
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
// All entries are layout segments — the server filters out layoutless
|
|
132
|
+
// segments (including the page leaf) in buildSegmentInfo. Cache every
|
|
133
|
+
// entry; pages are never sent.
|
|
136
134
|
let root: SegmentNode | undefined;
|
|
137
135
|
let parent: SegmentNode | undefined;
|
|
138
136
|
|
|
139
|
-
for (const info of
|
|
137
|
+
for (const info of segments) {
|
|
138
|
+
const id = info.segmentId ?? info.path;
|
|
140
139
|
const node: SegmentNode = {
|
|
141
|
-
segment:
|
|
140
|
+
segment: id,
|
|
142
141
|
payload: null,
|
|
143
142
|
isAsync: info.isAsync,
|
|
144
143
|
children: new Map(),
|
|
@@ -149,7 +148,7 @@ export function buildSegmentTree(segments: SegmentInfo[]): SegmentNode | undefin
|
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
if (parent) {
|
|
152
|
-
parent.children.set(
|
|
151
|
+
parent.children.set(id, node);
|
|
153
152
|
}
|
|
154
153
|
|
|
155
154
|
parent = node;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SegmentOutlet — client component boundary at each layout segment.
|
|
3
|
+
*
|
|
4
|
+
* Each layout in the segment tree is wrapped with a SegmentOutlet that:
|
|
5
|
+
* 1. Knows its segment path (prop from the server)
|
|
6
|
+
* 2. Reads from SegmentUpdateContext for partial navigation updates
|
|
7
|
+
* 3. Caches its rendered content in a ref across navigations
|
|
8
|
+
*
|
|
9
|
+
* On full navigation: receives new children via props, caches and renders them.
|
|
10
|
+
* On partial navigation (this segment skipped): the context map has no entry
|
|
11
|
+
* for this path, so the outlet returns cached content — preserving layout state.
|
|
12
|
+
* On partial navigation (this segment updated): the context map has content
|
|
13
|
+
* for this path, so the outlet renders the update.
|
|
14
|
+
*
|
|
15
|
+
* Uses React context instead of useSyncExternalStore to stay compatible
|
|
16
|
+
* with concurrent rendering (transitions). All outlets re-render when the
|
|
17
|
+
* context value changes, but each bails out quickly if its segment has
|
|
18
|
+
* no update — same approach as Next.js LayoutRouter.
|
|
19
|
+
*
|
|
20
|
+
* Security: performance optimization only. The server always runs all
|
|
21
|
+
* access.ts files regardless of segment skipping.
|
|
22
|
+
* See design/13-security.md §"State tree manipulation".
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
'use client';
|
|
26
|
+
|
|
27
|
+
import { useContext, useRef, type ReactNode } from 'react';
|
|
28
|
+
import { SegmentUpdateContext } from './segment-update-context.js';
|
|
29
|
+
|
|
30
|
+
export interface SegmentOutletProps {
|
|
31
|
+
/**
|
|
32
|
+
* Unique identifier for this segment. For normal segments this is the
|
|
33
|
+
* urlPath (e.g., "/", "/dashboard"). For route groups this includes the
|
|
34
|
+
* group name (e.g., "/(marketing)") to distinguish siblings that share
|
|
35
|
+
* the same urlPath. Must match the segmentId used in state-tree-diff.ts.
|
|
36
|
+
*/
|
|
37
|
+
segmentPath: string;
|
|
38
|
+
|
|
39
|
+
/** The segment's React subtree (layout + inner content). */
|
|
40
|
+
children: ReactNode;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Client component boundary at each layout segment in the element tree.
|
|
45
|
+
*
|
|
46
|
+
* On full navigation (context map is empty): renders children, caches in ref.
|
|
47
|
+
* On partial navigation: checks the context map for an update at segmentPath.
|
|
48
|
+
* - Update found → renders update, caches in ref.
|
|
49
|
+
* - No update → returns cached content (layout state preserved).
|
|
50
|
+
*
|
|
51
|
+
* React preserves component instances across reactRoot.render() calls
|
|
52
|
+
* when the same type appears at the same tree position. The ref persists
|
|
53
|
+
* across navigations because SegmentOutlet is reconciled, not remounted.
|
|
54
|
+
*/
|
|
55
|
+
export function SegmentOutlet({ segmentPath, children }: SegmentOutletProps) {
|
|
56
|
+
const updates = useContext(SegmentUpdateContext);
|
|
57
|
+
const contentRef = useRef<ReactNode>(null);
|
|
58
|
+
|
|
59
|
+
const update = updates.get(segmentPath);
|
|
60
|
+
|
|
61
|
+
if (update !== undefined) {
|
|
62
|
+
contentRef.current = update;
|
|
63
|
+
return update;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (contentRef.current === null) {
|
|
67
|
+
contentRef.current = children;
|
|
68
|
+
return children;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (children !== contentRef.current) {
|
|
72
|
+
contentRef.current = children;
|
|
73
|
+
return children;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return contentRef.current;
|
|
77
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SegmentUpdateContext — React context for partial navigation updates.
|
|
3
|
+
*
|
|
4
|
+
* During partial navigation (server skips unchanged sync layouts), the
|
|
5
|
+
* router builds a Map of segment path → ReactNode updates and passes it
|
|
6
|
+
* as the context value. Mounted SegmentOutlet components read from this
|
|
7
|
+
* context to decide whether to render the update or their cached content.
|
|
8
|
+
*
|
|
9
|
+
* SINGLETON GUARANTEE: Uses globalThis + Symbol.for — same pattern as
|
|
10
|
+
* NavigationContext. The RSC client bundler can duplicate this module
|
|
11
|
+
* across chunks (browser-entry graph + client-reference graph). With
|
|
12
|
+
* ESM output, each chunk gets its own module scope — a bare createContext
|
|
13
|
+
* at module level would create separate instances per chunk. globalThis
|
|
14
|
+
* guarantees a single instance regardless of duplication.
|
|
15
|
+
*
|
|
16
|
+
* See design/19-client-navigation.md §"Singleton Guarantee via globalThis"
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
'use client';
|
|
20
|
+
|
|
21
|
+
import React, { type ReactNode } from 'react';
|
|
22
|
+
|
|
23
|
+
export const EMPTY_SEGMENT_UPDATES = new Map<string, ReactNode>();
|
|
24
|
+
|
|
25
|
+
const CTX_KEY = Symbol.for('__timber_segment_update_ctx');
|
|
26
|
+
|
|
27
|
+
function getOrCreateContext(): React.Context<Map<string, ReactNode>> {
|
|
28
|
+
const existing = (globalThis as Record<symbol, unknown>)[CTX_KEY] as
|
|
29
|
+
| React.Context<Map<string, ReactNode>>
|
|
30
|
+
| undefined;
|
|
31
|
+
if (existing !== undefined) return existing;
|
|
32
|
+
if (typeof React.createContext === 'function') {
|
|
33
|
+
const ctx = React.createContext<Map<string, ReactNode>>(EMPTY_SEGMENT_UPDATES);
|
|
34
|
+
(globalThis as Record<symbol, unknown>)[CTX_KEY] = ctx;
|
|
35
|
+
return ctx;
|
|
36
|
+
}
|
|
37
|
+
// RSC environment — createContext not available. Return a dummy that
|
|
38
|
+
// won't be used (outlets only render on the client).
|
|
39
|
+
return undefined as unknown as React.Context<Map<string, ReactNode>>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const SegmentUpdateContext = getOrCreateContext();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shallow URL replacement — update the browser URL bar without triggering
|
|
3
|
+
* RSC navigation, TopLoader, or any server round-trip.
|
|
4
|
+
*
|
|
5
|
+
* Uses the Navigation API's `info: { shallow: true }` when available (Chrome),
|
|
6
|
+
* which the navigate event handler intercepts with a no-op handler. Falls back
|
|
7
|
+
* to raw `history.replaceState` (Safari/Firefox — no navigate event fired).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getNavigationApi } from './navigation-api.js';
|
|
11
|
+
|
|
12
|
+
export function replaceUrl(url: string): void {
|
|
13
|
+
const nav = getNavigationApi();
|
|
14
|
+
if (nav) {
|
|
15
|
+
nav.navigate(url, {
|
|
16
|
+
history: 'replace',
|
|
17
|
+
info: { shallow: true },
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
history.replaceState(history.state, '', url);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlotContext — delivers live slot content to SlotOutlet holes inside
|
|
3
|
+
* cached component shells (TIM-1173).
|
|
4
|
+
*
|
|
5
|
+
* A `cache.component(Fn, { slots: [...] })` shell is captured with a
|
|
6
|
+
* stable <SlotOutlet slot={name} /> client reference in place of each
|
|
7
|
+
* declared slot prop. At request time the revived shell is wrapped in a
|
|
8
|
+
* SlotsProvider carrying the live slot values; each outlet reads its
|
|
9
|
+
* value from this context by name.
|
|
10
|
+
*
|
|
11
|
+
* The value is a per-instance record — the NEAREST provider wins, so two
|
|
12
|
+
* instances of the same cached component on one page each resolve their
|
|
13
|
+
* own children, and a slot component nested inside another slot
|
|
14
|
+
* component's children reads its own provider, not the outer one.
|
|
15
|
+
*
|
|
16
|
+
* Generalizes the ChildSegmentContext pattern (TIM-1181) from a single
|
|
17
|
+
* implicit `children` hole on layouts to explicitly declared, named slot
|
|
18
|
+
* props on any cached component.
|
|
19
|
+
*
|
|
20
|
+
* SINGLETON GUARANTEE: globalThis + Symbol.for — the RSC client bundler
|
|
21
|
+
* can duplicate this module across chunks; globalThis guarantees a single
|
|
22
|
+
* context instance. Same pattern as ChildSegmentContext.
|
|
23
|
+
*
|
|
24
|
+
* See design/45-cache-lifetimes.md §Slot Components.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
'use client';
|
|
28
|
+
|
|
29
|
+
import React, { type ReactNode } from 'react';
|
|
30
|
+
|
|
31
|
+
export type SlotValues = Record<string, ReactNode>;
|
|
32
|
+
|
|
33
|
+
const CTX_KEY = Symbol.for('__timber_slot_ctx');
|
|
34
|
+
|
|
35
|
+
function getOrCreateContext(): React.Context<SlotValues | null> {
|
|
36
|
+
const existing = (globalThis as Record<symbol, unknown>)[CTX_KEY] as
|
|
37
|
+
| React.Context<SlotValues | null>
|
|
38
|
+
| undefined;
|
|
39
|
+
if (existing !== undefined) return existing;
|
|
40
|
+
if (typeof React.createContext === 'function') {
|
|
41
|
+
const ctx = React.createContext<SlotValues | null>(null);
|
|
42
|
+
(globalThis as Record<symbol, unknown>)[CTX_KEY] = ctx;
|
|
43
|
+
return ctx;
|
|
44
|
+
}
|
|
45
|
+
return undefined as unknown as React.Context<SlotValues | null>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const SlotContext = getOrCreateContext();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlotOutlet — the hole in a cached component shell (TIM-1173).
|
|
3
|
+
*
|
|
4
|
+
* At capture time the prebuilt runtime renders the wrapped component with
|
|
5
|
+
* <SlotOutlet slot={name} /> in place of each declared slot prop. Being a
|
|
6
|
+
* client component, it serializes into the flight payload as a stable,
|
|
7
|
+
* deterministic client reference — the same bytes regardless of what live
|
|
8
|
+
* content will fill the hole. At request time the revived shell sits under
|
|
9
|
+
* a SlotsProvider and each outlet reads its live value from SlotContext.
|
|
10
|
+
*
|
|
11
|
+
* See design/45-cache-lifetimes.md §Slot Components.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
15
|
+
|
|
16
|
+
import { useContext } from 'react';
|
|
17
|
+
import { SlotContext } from './slot-context.js';
|
|
18
|
+
|
|
19
|
+
export function SlotOutlet({ slot }: { slot: string }) {
|
|
20
|
+
const values = useContext(SlotContext);
|
|
21
|
+
return values ? (values[slot] ?? null) : null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SlotsProvider — wraps a revived cached shell to supply live slot content
|
|
3
|
+
* to the SlotOutlet holes inside it (TIM-1173).
|
|
4
|
+
*
|
|
5
|
+
* Tree structure per cached-component instance:
|
|
6
|
+
* SlotsProvider(values={children: <Live />})
|
|
7
|
+
* └── revived shell
|
|
8
|
+
* └── SlotOutlet(slot="children") → reads context → <Live />
|
|
9
|
+
*
|
|
10
|
+
* See design/45-cache-lifetimes.md §Slot Components.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use client';
|
|
14
|
+
|
|
15
|
+
import { createElement, type ReactNode } from 'react';
|
|
16
|
+
import { SlotContext, type SlotValues } from './slot-context.js';
|
|
17
|
+
|
|
18
|
+
interface SlotsProviderProps {
|
|
19
|
+
values: SlotValues;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function SlotsProvider({ values, children }: SlotsProviderProps) {
|
|
24
|
+
return createElement(SlotContext.Provider, { value: values }, children);
|
|
25
|
+
}
|