@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
package/src/server/tracing.ts
CHANGED
|
@@ -32,7 +32,7 @@ export function getTraceId(): string {
|
|
|
32
32
|
'It can only be used in middleware, access checks, server components, and server actions.'
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
|
-
return store.traceId;
|
|
35
|
+
return store.request.traceId;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
@@ -57,31 +57,35 @@ export function generateTraceId(): string {
|
|
|
57
57
|
* per-request ALS scope.
|
|
58
58
|
*/
|
|
59
59
|
export function runWithTraceId<T>(id: string, fn: () => T): T {
|
|
60
|
-
return traceAls.run({ traceId: id }, fn);
|
|
60
|
+
return traceAls.run({ request: { traceId: id } }, fn);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Replace the trace ID
|
|
65
|
-
*
|
|
66
|
-
*
|
|
64
|
+
* Replace the request's trace ID. Used when OTEL creates the root span and
|
|
65
|
+
* we want to switch from the UUID fallback to the real OTEL trace ID. Writes
|
|
66
|
+
* the request's shared trace, so every scope in the request sees it —
|
|
67
|
+
* including the ones outside the span this runs in.
|
|
67
68
|
*/
|
|
68
|
-
export function replaceTraceId(newTraceId: string
|
|
69
|
+
export function replaceTraceId(newTraceId: string): void {
|
|
69
70
|
const store = traceAls.getStore();
|
|
70
71
|
if (store) {
|
|
71
|
-
store.traceId = newTraceId;
|
|
72
|
-
store.spanId = newSpanId;
|
|
72
|
+
store.request.traceId = newTraceId;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
77
|
+
* Run `fn` in a new trace scope for one span: the enclosing scope's request
|
|
78
|
+
* trace, with this span's pointers. A scope per span, not a save/restore on
|
|
79
|
+
* a shared store — spans overlap (MetadataCollector does not await
|
|
80
|
+
* `timber.metadata`), and a restore that runs after a sibling's would
|
|
81
|
+
* leave the sibling's pointer behind (TIM-1538).
|
|
79
82
|
*/
|
|
80
|
-
|
|
83
|
+
function runInSpanScope<T>(
|
|
84
|
+
pointers: Pick<TraceStore, 'spanId'> | Pick<TraceStore, 'platformSpan'>,
|
|
85
|
+
fn: () => T
|
|
86
|
+
): T {
|
|
81
87
|
const store = traceAls.getStore();
|
|
82
|
-
|
|
83
|
-
store.spanId = newSpanId;
|
|
84
|
-
}
|
|
88
|
+
return store ? traceAls.run({ ...store, ...pointers }, fn) : fn();
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
/**
|
|
@@ -113,7 +117,8 @@ const DEV_TRACING_INIT_KEY = Symbol.for('timber.dev.tracing-initialized');
|
|
|
113
117
|
* we create a BasicTracerProvider with our processor.
|
|
114
118
|
*
|
|
115
119
|
* Idempotent across module re-evaluations (HMR) — only the first call
|
|
116
|
-
* registers.
|
|
120
|
+
* registers. Called in dev, and in production only when TIMBER_DEBUG is
|
|
121
|
+
* set — otherwise production never loads the OTEL SDK.
|
|
117
122
|
*/
|
|
118
123
|
export async function initDevTracing(
|
|
119
124
|
config: import('../dev-tools/logger.ts').DevLoggerConfig
|
|
@@ -124,39 +129,17 @@ export async function initDevTracing(
|
|
|
124
129
|
const api = await getOtelApi();
|
|
125
130
|
if (!api) return;
|
|
126
131
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
let AsyncLocalStorageContextManager: typeof import('@opentelemetry/context-async-hooks').AsyncLocalStorageContextManager;
|
|
130
|
-
|
|
132
|
+
// Tracing is a diagnostic: any failure to load or construct the SDK
|
|
133
|
+
// disables it with a warning and never fails the server's boot (TIM-1554).
|
|
131
134
|
try {
|
|
132
|
-
|
|
133
|
-
(
|
|
134
|
-
({ AsyncLocalStorageContextManager } = await import('@opentelemetry/context-async-hooks'));
|
|
135
|
+
const { registerDevTracing } = await import('../dev-tools/instrumentation.ts');
|
|
136
|
+
registerDevTracing(config);
|
|
135
137
|
} catch (err) {
|
|
136
138
|
const msg = err instanceof Error ? err.message : String(err);
|
|
137
|
-
console.warn(`[timber] Dev tracing disabled — failed to
|
|
139
|
+
console.warn(`[timber] Dev tracing disabled — failed to set up OTEL:\n ${msg}`);
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
const processor = new DevSpanProcessor(config);
|
|
142
|
-
|
|
143
|
-
// Register a context manager so OTEL can propagate the active span
|
|
144
|
-
// across async boundaries. Without this, startActiveSpan can't make
|
|
145
|
-
// spans "active" — child spans get random trace IDs and getActiveSpan()
|
|
146
|
-
// returns undefined.
|
|
147
|
-
const contextManager = new AsyncLocalStorageContextManager();
|
|
148
|
-
contextManager.enable();
|
|
149
|
-
api.context.setGlobalContextManager(contextManager);
|
|
150
|
-
|
|
151
|
-
// Create a minimal TracerProvider with our DevSpanProcessor.
|
|
152
|
-
// If the user also configures an SDK in register(), their provider
|
|
153
|
-
// will coexist — the global provider set last wins for new tracers,
|
|
154
|
-
// but our processor captures all spans from the timber.js tracer.
|
|
155
|
-
const provider = new BasicTracerProvider({
|
|
156
|
-
spanProcessors: [processor],
|
|
157
|
-
});
|
|
158
|
-
api.trace.setGlobalTracerProvider(provider);
|
|
159
|
-
|
|
160
143
|
// Reset cached tracer so next getTracer() picks up the new provider
|
|
161
144
|
_tracer = undefined;
|
|
162
145
|
|
|
@@ -259,7 +242,8 @@ export async function getTracer(): Promise<import('@opentelemetry/api').Tracer |
|
|
|
259
242
|
*
|
|
260
243
|
* Automatically:
|
|
261
244
|
* - Creates the span as a child of the current context
|
|
262
|
-
* -
|
|
245
|
+
* - Runs fn in its own trace scope carrying the span's IDs, for log–trace
|
|
246
|
+
* correlation and setSpanAttribute()
|
|
263
247
|
* - Ends the span when the function completes
|
|
264
248
|
* - Records exceptions on error (OTEL channel)
|
|
265
249
|
*/
|
|
@@ -274,21 +258,13 @@ export async function withSpan<T>(
|
|
|
274
258
|
}
|
|
275
259
|
|
|
276
260
|
// Native platform span wraps the OTEL emission (dual emission). The
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
|
|
280
|
-
return platformTracer.enterSpan(name, async (span) => {
|
|
261
|
+
// span is tracked on its own trace scope so setSpanAttribute() can reach
|
|
262
|
+
// it after creation — the platform API has no getActiveSpan() equivalent.
|
|
263
|
+
return platformTracer.enterSpan(name, (span) => {
|
|
281
264
|
for (const key of Object.keys(attributes)) {
|
|
282
265
|
span.setAttribute(key, attributes[key]);
|
|
283
266
|
}
|
|
284
|
-
|
|
285
|
-
const prevPlatformSpan = store?.platformSpan;
|
|
286
|
-
if (store) store.platformSpan = span;
|
|
287
|
-
try {
|
|
288
|
-
return await runOtelSpan(name, attributes, fn);
|
|
289
|
-
} finally {
|
|
290
|
-
if (store) store.platformSpan = prevPlatformSpan;
|
|
291
|
-
}
|
|
267
|
+
return runInSpanScope({ platformSpan: span }, () => runOtelSpan(name, attributes, fn));
|
|
292
268
|
});
|
|
293
269
|
}
|
|
294
270
|
|
|
@@ -304,24 +280,30 @@ async function runOtelSpan<T>(
|
|
|
304
280
|
}
|
|
305
281
|
|
|
306
282
|
const api = (await getOtelApi())!;
|
|
307
|
-
return tracer.startActiveSpan(name, { attributes },
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
283
|
+
return tracer.startActiveSpan(name, { attributes }, (span) =>
|
|
284
|
+
runInSpanScope({ spanId: span.spanContext().spanId }, () => settleOtelSpan(api, span, fn))
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** Run `fn` and end `span` with its outcome. */
|
|
289
|
+
async function settleOtelSpan<T>(
|
|
290
|
+
api: typeof import('@opentelemetry/api'),
|
|
291
|
+
span: import('@opentelemetry/api').Span,
|
|
292
|
+
fn: () => T | Promise<T>
|
|
293
|
+
): Promise<T> {
|
|
294
|
+
try {
|
|
295
|
+
const result = await fn();
|
|
296
|
+
span.setStatus({ code: api.SpanStatusCode.OK });
|
|
297
|
+
return result;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
span.setStatus({ code: api.SpanStatusCode.ERROR });
|
|
300
|
+
if (error instanceof Error) {
|
|
301
|
+
span.recordException(error);
|
|
323
302
|
}
|
|
324
|
-
|
|
303
|
+
throw error;
|
|
304
|
+
} finally {
|
|
305
|
+
span.end();
|
|
306
|
+
}
|
|
325
307
|
}
|
|
326
308
|
|
|
327
309
|
/**
|
|
@@ -389,9 +371,10 @@ export function addSpanEventSync(
|
|
|
389
371
|
|
|
390
372
|
/**
|
|
391
373
|
* Try to extract the OTEL trace ID from the current active span context.
|
|
392
|
-
* Returns undefined if OTEL is not active or no span exists.
|
|
374
|
+
* Returns undefined if OTEL is not active or no span exists. (The span ID
|
|
375
|
+
* reaches logs through the span's own trace scope, not from here.)
|
|
393
376
|
*/
|
|
394
|
-
export async function getOtelTraceId(): Promise<
|
|
377
|
+
export async function getOtelTraceId(): Promise<string | undefined> {
|
|
395
378
|
const api = await getOtelApi();
|
|
396
379
|
if (!api) return undefined;
|
|
397
380
|
|
|
@@ -404,5 +387,5 @@ export async function getOtelTraceId(): Promise<{ traceId: string; spanId: strin
|
|
|
404
387
|
return undefined;
|
|
405
388
|
}
|
|
406
389
|
|
|
407
|
-
return
|
|
390
|
+
return ctx.traceId;
|
|
408
391
|
}
|
package/src/server/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { EarlyHint } from './early-hints.ts';
|
|
|
6
6
|
/**
|
|
7
7
|
* A value that is safe to pass through `JSON.stringify` without data loss.
|
|
8
8
|
*
|
|
9
|
-
* Used as the constraint for `deny(status,
|
|
9
|
+
* Used as the constraint for `deny(status, { dangerouslyPassData })` data
|
|
10
10
|
* because the post-flush path serializes via JSON.stringify, not React Flight.
|
|
11
11
|
* Types that survive Flight (Date, Map, Set, BigInt) would silently coerce or
|
|
12
12
|
* throw when serialized as JSON. This type prevents that at compile time.
|
|
@@ -32,15 +32,15 @@ export const RELOAD_HEADER = 'X-Timber-Reload';
|
|
|
32
32
|
// ─── Deployment ID ───────────────────────────────────────────────
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* The current build's deployment ID. Set at startup from the
|
|
36
|
-
*
|
|
35
|
+
* The current build's deployment ID. Set at startup from the runtime config
|
|
36
|
+
* (`virtual:timber-config`'s `deploymentId`). Null in dev mode.
|
|
37
37
|
*/
|
|
38
38
|
let currentDeploymentId: string | null = null;
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
* Set the current deployment ID. Called once at server startup
|
|
42
|
-
*
|
|
43
|
-
* checks are skipped).
|
|
41
|
+
* Set the current deployment ID. Called once at server startup by the RSC
|
|
42
|
+
* entry's `createRequestHandler()`. In dev mode this is never called
|
|
43
|
+
* (deployment ID checks are skipped).
|
|
44
44
|
*/
|
|
45
45
|
export function setDeploymentId(id: string): void {
|
|
46
46
|
currentDeploymentId = id;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Marker header on CSRF rejections.
|
|
3
|
+
*
|
|
4
|
+
* A CSRF rejection is a 403, the same status as an access-control denial.
|
|
5
|
+
* The server stamps this header on every CSRF 403 so callers — the browser
|
|
6
|
+
* action runtime, a same-origin `fetch` in user code, a curl session — can
|
|
7
|
+
* tell the two apart without parsing the body. A cross-origin `fetch` cannot
|
|
8
|
+
* read it: the rejection returns before proxy.ts, so no CORS headers are set
|
|
9
|
+
* and the browser reports a network error instead. Shared so the server writer and the client
|
|
10
|
+
* reader cannot drift.
|
|
11
|
+
*
|
|
12
|
+
* See design/08-forms-and-actions.md §"CSRF Protection" (TIM-1459).
|
|
13
|
+
*/
|
|
14
|
+
export const CSRF_REJECT_HEADER = 'X-Timber-Reject';
|
|
15
|
+
export const CSRF_REJECT_VALUE = 'csrf';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The digest an unhandled render error carries across Flight, and the
|
|
3
|
+
* correlation ID error pages read back out of it.
|
|
4
|
+
*
|
|
5
|
+
* Flight's `onError` (server/rsc-entry/rsc-stream.ts) returns this string for
|
|
6
|
+
* any error that is not a deny or redirect, and React sets it as `digest` on
|
|
7
|
+
* the Error it revives for that row, in SSR and on the client alike. The
|
|
8
|
+
* `errorId` is the one the server logged the error with, so an error page
|
|
9
|
+
* that shows it gives the reader something to quote that an operator can
|
|
10
|
+
* find. It is the `digest` prop every TSX error page receives.
|
|
11
|
+
*
|
|
12
|
+
* `message` is the real message only in dev; production sends a fixed string
|
|
13
|
+
* (design/13-security.md §"Errors don't leak").
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
interface ErrorRowDigest {
|
|
17
|
+
type: 'error';
|
|
18
|
+
message: string;
|
|
19
|
+
errorId: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function encodeErrorDigest(digest: Omit<ErrorRowDigest, 'type'>): string {
|
|
23
|
+
const row: ErrorRowDigest = { type: 'error', ...digest };
|
|
24
|
+
return JSON.stringify(row);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The correlation ID in an error's Flight digest, or `null` when the error
|
|
29
|
+
* carries none — a deny or redirect row, an error that never crossed Flight,
|
|
30
|
+
* or anything that is not an object.
|
|
31
|
+
*/
|
|
32
|
+
export function errorDigestId(error: unknown): string | null {
|
|
33
|
+
if (typeof error !== 'object' || error === null) return null;
|
|
34
|
+
const digest: unknown = Reflect.get(error, 'digest');
|
|
35
|
+
if (typeof digest !== 'string') return null;
|
|
36
|
+
let parsed: unknown;
|
|
37
|
+
try {
|
|
38
|
+
parsed = JSON.parse(digest);
|
|
39
|
+
} catch {
|
|
40
|
+
// A digest someone else set (a library's own error): not ours to read.
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (typeof parsed !== 'object' || parsed === null) return null;
|
|
44
|
+
const errorId: unknown = Reflect.get(parsed, 'errorId');
|
|
45
|
+
return Reflect.get(parsed, 'type') === 'error' && typeof errorId === 'string' ? errorId : null;
|
|
46
|
+
}
|
|
@@ -67,9 +67,9 @@ export interface RscPayloadRoot extends PublishedParams {
|
|
|
67
67
|
* In the browser this is unreachable for a real response: all four producers
|
|
68
68
|
* of a route payload go through `withPublishedParams`, and a client talking to
|
|
69
69
|
* a different build is answered with 204 at Stage 1c
|
|
70
|
-
* (`server/pipeline-phases.ts`) before any payload exists. It is
|
|
71
|
-
*
|
|
72
|
-
*
|
|
70
|
+
* (`server/pipeline-phases.ts`) before any payload exists. It is what a page
|
|
71
|
+
* with no payload at all publishes — a document hydrated without an inlined
|
|
72
|
+
* payload, or a prefetch entry that carries no params.
|
|
73
73
|
*/
|
|
74
74
|
export const NO_PUBLISHED_PARAMS: PublishedParams = { params: {}, slotParams: null };
|
|
75
75
|
|
|
@@ -99,9 +99,8 @@ export function readPublishedParams(source: unknown): PublishedParams {
|
|
|
99
99
|
/**
|
|
100
100
|
* Read the renderable tree out of a payload root.
|
|
101
101
|
*
|
|
102
|
-
* Returns the value unchanged when it is not a root
|
|
103
|
-
*
|
|
104
|
-
* that text should see the text.
|
|
102
|
+
* Returns the value unchanged when it is not a root, so a malformed value
|
|
103
|
+
* reaches React (and its error boundaries) rather than vanishing here.
|
|
105
104
|
*/
|
|
106
105
|
export function readPayloadTree(root: unknown): unknown {
|
|
107
106
|
if (typeof root === 'object' && root !== null && 'tree' in root && hasPublishedParams(root)) {
|
|
@@ -118,10 +117,12 @@ export interface SplitPayload {
|
|
|
118
117
|
* The params published beside it. Settled when the root already is, so the
|
|
119
118
|
* hydration path can render without an extra await.
|
|
120
119
|
*
|
|
121
|
-
* **Never rejects.** A decode failure has to surface
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
120
|
+
* **Never rejects.** A decode failure has to surface through `tree`: where
|
|
121
|
+
* React renders it on hydration, so the error boundary *around the tree*
|
|
122
|
+
* catches it, and where the router awaits it before handing a navigation
|
|
123
|
+
* over, so the navigation fails and recovers. Rejecting here too would take
|
|
124
|
+
* down the provider above every boundary in the app, turning a contained
|
|
125
|
+
* failure into a blank page (TIM-1297).
|
|
125
126
|
*/
|
|
126
127
|
params: ParamsSource;
|
|
127
128
|
}
|
|
@@ -39,7 +39,14 @@
|
|
|
39
39
|
* normalize; this function does not, because the two callers normalize from
|
|
40
40
|
* different sources (a browser URL, a build-time route entry).
|
|
41
41
|
*/
|
|
42
|
+
/**
|
|
43
|
+
* The directory, relative to the site root, that holds every static RSC
|
|
44
|
+
* payload. The one spelling: the build writes, hashes, and reports it as
|
|
45
|
+
* content-hashed from here.
|
|
46
|
+
*/
|
|
47
|
+
export const RSC_PAYLOAD_DIR = '_rsc';
|
|
48
|
+
|
|
42
49
|
export function rscPayloadPath(routePath: string): string {
|
|
43
50
|
const prefix = routePath === '/' ? '' : routePath;
|
|
44
|
-
return
|
|
51
|
+
return `/${RSC_PAYLOAD_DIR}${prefix}/index.rsc`;
|
|
45
52
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace a file's contents in one step: write a uniquely named temp sibling,
|
|
3
|
+
* then `rename()` it over the target.
|
|
4
|
+
*
|
|
5
|
+
* `writeFile()` opens its target with `O_TRUNC`, so for the length of the write
|
|
6
|
+
* a concurrent reader sees an empty or half-written file under the real name.
|
|
7
|
+
* `rename()` within one directory swaps the name atomically, so a reader sees
|
|
8
|
+
* either the old file or the new one — never a torn one — and a crashed
|
|
9
|
+
* writer leaves no partial artifact under the final name.
|
|
10
|
+
*
|
|
11
|
+
* The temp name is unique per call, not a fixed `${path}.tmp`: two writers of
|
|
12
|
+
* the same path (a dev server and a `vite build` rewriting the same route
|
|
13
|
+
* types, parallel CLI invocations sharing a cache) would otherwise write into
|
|
14
|
+
* one temp file and rename each other's half-written bytes into place.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { randomUUID } from 'node:crypto';
|
|
18
|
+
import { rename, rm, writeFile } from 'node:fs/promises';
|
|
19
|
+
|
|
20
|
+
export async function writeFileAtomic(path: string, data: Uint8Array | string): Promise<void> {
|
|
21
|
+
const tmp = `${path}.${randomUUID()}.tmp`;
|
|
22
|
+
try {
|
|
23
|
+
await writeFile(tmp, data);
|
|
24
|
+
await rename(tmp, path);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
// Best-effort cleanup. If the directory refuses the write it may refuse
|
|
27
|
+
// the rm too, and that error — naming a random temp path — must not
|
|
28
|
+
// replace the one that says what actually failed.
|
|
29
|
+
await rm(tmp, { force: true }).catch(() => {});
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
}
|