@timber-js/app 0.2.0-alpha.207 → 0.2.0-alpha.209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{primitives-DLAnvsrk.js → actions-BerlqoXA.js} +640 -410
- package/dist/_chunks/actions-BerlqoXA.js.map +1 -0
- package/dist/_chunks/{als-registry-C6kcfprT.js → als-registry-DaxkVjt5.js} +6 -2
- package/dist/_chunks/als-registry-DaxkVjt5.js.map +1 -0
- package/dist/_chunks/{build-manifest-DTmSGLRz.js → build-manifest-DWppEdLB.js} +2 -51
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/{build-output-helper-9dqCv1pZ.js → build-output-helper-RV_BRcF1.js} +50 -53
- package/dist/_chunks/build-output-helper-RV_BRcF1.js.map +1 -0
- package/dist/_chunks/{cache-api-CUD9Ezaq.js → cache-api-CR23J_NC.js} +64 -32
- package/dist/_chunks/cache-api-CR23J_NC.js.map +1 -0
- package/dist/_chunks/{chains-B4bgOl2g.js → chains-CpFg56UB.js} +2 -2
- package/dist/_chunks/{chains-B4bgOl2g.js.map → chains-CpFg56UB.js.map} +1 -1
- package/dist/_chunks/{cli-check-G8o30ldg.js → cli-check-C6Ev6wBO.js} +11 -52
- package/dist/_chunks/cli-check-C6Ev6wBO.js.map +1 -0
- package/dist/_chunks/cli-context-By7k2xVo.js +70 -0
- package/dist/_chunks/cli-context-By7k2xVo.js.map +1 -0
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js → cli-schema-sync-CbT2AUUI.js} +3 -3
- package/dist/_chunks/{cli-schema-sync--LZKs8Zn.js.map → cli-schema-sync-CbT2AUUI.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BFb__LYG.js → cloudflare-Byxl8FWP.js} +96 -53
- package/dist/_chunks/{cloudflare-BFb__LYG.js.map → cloudflare-Byxl8FWP.js.map} +1 -1
- package/dist/_chunks/{convention-lint-5KzoMg_A.js → convention-lint-jKTwKwPe.js} +21 -6
- package/dist/_chunks/convention-lint-jKTwKwPe.js.map +1 -0
- package/dist/_chunks/{dev-server-BzBxgYAV.js → dev-server-C4WZdB7L.js} +15 -167
- package/dist/_chunks/dev-server-C4WZdB7L.js.map +1 -0
- package/dist/_chunks/{error-boundary-BndF-3Td.js → error-boundary-tA7kVfs4.js} +84 -104
- package/dist/_chunks/error-boundary-tA7kVfs4.js.map +1 -0
- package/dist/_chunks/{fs-identity-D7vb6GdI.js → fs-identity-BRKuL215.js} +3 -4
- package/dist/_chunks/fs-identity-BRKuL215.js.map +1 -0
- package/dist/_chunks/{graph-cache-CP4GEmf9.js → graph-cache-CYiUS2aS.js} +4 -5
- package/dist/_chunks/graph-cache-CYiUS2aS.js.map +1 -0
- package/dist/_chunks/{json-lossy-check-ClNvBM_3.js → json-lossy-check-ip0Qi0MT.js} +6 -3
- package/dist/_chunks/json-lossy-check-ip0Qi0MT.js.map +1 -0
- package/dist/_chunks/{live-graph-Bm5WTvcr.js → live-graph-Dv-JJCZw.js} +3 -3
- package/dist/_chunks/{live-graph-Bm5WTvcr.js.map → live-graph-Dv-JJCZw.js.map} +1 -1
- package/dist/_chunks/{logger-k2DQ4EUf.js → logger-DiDt5ppH.js} +192 -51
- package/dist/_chunks/logger-DiDt5ppH.js.map +1 -0
- package/dist/_chunks/{navigation-root-mHSK9psY.js → navigation-root-BQfo1-kG.js} +2 -2
- package/dist/_chunks/{navigation-root-mHSK9psY.js.map → navigation-root-BQfo1-kG.js.map} +1 -1
- package/dist/_chunks/{plugin-context-8idfR3UZ.js → plugin-context-BPBPc3lL.js} +28 -4
- package/dist/_chunks/plugin-context-BPBPc3lL.js.map +1 -0
- package/dist/_chunks/{poison-scan-DG5eI2_z.js → poison-scan-CpeT6_OJ.js} +2 -2
- package/dist/_chunks/{poison-scan-DG5eI2_z.js.map → poison-scan-CpeT6_OJ.js.map} +1 -1
- package/dist/_chunks/render-timeout-DOf_BBcO.js +46 -0
- package/dist/_chunks/render-timeout-DOf_BBcO.js.map +1 -0
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js → rsc-payload-path-dffcs4jp.js} +9 -3
- package/dist/_chunks/{rsc-payload-path-B_LBodc2.js.map → rsc-payload-path-dffcs4jp.js.map} +1 -1
- package/dist/_chunks/{scanner-BQ5sPIJ7.js → scanner-Bw0oq1HB.js} +2 -2
- package/dist/_chunks/{scanner-BQ5sPIJ7.js.map → scanner-Bw0oq1HB.js.map} +1 -1
- package/dist/_chunks/{navigation-context-D0TU0Jog.js → segment-context-xtPUGfdq.js} +36 -34
- package/dist/_chunks/segment-context-xtPUGfdq.js.map +1 -0
- package/dist/_chunks/{singleflight-2lUWfcAk.js → singleflight-BeVMMKi0.js} +4 -3
- package/dist/_chunks/{singleflight-2lUWfcAk.js.map → singleflight-BeVMMKi0.js.map} +1 -1
- package/dist/_chunks/{sizeof-lXffQ1Vr.js → sizeof-UwzwB1uM.js} +3 -2
- package/dist/_chunks/sizeof-UwzwB1uM.js.map +1 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js +49 -0
- package/dist/_chunks/ssr-data-nA3I70_n.js.map +1 -0
- package/dist/_chunks/{state-FippDgxN.js → state-BhNGPsdi.js} +6 -8
- package/dist/_chunks/state-BhNGPsdi.js.map +1 -0
- package/dist/_chunks/{status-page-marker-DwQBrLBz.js → status-page-marker-gaihi0KZ.js} +140 -28
- package/dist/_chunks/status-page-marker-gaihi0KZ.js.map +1 -0
- package/dist/_chunks/{walkers-CN2N_bA-.js → walkers-BXExhzzk.js} +2 -2
- package/dist/_chunks/{walkers-CN2N_bA-.js.map → walkers-BXExhzzk.js.map} +1 -1
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js +32 -0
- package/dist/_chunks/write-file-atomic-D1qWqHb4.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +7 -7
- package/dist/adapters/build-output-helper.d.ts.map +1 -1
- package/dist/adapters/canonicalize-module.d.ts +8 -0
- package/dist/adapters/canonicalize-module.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +2 -2
- package/dist/adapters/cloudflare.d.ts +30 -8
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -2
- package/dist/adapters/compress-module.d.ts +8 -0
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +2 -3
- package/dist/adapters/fs-identity.d.ts.map +1 -1
- package/dist/adapters/nitro-presets.d.ts +0 -6
- package/dist/adapters/nitro-presets.d.ts.map +1 -1
- package/dist/adapters/nitro-preview.d.ts +43 -11
- package/dist/adapters/nitro-preview.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +1 -13
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +291 -176
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/types.d.ts +105 -21
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js +0 -0
- package/dist/analyze/crawl-entry.js +3 -3
- package/dist/analyze/graph-cache.d.ts.map +1 -1
- package/dist/analyze/graph-command.js +4 -4
- package/dist/cache/index.js +2 -2
- package/dist/cache/json-lossy-check.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/sizeof.d.ts.map +1 -1
- package/dist/cache/stores/memory.js +1 -1
- package/dist/cache/tag-aware-handler.d.ts.map +1 -1
- package/dist/cdn/workers-cache-purge.js +1 -1
- package/dist/cli-check.d.ts +7 -37
- package/dist/cli-check.d.ts.map +1 -1
- package/dist/cli-context.d.ts +54 -0
- package/dist/cli-context.d.ts.map +1 -0
- package/dist/cli.d.ts +9 -9
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +20 -24
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -1
- package/dist/client/browser-entry/hydrate.d.ts +19 -29
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +7 -7
- package/dist/client/browser-entry/post-hydration.d.ts +6 -9
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +6 -11
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +4 -3
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/error-reconstituter.d.ts +3 -9
- package/dist/client/error-reconstituter.d.ts.map +1 -1
- package/dist/client/history.d.ts +20 -11
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +5 -6
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +3 -3
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +95 -108
- package/dist/client/internal.js.map +1 -1
- package/dist/client/navigation-commit.d.ts +20 -7
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +3 -5
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +3 -2
- package/dist/client/react-root.d.ts.map +1 -1
- package/dist/client/router-pipeline.d.ts +3 -8
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +45 -39
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router-url.d.ts +24 -0
- package/dist/client/router-url.d.ts.map +1 -0
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +8 -4
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +44 -4
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/ssr-data.d.ts +18 -64
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +2 -5
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +1 -1
- package/dist/config-types.d.ts +2 -1
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/dev-page-shell.d.ts +17 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -1
- package/dist/dev-tools/index.d.ts +1 -1
- package/dist/dev-tools/index.d.ts.map +1 -1
- package/dist/dev-tools/instrumentation.d.ts +17 -2
- package/dist/dev-tools/instrumentation.d.ts.map +1 -1
- package/dist/dev-tools/overlay.d.ts +6 -27
- package/dist/dev-tools/overlay.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -373
- package/dist/index.js.map +1 -1
- package/dist/plugin-context.d.ts +26 -40
- package/dist/plugin-context.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +15 -2
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -1
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/post-build.d.ts +110 -0
- package/dist/plugins/post-build.d.ts.map +1 -0
- package/dist/plugins/prebuilt-capture.d.ts +11 -4
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -1
- package/dist/plugins/prebuilt.d.ts +17 -1
- package/dist/plugins/prebuilt.d.ts.map +1 -1
- package/dist/plugins/prerender-sugar.d.ts.map +1 -1
- package/dist/plugins/react-resolve.d.ts +49 -0
- package/dist/plugins/react-resolve.d.ts.map +1 -0
- package/dist/plugins/rsc-assets-manifest.d.ts +33 -0
- package/dist/plugins/rsc-assets-manifest.d.ts.map +1 -0
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +32 -9
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts +0 -9
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/segment-codegen.d.ts.map +1 -1
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-handler.d.ts +5 -4
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +46 -7
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +58 -5
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/children-interception.d.ts.map +1 -1
- package/dist/server/cookie-context.d.ts +2 -23
- package/dist/server/cookie-context.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +0 -9
- package/dist/server/csp-nonce.d.ts.map +1 -1
- package/dist/server/csrf.d.ts +27 -4
- package/dist/server/csrf.d.ts.map +1 -1
- package/dist/server/debug.d.ts +0 -1
- package/dist/server/debug.d.ts.map +1 -1
- package/dist/server/default-logger.d.ts +2 -1
- package/dist/server/default-logger.d.ts.map +1 -1
- package/dist/server/deny-boundary.d.ts +12 -6
- package/dist/server/deny-boundary.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts +2 -2
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -3
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +9 -2
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +4 -4
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -4
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +10 -3
- package/dist/server/instrumentation.d.ts.map +1 -1
- package/dist/server/internal.d.ts +1 -4
- package/dist/server/internal.d.ts.map +1 -1
- package/dist/server/internal.js +961 -581
- package/dist/server/internal.js.map +1 -1
- package/dist/server/json-status-response.d.ts +34 -0
- package/dist/server/json-status-response.d.ts.map +1 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/param-coercion.d.ts +11 -6
- package/dist/server/param-coercion.d.ts.map +1 -1
- package/dist/server/pipeline-helpers.d.ts +95 -7
- package/dist/server/pipeline-helpers.d.ts.map +1 -1
- package/dist/server/pipeline-interception.d.ts +11 -0
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-outcome.d.ts +11 -1
- package/dist/server/pipeline-outcome.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts +2 -2
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +23 -35
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/prebuilt/capture-render.d.ts +25 -0
- package/dist/server/prebuilt/capture-render.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-routes.d.ts +37 -0
- package/dist/server/prebuilt/capture-routes.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +79 -35
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -1
- package/dist/server/prebuilt/lifetime.d.ts +38 -0
- package/dist/server/prebuilt/lifetime.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +7 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -1
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -1
- package/dist/server/prebuilt-builder.d.ts.map +1 -1
- package/dist/server/prebuilt-runtime.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +6 -81
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/react-cache-bridge.d.ts +59 -0
- package/dist/server/react-cache-bridge.d.ts.map +1 -0
- package/dist/server/react-cache-scope.d.ts +49 -0
- package/dist/server/react-cache-scope.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +15 -0
- package/dist/server/render-timeout.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +9 -0
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/request-context.d.ts +26 -5
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts.map +1 -1
- package/dist/server/route-handler.d.ts.map +1 -1
- package/dist/server/route-matcher.d.ts +7 -0
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +22 -22
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +7 -0
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/deny-fallback.d.ts +32 -6
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +11 -18
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +0 -1
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +5 -15
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +5 -6
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-signals.d.ts +65 -0
- package/dist/server/rsc-entry/render-signals.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +6 -16
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +7 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +8 -53
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +2 -2
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +9 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -1
- package/dist/server/signal-identity.d.ts +43 -0
- package/dist/server/signal-identity.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +4 -3
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/slot-subtree-contain.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +91 -53
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +8 -5
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +26 -40
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +1 -1
- package/dist/server/static-generator.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +12 -0
- package/dist/server/stream-utils.d.ts.map +1 -1
- package/dist/server/tracing.d.ts +12 -16
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/version-skew.d.ts +3 -3
- package/dist/shared/csrf-reject.d.ts +16 -0
- package/dist/shared/csrf-reject.d.ts.map +1 -0
- package/dist/shared/error-digest.d.ts +28 -0
- package/dist/shared/error-digest.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +11 -10
- package/dist/shared/payload-root.d.ts.map +1 -1
- package/dist/shared/rsc-payload-path.d.ts +6 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -1
- package/dist/utils/write-file-atomic.d.ts +17 -0
- package/dist/utils/write-file-atomic.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +17 -14
- package/docs/api/32-api-cache.mdx +51 -23
- package/docs/api/34-api-config.mdx +34 -6
- package/docs/api/36-cli.mdx +11 -1
- package/docs/learn/03-fetching-data.mdx +17 -1
- package/docs/learn/04-access-control.mdx +1 -1
- package/docs/learn/10-caching.mdx +29 -11
- package/docs/learn/11-middleware.mdx +8 -2
- package/docs/learn/12-error-handling.mdx +6 -1
- package/package.json +7 -3
- package/src/adapters/build-output-helper.ts +55 -53
- package/src/adapters/canonicalize-module.ts +29 -0
- package/src/adapters/cloudflare.ts +105 -63
- package/src/adapters/compress-module.ts +16 -5
- package/src/adapters/fs-identity.ts +2 -3
- package/src/adapters/nitro-presets.ts +0 -15
- package/src/adapters/nitro-preview.ts +272 -136
- package/src/adapters/nitro.ts +119 -82
- package/src/adapters/shared.ts +23 -14
- package/src/adapters/types.ts +110 -21
- package/src/analyze/graph-cache.ts +3 -4
- package/src/cache/json-lossy-check.ts +3 -9
- package/src/cache/singleflight.ts +5 -2
- package/src/cache/sizeof.ts +3 -1
- package/src/cache/tag-aware-handler.ts +43 -26
- package/src/cli-check.ts +8 -98
- package/src/cli-context.ts +119 -0
- package/src/cli.ts +19 -28
- package/src/client/browser-dev.ts +1 -1
- package/src/client/browser-entry/action-dispatch.ts +26 -4
- package/src/client/browser-entry/hydrate.ts +53 -58
- package/src/client/browser-entry/index.ts +16 -27
- package/src/client/browser-entry/post-hydration.ts +6 -40
- package/src/client/browser-entry/router-init.ts +66 -84
- package/src/client/error-boundary.tsx +9 -41
- package/src/client/error-reconstituter.tsx +10 -5
- package/src/client/history.ts +35 -21
- package/src/client/index.ts +0 -1
- package/src/client/internal.ts +2 -7
- package/src/client/navigation-commit.ts +41 -18
- package/src/client/navigation-context.ts +3 -39
- package/src/client/react-root.ts +3 -2
- package/src/client/router-pipeline.ts +96 -132
- package/src/client/router-types.ts +46 -44
- package/src/client/router-url.ts +32 -0
- package/src/client/router.ts +62 -21
- package/src/client/rsc-fetch.ts +117 -155
- package/src/client/segment-cache.ts +110 -11
- package/src/client/ssr-data.ts +19 -80
- package/src/client/state.ts +2 -9
- package/src/client/use-pathname.ts +1 -1
- package/src/config-types.ts +2 -1
- package/src/config-validation.ts +2 -1
- package/src/dev-tools/dev-page-shell.ts +18 -0
- package/src/dev-tools/index.ts +0 -2
- package/src/dev-tools/instrumentation.ts +50 -2
- package/src/dev-tools/overlay.ts +8 -238
- package/src/index.ts +26 -14
- package/src/plugin-context.ts +39 -40
- package/src/plugins/build-manifest.ts +4 -11
- package/src/plugins/build-report.ts +70 -70
- package/src/plugins/dev-server.ts +24 -44
- package/src/plugins/entries.ts +2 -1
- package/src/plugins/fonts.ts +35 -7
- package/src/plugins/post-build.ts +327 -0
- package/src/plugins/prebuilt-capture.ts +28 -32
- package/src/plugins/prebuilt.ts +54 -39
- package/src/plugins/prerender-sugar.ts +0 -4
- package/src/plugins/react-resolve.ts +149 -0
- package/src/plugins/{adapter-build.ts → rsc-assets-manifest.ts} +20 -109
- package/src/plugins/shims.ts +1 -0
- package/src/plugins/static-build.ts +42 -74
- package/src/routing/codegen-write.ts +25 -3
- package/src/routing/segment-codegen.ts +3 -2
- package/src/rsc-runtime/vendor-types.d.ts +8 -0
- package/src/server/access-gate.tsx +2 -1
- package/src/server/action-client.ts +1 -1
- package/src/server/action-handler.ts +253 -110
- package/src/server/actions.ts +73 -25
- package/src/server/als-registry.ts +73 -5
- package/src/server/chain-url-parts.ts +1 -1
- package/src/server/children-interception.ts +2 -1
- package/src/server/cookie-context.ts +18 -48
- package/src/server/csp-nonce.ts +0 -12
- package/src/server/csrf.ts +140 -8
- package/src/server/debug.ts +0 -1
- package/src/server/default-logger.ts +2 -1
- package/src/server/deny-boundary.ts +25 -13
- package/src/server/deny-renderer.ts +30 -97
- package/src/server/error-boundary-wrapper.ts +7 -3
- package/src/server/fallback-error.ts +26 -11
- package/src/server/flight-scripts.ts +1 -1
- package/src/server/head-response.ts +4 -4
- package/src/server/html-injector-core.ts +2 -2
- package/src/server/html-injectors.ts +2 -4
- package/src/server/index.ts +0 -4
- package/src/server/instrumentation.ts +10 -3
- package/src/server/internal.ts +1 -6
- package/src/server/json-status-response.ts +105 -0
- package/src/server/logger.ts +39 -3
- package/src/server/param-coercion.ts +15 -12
- package/src/server/pipeline-helpers.ts +257 -12
- package/src/server/pipeline-interception.ts +133 -0
- package/src/server/pipeline-outcome.ts +103 -31
- package/src/server/pipeline-phases.ts +127 -237
- package/src/server/pipeline.ts +204 -207
- package/src/server/prebuilt/capture-render.ts +118 -0
- package/src/server/prebuilt/capture-routes.ts +104 -0
- package/src/server/prebuilt/capture-state.ts +155 -48
- package/src/server/prebuilt/lifetime.ts +151 -0
- package/src/server/prebuilt/slots.ts +14 -2
- package/src/server/prebuilt/synthetic-store.ts +3 -0
- package/src/server/prebuilt-builder.ts +30 -320
- package/src/server/prebuilt-runtime.ts +125 -129
- package/src/server/primitives.ts +8 -168
- package/src/server/react-cache-bridge.ts +124 -0
- package/src/server/react-cache-scope.ts +104 -0
- package/src/server/render-timeout.ts +20 -0
- package/src/server/render-utils.ts +11 -1
- package/src/server/request-context.ts +36 -9
- package/src/server/route-element-builder.ts +11 -6
- package/src/server/route-handler.ts +36 -23
- package/src/server/route-matcher.ts +15 -1
- package/src/server/rsc-entry/action-middleware-runner.ts +79 -123
- package/src/server/rsc-entry/api-handler.ts +27 -103
- package/src/server/rsc-entry/deny-fallback.ts +93 -26
- package/src/server/rsc-entry/error-renderer.ts +39 -91
- package/src/server/rsc-entry/helpers.ts +2 -4
- package/src/server/rsc-entry/index.ts +64 -58
- package/src/server/rsc-entry/render-route.ts +15 -80
- package/src/server/rsc-entry/render-signals.ts +108 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +56 -57
- package/src/server/rsc-entry/rsc-payload.ts +28 -61
- package/src/server/rsc-entry/rsc-stream.ts +113 -213
- package/src/server/rsc-entry/ssr-bridge.ts +2 -2
- package/src/server/rsc-entry/ssr-renderer.ts +182 -263
- package/src/server/rsc-entry/wrap-action-dispatch.ts +12 -14
- package/src/server/signal-identity.ts +112 -0
- package/src/server/slot-resolver.ts +18 -18
- package/src/server/slot-subtree-contain.ts +2 -1
- package/src/server/ssr-bridge-types.ts +92 -56
- package/src/server/ssr-entry.ts +87 -111
- package/src/server/ssr-render.ts +55 -64
- package/src/server/ssr-wrappers.tsx +2 -2
- package/src/server/static-generator.ts +7 -42
- package/src/server/static-not-found.ts +3 -3
- package/src/server/stream-utils.ts +51 -0
- package/src/server/tracing.ts +58 -75
- package/src/server/types.ts +1 -1
- package/src/server/version-skew.ts +5 -5
- package/src/shared/csrf-reject.ts +15 -0
- package/src/shared/error-digest.ts +46 -0
- package/src/shared/payload-root.ts +11 -10
- package/src/shared/rsc-payload-path.ts +8 -1
- package/src/utils/write-file-atomic.ts +32 -0
- package/dist/_chunks/actions-jNrXdzgs.js +0 -346
- package/dist/_chunks/actions-jNrXdzgs.js.map +0 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +0 -1
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +0 -1
- package/dist/_chunks/build-output-helper-9dqCv1pZ.js.map +0 -1
- package/dist/_chunks/cache-api-CUD9Ezaq.js.map +0 -1
- package/dist/_chunks/cli-check-G8o30ldg.js.map +0 -1
- package/dist/_chunks/convention-lint-5KzoMg_A.js.map +0 -1
- package/dist/_chunks/dev-server-BzBxgYAV.js.map +0 -1
- package/dist/_chunks/error-boundary-BndF-3Td.js.map +0 -1
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +0 -1
- package/dist/_chunks/graph-cache-CP4GEmf9.js.map +0 -1
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +0 -1
- package/dist/_chunks/logger-k2DQ4EUf.js.map +0 -1
- package/dist/_chunks/navigation-context-D0TU0Jog.js.map +0 -1
- package/dist/_chunks/plugin-context-8idfR3UZ.js.map +0 -1
- package/dist/_chunks/primitives-DLAnvsrk.js.map +0 -1
- package/dist/_chunks/segment-context-D9_89u34.js +0 -34
- package/dist/_chunks/segment-context-D9_89u34.js.map +0 -1
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +0 -1
- package/dist/_chunks/ssr-data-D6T6Y3ef.js +0 -60
- package/dist/_chunks/ssr-data-D6T6Y3ef.js.map +0 -1
- package/dist/_chunks/state-FippDgxN.js.map +0 -1
- package/dist/_chunks/status-page-marker-DwQBrLBz.js.map +0 -1
- package/dist/client/types.d.ts +0 -14
- package/dist/client/types.d.ts.map +0 -1
- package/dist/plugins/adapter-build.d.ts +0 -38
- package/dist/plugins/adapter-build.d.ts.map +0 -1
- package/dist/server/asset-headers.d.ts +0 -32
- package/dist/server/asset-headers.d.ts.map +0 -1
- package/dist/server/dev-source-map.d.ts +0 -22
- package/dist/server/dev-source-map.d.ts.map +0 -1
- package/src/client/types.ts +0 -21
- package/src/server/asset-headers.ts +0 -59
- package/src/server/dev-source-map.ts +0 -31
package/src/index.ts
CHANGED
|
@@ -28,6 +28,7 @@ import { timberBuildManifest } from './plugins/build-manifest.ts';
|
|
|
28
28
|
import { timberDevLogs, originalConsole, wrapLoggerWithOriginalConsole } from './dev-tools/logs.ts';
|
|
29
29
|
import { resolveForwardConsole } from './dev-tools/browser-logs.ts';
|
|
30
30
|
import { timberReactProd } from './plugins/react-prod.ts';
|
|
31
|
+
import { timberReactResolve } from './plugins/react-resolve.ts';
|
|
31
32
|
import { timberChunks } from './plugins/chunks.ts';
|
|
32
33
|
import { clientChunkGroup } from './plugins/client-chunks.ts';
|
|
33
34
|
import { timberServerBundle } from './plugins/server-bundle.ts';
|
|
@@ -36,7 +37,7 @@ import { timberRequestDep } from './plugins/request-dep/index.ts';
|
|
|
36
37
|
import { timberPrebuilt } from './plugins/prebuilt.ts';
|
|
37
38
|
import { timberPrerenderSugar } from './plugins/prerender-sugar.ts';
|
|
38
39
|
import { timberCloudflareWasm } from './plugins/cloudflare-wasm.ts';
|
|
39
|
-
import {
|
|
40
|
+
import { timberPostBuild } from './plugins/post-build.ts';
|
|
40
41
|
import { timberBuildReport } from './plugins/build-report.ts';
|
|
41
42
|
import { createNoopTimer } from './utils/startup-timer.ts';
|
|
42
43
|
import {
|
|
@@ -288,11 +289,11 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
288
289
|
// ── Resolve build output directory ─────────────────────────
|
|
289
290
|
// Priority: timber.config.ts `buildDir` > Vite `build.outDir` > .timber/dist
|
|
290
291
|
// Set Vite's build.outDir so the RSC plugin and all environment
|
|
291
|
-
// builds write to the correct location.
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
// builds write to the correct location. ctx.buildDir is read back
|
|
293
|
+
// from Vite in configResolved, so there is one answer to where the
|
|
294
|
+
// build went.
|
|
294
295
|
const resolvedRoot = resolve(userConfig.root ?? process.cwd());
|
|
295
|
-
|
|
296
|
+
const buildDir = resolveBuildDir(resolvedRoot, ctx.config.buildDir, userConfig.build?.outDir);
|
|
296
297
|
|
|
297
298
|
// Warn if the Vite root differs from cwd and the re-loaded config
|
|
298
299
|
// has reactCompiler but the early cwd-based load missed it. In this
|
|
@@ -385,9 +386,9 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
385
386
|
resolvedDevPortExplicit = start.explicit;
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
// Derive relative buildOutDir from the absolute
|
|
389
|
+
// Derive relative buildOutDir from the absolute buildDir (set above)
|
|
389
390
|
// so Vite's config receives a root-relative path.
|
|
390
|
-
const buildOutDir = relative(resolvedRoot,
|
|
391
|
+
const buildOutDir = relative(resolvedRoot, buildDir);
|
|
391
392
|
|
|
392
393
|
// Set per-environment build.outDir so Vite's RSC plugin writes
|
|
393
394
|
// each environment to the correct subdirectory under our buildDir.
|
|
@@ -499,8 +500,10 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
499
500
|
// The watcher.add() call in dev-server.ts ensures the files are
|
|
500
501
|
// watched even if created after server start.
|
|
501
502
|
|
|
502
|
-
//
|
|
503
|
-
//
|
|
503
|
+
// The build directory is what Vite resolved build.outDir to — the
|
|
504
|
+
// config hook's value after every other plugin and the user config had
|
|
505
|
+
// their say. Vite keeps outDir as-is (may be relative), so resolve
|
|
506
|
+
// against root.
|
|
504
507
|
ctx.buildDir = resolve(resolved.root, resolved.build.outDir);
|
|
505
508
|
// In production builds, swap to a no-op timer to avoid overhead
|
|
506
509
|
if (!ctx.dev) {
|
|
@@ -551,8 +554,17 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
551
554
|
// We do NOT set customBuildApp — the RSC plugin's orchestration is correct
|
|
552
555
|
// and handles bundle ordering, asset manifest generation, and environment
|
|
553
556
|
// imports manifest. See @vitejs/plugin-rsc's buildApp implementation.
|
|
557
|
+
//
|
|
558
|
+
// Everything after it runs in timber-post-build, in the order that plugin
|
|
559
|
+
// states. The plugins that own a post-build step expose it as their `api`
|
|
560
|
+
// and are handed to it here, so no step's order depends on where a plugin
|
|
561
|
+
// sits in this array. See design/18-build-system.md §"Post-Build Phase".
|
|
562
|
+
const fonts = timberFonts(ctx);
|
|
563
|
+
const prebuilt = timberPrebuilt(ctx);
|
|
564
|
+
const buildReport = timberBuildReport(ctx);
|
|
554
565
|
return [
|
|
555
566
|
rootSync,
|
|
567
|
+
timberReactResolve(),
|
|
556
568
|
timberReactProd(),
|
|
557
569
|
// @vitejs/plugin-react provides React Fast Refresh (state-preserving HMR)
|
|
558
570
|
// for client components via Babel transform. Placed before @vitejs/plugin-rsc
|
|
@@ -568,19 +580,19 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
|
|
|
568
580
|
timberRouting(ctx),
|
|
569
581
|
timberEntries(ctx),
|
|
570
582
|
timberBuildManifest(ctx),
|
|
571
|
-
|
|
583
|
+
fonts,
|
|
572
584
|
timberMdx(ctx),
|
|
573
585
|
timberRequestDep(ctx),
|
|
574
586
|
timberCacheTransform(ctx),
|
|
575
587
|
timberPrerenderSugar(ctx), // export const prerender → cache.component() desugaring
|
|
576
|
-
|
|
577
|
-
timberStaticBuild(ctx), // Static mode: validate
|
|
588
|
+
prebuilt, // cache.component() → __prebuilt() callsite rewrite
|
|
589
|
+
timberStaticBuild(ctx), // Static mode: validate dynamic API usage
|
|
578
590
|
timberContent(ctx),
|
|
579
591
|
timberServerBundle(), // Bundle all deps in server environments for prod
|
|
580
592
|
timberCloudflareWasm(ctx), // Externalize WASM for Cloudflare Workers
|
|
581
593
|
timberChunks(ctx),
|
|
582
|
-
|
|
583
|
-
|
|
594
|
+
buildReport, // Route table with bundle sizes, printed by timber-post-build
|
|
595
|
+
timberPostBuild(ctx, { fonts: fonts.api, prebuilt: prebuilt.api, report: buildReport.api }),
|
|
584
596
|
timberDevLogs(ctx), // Dev-only: forward server console.* to browser console
|
|
585
597
|
timberDevServer(ctx), // Must be last — configureServer post-hook runs after all watchers
|
|
586
598
|
];
|
package/src/plugin-context.ts
CHANGED
|
@@ -14,13 +14,13 @@ import { createRequire } from 'node:module';
|
|
|
14
14
|
import { parseAst } from 'vite';
|
|
15
15
|
import type { RouteTree } from './routing/types.ts';
|
|
16
16
|
import type { BuildManifest } from './server/build-manifest.ts';
|
|
17
|
-
import type { CaptureSummary } from './server/prebuilt-builder.ts';
|
|
18
17
|
import type { StartupTimer } from './utils/startup-timer.ts';
|
|
19
18
|
import { createStartupTimer } from './utils/startup-timer.ts';
|
|
20
19
|
import type { TimberUserConfig, ClientJavascriptConfig } from './config-types.ts';
|
|
21
|
-
import type { RscManifest } from './plugins/static-build.ts';
|
|
22
20
|
import type { HoldingServer } from './dev-tools/holding-server.ts';
|
|
23
21
|
import type { ProgramNode } from './plugins/callsite-ast.ts';
|
|
22
|
+
import type { TimberConfig, TimberPlatformAdapter } from './adapters/types.ts';
|
|
23
|
+
import { normalizeBasePath } from './shared/base-path.ts';
|
|
24
24
|
|
|
25
25
|
// Re-export for sub-plugin convenience — they import from plugin-context.ts
|
|
26
26
|
export type { TimberUserConfig, ClientJavascriptConfig } from './config-types.ts';
|
|
@@ -88,7 +88,11 @@ export interface PluginContext {
|
|
|
88
88
|
* does). See TIM-1261.
|
|
89
89
|
*/
|
|
90
90
|
base: string;
|
|
91
|
-
/**
|
|
91
|
+
/**
|
|
92
|
+
* The build manifest. Created by timber-build-manifest from the client
|
|
93
|
+
* bundle and finalized by the post-build phase (plugins/post-build.ts),
|
|
94
|
+
* which is the only reader. Null in dev.
|
|
95
|
+
*/
|
|
92
96
|
buildManifest: BuildManifest | null;
|
|
93
97
|
/** Per-build deployment ID for version skew detection (null in dev) */
|
|
94
98
|
deploymentId: string | null;
|
|
@@ -103,13 +107,16 @@ export interface PluginContext {
|
|
|
103
107
|
* `timber.config.ts` `buildDir` or Vite's `build.outDir`.
|
|
104
108
|
* Timber config takes precedence when both are set.
|
|
105
109
|
*
|
|
106
|
-
*
|
|
110
|
+
* The `config` hook resolves it into Vite's `build.outDir`, and
|
|
111
|
+
* `configResolved` reads it back from Vite — the one assignment after
|
|
112
|
+
* construction, so what the build writes to and what `timber preview`
|
|
113
|
+
* serves (through {@link TimberPluginApi}) are the same directory.
|
|
107
114
|
*/
|
|
108
115
|
buildDir: string;
|
|
109
116
|
/**
|
|
110
117
|
* Per-route client reference keys captured during the RSC build.
|
|
111
118
|
* Maps absolute route file paths to the set of client reference
|
|
112
|
-
* hash keys they transitively import. Used by
|
|
119
|
+
* hash keys they transitively import. Used by the post-build phase to
|
|
113
120
|
* populate per-route modulepreload entries from clientReferenceDeps.
|
|
114
121
|
*/
|
|
115
122
|
routeClientRefKeys?: Map<string, Set<string>>;
|
|
@@ -138,19 +145,6 @@ export interface PluginContext {
|
|
|
138
145
|
* See design/27-chunking-strategy.md, TIM-1107.
|
|
139
146
|
*/
|
|
140
147
|
sharedModuleFacades?: Map<string, string[]>;
|
|
141
|
-
/**
|
|
142
|
-
* Module ID → prebuilt component IDs declared in it. Recorded by the
|
|
143
|
-
* timber-prebuilt transform (RSC environment, production builds only),
|
|
144
|
-
* consumed by the RSC `generateBundle` module-graph walk that computes
|
|
145
|
-
* `routePrebuiltComponents`. See design/44-render-at-build-time.md.
|
|
146
|
-
*/
|
|
147
|
-
prebuiltModuleComponents?: Map<string, string[]>;
|
|
148
|
-
/**
|
|
149
|
-
* Module ID → mapping of variable name to component ID for the prebuilt
|
|
150
|
-
* components declared in that module. Used at `generateBundle` time to
|
|
151
|
-
* trace imports from other modules back to specific component IDs.
|
|
152
|
-
*/
|
|
153
|
-
prebuiltBindingNames?: Map<string, Map<string, string>>;
|
|
154
148
|
/**
|
|
155
149
|
* Component ID → distinct static call-site prop objects captured from
|
|
156
150
|
* JSX usage sites during the transform and generateBundle phases.
|
|
@@ -165,12 +159,6 @@ export interface PluginContext {
|
|
|
165
159
|
* components to render under which route's param combos.
|
|
166
160
|
*/
|
|
167
161
|
routePrebuiltComponents?: Map<string, string[]>;
|
|
168
|
-
/**
|
|
169
|
-
* Page file paths that were desugared from `export const prerender` by
|
|
170
|
-
* timber-prerender-sugar. The prebuilt transform uses this to verify
|
|
171
|
-
* the generated `cache.component(...)` call was picked up.
|
|
172
|
-
*/
|
|
173
|
-
prerenderSugarPages?: Set<string>;
|
|
174
162
|
/**
|
|
175
163
|
* Component ID → built chunk file name for prebuilt-declaring modules
|
|
176
164
|
* that are only reachable via dynamic imports (import.meta.glob, lazy
|
|
@@ -179,8 +167,6 @@ export interface PluginContext {
|
|
|
179
167
|
* RSC generateBundle alongside routePrebuiltComponents.
|
|
180
168
|
*/
|
|
181
169
|
prebuiltLazyChunks?: Map<string, string>;
|
|
182
|
-
/** Post-build prebuilt capture summary (populated by timber-prebuilt, consumed by build-report). */
|
|
183
|
-
captureSummary?: CaptureSummary;
|
|
184
170
|
/**
|
|
185
171
|
* Content-keyed AST parse memo shared across cache/prebuilt/prerender-sugar
|
|
186
172
|
* transforms. Collapses both cross-plugin and cross-environment duplicate
|
|
@@ -192,18 +178,6 @@ export interface PluginContext {
|
|
|
192
178
|
* ranges and rewrite CODE via MagicString; the AST itself is never mutated.
|
|
193
179
|
*/
|
|
194
180
|
parseCached?: ParseMemo;
|
|
195
|
-
/**
|
|
196
|
-
* Content-Type mappings for extensionless static API route outputs.
|
|
197
|
-
* Populated during static generation, consumed by adapter-build to
|
|
198
|
-
* write per-path Content-Type rules in _headers. See TIM-1241.
|
|
199
|
-
*/
|
|
200
|
-
staticContentTypes?: Record<string, string>;
|
|
201
|
-
/**
|
|
202
|
-
* RSC flight payload manifest mapping unhashed → hashed URLs.
|
|
203
|
-
* Populated during static generation, consumed by adapters to set
|
|
204
|
-
* immutable cache headers for `_rsc/` files. See TIM-1254.
|
|
205
|
-
*/
|
|
206
|
-
rscManifest?: RscManifest;
|
|
207
181
|
}
|
|
208
182
|
|
|
209
183
|
// ── AST parse memo ───────────────────────────────────────────────────────
|
|
@@ -274,6 +248,30 @@ export function isTimberPluginApi(api: unknown): api is TimberPluginApi {
|
|
|
274
248
|
);
|
|
275
249
|
}
|
|
276
250
|
|
|
251
|
+
/**
|
|
252
|
+
* The configured platform adapter. `adapter` is typed `unknown` on the user
|
|
253
|
+
* config so that `timber.config.ts` does not depend on the adapter types; the
|
|
254
|
+
* adapter factories are what produce values of this shape.
|
|
255
|
+
*/
|
|
256
|
+
export function contextAdapter(ctx: PluginContext): TimberPlatformAdapter | undefined {
|
|
257
|
+
return ctx.config.adapter as TimberPlatformAdapter | undefined;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The configuration an adapter is handed, derived once from the resolved
|
|
262
|
+
* context — by the post-build phase for `buildOutput` and by `timber preview`
|
|
263
|
+
* for `preview`.
|
|
264
|
+
*/
|
|
265
|
+
export function adapterConfig(ctx: PluginContext): TimberConfig {
|
|
266
|
+
return {
|
|
267
|
+
root: ctx.root,
|
|
268
|
+
// Normalized once here, not in each adapter: the platform files
|
|
269
|
+
// adapters write address deployed-URL space (TIM-1274).
|
|
270
|
+
base: normalizeBasePath(ctx.base),
|
|
271
|
+
clientJavascriptDisabled: ctx.clientJavascript.disabled,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
277
275
|
/**
|
|
278
276
|
* Resolve the app directory. Checks (in order):
|
|
279
277
|
* 1. Explicit `configAppDir` from timber.config.ts
|
|
@@ -439,8 +437,9 @@ export function loadTimberConfigFile(root: string): TimberUserConfig | null {
|
|
|
439
437
|
|
|
440
438
|
/**
|
|
441
439
|
* Detect config keys set in both inline (vite.config.ts) and file (timber.config.ts)
|
|
442
|
-
* and warn the user.
|
|
443
|
-
*
|
|
440
|
+
* and warn the user. Only keys the inline config actually sets count — the
|
|
441
|
+
* `output` default is applied after the merge (timber-root-sync), so it never
|
|
442
|
+
* appears here as an inline key.
|
|
444
443
|
*
|
|
445
444
|
* Returns the list of conflicting key names (for testing).
|
|
446
445
|
*/
|
|
@@ -418,7 +418,7 @@ export function timberBuildManifest(ctx: PluginContext): Plugin {
|
|
|
418
418
|
|
|
419
419
|
// RSC environment: walk the module graph to find which client
|
|
420
420
|
// references each route file transitively imports. Store the
|
|
421
|
-
// mapping in ctx so the
|
|
421
|
+
// mapping in ctx so the post-build phase can cross-reference
|
|
422
422
|
// with clientReferenceDeps to populate per-route modulepreloads.
|
|
423
423
|
if (envName === 'rsc' && ctx.routeTree) {
|
|
424
424
|
const clientRefIndex = buildClientRefIndex(bundle);
|
|
@@ -475,17 +475,10 @@ export function timberBuildManifest(ctx: PluginContext): Plugin {
|
|
|
475
475
|
|
|
476
476
|
// When client JavaScript is disabled, strip JS chunks from the bundle
|
|
477
477
|
// so Rollup never writes them to disk. CSS assets are preserved —
|
|
478
|
-
// they're still needed for server-rendered HTML.
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
// build manifest and RSC assets manifest as a defense-in-depth fallback.
|
|
478
|
+
// they're still needed for server-rendered HTML. The JS references
|
|
479
|
+
// in the manifest are stripped once, by the post-build phase, after
|
|
480
|
+
// it has merged in everything else (plugins/post-build.ts).
|
|
482
481
|
if (ctx.clientJavascript.disabled) {
|
|
483
|
-
// Clear JS and modulepreload from the manifest (they'd be stripped
|
|
484
|
-
// by adapter-build.ts anyway, but doing it here avoids the round-trip).
|
|
485
|
-
ctx.buildManifest.js = {};
|
|
486
|
-
ctx.buildManifest.modulepreload = {};
|
|
487
|
-
|
|
488
|
-
// Remove JS chunks from the Rollup bundle — prevents disk writes.
|
|
489
482
|
for (const [fileName, item] of Object.entries(bundle)) {
|
|
490
483
|
if (item.type === 'chunk') {
|
|
491
484
|
delete bundle[fileName];
|
|
@@ -20,6 +20,7 @@ import type { Plugin, Logger } from 'vite';
|
|
|
20
20
|
import type { PluginContext } from '../plugin-context.ts';
|
|
21
21
|
import type { SegmentNode, RouteTree } from '../routing/types.ts';
|
|
22
22
|
import type { CaptureSummary } from '../server/prebuilt-builder.ts';
|
|
23
|
+
import type { PrebuiltCaptureResult } from './prebuilt-capture.ts';
|
|
23
24
|
import type { PrebuiltManifest } from '../server/prebuilt/payload-source.ts';
|
|
24
25
|
import { collectLeafRoutes } from '../routing/walkers.ts';
|
|
25
26
|
import { formatSize } from '../utils/format.ts';
|
|
@@ -199,13 +200,10 @@ export interface PrebuiltReportData {
|
|
|
199
200
|
skippedReasons: Array<{ componentId: string; route: string; message: string }>;
|
|
200
201
|
}
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
} catch {
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
203
|
+
/** Read the manifest of the prebuilt artifact this build recorded, if any. */
|
|
204
|
+
export function loadPrebuiltManifest(prebuiltDir: string | undefined): PrebuiltManifest | null {
|
|
205
|
+
if (!prebuiltDir) return null;
|
|
206
|
+
return JSON.parse(readFileSync(join(prebuiltDir, 'manifest.json'), 'utf-8')) as PrebuiltManifest;
|
|
209
207
|
}
|
|
210
208
|
|
|
211
209
|
export function buildPrebuiltReportData(
|
|
@@ -488,17 +486,79 @@ function suppressNonClientLogs(config: { command: string; logger: Logger }): voi
|
|
|
488
486
|
};
|
|
489
487
|
}
|
|
490
488
|
|
|
491
|
-
|
|
489
|
+
/**
|
|
490
|
+
* What the post-build phase asks of the build report (plugins/post-build.ts).
|
|
491
|
+
* Printed from there, once, after every environment is built and after the
|
|
492
|
+
* prebuilt capture pass — so nothing here depends on the order in which
|
|
493
|
+
* Vite closes each environment's bundle.
|
|
494
|
+
*/
|
|
495
|
+
export interface BuildReportStep {
|
|
496
|
+
print(prebuilt: PrebuiltCaptureResult | null): void;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export function timberBuildReport(ctx: PluginContext): Plugin & { api: BuildReportStep } {
|
|
492
500
|
let logger: Logger | null = null;
|
|
493
501
|
let chunkSizes: Map<string, ChunkSize> | null = null;
|
|
494
502
|
let clientBundle: Record<string, OutputChunkLike> | null = null;
|
|
495
|
-
let reported = false;
|
|
496
|
-
let deferReport = false;
|
|
497
503
|
const buildStart = performance.now();
|
|
498
504
|
|
|
505
|
+
function printRouteTable(): void {
|
|
506
|
+
if (!ctx.routeTree || !chunkSizes || !clientBundle || !logger) return;
|
|
507
|
+
|
|
508
|
+
const outputMode = ctx.config.output ?? 'server';
|
|
509
|
+
const clientJsDisabled = ctx.clientJavascript.disabled;
|
|
510
|
+
const { entries, sharedGzip } = clientJsDisabled
|
|
511
|
+
? {
|
|
512
|
+
entries: collectRoutes(ctx.routeTree).map((info) => ({
|
|
513
|
+
path: info.path,
|
|
514
|
+
type: classifyRoute(info.segments, outputMode),
|
|
515
|
+
size: 0,
|
|
516
|
+
firstLoadSize: 0,
|
|
517
|
+
})),
|
|
518
|
+
sharedGzip: 0,
|
|
519
|
+
}
|
|
520
|
+
: buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode, ctx.appDir, ctx.root);
|
|
521
|
+
const elapsed = ((performance.now() - buildStart) / 1000).toFixed(2);
|
|
522
|
+
const lines = buildRouteReport(entries, sharedGzip);
|
|
523
|
+
|
|
524
|
+
logger.info('');
|
|
525
|
+
for (const line of lines) logger.info(line);
|
|
526
|
+
|
|
527
|
+
const warnings = buildWarnings(entries, ctx.config.budget);
|
|
528
|
+
if (warnings.length > 0) {
|
|
529
|
+
logger.info('');
|
|
530
|
+
for (const w of warnings) logger.warn(w);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
logger.info('');
|
|
534
|
+
logger.info(
|
|
535
|
+
`✓ built ${entries.length} routes for all three environments (rsc, ssr, client) in ${elapsed}s`
|
|
536
|
+
);
|
|
537
|
+
logger.info('');
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function printPrebuiltReport(prebuilt: PrebuiltCaptureResult | null): void {
|
|
541
|
+
if (!logger || !prebuilt) return;
|
|
542
|
+
const manifest = loadPrebuiltManifest(prebuilt.artifact?.path);
|
|
543
|
+
const prebuiltData = buildPrebuiltReportData(manifest, prebuilt.summary);
|
|
544
|
+
if (!prebuiltData) return;
|
|
545
|
+
|
|
546
|
+
logger.info('');
|
|
547
|
+
for (const line of buildPrebuiltReport(prebuiltData)) logger.info(line);
|
|
548
|
+
logger.info('');
|
|
549
|
+
}
|
|
550
|
+
|
|
499
551
|
return {
|
|
500
552
|
name: 'timber-build-report',
|
|
501
553
|
|
|
554
|
+
api: {
|
|
555
|
+
print(prebuilt) {
|
|
556
|
+
if (ctx.dev) return;
|
|
557
|
+
printRouteTable();
|
|
558
|
+
printPrebuiltReport(prebuilt);
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
|
|
502
562
|
config(_cfg, { command }) {
|
|
503
563
|
if (command !== 'build') return;
|
|
504
564
|
return {
|
|
@@ -520,66 +580,6 @@ export function timberBuildReport(ctx: PluginContext): Plugin {
|
|
|
520
580
|
|
|
521
581
|
chunkSizes = collectChunkSizes(bundle as Record<string, OutputChunkLike>);
|
|
522
582
|
clientBundle = { ...bundle } as Record<string, OutputChunkLike>;
|
|
523
|
-
deferReport = true; // skip client's closeBundle; emit after SSR's
|
|
524
|
-
},
|
|
525
|
-
|
|
526
|
-
closeBundle() {
|
|
527
|
-
if (ctx.dev || reported) return;
|
|
528
|
-
|
|
529
|
-
// The client build's closeBundle fires before SSR starts.
|
|
530
|
-
// Defer one cycle so the report appears after all builds complete.
|
|
531
|
-
if (deferReport) {
|
|
532
|
-
deferReport = false;
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
if (!ctx.routeTree || !chunkSizes || !clientBundle || !logger) return;
|
|
536
|
-
|
|
537
|
-
reported = true;
|
|
538
|
-
const outputMode = ctx.config.output ?? 'server';
|
|
539
|
-
const clientJsDisabled = ctx.clientJavascript.disabled;
|
|
540
|
-
const { entries, sharedGzip } = clientJsDisabled
|
|
541
|
-
? {
|
|
542
|
-
entries: collectRoutes(ctx.routeTree).map((info) => ({
|
|
543
|
-
path: info.path,
|
|
544
|
-
type: classifyRoute(info.segments, outputMode),
|
|
545
|
-
size: 0,
|
|
546
|
-
firstLoadSize: 0,
|
|
547
|
-
})),
|
|
548
|
-
sharedGzip: 0,
|
|
549
|
-
}
|
|
550
|
-
: buildEntries(ctx.routeTree, chunkSizes, clientBundle, outputMode, ctx.appDir, ctx.root);
|
|
551
|
-
const elapsed = ((performance.now() - buildStart) / 1000).toFixed(2);
|
|
552
|
-
const lines = buildRouteReport(entries, sharedGzip);
|
|
553
|
-
|
|
554
|
-
logger.info('');
|
|
555
|
-
for (const line of lines) logger.info(line);
|
|
556
|
-
|
|
557
|
-
const warnings = buildWarnings(entries, ctx.config.budget);
|
|
558
|
-
if (warnings.length > 0) {
|
|
559
|
-
logger.info('');
|
|
560
|
-
for (const w of warnings) logger.warn(w);
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
logger.info('');
|
|
564
|
-
logger.info(
|
|
565
|
-
`✓ built ${entries.length} routes for all three environments (rsc, ssr, client) in ${elapsed}s`
|
|
566
|
-
);
|
|
567
|
-
logger.info('');
|
|
568
|
-
},
|
|
569
|
-
|
|
570
|
-
buildApp: {
|
|
571
|
-
order: 'post' as const,
|
|
572
|
-
async handler() {
|
|
573
|
-
if (ctx.dev || !logger) return;
|
|
574
|
-
const manifest = loadPrebuiltManifest(ctx.buildDir);
|
|
575
|
-
const prebuiltData = buildPrebuiltReportData(manifest, ctx.captureSummary);
|
|
576
|
-
if (!prebuiltData) return;
|
|
577
|
-
|
|
578
|
-
logger.info('');
|
|
579
|
-
const prebuiltLines = buildPrebuiltReport(prebuiltData);
|
|
580
|
-
for (const line of prebuiltLines) logger.info(line);
|
|
581
|
-
logger.info('');
|
|
582
|
-
},
|
|
583
583
|
},
|
|
584
584
|
};
|
|
585
585
|
}
|
|
@@ -22,12 +22,15 @@ import type { PluginContext } from '../plugin-context.ts';
|
|
|
22
22
|
import {
|
|
23
23
|
sendErrorToOverlay,
|
|
24
24
|
classifyErrorPhase,
|
|
25
|
-
fixErrorStacktrace,
|
|
26
25
|
parseFirstAppFrame,
|
|
27
26
|
type ErrorPhase,
|
|
28
27
|
} from '../dev-tools/overlay.ts';
|
|
29
28
|
import { generateDevErrorPage } from '../dev-tools/error-page.ts';
|
|
30
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
extractHmrOptions,
|
|
31
|
+
type DevErrorHmrOptions,
|
|
32
|
+
type DevHooks,
|
|
33
|
+
} from '../dev-tools/dev-page-shell.ts';
|
|
31
34
|
import { addVirtualModuleContext } from '../config-validation.ts';
|
|
32
35
|
import { registerDevDiscovery } from './dev-discovery.ts';
|
|
33
36
|
import {
|
|
@@ -36,7 +39,6 @@ import {
|
|
|
36
39
|
type GraphUpdateChannel,
|
|
37
40
|
} from './graph-endpoint.ts';
|
|
38
41
|
import { compressResponse } from '../server/compress.ts';
|
|
39
|
-
import { isSsrStreamError } from '../server/primitives.ts';
|
|
40
42
|
import { isMetadataRouteServePath } from '../server/metadata-routes.ts';
|
|
41
43
|
import { canonicalize } from '../server/canonicalize.ts';
|
|
42
44
|
import { matchUrlParts } from '../server/tree-match.ts';
|
|
@@ -317,37 +319,18 @@ function createTimberMiddleware(server: ViteDevServer, ctx: PluginContext) {
|
|
|
317
319
|
const rscModule = await rscEnv.runner.import(RSC_ENTRY_ID);
|
|
318
320
|
handler = rscModule.default as (req: Request) => Promise<Response>;
|
|
319
321
|
|
|
320
|
-
// Wire pipeline errors into the browser error overlay
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
| undefined;
|
|
329
|
-
if (config) {
|
|
330
|
-
config.devPipelineErrorHandler = (error) => {
|
|
322
|
+
// Wire pipeline errors into the browser error overlay, and plumb the
|
|
323
|
+
// resolved HMR options into the RSC environment. The RSC entry can't
|
|
324
|
+
// read the Vite server config (separate module graph), but its dev 404
|
|
325
|
+
// page and fallback error page need the HMR endpoint (including Vite
|
|
326
|
+
// 8's required WS token) for auto-reload (TIM-1067).
|
|
327
|
+
const setDevHooks = rscModule.setDevHooks as ((hooks: DevHooks) => void) | undefined;
|
|
328
|
+
setDevHooks?.({
|
|
329
|
+
onPipelineError: (error) => {
|
|
331
330
|
sendErrorToOverlay(server, error, classifyErrorPhase(error, projectRoot), projectRoot);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// but its dev 404 page and fallback error page need the HMR endpoint
|
|
336
|
-
// (including Vite 8's required WS token) for auto-reload (TIM-1067).
|
|
337
|
-
config.devHmrOptions = hmrOptions;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Wire source-map handler so error pages show original positions.
|
|
341
|
-
// fixErrorStacktrace rewrites the error's stack trace in-place using
|
|
342
|
-
// the Vite dev server's module graph. See TIM-811.
|
|
343
|
-
const setSourceMap = rscModule.setDevSourceMapHandler as
|
|
344
|
-
| ((fn: (error: Error) => void) => void)
|
|
345
|
-
| undefined;
|
|
346
|
-
if (typeof setSourceMap === 'function') {
|
|
347
|
-
setSourceMap((error: Error) => {
|
|
348
|
-
fixErrorStacktrace(server, error);
|
|
349
|
-
});
|
|
350
|
-
}
|
|
331
|
+
},
|
|
332
|
+
hmrOptions,
|
|
333
|
+
});
|
|
351
334
|
} catch (error) {
|
|
352
335
|
// Module transform error — syntax error, missing import, etc.
|
|
353
336
|
// Vite may already show its own overlay for these, but we still
|
|
@@ -404,18 +387,15 @@ function createTimberMiddleware(server: ViteDevServer, ctx: PluginContext) {
|
|
|
404
387
|
// srvx skips its own writeHead since headers are already sent.
|
|
405
388
|
await sendNodeResponse(res, finalResponse);
|
|
406
389
|
} catch (error) {
|
|
407
|
-
//
|
|
408
|
-
//
|
|
390
|
+
// An error the pipeline did not turn into a response, or one sending
|
|
391
|
+
// the response threw — classify the phase, send to overlay, respond
|
|
392
|
+
// 500. The pipeline answers render errors itself (an SsrStreamError
|
|
393
|
+
// never gets here), so this sees the error as thrown. The dev server
|
|
394
|
+
// remains running for recovery on file fix + HMR.
|
|
409
395
|
if (error instanceof Error) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
// "useSegmentParams is not a function"), not the wrapper.
|
|
414
|
-
const displayError =
|
|
415
|
-
isSsrStreamError(error) && error.cause instanceof Error ? error.cause : error;
|
|
416
|
-
const phase = classifyErrorPhase(displayError, projectRoot);
|
|
417
|
-
sendErrorToOverlay(server, displayError, phase, projectRoot);
|
|
418
|
-
respond500(res, displayError, phase, projectRoot, hmrOptions);
|
|
396
|
+
const phase = classifyErrorPhase(error, projectRoot);
|
|
397
|
+
sendErrorToOverlay(server, error, phase, projectRoot);
|
|
398
|
+
respond500(res, error, phase, projectRoot, hmrOptions);
|
|
419
399
|
} else {
|
|
420
400
|
process.stderr.write(`\x1b[31m[timber] Dev server error:\x1b[0m ${String(error)}\n`);
|
|
421
401
|
respond500(res, error, 'render', projectRoot, hmrOptions);
|
package/src/plugins/entries.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { resolve, dirname } from 'node:path';
|
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
17
|
import { existsSync } from 'node:fs';
|
|
18
18
|
import type { PluginContext } from '../plugin-context.ts';
|
|
19
|
+
import { resolveRenderTimeoutMs } from '../server/render-timeout.ts';
|
|
19
20
|
|
|
20
21
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
22
|
|
|
@@ -146,7 +147,7 @@ function generateConfigModule(ctx: PluginContext): string {
|
|
|
146
147
|
topLoader: ctx.config.topLoader,
|
|
147
148
|
debug: ctx.config.debug ?? false,
|
|
148
149
|
serverTiming: ctx.config.serverTiming,
|
|
149
|
-
renderTimeoutMs: ctx.config.renderTimeoutMs
|
|
150
|
+
renderTimeoutMs: resolveRenderTimeoutMs(ctx.config.renderTimeoutMs),
|
|
150
151
|
// Auto-generated sitemap config — opt-in via timber.config.ts.
|
|
151
152
|
// See design/16-metadata.md §"Auto-generated Sitemap"
|
|
152
153
|
sitemap: ctx.config.sitemap,
|
package/src/plugins/fonts.ts
CHANGED
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
import { parseAst } from 'vite';
|
|
22
22
|
import type { Plugin, ResolvedConfig, ViteDevServer } from 'vite';
|
|
23
23
|
import type { PluginContext } from '../plugin-context.ts';
|
|
24
|
+
import type { BuildManifest } from '../server/build-manifest.ts';
|
|
24
25
|
import {
|
|
25
26
|
downloadAndCacheFonts,
|
|
26
27
|
generateProductionFontFaces,
|
|
27
28
|
resolveDevFontFaces,
|
|
28
29
|
} from '../fonts/google.ts';
|
|
29
|
-
import { fontUrlPrefix } from '../fonts/paths.ts';
|
|
30
|
+
import { FONT_OUTPUT_DIR, fontUrlPrefix } from '../fonts/paths.ts';
|
|
30
31
|
import { FontPipeline } from '../fonts/pipeline.ts';
|
|
31
32
|
import { runFontsTransform } from '../fonts/transform.ts';
|
|
32
33
|
import { installFontDevMiddleware } from '../fonts/dev-middleware.ts';
|
|
@@ -57,15 +58,38 @@ export {
|
|
|
57
58
|
parseLocalFontImportName,
|
|
58
59
|
} from '../fonts/transform.ts';
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* What the post-build phase asks of the font plugin (plugins/post-build.ts).
|
|
63
|
+
* Called after every environment has been built, so the font entries are
|
|
64
|
+
* complete — no environment's `generateBundle` has to run after the build
|
|
65
|
+
* manifest exists.
|
|
66
|
+
*/
|
|
67
|
+
export interface FontsBuildStep {
|
|
68
|
+
/** Write this build's font entries into the build manifest. */
|
|
69
|
+
contributeManifest(manifest: BuildManifest): void;
|
|
70
|
+
/**
|
|
71
|
+
* Directories of the client bundle this build filled with content-hashed
|
|
72
|
+
* font binaries — `[FONT_OUTPUT_DIR]` when any were emitted, else none.
|
|
73
|
+
*/
|
|
74
|
+
immutableDirs(): string[];
|
|
75
|
+
}
|
|
76
|
+
|
|
60
77
|
/**
|
|
61
78
|
* Create the timber-fonts Vite plugin.
|
|
62
79
|
*/
|
|
63
|
-
export function timberFonts(ctx: PluginContext): Plugin {
|
|
80
|
+
export function timberFonts(ctx: PluginContext): Plugin & { api: FontsBuildStep } {
|
|
64
81
|
const pipeline = new FontPipeline({ hashOnRegister: !ctx.dev });
|
|
82
|
+
/** Whether the client environment emitted a binary this build. */
|
|
83
|
+
let emittedToClient = false;
|
|
65
84
|
|
|
66
85
|
return {
|
|
67
86
|
name: 'timber-fonts',
|
|
68
87
|
|
|
88
|
+
api: {
|
|
89
|
+
contributeManifest: (manifest) => writeFontManifest(pipeline, manifest, ctx.base),
|
|
90
|
+
immutableDirs: () => (emittedToClient ? [FONT_OUTPUT_DIR] : []),
|
|
91
|
+
},
|
|
92
|
+
|
|
69
93
|
/**
|
|
70
94
|
* Push Vite's resolved `base` into the pipeline so every font URL it
|
|
71
95
|
* emits (@font-face src, manifest hrefs, dev middleware matching)
|
|
@@ -289,20 +313,24 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
289
313
|
},
|
|
290
314
|
|
|
291
315
|
/**
|
|
292
|
-
* Emit font binaries
|
|
316
|
+
* Emit font binaries.
|
|
293
317
|
*
|
|
294
318
|
* All font binaries (Google and local) use content-hashed filenames
|
|
295
319
|
* for immutable caching. Font CSS is handled by Vite's CSS pipeline
|
|
296
|
-
* via virtual modules — we only emit binaries here.
|
|
320
|
+
* via virtual modules — we only emit binaries here. Manifest entries are
|
|
321
|
+
* written by the post-build phase through `api.contributeManifest`.
|
|
297
322
|
*/
|
|
298
323
|
generateBundle() {
|
|
324
|
+
let emitted = 0;
|
|
299
325
|
emitFontAssets(
|
|
300
326
|
pipeline,
|
|
301
|
-
(asset) =>
|
|
327
|
+
(asset) => {
|
|
328
|
+
emitted++;
|
|
329
|
+
return this.emitFile(asset);
|
|
330
|
+
},
|
|
302
331
|
(msg) => this.warn(msg)
|
|
303
332
|
);
|
|
304
|
-
if (
|
|
305
|
-
writeFontManifest(pipeline, ctx.buildManifest, ctx.base);
|
|
333
|
+
if (this.environment?.name === 'client') emittedToClient = emitted > 0;
|
|
306
334
|
},
|
|
307
335
|
};
|
|
308
336
|
}
|