@timber-js/app 0.2.0-alpha.14 → 0.2.0-alpha.141
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/actions-DzFMnUAR.js +1147 -0
- package/dist/_chunks/actions-DzFMnUAR.js.map +1 -0
- package/dist/_chunks/build-output-helper-B20ZuTSA.js +102 -0
- package/dist/_chunks/build-output-helper-B20ZuTSA.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-D2IpXicg.js +785 -0
- package/dist/_chunks/cli-schema-sync-D2IpXicg.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-DH-M8Poy.js +2 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
- package/dist/_chunks/define-C3RvHQPK.js +195 -0
- package/dist/_chunks/define-C3RvHQPK.js.map +1 -0
- package/dist/_chunks/define-DMVhsipD.js +112 -0
- package/dist/_chunks/define-DMVhsipD.js.map +1 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js +36 -0
- package/dist/_chunks/fast-hash-D6hIVt1Y.js.map +1 -0
- package/dist/_chunks/format-CfwjgPz9.js +14 -0
- package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
- package/dist/_chunks/handler-store-DjISKYEB.js +54 -0
- package/dist/_chunks/handler-store-DjISKYEB.js.map +1 -0
- package/dist/_chunks/href-validation-EZktELp8.js +124 -0
- package/dist/_chunks/href-validation-EZktELp8.js.map +1 -0
- package/dist/_chunks/logger-Dt-jQaBO.js +291 -0
- package/dist/_chunks/logger-Dt-jQaBO.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-BjepjefT.js} +32 -19
- package/dist/_chunks/metadata-routes-BjepjefT.js.map +1 -0
- package/dist/_chunks/navigation-root-DLc4s4ZC.js +103 -0
- package/dist/_chunks/navigation-root-DLc4s4ZC.js.map +1 -0
- package/dist/_chunks/registry-DbJPKoBp.js +20 -0
- package/dist/_chunks/registry-DbJPKoBp.js.map +1 -0
- package/dist/_chunks/resolve-schema-Dj8tQloi.js +77 -0
- package/dist/_chunks/resolve-schema-Dj8tQloi.js.map +1 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js +28 -0
- package/dist/_chunks/router-ref-CtmF-aPv.js.map +1 -0
- package/dist/_chunks/schema-bridge-DK_89h8O.js +86 -0
- package/dist/_chunks/schema-bridge-DK_89h8O.js.map +1 -0
- package/dist/_chunks/segment-classify-CDDRVKs7.js +137 -0
- package/dist/_chunks/segment-classify-CDDRVKs7.js.map +1 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js +34 -0
- package/dist/_chunks/segment-context-ZDnXDkbz.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-BOWsq18U.js} +1 -1
- package/dist/_chunks/ssr-data-BOWsq18U.js.map +1 -0
- package/dist/_chunks/tracing-M_zKubhk.js +358 -0
- package/dist/_chunks/tracing-M_zKubhk.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-CbeQmext.js} +7 -20
- package/dist/_chunks/use-query-states-CbeQmext.js.map +1 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js +151 -0
- package/dist/_chunks/use-segment-params-D1CzlgBo.js.map +1 -0
- package/dist/_chunks/validation-taUkvA4Q.js +113 -0
- package/dist/_chunks/validation-taUkvA4Q.js.map +1 -0
- package/dist/_chunks/walkers-7FBPM-hX.js +724 -0
- package/dist/_chunks/walkers-7FBPM-hX.js.map +1 -0
- package/dist/_chunks/{format-RyoGQL74.js → warnings-CNPXaypM.js} +6 -45
- package/dist/_chunks/warnings-CNPXaypM.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +28 -0
- package/dist/adapters/build-output-helper.d.ts.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-kv-cache.d.ts +64 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +95 -0
- package/dist/adapters/cloudflare-kv-cache.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 +142 -38
- 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 +154 -48
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +16 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/cache/cache-api.d.ts +24 -0
- package/dist/cache/cache-api.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 +23 -7
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +165 -117
- 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/sizeof.d.ts +22 -0
- package/dist/cache/sizeof.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +1 -1
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cli-schema-sync.d.ts +39 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +14 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +48 -6
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +34 -1
- package/dist/client/browser-dev.d.ts.map +1 -1
- package/dist/client/browser-entry/action-dispatch.d.ts +17 -0
- package/dist/client/browser-entry/action-dispatch.d.ts.map +1 -0
- package/dist/client/browser-entry/hmr.d.ts +21 -0
- package/dist/client/browser-entry/hmr.d.ts.map +1 -0
- package/dist/client/browser-entry/hydrate.d.ts +46 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +30 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +26 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +26 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +24 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +19 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- 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 +29 -6
- package/dist/client/error-boundary.js.map +1 -1
- 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 +16 -27
- 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 +10 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +183 -1134
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +19 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +925 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link-pending-store.d.ts +65 -0
- package/dist/client/link-pending-store.d.ts.map +1 -0
- package/dist/client/link.d.ts +69 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/nav-link-store.d.ts +27 -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 +14 -2
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/{transition-root.d.ts → navigation-root.d.ts} +46 -9
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/router-ref.d.ts +1 -1
- package/dist/client/router.d.ts +79 -10
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +46 -3
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +3 -1
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +49 -0
- package/dist/client/segment-outlet.d.ts.map +1 -0
- package/dist/client/segment-update-context.d.ts +21 -0
- package/dist/client/segment-update-context.d.ts.map +1 -0
- package/dist/client/shallow-url.d.ts +10 -0
- package/dist/client/shallow-url.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/state.d.ts +1 -1
- package/dist/client/top-loader.d.ts +5 -5
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/use-cookie.d.ts +12 -0
- package/dist/client/use-cookie.d.ts.map +1 -1
- package/dist/client/use-link-status.d.ts +5 -5
- package/dist/client/use-link-status.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts.map +1 -1
- package/dist/client/use-pending-navigation.d.ts +23 -0
- package/dist/client/use-pending-navigation.d.ts.map +1 -0
- package/dist/client/use-query-states.d.ts +1 -1
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +1 -1
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +7 -5
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +8 -6
- package/dist/client/use-segment-params.d.ts.map +1 -0
- package/dist/codec.d.ts +69 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +75 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +294 -0
- package/dist/config-types.d.ts.map +1 -0
- package/dist/config-validation.d.ts +51 -0
- package/dist/config-validation.d.ts.map +1 -0
- package/dist/content/index.d.ts +1 -10
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +0 -2
- package/dist/cookies/define-cookie.d.ts +58 -25
- package/dist/cookies/define-cookie.d.ts.map +1 -1
- package/dist/cookies/index.d.ts +2 -1
- package/dist/cookies/index.d.ts.map +1 -1
- package/dist/cookies/index.js +251 -36
- package/dist/cookies/index.js.map +1 -1
- package/dist/cookies/json-cookie.d.ts +64 -0
- package/dist/cookies/json-cookie.d.ts.map +1 -0
- package/dist/cookies/validation.d.ts +34 -0
- package/dist/cookies/validation.d.ts.map +1 -0
- package/dist/dev-tools/404-page.d.ts +46 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +84 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +58 -0
- package/dist/dev-tools/error-page.d.ts.map +1 -0
- package/dist/dev-tools/holding-server.d.ts +54 -0
- package/dist/dev-tools/holding-server.d.ts.map +1 -0
- package/dist/dev-tools/index.d.ts +31 -0
- package/dist/dev-tools/index.d.ts.map +1 -0
- package/dist/{server/dev-span-processor.d.ts → dev-tools/instrumentation.d.ts} +26 -6
- package/dist/dev-tools/instrumentation.d.ts.map +1 -0
- package/dist/{server/dev-logger.d.ts → dev-tools/logger.d.ts} +1 -1
- package/dist/dev-tools/logger.d.ts.map +1 -0
- package/dist/{plugins/dev-logs.d.ts → dev-tools/logs.d.ts} +2 -2
- package/dist/dev-tools/logs.d.ts.map +1 -0
- package/dist/dev-tools/overlay.d.ts +91 -0
- package/dist/dev-tools/overlay.d.ts.map +1 -0
- package/dist/dev-tools/stack-classifier.d.ts +34 -0
- package/dist/dev-tools/stack-classifier.d.ts.map +1 -0
- package/dist/dev-tools/terminal.d.ts +28 -0
- package/dist/dev-tools/terminal.d.ts.map +1 -0
- package/dist/{server/dev-warnings.d.ts → dev-tools/warnings.d.ts} +2 -22
- package/dist/dev-tools/warnings.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +98 -6
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +48 -0
- package/dist/fonts/bundle.d.ts.map +1 -0
- package/dist/fonts/dev-middleware.d.ts +22 -0
- package/dist/fonts/dev-middleware.d.ts.map +1 -0
- package/dist/fonts/local.d.ts +1 -1
- package/dist/fonts/pipeline.d.ts +172 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +78 -0
- package/dist/fonts/transform.d.ts.map +1 -0
- package/dist/fonts/types.d.ts +47 -1
- package/dist/fonts/types.d.ts.map +1 -1
- package/dist/fonts/virtual-modules.d.ts +94 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +46 -180
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5315 -12687
- package/dist/index.js.map +1 -1
- package/dist/params/codec-registry.d.ts +26 -0
- package/dist/params/codec-registry.d.ts.map +1 -0
- package/dist/params/define-schema.d.ts +81 -0
- package/dist/params/define-schema.d.ts.map +1 -0
- package/dist/params/index.d.ts +5 -0
- package/dist/params/index.d.ts.map +1 -0
- package/dist/params/index.js +34 -0
- package/dist/params/index.js.map +1 -0
- package/dist/params/resolve-schema.d.ts +34 -0
- package/dist/params/resolve-schema.d.ts.map +1 -0
- package/dist/plugin-context.d.ts +114 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +20 -1
- package/dist/plugins/adapter-build.d.ts.map +1 -1
- package/dist/plugins/build-manifest.d.ts +7 -3
- package/dist/plugins/build-manifest.d.ts.map +1 -1
- package/dist/plugins/build-report.d.ts +9 -7
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +31 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/client-chunks.d.ts +39 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/cloudflare-wasm.d.ts +18 -0
- package/dist/plugins/cloudflare-wasm.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-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 +17 -73
- 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 +5 -26
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +67 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +60 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen.d.ts +7 -2
- package/dist/routing/codegen.d.ts.map +1 -1
- package/dist/routing/convention-lint.d.ts +41 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/index.d.ts +7 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -2
- package/dist/routing/link-codegen.d.ts +90 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/scanner.d.ts +1 -10
- package/dist/routing/scanner.d.ts.map +1 -1
- package/dist/routing/schema-validation.d.ts +35 -0
- package/dist/routing/schema-validation.d.ts.map +1 -0
- package/dist/routing/segment-classify.d.ts +75 -0
- package/dist/routing/segment-classify.d.ts.map +1 -0
- package/dist/routing/segment-codegen.d.ts +38 -0
- package/dist/routing/segment-codegen.d.ts.map +1 -0
- package/dist/routing/types.d.ts +77 -25
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +51 -0
- package/dist/routing/walkers.d.ts.map +1 -0
- 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 +157 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +4 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +34 -441
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/registry.d.ts +2 -2
- package/dist/search-params/registry.d.ts.map +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 +89 -0
- package/dist/segment-params/define.d.ts.map +1 -0
- package/dist/segment-params/index.d.ts +3 -0
- package/dist/segment-params/index.d.ts.map +1 -0
- package/dist/segment-params/index.js +2 -0
- package/dist/server/access-gate.d.ts +8 -3
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +41 -6
- 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 +35 -1
- package/dist/server/action-handler.d.ts.map +1 -1
- package/dist/server/actions.d.ts +6 -14
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +70 -11
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +1 -15
- package/dist/server/asset-headers.d.ts.map +1 -1
- package/dist/server/body-limits.d.ts.map +1 -1
- package/dist/server/build-manifest.d.ts +8 -2
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/cookie-context.d.ts +170 -0
- package/dist/server/cookie-context.d.ts.map +1 -0
- package/dist/server/cookie-parsing.d.ts +51 -0
- package/dist/server/cookie-parsing.d.ts.map +1 -0
- package/dist/server/csrf.d.ts +3 -2
- package/dist/server/csrf.d.ts.map +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-boundary.d.ts +90 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +1 -1
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/dev-source-map.d.ts +22 -0
- package/dist/server/dev-source-map.d.ts.map +1 -0
- package/dist/server/early-hints-sender.d.ts.map +1 -1
- package/dist/server/early-hints.d.ts +13 -11
- 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 +12 -7
- 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-injector-core.d.ts +213 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +81 -41
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +10 -46
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +170 -2911
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +48 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +3126 -0
- package/dist/server/internal.js.map +1 -0
- package/dist/server/logger.d.ts +39 -7
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/metadata-routes.d.ts +23 -7
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +36 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +112 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +54 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +95 -0
- package/dist/server/pipeline-helpers.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-outcome.d.ts +49 -0
- package/dist/server/pipeline-outcome.d.ts.map +1 -0
- package/dist/server/pipeline-phases.d.ts +56 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +111 -19
- package/dist/server/pipeline.d.ts.map +1 -1
- package/dist/server/port-resolution.d.ts +117 -0
- package/dist/server/port-resolution.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +74 -20
- 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 +62 -107
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/route-element-builder.d.ts +28 -2
- 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 +25 -36
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts +66 -0
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -0
- package/dist/server/rsc-entry/api-handler.d.ts +12 -3
- 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 +50 -6
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +19 -8
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +50 -0
- package/dist/server/rsc-entry/render-route.d.ts.map +1 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts +108 -0
- package/dist/server/rsc-entry/revalidate-renderer.d.ts.map +1 -0
- 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 +17 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts +5 -1
- package/dist/server/rsc-entry/ssr-bridge.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts +34 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +119 -0
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts.map +1 -0
- package/dist/server/safe-load.d.ts +46 -0
- package/dist/server/safe-load.d.ts.map +1 -0
- package/dist/server/sensitive-fields.d.ts +74 -0
- package/dist/server/sensitive-fields.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-bridge-types.d.ts +121 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +2 -43
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +64 -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/state-tree-diff.d.ts +12 -5
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/status-code-resolver.d.ts +16 -11
- 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 +5 -5
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +62 -30
- package/dist/server/tree-builder.d.ts.map +1 -1
- package/dist/server/tree-match.d.ts +49 -0
- package/dist/server/tree-match.d.ts.map +1 -0
- package/dist/server/types.d.ts +71 -6
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- package/dist/server/version-skew.d.ts +61 -0
- package/dist/server/version-skew.d.ts.map +1 -0
- package/dist/shared/href-validation.d.ts +38 -0
- package/dist/shared/href-validation.d.ts.map +1 -0
- 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/headers.d.ts +2 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/image.d.ts +1 -1
- package/dist/shims/navigation-client.d.ts +3 -1
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +11 -5
- package/dist/shims/navigation.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 +63 -22
- package/src/adapters/build-output-helper.ts +139 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +142 -0
- package/src/adapters/cloudflare.ts +350 -76
- package/src/adapters/compress-module.ts +24 -4
- package/src/adapters/nitro.ts +147 -60
- package/src/adapters/shared.ts +40 -0
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +39 -0
- package/src/cache/handler-store.ts +68 -0
- package/src/cache/index.ts +81 -18
- package/src/cache/singleflight.ts +62 -4
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/timber-cache.ts +52 -24
- package/src/cli-schema-sync.ts +295 -0
- package/src/cli.ts +76 -8
- package/src/client/browser-dev.ts +153 -1
- package/src/client/browser-entry/action-dispatch.ts +125 -0
- package/src/client/browser-entry/hmr.ts +81 -0
- package/src/client/browser-entry/hydrate.ts +153 -0
- package/src/client/browser-entry/index.ts +151 -0
- package/src/client/browser-entry/post-hydration.ts +113 -0
- package/src/client/browser-entry/router-init.ts +219 -0
- package/src/client/browser-entry/rsc-stream.ts +157 -0
- package/src/client/browser-entry/scroll.ts +27 -0
- package/src/client/error-boundary.tsx +99 -22
- package/src/client/error-reconstituter.tsx +65 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +26 -4
- package/src/client/index.ts +67 -45
- package/src/client/internal.ts +58 -0
- package/src/client/link-pending-store.ts +116 -0
- package/src/client/link.tsx +343 -150
- package/src/client/nav-link-store.ts +37 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +338 -0
- package/src/client/navigation-context.ts +35 -7
- package/src/client/navigation-root.tsx +347 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/router-ref.ts +1 -1
- package/src/client/router.ts +418 -128
- package/src/client/rsc-fetch.ts +208 -10
- package/src/client/segment-cache.ts +6 -3
- package/src/client/segment-outlet.tsx +77 -0
- package/src/client/segment-update-context.ts +42 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/ssr-data.ts +13 -5
- package/src/client/stale-reload.ts +72 -3
- package/src/client/state.ts +2 -2
- package/src/client/top-loader.tsx +11 -9
- package/src/client/use-cookie.ts +31 -2
- package/src/client/use-link-status.ts +7 -7
- package/src/client/use-pathname.ts +1 -0
- package/src/client/use-pending-navigation.ts +40 -0
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +4 -1
- package/src/client/use-search-params.ts +26 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +9 -6
- package/src/codec.ts +147 -0
- package/src/config-types.ts +292 -0
- package/src/config-validation.ts +303 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +233 -53
- package/src/cookies/index.ts +12 -1
- package/src/cookies/json-cookie.ts +105 -0
- package/src/cookies/validation.ts +192 -0
- package/src/dev-tools/404-page.ts +387 -0
- package/src/dev-tools/browser-logs.ts +291 -0
- package/src/dev-tools/error-page.ts +507 -0
- package/src/dev-tools/holding-server.ts +187 -0
- package/src/dev-tools/index.ts +90 -0
- package/src/dev-tools/instrumentation.ts +176 -0
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +9 -5
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +183 -0
- package/src/{server/dev-warnings.ts → dev-tools/warnings.ts} +5 -50
- package/src/fonts/ast.ts +525 -16
- package/src/fonts/bundle.ts +131 -0
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/local.ts +3 -3
- package/src/fonts/pipeline.ts +337 -0
- package/src/fonts/transform.ts +317 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +235 -0
- package/src/index.ts +415 -345
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +115 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +116 -0
- package/src/plugin-context.ts +247 -0
- package/src/plugins/adapter-build.ts +98 -4
- package/src/plugins/build-manifest.ts +168 -23
- package/src/plugins/build-report.ts +16 -25
- package/src/plugins/cache.ts +180 -0
- package/src/plugins/client-chunks.ts +113 -0
- package/src/plugins/cloudflare-wasm.ts +103 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +179 -37
- package/src/plugins/entries.ts +110 -8
- package/src/plugins/fonts.ts +167 -655
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/routing.ts +386 -47
- package/src/plugins/server-bundle.ts +59 -3
- package/src/plugins/shims.ts +136 -35
- package/src/plugins/static-build.ts +15 -89
- package/src/routing/codegen-shared.ts +115 -0
- package/src/routing/codegen-types.ts +61 -0
- package/src/routing/codegen.ts +321 -177
- package/src/routing/convention-lint.ts +357 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +1 -1
- package/src/routing/link-codegen.ts +310 -0
- package/src/routing/scanner.ts +165 -110
- package/src/routing/schema-validation.ts +149 -0
- package/src/routing/segment-classify.ts +188 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/types.ts +78 -25
- package/src/routing/walkers.ts +90 -0
- 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} +60 -22
- package/src/search-params/define.ts +538 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/registry.ts +2 -2
- package/src/search-params/wrappers.ts +92 -0
- package/src/segment-params/define.ts +309 -0
- package/src/segment-params/index.ts +9 -0
- package/src/server/access-gate.tsx +76 -34
- package/src/server/action-client.ts +119 -28
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +112 -14
- package/src/server/actions.ts +34 -26
- package/src/server/als-registry.ts +108 -20
- package/src/server/asset-headers.ts +8 -34
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +17 -4
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +25 -7
- package/src/server/cookie-context.ts +473 -0
- package/src/server/cookie-parsing.ts +135 -0
- package/src/server/csrf.ts +39 -6
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-boundary.ts +218 -0
- package/src/server/deny-renderer.ts +32 -52
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/early-hints.ts +35 -27
- package/src/server/error-boundary-wrapper.ts +74 -22
- package/src/server/fallback-error.ts +74 -102
- 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 +101 -5
- package/src/server/html-injector-core.ts +418 -0
- package/src/server/html-injectors.ts +238 -223
- package/src/server/index.ts +29 -183
- package/src/server/internal.ts +182 -0
- package/src/server/logger.ts +67 -36
- package/src/server/metadata-routes.ts +44 -19
- package/src/server/middleware-runner.ts +75 -4
- package/src/server/node-stream-transforms.ts +361 -0
- package/src/server/param-coercion.ts +206 -0
- package/src/server/pipeline-helpers.ts +204 -0
- package/src/server/pipeline-interception.ts +32 -18
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline-outcome.ts +197 -0
- package/src/server/pipeline-phases.ts +527 -0
- package/src/server/pipeline.ts +201 -382
- package/src/server/port-resolution.ts +215 -0
- package/src/server/primitives.ts +130 -46
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +168 -337
- package/src/server/route-element-builder.ts +437 -208
- package/src/server/route-handler.ts +31 -4
- package/src/server/route-matcher.ts +128 -277
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +69 -32
- package/src/server/rsc-entry/error-renderer.ts +316 -89
- package/src/server/rsc-entry/helpers.ts +155 -26
- package/src/server/rsc-entry/index.ts +283 -329
- package/src/server/rsc-entry/render-route.ts +313 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +344 -0
- package/src/server/rsc-entry/rsc-payload.ts +65 -22
- package/src/server/rsc-entry/rsc-stream.ts +85 -13
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +271 -41
- package/src/server/rsc-entry/wrap-action-dispatch.ts +449 -0
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/sitemap-generator.ts +338 -0
- package/src/server/sitemap-handler.ts +148 -0
- package/src/server/slot-resolver.ts +234 -246
- package/src/server/ssr-bridge-types.ts +124 -0
- package/src/server/ssr-entry.ts +217 -78
- package/src/server/ssr-render.ts +344 -71
- package/src/server/ssr-wrappers.tsx +141 -0
- package/src/server/state-tree-diff.ts +30 -23
- package/src/server/status-code-resolver.ts +112 -128
- package/src/server/stream-utils.ts +213 -0
- package/src/server/tracing.ts +21 -10
- package/src/server/tree-builder.ts +204 -90
- package/src/server/tree-match.ts +210 -0
- package/src/server/types.ts +78 -9
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/version-skew.ts +104 -0
- package/src/shared/href-validation.ts +127 -0
- 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/headers.ts +5 -1
- package/src/shims/navigation-client.ts +4 -3
- package/src/shims/navigation.ts +14 -7
- package/src/utils/state-machine.ts +111 -0
- package/LICENSE +0 -8
- package/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-B3Gypr3D.js +0 -108
- package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
- package/dist/_chunks/format-RyoGQL74.js.map +0 -1
- package/dist/_chunks/interception-BOoWmLUA.js +0 -676
- package/dist/_chunks/interception-BOoWmLUA.js.map +0 -1
- package/dist/_chunks/metadata-routes-Cjmvi3rQ.js.map +0 -1
- package/dist/_chunks/request-context-BQUC8PHn.js +0 -330
- package/dist/_chunks/request-context-BQUC8PHn.js.map +0 -1
- package/dist/_chunks/ssr-data-MjmprTmO.js.map +0 -1
- package/dist/_chunks/tracing-CemImE6h.js +0 -187
- package/dist/_chunks/tracing-CemImE6h.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/browser-entry.d.ts +0 -21
- package/dist/client/browser-entry.d.ts.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/segment-merger.d.ts +0 -119
- package/dist/client/segment-merger.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts.map +0 -1
- package/dist/client/use-navigation-pending.d.ts +0 -26
- package/dist/client/use-navigation-pending.d.ts.map +0 -1
- package/dist/client/use-params.d.ts.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/dev-error-overlay.d.ts +0 -60
- package/dist/plugins/dev-error-overlay.d.ts.map +0 -1
- package/dist/plugins/dev-logs.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/plugins/server-action-exports.d.ts +0 -26
- package/dist/plugins/server-action-exports.d.ts.map +0 -1
- package/dist/routing/status-file-lint.d.ts +0 -33
- package/dist/routing/status-file-lint.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/server/dev-fetch-instrumentation.d.ts +0 -22
- package/dist/server/dev-fetch-instrumentation.d.ts.map +0 -1
- package/dist/server/dev-logger.d.ts.map +0 -1
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/manifest-status-resolver.d.ts +0 -58
- package/dist/server/manifest-status-resolver.d.ts.map +0 -1
- package/dist/server/prerender.d.ts +0 -77
- package/dist/server/prerender.d.ts.map +0 -1
- package/dist/utils/directive-parser.d.ts +0 -70
- package/dist/utils/directive-parser.d.ts.map +0 -1
- package/src/cache/register-cached-function.ts +0 -103
- package/src/client/browser-entry.ts +0 -678
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/segment-merger.ts +0 -339
- package/src/client/transition-root.tsx +0 -166
- package/src/client/use-navigation-pending.ts +0 -38
- package/src/plugins/cache-transform.ts +0 -199
- package/src/plugins/dev-error-overlay.ts +0 -230
- package/src/plugins/dynamic-transform.ts +0 -161
- package/src/plugins/server-action-exports.ts +0 -220
- package/src/routing/status-file-lint.ts +0 -112
- 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/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/utils/directive-parser.ts +0 -529
- /package/src/{server/dev-logger.ts → dev-tools/logger.ts} +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform-hook logic for the timber-fonts plugin.
|
|
3
|
+
*
|
|
4
|
+
* Scans source files for font function calls (`Inter({...})`,
|
|
5
|
+
* `localFont({...})`), validates that they are statically analysable,
|
|
6
|
+
* registers the extracted fonts in the `FontPipeline`, and rewrites the
|
|
7
|
+
* call sites to static `FontResult` literals so the runtime never has to
|
|
8
|
+
* evaluate the font function.
|
|
9
|
+
*
|
|
10
|
+
* Uses a single OXC (via vite.parseAst) parse of the source file (via `findFontCallSites`)
|
|
11
|
+
* and magic-string for precise source rewrites with source maps.
|
|
12
|
+
*
|
|
13
|
+
* Design doc: 24-fonts.md
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import MagicString from 'magic-string';
|
|
17
|
+
import type { ExtractedFont, GoogleFontConfig } from './types.js';
|
|
18
|
+
import { buildFontStack } from './fallbacks.js';
|
|
19
|
+
import { processLocalFont } from './local.js';
|
|
20
|
+
import {
|
|
21
|
+
extractFontConfigAst,
|
|
22
|
+
detectDynamicFontCallAst,
|
|
23
|
+
findFontCallSites,
|
|
24
|
+
extractGoogleFontConfigFromNode,
|
|
25
|
+
extractLocalFontConfigFromNode,
|
|
26
|
+
} from './ast.js';
|
|
27
|
+
import type { FontPipeline } from './pipeline.js';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Convert a font family name to a scoped class name.
|
|
31
|
+
* e.g. "JetBrains Mono" → "timber-font-jetbrains-mono"
|
|
32
|
+
*/
|
|
33
|
+
function familyToClassName(family: string): string {
|
|
34
|
+
return `timber-font-${family.toLowerCase().replace(/\s+/g, '-')}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Normalize a string or string array to an array (default `['400']`). */
|
|
38
|
+
function normalizeWeightArray(value: string | string[] | undefined): string[] {
|
|
39
|
+
if (!value) return ['400'];
|
|
40
|
+
return Array.isArray(value) ? value : [value];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Normalize style to an array (default `['normal']`). */
|
|
44
|
+
function normalizeStyleArray(value: string | string[] | undefined): string[] {
|
|
45
|
+
if (!value) return ['normal'];
|
|
46
|
+
return Array.isArray(value) ? value : [value];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Generate a unique font ID from family + config hash.
|
|
51
|
+
*
|
|
52
|
+
* The ID intentionally includes every property that affects the rendered
|
|
53
|
+
* `@font-face` output (`weight`, `style`, `subsets`, `display`) so that an
|
|
54
|
+
* HMR edit changing any of those produces a new ID and the registry is
|
|
55
|
+
* forced to re-emit fresh CSS.
|
|
56
|
+
*/
|
|
57
|
+
export function generateFontId(family: string, config: GoogleFontConfig): string {
|
|
58
|
+
const weights = normalizeWeightArray(config.weight);
|
|
59
|
+
const styles = normalizeStyleArray(config.style);
|
|
60
|
+
const subsets = config.subsets ?? ['latin'];
|
|
61
|
+
const display = config.display ?? 'swap';
|
|
62
|
+
return `${family.toLowerCase()}-${weights.join(',')}-${styles.join(',')}-${subsets.join(',')}-${display}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Extract static font config from a font function call source.
|
|
67
|
+
*
|
|
68
|
+
* Returns `null` if the call cannot be statically analysed.
|
|
69
|
+
*/
|
|
70
|
+
export function extractFontConfig(callSource: string): GoogleFontConfig | null {
|
|
71
|
+
return extractFontConfigAst(callSource);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Detect dynamic/computed font function calls that cannot be statically
|
|
76
|
+
* analysed. Returns the offending expression text, or `null` if all calls
|
|
77
|
+
* are static.
|
|
78
|
+
*/
|
|
79
|
+
export function detectDynamicFontCall(source: string, importedNames: string[]): string | null {
|
|
80
|
+
return detectDynamicFontCallAst(source, importedNames);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── Regex-free import/family parsing (thin wrappers over AST) ────────────────
|
|
84
|
+
//
|
|
85
|
+
// These keep the public surface stable. They use `findFontCallSites`
|
|
86
|
+
// internally so they agree with the transform on what counts as an import.
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Parse the local names imported from `@timber/fonts/google` /
|
|
90
|
+
* `next/font/google`. e.g. `import { Inter, JetBrains_Mono as Mono }` →
|
|
91
|
+
* `['Inter', 'Mono']`.
|
|
92
|
+
*/
|
|
93
|
+
export function parseGoogleFontImports(source: string): string[] {
|
|
94
|
+
const analysis = findFontCallSites(source);
|
|
95
|
+
if (!analysis) return [];
|
|
96
|
+
return analysis.bindings.filter((b) => b.provider === 'google').map((b) => b.localName);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Parse Google font imports into a `localName → familyName` map.
|
|
101
|
+
*
|
|
102
|
+
* e.g. `import { JetBrains_Mono as Mono }` → `{ Mono: 'JetBrains Mono' }`.
|
|
103
|
+
* The original (pre-`as`) name is converted from PascalCase-with-underscores
|
|
104
|
+
* to the human-readable family name by replacing `_` with a space.
|
|
105
|
+
*/
|
|
106
|
+
export function parseGoogleFontFamilies(source: string): Map<string, string> {
|
|
107
|
+
const analysis = findFontCallSites(source);
|
|
108
|
+
const families = new Map<string, string>();
|
|
109
|
+
if (!analysis) return families;
|
|
110
|
+
for (const b of analysis.bindings) {
|
|
111
|
+
if (b.provider !== 'google') continue;
|
|
112
|
+
const family = b.importedName.replace(/_/g, ' ');
|
|
113
|
+
families.set(b.localName, family);
|
|
114
|
+
}
|
|
115
|
+
return families;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Parse the local name used for the default import of `@timber/fonts/local`.
|
|
120
|
+
*
|
|
121
|
+
* Handles either spelling and arbitrary local names:
|
|
122
|
+
* import localFont from '@timber/fonts/local'
|
|
123
|
+
* import myLoader from 'next/font/local'
|
|
124
|
+
*/
|
|
125
|
+
export function parseLocalFontImportName(source: string): string | null {
|
|
126
|
+
const analysis = findFontCallSites(source);
|
|
127
|
+
if (!analysis) return null;
|
|
128
|
+
const localBinding = analysis.bindings.find((b) => b.provider === 'local');
|
|
129
|
+
return localBinding?.localName ?? null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Build the static `FontResult` literal we substitute for a font call. */
|
|
133
|
+
function buildFontResultLiteral(extracted: ExtractedFont): string {
|
|
134
|
+
return extracted.variable
|
|
135
|
+
? `{ className: "${extracted.className}", style: { fontFamily: "${extracted.fontFamily}" }, variable: "${extracted.variable}" }`
|
|
136
|
+
: `{ className: "${extracted.className}", style: { fontFamily: "${extracted.fontFamily}" } }`;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Type for the Vite plugin's `this.error` callback. */
|
|
140
|
+
type EmitError = (msg: string) => never;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* File extensions that may contain real font imports. Only JS/TS module
|
|
144
|
+
* variants are scanned. Excluding non-JS extensions (.mdx, .md, .css,
|
|
145
|
+
* .json, etc.) prevents false-positive matches on text that mentions a
|
|
146
|
+
* font specifier inside documentation, code fences, or asset metadata.
|
|
147
|
+
*
|
|
148
|
+
* See TIM-840.
|
|
149
|
+
*/
|
|
150
|
+
const FONT_IMPORT_SCANNABLE_EXTENSIONS = new Set([
|
|
151
|
+
'.js',
|
|
152
|
+
'.jsx',
|
|
153
|
+
'.ts',
|
|
154
|
+
'.tsx',
|
|
155
|
+
'.mjs',
|
|
156
|
+
'.cjs',
|
|
157
|
+
'.mts',
|
|
158
|
+
'.cts',
|
|
159
|
+
]);
|
|
160
|
+
|
|
161
|
+
function hasScannableExtension(id: string): boolean {
|
|
162
|
+
const path = id.split('?', 1)[0];
|
|
163
|
+
const dot = path.lastIndexOf('.');
|
|
164
|
+
if (dot === -1) return false;
|
|
165
|
+
return FONT_IMPORT_SCANNABLE_EXTENSIONS.has(path.slice(dot).toLowerCase());
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Run the timber-fonts transform pass on a single source file.
|
|
170
|
+
*
|
|
171
|
+
* Parses the source once with OXC (via vite.parseAst), walks the AST to find font imports
|
|
172
|
+
* and call sites, then uses magic-string to rewrite call sites to static
|
|
173
|
+
* `FontResult` literals and strip the import declarations. Returns a
|
|
174
|
+
* source map alongside the transformed code.
|
|
175
|
+
*
|
|
176
|
+
* Returns `null` if the file does not import from any font virtual module.
|
|
177
|
+
*/
|
|
178
|
+
export function runFontsTransform(
|
|
179
|
+
code: string,
|
|
180
|
+
id: string,
|
|
181
|
+
pipeline: FontPipeline,
|
|
182
|
+
emitError: EmitError
|
|
183
|
+
): { code: string; map: ReturnType<MagicString['generateMap']> } | null {
|
|
184
|
+
// Skip virtual modules and node_modules
|
|
185
|
+
if (id.startsWith('\0') || id.includes('node_modules')) return null;
|
|
186
|
+
|
|
187
|
+
// Only scan JS/TS module variants (see TIM-840).
|
|
188
|
+
if (!hasScannableExtension(id)) return null;
|
|
189
|
+
|
|
190
|
+
// Fast pre-filter: skip files that don't mention any font module.
|
|
191
|
+
const hasGoogleImport =
|
|
192
|
+
code.includes('@timber/fonts/google') ||
|
|
193
|
+
code.includes('@timber-js/app/fonts/google') ||
|
|
194
|
+
code.includes('next/font/google');
|
|
195
|
+
const hasLocalImport =
|
|
196
|
+
code.includes('@timber/fonts/local') ||
|
|
197
|
+
code.includes('@timber-js/app/fonts/local') ||
|
|
198
|
+
code.includes('next/font/local');
|
|
199
|
+
if (!hasGoogleImport && !hasLocalImport) return null;
|
|
200
|
+
|
|
201
|
+
// Single parse + AST walk.
|
|
202
|
+
const analysis = findFontCallSites(code);
|
|
203
|
+
if (!analysis) return null;
|
|
204
|
+
|
|
205
|
+
// Bail on dynamic calls.
|
|
206
|
+
if (analysis.dynamicCall) {
|
|
207
|
+
emitError(
|
|
208
|
+
`Font function calls must be statically analyzable. ` +
|
|
209
|
+
`Found dynamic call: ${analysis.dynamicCall}. ` +
|
|
210
|
+
`Pass a literal object with string/array values instead.`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Bail on nested font calls (must be module-level).
|
|
215
|
+
if (analysis.nestedCalls.length > 0) {
|
|
216
|
+
const first = analysis.nestedCalls[0];
|
|
217
|
+
emitError(
|
|
218
|
+
`Font function \`${first.name}()\` must be called at module scope. ` +
|
|
219
|
+
`Found nested call at line ${first.line}, column ${first.column}. ` +
|
|
220
|
+
`Move the call to the top level of the module.`
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (analysis.callSites.length === 0 && analysis.bindings.length === 0) return null;
|
|
225
|
+
|
|
226
|
+
const s = new MagicString(code);
|
|
227
|
+
|
|
228
|
+
// Process each call site.
|
|
229
|
+
for (const site of analysis.callSites) {
|
|
230
|
+
if (site.binding.provider === 'google') {
|
|
231
|
+
const family = site.binding.importedName.replace(/_/g, ' ');
|
|
232
|
+
|
|
233
|
+
const config = extractGoogleFontConfigFromNode(site.configNode);
|
|
234
|
+
if (!config) {
|
|
235
|
+
emitError(
|
|
236
|
+
`Could not statically analyze font config for ${family} ` +
|
|
237
|
+
`at line ${site.line}, column ${site.column}. ` +
|
|
238
|
+
`Ensure all config values are string literals or arrays of string literals.`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const fontId = generateFontId(family, config!);
|
|
243
|
+
const className = familyToClassName(family);
|
|
244
|
+
const fontStack = buildFontStack(family);
|
|
245
|
+
const display = config!.display ?? 'swap';
|
|
246
|
+
|
|
247
|
+
const extracted: ExtractedFont = {
|
|
248
|
+
id: fontId,
|
|
249
|
+
family,
|
|
250
|
+
provider: 'google',
|
|
251
|
+
weights: normalizeWeightArray(config!.weight),
|
|
252
|
+
styles: normalizeStyleArray(config!.style),
|
|
253
|
+
subsets: config!.subsets ?? ['latin'],
|
|
254
|
+
display,
|
|
255
|
+
variable: config!.variable,
|
|
256
|
+
className,
|
|
257
|
+
fontFamily: fontStack,
|
|
258
|
+
importer: id,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
pipeline.pruneFor(id, family);
|
|
262
|
+
pipeline.register(extracted);
|
|
263
|
+
|
|
264
|
+
s.overwrite(site.replaceStart, site.replaceEnd, buildFontResultLiteral(extracted));
|
|
265
|
+
} else {
|
|
266
|
+
// local font
|
|
267
|
+
const config = extractLocalFontConfigFromNode(site.configNode);
|
|
268
|
+
if (!config) {
|
|
269
|
+
emitError(
|
|
270
|
+
`Could not statically analyze local font config ` +
|
|
271
|
+
`at line ${site.line}, column ${site.column}. ` +
|
|
272
|
+
`Ensure src is a string or array of { path, weight?, style? } objects.`
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const extracted = processLocalFont(config!, id);
|
|
277
|
+
pipeline.pruneFor(id, extracted.family);
|
|
278
|
+
pipeline.register(extracted);
|
|
279
|
+
|
|
280
|
+
s.overwrite(site.replaceStart, site.replaceEnd, buildFontResultLiteral(extracted));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Remove font import declarations. Use a Set to avoid double-removing
|
|
285
|
+
// when multiple bindings come from the same ImportDeclaration.
|
|
286
|
+
const removedRanges = new Set<string>();
|
|
287
|
+
for (const imp of analysis.importNodesToRemove) {
|
|
288
|
+
const key = `${imp.start}:${imp.end}`;
|
|
289
|
+
if (removedRanges.has(key)) continue;
|
|
290
|
+
removedRanges.add(key);
|
|
291
|
+
|
|
292
|
+
// Also remove the trailing newline if present.
|
|
293
|
+
let end = imp.end;
|
|
294
|
+
if (code[end] === '\n') end++;
|
|
295
|
+
else if (code[end] === '\r' && code[end + 1] === '\n') end += 2;
|
|
296
|
+
// Also remove a trailing semicolon before the newline.
|
|
297
|
+
if (code[imp.end] === ';') {
|
|
298
|
+
end = imp.end + 1;
|
|
299
|
+
if (code[end] === '\n') end++;
|
|
300
|
+
else if (code[end] === '\r' && code[end + 1] === '\n') end += 2;
|
|
301
|
+
}
|
|
302
|
+
s.remove(imp.start, end);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (!s.hasChanged()) return null;
|
|
306
|
+
|
|
307
|
+
// Inject a side-effect import for the per-importer virtual CSS module.
|
|
308
|
+
if (pipeline.size() > 0) {
|
|
309
|
+
const virtualCssId = pipeline.cssIdMap.idFor(id);
|
|
310
|
+
s.prepend(`import '${virtualCssId}';\n`);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
code: s.toString(),
|
|
315
|
+
map: s.generateMap({ hires: true }),
|
|
316
|
+
};
|
|
317
|
+
}
|
package/src/fonts/types.ts
CHANGED
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
* Design doc: 24-fonts.md
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
// `CachedFont` lives in `google.ts`. Importing it here is type-only so
|
|
11
|
+
// there is no runtime dependency cycle — TypeScript erases the import.
|
|
12
|
+
import type { CachedFont } from './google.js';
|
|
13
|
+
|
|
10
14
|
/** Configuration passed to a Google font function (e.g. `Inter({ ... })`). */
|
|
11
15
|
export interface GoogleFontConfig {
|
|
12
16
|
weight?: string | string[];
|
|
@@ -22,6 +26,8 @@ export interface LocalFontSrc {
|
|
|
22
26
|
path: string;
|
|
23
27
|
weight?: string;
|
|
24
28
|
style?: string;
|
|
29
|
+
/** Content-hashed basename for production builds (e.g. `MyFont-Bold-a1b2c3d4.woff2`). */
|
|
30
|
+
hashedBasename?: string;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
/** Configuration passed to `localFont()`. */
|
|
@@ -47,7 +53,16 @@ export interface FontResult {
|
|
|
47
53
|
variable?: string;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Internal representation of a font extracted during static analysis.
|
|
58
|
+
*
|
|
59
|
+
* `ExtractedFont` is the **registration input** to `FontPipeline.register()`.
|
|
60
|
+
* Once a font has been registered the pipeline stores a `FontEntry` (which
|
|
61
|
+
* extends `ExtractedFont` with optional resolved `@font-face` descriptors
|
|
62
|
+
* and cached binary files). External code that needs to model a font that
|
|
63
|
+
* is not yet inside a pipeline (e.g. test fixtures) should use
|
|
64
|
+
* `ExtractedFont` directly.
|
|
65
|
+
*/
|
|
51
66
|
export interface ExtractedFont {
|
|
52
67
|
/** Unique identifier for this font instance (e.g. `inter-400-normal-latin`). */
|
|
53
68
|
id: string;
|
|
@@ -86,3 +101,39 @@ export interface FontFaceDescriptor {
|
|
|
86
101
|
display?: string;
|
|
87
102
|
unicodeRange?: string;
|
|
88
103
|
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The unified per-font store entry held inside `FontPipeline`.
|
|
107
|
+
*
|
|
108
|
+
* Combines what used to live in three parallel maps:
|
|
109
|
+
*
|
|
110
|
+
* - `registry: Map<string, ExtractedFont>` → the base extracted config
|
|
111
|
+
* - `googleFontFacesMap: Map<string, FontFaceDescriptor[]>` → `faces`
|
|
112
|
+
* - `cachedFonts: CachedFont[]` (flat, family-grouped) → `cachedFiles`
|
|
113
|
+
*
|
|
114
|
+
* `pruneFor` drops the entry **and** all of its attached state in one
|
|
115
|
+
* operation, so future code paths cannot reintroduce a TIM-824-style
|
|
116
|
+
* desync between parallel maps.
|
|
117
|
+
*
|
|
118
|
+
* See TIM-829.
|
|
119
|
+
*/
|
|
120
|
+
export interface FontEntry extends ExtractedFont {
|
|
121
|
+
/**
|
|
122
|
+
* Pre-resolved `@font-face` descriptors. Populated in `buildStart`
|
|
123
|
+
* (production) or lazily in `load` (dev). For local fonts the descriptors
|
|
124
|
+
* are derived from the source list at CSS-generation time and are not
|
|
125
|
+
* stored here.
|
|
126
|
+
*/
|
|
127
|
+
faces?: FontFaceDescriptor[];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Downloaded Google Font binaries that back this entry's `@font-face`
|
|
131
|
+
* declarations. Empty for local fonts and in dev mode (where Google fonts
|
|
132
|
+
* are served straight from the CDN).
|
|
133
|
+
*
|
|
134
|
+
* Multiple entries that share the same `family` will hold references to
|
|
135
|
+
* the same `CachedFont` objects. The bundle emitter dedupes by
|
|
136
|
+
* `hashedFilename` so each binary is written exactly once.
|
|
137
|
+
*/
|
|
138
|
+
cachedFiles?: CachedFont[];
|
|
139
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Virtual module source generators for the timber-fonts plugin.
|
|
3
|
+
*
|
|
4
|
+
* The plugin exposes three virtual modules:
|
|
5
|
+
*
|
|
6
|
+
* - `@timber/fonts/google` — exports Google font loader functions. The
|
|
7
|
+
* transform hook replaces actual call sites with static `FontResult`
|
|
8
|
+
* objects, so this module is only loaded as a fallback (e.g. when the
|
|
9
|
+
* transform hook hasn't run yet, or when an unknown font is referenced
|
|
10
|
+
* via the default export proxy).
|
|
11
|
+
* - `@timber/fonts/local` — exports `localFont()` as a fallback default.
|
|
12
|
+
* - `virtual:timber-font-css/<hash>.css` — per-importer CSS module that
|
|
13
|
+
* holds the combined `@font-face` + fallback + class CSS for every
|
|
14
|
+
* font registered under that importer. The transform hook injects a
|
|
15
|
+
* side-effect `import 'virtual:timber-font-css/<hash>.css'` into each
|
|
16
|
+
* file that calls a font function, so Vite's CSS pipeline picks it up
|
|
17
|
+
* like any other CSS asset. @vitejs/plugin-rsc's `collectCss` walks
|
|
18
|
+
* the RSC module graph, finds the virtual module, and injects a
|
|
19
|
+
* `<link rel="stylesheet" data-rsc-css-href=...>` via React Float —
|
|
20
|
+
* the same machinery component CSS rides on (TIM-828).
|
|
21
|
+
*
|
|
22
|
+
* The `.css` suffix is load-bearing: Vite's `isCSSRequest` regex matches
|
|
23
|
+
* on file extension, so keeping it in the virtual id is how we tell
|
|
24
|
+
* Vite's CSS pipeline (dev HMR + build asset emission) that this
|
|
25
|
+
* module is CSS. The old `virtual:timber-font-css-register` side-effect
|
|
26
|
+
* module, `globalThis.__timber_font_css` channel, and inline `<style>`
|
|
27
|
+
* tag in the RSC entry were all removed in TIM-828.
|
|
28
|
+
*
|
|
29
|
+
* Design doc: 24-fonts.md
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { createHash } from 'node:crypto';
|
|
33
|
+
import type { ExtractedFont, FontFaceDescriptor } from './types.js';
|
|
34
|
+
import { generateVariableClass, generateFontFamilyClass, generateFontFaces } from './css.js';
|
|
35
|
+
import { generateFallbackCss } from './fallbacks.js';
|
|
36
|
+
import { generateLocalFontFaces } from './local.js';
|
|
37
|
+
|
|
38
|
+
export const VIRTUAL_GOOGLE = '@timber/fonts/google';
|
|
39
|
+
export const VIRTUAL_LOCAL = '@timber/fonts/local';
|
|
40
|
+
export const RESOLVED_GOOGLE = '\0@timber/fonts/google';
|
|
41
|
+
export const RESOLVED_LOCAL = '\0@timber/fonts/local';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Prefix used for the per-importer virtual CSS modules. The full id is
|
|
45
|
+
* `virtual:timber-font-css/<hash>.css` where `<hash>` is a short SHA-256
|
|
46
|
+
* digest of the importer path. We encode the hash (not the path itself)
|
|
47
|
+
* so the id stays filesystem-safe and opaque to downstream consumers.
|
|
48
|
+
*/
|
|
49
|
+
export const VIRTUAL_FONT_CSS_PREFIX = 'virtual:timber-font-css/';
|
|
50
|
+
export const VIRTUAL_FONT_CSS_SUFFIX = '.css';
|
|
51
|
+
export const RESOLVED_FONT_CSS_PREFIX = '\0' + VIRTUAL_FONT_CSS_PREFIX;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* In-memory map from the short hash used in virtual module ids back to
|
|
55
|
+
* the absolute importer path. Populated by `virtualFontCssIdFor()` when
|
|
56
|
+
* the transform hook registers an importer and read by the plugin's
|
|
57
|
+
* `load` hook when Vite asks for the CSS content.
|
|
58
|
+
*
|
|
59
|
+
* Scoped to a single `FontPipeline` instance to avoid cross-plugin-
|
|
60
|
+
* instance collisions during multi-build pipelines.
|
|
61
|
+
*/
|
|
62
|
+
function stripIdDecorations(id: string): string {
|
|
63
|
+
const bare = id.startsWith('\0') ? id.slice(1) : id;
|
|
64
|
+
const qIdx = bare.indexOf('?');
|
|
65
|
+
return qIdx === -1 ? bare : bare.slice(0, qIdx);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class VirtualFontCssIdMap {
|
|
69
|
+
private readonly map = new Map<string, string>();
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Return a stable virtual module id for `importer`. Calling this twice
|
|
73
|
+
* with the same importer returns the same id. Registering under an
|
|
74
|
+
* existing hash is idempotent.
|
|
75
|
+
*/
|
|
76
|
+
idFor(importer: string): string {
|
|
77
|
+
const hash = createHash('sha256').update(importer).digest('hex').slice(0, 16);
|
|
78
|
+
this.map.set(hash, importer);
|
|
79
|
+
return `${VIRTUAL_FONT_CSS_PREFIX}${hash}${VIRTUAL_FONT_CSS_SUFFIX}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Decode the importer from a resolved (or unresolved) virtual css id. */
|
|
83
|
+
importerFor(id: string): string | undefined {
|
|
84
|
+
const body = stripIdDecorations(id);
|
|
85
|
+
if (!body.startsWith(VIRTUAL_FONT_CSS_PREFIX)) return undefined;
|
|
86
|
+
if (!body.endsWith(VIRTUAL_FONT_CSS_SUFFIX)) return undefined;
|
|
87
|
+
const hash = body.slice(
|
|
88
|
+
VIRTUAL_FONT_CSS_PREFIX.length,
|
|
89
|
+
body.length - VIRTUAL_FONT_CSS_SUFFIX.length
|
|
90
|
+
);
|
|
91
|
+
return this.map.get(hash);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** True if `id` is any form of the virtual font css module. */
|
|
95
|
+
matches(id: string): boolean {
|
|
96
|
+
const body = stripIdDecorations(id);
|
|
97
|
+
return body.startsWith(VIRTUAL_FONT_CSS_PREFIX) && body.endsWith(VIRTUAL_FONT_CSS_SUFFIX);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Drop every registered mapping. Used by tests. */
|
|
101
|
+
clear(): void {
|
|
102
|
+
this.map.clear();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Convert a font family name to a PascalCase export name.
|
|
108
|
+
* e.g. "JetBrains Mono" → "JetBrains_Mono"
|
|
109
|
+
*/
|
|
110
|
+
function familyToExportName(family: string): string {
|
|
111
|
+
return family.replace(/\s+/g, '_');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Generate the virtual module source for `@timber/fonts/google`.
|
|
116
|
+
*
|
|
117
|
+
* The transform hook replaces real call sites at build time, so this
|
|
118
|
+
* module only matters as a runtime fallback. We export a Proxy default
|
|
119
|
+
* that handles any font name plus named exports for known families
|
|
120
|
+
* (for tree-shaking).
|
|
121
|
+
*/
|
|
122
|
+
export function generateGoogleVirtualModule(fonts: Iterable<ExtractedFont>): string {
|
|
123
|
+
const families = new Set<string>();
|
|
124
|
+
for (const font of fonts) {
|
|
125
|
+
if (font.provider === 'google') families.add(font.family);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const lines = [
|
|
129
|
+
'// Auto-generated virtual module: @timber/fonts/google',
|
|
130
|
+
'// Each export is a font loader function that returns a FontResult.',
|
|
131
|
+
'',
|
|
132
|
+
'function createFontResult(family, config) {',
|
|
133
|
+
' return {',
|
|
134
|
+
// eslint-disable-next-line no-template-curly-in-string -- codegen output
|
|
135
|
+
' className: `timber-font-${family.toLowerCase().replace(/\\s+/g, "-")}`,',
|
|
136
|
+
' style: { fontFamily: family },',
|
|
137
|
+
' variable: config?.variable,',
|
|
138
|
+
' };',
|
|
139
|
+
'}',
|
|
140
|
+
'',
|
|
141
|
+
'export default new Proxy({}, {',
|
|
142
|
+
' get(_, prop) {',
|
|
143
|
+
' if (typeof prop === "string") {',
|
|
144
|
+
' return (config) => createFontResult(prop.replace(/_/g, " "), config);',
|
|
145
|
+
' }',
|
|
146
|
+
' }',
|
|
147
|
+
'});',
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
for (const family of families) {
|
|
151
|
+
const exportName = familyToExportName(family);
|
|
152
|
+
lines.push('');
|
|
153
|
+
lines.push(`export function ${exportName}(config) {`);
|
|
154
|
+
lines.push(` return createFontResult('${family}', config);`);
|
|
155
|
+
lines.push('}');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return lines.join('\n');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Generate the virtual module source for `@timber/fonts/local`.
|
|
163
|
+
*
|
|
164
|
+
* Like the google virtual module, this is a runtime fallback. The
|
|
165
|
+
* transform hook normally replaces `localFont(...)` calls with static
|
|
166
|
+
* `FontResult` objects at build time.
|
|
167
|
+
*/
|
|
168
|
+
export function generateLocalVirtualModule(): string {
|
|
169
|
+
return [
|
|
170
|
+
'// Auto-generated virtual module: @timber/fonts/local',
|
|
171
|
+
'',
|
|
172
|
+
'export default function localFont(config) {',
|
|
173
|
+
' const family = config?.family || "Local Font";',
|
|
174
|
+
' return {',
|
|
175
|
+
// eslint-disable-next-line no-template-curly-in-string -- codegen output
|
|
176
|
+
' className: `timber-font-${family.toLowerCase().replace(/\\s+/g, "-")}`,',
|
|
177
|
+
' style: { fontFamily: family },',
|
|
178
|
+
' variable: config?.variable,',
|
|
179
|
+
' };',
|
|
180
|
+
'}',
|
|
181
|
+
].join('\n');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Generate combined CSS for a single extracted font.
|
|
186
|
+
*
|
|
187
|
+
* Includes `@font-face` rules (local or Google), the size-adjusted fallback
|
|
188
|
+
* `@font-face`, and the scoped class rule. For Google fonts the resolved
|
|
189
|
+
* `FontFaceDescriptor[]` must be passed in (from `generateProductionFontFaces`
|
|
190
|
+
* in production or `resolveDevFontFaces` in dev).
|
|
191
|
+
*/
|
|
192
|
+
export function generateFontCss(font: ExtractedFont, googleFaces?: FontFaceDescriptor[]): string {
|
|
193
|
+
const cssParts: string[] = [];
|
|
194
|
+
|
|
195
|
+
if (font.provider === 'local' && font.localSources) {
|
|
196
|
+
const faces = generateLocalFontFaces(font.family, font.localSources, font.display);
|
|
197
|
+
const faceCss = generateFontFaces(faces);
|
|
198
|
+
if (faceCss) cssParts.push(faceCss);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (font.provider === 'google' && googleFaces && googleFaces.length > 0) {
|
|
202
|
+
const faceCss = generateFontFaces(googleFaces);
|
|
203
|
+
if (faceCss) cssParts.push(faceCss);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const fallbackCss = generateFallbackCss(font.family);
|
|
207
|
+
if (fallbackCss) cssParts.push(fallbackCss);
|
|
208
|
+
|
|
209
|
+
if (font.variable) {
|
|
210
|
+
cssParts.push(generateVariableClass(font.className, font.variable, font.fontFamily));
|
|
211
|
+
} else {
|
|
212
|
+
cssParts.push(generateFontFamilyClass(font.className, font.fontFamily));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return cssParts.join('\n\n');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Generate the CSS output for all extracted fonts.
|
|
220
|
+
*
|
|
221
|
+
* Includes `@font-face` rules for local and Google fonts, fallback rules,
|
|
222
|
+
* and scoped classes. `googleFontFacesMap` provides pre-resolved
|
|
223
|
+
* `FontFaceDescriptor[]` for each Google font (keyed by `ExtractedFont.id`).
|
|
224
|
+
*/
|
|
225
|
+
export function generateAllFontCss(
|
|
226
|
+
registry: Map<string, ExtractedFont>,
|
|
227
|
+
googleFontFacesMap?: Map<string, FontFaceDescriptor[]>
|
|
228
|
+
): string {
|
|
229
|
+
const cssParts: string[] = [];
|
|
230
|
+
for (const font of registry.values()) {
|
|
231
|
+
const googleFaces = googleFontFacesMap?.get(font.id);
|
|
232
|
+
cssParts.push(generateFontCss(font, googleFaces));
|
|
233
|
+
}
|
|
234
|
+
return cssParts.join('\n\n');
|
|
235
|
+
}
|