@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209
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/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
- package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
- package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
- package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
- package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
- package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
- package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
- package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
- package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
- package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
- package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
- package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
- package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
- package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
- package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
- package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
- package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
- package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
- package/dist/_chunks/{error-boundary-BndF-3Td.js → error-boundary-tA7kVfs4.js} +84 -104
- package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
- package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
- package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
- package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
- package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
- package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
- package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
- package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
- package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
- package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
- package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
- package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
- package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
- package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
- package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
- package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
- package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
- package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
- package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
- package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
- package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
- package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
- package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
- package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
- package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
- package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
- package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
- package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
- package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
- package/dist/_chunks/{status-page-marker-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
- package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
- package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
- package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +7 -7
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/canonicalize-module.d.ts +8 -0
- package/dist/adapters/canonicalize-module.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +2 -2
- package/dist/adapters/cloudflare.d.ts +30 -8
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -2
- package/dist/adapters/compress-module.d.ts +8 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +2 -3
- package/dist/adapters/fs-identity.d.ts.map +1 -1
- package/dist/adapters/nitro-presets.d.ts +0 -6
- package/dist/adapters/nitro-presets.d.ts.map +1 -1
- package/dist/adapters/nitro-preview.d.ts +43 -11
- package/dist/adapters/nitro-preview.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +1 -13
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +291 -176
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +105 -21
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +0 -0
- package/dist/analyze/crawl-entry.js +3 -3
- package/dist/analyze/graph-cache.d.ts.map +1 -1
- package/dist/analyze/graph-command.js +4 -4
- package/dist/cache/index.js +2 -2
- package/dist/cache/json-lossy-check.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli-check.d.ts +7 -37
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli-context.d.ts +54 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli.d.ts +9 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -24
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +19 -29
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +7 -7
- package/dist/client/browser-entry/post-hydration.d.ts +6 -9
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +6 -11
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +4 -3
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/error-reconstituter.d.ts +3 -9
- package/dist/client/error-reconstituter.d.ts.map +1 -1
- package/dist/client/history.d.ts +20 -11
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +3 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +95 -108
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +20 -7
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +3 -5
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +3 -2
- package/dist/client/react-root.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +3 -8
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +45 -39
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router-url.d.ts +24 -0
- package/dist/client/router-url.d.ts.map +1 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +44 -4
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +18 -64
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +2 -5
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +1 -1
- package/dist/config-types.d.ts +2 -1
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/dev-page-shell.d.ts +17 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
- package/dist/dev-tools/index.d.ts +1 -1
- package/dist/dev-tools/index.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts +17 -2
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +6 -27
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -373
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +26 -40
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +15 -2
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/post-build.d.ts +110 -0
- package/dist/plugins/post-build.d.ts.map +1 -0
- package/dist/plugins/prebuilt-capture.d.ts +11 -4
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/prebuilt.d.ts +17 -1
- package/dist/plugins/prebuilt.d.ts.map +1 -1
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/react-resolve.d.ts +49 -0
- package/dist/plugins/react-resolve.d.ts.map +1 -0
- package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
- package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +32 -9
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +0 -9
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/segment-codegen.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +5 -4
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +46 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +58 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/children-interception.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +2 -23
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +0 -9
- package/dist/server/csp-nonce.d.ts.map +1 -1
- package/dist/server/csrf.d.ts +27 -4
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +0 -1
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +2 -1
- package/dist/server/default-logger.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +12 -6
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -3
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +9 -2
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +4 -4
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +10 -3
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/internal.d.ts +1 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +961 -581
- package/dist/server/internal.js.map +1 -1
- package/dist/server/json-status-response.d.ts +34 -0
- package/dist/server/json-status-response.d.ts.map +1 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +11 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +95 -7
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +11 -0
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +11 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +23 -35
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-render.d.ts +25 -0
- package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-routes.d.ts +37 -0
- package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +79 -35
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/lifetime.d.ts +38 -0
- package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +7 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +6 -81
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/react-cache-bridge.d.ts +59 -0
- package/dist/server/react-cache-bridge.d.ts.map +1 -0
- package/dist/server/react-cache-scope.d.ts +49 -0
- package/dist/server/react-cache-scope.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +15 -0
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +9 -0
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +26 -5
- package/dist/server/request-context.d.ts.map +1 -1
- 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 +7 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +7 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +0 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +5 -15
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +5 -6
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-signals.d.ts +65 -0
- package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/signal-identity.d.ts +43 -0
- package/dist/server/signal-identity.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +4 -3
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +91 -53
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +8 -5
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +26 -40
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +1 -1
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +12 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +12 -16
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/version-skew.d.ts +3 -3
- package/dist/shared/csrf-reject.d.ts +16 -0
- package/dist/shared/csrf-reject.d.ts.map +1 -0
- package/dist/shared/error-digest.d.ts +28 -0
- package/dist/shared/error-digest.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +11 -10
- package/dist/shared/payload-root.d.ts.map +1 -1
- package/dist/shared/rsc-payload-path.d.ts +6 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -1
- package/dist/utils/write-file-atomic.d.ts +17 -0
- package/dist/utils/write-file-atomic.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +17 -14
- package/docs/api/32-api-cache.mdx +51 -23
- package/docs/api/34-api-config.mdx +34 -6
- package/docs/api/36-cli.mdx +11 -1
- package/docs/learn/03-fetching-data.mdx +17 -1
- package/docs/learn/04-access-control.mdx +1 -1
- package/docs/learn/10-caching.mdx +29 -11
- package/docs/learn/11-middleware.mdx +8 -2
- package/docs/learn/12-error-handling.mdx +6 -1
- package/package.json +7 -3
- package/src/adapters/build-output-helper.ts +55 -53
- package/src/adapters/canonicalize-module.ts +29 -0
- package/src/adapters/cloudflare.ts +105 -63
- package/src/adapters/compress-module.ts +16 -5
- package/src/adapters/fs-identity.ts +2 -3
- package/src/adapters/nitro-presets.ts +0 -15
- package/src/adapters/nitro-preview.ts +272 -136
- package/src/adapters/nitro.ts +119 -82
- package/src/adapters/shared.ts +23 -14
- package/src/adapters/types.ts +110 -21
- package/src/analyze/graph-cache.ts +3 -4
- package/src/cache/json-lossy-check.ts +3 -9
- package/src/cache/singleflight.ts +5 -2
- package/src/cache/sizeof.ts +3 -1
- package/src/cache/tag-aware-handler.ts +43 -26
- package/src/cli-check.ts +8 -98
- package/src/cli-context.ts +119 -0
- package/src/cli.ts +19 -28
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +26 -4
- package/src/client/browser-entry/hydrate.ts +53 -58
- package/src/client/browser-entry/index.ts +16 -27
- package/src/client/browser-entry/post-hydration.ts +6 -40
- package/src/client/browser-entry/router-init.ts +66 -84
- package/src/client/error-boundary.tsx +9 -41
- package/src/client/error-reconstituter.tsx +10 -5
- package/src/client/history.ts +35 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +41 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +96 -132
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +62 -21
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/segment-cache.ts +110 -11
- package/src/client/ssr-data.ts +19 -80
- package/src/client/state.ts +2 -9
- package/src/client/use-pathname.ts +1 -1
- package/src/config-types.ts +2 -1
- package/src/config-validation.ts +2 -1
- package/src/dev-tools/dev-page-shell.ts +18 -0
- package/src/dev-tools/index.ts +0 -2
- package/src/dev-tools/instrumentation.ts +50 -2
- package/src/dev-tools/overlay.ts +8 -238
- package/src/index.ts +26 -14
- package/src/plugin-context.ts +39 -40
- package/src/plugins/build-manifest.ts +4 -11
- package/src/plugins/build-report.ts +70 -70
- package/src/plugins/dev-server.ts +24 -44
- package/src/plugins/entries.ts +2 -1
- package/src/plugins/fonts.ts +35 -7
- package/src/plugins/post-build.ts +327 -0
- package/src/plugins/prebuilt-capture.ts +28 -32
- package/src/plugins/prebuilt.ts +54 -39
- package/src/plugins/prerender-sugar.ts +0 -4
- package/src/plugins/react-resolve.ts +149 -0
- package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
- package/src/plugins/shims.ts +1 -0
- package/src/plugins/static-build.ts +42 -74
- package/src/routing/codegen-write.ts +25 -3
- package/src/routing/segment-codegen.ts +3 -2
- package/src/rsc-runtime/vendor-types.d.ts +8 -0
- package/src/server/access-gate.tsx +2 -1
- package/src/server/action-client.ts +1 -1
- package/src/server/action-handler.ts +253 -110
- package/src/server/actions.ts +73 -25
- package/src/server/als-registry.ts +73 -5
- package/src/server/chain-url-parts.ts +1 -1
- package/src/server/children-interception.ts +2 -1
- package/src/server/cookie-context.ts +18 -48
- package/src/server/csp-nonce.ts +0 -12
- package/src/server/csrf.ts +140 -8
- package/src/server/debug.ts +0 -1
- package/src/server/default-logger.ts +2 -1
- package/src/server/deny-boundary.ts +25 -13
- package/src/server/deny-renderer.ts +30 -97
- package/src/server/error-boundary-wrapper.ts +7 -3
- package/src/server/fallback-error.ts +26 -11
- package/src/server/flight-scripts.ts +1 -1
- package/src/server/head-response.ts +4 -4
- package/src/server/html-injector-core.ts +2 -2
- package/src/server/html-injectors.ts +2 -4
- package/src/server/index.ts +0 -4
- package/src/server/instrumentation.ts +10 -3
- package/src/server/internal.ts +1 -6
- package/src/server/json-status-response.ts +105 -0
- package/src/server/logger.ts +39 -3
- package/src/server/param-coercion.ts +15 -12
- package/src/server/pipeline-helpers.ts +257 -12
- package/src/server/pipeline-interception.ts +133 -0
- package/src/server/pipeline-outcome.ts +103 -31
- package/src/server/pipeline-phases.ts +127 -237
- package/src/server/pipeline.ts +204 -207
- package/src/server/prebuilt/capture-render.ts +118 -0
- package/src/server/prebuilt/capture-routes.ts +104 -0
- package/src/server/prebuilt/capture-state.ts +155 -48
- package/src/server/prebuilt/lifetime.ts +151 -0
- package/src/server/prebuilt/slots.ts +14 -2
- package/src/server/prebuilt/synthetic-store.ts +3 -0
- package/src/server/prebuilt-builder.ts +30 -320
- package/src/server/prebuilt-runtime.ts +125 -129
- package/src/server/primitives.ts +8 -168
- package/src/server/react-cache-bridge.ts +124 -0
- package/src/server/react-cache-scope.ts +104 -0
- package/src/server/render-timeout.ts +20 -0
- package/src/server/render-utils.ts +11 -1
- package/src/server/request-context.ts +36 -9
- package/src/server/route-element-builder.ts +11 -6
- package/src/server/route-handler.ts +36 -23
- package/src/server/route-matcher.ts +15 -1
- package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
- package/src/server/rsc-entry/api-handler.ts +27 -103
- package/src/server/rsc-entry/deny-fallback.ts +93 -26
- package/src/server/rsc-entry/error-renderer.ts +39 -91
- package/src/server/rsc-entry/helpers.ts +2 -4
- package/src/server/rsc-entry/index.ts +64 -58
- package/src/server/rsc-entry/render-route.ts +15 -80
- package/src/server/rsc-entry/render-signals.ts +108 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
- package/src/server/rsc-entry/rsc-payload.ts +28 -61
- package/src/server/rsc-entry/rsc-stream.ts +113 -213
- package/src/server/rsc-entry/ssr-bridge.ts +2 -2
- package/src/server/rsc-entry/ssr-renderer.ts +182 -263
- package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
- package/src/server/signal-identity.ts +112 -0
- package/src/server/slot-resolver.ts +18 -18
- package/src/server/slot-subtree-contain.ts +2 -1
- package/src/server/ssr-bridge-types.ts +92 -56
- package/src/server/ssr-entry.ts +87 -111
- package/src/server/ssr-render.ts +55 -64
- package/src/server/ssr-wrappers.tsx +2 -2
- package/src/server/static-generator.ts +7 -42
- package/src/server/static-not-found.ts +3 -3
- package/src/server/stream-utils.ts +51 -0
- package/src/server/tracing.ts +58 -75
- package/src/server/types.ts +1 -1
- package/src/server/version-skew.ts +5 -5
- package/src/shared/csrf-reject.ts +15 -0
- package/src/shared/error-digest.ts +46 -0
- package/src/shared/payload-root.ts +11 -10
- package/src/shared/rsc-payload-path.ts +8 -1
- package/src/utils/write-file-atomic.ts +32 -0
- package/dist/_chunks/actions-jNrXdzgs.js +0 -346
- package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
- package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
- package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
- package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
- package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
- package/dist/_chunks/error-boundary-BndF-3Td.js.map +0 -1
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
- package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
- package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
- package/dist/_chunks/segment-context-D9_89u34.js +0 -34
- package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
- package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
- package/dist/_chunks/state-FippDgxN.js.map +0 -1
- package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +0 -1
- package/dist/client/types.d.ts +0 -14
- package/dist/client/types.d.ts.map +0 -1
- package/dist/plugins/adapter-build.d.ts +0 -38
- package/dist/plugins/adapter-build.d.ts.map +0 -1
- package/dist/server/asset-headers.d.ts +0 -32
- package/dist/server/asset-headers.d.ts.map +0 -1
- package/dist/server/dev-source-map.d.ts +0 -22
- package/dist/server/dev-source-map.d.ts.map +0 -1
- package/src/client/types.ts +0 -21
- package/src/server/asset-headers.ts +0 -59
- package/src/server/dev-source-map.ts +0 -31
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Signal identity — the brands framework signals carry, the predicates that
|
|
2
|
+
// recognise them, and SsrStreamError.
|
|
3
|
+
//
|
|
4
|
+
// No runtime imports (the one import is type-only), so any environment can
|
|
5
|
+
// load it. The SSR entry's import graph
|
|
6
|
+
// must not reach RSC request state (`request-context.ts` and friends, held
|
|
7
|
+
// to that by `tests/ssr-import-boundary.test.ts`), and the signal classes
|
|
8
|
+
// in primitives.ts sit beside `deny()` and `redirect()`, which read it. SSR
|
|
9
|
+
// code that has to recognise a signal (the logger skips them) imports the
|
|
10
|
+
// predicates from here; the classes stamp the brands exported here.
|
|
11
|
+
|
|
12
|
+
import type { DenySignal, RedirectSignal } from './primitives.ts';
|
|
13
|
+
|
|
14
|
+
// ─── Signal branding ────────────────────────────────────────────────────────
|
|
15
|
+
//
|
|
16
|
+
// Catch sites must NOT use `instanceof` on these classes. In dev, an HMR
|
|
17
|
+
// program reload clears the RSC module cache; a request that is mid-render
|
|
18
|
+
// still holds the catch sites from the old evaluation of primitives.ts while
|
|
19
|
+
// user code loaded after the reload throws from the new one. The two
|
|
20
|
+
// evaluations are distinct classes, so `instanceof` fails and a correct
|
|
21
|
+
// deny() falls through every catch site as an unhandled 500 (TIM-1499).
|
|
22
|
+
//
|
|
23
|
+
// Each class stamps a `Symbol.for` brand on its instances in the constructor.
|
|
24
|
+
// `Symbol.for` keys live in the realm-wide symbol registry, so every
|
|
25
|
+
// evaluation of these modules — and every module graph in the same process —
|
|
26
|
+
// agrees on the key. The `is*` predicates below check the brand and are the
|
|
27
|
+
// only supported way to detect a signal. The classes themselves are NOT
|
|
28
|
+
// anchored on globalThis: a re-evaluated module must hand out its own
|
|
29
|
+
// (possibly updated) class, not a stale one.
|
|
30
|
+
//
|
|
31
|
+
// See design/18-build-system.md §"Dev Mode: Signal Identity Across Program Reloads".
|
|
32
|
+
|
|
33
|
+
export const DENY_BRAND: unique symbol = Symbol.for('timber:signal.deny');
|
|
34
|
+
export const REDIRECT_BRAND: unique symbol = Symbol.for('timber:signal.redirect');
|
|
35
|
+
const SSR_STREAM_ERROR_BRAND: unique symbol = Symbol.for('timber:signal.ssr-stream-error');
|
|
36
|
+
|
|
37
|
+
function hasBrand(value: unknown, brand: symbol): boolean {
|
|
38
|
+
return typeof value === 'object' && value !== null && brand in value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** True for any `DenySignal`, regardless of which module evaluation created it. */
|
|
42
|
+
export function isDenySignal(error: unknown): error is DenySignal {
|
|
43
|
+
return hasBrand(error, DENY_BRAND);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** True for any `RedirectSignal`, regardless of which module evaluation created it. */
|
|
47
|
+
export function isRedirectSignal(error: unknown): error is RedirectSignal {
|
|
48
|
+
return hasBrand(error, REDIRECT_BRAND);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* True for any `SsrStreamError`. This one also crosses Vite environments:
|
|
53
|
+
* it is thrown in SSR and caught in RSC, which are separate module graphs in
|
|
54
|
+
* the same process — the brand is the only identity the two share.
|
|
55
|
+
*/
|
|
56
|
+
export function isSsrStreamError(error: unknown): error is SsrStreamError {
|
|
57
|
+
return hasBrand(error, SSR_STREAM_ERROR_BRAND);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns true if the error is a framework control-flow signal (RedirectSignal
|
|
62
|
+
* or DenySignal) rather than a genuine application error. Works both for direct
|
|
63
|
+
* instances (RSC-side) and deserialized digest errors (SSR cross-boundary).
|
|
64
|
+
*
|
|
65
|
+
* See also: isFrameworkSignalError() in client/browser-dev.ts (client-only).
|
|
66
|
+
*/
|
|
67
|
+
export function isControlFlowSignal(error: unknown): boolean {
|
|
68
|
+
if (isDenySignal(error) || isRedirectSignal(error)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (error && typeof error === 'object') {
|
|
72
|
+
const digest = (error as { digest?: unknown }).digest;
|
|
73
|
+
if (typeof digest === 'string') {
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(digest) as { type?: unknown } | null;
|
|
76
|
+
if (parsed && typeof parsed === 'object') {
|
|
77
|
+
return parsed.type === 'redirect' || parsed.type === 'deny';
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
// Not valid digest JSON
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ─── SsrStreamError ─────────────────────────────────────────────────────────
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Error thrown when SSR's renderToReadableStream fails due to an error
|
|
91
|
+
* in the decoded RSC stream (e.g., uncontained slot errors).
|
|
92
|
+
*
|
|
93
|
+
* The RSC entry checks for this error type in its catch block. A captured
|
|
94
|
+
* deny or redirect is rethrown to the pipeline first; with no captured
|
|
95
|
+
* signal, it renders the error page for the uncontained error.
|
|
96
|
+
*
|
|
97
|
+
* Not defined in ssr-entry.ts because ssr-entry.ts imports react-dom/server,
|
|
98
|
+
* which cannot be loaded in the RSC environment.
|
|
99
|
+
*
|
|
100
|
+
* Detect with `isSsrStreamError()` — it is thrown in the SSR environment and
|
|
101
|
+
* caught in RSC, so `instanceof` never matches. See "Signal branding" above.
|
|
102
|
+
*/
|
|
103
|
+
export class SsrStreamError extends Error {
|
|
104
|
+
readonly [SSR_STREAM_ERROR_BRAND] = true;
|
|
105
|
+
override readonly cause: unknown;
|
|
106
|
+
|
|
107
|
+
constructor(message: string, cause: unknown) {
|
|
108
|
+
super(message);
|
|
109
|
+
this.name = 'SsrStreamError';
|
|
110
|
+
this.cause = cause;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -22,10 +22,10 @@ import { SlotAccessGate } from './access-gate.tsx';
|
|
|
22
22
|
import { wrapSegmentWithErrorBoundaries } from './error-boundary-wrapper.ts';
|
|
23
23
|
import { isClientReference } from './utils/element-type.ts';
|
|
24
24
|
import { containSlotSubtree } from './slot-subtree-contain.ts';
|
|
25
|
-
import { loadModule } from './safe-load.ts';
|
|
25
|
+
import { loadModule, type ManifestLoader } from './safe-load.ts';
|
|
26
26
|
import type { InterceptionContext, RouteMatch } from './pipeline.ts';
|
|
27
|
-
import { isDenySignal, isRedirectSignal } from './
|
|
28
|
-
import {
|
|
27
|
+
import { isDenySignal, isRedirectSignal } from './signal-identity.ts';
|
|
28
|
+
import { loadFallbackModule, reportRenderError } from './pipeline-helpers.ts';
|
|
29
29
|
import type { ManifestSegmentNode } from './route-matcher.ts';
|
|
30
30
|
import { setSlotParams, runWithSlotSegmentParams } from './request-context.ts';
|
|
31
31
|
import { coerceSlotParams } from './param-coercion.ts';
|
|
@@ -87,6 +87,7 @@ export async function resolveSlotElement(
|
|
|
87
87
|
slotNode: ManifestSegmentNode,
|
|
88
88
|
match: RouteMatch,
|
|
89
89
|
h: CreateElementFn,
|
|
90
|
+
req: Request,
|
|
90
91
|
interception?: InterceptionContext,
|
|
91
92
|
parentTreePath?: string
|
|
92
93
|
): Promise<React.ReactElement | null> {
|
|
@@ -167,13 +168,10 @@ export async function resolveSlotElement(
|
|
|
167
168
|
if (isDenySignal(error)) {
|
|
168
169
|
return denyFallback;
|
|
169
170
|
}
|
|
170
|
-
//
|
|
171
|
+
// Report the error but don't re-throw — returning fallback ensures
|
|
171
172
|
// the Flight row is resolved and the page hydrates correctly.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
path: '',
|
|
175
|
-
error,
|
|
176
|
-
});
|
|
173
|
+
// Nothing downstream sees it, so this is its one report.
|
|
174
|
+
reportRenderError(error, req, { segments: match.segments });
|
|
177
175
|
return denyFallback;
|
|
178
176
|
}
|
|
179
177
|
};
|
|
@@ -188,6 +186,7 @@ export async function resolveSlotElement(
|
|
|
188
186
|
slotMatch.chain,
|
|
189
187
|
element,
|
|
190
188
|
h,
|
|
189
|
+
req,
|
|
191
190
|
scope,
|
|
192
191
|
denyFallback
|
|
193
192
|
);
|
|
@@ -210,7 +209,7 @@ export async function resolveSlotElement(
|
|
|
210
209
|
// status page must not set the document status or empty the main
|
|
211
210
|
// route's segment cache.
|
|
212
211
|
element = await wrapSegmentWithErrorBoundaries(slotNode, element, {
|
|
213
|
-
loadModule,
|
|
212
|
+
loadModule: (file: ManifestLoader) => loadFallbackModule(file, req, match.segments),
|
|
214
213
|
createElement: h,
|
|
215
214
|
errorBoundaryComponent: TimberErrorBoundary,
|
|
216
215
|
isSlotBoundary: true,
|
|
@@ -289,13 +288,14 @@ async function wrapWithIntermediateSegments(
|
|
|
289
288
|
chain: ManifestSegmentNode[],
|
|
290
289
|
element: React.ReactElement,
|
|
291
290
|
h: CreateElementFn,
|
|
291
|
+
req: Request,
|
|
292
292
|
scope?: SlotParamScope,
|
|
293
293
|
denyFallback?: React.ReactNode
|
|
294
294
|
): Promise<React.ReactElement> {
|
|
295
295
|
for (let i = chain.length - 1; i > 0; i--) {
|
|
296
296
|
const seg = chain[i];
|
|
297
297
|
element = await wrapSegmentWithErrorBoundaries(seg, element, {
|
|
298
|
-
loadModule,
|
|
298
|
+
loadModule: (file: ManifestLoader) => loadFallbackModule(file, req),
|
|
299
299
|
createElement: h,
|
|
300
300
|
errorBoundaryComponent: TimberErrorBoundary,
|
|
301
301
|
isSlotBoundary: true,
|
|
@@ -483,10 +483,8 @@ function findSlotMatch(slotNode: ManifestSegmentNode, match: RouteMatch): SlotMa
|
|
|
483
483
|
const remainingSegments = parentIndex >= 0 ? segments.slice(parentIndex + 1) : [];
|
|
484
484
|
|
|
485
485
|
// Extract raw URL parts from the remaining main-route segments.
|
|
486
|
-
//
|
|
487
|
-
|
|
488
|
-
const rawParams = match.rawSegmentParams ?? match.segmentParams ?? {};
|
|
489
|
-
const urlParts = extractUrlParts(remainingSegments, rawParams);
|
|
486
|
+
// Raw (pre-coercion) params: actual URL strings, not codec-transformed values.
|
|
487
|
+
const urlParts = extractUrlParts(remainingSegments, match.rawSegmentParams);
|
|
490
488
|
|
|
491
489
|
// Match URL parts against the slot's segment tree using the shared walker.
|
|
492
490
|
// Handles zero parts (slot's own page), catch-all, optional-catch-all,
|
|
@@ -674,7 +672,8 @@ interface ResolveSlotPropsArgs {
|
|
|
674
672
|
h: CreateElementFn;
|
|
675
673
|
interception?: InterceptionContext;
|
|
676
674
|
parentTreePath: string;
|
|
677
|
-
|
|
675
|
+
/** The request being rendered. Its URL is the slot-matching destination. */
|
|
676
|
+
req: Request;
|
|
678
677
|
clientStateTree: ClientStateTree | null;
|
|
679
678
|
slotSkipInfo: SlotSkipEntry[];
|
|
680
679
|
}
|
|
@@ -699,7 +698,7 @@ export async function resolveSlotProps({
|
|
|
699
698
|
h,
|
|
700
699
|
interception,
|
|
701
700
|
parentTreePath,
|
|
702
|
-
|
|
701
|
+
req,
|
|
703
702
|
clientStateTree,
|
|
704
703
|
slotSkipInfo,
|
|
705
704
|
}: ResolveSlotPropsArgs): Promise<Record<string, unknown>> {
|
|
@@ -707,7 +706,7 @@ export async function resolveSlotProps({
|
|
|
707
706
|
const slotEntries = Object.entries(segment.slots ?? {});
|
|
708
707
|
if (slotEntries.length === 0) return slotProps;
|
|
709
708
|
|
|
710
|
-
const destinationParts = slotUrlParts(segment, match,
|
|
709
|
+
const destinationParts = slotUrlParts(segment, match, req.url);
|
|
711
710
|
const clientSlotKeys = clientStateTree?.slots ?? null;
|
|
712
711
|
|
|
713
712
|
// Owner URL parts — the URL values consumed through this segment.
|
|
@@ -770,6 +769,7 @@ export async function resolveSlotProps({
|
|
|
770
769
|
slotManifest,
|
|
771
770
|
match,
|
|
772
771
|
h,
|
|
772
|
+
req,
|
|
773
773
|
interception,
|
|
774
774
|
parentTreePath
|
|
775
775
|
);
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
|
|
41
41
|
import { createElement, type ElementType, type ReactElement, type ReactNode } from 'react';
|
|
42
42
|
|
|
43
|
-
import {
|
|
43
|
+
import { DenySignal } from './primitives.ts';
|
|
44
|
+
import { isDenySignal } from './signal-identity.ts';
|
|
44
45
|
import { isClientReference } from './utils/element-type.ts';
|
|
45
46
|
|
|
46
47
|
// React 19 elements; the legacy tag is accepted so a stray pre-19 element in
|
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RSC ↔ SSR Bridge Contract
|
|
3
3
|
*
|
|
4
|
-
* This file defines
|
|
5
|
-
*
|
|
4
|
+
* This file defines what crosses the RSC ↔ SSR environment boundary: the
|
|
5
|
+
* `NavContext` input and the `SsrRenderResult` output. The RSC
|
|
6
|
+
* environment calls `handleSsr(rscStream, navContext)`
|
|
6
7
|
* in the SSR environment via `import.meta.viteRsc.import(...)` (see
|
|
7
8
|
* `rsc-entry/ssr-bridge.ts`). RSC and SSR are separate Vite module graphs
|
|
8
9
|
* with separate module instances, so every per-request field that SSR
|
|
9
10
|
* needs must be declared here and passed explicitly.
|
|
10
11
|
*
|
|
12
|
+
* The ALS stores are the exception to "separate instances": `als-registry.ts`
|
|
13
|
+
* anchors them on `globalThis`, and SSR runs inside the RSC request's
|
|
14
|
+
* async context, so an SSR module that imported `request-context.ts` would
|
|
15
|
+
* read live RSC state. The framework's SSR code must not — that is the
|
|
16
|
+
* coupling this contract removes — and `tests/ssr-import-boundary.test.ts`
|
|
17
|
+
* holds the SSR entry's import graph to it (its allowlist names the one
|
|
18
|
+
* registry reader permitted). User `'use client'` code rendered in SSR can
|
|
19
|
+
* still reach request state through public APIs (`redirect()`, a
|
|
20
|
+
* `defineCookie()` cookie's `get()`); that test does not cover them.
|
|
21
|
+
*
|
|
11
22
|
* Rules for changes to this file:
|
|
12
23
|
*
|
|
13
24
|
* 1. **Structurally serializable shape.** Fields must be values that can
|
|
14
25
|
* cross the environment boundary as plain data or as platform-neutral
|
|
15
26
|
* primitives (`Headers`, `ReadableStream`, `AbortSignal`, `Map`). Do
|
|
16
27
|
* not add closures, class instances tied to RSC-only modules, or
|
|
17
|
-
* anything whose identity must be preserved across the bridge.
|
|
28
|
+
* anything whose identity must be preserved across the bridge. The one
|
|
29
|
+
* sanctioned exception is `NavContext.getHeadSegmentScript`.
|
|
30
|
+
*
|
|
31
|
+
* 1a. **Directional.** `NavContext` is input. Anything SSR produces for
|
|
32
|
+
* RSC is returned in `SsrRenderResult`, not written back onto the
|
|
33
|
+
* context. SSR never writes to a `NavContext` or through one. That
|
|
34
|
+
* includes `responseHeaders`: it is the pipeline's bag, passed by
|
|
35
|
+
* reference, and SSR copies it before adding response-local headers.
|
|
36
|
+
* RSC-side code may still write the bag after `handleSsr()` returns
|
|
37
|
+
* (a promoted redirect's `Location`, for one); that is the pipeline
|
|
38
|
+
* using its own bag, not a return channel.
|
|
18
39
|
*
|
|
19
40
|
* 2. **No runtime imports of RSC-only modules.** This file is read by
|
|
20
41
|
* both environments at type-check time. Keep it type-only. Importing
|
|
@@ -29,9 +50,6 @@
|
|
|
29
50
|
* and `CLAUDE.md` §"RSC and SSR Are Separate Vite Environments".
|
|
30
51
|
*/
|
|
31
52
|
|
|
32
|
-
import type { CoercedParams } from '../shared/param-value.ts';
|
|
33
|
-
import type { SlotParamsRecord } from '../shared/slot-params.ts';
|
|
34
|
-
|
|
35
53
|
/**
|
|
36
54
|
* Navigation context passed from the RSC environment to SSR.
|
|
37
55
|
*
|
|
@@ -53,14 +71,6 @@ export interface NavContext {
|
|
|
53
71
|
* reintroduce one beside this field (TIM-1428).
|
|
54
72
|
*/
|
|
55
73
|
search: string;
|
|
56
|
-
/** Extracted route segment params. Post-coercion, values may be non-string (TIM-1347). */
|
|
57
|
-
segmentParams: CoercedParams;
|
|
58
|
-
/**
|
|
59
|
-
* Per-slot segment params, keyed by slot tree path. Absent when the request
|
|
60
|
-
* rendered no slot with params of its own. Feeds `useSegmentParams(path)`
|
|
61
|
-
* during SSR and, via `__timber_slot_params`, after hydration (TIM-1285).
|
|
62
|
-
*/
|
|
63
|
-
slotParams?: SlotParamsRecord;
|
|
64
74
|
/** The committed HTTP status code */
|
|
65
75
|
statusCode: number;
|
|
66
76
|
/** Response headers from middleware/proxy */
|
|
@@ -102,39 +112,16 @@ export interface NavContext {
|
|
|
102
112
|
*
|
|
103
113
|
* Undefined when client JS is disabled (no client to consume it).
|
|
104
114
|
* See TIM-1365, TIM-1359.
|
|
105
|
-
*/
|
|
106
|
-
getHeadSegmentScript?: () => string;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Mutable flag: set by TimberErrorBoundary during SSR when it catches
|
|
110
|
-
* a DenySignal (via digest). This tells the RSC entry that the denial
|
|
111
|
-
* was contained by a slot error boundary and should NOT be promoted
|
|
112
|
-
* to a page-level deny. See LOCAL-298.
|
|
113
|
-
*/
|
|
114
|
-
_denyHandledByBoundary?: boolean;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Mutable: SSR timing data populated by handleSsr().
|
|
118
|
-
* Read by the RSC entry to record sub-phase Server-Timing entries
|
|
119
|
-
* when `serverTiming: 'detailed'` is configured.
|
|
120
115
|
*
|
|
121
|
-
* This
|
|
122
|
-
*
|
|
116
|
+
* This is the bridge's one sanctioned exception to rule 1 (no closures).
|
|
117
|
+
* SSR must not import the RSC request state that holds the
|
|
118
|
+
* denied-segment index (tests/ssr-import-boundary.test.ts), and evaluating
|
|
119
|
+
* it eagerly, before AccessGates settle, would serialize a
|
|
120
|
+
* non-authoritative index. See
|
|
121
|
+
* design/49-explicit-subsystem-boundaries.md §"Decision: the head-segment
|
|
122
|
+
* callback stays". Do not add a second one.
|
|
123
123
|
*/
|
|
124
|
-
|
|
125
|
-
/** Time to decode RSC stream (createFromReadableStream/createFromNodeStream) */
|
|
126
|
-
decodeMs: number;
|
|
127
|
-
/** Time for Fizz to render the shell (onShellReady) */
|
|
128
|
-
shellMs: number;
|
|
129
|
-
/** Time for pipe() to flush shell bytes to the output stream */
|
|
130
|
-
pipeMs: number;
|
|
131
|
-
/** Time to set up Node.js Transform pipeline / Web Stream transforms */
|
|
132
|
-
pipelineMs: number;
|
|
133
|
-
/** Total SSR time (decode → response ready) */
|
|
134
|
-
totalMs: number;
|
|
135
|
-
/** Whether the Node.js native stream path was used */
|
|
136
|
-
nodeStreams: boolean;
|
|
137
|
-
};
|
|
124
|
+
getHeadSegmentScript?: () => string;
|
|
138
125
|
|
|
139
126
|
/**
|
|
140
127
|
* Signal that fires when an unhandled RSC error is detected.
|
|
@@ -143,23 +130,72 @@ export interface NavContext {
|
|
|
143
130
|
* chunks from crashing the client's Flight decoder.
|
|
144
131
|
*/
|
|
145
132
|
_errorSignal?: AbortSignal;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* SSR sub-phase timings, recorded by `handleSsr()` and turned into
|
|
137
|
+
* `Server-Timing` entries by the RSC renderer when
|
|
138
|
+
* `serverTiming: 'detailed'` is configured.
|
|
139
|
+
*/
|
|
140
|
+
export interface SsrTimings {
|
|
141
|
+
/** Time to decode the RSC stream (createFromReadableStream/createFromNodeStream) */
|
|
142
|
+
decodeMs: number;
|
|
143
|
+
/** Time for Fizz to render the shell (onShellReady, plus any hold window) */
|
|
144
|
+
shellMs: number;
|
|
145
|
+
/** Time to set up the Node.js Transform pipeline / Web Stream transforms */
|
|
146
|
+
pipelineMs: number;
|
|
147
|
+
/** Total SSR time (decode → response ready) */
|
|
148
|
+
totalMs: number;
|
|
149
|
+
/** Whether the Node.js native stream path was used */
|
|
150
|
+
nodeStreams: boolean;
|
|
151
|
+
}
|
|
146
152
|
|
|
153
|
+
/**
|
|
154
|
+
* What `handleSsr()` returns to the RSC environment.
|
|
155
|
+
*
|
|
156
|
+
* Directional and terminal: every field is produced by the SSR entry and
|
|
157
|
+
* settled by the time `handleSsr()` resolves. Do not add request inputs
|
|
158
|
+
* (those belong on `NavContext`) or methods here.
|
|
159
|
+
*
|
|
160
|
+
* `response.status` is not an SSR decision. It echoes
|
|
161
|
+
* `NavContext.statusCode`, and response status has exactly two owners,
|
|
162
|
+
* both in the RSC environment:
|
|
163
|
+
*
|
|
164
|
+
* 1. the `statusCode` on the `NavContext` itself, seeded by whichever
|
|
165
|
+
* RSC-side renderer builds it before `callSsr()`: 200 from
|
|
166
|
+
* `rsc-entry/ssr-renderer.ts`, the deny status from `renderDenyPage()`,
|
|
167
|
+
* the error status from `rsc-entry/error-renderer.ts`; and
|
|
168
|
+
* 2. the post-`callSsr()` `getDenyStatus()` override in
|
|
169
|
+
* `rsc-entry/ssr-renderer.ts`, which rebuilds the `Response` with the
|
|
170
|
+
* status an in-tree `AccessGate`/`PageDenyBoundary` denial recorded
|
|
171
|
+
* in the RSC-side ALS (TIM-666).
|
|
172
|
+
*
|
|
173
|
+
* The override reads RSC state after SSR returns; it is not a write back
|
|
174
|
+
* across the bridge. No SSR-side code (error boundaries included) sets a
|
|
175
|
+
* status: Fizz never renders a class boundary's fallback on the document
|
|
176
|
+
* path (design/spike-TIM-1441-eliminate-second-pass.md F1/F2), so there
|
|
177
|
+
* is nothing in-tree to report. See design/49 §"A2".
|
|
178
|
+
*/
|
|
179
|
+
export interface SsrRenderResult {
|
|
180
|
+
/** The HTML document response, streaming the post-shell remainder. */
|
|
181
|
+
response: Response;
|
|
182
|
+
timings: SsrTimings;
|
|
147
183
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
184
|
+
* Whether Fizz's `stream.allReady` settled before the
|
|
185
|
+
* `deferSuspenseFor` hold ended.
|
|
150
186
|
*
|
|
151
|
-
* When true, the RSC
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* already been captured in `RenderSignals`.
|
|
187
|
+
* When true, the RSC renderer skips its signal-promotion microtask
|
|
188
|
+
* retry: Fizz allReady implies Flight closed its stream, which implies
|
|
189
|
+
* `onError` already fired for every rejected Flight task, so every
|
|
190
|
+
* DenySignal/RedirectSignal in the tree is already captured.
|
|
156
191
|
*
|
|
157
|
-
* When false
|
|
158
|
-
*
|
|
159
|
-
*
|
|
192
|
+
* When false (hold timed out, no hold window, shell-only return), there
|
|
193
|
+
* is no such guarantee and the renderer falls back to the bounded retry.
|
|
194
|
+
* Settled before `handleSsr()` resolves: `onFizzAllReadyResolved` fires
|
|
195
|
+
* synchronously just before the render-stream promise resolves.
|
|
160
196
|
*
|
|
161
197
|
* See design/05-streaming.md §"deferSuspenseFor and the Hold Window"
|
|
162
198
|
* and design/spike-signal-promotion-protocol.md (Option 1).
|
|
163
199
|
*/
|
|
164
|
-
|
|
200
|
+
fizzAllReadyResolved: boolean;
|
|
165
201
|
}
|