@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/dist/index.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { a as formatMissingPeers, i as formatConfigErrors, n as timberDevServer, o as validateConfig, r as checkPeerDependencies } from "./_chunks/dev-server-
|
|
1
|
+
import { a as formatMissingPeers, i as formatConfigErrors, n as timberDevServer, o as validateConfig, r as checkPeerDependencies } from "./_chunks/dev-server-C4WZdB7L.js";
|
|
2
|
+
import { i as resolveRenderTimeoutMs } from "./_chunks/render-timeout-DOf_BBcO.js";
|
|
3
|
+
import { t as writeFileAtomic } from "./_chunks/write-file-atomic-D1qWqHb4.js";
|
|
2
4
|
import { a as isDynamicMetadataExtension } from "./_chunks/metadata-routes-DSDjM_hJ.js";
|
|
3
|
-
import { n as scanRoutes, r as collectInterceptionRewrites } from "./_chunks/scanner-
|
|
4
|
-
import {
|
|
5
|
-
import { c as writeRouteCodegen, i as getPrerenderExport, l as buildDirToRouteMap, n as formatConventionWarnings, r as lintConventions, s as flushCodegenWrites, t as checkAppDirExists } from "./_chunks/convention-lint-
|
|
6
|
-
import { c as
|
|
7
|
-
import { r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "./_chunks/walkers-CN2N_bA-.js";
|
|
8
|
-
import { i as poisonPillSource, r as markerFor, t as EXPLICIT_MARKERS } from "./_chunks/poison-rules-DoEhbqaY.js";
|
|
5
|
+
import { n as scanRoutes, r as collectInterceptionRewrites } from "./_chunks/scanner-Bw0oq1HB.js";
|
|
6
|
+
import { _ as swallow } from "./_chunks/logger-DiDt5ppH.js";
|
|
7
|
+
import { c as writeRouteCodegen, i as getPrerenderExport, l as buildDirToRouteMap, n as formatConventionWarnings, r as lintConventions, s as flushCodegenWrites, t as checkAppDirExists } from "./_chunks/convention-lint-jKTwKwPe.js";
|
|
8
|
+
import { a as loadTimberConfigFile, c as resolveAppDir, d as createNoopTimer, l as resolveBuildDir, n as contextAdapter, o as mergeFileConfig, r as createPluginContext, t as adapterConfig, u as resolveClientJavascript } from "./_chunks/plugin-context-BPBPc3lL.js";
|
|
9
9
|
import { i as withBasePath, n as normalizeBasePath, t as isRelativeBase } from "./_chunks/base-path-DaQrzbez.js";
|
|
10
|
-
import { t as
|
|
11
|
-
import { t as
|
|
12
|
-
import {
|
|
10
|
+
import { r as validateSchemaAgainstRoutes, t as collectLeafRoutes } from "./_chunks/walkers-BXExhzzk.js";
|
|
11
|
+
import { i as poisonPillSource, r as markerFor, t as EXPLICIT_MARKERS } from "./_chunks/poison-rules-DoEhbqaY.js";
|
|
12
|
+
import { n as rscPayloadPath, t as RSC_PAYLOAD_DIR } from "./_chunks/rsc-payload-path-dffcs4jp.js";
|
|
13
|
+
import { a as REDIRECTS_FILE, n as detectFsIdentity, o as RESERVED_OUTPUT_PATHS, r as fsKey, t as EXACT_FS_IDENTITY } from "./_chunks/fs-identity-BRKuL215.js";
|
|
14
|
+
import { t as EMPTY_BUILD_MANIFEST } from "./_chunks/build-manifest-DWppEdLB.js";
|
|
13
15
|
import { t as fnv1aHash } from "./_chunks/fast-hash-C-tVYrLb.js";
|
|
14
16
|
import { t as formatSize } from "./_chunks/format-BKclgVbk.js";
|
|
15
17
|
import { createLogger, parseAst } from "vite";
|
|
@@ -202,7 +204,7 @@ function generateConfigModule(ctx) {
|
|
|
202
204
|
topLoader: ctx.config.topLoader,
|
|
203
205
|
debug: ctx.config.debug ?? false,
|
|
204
206
|
serverTiming: ctx.config.serverTiming,
|
|
205
|
-
renderTimeoutMs: ctx.config.renderTimeoutMs
|
|
207
|
+
renderTimeoutMs: resolveRenderTimeoutMs(ctx.config.renderTimeoutMs),
|
|
206
208
|
sitemap: ctx.config.sitemap,
|
|
207
209
|
forms: serializeFormsConfig(ctx.config.forms),
|
|
208
210
|
deploymentId: ctx.deploymentId ?? null,
|
|
@@ -962,7 +964,8 @@ var SUBPATH_SRC_MAP = {
|
|
|
962
964
|
"adapters/cloudflare": "adapters/cloudflare.ts",
|
|
963
965
|
"adapters/cloudflare/cache": "adapters/cloudflare-kv-cache.ts",
|
|
964
966
|
"adapters/cloudflare/dev": "adapters/cloudflare-dev.ts",
|
|
965
|
-
"adapters/nitro": "adapters/nitro.ts"
|
|
967
|
+
"adapters/nitro": "adapters/nitro.ts",
|
|
968
|
+
"adapters/types": "adapters/types.ts"
|
|
966
969
|
};
|
|
967
970
|
/**
|
|
968
971
|
* Runtime value exports of @timber-js/app/server, stubbed in the client
|
|
@@ -4543,8 +4546,14 @@ function writeFontManifest(pipeline, buildManifest, base = "/") {
|
|
|
4543
4546
|
*/
|
|
4544
4547
|
function timberFonts(ctx) {
|
|
4545
4548
|
const pipeline = new FontPipeline({ hashOnRegister: !ctx.dev });
|
|
4549
|
+
/** Whether the client environment emitted a binary this build. */
|
|
4550
|
+
let emittedToClient = false;
|
|
4546
4551
|
return {
|
|
4547
4552
|
name: "timber-fonts",
|
|
4553
|
+
api: {
|
|
4554
|
+
contributeManifest: (manifest) => writeFontManifest(pipeline, manifest, ctx.base),
|
|
4555
|
+
immutableDirs: () => emittedToClient ? [FONT_OUTPUT_DIR] : []
|
|
4556
|
+
},
|
|
4548
4557
|
/**
|
|
4549
4558
|
* Push Vite's resolved `base` into the pipeline so every font URL it
|
|
4550
4559
|
* emits (@font-face src, manifest hrefs, dev middleware matching)
|
|
@@ -4724,212 +4733,23 @@ function timberFonts(ctx) {
|
|
|
4724
4733
|
}
|
|
4725
4734
|
},
|
|
4726
4735
|
/**
|
|
4727
|
-
* Emit font binaries
|
|
4736
|
+
* Emit font binaries.
|
|
4728
4737
|
*
|
|
4729
4738
|
* All font binaries (Google and local) use content-hashed filenames
|
|
4730
4739
|
* for immutable caching. Font CSS is handled by Vite's CSS pipeline
|
|
4731
|
-
* via virtual modules — we only emit binaries here.
|
|
4740
|
+
* via virtual modules — we only emit binaries here. Manifest entries are
|
|
4741
|
+
* written by the post-build phase through `api.contributeManifest`.
|
|
4732
4742
|
*/
|
|
4733
4743
|
generateBundle() {
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
//#endregion
|
|
4741
|
-
//#region src/plugins/adapter-build.ts
|
|
4742
|
-
function timberAdapterBuild(ctx) {
|
|
4743
|
-
return {
|
|
4744
|
-
name: "timber-adapter-build",
|
|
4745
|
-
buildApp: {
|
|
4746
|
-
order: "post",
|
|
4747
|
-
async handler() {
|
|
4748
|
-
if (ctx.dev) return;
|
|
4749
|
-
const adapter = ctx.config.adapter;
|
|
4750
|
-
if (!adapter || typeof adapter.buildOutput !== "function") return;
|
|
4751
|
-
const buildDir = ctx.buildDir;
|
|
4752
|
-
if (ctx.buildManifest) await mergeRscAssetsManifest(buildDir, ctx.root, ctx.buildManifest, ctx.routeClientRefKeys);
|
|
4753
|
-
let manifestInit;
|
|
4754
|
-
if (ctx.buildManifest) {
|
|
4755
|
-
const manifest = ctx.clientJavascript.disabled ? {
|
|
4756
|
-
...ctx.buildManifest,
|
|
4757
|
-
js: {},
|
|
4758
|
-
modulepreload: {}
|
|
4759
|
-
} : ctx.buildManifest;
|
|
4760
|
-
manifestInit = `globalThis.__TIMBER_BUILD_MANIFEST__ = ${JSON.stringify(manifest)};\n`;
|
|
4761
|
-
if (ctx.deploymentId) manifestInit += `globalThis.__TIMBER_DEPLOYMENT_ID__ = ${JSON.stringify(ctx.deploymentId)};\n`;
|
|
4762
|
-
}
|
|
4763
|
-
if (ctx.clientJavascript.disabled) await stripJsFromRscAssetsManifests(buildDir);
|
|
4764
|
-
const adapterConfig = {
|
|
4765
|
-
root: ctx.root,
|
|
4766
|
-
base: normalizeBasePath(ctx.base),
|
|
4767
|
-
output: ctx.config.output ?? "server",
|
|
4768
|
-
clientJavascriptDisabled: ctx.clientJavascript.disabled,
|
|
4769
|
-
manifestInit,
|
|
4770
|
-
staticPagesDir: (ctx.config.output ?? "server") === "static" ? join(buildDir, "static-pages") : void 0,
|
|
4771
|
-
staticContentTypes: ctx.staticContentTypes
|
|
4772
|
-
};
|
|
4773
|
-
await adapter.buildOutput(adapterConfig, buildDir);
|
|
4774
|
-
}
|
|
4744
|
+
let emitted = 0;
|
|
4745
|
+
emitFontAssets(pipeline, (asset) => {
|
|
4746
|
+
emitted++;
|
|
4747
|
+
return this.emitFile(asset);
|
|
4748
|
+
}, (msg) => this.warn(msg));
|
|
4749
|
+
if (this.environment?.name === "client") emittedToClient = emitted > 0;
|
|
4775
4750
|
}
|
|
4776
4751
|
};
|
|
4777
4752
|
}
|
|
4778
|
-
/**
|
|
4779
|
-
* Parse the RSC assets manifest at `manifestPath`. Tries JSON.parse first
|
|
4780
|
-
* (fast path for plain-string manifests); falls back to a dynamic import()
|
|
4781
|
-
* for manifests that contain runtime expressions from renderBuiltUrl.
|
|
4782
|
-
* Returns null if both paths fail.
|
|
4783
|
-
*/
|
|
4784
|
-
async function parseRscManifest(manifestPath, content) {
|
|
4785
|
-
const jsonStr = content.replace(/^export default\s*/, "").replace(/;?\s*$/, "");
|
|
4786
|
-
try {
|
|
4787
|
-
return JSON.parse(jsonStr);
|
|
4788
|
-
} catch {}
|
|
4789
|
-
try {
|
|
4790
|
-
return (await import(`${pathToFileURL(manifestPath).href}?t=${Date.now()}`)).default ?? null;
|
|
4791
|
-
} catch (err) {
|
|
4792
|
-
swallow(err, `failed to evaluate RSC assets manifest: ${manifestPath}`, { level: "warn" });
|
|
4793
|
-
return null;
|
|
4794
|
-
}
|
|
4795
|
-
}
|
|
4796
|
-
/**
|
|
4797
|
-
* Replace all `"js": [...]` array contents with `"js": []` using balanced
|
|
4798
|
-
* bracket matching. Handles nested brackets from runtime expressions like
|
|
4799
|
-
* `__rbu("path/to/[slug]/file.js")`.
|
|
4800
|
-
*/
|
|
4801
|
-
function clearJsArrays(src) {
|
|
4802
|
-
const pattern = /"js"\s*:\s*\[/g;
|
|
4803
|
-
let result = "";
|
|
4804
|
-
let lastEnd = 0;
|
|
4805
|
-
let match;
|
|
4806
|
-
while ((match = pattern.exec(src)) !== null) {
|
|
4807
|
-
const arrayStart = match.index + match[0].length;
|
|
4808
|
-
let depth = 1;
|
|
4809
|
-
let i = arrayStart;
|
|
4810
|
-
while (i < src.length && depth > 0) {
|
|
4811
|
-
if (src[i] === "[") depth++;
|
|
4812
|
-
else if (src[i] === "]") depth--;
|
|
4813
|
-
i++;
|
|
4814
|
-
}
|
|
4815
|
-
result += src.slice(lastEnd, match.index) + "\"js\": []";
|
|
4816
|
-
lastEnd = i;
|
|
4817
|
-
}
|
|
4818
|
-
result += src.slice(lastEnd);
|
|
4819
|
-
return result;
|
|
4820
|
-
}
|
|
4821
|
-
/**
|
|
4822
|
-
* Replace `"bootstrapScriptContent": <value>` with an empty string. The
|
|
4823
|
-
* value may be a JS expression (e.g., concatenation with runtime helpers),
|
|
4824
|
-
* not a simple string literal. Scans forward from the colon, tracking
|
|
4825
|
-
* balanced parens and brackets, and stops at the next unbalanced `,` or `}`.
|
|
4826
|
-
*/
|
|
4827
|
-
function clearBootstrapScriptContent(src) {
|
|
4828
|
-
const idx = src.indexOf("\"bootstrapScriptContent\"");
|
|
4829
|
-
if (idx === -1) return src;
|
|
4830
|
-
const colonIdx = src.indexOf(":", idx + 24);
|
|
4831
|
-
if (colonIdx === -1) return src;
|
|
4832
|
-
let valStart = colonIdx + 1;
|
|
4833
|
-
while (valStart < src.length && /\s/.test(src[valStart])) valStart++;
|
|
4834
|
-
let i = valStart;
|
|
4835
|
-
let depth = 0;
|
|
4836
|
-
let inString = false;
|
|
4837
|
-
let stringChar = "";
|
|
4838
|
-
while (i < src.length) {
|
|
4839
|
-
const ch = src[i];
|
|
4840
|
-
if (inString) {
|
|
4841
|
-
if (ch === "\\") {
|
|
4842
|
-
i += 2;
|
|
4843
|
-
continue;
|
|
4844
|
-
}
|
|
4845
|
-
if (ch === stringChar) inString = false;
|
|
4846
|
-
} else if (ch === "\"" || ch === "'") {
|
|
4847
|
-
inString = true;
|
|
4848
|
-
stringChar = ch;
|
|
4849
|
-
} else if (ch === "(" || ch === "[") depth++;
|
|
4850
|
-
else if (ch === ")" || ch === "]") depth--;
|
|
4851
|
-
else if (depth === 0 && (ch === "," || ch === "}" || ch === "\n")) break;
|
|
4852
|
-
i++;
|
|
4853
|
-
}
|
|
4854
|
-
return src.slice(0, idx) + "\"bootstrapScriptContent\": \"\"" + src.slice(i);
|
|
4855
|
-
}
|
|
4856
|
-
/**
|
|
4857
|
-
* Strip JS references from the RSC plugin's assets manifest files.
|
|
4858
|
-
*
|
|
4859
|
-
* The RSC plugin writes `__vite_rsc_assets_manifest.js` to rsc/ and ssr/
|
|
4860
|
-
* as standalone files (not Rollup chunks), so generateBundle can't
|
|
4861
|
-
* intercept them. This rewrites the files on disk after all builds
|
|
4862
|
-
* complete but before the adapter copies them to the output directory.
|
|
4863
|
-
*/
|
|
4864
|
-
/**
|
|
4865
|
-
* Read the RSC plugin's assets manifest and merge per-route CSS and
|
|
4866
|
-
* per-route JS modulepreloads into the build manifest.
|
|
4867
|
-
*
|
|
4868
|
-
* CSS: `serverResources` maps server component paths to CSS URLs.
|
|
4869
|
-
* JS: `clientReferenceDeps` maps reference hashes to JS dep URLs.
|
|
4870
|
-
* Combined with `routeClientRefKeys` (from the RSC generateBundle
|
|
4871
|
-
* module graph walk) to produce per-route modulepreload entries.
|
|
4872
|
-
*/
|
|
4873
|
-
async function mergeRscAssetsManifest(buildDir, root, buildManifest, routeClientRefKeys) {
|
|
4874
|
-
const manifestPath = join(buildDir, "rsc", "__vite_rsc_assets_manifest.js");
|
|
4875
|
-
let content;
|
|
4876
|
-
try {
|
|
4877
|
-
content = await readFile(manifestPath, "utf-8");
|
|
4878
|
-
} catch {
|
|
4879
|
-
return;
|
|
4880
|
-
}
|
|
4881
|
-
const manifest = await parseRscManifest(manifestPath, content);
|
|
4882
|
-
if (!manifest) return;
|
|
4883
|
-
const serverResources = manifest.serverResources;
|
|
4884
|
-
if (serverResources) {
|
|
4885
|
-
for (const [relativePath, deps] of Object.entries(serverResources)) if (deps.css && deps.css.length > 0) {
|
|
4886
|
-
const absolutePath = join(root, relativePath);
|
|
4887
|
-
buildManifest.css[absolutePath] = deps.css;
|
|
4888
|
-
}
|
|
4889
|
-
}
|
|
4890
|
-
if (routeClientRefKeys && routeClientRefKeys.size > 0) {
|
|
4891
|
-
const clientReferenceDeps = manifest.clientReferenceDeps;
|
|
4892
|
-
if (clientReferenceDeps) for (const [filePath, refKeys] of routeClientRefKeys) {
|
|
4893
|
-
const jsUrls = /* @__PURE__ */ new Set();
|
|
4894
|
-
for (const key of refKeys) {
|
|
4895
|
-
const deps = clientReferenceDeps[key];
|
|
4896
|
-
if (deps?.js) for (const url of deps.js) jsUrls.add(url);
|
|
4897
|
-
}
|
|
4898
|
-
if (jsUrls.size > 0) buildManifest.modulepreload[filePath] = Array.from(jsUrls);
|
|
4899
|
-
}
|
|
4900
|
-
}
|
|
4901
|
-
}
|
|
4902
|
-
async function stripJsFromRscAssetsManifests(buildDir) {
|
|
4903
|
-
const manifestName = "__vite_rsc_assets_manifest.js";
|
|
4904
|
-
const paths = [join(buildDir, "rsc", manifestName), join(buildDir, "ssr", manifestName)];
|
|
4905
|
-
for (const path of paths) {
|
|
4906
|
-
let content;
|
|
4907
|
-
try {
|
|
4908
|
-
content = await readFile(path, "utf-8");
|
|
4909
|
-
} catch {
|
|
4910
|
-
continue;
|
|
4911
|
-
}
|
|
4912
|
-
const jsonStr = content.replace(/^export default\s*/, "").replace(/;?\s*$/, "");
|
|
4913
|
-
let isStrictJson = true;
|
|
4914
|
-
let manifest = null;
|
|
4915
|
-
try {
|
|
4916
|
-
manifest = JSON.parse(jsonStr);
|
|
4917
|
-
} catch {
|
|
4918
|
-
isStrictJson = false;
|
|
4919
|
-
}
|
|
4920
|
-
if (!isStrictJson) {
|
|
4921
|
-
let rewritten = content;
|
|
4922
|
-
rewritten = clearJsArrays(rewritten);
|
|
4923
|
-
rewritten = clearBootstrapScriptContent(rewritten);
|
|
4924
|
-
await writeFile(path, rewritten);
|
|
4925
|
-
continue;
|
|
4926
|
-
}
|
|
4927
|
-
const deps = manifest?.clientReferenceDeps;
|
|
4928
|
-
if (deps) for (const entry of Object.values(deps)) entry.js = [];
|
|
4929
|
-
if (manifest) manifest.bootstrapScriptContent = "";
|
|
4930
|
-
await writeFile(path, `export default ${JSON.stringify(manifest, null, 2)};\n`);
|
|
4931
|
-
}
|
|
4932
|
-
}
|
|
4933
4753
|
//#endregion
|
|
4934
4754
|
//#region src/server/flight-scripts.ts
|
|
4935
4755
|
/**
|
|
@@ -5012,12 +4832,6 @@ function generateRedirectsFile(redirects, base) {
|
|
|
5012
4832
|
const target = (to) => to.startsWith("/") && !to.startsWith("//") ? withBasePath(base, to) : to;
|
|
5013
4833
|
return redirects.map((r) => `${withBasePath(base, r.from)} ${target(r.to)} ${r.status}`).join("\n") + "\n";
|
|
5014
4834
|
}
|
|
5015
|
-
/** Write a file atomically: temp sibling + rename. */
|
|
5016
|
-
async function writeFileAtomic$1(path, data) {
|
|
5017
|
-
const tmp = `${path}.tmp`;
|
|
5018
|
-
await writeFile(tmp, data);
|
|
5019
|
-
await rename(tmp, path);
|
|
5020
|
-
}
|
|
5021
4835
|
/**
|
|
5022
4836
|
* Determine the output file path for a static page entry.
|
|
5023
4837
|
*
|
|
@@ -5056,7 +4870,7 @@ function staticOutputPath(entry) {
|
|
|
5056
4870
|
* API route, `about/index.html` from a page). The filesystem does refuse that
|
|
5057
4871
|
* one — `EISDIR` on the rename, `ENOTDIR` on the mkdir, depending on which
|
|
5058
4872
|
* lands second — but an errno names a path, and in the rename case the path
|
|
5059
|
-
* it names is
|
|
4873
|
+
* it names is the write's temp file. Reported here instead, so the message says which
|
|
5060
4874
|
* two routes.
|
|
5061
4875
|
*
|
|
5062
4876
|
* Collisions are **collected, not thrown**. `onEntry` runs inside the
|
|
@@ -5145,7 +4959,7 @@ var StaticSiteWriter = class {
|
|
|
5145
4959
|
if (rel.split(/[\\/]/)[0] === ".." || isAbsolute(rel) || resolve(this.staticDir, rel) !== fullPath) throw new Error(`[timber] Static generation: output path "${relPath}" escapes the static output directory — check generateStaticSegmentParams for path traversal characters in ${entry.urlPath}`);
|
|
5146
4960
|
if (!this.paths.claim(rel.replace(/\\/g, "/"), entry)) return;
|
|
5147
4961
|
await mkdir(dirname(fullPath), { recursive: true });
|
|
5148
|
-
await writeFileAtomic
|
|
4962
|
+
await writeFileAtomic(fullPath, entry.body);
|
|
5149
4963
|
if (entry.kind === "api" && !extname(relPath) && entry.contentType) this.contentTypes[entry.urlPath] = entry.contentType;
|
|
5150
4964
|
}
|
|
5151
4965
|
/** Throw if any two entries could not both be written. */
|
|
@@ -5173,7 +4987,7 @@ var StaticSiteWriter = class {
|
|
|
5173
4987
|
* @internal Exported for testing.
|
|
5174
4988
|
*/
|
|
5175
4989
|
async function cleanConditionalArtifacts(staticDir) {
|
|
5176
|
-
await rm(join(staticDir,
|
|
4990
|
+
await rm(join(staticDir, RSC_PAYLOAD_DIR), {
|
|
5177
4991
|
recursive: true,
|
|
5178
4992
|
force: true
|
|
5179
4993
|
}).catch(() => {});
|
|
@@ -5219,19 +5033,21 @@ async function withSchedulerPortsReleased(fn) {
|
|
|
5219
5033
|
}
|
|
5220
5034
|
}
|
|
5221
5035
|
/**
|
|
5222
|
-
* Load the built RSC entry and run the static generation pass
|
|
5036
|
+
* Load the built RSC entry and run the static generation pass — the static
|
|
5037
|
+
* generation step of the post-build phase (plugins/post-build.ts).
|
|
5223
5038
|
*
|
|
5224
|
-
*
|
|
5039
|
+
* The build manifest it renders with is already final: the phase merged the
|
|
5040
|
+
* RSC assets manifest into it and published it before this step. Unlike
|
|
5041
|
+
* prebuilt capture, this needs the FULL pipeline handler, so
|
|
5225
5042
|
* __TIMBER_CAPTURE_MODE__ must be false.
|
|
5043
|
+
*
|
|
5044
|
+
* Returns the site only once it is complete, so an adapter is never handed a
|
|
5045
|
+
* directory a failed pass left half-written — a failure throws instead.
|
|
5226
5046
|
*/
|
|
5227
|
-
async function runStaticGeneration(ctx) {
|
|
5228
|
-
const entryPath = join(
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
if (ctx.buildManifest) g.__TIMBER_BUILD_MANIFEST__ ??= ctx.buildManifest;
|
|
5232
|
-
if (ctx.deploymentId) g.__TIMBER_DEPLOYMENT_ID__ ??= ctx.deploymentId;
|
|
5233
|
-
g.__TIMBER_CAPTURE_MODE__ = false;
|
|
5234
|
-
if (ctx.buildManifest) await mergeRscAssetsManifest(ctx.buildDir, ctx.root, ctx.buildManifest, ctx.routeClientRefKeys);
|
|
5047
|
+
async function runStaticGeneration(ctx, rscDir) {
|
|
5048
|
+
const entryPath = join(rscDir, "index.js");
|
|
5049
|
+
warnUnusableBase(ctx);
|
|
5050
|
+
globalThis.__TIMBER_CAPTURE_MODE__ = false;
|
|
5235
5051
|
console.log("[timber] Static generation: building site…");
|
|
5236
5052
|
const staticDir = join(ctx.buildDir, "static-pages");
|
|
5237
5053
|
await cleanConditionalArtifacts(staticDir);
|
|
@@ -5265,12 +5081,12 @@ async function runStaticGeneration(ctx) {
|
|
|
5265
5081
|
throw new Error(`[timber] Static generation failed:\n${details}`);
|
|
5266
5082
|
}
|
|
5267
5083
|
writer.assertNoCollisions();
|
|
5268
|
-
|
|
5084
|
+
const immutableDirs = [];
|
|
5269
5085
|
if (!ctx.clientJavascript.disabled) {
|
|
5270
5086
|
const rscManifest = await hashRscPayloads(staticDir);
|
|
5271
5087
|
if (Object.keys(rscManifest).length > 0) {
|
|
5088
|
+
immutableDirs.push(RSC_PAYLOAD_DIR);
|
|
5272
5089
|
await injectRscManifestIntoHtml(staticDir, rscManifest);
|
|
5273
|
-
ctx.rscManifest = rscManifest;
|
|
5274
5090
|
console.log(`[timber] Static generation: hashed ${Object.keys(rscManifest).length} RSC flight payloads`);
|
|
5275
5091
|
}
|
|
5276
5092
|
}
|
|
@@ -5279,14 +5095,18 @@ async function runStaticGeneration(ctx) {
|
|
|
5279
5095
|
const redirectsPath = join(staticDir, REDIRECTS_FILE);
|
|
5280
5096
|
const userRedirects = await readUserRedirects(ctx.root);
|
|
5281
5097
|
if (userRedirects !== null) {
|
|
5282
|
-
await writeFileAtomic
|
|
5098
|
+
await writeFileAtomic(redirectsPath, generated + "\n" + userRedirects);
|
|
5283
5099
|
console.log(`[timber] Static generation: wrote _redirects with ${summary.redirects.length} generated rule(s), merged with user-authored _redirects`);
|
|
5284
5100
|
} else {
|
|
5285
|
-
await writeFileAtomic
|
|
5101
|
+
await writeFileAtomic(redirectsPath, generated);
|
|
5286
5102
|
console.log(`[timber] Static generation: wrote _redirects with ${summary.redirects.length} rule(s)`);
|
|
5287
5103
|
}
|
|
5288
5104
|
}
|
|
5289
|
-
return
|
|
5105
|
+
return {
|
|
5106
|
+
pages: { path: staticDir },
|
|
5107
|
+
contentTypes: writer.contentTypes,
|
|
5108
|
+
immutableDirs
|
|
5109
|
+
};
|
|
5290
5110
|
}
|
|
5291
5111
|
/**
|
|
5292
5112
|
* Warn when Vite's `base` is document-relative (`'./'`) in static mode.
|
|
@@ -5359,7 +5179,7 @@ async function walkDir(dir) {
|
|
|
5359
5179
|
* @internal Exported for testing.
|
|
5360
5180
|
*/
|
|
5361
5181
|
async function hashRscPayloads(staticDir) {
|
|
5362
|
-
const files = await walkDir(join(staticDir,
|
|
5182
|
+
const files = await walkDir(join(staticDir, RSC_PAYLOAD_DIR));
|
|
5363
5183
|
const manifest = {};
|
|
5364
5184
|
for (const filePath of files) {
|
|
5365
5185
|
if (!filePath.endsWith(".rsc")) continue;
|
|
@@ -5407,11 +5227,9 @@ async function readUserRedirects(root) {
|
|
|
5407
5227
|
/**
|
|
5408
5228
|
* Create the timber-static-build Vite plugin.
|
|
5409
5229
|
*
|
|
5410
|
-
* Only active when output: 'static' is configured.
|
|
5411
|
-
*
|
|
5412
|
-
*
|
|
5413
|
-
* - transform: Validates source files for static mode violations
|
|
5414
|
-
* - buildApp (post): Renders all routes to static HTML after the build
|
|
5230
|
+
* Only active when output: 'static' is configured. Validates source files
|
|
5231
|
+
* for static mode violations; rendering the site is `runStaticGeneration`,
|
|
5232
|
+
* which the post-build phase calls.
|
|
5415
5233
|
*/
|
|
5416
5234
|
function timberStaticBuild(ctx) {
|
|
5417
5235
|
return {
|
|
@@ -5433,22 +5251,6 @@ function timberStaticBuild(ctx) {
|
|
|
5433
5251
|
this.error(messages.join("\n\n"));
|
|
5434
5252
|
}
|
|
5435
5253
|
return null;
|
|
5436
|
-
},
|
|
5437
|
-
/**
|
|
5438
|
-
* After all environments are built, render every route to static HTML.
|
|
5439
|
-
*
|
|
5440
|
-
* Runs with order: 'post' so the RSC plugin's buildApp completes first,
|
|
5441
|
-
* producing the built entry we import. Must run BEFORE the adapter
|
|
5442
|
-
* build copies output to its platform-specific directory.
|
|
5443
|
-
*/
|
|
5444
|
-
buildApp: {
|
|
5445
|
-
order: "post",
|
|
5446
|
-
async handler() {
|
|
5447
|
-
if (ctx.dev) return;
|
|
5448
|
-
if (!(ctx.config.output === "static")) return;
|
|
5449
|
-
warnUnusableBase(ctx);
|
|
5450
|
-
await runStaticGeneration(ctx);
|
|
5451
|
-
}
|
|
5452
5254
|
}
|
|
5453
5255
|
};
|
|
5454
5256
|
}
|
|
@@ -5658,8 +5460,6 @@ function timberBuildManifest(ctx) {
|
|
|
5658
5460
|
if (ctx.requestDepMap === void 0) throw new Error("[timber] Build manifest: the request-dependency map was never computed. The RSC environment's buildEnd hook did not run before the client build, so no segment or slot could be skipped on client navigation. This is a plugin pipeline bug — timber-request-dep must run in the rsc environment.");
|
|
5659
5461
|
ctx.buildManifest.requestDep = ctx.requestDepMap;
|
|
5660
5462
|
if (ctx.clientJavascript.disabled) {
|
|
5661
|
-
ctx.buildManifest.js = {};
|
|
5662
|
-
ctx.buildManifest.modulepreload = {};
|
|
5663
5463
|
for (const [fileName, item] of Object.entries(bundle)) if (item.type === "chunk") delete bundle[fileName];
|
|
5664
5464
|
}
|
|
5665
5465
|
}
|
|
@@ -5989,6 +5789,106 @@ function timberReactProd() {
|
|
|
5989
5789
|
};
|
|
5990
5790
|
}
|
|
5991
5791
|
//#endregion
|
|
5792
|
+
//#region src/plugins/react-resolve.ts
|
|
5793
|
+
/**
|
|
5794
|
+
* timber-react-resolve — Deduplicate React across timber and user project.
|
|
5795
|
+
*
|
|
5796
|
+
* Without this plugin, pnpm's strict isolation can install two physical
|
|
5797
|
+
* copies of React when the user's pinned version differs from timber's
|
|
5798
|
+
* peer dep. Timber's 47 bare `from 'react'` imports resolve to one copy
|
|
5799
|
+
* while react-dom uses the other — causing "Invalid hook call" hydration
|
|
5800
|
+
* crashes with no indication of the real cause.
|
|
5801
|
+
*
|
|
5802
|
+
* The fix: inject `resolve.dedupe` entries so Vite always resolves React
|
|
5803
|
+
* packages from the project root. Unlike `resolve.alias`, `dedupe`
|
|
5804
|
+
* preserves Vite's per-environment export conditions — the RSC
|
|
5805
|
+
* environment still gets the `react-server` build, SSR gets the SSR
|
|
5806
|
+
* build, and the browser gets the browser build. The deduplication
|
|
5807
|
+
* happens at the package level, not the file level.
|
|
5808
|
+
*
|
|
5809
|
+
* A `configResolved` check detects version mismatches between timber's
|
|
5810
|
+
* resolved React and the project's React, and logs an actionable error.
|
|
5811
|
+
*
|
|
5812
|
+
* Design doc: 18-build-system.md §"Module Resolution"
|
|
5813
|
+
* Task: TIM-1520
|
|
5814
|
+
*/
|
|
5815
|
+
/**
|
|
5816
|
+
* React packages to deduplicate. Vite's `resolve.dedupe` extracts the
|
|
5817
|
+
* base package name (via `deepImportRE`) before checking, so subpath
|
|
5818
|
+
* specifiers like `react/jsx-runtime` are covered by the base `react`
|
|
5819
|
+
* entry — listing them separately has no effect.
|
|
5820
|
+
*/
|
|
5821
|
+
var REACT_DEDUPE_PACKAGES = ["react", "react-dom"];
|
|
5822
|
+
var RED = "\x1B[31m";
|
|
5823
|
+
var BOLD = "\x1B[1m";
|
|
5824
|
+
var DIM = "\x1B[2m";
|
|
5825
|
+
var RESET = "\x1B[0m";
|
|
5826
|
+
/**
|
|
5827
|
+
* Read the version from a package's package.json given a resolve root.
|
|
5828
|
+
*/
|
|
5829
|
+
function readPackageVersion(packageName, resolveRoot) {
|
|
5830
|
+
try {
|
|
5831
|
+
const req = createRequire(`${resolveRoot}/package.json`);
|
|
5832
|
+
return req(req.resolve(`${packageName}/package.json`)).version ?? null;
|
|
5833
|
+
} catch {
|
|
5834
|
+
return null;
|
|
5835
|
+
}
|
|
5836
|
+
}
|
|
5837
|
+
/**
|
|
5838
|
+
* Check whether timber's React and the user project's React resolve to
|
|
5839
|
+
* the same version. Returns mismatches if any.
|
|
5840
|
+
*/
|
|
5841
|
+
function detectReactMismatch(projectRoot) {
|
|
5842
|
+
const mismatches = [];
|
|
5843
|
+
const timberRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
5844
|
+
for (const pkg of ["react", "react-dom"]) {
|
|
5845
|
+
const timberVersion = readPackageVersion(pkg, timberRoot);
|
|
5846
|
+
const projectVersion = readPackageVersion(pkg, projectRoot);
|
|
5847
|
+
if (timberVersion && projectVersion && timberVersion !== projectVersion) mismatches.push({
|
|
5848
|
+
specifier: pkg,
|
|
5849
|
+
timberVersion,
|
|
5850
|
+
projectVersion
|
|
5851
|
+
});
|
|
5852
|
+
}
|
|
5853
|
+
return mismatches;
|
|
5854
|
+
}
|
|
5855
|
+
/**
|
|
5856
|
+
* Format React version mismatches as an actionable warning.
|
|
5857
|
+
*/
|
|
5858
|
+
function formatReactMismatch(mismatches) {
|
|
5859
|
+
if (mismatches.length === 0) return "";
|
|
5860
|
+
const lines = [];
|
|
5861
|
+
lines.push(`${RED}${BOLD}[timber]${RESET} ${RED}React version mismatch detected — this causes silent hydration crashes${RESET}`);
|
|
5862
|
+
lines.push("");
|
|
5863
|
+
for (const m of mismatches) lines.push(` ${RED}✗${RESET} ${m.specifier}: timber has ${BOLD}${m.timberVersion}${RESET}, project has ${BOLD}${m.projectVersion}${RESET}`);
|
|
5864
|
+
lines.push("");
|
|
5865
|
+
lines.push(` ${DIM}This typically causes "Invalid hook call" errors because two copies of${RESET}`);
|
|
5866
|
+
lines.push(` ${DIM}React are loaded. timber's resolve.dedupe should handle this, but${RESET}`);
|
|
5867
|
+
lines.push(` ${DIM}if you see hook errors, ensure your React version satisfies timber's peer dep.${RESET}`);
|
|
5868
|
+
lines.push("");
|
|
5869
|
+
lines.push(` ${DIM}Fix: update React in your project to match —${RESET}`);
|
|
5870
|
+
lines.push(` ${BOLD}pnpm add react@${mismatches[0].timberVersion} react-dom@${mismatches[0].timberVersion}${RESET}`);
|
|
5871
|
+
return lines.join("\n");
|
|
5872
|
+
}
|
|
5873
|
+
/**
|
|
5874
|
+
* Create the timber-react-resolve Vite plugin.
|
|
5875
|
+
*/
|
|
5876
|
+
function timberReactResolve() {
|
|
5877
|
+
return {
|
|
5878
|
+
name: "timber-react-resolve",
|
|
5879
|
+
enforce: "pre",
|
|
5880
|
+
config(userConfig) {
|
|
5881
|
+
const merged = [...userConfig.resolve?.dedupe ?? []];
|
|
5882
|
+
for (const pkg of REACT_DEDUPE_PACKAGES) if (!merged.includes(pkg)) merged.push(pkg);
|
|
5883
|
+
return { resolve: { dedupe: merged } };
|
|
5884
|
+
},
|
|
5885
|
+
configResolved(resolved) {
|
|
5886
|
+
const mismatches = detectReactMismatch(resolved.root);
|
|
5887
|
+
if (mismatches.length > 0) process.stderr.write(`${formatReactMismatch(mismatches)}\n\n`);
|
|
5888
|
+
}
|
|
5889
|
+
};
|
|
5890
|
+
}
|
|
5891
|
+
//#endregion
|
|
5992
5892
|
//#region src/plugins/chunks.ts
|
|
5993
5893
|
/**
|
|
5994
5894
|
* Build a map from absolute module IDs in non-facade RSC chunks to the
|
|
@@ -7741,8 +7641,8 @@ function mayPrerender(call) {
|
|
|
7741
7641
|
/**
|
|
7742
7642
|
* Post-build prebuilt capture — Node-side orchestration (TIM-1119).
|
|
7743
7643
|
*
|
|
7744
|
-
* Runs
|
|
7745
|
-
* build sequence. Imports the BUILT `rsc/index.js` (the bundle carries
|
|
7644
|
+
* Runs as the capture step of the post-build phase (plugins/post-build.ts),
|
|
7645
|
+
* after Vite's 5-step build sequence and the manifest finalization step. Imports the BUILT `rsc/index.js` (the bundle carries
|
|
7746
7646
|
* the react-server condition resolved at build time, so a plain dynamic
|
|
7747
7647
|
* import works) and calls its `__timber_capturePrebuilt` export — the
|
|
7748
7648
|
* capture itself must run inside the bundle's module graph, where the
|
|
@@ -7771,12 +7671,6 @@ function mayPrerender(call) {
|
|
|
7771
7671
|
*/
|
|
7772
7672
|
var COMPONENT_ID_RE = /^[a-z0-9]+_[0-9a-f]{16}$/;
|
|
7773
7673
|
var CACHE_KEY_RE = /^[0-9a-f]{16}$/;
|
|
7774
|
-
/** Write a file atomically: temp sibling + rename. */
|
|
7775
|
-
async function writeFileAtomic(path, data) {
|
|
7776
|
-
const tmp = `${path}.tmp`;
|
|
7777
|
-
await writeFile(tmp, data);
|
|
7778
|
-
await rename(tmp, path);
|
|
7779
|
-
}
|
|
7780
7674
|
/**
|
|
7781
7675
|
* Create the writer for `.timber/dist/prebuilt/`. Storage layout per
|
|
7782
7676
|
* design/44 §Storage: one directory per component ID, one `.flight` file
|
|
@@ -7818,7 +7712,7 @@ function createPrebuiltArtifactWriter(prebuiltDir) {
|
|
|
7818
7712
|
* make adapters ship payloads from an OLD build — reviving them serves
|
|
7819
7713
|
* outdated content with that build's chunk references instead of the
|
|
7820
7714
|
* intended miss → live render. Runs unconditionally at the start of the
|
|
7821
|
-
*
|
|
7715
|
+
* capture step, BEFORE the capture decision: a build whose app no
|
|
7822
7716
|
* longer declares any prebuilt components must also shed the artifacts
|
|
7823
7717
|
* (codex P2 on PR #836).
|
|
7824
7718
|
*/
|
|
@@ -7835,19 +7729,16 @@ async function cleanPrebuiltDir(buildDir) {
|
|
|
7835
7729
|
* component). Per-entry data errors skip-and-report per design/44
|
|
7836
7730
|
* §Build-Phase Error Handling.
|
|
7837
7731
|
*/
|
|
7838
|
-
async function runPrebuiltCapture(ctx) {
|
|
7732
|
+
async function runPrebuiltCapture(ctx, rscDir) {
|
|
7839
7733
|
const routeComponents = ctx.routePrebuiltComponents;
|
|
7840
|
-
if (!routeComponents || routeComponents.size === 0) return {
|
|
7734
|
+
if (!routeComponents || routeComponents.size === 0) return { summary: {
|
|
7841
7735
|
captured: 0,
|
|
7842
7736
|
skipped: [],
|
|
7843
7737
|
hardErrors: [],
|
|
7844
7738
|
nestingWarnings: 0
|
|
7845
|
-
};
|
|
7846
|
-
const entryPath = join(
|
|
7847
|
-
if (!existsSync(entryPath)) throw new Error(`[timber] prebuilt capture: built RSC entry not found at ${entryPath} — the app declares cache.component({ prerender: true }) call sites but the RSC build output is missing`);
|
|
7739
|
+
} };
|
|
7740
|
+
const entryPath = join(rscDir, "index.js");
|
|
7848
7741
|
const g = globalThis;
|
|
7849
|
-
if (ctx.buildManifest) g.__TIMBER_BUILD_MANIFEST__ ??= ctx.buildManifest;
|
|
7850
|
-
if (ctx.deploymentId) g.__TIMBER_DEPLOYMENT_ID__ ??= ctx.deploymentId;
|
|
7851
7742
|
console.log("[timber] cache.component: capturing prebuilt flight payloads…");
|
|
7852
7743
|
g.__TIMBER_CAPTURE_MODE__ = true;
|
|
7853
7744
|
let mod;
|
|
@@ -7861,7 +7752,8 @@ async function runPrebuiltCapture(ctx) {
|
|
|
7861
7752
|
}
|
|
7862
7753
|
const capture = mod.__timber_capturePrebuilt;
|
|
7863
7754
|
if (typeof capture !== "function") throw new Error("[timber] prebuilt capture: built RSC entry does not export __timber_capturePrebuilt — the build output predates this framework version; rebuild from a clean .timber/dist");
|
|
7864
|
-
const
|
|
7755
|
+
const prebuiltDir = join(ctx.buildDir, "prebuilt");
|
|
7756
|
+
const writer = createPrebuiltArtifactWriter(prebuiltDir);
|
|
7865
7757
|
const summary = await capture({
|
|
7866
7758
|
fileComponentMap: Object.fromEntries(routeComponents),
|
|
7867
7759
|
callSiteProps: ctx.prebuiltCallSiteProps ? Object.fromEntries(ctx.prebuiltCallSiteProps) : void 0,
|
|
@@ -7872,10 +7764,13 @@ async function runPrebuiltCapture(ctx) {
|
|
|
7872
7764
|
const details = summary.hardErrors.map((issue) => ` - ${issue.message}`).join("\n");
|
|
7873
7765
|
throw new Error(`[timber] prebuilt capture failed: ${summary.hardErrors.length} component(s) read per-request context at build time:\n${details}`);
|
|
7874
7766
|
}
|
|
7875
|
-
await writer.finalize();
|
|
7767
|
+
const written = await writer.finalize();
|
|
7876
7768
|
const total = summary.captured + summary.skipped.length;
|
|
7877
7769
|
console.log(`[timber] Prebuilt ${summary.captured}/${total} entries.` + (summary.skipped.length > 0 ? ` ${summary.skipped.length} skipped due to errors.` : ""));
|
|
7878
|
-
return
|
|
7770
|
+
return written > 0 ? {
|
|
7771
|
+
summary,
|
|
7772
|
+
artifact: { path: prebuiltDir }
|
|
7773
|
+
} : { summary };
|
|
7879
7774
|
}
|
|
7880
7775
|
//#endregion
|
|
7881
7776
|
//#region src/plugins/prebuilt.ts
|
|
@@ -8049,8 +7944,7 @@ function collectPageAndLayoutFiles(root) {
|
|
|
8049
7944
|
return files;
|
|
8050
7945
|
}
|
|
8051
7946
|
var DEFAULT_SENTINEL = "\0default";
|
|
8052
|
-
async function collectCrossModuleProps(ctx, moduleId, getInfo, resolve) {
|
|
8053
|
-
const bindingNames = ctx.prebuiltBindingNames;
|
|
7947
|
+
async function collectCrossModuleProps(ctx, bindingNames, moduleId, getInfo, resolve) {
|
|
8054
7948
|
const info = getInfo(moduleId);
|
|
8055
7949
|
if (!info) return;
|
|
8056
7950
|
const declaringImports = info.importedIds.filter((id) => bindingNames.has(id) && id !== moduleId);
|
|
@@ -8118,10 +8012,34 @@ async function collectCrossModuleProps(ctx, moduleId, getInfo, resolve) {
|
|
|
8118
8012
|
}
|
|
8119
8013
|
}
|
|
8120
8014
|
function timberPrebuilt(ctx) {
|
|
8015
|
+
/**
|
|
8016
|
+
* Module ID → prerender-capable component IDs declared in it. Recorded by
|
|
8017
|
+
* the RSC transform, read by the RSC `generateBundle` module-graph walk
|
|
8018
|
+
* that computes `ctx.routePrebuiltComponents`. Build only.
|
|
8019
|
+
*/
|
|
8020
|
+
const moduleComponents = /* @__PURE__ */ new Map();
|
|
8021
|
+
/**
|
|
8022
|
+
* Module ID → variable name → component ID, for the prebuilt components
|
|
8023
|
+
* that module declares. Read at `generateBundle` time to trace imports in
|
|
8024
|
+
* other modules back to component IDs (cross-module call-site props).
|
|
8025
|
+
*/
|
|
8026
|
+
const bindingNames = /* @__PURE__ */ new Map();
|
|
8121
8027
|
return {
|
|
8122
8028
|
name: "timber-prebuilt",
|
|
8029
|
+
api: { async capture(rscDir) {
|
|
8030
|
+
await cleanPrebuiltDir(ctx.buildDir);
|
|
8031
|
+
if (!ctx.routePrebuiltComponents || ctx.routePrebuiltComponents.size === 0) return null;
|
|
8032
|
+
if (ctx.config.output === "static") {
|
|
8033
|
+
console.log(`[timber] cache.component: skipped prerender capture (output: 'static' renders all components at build time)`);
|
|
8034
|
+
return null;
|
|
8035
|
+
}
|
|
8036
|
+
return runPrebuiltCapture(ctx, rscDir);
|
|
8037
|
+
} },
|
|
8123
8038
|
transform(code, id) {
|
|
8124
|
-
if (!ctx.dev && this?.environment?.name === "rsc")
|
|
8039
|
+
if (!ctx.dev && this?.environment?.name === "rsc") {
|
|
8040
|
+
moduleComponents.delete(id);
|
|
8041
|
+
bindingNames.delete(id);
|
|
8042
|
+
}
|
|
8125
8043
|
if (!code.includes("@timber-js/app/cache") && !code.includes("timber/cache")) return;
|
|
8126
8044
|
if (id.includes("node_modules")) return;
|
|
8127
8045
|
if (this?.environment?.name === "client") return;
|
|
@@ -8153,8 +8071,7 @@ function timberPrebuilt(ctx) {
|
|
|
8153
8071
|
s.appendLeft(call.arguments[0].start, `${JSON.stringify(firstArg)}, `);
|
|
8154
8072
|
}
|
|
8155
8073
|
if (!ctx.dev && componentIds.length > 0 && this?.environment?.name === "rsc") {
|
|
8156
|
-
|
|
8157
|
-
ctx.prebuiltModuleComponents.set(id, componentIds);
|
|
8074
|
+
moduleComponents.set(id, componentIds);
|
|
8158
8075
|
const bindingMap = /* @__PURE__ */ new Map();
|
|
8159
8076
|
let componentIdIdx = 0;
|
|
8160
8077
|
for (const { call, stmt, displayName } of callSites) if (!ctx.dev && mayPrerender(call)) {
|
|
@@ -8174,10 +8091,7 @@ function timberPrebuilt(ctx) {
|
|
|
8174
8091
|
}
|
|
8175
8092
|
}
|
|
8176
8093
|
}
|
|
8177
|
-
if (bindingMap.size > 0)
|
|
8178
|
-
ctx.prebuiltBindingNames ??= /* @__PURE__ */ new Map();
|
|
8179
|
-
ctx.prebuiltBindingNames.set(id, bindingMap);
|
|
8180
|
-
}
|
|
8094
|
+
if (bindingMap.size > 0) bindingNames.set(id, bindingMap);
|
|
8181
8095
|
const declaredBindings = new Set([...bindingMap.keys()].filter((k) => k !== DEFAULT_SENTINEL));
|
|
8182
8096
|
if (declaredBindings.size > 0) {
|
|
8183
8097
|
const usages = collectJsxUsages(program, declaredBindings);
|
|
@@ -8208,8 +8122,8 @@ function timberPrebuilt(ctx) {
|
|
|
8208
8122
|
if (ctx.dev) return;
|
|
8209
8123
|
if (this?.environment?.name !== "rsc") return;
|
|
8210
8124
|
ctx.routePrebuiltComponents = void 0;
|
|
8211
|
-
|
|
8212
|
-
if (
|
|
8125
|
+
ctx.prebuiltLazyChunks = void 0;
|
|
8126
|
+
if (moduleComponents.size === 0 || !ctx.routeTree) return;
|
|
8213
8127
|
const self = this;
|
|
8214
8128
|
const getInfo = (id) => self.getModuleInfo?.(id) ?? null;
|
|
8215
8129
|
const resolveFn = async (source, importer) => {
|
|
@@ -8237,7 +8151,7 @@ function timberPrebuilt(ctx) {
|
|
|
8237
8151
|
}
|
|
8238
8152
|
if (lazyChunks.size > 0) ctx.prebuiltLazyChunks = lazyChunks;
|
|
8239
8153
|
}
|
|
8240
|
-
if (
|
|
8154
|
+
if (bindingNames.size > 0) {
|
|
8241
8155
|
const scannedModules = /* @__PURE__ */ new Set();
|
|
8242
8156
|
for (const filePath of routeComponents.keys()) {
|
|
8243
8157
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -8248,7 +8162,7 @@ function timberPrebuilt(ctx) {
|
|
|
8248
8162
|
visited.add(modId);
|
|
8249
8163
|
if (!scannedModules.has(modId)) {
|
|
8250
8164
|
scannedModules.add(modId);
|
|
8251
|
-
await collectCrossModuleProps(ctx, modId, getInfo, resolveFn);
|
|
8165
|
+
await collectCrossModuleProps(ctx, bindingNames, modId, getInfo, resolveFn);
|
|
8252
8166
|
}
|
|
8253
8167
|
const modInfo = getInfo(modId);
|
|
8254
8168
|
if (!modInfo) continue;
|
|
@@ -8258,26 +8172,6 @@ function timberPrebuilt(ctx) {
|
|
|
8258
8172
|
}
|
|
8259
8173
|
}
|
|
8260
8174
|
} else console.warn(`[timber] cache.component: ${moduleComponents.size} module(s) declare prebuilt components, but none are reachable from any page or layout — no payloads will be prerendered`);
|
|
8261
|
-
},
|
|
8262
|
-
/**
|
|
8263
|
-
* Post-build capture (design/44 §Build Phase). `order: 'post'` runs
|
|
8264
|
-
* after the RSC plugin's buildApp — all five build steps are complete —
|
|
8265
|
-
* and BEFORE timber-adapter-build's post hook (plugin array order), so
|
|
8266
|
-
* `prebuilt/` exists when the adapter assembles its output (TIM-1122).
|
|
8267
|
-
*/
|
|
8268
|
-
buildApp: {
|
|
8269
|
-
order: "post",
|
|
8270
|
-
async handler() {
|
|
8271
|
-
if (ctx.dev) return;
|
|
8272
|
-
ctx.captureSummary = void 0;
|
|
8273
|
-
await cleanPrebuiltDir(ctx.buildDir);
|
|
8274
|
-
if (!ctx.routePrebuiltComponents || ctx.routePrebuiltComponents.size === 0) return;
|
|
8275
|
-
if (ctx.config.output === "static") {
|
|
8276
|
-
console.log(`[timber] cache.component: skipped prerender capture (output: 'static' renders all components at build time)`);
|
|
8277
|
-
return;
|
|
8278
|
-
}
|
|
8279
|
-
ctx.captureSummary = await runPrebuiltCapture(ctx);
|
|
8280
|
-
}
|
|
8281
8175
|
}
|
|
8282
8176
|
};
|
|
8283
8177
|
}
|
|
@@ -8430,8 +8324,6 @@ function timberPrerenderSugar(ctx) {
|
|
|
8430
8324
|
if (defaultExport.kind === "expression" && defaultExport.node.declaration) {
|
|
8431
8325
|
if (code.slice(defaultExport.node.declaration.start, defaultExport.node.declaration.end).includes(".component(")) return;
|
|
8432
8326
|
}
|
|
8433
|
-
ctx.prerenderSugarPages ??= /* @__PURE__ */ new Set();
|
|
8434
|
-
ctx.prerenderSugarPages.add(id);
|
|
8435
8327
|
const s = new MagicString(code);
|
|
8436
8328
|
const optionsSource = buildOptionsSource(value);
|
|
8437
8329
|
const importAlias = "__timber_prerender_cache__";
|
|
@@ -8568,6 +8460,378 @@ function timberCloudflareWasm(ctx) {
|
|
|
8568
8460
|
}];
|
|
8569
8461
|
}
|
|
8570
8462
|
//#endregion
|
|
8463
|
+
//#region src/plugins/rsc-assets-manifest.ts
|
|
8464
|
+
/**
|
|
8465
|
+
* The RSC plugin's assets manifest (`__vite_rsc_assets_manifest.js`) — read
|
|
8466
|
+
* into the build manifest, and stripped of JavaScript when client JS is off.
|
|
8467
|
+
*
|
|
8468
|
+
* The RSC plugin writes the file to rsc/ and ssr/ as a standalone file, not
|
|
8469
|
+
* a Rollup chunk, so no `generateBundle` can intercept it; both operations
|
|
8470
|
+
* work on the written files. Both run once, from the post-build phase's
|
|
8471
|
+
* manifest finalization step (plugins/post-build.ts), before anything
|
|
8472
|
+
* imports the built bundle.
|
|
8473
|
+
*
|
|
8474
|
+
* Design doc: 18-build-system.md §"Post-Build Phase"
|
|
8475
|
+
*/
|
|
8476
|
+
/**
|
|
8477
|
+
* Parse the RSC assets manifest at `manifestPath`. Tries JSON.parse first
|
|
8478
|
+
* (fast path for plain-string manifests); falls back to a dynamic import()
|
|
8479
|
+
* for manifests that contain runtime expressions from renderBuiltUrl.
|
|
8480
|
+
* Returns null if both paths fail.
|
|
8481
|
+
*/
|
|
8482
|
+
async function parseRscManifest(manifestPath, content) {
|
|
8483
|
+
const jsonStr = content.replace(/^export default\s*/, "").replace(/;?\s*$/, "");
|
|
8484
|
+
try {
|
|
8485
|
+
return JSON.parse(jsonStr);
|
|
8486
|
+
} catch {}
|
|
8487
|
+
try {
|
|
8488
|
+
return (await import(`${pathToFileURL(manifestPath).href}?t=${Date.now()}`)).default ?? null;
|
|
8489
|
+
} catch (err) {
|
|
8490
|
+
swallow(err, `failed to evaluate RSC assets manifest: ${manifestPath}`, { level: "warn" });
|
|
8491
|
+
return null;
|
|
8492
|
+
}
|
|
8493
|
+
}
|
|
8494
|
+
/**
|
|
8495
|
+
* Replace all `"js": [...]` array contents with `"js": []` using balanced
|
|
8496
|
+
* bracket matching. Handles nested brackets from runtime expressions like
|
|
8497
|
+
* `__rbu("path/to/[slug]/file.js")`.
|
|
8498
|
+
*/
|
|
8499
|
+
function clearJsArrays(src) {
|
|
8500
|
+
const pattern = /"js"\s*:\s*\[/g;
|
|
8501
|
+
let result = "";
|
|
8502
|
+
let lastEnd = 0;
|
|
8503
|
+
let match;
|
|
8504
|
+
while ((match = pattern.exec(src)) !== null) {
|
|
8505
|
+
const arrayStart = match.index + match[0].length;
|
|
8506
|
+
let depth = 1;
|
|
8507
|
+
let i = arrayStart;
|
|
8508
|
+
while (i < src.length && depth > 0) {
|
|
8509
|
+
if (src[i] === "[") depth++;
|
|
8510
|
+
else if (src[i] === "]") depth--;
|
|
8511
|
+
i++;
|
|
8512
|
+
}
|
|
8513
|
+
result += src.slice(lastEnd, match.index) + "\"js\": []";
|
|
8514
|
+
lastEnd = i;
|
|
8515
|
+
}
|
|
8516
|
+
result += src.slice(lastEnd);
|
|
8517
|
+
return result;
|
|
8518
|
+
}
|
|
8519
|
+
/**
|
|
8520
|
+
* Replace `"bootstrapScriptContent": <value>` with an empty string. The
|
|
8521
|
+
* value may be a JS expression (e.g., concatenation with runtime helpers),
|
|
8522
|
+
* not a simple string literal. Scans forward from the colon, tracking
|
|
8523
|
+
* balanced parens and brackets, and stops at the next unbalanced `,` or `}`.
|
|
8524
|
+
*/
|
|
8525
|
+
function clearBootstrapScriptContent(src) {
|
|
8526
|
+
const idx = src.indexOf("\"bootstrapScriptContent\"");
|
|
8527
|
+
if (idx === -1) return src;
|
|
8528
|
+
const colonIdx = src.indexOf(":", idx + 24);
|
|
8529
|
+
if (colonIdx === -1) return src;
|
|
8530
|
+
let valStart = colonIdx + 1;
|
|
8531
|
+
while (valStart < src.length && /\s/.test(src[valStart])) valStart++;
|
|
8532
|
+
let i = valStart;
|
|
8533
|
+
let depth = 0;
|
|
8534
|
+
let inString = false;
|
|
8535
|
+
let stringChar = "";
|
|
8536
|
+
while (i < src.length) {
|
|
8537
|
+
const ch = src[i];
|
|
8538
|
+
if (inString) {
|
|
8539
|
+
if (ch === "\\") {
|
|
8540
|
+
i += 2;
|
|
8541
|
+
continue;
|
|
8542
|
+
}
|
|
8543
|
+
if (ch === stringChar) inString = false;
|
|
8544
|
+
} else if (ch === "\"" || ch === "'") {
|
|
8545
|
+
inString = true;
|
|
8546
|
+
stringChar = ch;
|
|
8547
|
+
} else if (ch === "(" || ch === "[") depth++;
|
|
8548
|
+
else if (ch === ")" || ch === "]") depth--;
|
|
8549
|
+
else if (depth === 0 && (ch === "," || ch === "}" || ch === "\n")) break;
|
|
8550
|
+
i++;
|
|
8551
|
+
}
|
|
8552
|
+
return src.slice(0, idx) + "\"bootstrapScriptContent\": \"\"" + src.slice(i);
|
|
8553
|
+
}
|
|
8554
|
+
/**
|
|
8555
|
+
* Read the RSC plugin's assets manifest and merge per-route CSS and
|
|
8556
|
+
* per-route JS modulepreloads into the build manifest.
|
|
8557
|
+
*
|
|
8558
|
+
* CSS: `serverResources` maps server component paths to CSS URLs.
|
|
8559
|
+
* JS: `clientReferenceDeps` maps reference hashes to JS dep URLs.
|
|
8560
|
+
* Combined with `routeClientRefKeys` (from the RSC generateBundle
|
|
8561
|
+
* module graph walk) to produce per-route modulepreload entries.
|
|
8562
|
+
*/
|
|
8563
|
+
async function mergeRscAssetsManifest(rscDir, root, buildManifest, routeClientRefKeys) {
|
|
8564
|
+
const manifestPath = join(rscDir, "__vite_rsc_assets_manifest.js");
|
|
8565
|
+
let content;
|
|
8566
|
+
try {
|
|
8567
|
+
content = await readFile(manifestPath, "utf-8");
|
|
8568
|
+
} catch {
|
|
8569
|
+
return;
|
|
8570
|
+
}
|
|
8571
|
+
const manifest = await parseRscManifest(manifestPath, content);
|
|
8572
|
+
if (!manifest) return;
|
|
8573
|
+
const serverResources = manifest.serverResources;
|
|
8574
|
+
if (serverResources) {
|
|
8575
|
+
for (const [relativePath, deps] of Object.entries(serverResources)) if (deps.css && deps.css.length > 0) {
|
|
8576
|
+
const absolutePath = join(root, relativePath);
|
|
8577
|
+
buildManifest.css[absolutePath] = deps.css;
|
|
8578
|
+
}
|
|
8579
|
+
}
|
|
8580
|
+
if (routeClientRefKeys && routeClientRefKeys.size > 0) {
|
|
8581
|
+
const clientReferenceDeps = manifest.clientReferenceDeps;
|
|
8582
|
+
if (clientReferenceDeps) for (const [filePath, refKeys] of routeClientRefKeys) {
|
|
8583
|
+
const jsUrls = /* @__PURE__ */ new Set();
|
|
8584
|
+
for (const key of refKeys) {
|
|
8585
|
+
const deps = clientReferenceDeps[key];
|
|
8586
|
+
if (deps?.js) for (const url of deps.js) jsUrls.add(url);
|
|
8587
|
+
}
|
|
8588
|
+
if (jsUrls.size > 0) buildManifest.modulepreload[filePath] = Array.from(jsUrls);
|
|
8589
|
+
}
|
|
8590
|
+
}
|
|
8591
|
+
}
|
|
8592
|
+
/**
|
|
8593
|
+
* Strip JS references from the RSC plugin's assets manifest files.
|
|
8594
|
+
*
|
|
8595
|
+
* The RSC plugin writes `__vite_rsc_assets_manifest.js` to rsc/ and ssr/
|
|
8596
|
+
* as standalone files (not Rollup chunks), so generateBundle can't
|
|
8597
|
+
* intercept them. This rewrites the files on disk after all builds
|
|
8598
|
+
* complete but before the adapter copies them to the output directory.
|
|
8599
|
+
*/
|
|
8600
|
+
async function stripJsFromRscAssetsManifests(serverDirs) {
|
|
8601
|
+
const paths = serverDirs.map((dir) => join(dir, "__vite_rsc_assets_manifest.js"));
|
|
8602
|
+
for (const path of paths) {
|
|
8603
|
+
let content;
|
|
8604
|
+
try {
|
|
8605
|
+
content = await readFile(path, "utf-8");
|
|
8606
|
+
} catch {
|
|
8607
|
+
continue;
|
|
8608
|
+
}
|
|
8609
|
+
const jsonStr = content.replace(/^export default\s*/, "").replace(/;?\s*$/, "");
|
|
8610
|
+
let isStrictJson = true;
|
|
8611
|
+
let manifest = null;
|
|
8612
|
+
try {
|
|
8613
|
+
manifest = JSON.parse(jsonStr);
|
|
8614
|
+
} catch {
|
|
8615
|
+
isStrictJson = false;
|
|
8616
|
+
}
|
|
8617
|
+
if (!isStrictJson) {
|
|
8618
|
+
let rewritten = content;
|
|
8619
|
+
rewritten = clearJsArrays(rewritten);
|
|
8620
|
+
rewritten = clearBootstrapScriptContent(rewritten);
|
|
8621
|
+
await writeFile(path, rewritten);
|
|
8622
|
+
continue;
|
|
8623
|
+
}
|
|
8624
|
+
const deps = manifest?.clientReferenceDeps;
|
|
8625
|
+
if (deps) for (const entry of Object.values(deps)) entry.js = [];
|
|
8626
|
+
if (manifest) manifest.bootstrapScriptContent = "";
|
|
8627
|
+
await writeFile(path, `export default ${JSON.stringify(manifest, null, 2)};\n`);
|
|
8628
|
+
}
|
|
8629
|
+
}
|
|
8630
|
+
//#endregion
|
|
8631
|
+
//#region src/plugins/post-build.ts
|
|
8632
|
+
/** The Vite environments whose output adapters consume. */
|
|
8633
|
+
var ARTIFACT_ENVIRONMENTS = [
|
|
8634
|
+
"client",
|
|
8635
|
+
"rsc",
|
|
8636
|
+
"ssr"
|
|
8637
|
+
];
|
|
8638
|
+
function isArtifactEnvironment(name) {
|
|
8639
|
+
return ARTIFACT_ENVIRONMENTS.includes(name);
|
|
8640
|
+
}
|
|
8641
|
+
function timberPostBuild(ctx, steps) {
|
|
8642
|
+
const environments = {};
|
|
8643
|
+
/** What the client environment's bundle wrote, from its `writeBundle`. */
|
|
8644
|
+
let clientOutput = {
|
|
8645
|
+
assetsDir: "",
|
|
8646
|
+
emitted: /* @__PURE__ */ new Set()
|
|
8647
|
+
};
|
|
8648
|
+
return {
|
|
8649
|
+
name: "timber-post-build",
|
|
8650
|
+
writeBundle(options, bundle) {
|
|
8651
|
+
if (ctx.dev) return;
|
|
8652
|
+
const env = this.environment;
|
|
8653
|
+
if (!isArtifactEnvironment(env.name)) return;
|
|
8654
|
+
environments[env.name] = { path: resolve(env.config.root, env.config.build.outDir) };
|
|
8655
|
+
if (env.name === "client") clientOutput = {
|
|
8656
|
+
assetsDir: hashedAssetsDir(env.config.build.assetsDir, options),
|
|
8657
|
+
emitted: new Set(Object.keys(bundle))
|
|
8658
|
+
};
|
|
8659
|
+
},
|
|
8660
|
+
buildApp: {
|
|
8661
|
+
order: "post",
|
|
8662
|
+
async handler() {
|
|
8663
|
+
if (ctx.dev) return;
|
|
8664
|
+
await runPostBuild(ctx, steps, environments, clientOutput);
|
|
8665
|
+
}
|
|
8666
|
+
}
|
|
8667
|
+
};
|
|
8668
|
+
}
|
|
8669
|
+
/**
|
|
8670
|
+
* The client bundle's assets directory, in the artifacts' form (no leading
|
|
8671
|
+
* or trailing slash) — or `''` when its files are not all content-hashed.
|
|
8672
|
+
*
|
|
8673
|
+
* `assetsDir` names where Vite writes; it is the naming patterns that decide
|
|
8674
|
+
* whether a file name carries a hash. Vite's defaults do
|
|
8675
|
+
* (`<assetsDir>/[name]-[hash].js`), but an app can set
|
|
8676
|
+
* `assetFileNames: 'static/[name][extname]'`, and marking that directory
|
|
8677
|
+
* immutable would pin a changed image under an unchanged URL for a year. A
|
|
8678
|
+
* pattern given as a function cannot be inspected, so it counts as unhashed:
|
|
8679
|
+
* those files fall back to the revalidating per-file rule.
|
|
8680
|
+
*
|
|
8681
|
+
* @internal Exported for testing.
|
|
8682
|
+
*/
|
|
8683
|
+
function hashedAssetsDir(assetsDir, output) {
|
|
8684
|
+
const dir = assetsDir.replace(/^\/+|\/+$/g, "");
|
|
8685
|
+
return [
|
|
8686
|
+
output.entryFileNames,
|
|
8687
|
+
output.chunkFileNames,
|
|
8688
|
+
output.assetFileNames
|
|
8689
|
+
].every((p) => typeof p === "string" && p.includes("[hash")) ? dir : "";
|
|
8690
|
+
}
|
|
8691
|
+
/**
|
|
8692
|
+
* Keep only the directories whose every file the client bundle emitted.
|
|
8693
|
+
*
|
|
8694
|
+
* A producer knows it hashes what *it* writes, not what else lands beside it:
|
|
8695
|
+
* Vite copies `public/` into the client output verbatim, so `public/assets/logo.png`
|
|
8696
|
+
* sits in `assets/` under a stable name, and `public/_rsc/…` would sit among
|
|
8697
|
+
* the hashed payloads. A directory holding any file the bundle did not emit
|
|
8698
|
+
* is not content-hashed as a whole, and marking it immutable would pin that
|
|
8699
|
+
* file for a year — so it is dropped, and its files take the per-file rule.
|
|
8700
|
+
*
|
|
8701
|
+
* @internal Exported for testing.
|
|
8702
|
+
*/
|
|
8703
|
+
async function onlyEmittedDirs(clientDir, dirs, emitted) {
|
|
8704
|
+
const kept = [];
|
|
8705
|
+
for (const dir of dirs) {
|
|
8706
|
+
const root = join(clientDir, dir);
|
|
8707
|
+
if (!(await readdir(root, {
|
|
8708
|
+
recursive: true,
|
|
8709
|
+
withFileTypes: true
|
|
8710
|
+
}).catch(() => [])).some((entry) => entry.isFile() && !emitted.has(relative(clientDir, join(entry.parentPath, entry.name)).replace(/\\/g, "/")))) kept.push(dir);
|
|
8711
|
+
}
|
|
8712
|
+
return kept;
|
|
8713
|
+
}
|
|
8714
|
+
async function runPostBuild(ctx, steps, environments, clientOutput) {
|
|
8715
|
+
const output = ctx.config.output ?? "server";
|
|
8716
|
+
const rsc = requireEnvironment(environments, "rsc");
|
|
8717
|
+
const ssr = requireEnvironment(environments, "ssr");
|
|
8718
|
+
const manifest = await finalizeBuildManifest(ctx, steps.fonts, rsc, ssr);
|
|
8719
|
+
if (manifest) Reflect.set(globalThis, "__TIMBER_BUILD_MANIFEST__", manifest);
|
|
8720
|
+
const prebuilt = await steps.prebuilt.capture(rsc.path);
|
|
8721
|
+
const site = output === "static" ? await runStaticGeneration(ctx, rsc.path) : void 0;
|
|
8722
|
+
steps.report.print(prebuilt);
|
|
8723
|
+
const adapter = contextAdapter(ctx);
|
|
8724
|
+
if (!adapter || typeof adapter.buildOutput !== "function") return;
|
|
8725
|
+
await adapter.buildOutput(adapterConfig(ctx), assembleBuildArtifacts({
|
|
8726
|
+
output,
|
|
8727
|
+
outputDir: ctx.buildDir,
|
|
8728
|
+
environments,
|
|
8729
|
+
immutableDirs: await onlyEmittedDirs(requireEnvironment(environments, "client").path, [
|
|
8730
|
+
...clientOutput.assetsDir ? [clientOutput.assetsDir] : [],
|
|
8731
|
+
...steps.fonts.immutableDirs(),
|
|
8732
|
+
...site?.immutableDirs ?? []
|
|
8733
|
+
], clientOutput.emitted),
|
|
8734
|
+
prebuilt: prebuilt?.artifact,
|
|
8735
|
+
site,
|
|
8736
|
+
manifestInit: manifest ? serializeManifestInit(manifest) : void 0
|
|
8737
|
+
}));
|
|
8738
|
+
}
|
|
8739
|
+
function requireEnvironment(environments, name) {
|
|
8740
|
+
const artifact = environments[name];
|
|
8741
|
+
if (!artifact) throw new Error(`[timber] Build output: the ${name} environment wrote no bundle`);
|
|
8742
|
+
return artifact;
|
|
8743
|
+
}
|
|
8744
|
+
/**
|
|
8745
|
+
* Step 1: bring the build manifest to its final shape, once.
|
|
8746
|
+
*
|
|
8747
|
+
* `timber-build-manifest` creates it from the client bundle; this adds what
|
|
8748
|
+
* only exists once every environment is built — the font entries and the
|
|
8749
|
+
* per-route CSS and modulepreloads in the RSC plugin's assets manifest —
|
|
8750
|
+
* and then, when client JavaScript is disabled, removes every JavaScript
|
|
8751
|
+
* reference, from the manifest and from the assets manifests on disk. The
|
|
8752
|
+
* manifest's `js` / `modulepreload` are cleared after the merge has written
|
|
8753
|
+
* into them, so nothing the merge adds survives.
|
|
8754
|
+
*
|
|
8755
|
+
* Returns null only when no client bundle produced a manifest.
|
|
8756
|
+
*
|
|
8757
|
+
* @internal Exported for testing.
|
|
8758
|
+
*/
|
|
8759
|
+
async function finalizeBuildManifest(ctx, fonts, rsc, ssr) {
|
|
8760
|
+
const manifest = ctx.buildManifest;
|
|
8761
|
+
if (manifest) {
|
|
8762
|
+
fonts.contributeManifest(manifest);
|
|
8763
|
+
await mergeRscAssetsManifest(rsc.path, ctx.root, manifest, ctx.routeClientRefKeys);
|
|
8764
|
+
}
|
|
8765
|
+
if (ctx.clientJavascript.disabled) {
|
|
8766
|
+
if (manifest) {
|
|
8767
|
+
manifest.js = {};
|
|
8768
|
+
manifest.modulepreload = {};
|
|
8769
|
+
}
|
|
8770
|
+
await stripJsFromRscAssetsManifests([rsc.path, ssr.path]);
|
|
8771
|
+
}
|
|
8772
|
+
return manifest;
|
|
8773
|
+
}
|
|
8774
|
+
/**
|
|
8775
|
+
* The build manifest as a JS module that sets the global. Adapters write
|
|
8776
|
+
* it as `_timber-manifest-init.js` (or prepend it to the entry) and
|
|
8777
|
+
* evaluate it before the RSC handler, so `virtual:timber-build-manifest`
|
|
8778
|
+
* finds it.
|
|
8779
|
+
*/
|
|
8780
|
+
function serializeManifestInit(manifest) {
|
|
8781
|
+
return `globalThis.__TIMBER_BUILD_MANIFEST__ = ${JSON.stringify(manifest)};\n`;
|
|
8782
|
+
}
|
|
8783
|
+
/**
|
|
8784
|
+
* Dedupe the producers' directories and drop any that sits inside another.
|
|
8785
|
+
*
|
|
8786
|
+
* Two producers can name overlapping directories — a custom `assetsDir` of
|
|
8787
|
+
* `_timber` beside the fonts' `_timber/fonts`. Cloudflare and Netlify apply
|
|
8788
|
+
* every matching `_headers` rule, so emitting both would send two
|
|
8789
|
+
* `Cache-Control` values for one file; the outer directory already covers
|
|
8790
|
+
* the inner one.
|
|
8791
|
+
*/
|
|
8792
|
+
function canonicalImmutableDirs(dirs) {
|
|
8793
|
+
const unique = [...new Set(dirs)];
|
|
8794
|
+
return unique.filter((dir) => !unique.some((other) => other !== dir && dir.startsWith(`${other}/`)));
|
|
8795
|
+
}
|
|
8796
|
+
/**
|
|
8797
|
+
* Assemble the adapter's view of the build from what each step returned.
|
|
8798
|
+
*
|
|
8799
|
+
* Not a validator: every field is copied from the phase that produced it.
|
|
8800
|
+
* The throws are the states the union cannot represent — a Vite environment
|
|
8801
|
+
* that wrote no bundle, a static build with no site. Each means an earlier
|
|
8802
|
+
* phase failed without failing the build, and a deploy missing its SSR
|
|
8803
|
+
* bundle fails on the first request rather than here.
|
|
8804
|
+
*
|
|
8805
|
+
* @internal Exported for testing.
|
|
8806
|
+
*/
|
|
8807
|
+
function assembleBuildArtifacts(input) {
|
|
8808
|
+
const { output, outputDir, environments } = input;
|
|
8809
|
+
const client = requireEnvironment(environments, "client");
|
|
8810
|
+
const immutableDirs = canonicalImmutableDirs(input.immutableDirs);
|
|
8811
|
+
if (output === "static") {
|
|
8812
|
+
if (!input.site) throw new Error("[timber] Build output: output is 'static' but static generation recorded no site");
|
|
8813
|
+
const { pages, contentTypes } = input.site;
|
|
8814
|
+
return {
|
|
8815
|
+
output,
|
|
8816
|
+
outputDir,
|
|
8817
|
+
client,
|
|
8818
|
+
immutableDirs,
|
|
8819
|
+
pages,
|
|
8820
|
+
contentTypes
|
|
8821
|
+
};
|
|
8822
|
+
}
|
|
8823
|
+
return {
|
|
8824
|
+
output,
|
|
8825
|
+
outputDir,
|
|
8826
|
+
client,
|
|
8827
|
+
immutableDirs,
|
|
8828
|
+
rsc: requireEnvironment(environments, "rsc"),
|
|
8829
|
+
ssr: requireEnvironment(environments, "ssr"),
|
|
8830
|
+
prebuilt: input.prebuilt,
|
|
8831
|
+
manifestInit: input.manifestInit
|
|
8832
|
+
};
|
|
8833
|
+
}
|
|
8834
|
+
//#endregion
|
|
8571
8835
|
//#region src/plugins/build-report.ts
|
|
8572
8836
|
/**
|
|
8573
8837
|
* timber-build-report — Post-build route summary table.
|
|
@@ -8671,13 +8935,10 @@ function pad(str, width, align = "right") {
|
|
|
8671
8935
|
function stripAnsi(str) {
|
|
8672
8936
|
return str.replace(/\u001b\[\d+m/g, "");
|
|
8673
8937
|
}
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
} catch {
|
|
8679
|
-
return null;
|
|
8680
|
-
}
|
|
8938
|
+
/** Read the manifest of the prebuilt artifact this build recorded, if any. */
|
|
8939
|
+
function loadPrebuiltManifest(prebuiltDir) {
|
|
8940
|
+
if (!prebuiltDir) return null;
|
|
8941
|
+
return JSON.parse(readFileSync(join(prebuiltDir, "manifest.json"), "utf-8"));
|
|
8681
8942
|
}
|
|
8682
8943
|
function buildPrebuiltReportData(manifest, summary) {
|
|
8683
8944
|
const hasCaptures = summary && (summary.captured > 0 || summary.skipped.length > 0);
|
|
@@ -8881,11 +9142,47 @@ function timberBuildReport(ctx) {
|
|
|
8881
9142
|
let logger = null;
|
|
8882
9143
|
let chunkSizes = null;
|
|
8883
9144
|
let clientBundle = null;
|
|
8884
|
-
let reported = false;
|
|
8885
|
-
let deferReport = false;
|
|
8886
9145
|
const buildStart = performance.now();
|
|
9146
|
+
function printRouteTable() {
|
|
9147
|
+
if (!ctx.routeTree || !chunkSizes || !clientBundle || !logger) return;
|
|
9148
|
+
const outputMode = ctx.config.output ?? "server";
|
|
9149
|
+
const { entries, sharedGzip } = ctx.clientJavascript.disabled ? {
|
|
9150
|
+
entries: collectRoutes(ctx.routeTree).map((info) => ({
|
|
9151
|
+
path: info.path,
|
|
9152
|
+
type: classifyRoute(info.segments, outputMode),
|
|
9153
|
+
size: 0,
|
|
9154
|
+
firstLoadSize: 0
|
|
9155
|
+
})),
|
|
9156
|
+
sharedGzip: 0
|
|
9157
|
+
} : buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode, ctx.appDir, ctx.root);
|
|
9158
|
+
const elapsed = ((performance.now() - buildStart) / 1e3).toFixed(2);
|
|
9159
|
+
const lines = buildRouteReport(entries, sharedGzip);
|
|
9160
|
+
logger.info("");
|
|
9161
|
+
for (const line of lines) logger.info(line);
|
|
9162
|
+
const warnings = buildWarnings(entries, ctx.config.budget);
|
|
9163
|
+
if (warnings.length > 0) {
|
|
9164
|
+
logger.info("");
|
|
9165
|
+
for (const w of warnings) logger.warn(w);
|
|
9166
|
+
}
|
|
9167
|
+
logger.info("");
|
|
9168
|
+
logger.info(`✓ built ${entries.length} routes for all three environments (rsc, ssr, client) in ${elapsed}s`);
|
|
9169
|
+
logger.info("");
|
|
9170
|
+
}
|
|
9171
|
+
function printPrebuiltReport(prebuilt) {
|
|
9172
|
+
if (!logger || !prebuilt) return;
|
|
9173
|
+
const prebuiltData = buildPrebuiltReportData(loadPrebuiltManifest(prebuilt.artifact?.path), prebuilt.summary);
|
|
9174
|
+
if (!prebuiltData) return;
|
|
9175
|
+
logger.info("");
|
|
9176
|
+
for (const line of buildPrebuiltReport(prebuiltData)) logger.info(line);
|
|
9177
|
+
logger.info("");
|
|
9178
|
+
}
|
|
8887
9179
|
return {
|
|
8888
9180
|
name: "timber-build-report",
|
|
9181
|
+
api: { print(prebuilt) {
|
|
9182
|
+
if (ctx.dev) return;
|
|
9183
|
+
printRouteTable();
|
|
9184
|
+
printPrebuiltReport(prebuilt);
|
|
9185
|
+
} },
|
|
8889
9186
|
config(_cfg, { command }) {
|
|
8890
9187
|
if (command !== "build") return;
|
|
8891
9188
|
return { environments: {
|
|
@@ -8902,50 +9199,6 @@ function timberBuildReport(ctx) {
|
|
|
8902
9199
|
if (this.environment?.name && this.environment.name !== "client") return;
|
|
8903
9200
|
chunkSizes = collectChunkSizes(bundle);
|
|
8904
9201
|
clientBundle = { ...bundle };
|
|
8905
|
-
deferReport = true;
|
|
8906
|
-
},
|
|
8907
|
-
closeBundle() {
|
|
8908
|
-
if (ctx.dev || reported) return;
|
|
8909
|
-
if (deferReport) {
|
|
8910
|
-
deferReport = false;
|
|
8911
|
-
return;
|
|
8912
|
-
}
|
|
8913
|
-
if (!ctx.routeTree || !chunkSizes || !clientBundle || !logger) return;
|
|
8914
|
-
reported = true;
|
|
8915
|
-
const outputMode = ctx.config.output ?? "server";
|
|
8916
|
-
const { entries, sharedGzip } = ctx.clientJavascript.disabled ? {
|
|
8917
|
-
entries: collectRoutes(ctx.routeTree).map((info) => ({
|
|
8918
|
-
path: info.path,
|
|
8919
|
-
type: classifyRoute(info.segments, outputMode),
|
|
8920
|
-
size: 0,
|
|
8921
|
-
firstLoadSize: 0
|
|
8922
|
-
})),
|
|
8923
|
-
sharedGzip: 0
|
|
8924
|
-
} : buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode, ctx.appDir, ctx.root);
|
|
8925
|
-
const elapsed = ((performance.now() - buildStart) / 1e3).toFixed(2);
|
|
8926
|
-
const lines = buildRouteReport(entries, sharedGzip);
|
|
8927
|
-
logger.info("");
|
|
8928
|
-
for (const line of lines) logger.info(line);
|
|
8929
|
-
const warnings = buildWarnings(entries, ctx.config.budget);
|
|
8930
|
-
if (warnings.length > 0) {
|
|
8931
|
-
logger.info("");
|
|
8932
|
-
for (const w of warnings) logger.warn(w);
|
|
8933
|
-
}
|
|
8934
|
-
logger.info("");
|
|
8935
|
-
logger.info(`✓ built ${entries.length} routes for all three environments (rsc, ssr, client) in ${elapsed}s`);
|
|
8936
|
-
logger.info("");
|
|
8937
|
-
},
|
|
8938
|
-
buildApp: {
|
|
8939
|
-
order: "post",
|
|
8940
|
-
async handler() {
|
|
8941
|
-
if (ctx.dev || !logger) return;
|
|
8942
|
-
const prebuiltData = buildPrebuiltReportData(loadPrebuiltManifest(ctx.buildDir), ctx.captureSummary);
|
|
8943
|
-
if (!prebuiltData) return;
|
|
8944
|
-
logger.info("");
|
|
8945
|
-
const prebuiltLines = buildPrebuiltReport(prebuiltData);
|
|
8946
|
-
for (const line of prebuiltLines) logger.info(line);
|
|
8947
|
-
logger.info("");
|
|
8948
|
-
}
|
|
8949
9202
|
}
|
|
8950
9203
|
};
|
|
8951
9204
|
}
|
|
@@ -9287,10 +9540,8 @@ function timber(config) {
|
|
|
9287
9540
|
}
|
|
9288
9541
|
ctx.config.output ??= "server";
|
|
9289
9542
|
ctx.timer.end("config-load");
|
|
9290
|
-
const viteOutDir = userConfig.build?.outDir;
|
|
9291
|
-
const timberBuildDir = ctx.config.buildDir;
|
|
9292
9543
|
const resolvedRoot = resolve(userConfig.root ?? process.cwd());
|
|
9293
|
-
|
|
9544
|
+
const buildDir = resolveBuildDir(resolvedRoot, ctx.config.buildDir, userConfig.build?.outDir);
|
|
9294
9545
|
if (viteRoot !== process.cwd()) {
|
|
9295
9546
|
const hasCompilerInReloaded = !config?.reactCompiler && ctx.config.reactCompiler;
|
|
9296
9547
|
const hadCompilerInEarly = !config?.reactCompiler && earlyFileConfig?.reactCompiler;
|
|
@@ -9321,7 +9572,7 @@ function timber(config) {
|
|
|
9321
9572
|
resolvedDevPort = start.port;
|
|
9322
9573
|
resolvedDevPortExplicit = start.explicit;
|
|
9323
9574
|
}
|
|
9324
|
-
const buildOutDir = relative(resolvedRoot,
|
|
9575
|
+
const buildOutDir = relative(resolvedRoot, buildDir);
|
|
9325
9576
|
const envOutDirs = {};
|
|
9326
9577
|
for (const envName of [
|
|
9327
9578
|
"rsc",
|
|
@@ -9385,8 +9636,12 @@ function timber(config) {
|
|
|
9385
9636
|
};
|
|
9386
9637
|
const effectiveReactCompiler = config?.reactCompiler ?? earlyFileConfig?.reactCompiler ?? true;
|
|
9387
9638
|
// @vitejs/plugin-rsc handles:
|
|
9639
|
+
const fonts = timberFonts(ctx);
|
|
9640
|
+
const prebuilt = timberPrebuilt(ctx);
|
|
9641
|
+
const buildReport = timberBuildReport(ctx);
|
|
9388
9642
|
return [
|
|
9389
9643
|
rootSync,
|
|
9644
|
+
timberReactResolve(),
|
|
9390
9645
|
timberReactProd(),
|
|
9391
9646
|
...patchReactCompilerForProdJsx(react({ compiler: effectiveReactCompiler || false })),
|
|
9392
9647
|
vitePluginRsc(createRscOptions(ctx, encryptionKeyExpr)),
|
|
@@ -9394,19 +9649,23 @@ function timber(config) {
|
|
|
9394
9649
|
timberRouting(ctx),
|
|
9395
9650
|
timberEntries(ctx),
|
|
9396
9651
|
timberBuildManifest(ctx),
|
|
9397
|
-
|
|
9652
|
+
fonts,
|
|
9398
9653
|
timberMdx(ctx),
|
|
9399
9654
|
timberRequestDep(ctx),
|
|
9400
9655
|
timberCacheTransform(ctx),
|
|
9401
9656
|
timberPrerenderSugar(ctx),
|
|
9402
|
-
|
|
9657
|
+
prebuilt,
|
|
9403
9658
|
timberStaticBuild(ctx),
|
|
9404
9659
|
timberContent(ctx),
|
|
9405
9660
|
timberServerBundle(),
|
|
9406
9661
|
timberCloudflareWasm(ctx),
|
|
9407
9662
|
timberChunks(ctx),
|
|
9408
|
-
|
|
9409
|
-
|
|
9663
|
+
buildReport,
|
|
9664
|
+
timberPostBuild(ctx, {
|
|
9665
|
+
fonts: fonts.api,
|
|
9666
|
+
prebuilt: prebuilt.api,
|
|
9667
|
+
report: buildReport.api
|
|
9668
|
+
}),
|
|
9410
9669
|
timberDevLogs(ctx),
|
|
9411
9670
|
timberDevServer(ctx)
|
|
9412
9671
|
];
|