@timber-js/app 0.2.0-alpha.7 → 0.2.0-alpha.71
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/LICENSE +8 -0
- package/dist/_chunks/{als-registry-B7DbZ2hS.js → als-registry-BJARkOcu.js} +1 -1
- package/dist/_chunks/als-registry-BJARkOcu.js.map +1 -0
- package/dist/_chunks/chunk-DYhsFzuS.js +33 -0
- package/dist/_chunks/{debug-gwlJkDuf.js → debug-ECi_61pb.js} +2 -2
- package/dist/_chunks/debug-ECi_61pb.js.map +1 -0
- package/dist/_chunks/define-CGuYoRHU.js +199 -0
- package/dist/_chunks/define-CGuYoRHU.js.map +1 -0
- package/dist/_chunks/define-Dz1bqwaS.js +106 -0
- package/dist/_chunks/define-Dz1bqwaS.js.map +1 -0
- package/dist/_chunks/define-cookie-B5mewxwM.js +93 -0
- package/dist/_chunks/define-cookie-B5mewxwM.js.map +1 -0
- package/dist/_chunks/error-boundary-D9hzsveV.js +216 -0
- package/dist/_chunks/error-boundary-D9hzsveV.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → format-Rn922VH2.js} +3 -20
- package/dist/_chunks/format-Rn922VH2.js.map +1 -0
- package/dist/_chunks/{tracing-Cwn7697K.js → handler-store-BVePM7hp.js} +68 -3
- package/dist/_chunks/handler-store-BVePM7hp.js.map +1 -0
- package/dist/_chunks/{interception-BOoWmLUA.js → interception-CEdHHviP.js} +171 -97
- package/dist/_chunks/interception-CEdHHviP.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DS3eKNmf.js} +1 -1
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js.map → metadata-routes-DS3eKNmf.js.map} +1 -1
- package/dist/_chunks/{request-context-DIkVh_jG.js → request-context-CywiO4jV.js} +181 -69
- package/dist/_chunks/request-context-CywiO4jV.js.map +1 -0
- package/dist/_chunks/schema-bridge-C4SwjCQD.js +86 -0
- package/dist/_chunks/schema-bridge-C4SwjCQD.js.map +1 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js +65 -0
- package/dist/_chunks/segment-classify-BDNn6EzD.js.map +1 -0
- package/dist/_chunks/segment-context-hzuJ048X.js +72 -0
- package/dist/_chunks/segment-context-hzuJ048X.js.map +1 -0
- package/dist/_chunks/stale-reload-BLUC_Pl_.js +64 -0
- package/dist/_chunks/stale-reload-BLUC_Pl_.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-DAhgj8Gx.js} +1 -1
- package/dist/_chunks/use-query-states-DAhgj8Gx.js.map +1 -0
- package/dist/_chunks/wrappers-LZbghvn0.js +63 -0
- package/dist/_chunks/wrappers-LZbghvn0.js.map +1 -0
- package/dist/adapters/cloudflare-dev.d.ts +109 -0
- package/dist/adapters/cloudflare-dev.d.ts.map +1 -0
- package/dist/adapters/cloudflare-dev.js +73 -0
- package/dist/adapters/cloudflare-dev.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +148 -12
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +135 -11
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/nitro.d.ts +17 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +56 -13
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/fast-hash.d.ts +22 -0
- package/dist/cache/fast-hash.d.ts.map +1 -0
- package/dist/cache/handler-store.d.ts +31 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +7 -5
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +111 -73
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/singleflight.d.ts +18 -1
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/client/error-boundary.d.ts +12 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -125
- package/dist/client/error-reconstituter.d.ts +54 -0
- package/dist/client/error-reconstituter.d.ts.map +1 -0
- package/dist/client/form.d.ts +2 -2
- package/dist/client/form.d.ts.map +1 -1
- package/dist/client/history.d.ts +19 -4
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +6 -5
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +537 -166
- package/dist/client/index.js.map +1 -1
- package/dist/client/link-pending-store.d.ts +78 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +90 -32
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/nav-link-store.d.ts +36 -0
- package/dist/client/nav-link-store.d.ts.map +1 -0
- package/dist/client/navigation-api-types.d.ts +90 -0
- package/dist/client/navigation-api-types.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts +115 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +13 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +42 -8
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router.d.ts +70 -4
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +38 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +1 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-context.d.ts +1 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-merger.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +63 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +13 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-reload.d.ts +15 -0
- package/dist/client/stale-reload.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +3 -3
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-params.d.ts +6 -4
- package/dist/client/use-params.d.ts.map +1 -1
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/codec.d.ts +23 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +2 -0
- package/dist/cookies/define-cookie.d.ts +35 -14
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -0
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +3 -84
- package/dist/fonts/css.d.ts +1 -0
- package/dist/fonts/css.d.ts.map +1 -1
- package/dist/index.d.ts +154 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12092 -11916
- package/dist/index.js.map +1 -1
- package/dist/plugins/adapter-build.d.ts +1 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +2 -2
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +3 -3
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +32 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/content.d.ts +1 -1
- package/dist/plugins/content.d.ts.map +1 -1
- package/dist/plugins/dev-browser-logs.d.ts +84 -0
- package/dist/plugins/dev-browser-logs.d.ts.map +1 -0
- package/dist/plugins/dev-error-overlay.d.ts +26 -1
- package/dist/plugins/dev-error-overlay.d.ts.map +1 -1
- package/dist/plugins/dev-logs.d.ts +1 -1
- package/dist/plugins/dev-logs.d.ts.map +1 -1
- package/dist/plugins/dev-server.d.ts +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +19 -5
- package/dist/plugins/fonts.d.ts.map +1 -1
- package/dist/plugins/mdx.d.ts +1 -1
- package/dist/plugins/mdx.d.ts.map +1 -1
- package/dist/plugins/routing.d.ts +1 -1
- package/dist/plugins/routing.d.ts.map +1 -1
- package/dist/plugins/server-bundle.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts +6 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +1 -1
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen.d.ts +2 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +3 -2
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/segment-classify.d.ts +46 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/status-file-lint.d.ts +2 -1
- package/dist/routing/status-file-lint.d.ts.map +1 -1
- package/dist/routing/types.d.ts +16 -4
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/rsc-runtime/rsc.d.ts +1 -1
- package/dist/rsc-runtime/rsc.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +12 -0
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/schema-bridge.d.ts +76 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +139 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -6
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +4 -474
- package/dist/search-params/registry.d.ts +1 -1
- package/dist/search-params/wrappers.d.ts +53 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/segment-params/define.d.ts +78 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +7 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +4 -0
- package/dist/server/access-gate.d.ts +4 -0
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +12 -1
- package/dist/server/action-client.d.ts.map +1 -1
- package/dist/server/action-encryption.d.ts +76 -0
- package/dist/server/action-encryption.d.ts.map +1 -0
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +3 -6
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +32 -4
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +2 -2
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/debug.d.ts +1 -1
- package/dist/server/default-logger.d.ts +22 -0
- package/dist/server/default-logger.d.ts.map +1 -0
- package/dist/server/deny-page-resolver.d.ts +52 -0
- package/dist/server/deny-page-resolver.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-warnings.d.ts +0 -14
- package/dist/server/dev-warnings.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -5
- package/dist/server/early-hints.d.ts.map +1 -1
- package/dist/server/error-boundary-wrapper.d.ts +7 -1
- package/dist/server/error-boundary-wrapper.d.ts.map +1 -1
- package/dist/server/fallback-error.d.ts +4 -3
- package/dist/server/fallback-error.d.ts.map +1 -1
- package/dist/server/flight-injection-state.d.ts +66 -0
- package/dist/server/flight-injection-state.d.ts.map +1 -0
- package/dist/server/flight-scripts.d.ts +42 -0
- package/dist/server/flight-scripts.d.ts.map +1 -0
- package/dist/server/flush.d.ts.map +1 -1
- package/dist/server/form-data.d.ts +29 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +51 -11
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2176 -1663
- package/dist/server/index.js.map +1 -1
- package/dist/server/logger.d.ts +25 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +113 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/page-deny-boundary.d.ts +31 -0
- package/dist/server/page-deny-boundary.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +1 -1
- package/dist/server/pipeline-interception.d.ts.map +1 -1
- package/dist/server/pipeline-metadata.d.ts +6 -0
- package/dist/server/pipeline-metadata.d.ts.map +1 -1
- package/dist/server/pipeline.d.ts +32 -10
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts +30 -3
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +76 -37
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +27 -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 +9 -2
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/api-handler.d.ts +2 -2
- package/dist/server/rsc-entry/api-handler.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts +26 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +48 -5
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +8 -3
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-payload.d.ts +3 -3
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +10 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +19 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sitemap-generator.d.ts +129 -0
- package/dist/server/sitemap-generator.d.ts.map +1 -0
- package/dist/server/sitemap-handler.d.ts +22 -0
- package/dist/server/sitemap-handler.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +1 -1
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts +22 -0
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +39 -21
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +50 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +1 -1
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +36 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +10 -0
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +22 -19
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/server/waituntil-bridge.d.ts.map +1 -1
- package/dist/shared/merge-search-params.d.ts +22 -0
- package/dist/shared/merge-search-params.d.ts.map +1 -0
- package/dist/shims/font-google.d.ts +1 -1
- package/dist/shims/font-google.d.ts.map +1 -1
- package/dist/shims/font-google.js +42 -0
- package/dist/shims/font-google.js.map +1 -0
- package/dist/shims/font-local.d.ts +26 -0
- package/dist/shims/font-local.d.ts.map +1 -0
- package/dist/shims/font-local.js +20 -0
- package/dist/shims/font-local.js.map +1 -0
- package/dist/shims/navigation-client.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.d.ts.map +1 -1
- package/dist/utils/directive-parser.d.ts +5 -2
- package/dist/utils/directive-parser.d.ts.map +1 -1
- package/dist/utils/state-machine.d.ts +80 -0
- package/dist/utils/state-machine.d.ts.map +1 -0
- package/package.json +37 -17
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare.ts +342 -28
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +58 -9
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -0
- package/src/cache/fast-hash.ts +34 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +9 -5
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/timber-cache.ts +40 -29
- package/src/cli.ts +0 -0
- package/src/client/browser-entry.ts +314 -142
- package/src/client/error-boundary.tsx +48 -16
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +2 -2
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +13 -4
- package/src/client/link-pending-store.ts +136 -0
- package/src/client/link.tsx +346 -105
- package/src/client/nav-link-store.ts +47 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +332 -0
- package/src/client/navigation-context.ts +27 -6
- package/src/client/navigation-root.tsx +346 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router.ts +302 -77
- package/src/client/rsc-fetch.ts +93 -5
- package/src/client/segment-cache.ts +1 -1
- package/src/client/segment-context.ts +6 -1
- package/src/client/segment-merger.ts +2 -8
- package/src/client/segment-outlet.tsx +86 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +73 -6
- package/src/client/top-loader.tsx +22 -13
- package/src/client/use-navigation-pending.ts +1 -1
- package/src/client/use-params.ts +7 -5
- package/src/client/use-query-states.ts +2 -2
- package/src/codec.ts +34 -0
- package/src/cookies/define-cookie.ts +72 -21
- package/src/cookies/index.ts +7 -0
- package/src/fonts/css.ts +2 -1
- package/src/index.ts +328 -92
- package/src/plugins/adapter-build.ts +8 -2
- package/src/plugins/build-manifest.ts +13 -2
- package/src/plugins/build-report.ts +3 -3
- package/src/plugins/client-chunks.ts +65 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-browser-logs.ts +288 -0
- package/src/plugins/dev-error-overlay.ts +70 -1
- package/src/plugins/dev-logs.ts +1 -1
- package/src/plugins/dev-server.ts +55 -9
- package/src/plugins/entries.ts +70 -9
- package/src/plugins/fonts.ts +167 -61
- package/src/plugins/mdx.ts +1 -1
- package/src/plugins/routing.ts +57 -17
- package/src/plugins/server-action-exports.ts +1 -1
- package/src/plugins/server-bundle.ts +32 -1
- package/src/plugins/shims.ts +76 -33
- package/src/plugins/static-build.ts +10 -6
- package/src/routing/codegen.ts +165 -105
- package/src/routing/index.ts +2 -0
- package/src/routing/scanner.ts +93 -23
- package/src/routing/segment-classify.ts +89 -0
- package/src/routing/status-file-lint.ts +3 -2
- package/src/routing/types.ts +17 -4
- package/src/rsc-runtime/rsc.ts +2 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/{search-params/codecs.ts → schema-bridge.ts} +57 -20
- package/src/search-params/define.ts +482 -0
- package/src/search-params/index.ts +13 -19
- package/src/search-params/registry.ts +1 -1
- package/src/search-params/wrappers.ts +85 -0
- package/src/segment-params/define.ts +279 -0
- package/src/segment-params/index.ts +28 -0
- package/src/server/access-gate.tsx +70 -29
- package/src/server/action-client.ts +28 -3
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +20 -3
- package/src/server/actions.ts +10 -9
- package/src/server/als-registry.ts +32 -4
- package/src/server/build-manifest.ts +10 -4
- package/src/server/compress.ts +25 -7
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-page-resolver.ts +154 -0
- package/src/server/deny-renderer.ts +24 -38
- package/src/server/dev-warnings.ts +2 -28
- package/src/server/early-hints.ts +36 -15
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +31 -15
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/flush.ts +2 -1
- package/src/server/form-data.ts +76 -0
- package/src/server/html-injectors.ts +277 -117
- package/src/server/index.ts +9 -5
- package/src/server/logger.ts +44 -36
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +509 -0
- package/src/server/page-deny-boundary.tsx +56 -0
- package/src/server/pipeline-interception.ts +17 -16
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline.ts +195 -51
- package/src/server/primitives.ts +47 -5
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +240 -117
- package/src/server/route-element-builder.ts +284 -197
- package/src/server/route-handler.ts +24 -4
- package/src/server/route-matcher.ts +24 -20
- package/src/server/rsc-entry/api-handler.ts +15 -16
- package/src/server/rsc-entry/error-renderer.ts +300 -89
- package/src/server/rsc-entry/helpers.ts +134 -5
- package/src/server/rsc-entry/index.ts +202 -113
- package/src/server/rsc-entry/rsc-payload.ts +100 -21
- package/src/server/rsc-entry/rsc-stream.ts +74 -18
- package/src/server/rsc-entry/ssr-bridge.ts +14 -5
- package/src/server/rsc-entry/ssr-renderer.ts +173 -40
- package/src/server/safe-load.ts +60 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +126 -0
- package/src/server/slot-resolver.ts +243 -228
- package/src/server/ssr-entry.ts +211 -32
- package/src/server/ssr-render.ts +289 -67
- package/src/server/ssr-wrappers.tsx +139 -0
- package/src/server/status-code-resolver.ts +1 -1
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +37 -3
- package/src/server/tree-builder.ts +92 -58
- package/src/server/types.ts +3 -6
- package/src/server/version-skew.ts +104 -0
- package/src/server/waituntil-bridge.ts +4 -1
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/navigation-client.ts +1 -1
- package/src/shims/navigation.ts +2 -1
- package/src/utils/directive-parser.ts +5 -2
- package/src/utils/state-machine.ts +111 -0
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/request-context-DIkVh_jG.js.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js +0 -88
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-Cwn7697K.js.map +0 -1
- package/dist/_chunks/use-cookie-DX-l1_5E.js +0 -91
- package/dist/_chunks/use-cookie-DX-l1_5E.js.map +0 -1
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/cache/register-cached-function.d.ts +0 -17
- package/dist/cache/register-cached-function.d.ts.map +0 -1
- package/dist/client/error-boundary.js.map +0 -1
- package/dist/client/link-status-provider.d.ts +0 -11
- package/dist/client/link-status-provider.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/cookies/index.js.map +0 -1
- package/dist/plugins/cache-transform.d.ts +0 -36
- package/dist/plugins/cache-transform.d.ts.map +0 -1
- package/dist/plugins/dynamic-transform.d.ts +0 -72
- package/dist/plugins/dynamic-transform.d.ts.map +0 -1
- package/dist/search-params/analyze.d.ts +0 -54
- package/dist/search-params/analyze.d.ts.map +0 -1
- package/dist/search-params/builtin-codecs.d.ts +0 -105
- package/dist/search-params/builtin-codecs.d.ts.map +0 -1
- package/dist/search-params/codecs.d.ts +0 -53
- package/dist/search-params/codecs.d.ts.map +0 -1
- package/dist/search-params/create.d.ts +0 -106
- package/dist/search-params/create.d.ts.map +0 -1
- package/dist/search-params/index.js.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/server/response-cache.d.ts +0 -53
- package/dist/server/response-cache.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -99
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/transition-root.tsx +0 -160
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/search-params/analyze.ts +0 -192
- package/src/search-params/builtin-codecs.ts +0 -228
- package/src/search-params/create.ts +0 -321
- package/src/server/prerender.ts +0 -139
- package/src/server/response-cache.ts +0 -277
package/src/plugins/entries.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { Plugin } from 'vite';
|
|
|
15
15
|
import { resolve, dirname } from 'node:path';
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
17
|
import { existsSync } from 'node:fs';
|
|
18
|
-
import type { PluginContext } from '
|
|
18
|
+
import type { PluginContext } from '../index.js';
|
|
19
19
|
|
|
20
20
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
21
|
|
|
@@ -34,6 +34,7 @@ const VIRTUAL_IDS = {
|
|
|
34
34
|
browserEntry: 'virtual:timber-browser-entry',
|
|
35
35
|
config: 'virtual:timber-config',
|
|
36
36
|
instrumentation: 'virtual:timber-instrumentation',
|
|
37
|
+
cacheHandler: 'virtual:timber-cache-handler',
|
|
37
38
|
} as const;
|
|
38
39
|
|
|
39
40
|
/**
|
|
@@ -57,6 +58,9 @@ const RESOLVED_CONFIG_ID = `\0${VIRTUAL_IDS.config}`;
|
|
|
57
58
|
/** The \0-prefixed resolved ID for virtual:timber-instrumentation */
|
|
58
59
|
const RESOLVED_INSTRUMENTATION_ID = `\0${VIRTUAL_IDS.instrumentation}`;
|
|
59
60
|
|
|
61
|
+
/** The \0-prefixed resolved ID for virtual:timber-cache-handler */
|
|
62
|
+
const RESOLVED_CACHE_HANDLER_ID = `\0${VIRTUAL_IDS.cacheHandler}`;
|
|
63
|
+
|
|
60
64
|
/**
|
|
61
65
|
* Strip the \0 prefix from a module ID.
|
|
62
66
|
*
|
|
@@ -95,11 +99,6 @@ function stripRootPrefix(id: string, root: string): string {
|
|
|
95
99
|
* Serializes output mode and feature flags for runtime consumption.
|
|
96
100
|
*/
|
|
97
101
|
function generateConfigModule(ctx: PluginContext): string {
|
|
98
|
-
// Resolve cookie secrets: `secret` shorthand expands to `secrets: [secret]`
|
|
99
|
-
const cookieSecrets =
|
|
100
|
-
ctx.config.cookies?.secrets ??
|
|
101
|
-
(ctx.config.cookies?.secret ? [ctx.config.cookies.secret] : undefined);
|
|
102
|
-
|
|
103
102
|
const runtimeConfig = {
|
|
104
103
|
output: ctx.config.output ?? 'server',
|
|
105
104
|
csrf: ctx.config.csrf ?? true,
|
|
@@ -108,11 +107,16 @@ function generateConfigModule(ctx: PluginContext): string {
|
|
|
108
107
|
dev: ctx.dev ?? false,
|
|
109
108
|
slowPhaseMs: ctx.config.dev?.slowPhaseMs ?? 200,
|
|
110
109
|
slowRequestMs: ctx.config.slowRequestMs ?? 3000,
|
|
111
|
-
cookieSecrets,
|
|
112
110
|
topLoader: ctx.config.topLoader,
|
|
113
|
-
responseCache: ctx.config.responseCache,
|
|
114
111
|
debug: ctx.config.debug ?? false,
|
|
115
|
-
|
|
112
|
+
serverTiming: ctx.config.serverTiming,
|
|
113
|
+
renderTimeoutMs: ctx.config.renderTimeoutMs ?? 30_000,
|
|
114
|
+
// Auto-generated sitemap config — opt-in via timber.config.ts.
|
|
115
|
+
// See design/16-metadata.md §"Auto-generated Sitemap"
|
|
116
|
+
sitemap: ctx.config.sitemap,
|
|
117
|
+
// Per-build deployment ID for version skew detection (TIM-446).
|
|
118
|
+
// Null in dev mode — HMR handles code updates without full reloads.
|
|
119
|
+
deploymentId: ctx.deploymentId ?? null,
|
|
116
120
|
};
|
|
117
121
|
|
|
118
122
|
return [
|
|
@@ -178,6 +182,53 @@ export function generateInstrumentationModule(instrumentationPath: string | null
|
|
|
178
182
|
].join('\n');
|
|
179
183
|
}
|
|
180
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Detect the user's timber.config file at the project root.
|
|
187
|
+
* Returns the absolute path or null if not found.
|
|
188
|
+
*/
|
|
189
|
+
function detectConfigFile(root: string): string | null {
|
|
190
|
+
const names = ['timber.config.ts', 'timber.config.js', 'timber.config.mjs'];
|
|
191
|
+
for (const name of names) {
|
|
192
|
+
const candidate = resolve(root, name);
|
|
193
|
+
if (existsSync(candidate)) return candidate;
|
|
194
|
+
}
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Generate the virtual:timber-cache-handler module source.
|
|
200
|
+
*
|
|
201
|
+
* When the user's config has a cacheHandler, generates a module that
|
|
202
|
+
* dynamically imports the config file and extracts the cacheHandler.
|
|
203
|
+
* The cacheHandler is a class instance (e.g. RedisCacheHandler) that
|
|
204
|
+
* cannot be JSON-serialized into virtual:timber-config, so it must
|
|
205
|
+
* be loaded at runtime via dynamic import. See TIM-599.
|
|
206
|
+
*/
|
|
207
|
+
function generateCacheHandlerModule(configPath: string | null, hasCacheHandler: boolean): string {
|
|
208
|
+
if (configPath && hasCacheHandler) {
|
|
209
|
+
return [
|
|
210
|
+
'// Auto-generated cache handler loader — do not edit.',
|
|
211
|
+
'// Generated by timber-entries plugin.',
|
|
212
|
+
'',
|
|
213
|
+
`export default async function loadCacheHandler() {`,
|
|
214
|
+
` const mod = await import(${JSON.stringify(configPath)});`,
|
|
215
|
+
` const config = mod.default ?? mod;`,
|
|
216
|
+
` return config.cacheHandler ?? null;`,
|
|
217
|
+
`}`,
|
|
218
|
+
].join('\n');
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return [
|
|
222
|
+
'// Auto-generated cache handler loader — do not edit.',
|
|
223
|
+
'// Generated by timber-entries plugin.',
|
|
224
|
+
'// No cacheHandler configured in timber.config.',
|
|
225
|
+
'',
|
|
226
|
+
`export default async function loadCacheHandler() {`,
|
|
227
|
+
` return null;`,
|
|
228
|
+
`}`,
|
|
229
|
+
].join('\n');
|
|
230
|
+
}
|
|
231
|
+
|
|
181
232
|
/**
|
|
182
233
|
* Create the timber-entries Vite plugin.
|
|
183
234
|
*
|
|
@@ -220,6 +271,11 @@ export function timberEntries(ctx: PluginContext): Plugin {
|
|
|
220
271
|
return RESOLVED_INSTRUMENTATION_ID;
|
|
221
272
|
}
|
|
222
273
|
|
|
274
|
+
// Check cache handler virtual module
|
|
275
|
+
if (cleanId === VIRTUAL_IDS.cacheHandler) {
|
|
276
|
+
return RESOLVED_CACHE_HANDLER_ID;
|
|
277
|
+
}
|
|
278
|
+
|
|
223
279
|
return null;
|
|
224
280
|
},
|
|
225
281
|
|
|
@@ -237,6 +293,11 @@ export function timberEntries(ctx: PluginContext): Plugin {
|
|
|
237
293
|
const instrumentationPath = detectInstrumentationFile(ctx.root);
|
|
238
294
|
return generateInstrumentationModule(instrumentationPath);
|
|
239
295
|
}
|
|
296
|
+
if (id === RESOLVED_CACHE_HANDLER_ID) {
|
|
297
|
+
const configPath = detectConfigFile(ctx.root);
|
|
298
|
+
const hasCacheHandler = ctx.config.cacheHandler != null;
|
|
299
|
+
return generateCacheHandlerModule(configPath, hasCacheHandler);
|
|
300
|
+
}
|
|
240
301
|
return null;
|
|
241
302
|
},
|
|
242
303
|
|
package/src/plugins/fonts.ts
CHANGED
|
@@ -17,27 +17,47 @@
|
|
|
17
17
|
import type { Plugin, ViteDevServer } from 'vite';
|
|
18
18
|
import { readFileSync, existsSync } from 'node:fs';
|
|
19
19
|
import { resolve, normalize } from 'node:path';
|
|
20
|
-
import type { PluginContext } from '
|
|
21
|
-
import type { ExtractedFont, GoogleFontConfig } from '
|
|
22
|
-
import type { ManifestFontEntry } from '
|
|
23
|
-
import { generateVariableClass, generateFontFamilyClass, generateFontFaces } from '
|
|
24
|
-
import { generateFallbackCss, buildFontStack } from '
|
|
25
|
-
import { processLocalFont, generateLocalFontFaces } from '
|
|
26
|
-
import { inferFontFormat } from '
|
|
27
|
-
import {
|
|
20
|
+
import type { PluginContext } from '../index.js';
|
|
21
|
+
import type { ExtractedFont, GoogleFontConfig } from '../fonts/types.js';
|
|
22
|
+
import type { ManifestFontEntry } from '../server/build-manifest.js';
|
|
23
|
+
import { generateVariableClass, generateFontFamilyClass, generateFontFaces } from '../fonts/css.js';
|
|
24
|
+
import { generateFallbackCss, buildFontStack } from '../fonts/fallbacks.js';
|
|
25
|
+
import { processLocalFont, generateLocalFontFaces } from '../fonts/local.js';
|
|
26
|
+
import { inferFontFormat } from '../fonts/local.js';
|
|
27
|
+
import {
|
|
28
|
+
downloadAndCacheFonts,
|
|
29
|
+
generateProductionFontFaces,
|
|
30
|
+
resolveDevFontFaces,
|
|
31
|
+
type CachedFont,
|
|
32
|
+
} from '../fonts/google.js';
|
|
33
|
+
import type { FontFaceDescriptor } from '../fonts/types.js';
|
|
28
34
|
import {
|
|
29
35
|
extractFontConfigAst,
|
|
30
36
|
extractLocalFontConfigAst,
|
|
31
37
|
detectDynamicFontCallAst,
|
|
32
|
-
} from '
|
|
38
|
+
} from '../fonts/ast.js';
|
|
33
39
|
|
|
34
40
|
const VIRTUAL_GOOGLE = '@timber/fonts/google';
|
|
35
41
|
const VIRTUAL_LOCAL = '@timber/fonts/local';
|
|
36
42
|
const RESOLVED_GOOGLE = '\0@timber/fonts/google';
|
|
37
43
|
const RESOLVED_LOCAL = '\0@timber/fonts/local';
|
|
38
44
|
|
|
39
|
-
/**
|
|
40
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Virtual side-effect module that registers font CSS on globalThis.
|
|
47
|
+
*
|
|
48
|
+
* When a file calls localFont() or a Google font function, the transform
|
|
49
|
+
* hook injects `import 'virtual:timber-font-css-register'` into that file.
|
|
50
|
+
* This virtual module sets `globalThis.__timber_font_css` with the combined
|
|
51
|
+
* @font-face CSS. The RSC entry reads it at render time to inline a <style> tag.
|
|
52
|
+
*
|
|
53
|
+
* This approach avoids timing issues because:
|
|
54
|
+
* 1. The font file is in the RSC module graph (imported by layout.tsx)
|
|
55
|
+
* 2. The side-effect import is added to the font file during transform
|
|
56
|
+
* 3. When layout.tsx is loaded, fonts.ts runs → side-effect module runs → globalThis is set
|
|
57
|
+
* 4. RSC entry renders → reads globalThis → inlines <style>
|
|
58
|
+
*/
|
|
59
|
+
const VIRTUAL_FONT_CSS_REGISTER = 'virtual:timber-font-css-register';
|
|
60
|
+
const RESOLVED_FONT_CSS_REGISTER = '\0virtual:timber-font-css-register';
|
|
41
61
|
|
|
42
62
|
/**
|
|
43
63
|
* Registry of fonts extracted during transform.
|
|
@@ -120,7 +140,7 @@ export function detectDynamicFontCall(source: string, importedNames: string[]):
|
|
|
120
140
|
* but the source code still contains the original import specifier.
|
|
121
141
|
*/
|
|
122
142
|
const GOOGLE_FONT_IMPORT_RE =
|
|
123
|
-
/import\s*\{([^}]+)\}\s*from\s*['"](?:@timber\/fonts\/google|next\/font\/google)['"]/g;
|
|
143
|
+
/import\s*\{([^}]+)\}\s*from\s*['"](?:@timber\/fonts\/google|@timber-js\/app\/fonts\/google|next\/font\/google)['"]/g;
|
|
124
144
|
|
|
125
145
|
/**
|
|
126
146
|
* Parse import specifiers from a source file that imports from
|
|
@@ -248,37 +268,61 @@ function generateLocalVirtualModule(): string {
|
|
|
248
268
|
}
|
|
249
269
|
|
|
250
270
|
/**
|
|
251
|
-
* Generate
|
|
271
|
+
* Generate CSS for a single extracted font.
|
|
272
|
+
*
|
|
273
|
+
* Includes @font-face rules (for local and Google fonts), fallback @font-face,
|
|
274
|
+
* and the scoped class rule.
|
|
252
275
|
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
276
|
+
* For Google fonts, pass the resolved FontFaceDescriptor[] from either
|
|
277
|
+
* `generateProductionFontFaces()` (production) or `resolveDevFontFaces()` (dev).
|
|
255
278
|
*/
|
|
256
|
-
export function
|
|
279
|
+
export function generateFontCss(font: ExtractedFont, googleFaces?: FontFaceDescriptor[]): string {
|
|
257
280
|
const cssParts: string[] = [];
|
|
258
281
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (faceCss) cssParts.push(faceCss);
|
|
265
|
-
}
|
|
282
|
+
if (font.provider === 'local' && font.localSources) {
|
|
283
|
+
const faces = generateLocalFontFaces(font.family, font.localSources, font.display);
|
|
284
|
+
const faceCss = generateFontFaces(faces);
|
|
285
|
+
if (faceCss) cssParts.push(faceCss);
|
|
286
|
+
}
|
|
266
287
|
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
if (
|
|
288
|
+
if (font.provider === 'google' && googleFaces && googleFaces.length > 0) {
|
|
289
|
+
const faceCss = generateFontFaces(googleFaces);
|
|
290
|
+
if (faceCss) cssParts.push(faceCss);
|
|
291
|
+
}
|
|
270
292
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
293
|
+
const fallbackCss = generateFallbackCss(font.family);
|
|
294
|
+
if (fallbackCss) cssParts.push(fallbackCss);
|
|
295
|
+
|
|
296
|
+
if (font.variable) {
|
|
297
|
+
cssParts.push(generateVariableClass(font.className, font.variable, font.fontFamily));
|
|
298
|
+
} else {
|
|
299
|
+
cssParts.push(generateFontFamilyClass(font.className, font.fontFamily));
|
|
277
300
|
}
|
|
278
301
|
|
|
279
302
|
return cssParts.join('\n\n');
|
|
280
303
|
}
|
|
281
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Generate the CSS output for all extracted fonts.
|
|
307
|
+
*
|
|
308
|
+
* Includes @font-face rules for local and Google fonts, fallback @font-face
|
|
309
|
+
* rules, and scoped classes.
|
|
310
|
+
*
|
|
311
|
+
* `googleFontFacesMap` provides pre-resolved FontFaceDescriptor[] for each
|
|
312
|
+
* Google font ID (keyed by ExtractedFont.id).
|
|
313
|
+
*/
|
|
314
|
+
export function generateAllFontCss(
|
|
315
|
+
registry: FontRegistry,
|
|
316
|
+
googleFontFacesMap?: Map<string, FontFaceDescriptor[]>
|
|
317
|
+
): string {
|
|
318
|
+
const cssParts: string[] = [];
|
|
319
|
+
for (const font of registry.values()) {
|
|
320
|
+
const googleFaces = googleFontFacesMap?.get(font.id);
|
|
321
|
+
cssParts.push(generateFontCss(font, googleFaces));
|
|
322
|
+
}
|
|
323
|
+
return cssParts.join('\n\n');
|
|
324
|
+
}
|
|
325
|
+
|
|
282
326
|
/**
|
|
283
327
|
* Parse the local name used for the default import of `@timber/fonts/local`.
|
|
284
328
|
*
|
|
@@ -288,7 +332,7 @@ export function generateAllFontCss(registry: FontRegistry): string {
|
|
|
288
332
|
*/
|
|
289
333
|
export function parseLocalFontImportName(source: string): string | null {
|
|
290
334
|
const match = source.match(
|
|
291
|
-
/import\s+(\w+)\s+from\s*['"](?:@timber\/fonts\/local|next\/font\/local)['"]/
|
|
335
|
+
/import\s+(\w+)\s+from\s*['"](?:@timber\/fonts\/local|@timber-js\/app\/fonts\/local|next\/font\/local)['"]/
|
|
292
336
|
);
|
|
293
337
|
return match ? match[1] : null;
|
|
294
338
|
}
|
|
@@ -353,7 +397,7 @@ function transformLocalFonts(
|
|
|
353
397
|
|
|
354
398
|
// Remove the import statement
|
|
355
399
|
transformedCode = transformedCode.replace(
|
|
356
|
-
/import\s+\w+\s+from\s*['"](?:@timber\/fonts\/local|next\/font\/local)['"];?\s*\n?/g,
|
|
400
|
+
/import\s+\w+\s+from\s*['"](?:@timber\/fonts\/local|@timber-js\/app\/fonts\/local|next\/font\/local)['"];?\s*\n?/g,
|
|
357
401
|
''
|
|
358
402
|
);
|
|
359
403
|
|
|
@@ -367,25 +411,79 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
367
411
|
const registry: FontRegistry = new Map();
|
|
368
412
|
/** Fonts downloaded during buildStart (production only). */
|
|
369
413
|
let cachedFonts: CachedFont[] = [];
|
|
414
|
+
/**
|
|
415
|
+
* Pre-resolved @font-face descriptors for Google fonts, keyed by font ID.
|
|
416
|
+
* Populated in buildStart (production) or lazily in load (dev).
|
|
417
|
+
*/
|
|
418
|
+
const googleFontFacesMap = new Map<string, FontFaceDescriptor[]>();
|
|
370
419
|
|
|
371
420
|
return {
|
|
372
421
|
name: 'timber-fonts',
|
|
373
422
|
|
|
374
423
|
/**
|
|
375
|
-
* Resolve `@timber/fonts/google
|
|
424
|
+
* Resolve `@timber/fonts/google`, `@timber/fonts/local`,
|
|
425
|
+
* and `virtual:timber-font-css` virtual modules.
|
|
426
|
+
*
|
|
427
|
+
* Handles \0 prefix and root prefix stripping for RSC/SSR
|
|
428
|
+
* environments where the RSC plugin re-imports virtual modules
|
|
429
|
+
* with additional prefixes.
|
|
376
430
|
*/
|
|
377
431
|
resolveId(id: string) {
|
|
378
|
-
|
|
379
|
-
|
|
432
|
+
// Strip \0 prefix (RSC plugin re-imports)
|
|
433
|
+
let cleanId = id.startsWith('\0') ? id.slice(1) : id;
|
|
434
|
+
// Strip root prefix (SSR build entries)
|
|
435
|
+
if (cleanId.startsWith(ctx.root)) {
|
|
436
|
+
const stripped = cleanId.slice(ctx.root.length);
|
|
437
|
+
if (stripped.startsWith('/') || stripped.startsWith('\\')) {
|
|
438
|
+
cleanId = stripped.slice(1);
|
|
439
|
+
} else {
|
|
440
|
+
cleanId = stripped;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (cleanId === VIRTUAL_GOOGLE) return RESOLVED_GOOGLE;
|
|
445
|
+
if (cleanId === VIRTUAL_LOCAL) return RESOLVED_LOCAL;
|
|
446
|
+
if (cleanId === VIRTUAL_FONT_CSS_REGISTER) return RESOLVED_FONT_CSS_REGISTER;
|
|
380
447
|
return null;
|
|
381
448
|
},
|
|
382
449
|
|
|
383
450
|
/**
|
|
384
451
|
* Return generated source for font virtual modules.
|
|
452
|
+
*
|
|
453
|
+
* `virtual:timber-font-css` exports the combined @font-face CSS
|
|
454
|
+
* as a string. The RSC entry imports it and inlines a <style> tag.
|
|
455
|
+
* Because this is loaded lazily (on first request), the font
|
|
456
|
+
* registry is always populated by the time it's needed.
|
|
385
457
|
*/
|
|
386
|
-
load(id: string) {
|
|
458
|
+
async load(id: string) {
|
|
387
459
|
if (id === RESOLVED_GOOGLE) return generateGoogleVirtualModule(registry);
|
|
388
460
|
if (id === RESOLVED_LOCAL) return generateLocalVirtualModule();
|
|
461
|
+
|
|
462
|
+
if (id === RESOLVED_FONT_CSS_REGISTER) {
|
|
463
|
+
// In dev mode, resolve Google font faces from CDN on demand.
|
|
464
|
+
if (ctx.dev) {
|
|
465
|
+
const googleFonts = [...registry.values()].filter((f) => f.provider === 'google');
|
|
466
|
+
for (const font of googleFonts) {
|
|
467
|
+
if (!googleFontFacesMap.has(font.id)) {
|
|
468
|
+
try {
|
|
469
|
+
const faces = await resolveDevFontFaces(font);
|
|
470
|
+
googleFontFacesMap.set(font.id, faces);
|
|
471
|
+
} catch (e) {
|
|
472
|
+
// In dev mode, fail gracefully — fonts fall back to system fonts.
|
|
473
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
474
|
+
console.warn(
|
|
475
|
+
`[timber-fonts] Failed to resolve Google font "${font.family}": ${msg}`
|
|
476
|
+
);
|
|
477
|
+
googleFontFacesMap.set(font.id, []);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const css = generateAllFontCss(registry, googleFontFacesMap);
|
|
484
|
+
// Side-effect module: sets font CSS on globalThis for the RSC entry to read.
|
|
485
|
+
return `globalThis.__timber_font_css = ${JSON.stringify(css)};`;
|
|
486
|
+
}
|
|
389
487
|
return null;
|
|
390
488
|
},
|
|
391
489
|
|
|
@@ -412,14 +510,8 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
412
510
|
return;
|
|
413
511
|
}
|
|
414
512
|
|
|
415
|
-
//
|
|
416
|
-
|
|
417
|
-
const css = generateAllFontCss(registry);
|
|
418
|
-
res.setHeader('Content-Type', 'text/css');
|
|
419
|
-
res.setHeader('Cache-Control', 'no-cache');
|
|
420
|
-
res.end(css);
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
513
|
+
// Font CSS is now injected via Vite's CSS pipeline (virtual:timber-font-css modules).
|
|
514
|
+
// This middleware only serves font binary files (woff2, etc.).
|
|
423
515
|
|
|
424
516
|
// Find the matching font file in the registry
|
|
425
517
|
for (const font of registry.values()) {
|
|
@@ -469,6 +561,22 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
469
561
|
if (googleFonts.length === 0) return;
|
|
470
562
|
|
|
471
563
|
cachedFonts = await downloadAndCacheFonts(googleFonts, ctx.root);
|
|
564
|
+
|
|
565
|
+
// Build a family→CachedFont[] lookup, then generate production @font-face
|
|
566
|
+
// descriptors for each registered Google font.
|
|
567
|
+
const cachedByFamily = new Map<string, CachedFont[]>();
|
|
568
|
+
for (const cf of cachedFonts) {
|
|
569
|
+
const key = cf.face.family.toLowerCase();
|
|
570
|
+
const arr = cachedByFamily.get(key) ?? [];
|
|
571
|
+
arr.push(cf);
|
|
572
|
+
cachedByFamily.set(key, arr);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
for (const font of googleFonts) {
|
|
576
|
+
const familyCached = cachedByFamily.get(font.family.toLowerCase()) ?? [];
|
|
577
|
+
const faces = generateProductionFontFaces(familyCached, font.display);
|
|
578
|
+
googleFontFacesMap.set(font.id, faces);
|
|
579
|
+
}
|
|
472
580
|
},
|
|
473
581
|
|
|
474
582
|
/**
|
|
@@ -486,9 +594,13 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
486
594
|
if (id.startsWith('\0') || id.includes('node_modules')) return null;
|
|
487
595
|
|
|
488
596
|
const hasGoogleImport =
|
|
489
|
-
code.includes('@timber/fonts/google') ||
|
|
597
|
+
code.includes('@timber/fonts/google') ||
|
|
598
|
+
code.includes('@timber-js/app/fonts/google') ||
|
|
599
|
+
code.includes('next/font/google');
|
|
490
600
|
const hasLocalImport =
|
|
491
|
-
code.includes('@timber/fonts/local') ||
|
|
601
|
+
code.includes('@timber/fonts/local') ||
|
|
602
|
+
code.includes('@timber-js/app/fonts/local') ||
|
|
603
|
+
code.includes('next/font/local');
|
|
492
604
|
if (!hasGoogleImport && !hasLocalImport) return null;
|
|
493
605
|
|
|
494
606
|
let transformedCode = code;
|
|
@@ -560,7 +672,7 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
560
672
|
}
|
|
561
673
|
|
|
562
674
|
transformedCode = transformedCode.replace(
|
|
563
|
-
/import\s*\{[^}]+\}\s*from\s*['"](?:@timber\/fonts\/google|next\/font\/google)['"];?\s*\n?/g,
|
|
675
|
+
/import\s*\{[^}]+\}\s*from\s*['"](?:@timber\/fonts\/google|@timber-js\/app\/fonts\/google|next\/font\/google)['"];?\s*\n?/g,
|
|
564
676
|
''
|
|
565
677
|
);
|
|
566
678
|
}
|
|
@@ -578,9 +690,10 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
578
690
|
}
|
|
579
691
|
|
|
580
692
|
if (transformedCode !== code) {
|
|
581
|
-
//
|
|
582
|
-
|
|
583
|
-
|
|
693
|
+
// Inject side-effect import that registers font CSS on globalThis.
|
|
694
|
+
// The RSC entry reads globalThis.__timber_font_css to inline a <style> tag.
|
|
695
|
+
if (registry.size > 0) {
|
|
696
|
+
transformedCode = `import '${VIRTUAL_FONT_CSS_REGISTER}';\n` + transformedCode;
|
|
584
697
|
}
|
|
585
698
|
return { code: transformedCode, map: null };
|
|
586
699
|
}
|
|
@@ -627,15 +740,8 @@ export function timberFonts(ctx: PluginContext): Plugin {
|
|
|
627
740
|
}
|
|
628
741
|
}
|
|
629
742
|
|
|
630
|
-
//
|
|
631
|
-
|
|
632
|
-
if (fontCss) {
|
|
633
|
-
this.emitFile({
|
|
634
|
-
type: 'asset',
|
|
635
|
-
fileName: '_timber/fonts/fonts.css',
|
|
636
|
-
source: fontCss,
|
|
637
|
-
});
|
|
638
|
-
}
|
|
743
|
+
// Font CSS is emitted by Vite's CSS pipeline via virtual:timber-font-css modules.
|
|
744
|
+
// We only need to emit font binary files and update the build manifest here.
|
|
639
745
|
|
|
640
746
|
if (!ctx.buildManifest) return;
|
|
641
747
|
|
package/src/plugins/mdx.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type { Plugin } from 'vite';
|
|
12
12
|
import { existsSync } from 'node:fs';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
-
import type { PluginContext } from '
|
|
14
|
+
import type { PluginContext } from '../index.js';
|
|
15
15
|
|
|
16
16
|
const MDX_EXTENSIONS = ['mdx', 'md'];
|
|
17
17
|
|
package/src/plugins/routing.ts
CHANGED
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
import type { Plugin, ViteDevServer } from 'vite';
|
|
12
12
|
import { writeFile, mkdir } from 'node:fs/promises';
|
|
13
13
|
import { join } from 'node:path';
|
|
14
|
-
import { scanRoutes } from '
|
|
15
|
-
import { generateRouteMap } from '
|
|
16
|
-
import { collectInterceptionRewrites } from '
|
|
14
|
+
import { scanRoutes } from '../routing/scanner.js';
|
|
15
|
+
import { generateRouteMap } from '../routing/codegen.js';
|
|
16
|
+
import { collectInterceptionRewrites } from '../routing/interception.js';
|
|
17
17
|
import {
|
|
18
18
|
lintStatusFileDirectives,
|
|
19
19
|
formatStatusFileLintWarnings,
|
|
20
|
-
} from '
|
|
21
|
-
import type { RouteTree, SegmentNode, RouteFile } from '
|
|
22
|
-
import type { PluginContext } from '
|
|
20
|
+
} from '../routing/status-file-lint.js';
|
|
21
|
+
import type { RouteTree, SegmentNode, RouteFile } from '../routing/types.js';
|
|
22
|
+
import type { PluginContext } from '../index.js';
|
|
23
23
|
|
|
24
24
|
const VIRTUAL_MODULE_ID = 'virtual:timber-route-manifest';
|
|
25
25
|
const RESOLVED_VIRTUAL_ID = `\0${VIRTUAL_MODULE_ID}`;
|
|
@@ -28,7 +28,7 @@ const RESOLVED_VIRTUAL_ID = `\0${VIRTUAL_MODULE_ID}`;
|
|
|
28
28
|
* File convention names we track for changes that require manifest regeneration.
|
|
29
29
|
*/
|
|
30
30
|
const ROUTE_FILE_PATTERNS =
|
|
31
|
-
/\/(page|layout|middleware|access|route|error|default|denied|
|
|
31
|
+
/\/(page|layout|middleware|access|route|error|global-error|default|denied|params|\d{3}|[45]xx|not-found|forbidden|unauthorized|sitemap|robots|manifest|favicon|icon|opengraph-image|twitter-image|apple-icon)\./;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Create the timber-routing Vite plugin.
|
|
@@ -168,20 +168,49 @@ export function timberRouting(ctx: PluginContext): Plugin {
|
|
|
168
168
|
// Watch the app directory
|
|
169
169
|
devServer.watcher.add(ctx.appDir);
|
|
170
170
|
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
/** Snapshot of the last generated manifest, used to detect structural changes. */
|
|
172
|
+
let lastManifest = ctx.routeTree ? generateManifestModule(ctx.routeTree) : '';
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Handle a route-significant file being added or removed.
|
|
176
|
+
* Always triggers a full-reload since the route tree structure changed.
|
|
177
|
+
*/
|
|
178
|
+
const handleStructuralChange = (filePath: string) => {
|
|
173
179
|
if (!filePath.startsWith(ctx.appDir)) return;
|
|
174
180
|
if (!ROUTE_FILE_PATTERNS.test(filePath)) return;
|
|
175
181
|
|
|
176
|
-
// Rescan the route tree
|
|
177
182
|
rescan();
|
|
178
|
-
|
|
179
|
-
// Invalidate the virtual module in all environments
|
|
183
|
+
lastManifest = ctx.routeTree ? generateManifestModule(ctx.routeTree) : '';
|
|
180
184
|
invalidateManifest(devServer);
|
|
181
185
|
};
|
|
182
186
|
|
|
183
|
-
|
|
184
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Handle a route file's content changing.
|
|
189
|
+
*
|
|
190
|
+
* Most content edits (JSX changes, fixing typos) don't affect route
|
|
191
|
+
* metadata — Vite's React Fast Refresh handles those via normal HMR.
|
|
192
|
+
* Only rescan and full-reload when route metadata actually changed
|
|
193
|
+
* (e.g., searchParams export added/removed, metadata export changed).
|
|
194
|
+
*/
|
|
195
|
+
const handleContentChange = (filePath: string) => {
|
|
196
|
+
if (!filePath.startsWith(ctx.appDir)) return;
|
|
197
|
+
if (!ROUTE_FILE_PATTERNS.test(filePath)) return;
|
|
198
|
+
|
|
199
|
+
rescan();
|
|
200
|
+
const newManifest = ctx.routeTree ? generateManifestModule(ctx.routeTree) : '';
|
|
201
|
+
if (newManifest !== lastManifest) {
|
|
202
|
+
lastManifest = newManifest;
|
|
203
|
+
invalidateManifest(devServer);
|
|
204
|
+
}
|
|
205
|
+
// Otherwise: content edit didn't change route metadata — let Vite HMR handle it
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
devServer.watcher.on('add', handleStructuralChange);
|
|
209
|
+
devServer.watcher.on('unlink', handleStructuralChange);
|
|
210
|
+
// Watch content changes to page files — searchParams detection depends
|
|
211
|
+
// on file contents (export const searchParams), not just file presence.
|
|
212
|
+
// But only full-reload when route metadata actually changes.
|
|
213
|
+
devServer.watcher.on('change', handleContentChange);
|
|
185
214
|
// Also watch renames (which are add+unlink) — handled by the above
|
|
186
215
|
},
|
|
187
216
|
};
|
|
@@ -301,12 +330,15 @@ function generateManifestModule(tree: RouteTree): string {
|
|
|
301
330
|
`${nextIndent}denied: { load: ${v}, filePath: ${JSON.stringify(node.denied.filePath)} },`
|
|
302
331
|
);
|
|
303
332
|
}
|
|
304
|
-
if (node.
|
|
305
|
-
const v = addImport(node.
|
|
333
|
+
if (node.params) {
|
|
334
|
+
const v = addImport(node.params);
|
|
306
335
|
parts.push(
|
|
307
|
-
`${nextIndent}
|
|
336
|
+
`${nextIndent}params: { load: ${v}, filePath: ${JSON.stringify(node.params.filePath)} },`
|
|
308
337
|
);
|
|
309
338
|
}
|
|
339
|
+
// searchParams is now a named export from page.tsx, not a separate file.
|
|
340
|
+
// The page module's searchParams export is loaded via the page's lazy import.
|
|
341
|
+
// Runtime registration happens in the route loader using the page module.
|
|
310
342
|
|
|
311
343
|
// Status-code files
|
|
312
344
|
if (node.statusFiles && node.statusFiles.size > 0) {
|
|
@@ -391,6 +423,13 @@ function generateManifestModule(tree: RouteTree): string {
|
|
|
391
423
|
proxyLine = ` proxy: { load: ${v}, filePath: ${JSON.stringify(tree.proxy.filePath)} },`;
|
|
392
424
|
}
|
|
393
425
|
|
|
426
|
+
// Global error page (Tier 2)
|
|
427
|
+
let globalErrorLine = '';
|
|
428
|
+
if (tree.globalError) {
|
|
429
|
+
const v = addImport(tree.globalError);
|
|
430
|
+
globalErrorLine = ` globalError: { load: ${v}, filePath: ${JSON.stringify(tree.globalError.filePath)} },`;
|
|
431
|
+
}
|
|
432
|
+
|
|
394
433
|
// Interception rewrites — computed at build time from the route tree.
|
|
395
434
|
// Only interceptedPattern and interceptingPrefix are needed at runtime.
|
|
396
435
|
const rewrites = collectInterceptionRewrites(tree.root);
|
|
@@ -407,6 +446,7 @@ function generateManifestModule(tree: RouteTree): string {
|
|
|
407
446
|
'',
|
|
408
447
|
'const manifest = {',
|
|
409
448
|
proxyLine,
|
|
449
|
+
globalErrorLine,
|
|
410
450
|
rewritesLine,
|
|
411
451
|
` root: ${rootSerialized},`,
|
|
412
452
|
'};',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
2
|
import { Parser } from 'acorn';
|
|
3
3
|
import acornJsx from 'acorn-jsx';
|
|
4
|
-
import { detectFileDirective } from '
|
|
4
|
+
import { detectFileDirective } from '../utils/directive-parser.js';
|
|
5
5
|
|
|
6
6
|
const jsxParser = Parser.extend(acornJsx());
|
|
7
7
|
|
|
@@ -137,5 +137,36 @@ export function timberServerBundle(): Plugin[] {
|
|
|
137
137
|
},
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
// Fix Rolldown's `createRequire(import.meta.url)` CJS interop shim for
|
|
141
|
+
// Cloudflare Workers. Rolldown emits this for CJS dependencies (e.g.
|
|
142
|
+
// @opentelemetry/context-async-hooks) that use `require()`. On Workers,
|
|
143
|
+
// `import.meta.url` is `undefined` for non-entry modules, causing:
|
|
144
|
+
// TypeError: The argument 'path' must be a file URL object, a file URL
|
|
145
|
+
// string, or an absolute path string. Received 'undefined'
|
|
146
|
+
//
|
|
147
|
+
// The fix: provide a fallback URL when `import.meta.url` is undefined.
|
|
148
|
+
// The actual URL doesn't matter — `createRequire` only needs it for
|
|
149
|
+
// resolving relative paths, but the only `__require()` calls are for
|
|
150
|
+
// Node built-ins (events, async_hooks) which resolve from any base.
|
|
151
|
+
//
|
|
152
|
+
// The top-level `ssr: { target: 'webworker' }` was supposed to prevent
|
|
153
|
+
// this, but it doesn't propagate to custom environments (rsc) in Vite's
|
|
154
|
+
// Environment API. See LOCAL-405.
|
|
155
|
+
const createRequireFixPlugin: Plugin = {
|
|
156
|
+
name: 'timber-create-require-fix',
|
|
157
|
+
applyToEnvironment(environment) {
|
|
158
|
+
return environment.name === 'rsc' || environment.name === 'ssr';
|
|
159
|
+
},
|
|
160
|
+
renderChunk(code) {
|
|
161
|
+
const pattern = 'createRequire(import.meta.url)';
|
|
162
|
+
if (!code.includes(pattern)) return null;
|
|
163
|
+
|
|
164
|
+
return {
|
|
165
|
+
code: code.replace(pattern, 'createRequire(import.meta.url || "file:///app")'),
|
|
166
|
+
map: null,
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
return [bundlePlugin, esmInitFixPlugin, createRequireFixPlugin];
|
|
141
172
|
}
|