@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
|
@@ -16,7 +16,7 @@ This is the number one confusion point. They are different things:
|
|
|
16
16
|
| ------------------- | --------------------------- | -------------------- |
|
|
17
17
|
| Scope | Cross-request (persistent) | Single request |
|
|
18
18
|
| TTL/tags | Yes | No |
|
|
19
|
-
| Works in middleware
|
|
19
|
+
| Works in middleware | Yes | Yes (same request) |
|
|
20
20
|
| Use case | Database queries, API calls | Request-scoped dedup |
|
|
21
21
|
|
|
22
22
|
`React.cache` deduplicates within a single request — if three components call `getUser(id)`, only one database query runs. `timber.cache` persists across requests with TTL — the same query serves cached results for 60 seconds.
|
|
@@ -58,10 +58,10 @@ const getUser = cache.data(
|
|
|
58
58
|
return db.users.findUnique({ where: { id: userId } });
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
|
-
ttl: 60,
|
|
62
|
-
key: (userId) => `user:${userId}`,
|
|
63
|
-
staleWhileRevalidate: true,
|
|
64
|
-
tags: (userId) => [`user:${userId}`],
|
|
61
|
+
ttl: 60, // Cache for 60 seconds
|
|
62
|
+
key: (userId) => `user:${userId}`, // Explicit cache key (optional)
|
|
63
|
+
staleWhileRevalidate: true, // Serve stale while refetching
|
|
64
|
+
tags: (userId) => [`user:${userId}`], // For tag-based invalidation
|
|
65
65
|
}
|
|
66
66
|
);
|
|
67
67
|
```
|
|
@@ -101,7 +101,18 @@ revalidateTag('products');
|
|
|
101
101
|
revalidateTag(`user:${userId}`);
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
`revalidateTag` works outside actions too. From a `route.ts` handler, say a CMS webhook, it invalidates immediately, and you await it before responding:
|
|
105
|
+
|
|
106
|
+
```ts title="app/api/cms-webhook/route.ts"
|
|
107
|
+
export async function POST(ctx: RouteContext) {
|
|
108
|
+
await revalidateTag('products');
|
|
109
|
+
return new Response(null, { status: 204 });
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`revalidatePath` is different: it re-renders a page into a server action's response, so it only works inside an action.
|
|
114
|
+
|
|
115
|
+
Invalidation wins races against in-flight cached functions: if a cached function is mid-execution when you invalidate one of its tags (the usual mutation flow — update the database, then `revalidateTag`), its result is not written back to the cache, and callers arriving after the invalidation re-execute instead of joining the superseded execution. This guard is per-process; with a shared handler (Redis/KV), an invalidation from a _different_ instance can still race a concurrent write on this one.
|
|
105
116
|
|
|
106
117
|
## `staleWhileRevalidate`
|
|
107
118
|
|
|
@@ -129,7 +140,12 @@ const PostBody = cache.component(
|
|
|
129
140
|
async function PostBody() {
|
|
130
141
|
const { slug } = getSegmentParams();
|
|
131
142
|
const post = await getPost(slug);
|
|
132
|
-
return
|
|
143
|
+
return (
|
|
144
|
+
<article>
|
|
145
|
+
<h1>{post.title}</h1>
|
|
146
|
+
<PostContent content={post.content} />
|
|
147
|
+
</article>
|
|
148
|
+
);
|
|
133
149
|
},
|
|
134
150
|
{ prerender: true }
|
|
135
151
|
);
|
|
@@ -188,10 +204,10 @@ export default async function BlogPost() {
|
|
|
188
204
|
const user = await getUser(getCookieJar());
|
|
189
205
|
return (
|
|
190
206
|
<>
|
|
191
|
-
<Nav user={user} />
|
|
192
|
-
<PostBody />
|
|
207
|
+
<Nav user={user} /> {/* dynamic — personalized */}
|
|
208
|
+
<PostBody /> {/* prerendered — from build artifact */}
|
|
193
209
|
<Suspense fallback={<CommentsSkeleton />}>
|
|
194
|
-
<Comments />
|
|
210
|
+
<Comments /> {/* dynamic — streams per-request */}
|
|
195
211
|
</Suspense>
|
|
196
212
|
</>
|
|
197
213
|
);
|
|
@@ -230,7 +246,9 @@ const Shell = cache.component(ExpensiveWrapper, {
|
|
|
230
246
|
});
|
|
231
247
|
|
|
232
248
|
// The shell serves from cache; children render live per request.
|
|
233
|
-
<Shell theme="dark"
|
|
249
|
+
<Shell theme="dark">
|
|
250
|
+
<LiveUserFeed />
|
|
251
|
+
</Shell>;
|
|
234
252
|
```
|
|
235
253
|
|
|
236
254
|
Slot props are excluded from the cache key. Slots are runtime tier only — `prerender` is ignored when `slots` is active.
|
|
@@ -27,10 +27,16 @@ Before diving in, the first question: should this be middleware or `access.ts`?
|
|
|
27
27
|
| ------------- | -------------------------------------- | --------------------------------- |
|
|
28
28
|
| Runs | Before rendering | Inside React tree |
|
|
29
29
|
| Purpose | Headers, redirects, cache warming | Auth, data gating |
|
|
30
|
-
| `React.cache` |
|
|
30
|
+
| `React.cache` | Active — shares scope with the render | Active — shares scope with layout |
|
|
31
31
|
| Slots | N/A | Graceful degradation |
|
|
32
32
|
|
|
33
|
-
Use `middleware.ts` for request-level decisions: should this request proceed? What headers does it need? Use `access.ts` for auth — it
|
|
33
|
+
Use `middleware.ts` for request-level decisions: should this request proceed? What headers does it need? Use `access.ts` for auth — it gates each segment, renders status pages with `deny()`, and supports slot degradation.
|
|
34
|
+
|
|
35
|
+
Both share one `React.cache` scope per request with your layouts and pages. A `React.cache`-wrapped `getUser()` called in middleware, `access.ts`, and a layout runs once. Middleware is a good place to start that fetch early.
|
|
36
|
+
|
|
37
|
+
If middleware changes a cookie, cached functions that already read it keep their old result. Have them take the cookie value as an argument (see [Fetching Data](/docs/fetching-data)); in development timber warns when this happens.
|
|
38
|
+
|
|
39
|
+
Middleware runs once, root to leaf, before any `access.ts`. A child `middleware.ts` that returns a `Response` responds before a parent's `access.ts` runs. Put authorization that must cover a whole subtree in `access.ts` or in a parent `middleware.ts`.
|
|
34
40
|
|
|
35
41
|
## `proxy.ts` — Global Middleware
|
|
36
42
|
|
|
@@ -111,21 +111,26 @@ The general error boundary. It's a client component:
|
|
|
111
111
|
|
|
112
112
|
export default function DashboardError({
|
|
113
113
|
error,
|
|
114
|
+
digest,
|
|
114
115
|
reset,
|
|
115
116
|
}: {
|
|
116
117
|
error: Error;
|
|
118
|
+
digest: string | null;
|
|
117
119
|
reset: () => void;
|
|
118
120
|
}) {
|
|
119
121
|
return (
|
|
120
122
|
<div>
|
|
121
123
|
<h2>Something went wrong</h2>
|
|
122
124
|
<p>{error.message}</p>
|
|
125
|
+
{digest && <p>Reference: {digest}</p>}
|
|
123
126
|
<button onClick={reset}>Try again</button>
|
|
124
127
|
</div>
|
|
125
128
|
);
|
|
126
129
|
}
|
|
127
130
|
```
|
|
128
131
|
|
|
132
|
+
`digest` is the ID the server logged the error with: the `errorId` field on its log line. In production `error.message` is a generic string, so the digest is what a reader can quote to you and what you search your logs for. It is `null` when the boundary is serving a `deny()`, and for an error the server logged without an ID: one thrown in the browser, one a client component throws while the page renders on the server, or one raised before the page renders (a module that fails to load, say).
|
|
133
|
+
|
|
129
134
|
Error boundaries wrap page content inside layouts — the layout shell (nav, sidebar) stays visible when an error fires.
|
|
130
135
|
|
|
131
136
|
A status page renders inside the layouts **above and including the segment it lives in**, and none below it. A root `404.tsx` serving a `deny(404)` from `app/docs/[slug]/page.tsx` renders inside the root layout only — `docs/layout.tsx` and `[slug]/layout.tsx` do not appear, because the file that matched lives above them. Co-locate the status file with the segment whose chrome you want kept: move that `404.tsx` to `app/docs/` and the docs layout comes with it.
|
|
@@ -184,4 +189,4 @@ if (!product) {
|
|
|
184
189
|
}
|
|
185
190
|
```
|
|
186
191
|
|
|
187
|
-
The status-code file receives the structured data as the `data` prop, surviving the RSC → client boundary where plain error properties are stripped.
|
|
192
|
+
The status-code file receives the structured data as the `data` prop, surviving the RSC → client boundary where plain error properties are stripped. This works for any 4xx or 5xx status: `deny(503, { dangerouslyPassData })` renders `503.tsx` (or `5xx.tsx`, or `error.tsx`) with its `data`. A plain `throw` is for failures you did not plan for: outside `<Suspense>` it renders the error page with a 500, and in production the page gets a generic message and a `digest` to find the log line by.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timber-js/app",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.209",
|
|
4
4
|
"description": "Vite-native React framework built for Servers and Serverless Platforms — correct HTTP semantics, real status codes, pages that work without JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare-workers",
|
|
@@ -133,6 +133,10 @@
|
|
|
133
133
|
"types": "./dist/adapters/nitro.d.ts",
|
|
134
134
|
"import": "./dist/adapters/nitro.js"
|
|
135
135
|
},
|
|
136
|
+
"./adapters/types": {
|
|
137
|
+
"types": "./dist/adapters/types.d.ts",
|
|
138
|
+
"import": "./dist/adapters/types.js"
|
|
139
|
+
},
|
|
136
140
|
"./fonts/google": {
|
|
137
141
|
"types": "./dist/shims/font-google.d.ts",
|
|
138
142
|
"import": "./dist/shims/font-google.js"
|
|
@@ -165,8 +169,8 @@
|
|
|
165
169
|
"@vitejs/plugin-react": "^6.1.0",
|
|
166
170
|
"@vitejs/plugin-rsc": ">=0.5.35",
|
|
167
171
|
"nuqs": "^2.0.0",
|
|
168
|
-
"react": "19.3.0",
|
|
169
|
-
"react-dom": "19.3.0",
|
|
172
|
+
"react": "^19.3.0",
|
|
173
|
+
"react-dom": "^19.3.0",
|
|
170
174
|
"satteri": "^0.9.5",
|
|
171
175
|
"vite": "8.3.0",
|
|
172
176
|
"vite-plugin-satteri": "^0.2.15",
|
|
@@ -23,15 +23,20 @@ import {
|
|
|
23
23
|
USER_PLATFORM_DIR,
|
|
24
24
|
} from '../shared/static-platform-files.ts';
|
|
25
25
|
import { detectFsIdentity, fsKey } from './fs-identity.ts';
|
|
26
|
-
import type {
|
|
26
|
+
import type {
|
|
27
|
+
BuildArtifacts,
|
|
28
|
+
ServerBuildArtifacts,
|
|
29
|
+
StaticBuildArtifacts,
|
|
30
|
+
TimberConfig,
|
|
31
|
+
} from './types.ts';
|
|
27
32
|
|
|
28
33
|
/** Options for the shared build output steps. */
|
|
29
34
|
export interface BuildOutputBaseOptions {
|
|
30
35
|
/** Resolved timber config. */
|
|
31
36
|
config: TimberConfig;
|
|
32
|
-
/**
|
|
33
|
-
|
|
34
|
-
/** Adapter-specific output directory (e.g. `.timber/
|
|
37
|
+
/** What the build produced. */
|
|
38
|
+
artifacts: ServerBuildArtifacts;
|
|
39
|
+
/** Adapter-specific output directory (e.g. `.timber/dist/nitro`). */
|
|
35
40
|
outDir: string;
|
|
36
41
|
/**
|
|
37
42
|
* Name of the public/static directory within outDir.
|
|
@@ -52,7 +57,7 @@ export interface BuildOutputBaseOptions {
|
|
|
52
57
|
* Returns the resolved public directory path for further adapter-specific use.
|
|
53
58
|
*/
|
|
54
59
|
export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise<string> {
|
|
55
|
-
const { config,
|
|
60
|
+
const { config, artifacts, outDir, publicDirName } = opts;
|
|
56
61
|
|
|
57
62
|
// 1. Create the output directory.
|
|
58
63
|
await mkdir(outDir, { recursive: true });
|
|
@@ -60,9 +65,9 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
|
|
|
60
65
|
// 2. Copy client assets to public/static directory.
|
|
61
66
|
// When client JavaScript is disabled, skip .js files — only CSS,
|
|
62
67
|
// fonts, images, and other static assets are needed.
|
|
63
|
-
const clientDir = join(buildDir, 'client');
|
|
64
68
|
const publicDir = join(outDir, publicDirName);
|
|
65
69
|
await mkdir(publicDir, { recursive: true });
|
|
70
|
+
const clientDir = artifacts.client.path;
|
|
66
71
|
// Find WASM files that are referenced by client JS (legitimate client WASM)
|
|
67
72
|
// vs orphaned server-only WASM (e.g. @takumi-rs for OG image generation).
|
|
68
73
|
// Only strip orphaned WASM to avoid breaking client-side WASM usage.
|
|
@@ -77,39 +82,31 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
|
|
|
77
82
|
if (config.clientJavascriptDisabled && src.endsWith('.js')) return false;
|
|
78
83
|
return true;
|
|
79
84
|
},
|
|
80
|
-
}).catch((e: NodeJS.ErrnoException) => {
|
|
81
|
-
// Client dir may not exist when client JavaScript is disabled
|
|
82
|
-
if (e.code !== 'ENOENT') throw e;
|
|
83
85
|
});
|
|
84
86
|
|
|
85
87
|
// 3. Write _headers file for static asset cache control.
|
|
86
88
|
// Scan for unhashed files so they get per-file Cache-Control rules in the
|
|
87
89
|
// _headers file. On platforms like Cloudflare Workers Static Assets, the
|
|
88
90
|
// worker never sees static file requests — _headers is the only mechanism.
|
|
89
|
-
await writeHeadersFile(publicDir, config,
|
|
91
|
+
await writeHeadersFile(publicDir, config, artifacts);
|
|
90
92
|
|
|
91
|
-
// 4. Copy RSC + SSR server bundles into the output directory.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
);
|
|
93
|
+
// 4. Copy RSC + SSR server bundles into the output directory. The RSC
|
|
94
|
+
// bundle imports the SSR one by a path the RSC plugin computed between the
|
|
95
|
+
// two *build* directories, which the build names `rsc/` and `ssr/` as
|
|
96
|
+
// siblings (index.ts); deploying them under the same names keeps it valid.
|
|
97
|
+
await cp(artifacts.rsc.path, join(outDir, 'rsc'), { recursive: true });
|
|
98
|
+
await cp(artifacts.ssr.path, join(outDir, 'ssr'), { recursive: true });
|
|
99
99
|
|
|
100
|
-
// 4b. Copy prebuilt/ flight payloads
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
|
|
104
|
-
(
|
|
105
|
-
|
|
106
|
-
if (e.code !== 'ENOENT') throw e;
|
|
107
|
-
}
|
|
108
|
-
);
|
|
100
|
+
// 4b. Copy prebuilt/ flight payloads (cache.component artifacts). These
|
|
101
|
+
// are produced by the post-build capture pass (design/44) and read at
|
|
102
|
+
// request time via the adapter's PrebuiltPayloadSource.
|
|
103
|
+
if (artifacts.prebuilt) {
|
|
104
|
+
await cp(artifacts.prebuilt.path, join(outDir, 'prebuilt'), { recursive: true });
|
|
105
|
+
}
|
|
109
106
|
|
|
110
107
|
// 5. Write manifest-init module if present.
|
|
111
|
-
if (
|
|
112
|
-
await writeFile(join(outDir, '_timber-manifest-init.js'),
|
|
108
|
+
if (artifacts.manifestInit) {
|
|
109
|
+
await writeFile(join(outDir, '_timber-manifest-init.js'), artifacts.manifestInit);
|
|
113
110
|
}
|
|
114
111
|
|
|
115
112
|
return publicDir;
|
|
@@ -120,9 +117,16 @@ export async function runSharedBuildSteps(opts: BuildOutputBaseOptions): Promise
|
|
|
120
117
|
* Cache-Control rules in the `_headers` file.
|
|
121
118
|
*
|
|
122
119
|
* Excludes:
|
|
123
|
-
* - Files under
|
|
120
|
+
* - Files under the build's `immutableDirs` (covered by wildcard rules)
|
|
121
|
+
* - Files under `rsc/` and `ssr/` (server bundles, never served)
|
|
124
122
|
* - Underscore-prefixed files (`_headers`, `_worker.js`, etc.)
|
|
125
123
|
*
|
|
124
|
+
* Ordered for the rule cap: well-known metadata files, then everything
|
|
125
|
+
* else, then files under an underscore-prefixed directory — the
|
|
126
|
+
* framework's own output (unhashed RSC payloads in a static build with
|
|
127
|
+
* client JavaScript disabled, which nothing fetches). Those can number one
|
|
128
|
+
* per route, and must not take the budget from the app's real files.
|
|
129
|
+
*
|
|
126
130
|
* @internal Exported for testing.
|
|
127
131
|
*/
|
|
128
132
|
// Well-known metadata files that should be prioritized when capping
|
|
@@ -136,7 +140,10 @@ const PRIORITY_FILES = new Set([
|
|
|
136
140
|
'/apple-touch-icon.png',
|
|
137
141
|
]);
|
|
138
142
|
|
|
139
|
-
export async function findUnhashedStaticFiles(
|
|
143
|
+
export async function findUnhashedStaticFiles(
|
|
144
|
+
publicDir: string,
|
|
145
|
+
immutableDirs: readonly string[]
|
|
146
|
+
): Promise<string[]> {
|
|
140
147
|
let files: string[];
|
|
141
148
|
try {
|
|
142
149
|
files = await collectFiles(publicDir);
|
|
@@ -146,20 +153,23 @@ export async function findUnhashedStaticFiles(publicDir: string): Promise<string
|
|
|
146
153
|
|
|
147
154
|
const priority: string[] = [];
|
|
148
155
|
const rest: string[] = [];
|
|
156
|
+
const framework: string[] = [];
|
|
149
157
|
for (const file of files) {
|
|
150
158
|
const rel = relative(publicDir, file).replace(/\\/g, '/');
|
|
151
|
-
if (
|
|
152
|
-
if (rel.startsWith('rsc/') || rel.startsWith('ssr/')
|
|
159
|
+
if (immutableDirs.some((dir) => rel.startsWith(`${dir}/`))) continue;
|
|
160
|
+
if (rel.startsWith('rsc/') || rel.startsWith('ssr/')) continue;
|
|
153
161
|
if (basename(rel).startsWith('_')) continue;
|
|
154
162
|
const urlPath = '/' + rel;
|
|
155
163
|
if (PRIORITY_FILES.has(urlPath)) {
|
|
156
164
|
priority.push(urlPath);
|
|
165
|
+
} else if (rel.startsWith('_')) {
|
|
166
|
+
framework.push(urlPath);
|
|
157
167
|
} else {
|
|
158
168
|
rest.push(urlPath);
|
|
159
169
|
}
|
|
160
170
|
}
|
|
161
171
|
|
|
162
|
-
return [...priority.sort(), ...rest.sort()];
|
|
172
|
+
return [...priority.sort(), ...rest.sort(), ...framework.sort()];
|
|
163
173
|
}
|
|
164
174
|
|
|
165
175
|
/**
|
|
@@ -169,13 +179,7 @@ export async function findUnhashedStaticFiles(publicDir: string): Promise<string
|
|
|
169
179
|
*/
|
|
170
180
|
async function findReferencedWasm(clientDir: string): Promise<Set<string>> {
|
|
171
181
|
const referenced = new Set<string>();
|
|
172
|
-
|
|
173
|
-
let files: string[];
|
|
174
|
-
try {
|
|
175
|
-
files = await collectFiles(clientDir);
|
|
176
|
-
} catch {
|
|
177
|
-
return referenced;
|
|
178
|
-
}
|
|
182
|
+
const files = await collectFiles(clientDir);
|
|
179
183
|
|
|
180
184
|
const jsFiles = files.filter((f) => f.endsWith('.js'));
|
|
181
185
|
const wasmFiles = files.filter((f) => f.endsWith('.wasm')).map((f) => basename(f));
|
|
@@ -200,7 +204,7 @@ async function findReferencedWasm(clientDir: string): Promise<Set<string>> {
|
|
|
200
204
|
*/
|
|
201
205
|
export async function buildStaticDirectoryOutput(
|
|
202
206
|
config: TimberConfig,
|
|
203
|
-
|
|
207
|
+
artifacts: StaticBuildArtifacts,
|
|
204
208
|
outDir: string,
|
|
205
209
|
publicDirName: string
|
|
206
210
|
): Promise<void> {
|
|
@@ -214,15 +218,12 @@ export async function buildStaticDirectoryOutput(
|
|
|
214
218
|
await mkdir(publicDir, { recursive: true });
|
|
215
219
|
|
|
216
220
|
// Copy client assets (JS, CSS, fonts, images).
|
|
217
|
-
|
|
218
|
-
await cp(clientDir, publicDir, {
|
|
221
|
+
await cp(artifacts.client.path, publicDir, {
|
|
219
222
|
recursive: true,
|
|
220
223
|
filter: (src: string) => {
|
|
221
224
|
if (config.clientJavascriptDisabled && src.endsWith('.js')) return false;
|
|
222
225
|
return true;
|
|
223
226
|
},
|
|
224
|
-
}).catch((e: NodeJS.ErrnoException) => {
|
|
225
|
-
if (e.code !== 'ENOENT') throw e;
|
|
226
227
|
});
|
|
227
228
|
|
|
228
229
|
// Copy pre-rendered static pages (HTML + RSC flight + API routes).
|
|
@@ -231,10 +232,8 @@ export async function buildStaticDirectoryOutput(
|
|
|
231
232
|
// into a single directory, and `cp` resolves an overlap by overwriting with
|
|
232
233
|
// no diagnostic — the deployment then contains one of the two artifacts and
|
|
233
234
|
// nothing recorded which. Refuse instead (TIM-1266).
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
await cp(config.staticPagesDir, publicDir, { recursive: true });
|
|
237
|
-
}
|
|
235
|
+
await assertNoTreeCollision(artifacts.pages.path, publicDir);
|
|
236
|
+
await cp(artifacts.pages.path, publicDir, { recursive: true });
|
|
238
237
|
}
|
|
239
238
|
|
|
240
239
|
/**
|
|
@@ -265,15 +264,18 @@ export async function buildStaticDirectoryOutput(
|
|
|
265
264
|
export async function writeHeadersFile(
|
|
266
265
|
dir: string,
|
|
267
266
|
config: TimberConfig,
|
|
268
|
-
|
|
267
|
+
artifacts: BuildArtifacts
|
|
269
268
|
): Promise<void> {
|
|
270
269
|
const userRules = await readUserPlatformFile(config.root, HEADERS_FILE);
|
|
271
270
|
await writeFile(
|
|
272
271
|
join(dir, HEADERS_FILE),
|
|
273
272
|
generateHeadersFile({
|
|
274
273
|
base: adapterBase(config),
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
immutableDirs: artifacts.immutableDirs,
|
|
275
|
+
// Scanned from the directory being deployed, which holds everything
|
|
276
|
+
// the platform will serve from it.
|
|
277
|
+
unhashedPaths: await findUnhashedStaticFiles(dir, artifacts.immutableDirs),
|
|
278
|
+
contentTypes: artifacts.output === 'static' ? artifacts.contentTypes : undefined,
|
|
277
279
|
userRules: userRules ?? undefined,
|
|
278
280
|
})
|
|
279
281
|
);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Compiles server/canonicalize.ts into a standalone ESM module
|
|
2
|
+
// (_canonicalize.mjs) for the Nitro preview server, so preview answers a
|
|
3
|
+
// request path exactly as the runtime's request boundary does — the same
|
|
4
|
+
// rejections (encoded separators, null bytes, malformed encoding, escaping
|
|
5
|
+
// the root) and the same single decode — instead of a hand-kept copy of
|
|
6
|
+
// those rules drifting from them. Same mechanism as compress-module.ts:
|
|
7
|
+
// type-stripped, not bundled, so the source must stay import-free.
|
|
8
|
+
|
|
9
|
+
import { transformWithOxc } from 'vite';
|
|
10
|
+
// Vite's ?raw import embeds the file as a string at build time (see
|
|
11
|
+
// compress-module.ts).
|
|
12
|
+
import canonicalizeSource from '../server/canonicalize.ts?raw';
|
|
13
|
+
import { assertStandalone } from './compress-module.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Compile server/canonicalize.ts into a standalone ESM module exporting
|
|
17
|
+
* `canonicalize`.
|
|
18
|
+
*
|
|
19
|
+
* @internal Exported for testing.
|
|
20
|
+
*/
|
|
21
|
+
export async function generateCanonicalizeModule(): Promise<string> {
|
|
22
|
+
const result = await transformWithOxc(canonicalizeSource, 'canonicalize.ts', { lang: 'ts' });
|
|
23
|
+
assertStandalone(result.code, 'server/canonicalize.ts', '_canonicalize.mjs');
|
|
24
|
+
return (
|
|
25
|
+
'// Generated by @timber-js/app — compiled from server/canonicalize.ts.\n' +
|
|
26
|
+
'// Do not edit — this file is regenerated on each build.\n' +
|
|
27
|
+
result.code
|
|
28
|
+
);
|
|
29
|
+
}
|