@timber-js/app 0.2.0-alpha.208 → 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-BrHmG-2X.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-CNbpUOPB.js → status-page-marker-gaihi0KZ.js} +53 -20
- 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 +12 -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 +68 -104
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +16 -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 +1 -6
- 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/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 +531 -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/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 +5 -1
- 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 +18 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +35 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +65 -128
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +43 -22
- package/src/client/rsc-fetch.ts +117 -155
- 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 +24 -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/{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-BrHmG-2X.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-CNbpUOPB.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
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* RSC Stream Renderer — Creates the RSC Flight stream with signal tracking.
|
|
3
3
|
*
|
|
4
4
|
* Wraps `renderToReadableStream` from `@vitejs/plugin-rsc/rsc` and captures
|
|
5
|
-
* render-phase signals (DenySignal, RedirectSignal
|
|
5
|
+
* render-phase signals (DenySignal, RedirectSignal) thrown by
|
|
6
6
|
* components during streaming. These signals are tracked in a shared
|
|
7
|
-
* `RenderSignals` object so the caller can decide the HTTP response.
|
|
7
|
+
* read-only `RenderSignals` object so the caller can decide the HTTP response.
|
|
8
8
|
*
|
|
9
9
|
* Design docs: 02-rendering-pipeline.md §"Single-Pass Rendering",
|
|
10
10
|
* 13-security.md §"Errors don't leak"
|
|
@@ -12,70 +12,22 @@
|
|
|
12
12
|
|
|
13
13
|
import { renderToReadableStream } from '../../rsc-runtime/rsc.ts';
|
|
14
14
|
import type { RscPayloadRoot } from '../../shared/payload-root.ts';
|
|
15
|
+
import { encodeErrorDigest } from '../../shared/error-digest.ts';
|
|
15
16
|
|
|
16
17
|
import { randomUUID } from 'node:crypto';
|
|
17
18
|
|
|
18
19
|
import { matchDenyEntries, type DenyPageEntry } from '../deny-boundary.ts';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
isDenySignal,
|
|
22
|
-
isRedirectSignal,
|
|
23
|
-
isRenderError,
|
|
24
|
-
DenySignal,
|
|
25
|
-
RedirectSignal,
|
|
26
|
-
RenderError,
|
|
27
|
-
} from '../primitives.ts';
|
|
20
|
+
import { reportRenderError } from '../pipeline-helpers.ts';
|
|
21
|
+
import { isDenySignal, isRedirectSignal } from '../signal-identity.ts';
|
|
28
22
|
import { checkAndWarnRscPropError } from '../rsc-prop-warnings.ts';
|
|
29
23
|
|
|
30
24
|
import { isAbortError } from './helpers.ts';
|
|
25
|
+
import { createSignalRecorder, type RenderSignals } from './render-signals.ts';
|
|
31
26
|
import { isDebug } from '../debug.ts';
|
|
32
27
|
import { isDevMode } from '../debug.ts';
|
|
33
28
|
|
|
34
|
-
/**
|
|
35
|
-
* Mutable signal state captured during RSC rendering.
|
|
36
|
-
*
|
|
37
|
-
* Signals fire asynchronously via `onError` during stream consumption.
|
|
38
|
-
* The first signal of each type wins — subsequent signals are ignored.
|
|
39
|
-
*
|
|
40
|
-
* `onSignal` is an optional callback fired when a DenySignal or
|
|
41
|
-
* RedirectSignal is captured. Consumers use it with Promise.race to
|
|
42
|
-
* react immediately instead of polling with setTimeout/queueMicrotask.
|
|
43
|
-
*/
|
|
44
|
-
export interface RenderSignals {
|
|
45
|
-
denySignal: DenySignal | null;
|
|
46
|
-
/**
|
|
47
|
-
* The first deny that no in-tree catch site could place — no `owners`, so
|
|
48
|
-
* no boundary may claim its error row and only the re-render fallback can
|
|
49
|
-
* produce a page for it.
|
|
50
|
-
*
|
|
51
|
-
* Tracked apart from `denySignal` because one render can produce both. A
|
|
52
|
-
* deep page can hoist a 404 to a boundary that will render it while an
|
|
53
|
-
* outer layout separately throws a 403 nothing matches; whichever lands in
|
|
54
|
-
* `denySignal` first, the unplaced one still needs the fallback, and
|
|
55
|
-
* deciding from `denySignal.owners` alone would strand it. See TIM-1356.
|
|
56
|
-
*/
|
|
57
|
-
unplacedDeny: DenySignal | null;
|
|
58
|
-
redirectSignal: RedirectSignal | null;
|
|
59
|
-
renderError: { error: unknown; status: number } | null;
|
|
60
|
-
/**
|
|
61
|
-
* The last unhandled error seen by RSC onError that isn't a signal.
|
|
62
|
-
* Used as a fallback when SSR fails (SsrStreamError) but no structured
|
|
63
|
-
* signal was captured — provides the original error for the error page
|
|
64
|
-
* instead of relying on SsrStreamError.cause extraction.
|
|
65
|
-
*
|
|
66
|
-
* NOT used for page-level error detection (that would break Suspense
|
|
67
|
-
* error isolation). Only consumed when SSR actually fails.
|
|
68
|
-
*/
|
|
69
|
-
lastUnhandledError: unknown | null;
|
|
70
|
-
/** Callback fired when a redirect or deny signal is captured in onError. */
|
|
71
|
-
onSignal?: () => void;
|
|
72
|
-
/** Callback fired when an unhandled error (non-signal) is captured. Used
|
|
73
|
-
* to halt Flight data injection into the inline stream. */
|
|
74
|
-
onUnhandledError?: () => void;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
29
|
export interface RscStreamResult {
|
|
78
|
-
rscStream: ReadableStream<Uint8Array
|
|
30
|
+
rscStream: ReadableStream<Uint8Array>;
|
|
79
31
|
signals: RenderSignals;
|
|
80
32
|
}
|
|
81
33
|
|
|
@@ -85,177 +37,125 @@ export interface RscStreamResult {
|
|
|
85
37
|
* The stream serializes server components as rendered output and client
|
|
86
38
|
* components ("use client") as serialized references with module ID + export name.
|
|
87
39
|
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
40
|
+
* Signals are captured in the returned `signals` object for the caller to
|
|
41
|
+
* handle. Every one arrives through `onError`, never as a throw from this
|
|
42
|
+
* call: Flight starts rendering in a microtask after the stream is created,
|
|
43
|
+
* so even a component that throws synchronously is reported asynchronously.
|
|
92
44
|
*/
|
|
93
45
|
export function renderRscStream(
|
|
94
46
|
payload: RscPayloadRoot,
|
|
95
47
|
req: Request,
|
|
96
48
|
leafDenyChain?: DenyPageEntry[]
|
|
97
49
|
): RscStreamResult {
|
|
98
|
-
const
|
|
99
|
-
denySignal: null,
|
|
100
|
-
unplacedDeny: null,
|
|
101
|
-
redirectSignal: null,
|
|
102
|
-
renderError: null,
|
|
103
|
-
lastUnhandledError: null,
|
|
104
|
-
};
|
|
50
|
+
const recorder = createSignalRecorder();
|
|
105
51
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const entries = matchDenyEntries(leafDenyChain, error.status);
|
|
125
|
-
if (entries.length > 0) {
|
|
126
|
-
error.owners = entries.map((e) => e.ownerKey);
|
|
127
|
-
}
|
|
52
|
+
const rscStream = renderToReadableStream(
|
|
53
|
+
payload,
|
|
54
|
+
{
|
|
55
|
+
signal: req.signal,
|
|
56
|
+
onError(error: unknown) {
|
|
57
|
+
// Connection abort (user refreshed or navigated away) — suppress.
|
|
58
|
+
// Not an application error; no need to track or log.
|
|
59
|
+
if (isAbortError(error) || req.signal?.aborted) return;
|
|
60
|
+
if (isDenySignal(error)) {
|
|
61
|
+
// Late addressing (TIM-1450): a nested-component deny escapes
|
|
62
|
+
// all in-tree catch sites and arrives here without owners.
|
|
63
|
+
// Resolve it against the leaf deny chain and stamp the full
|
|
64
|
+
// candidate list so the client can find the first reachable
|
|
65
|
+
// owner via its ancestry context.
|
|
66
|
+
if (!error.owners && leafDenyChain) {
|
|
67
|
+
const entries = matchDenyEntries(leafDenyChain, error.status);
|
|
68
|
+
if (entries.length > 0) {
|
|
69
|
+
error.owners = entries.map((e) => e.ownerKey);
|
|
128
70
|
}
|
|
129
|
-
// First-wins: two concurrent denies from separately serialized
|
|
130
|
-
// subtrees must commit a deterministic status. See
|
|
131
|
-
// spike-TIM-1441 §"two-concurrent-denials scenario".
|
|
132
|
-
signals.denySignal ??= error;
|
|
133
|
-
if (!error.owners) signals.unplacedDeny ??= error;
|
|
134
|
-
signals.onSignal?.();
|
|
135
|
-
return JSON.stringify({
|
|
136
|
-
type: 'deny',
|
|
137
|
-
status: error.status,
|
|
138
|
-
data: error.data,
|
|
139
|
-
owners: error.owners,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
if (isRedirectSignal(error)) {
|
|
143
|
-
signals.redirectSignal = error;
|
|
144
|
-
signals.onSignal?.();
|
|
145
|
-
return JSON.stringify({
|
|
146
|
-
type: 'redirect',
|
|
147
|
-
location: error.location,
|
|
148
|
-
status: error.status,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
if (isRenderError(error)) {
|
|
152
|
-
// Track the first render error for pre-flush handling
|
|
153
|
-
if (!signals.renderError) {
|
|
154
|
-
signals.renderError = { error, status: error.status };
|
|
155
|
-
}
|
|
156
|
-
logRenderError({ method: req.method, path: new URL(req.url).pathname, error });
|
|
157
|
-
return JSON.stringify({
|
|
158
|
-
type: 'render-error',
|
|
159
|
-
code: error.code,
|
|
160
|
-
data: error.digest.data,
|
|
161
|
-
status: error.status,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
// Dev diagnostic: detect "Invalid hook call" errors which indicate
|
|
165
|
-
// a 'use client' component is being executed during RSC rendering
|
|
166
|
-
// instead of being serialized as a client reference. This happens when
|
|
167
|
-
// the RSC plugin's transform doesn't detect the directive — e.g., the
|
|
168
|
-
// directive isn't at the very top of the file, or the component is
|
|
169
|
-
// re-exported through a barrel file without 'use client'.
|
|
170
|
-
// See LOCAL-297.
|
|
171
|
-
if (isDebug() && error instanceof Error && error.message.includes('Invalid hook call')) {
|
|
172
|
-
console.error(
|
|
173
|
-
'[timber] A React hook was called during RSC rendering. This usually means a ' +
|
|
174
|
-
"'use client' component is being executed as a server component instead of " +
|
|
175
|
-
'being serialized as a client reference.\n\n' +
|
|
176
|
-
'Common causes:\n' +
|
|
177
|
-
" 1. The 'use client' directive is not the FIRST statement in the file (before any imports)\n" +
|
|
178
|
-
" 2. The component is re-exported through a barrel file (index.ts) that lacks 'use client'\n" +
|
|
179
|
-
' 3. @vitejs/plugin-rsc is not loaded or is misconfigured\n\n' +
|
|
180
|
-
`Request: ${req.method} ${new URL(req.url).pathname}`
|
|
181
|
-
);
|
|
182
71
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Log the error but do NOT track it as a page-level render error.
|
|
192
|
-
// If this error is inside a <Suspense> boundary, React will emit
|
|
193
|
-
// an error row in the Flight stream and the Suspense fallback will
|
|
194
|
-
// render on the client. Tracking it as signals.renderError would
|
|
195
|
-
// cause the pipeline to treat the entire page as a 500, even though
|
|
196
|
-
// the shell rendered successfully. See TIM-524.
|
|
197
|
-
//
|
|
198
|
-
// Only track as renderError if no Suspense boundary contains it —
|
|
199
|
-
// React will call onShellError for truly unrecoverable errors.
|
|
200
|
-
|
|
201
|
-
// Track the last unhandled error so the pipeline can use it
|
|
202
|
-
// if SSR fails (SsrStreamError). This is NOT used for page-level
|
|
203
|
-
// error detection — only as a fallback when SSR actually fails.
|
|
204
|
-
signals.lastUnhandledError = error;
|
|
205
|
-
signals.onUnhandledError?.();
|
|
206
|
-
|
|
207
|
-
// Return a digest so React emits a per-row error in the Flight
|
|
208
|
-
// stream instead of leaving the lazy reference unresolved.
|
|
209
|
-
//
|
|
210
|
-
// SECURITY: Never include error.message in the digest — it may
|
|
211
|
-
// contain SQL queries, filesystem paths, secret fragments, or
|
|
212
|
-
// internal IDs. Use a generic message with a correlation ID so
|
|
213
|
-
// the error can be matched to server logs.
|
|
214
|
-
// See design/13-security.md §"Errors don't leak".
|
|
215
|
-
const errorId = randomUUID();
|
|
216
|
-
logRenderError({
|
|
217
|
-
method: req.method,
|
|
218
|
-
path: new URL(req.url).pathname,
|
|
219
|
-
error,
|
|
220
|
-
errorId,
|
|
72
|
+
recorder.deny(error);
|
|
73
|
+
return JSON.stringify({
|
|
74
|
+
type: 'deny',
|
|
75
|
+
status: error.status,
|
|
76
|
+
data: error.data,
|
|
77
|
+
owners: error.owners,
|
|
221
78
|
});
|
|
79
|
+
}
|
|
80
|
+
if (isRedirectSignal(error)) {
|
|
81
|
+
recorder.redirect(error);
|
|
222
82
|
return JSON.stringify({
|
|
223
|
-
type: '
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
? error.message
|
|
227
|
-
: String(error)
|
|
228
|
-
: 'An unexpected error occurred.',
|
|
229
|
-
errorId,
|
|
83
|
+
type: 'redirect',
|
|
84
|
+
location: error.location,
|
|
85
|
+
status: error.status,
|
|
230
86
|
});
|
|
231
|
-
}
|
|
87
|
+
}
|
|
88
|
+
// Dev diagnostic: detect "Invalid hook call" errors which indicate
|
|
89
|
+
// a 'use client' component is being executed during RSC rendering
|
|
90
|
+
// instead of being serialized as a client reference. This happens when
|
|
91
|
+
// the RSC plugin's transform doesn't detect the directive — e.g., the
|
|
92
|
+
// directive isn't at the very top of the file, or the component is
|
|
93
|
+
// re-exported through a barrel file without 'use client'.
|
|
94
|
+
// See LOCAL-297.
|
|
95
|
+
if (isDebug() && error instanceof Error && error.message.includes('Invalid hook call')) {
|
|
96
|
+
console.error(
|
|
97
|
+
'[timber] A React hook was called during RSC rendering. This usually means a ' +
|
|
98
|
+
"'use client' component is being executed as a server component instead of " +
|
|
99
|
+
'being serialized as a client reference.\n\n' +
|
|
100
|
+
'Common causes:\n' +
|
|
101
|
+
" 1. The 'use client' directive is not the FIRST statement in the file (before any imports)\n" +
|
|
102
|
+
" 2. The component is re-exported through a barrel file (index.ts) that lacks 'use client'\n" +
|
|
103
|
+
' 3. @vitejs/plugin-rsc is not loaded or is misconfigured\n\n' +
|
|
104
|
+
`Request: ${req.method} ${new URL(req.url).pathname}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Dev-mode: detect non-serializable RSC props and provide
|
|
109
|
+
// actionable fix suggestions (TIM-358).
|
|
110
|
+
// checkAndWarnRscPropError no-ops in production internally.
|
|
111
|
+
if (error instanceof Error) {
|
|
112
|
+
checkAndWarnRscPropError(error, new URL(req.url).pathname);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Log the error but do NOT track it as a page-level signal. If this
|
|
116
|
+
// error is inside a <Suspense> boundary, React will emit an error
|
|
117
|
+
// row in the Flight stream and the nearest error boundary renders
|
|
118
|
+
// it on the client; treating it as page-level would turn a page
|
|
119
|
+
// whose shell rendered into a 500. See TIM-524. An error no
|
|
120
|
+
// boundary contains fails SSR's shell instead, and the SSR renderer
|
|
121
|
+
// answers that with the error page.
|
|
122
|
+
recorder.unhandledError();
|
|
123
|
+
|
|
124
|
+
// Return a digest so React emits a per-row error in the Flight
|
|
125
|
+
// stream instead of leaving the lazy reference unresolved.
|
|
126
|
+
//
|
|
127
|
+
// SECURITY: Never include error.message in the digest — it may
|
|
128
|
+
// contain SQL queries, filesystem paths, secret fragments, or
|
|
129
|
+
// internal IDs. Use a generic message with a correlation ID so
|
|
130
|
+
// the error can be matched to server logs. The ID is the `digest`
|
|
131
|
+
// prop error pages receive (shared/error-digest.ts).
|
|
132
|
+
// See design/13-security.md §"Errors don't leak".
|
|
133
|
+
//
|
|
134
|
+
// This is the error's one log and one `onRequestError` report,
|
|
135
|
+
// whether a Suspense boundary contains it or it crashes the shell
|
|
136
|
+
// and the renderer answers with the error page (design/49
|
|
137
|
+
// §"Deferred: render-error handoff").
|
|
138
|
+
const errorId = randomUUID();
|
|
139
|
+
reportRenderError(error, req, { errorId });
|
|
140
|
+
return encodeErrorDigest({
|
|
141
|
+
message: isDevMode()
|
|
142
|
+
? error instanceof Error
|
|
143
|
+
? error.message
|
|
144
|
+
: String(error)
|
|
145
|
+
: 'An unexpected error occurred.',
|
|
146
|
+
errorId,
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
onClientReference(info: { id: string; name: string; deps: unknown }) {
|
|
152
|
+
// Client reference callback — invoked when a "use client"
|
|
153
|
+
// component is serialized into the RSC stream. Can be extended
|
|
154
|
+
// for CSS dep collection and Early Hints.
|
|
155
|
+
void info;
|
|
232
156
|
},
|
|
233
|
-
{
|
|
234
|
-
onClientReference(info: { id: string; name: string; deps: unknown }) {
|
|
235
|
-
// Client reference callback — invoked when a "use client"
|
|
236
|
-
// component is serialized into the RSC stream. Can be extended
|
|
237
|
-
// for CSS dep collection and Early Hints.
|
|
238
|
-
void info;
|
|
239
|
-
},
|
|
240
|
-
}
|
|
241
|
-
);
|
|
242
|
-
} catch (error) {
|
|
243
|
-
if (isDenySignal(error)) {
|
|
244
|
-
signals.denySignal ??= error;
|
|
245
|
-
if (!error.owners) signals.unplacedDeny ??= error;
|
|
246
|
-
} else if (isRedirectSignal(error)) {
|
|
247
|
-
signals.redirectSignal = error;
|
|
248
|
-
} else {
|
|
249
|
-
// Synchronous render error — component threw during
|
|
250
|
-
// renderToReadableStream creation. Capture instead of crashing
|
|
251
|
-
// the server; the error page will be rendered below.
|
|
252
|
-
signals.renderError = {
|
|
253
|
-
error,
|
|
254
|
-
status: isRenderError(error) ? error.status : 500,
|
|
255
|
-
};
|
|
256
|
-
logRenderError({ method: req.method, path: new URL(req.url).pathname, error });
|
|
257
157
|
}
|
|
258
|
-
|
|
158
|
+
);
|
|
259
159
|
|
|
260
|
-
return { rscStream, signals };
|
|
160
|
+
return { rscStream, signals: recorder.signals };
|
|
261
161
|
}
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
/// <reference types="@vitejs/plugin-rsc/types" />
|
|
10
10
|
|
|
11
|
-
import type { NavContext } from '../ssr-bridge-types.ts';
|
|
11
|
+
import type { NavContext, SsrRenderResult } from '../ssr-bridge-types.ts';
|
|
12
12
|
|
|
13
13
|
export async function callSsr(
|
|
14
14
|
rscStream: ReadableStream<Uint8Array>,
|
|
15
15
|
navContext: NavContext
|
|
16
|
-
): Promise<
|
|
16
|
+
): Promise<SsrRenderResult> {
|
|
17
17
|
let ssrEntry: typeof import('../ssr-entry.ts');
|
|
18
18
|
try {
|
|
19
19
|
ssrEntry = await import.meta.viteRsc.import<typeof import('../ssr-entry.ts')>(
|