@timber-js/app 0.2.0-alpha.13 → 0.2.0-alpha.132
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-BNhpxrnV.js +1104 -0
- package/dist/_chunks/actions-BNhpxrnV.js.map +1 -0
- package/dist/_chunks/build-output-helper-K7oUCRqU.js +102 -0
- package/dist/_chunks/build-output-helper-K7oUCRqU.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-CObqjGWF.js +2 -0
- package/dist/_chunks/cli-schema-sync-q-Ce6-iG.js +785 -0
- package/dist/_chunks/cli-schema-sync-q-Ce6-iG.js.map +1 -0
- package/dist/_chunks/codec-registry-DqkeAydt.js +21 -0
- package/dist/_chunks/codec-registry-DqkeAydt.js.map +1 -0
- package/dist/_chunks/define-DMq-Yjp7.js +112 -0
- package/dist/_chunks/define-DMq-Yjp7.js.map +1 -0
- package/dist/_chunks/define-jeHDXZGq.js +195 -0
- package/dist/_chunks/define-jeHDXZGq.js.map +1 -0
- package/dist/_chunks/format-BjN9HLu9.js +14 -0
- package/dist/_chunks/format-BjN9HLu9.js.map +1 -0
- package/dist/_chunks/handler-store-bIAstrxQ.js +54 -0
- package/dist/_chunks/handler-store-bIAstrxQ.js.map +1 -0
- package/dist/_chunks/logger-CMd9P1xQ.js +291 -0
- package/dist/_chunks/logger-CMd9P1xQ.js.map +1 -0
- package/dist/_chunks/merge-search-params-Cm1j99HC.js +41 -0
- package/dist/_chunks/merge-search-params-Cm1j99HC.js.map +1 -0
- package/dist/_chunks/{metadata-routes-Cjmvi3rQ.js → metadata-routes-DESG8uk5.js} +32 -19
- package/dist/_chunks/metadata-routes-DESG8uk5.js.map +1 -0
- package/dist/_chunks/navigation-root-B5-RmsPi.js +103 -0
- package/dist/_chunks/navigation-root-B5-RmsPi.js.map +1 -0
- package/dist/_chunks/registry-BI9cgCt7.js +20 -0
- package/dist/_chunks/registry-BI9cgCt7.js.map +1 -0
- package/dist/_chunks/resolve-schema-DU2nbVOi.js +77 -0
- package/dist/_chunks/resolve-schema-DU2nbVOi.js.map +1 -0
- package/dist/_chunks/router-ref-B2-2kIIC.js +28 -0
- package/dist/_chunks/router-ref-B2-2kIIC.js.map +1 -0
- package/dist/_chunks/schema-bridge-o0SwFtXW.js +86 -0
- package/dist/_chunks/schema-bridge-o0SwFtXW.js.map +1 -0
- package/dist/_chunks/segment-classify-BjfuctV2.js +137 -0
- package/dist/_chunks/segment-classify-BjfuctV2.js.map +1 -0
- package/dist/_chunks/segment-context-Bg0pFbLT.js +34 -0
- package/dist/_chunks/segment-context-Bg0pFbLT.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-DVX8S7vj.js} +1 -1
- package/dist/_chunks/ssr-data-DVX8S7vj.js.map +1 -0
- package/dist/_chunks/stale-reload-CCqb62Z3.js +84 -0
- package/dist/_chunks/stale-reload-CCqb62Z3.js.map +1 -0
- package/dist/_chunks/tracing-DP5djRq5.js +358 -0
- package/dist/_chunks/tracing-DP5djRq5.js.map +1 -0
- package/dist/_chunks/{use-query-states-D5KaffOK.js → use-query-states-C9G6LP0F.js} +7 -20
- package/dist/_chunks/use-query-states-C9G6LP0F.js.map +1 -0
- package/dist/_chunks/use-segment-params-CIeinIx2.js +151 -0
- package/dist/_chunks/use-segment-params-CIeinIx2.js.map +1 -0
- package/dist/_chunks/validation-AfEFM5ze.js +84 -0
- package/dist/_chunks/validation-AfEFM5ze.js.map +1 -0
- package/dist/_chunks/walkers-BbEu2_Pp.js +724 -0
- package/dist/_chunks/walkers-BbEu2_Pp.js.map +1 -0
- package/dist/_chunks/{format-DviM89f0.js → warnings-CAzunaGo.js} +6 -45
- package/dist/_chunks/warnings-CAzunaGo.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 +143 -45
- 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 +151 -81
- 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 +180 -1119
- 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 +845 -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 +67 -56
- 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-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-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 +46 -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 +167 -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 +45 -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 -164
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5584 -13386
- 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 +107 -0
- package/dist/plugin-context.d.ts.map +1 -0
- 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 +9 -7
- 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/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/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/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-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 -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 +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 +155 -2905
- 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 +3073 -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 +52 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +118 -23
- 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 +69 -18
- 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 +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 +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/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 +19 -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 +49 -4
- 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/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/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 +56 -16
- 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 +142 -59
- package/src/adapters/shared.ts +40 -0
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +38 -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 +25 -20
- 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 +66 -45
- package/src/client/internal.ts +58 -0
- package/src/client/link-pending-store.ts +116 -0
- package/src/client/link.tsx +336 -119
- package/src/client/nav-link-store.ts +37 -0
- package/src/client/navigation-api-types.ts +112 -0
- package/src/client/navigation-api.ts +332 -0
- package/src/client/navigation-context.ts +33 -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-pending-navigation.ts +40 -0
- package/src/client/use-query-states.ts +9 -3
- package/src/client/use-router.ts +1 -1
- package/src/client/use-search-params.ts +25 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +8 -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 +134 -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 +506 -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 +142 -0
- package/src/fonts/dev-middleware.ts +74 -0
- package/src/fonts/local.ts +1 -1
- package/src/fonts/pipeline.ts +314 -0
- package/src/fonts/transform.ts +317 -0
- package/src/fonts/types.ts +50 -1
- package/src/fonts/virtual-modules.ts +233 -0
- package/src/index.ts +411 -329
- package/src/params/codec-registry.ts +34 -0
- package/src/params/define-schema.ts +114 -0
- package/src/params/index.ts +17 -0
- package/src/params/resolve-schema.ts +116 -0
- package/src/plugin-context.ts +240 -0
- package/src/plugins/adapter-build.ts +12 -4
- package/src/plugins/build-manifest.ts +69 -6
- package/src/plugins/build-report.ts +16 -25
- package/src/plugins/client-chunks.ts +65 -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 +111 -8
- package/src/plugins/fonts.ts +165 -654
- 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 +308 -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} +57 -20
- 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 +88 -15
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +112 -14
- package/src/server/actions.ts +14 -23
- package/src/server/als-registry.ts +108 -20
- package/src/server/asset-headers.ts +8 -34
- 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 +468 -0
- package/src/server/cookie-parsing.ts +135 -0
- package/src/server/debug.ts +1 -1
- package/src/server/default-logger.ts +99 -0
- package/src/server/deny-boundary.ts +218 -0
- package/src/server/deny-renderer.ts +32 -51
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/early-hints.ts +36 -15
- 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 +417 -0
- package/src/server/html-injectors.ts +235 -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 +31 -18
- package/src/server/pipeline-metadata.ts +13 -0
- package/src/server/pipeline-outcome.ts +197 -0
- package/src/server/pipeline-phases.ts +497 -0
- package/src/server/pipeline.ts +194 -394
- package/src/server/port-resolution.ts +215 -0
- package/src/server/primitives.ts +111 -28
- package/src/server/render-timeout.ts +108 -0
- package/src/server/request-context.ts +168 -337
- package/src/server/route-element-builder.ts +435 -208
- package/src/server/route-handler.ts +24 -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 +16 -17
- package/src/server/rsc-entry/error-renderer.ts +315 -89
- package/src/server/rsc-entry/helpers.ts +155 -26
- package/src/server/rsc-entry/index.ts +316 -327
- package/src/server/rsc-entry/render-route.ts +313 -0
- package/src/server/rsc-entry/rsc-payload.ts +65 -18
- 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 +195 -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 +126 -0
- package/src/server/slot-resolver.ts +228 -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 +139 -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 +202 -90
- package/src/server/tree-match.ts +210 -0
- package/src/server/types.ts +55 -6
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/version-skew.ts +104 -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/dist/_chunks/als-registry-B7DbZ2hS.js +0 -41
- package/dist/_chunks/als-registry-B7DbZ2hS.js.map +0 -1
- package/dist/_chunks/debug-gwlJkDuf.js +0 -108
- package/dist/_chunks/debug-gwlJkDuf.js.map +0 -1
- package/dist/_chunks/format-DviM89f0.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-DIkVh_jG.js +0 -330
- package/dist/_chunks/request-context-DIkVh_jG.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
package/src/adapters/nitro.ts
CHANGED
|
@@ -5,28 +5,13 @@
|
|
|
5
5
|
// compression, graceful shutdown, static file serving, and platform quirks.
|
|
6
6
|
// See design/11-platform.md and design/25-production-deployments.md.
|
|
7
7
|
|
|
8
|
-
import { writeFile, readFile
|
|
8
|
+
import { writeFile, readFile } from 'node:fs/promises';
|
|
9
9
|
import { execFile } from 'node:child_process';
|
|
10
10
|
import { join, relative } from 'node:path';
|
|
11
11
|
import type { TimberPlatformAdapter, TimberConfig } from './types';
|
|
12
12
|
import { generateCompressModule } from './compress-module.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// directory .ts imports don't resolve.
|
|
16
|
-
const IMMUTABLE_CACHE = 'public, max-age=31536000, immutable';
|
|
17
|
-
const STATIC_CACHE = 'public, max-age=3600, must-revalidate';
|
|
18
|
-
|
|
19
|
-
function generateHeadersFile(): string {
|
|
20
|
-
return `# Auto-generated by @timber-js/app — static asset cache headers.
|
|
21
|
-
# See design/25-production-deployments.md §"CDN / Edge Cache"
|
|
22
|
-
|
|
23
|
-
/assets/*
|
|
24
|
-
Cache-Control: ${IMMUTABLE_CACHE}
|
|
25
|
-
|
|
26
|
-
/*
|
|
27
|
-
Cache-Control: ${STATIC_CACHE}
|
|
28
|
-
`;
|
|
29
|
-
}
|
|
13
|
+
import { IMMUTABLE_CACHE } from './shared.js';
|
|
14
|
+
import { runSharedBuildSteps } from './build-output-helper.js';
|
|
30
15
|
|
|
31
16
|
// ─── Presets ─────────────────────────────────────────────────────────────────
|
|
32
17
|
|
|
@@ -149,6 +134,23 @@ export interface NitroAdapterOptions {
|
|
|
149
134
|
*/
|
|
150
135
|
preset?: NitroPreset;
|
|
151
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Enable application-level gzip compression for HTML and RSC responses.
|
|
139
|
+
*
|
|
140
|
+
* When `true` (default), the origin compresses responses using the Web
|
|
141
|
+
* `CompressionStream` API. This is useful for self-hosted deployments
|
|
142
|
+
* where no reverse proxy or CDN handles compression.
|
|
143
|
+
*
|
|
144
|
+
* Set to `false` when deploying behind a reverse proxy (nginx, caddy)
|
|
145
|
+
* or CDN (Cloudflare, Fastly, Vercel) that compresses at the edge.
|
|
146
|
+
* Disabling origin compression saves CPU on the Node.js event loop —
|
|
147
|
+
* compressing 1MB+ streaming HTML responses takes 10-15ms of main
|
|
148
|
+
* thread time per request, directly reducing throughput under load.
|
|
149
|
+
*
|
|
150
|
+
* @default true
|
|
151
|
+
*/
|
|
152
|
+
compress?: boolean;
|
|
153
|
+
|
|
152
154
|
/**
|
|
153
155
|
* Additional Nitro configuration to merge into the generated config.
|
|
154
156
|
* Overrides default values for the selected preset.
|
|
@@ -176,6 +178,7 @@ export interface NitroAdapterOptions {
|
|
|
176
178
|
*/
|
|
177
179
|
export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter {
|
|
178
180
|
const preset = options.preset ?? 'node-server';
|
|
181
|
+
const compress = options.compress ?? true;
|
|
179
182
|
const presetConfig = PRESET_CONFIGS[preset];
|
|
180
183
|
const pendingPromises: Promise<unknown>[] = [];
|
|
181
184
|
|
|
@@ -184,40 +187,21 @@ export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter
|
|
|
184
187
|
|
|
185
188
|
async buildOutput(config: TimberConfig, buildDir: string) {
|
|
186
189
|
const outDir = join(buildDir, 'nitro');
|
|
187
|
-
await mkdir(outDir, { recursive: true });
|
|
188
|
-
|
|
189
|
-
// Copy client assets to public directory.
|
|
190
|
-
// When client JavaScript is disabled, skip .js files — only CSS,
|
|
191
|
-
// fonts, images, and other static assets are needed.
|
|
192
|
-
const clientDir = join(buildDir, 'client');
|
|
193
|
-
const publicDir = join(outDir, 'public');
|
|
194
|
-
await mkdir(publicDir, { recursive: true });
|
|
195
|
-
await cp(clientDir, publicDir, {
|
|
196
|
-
recursive: true,
|
|
197
|
-
filter: config.clientJavascriptDisabled ? (src: string) => !src.endsWith('.js') : undefined,
|
|
198
|
-
}).catch(() => {
|
|
199
|
-
// Client dir may not exist when client JavaScript is disabled
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// Write _headers file for platforms that support it (Netlify, etc.).
|
|
203
|
-
// See design/25-production-deployments.md §"CDN / Edge Cache"
|
|
204
|
-
await writeFile(join(publicDir, '_headers'), generateHeadersFile());
|
|
205
190
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
191
|
+
// Steps 1–5: shared across all adapters (mkdir, copy client/rsc/ssr,
|
|
192
|
+
// write _headers, write manifest-init).
|
|
193
|
+
await runSharedBuildSteps({
|
|
194
|
+
config,
|
|
195
|
+
buildDir,
|
|
196
|
+
outDir,
|
|
197
|
+
publicDirName: 'public',
|
|
198
|
+
});
|
|
210
199
|
|
|
211
200
|
// Write the compression helper module for runtime use.
|
|
212
201
|
// See design/25-production-deployments.md — self-hosted deployments
|
|
213
202
|
// need application-level compression (Cloudflare handles it at the edge).
|
|
214
203
|
await writeFile(join(outDir, '_compress.mjs'), generateCompressModule());
|
|
215
204
|
|
|
216
|
-
// Copy rsc/ssr build output into the nitro dir so imports stay local
|
|
217
|
-
// during the Nitro bundling step (avoids broken relative paths in output).
|
|
218
|
-
await cp(join(buildDir, 'rsc'), join(outDir, 'rsc'), { recursive: true });
|
|
219
|
-
await cp(join(buildDir, 'ssr'), join(outDir, 'ssr'), { recursive: true }).catch(() => {});
|
|
220
|
-
|
|
221
205
|
// Prepend the manifest assignment directly into the RSC entry so
|
|
222
206
|
// globalThis.__TIMBER_BUILD_MANIFEST__ is set before any module reads it.
|
|
223
207
|
// This must be top-level code, not an import, because rollup tree-shakes
|
|
@@ -229,7 +213,7 @@ export function nitro(options: NitroAdapterOptions = {}): TimberPlatformAdapter
|
|
|
229
213
|
}
|
|
230
214
|
|
|
231
215
|
// Generate the Nitro entry point (imports from ./rsc/ within nitro dir)
|
|
232
|
-
const entry = generateNitroEntry(buildDir, outDir, preset);
|
|
216
|
+
const entry = generateNitroEntry(buildDir, outDir, preset, compress);
|
|
233
217
|
await writeFile(join(outDir, 'entry.ts'), entry);
|
|
234
218
|
|
|
235
219
|
// Run the Nitro build to produce a production-ready server bundle.
|
|
@@ -273,6 +257,7 @@ export function generateNitroEntry(
|
|
|
273
257
|
buildDir: string,
|
|
274
258
|
outDir: string,
|
|
275
259
|
preset: NitroPreset,
|
|
260
|
+
compress = true,
|
|
276
261
|
hasManifestInit = false
|
|
277
262
|
): string {
|
|
278
263
|
// The RSC entry is the main request handler — it exports the fetch handler as default.
|
|
@@ -338,12 +323,14 @@ export function generateNitroEntry(
|
|
|
338
323
|
// Import runWithWaitUntil only when the preset supports it.
|
|
339
324
|
const waitUntilImport = supportsWaitUntil ? ', runWithWaitUntil' : '';
|
|
340
325
|
|
|
326
|
+
const compressImport = compress ? "import { compressResponse } from './_compress.mjs'\n" : '';
|
|
327
|
+
const compressCall = compress ? 'compressResponse(webRequest, webResponse)' : 'webResponse';
|
|
328
|
+
|
|
341
329
|
return `// Generated by @timber-js/app/adapters/nitro
|
|
342
330
|
// Do not edit — this file is regenerated on each build.
|
|
343
331
|
|
|
344
332
|
${manifestImport}import handler, { runWithEarlyHintsSender${waitUntilImport} } from '${serverEntryRelative}'
|
|
345
|
-
|
|
346
|
-
|
|
333
|
+
${compressImport}
|
|
347
334
|
// Set TIMBER_RUNTIME for instrumentation.ts conditional SDK initialization.
|
|
348
335
|
// See design/25-production-deployments.md §"TIMBER_RUNTIME".
|
|
349
336
|
process.env.TIMBER_RUNTIME = '${runtimeName}'
|
|
@@ -357,7 +344,7 @@ export default async function timberHandler(event) {
|
|
|
357
344
|
// h3 v2: event.req is the Web Request
|
|
358
345
|
const webRequest = event.req
|
|
359
346
|
${handlerCall}
|
|
360
|
-
return
|
|
347
|
+
return ${compressCall}
|
|
361
348
|
}
|
|
362
349
|
`;
|
|
363
350
|
}
|
|
@@ -465,11 +452,25 @@ const MIME_TYPES = {
|
|
|
465
452
|
};
|
|
466
453
|
|
|
467
454
|
const publicDir = join(__dirname, '${publicDir}');
|
|
468
|
-
|
|
455
|
+
|
|
456
|
+
// Port resolution (TIM-842):
|
|
457
|
+
// - Default to 3000
|
|
458
|
+
// - If PORT env var is set, honor it strictly (fail loudly on conflict)
|
|
459
|
+
// - Otherwise auto-bump from 3000 until a free port is found
|
|
460
|
+
// Mirrors the dev server behavior so timber dev/preview/production all
|
|
461
|
+
// behave the same way around port selection.
|
|
462
|
+
const envPort = process.env.PORT ? parseInt(process.env.PORT, 10) : null;
|
|
463
|
+
const portIsExplicit = envPort != null && Number.isFinite(envPort) && envPort > 0;
|
|
464
|
+
const startPort = portIsExplicit ? envPort : 3000;
|
|
469
465
|
const host = process.env.HOST || process.env.HOSTNAME || 'localhost';
|
|
470
466
|
|
|
467
|
+
// Set after listenWithBump() resolves so request handlers can build
|
|
468
|
+
// absolute URLs from the actual bound port (which may differ from
|
|
469
|
+
// startPort after an auto-bump).
|
|
470
|
+
let boundPort = startPort;
|
|
471
|
+
|
|
471
472
|
const server = createServer(async (req, res) => {
|
|
472
|
-
const url = new URL(req.url || '/', \`http://\${host}:\${
|
|
473
|
+
const url = new URL(req.url || '/', \`http://\${host}:\${boundPort}\`);
|
|
473
474
|
|
|
474
475
|
// Try serving static files from the public directory first.
|
|
475
476
|
const filePath = join(publicDir, url.pathname);
|
|
@@ -540,18 +541,64 @@ const server = createServer(async (req, res) => {
|
|
|
540
541
|
const webResponse = compressResponse(webRequest, rawResponse);
|
|
541
542
|
|
|
542
543
|
// Write the response back to the Node response.
|
|
543
|
-
|
|
544
|
+
//
|
|
545
|
+
// Set-Cookie needs special handling: Headers.entries() joins multiple
|
|
546
|
+
// Set-Cookie values with ", " into a single entry, but each cookie must
|
|
547
|
+
// be its own header per RFC 6265 §4.1. Object.fromEntries() would then
|
|
548
|
+
// collapse them into one malformed Set-Cookie header that browsers reject
|
|
549
|
+
// (or only honor partially). Use getSetCookie() to preserve individual
|
|
550
|
+
// values, and pass them as an array — Node's writeHead accepts
|
|
551
|
+
// Record<string, string | string[]> and emits one header per array entry.
|
|
552
|
+
//
|
|
553
|
+
// Without this, EVERY cookie set by the framework on Node—/Nitro deployments
|
|
554
|
+
// is silently dropped: defineCookie().setCookie() in actions, middleware
|
|
555
|
+
// cookie writes, the framework's own session cookies, all of it. See
|
|
556
|
+
// LOCAL-741.
|
|
557
|
+
const responseHeaders: Record<string, string | string[]> = {};
|
|
558
|
+
webResponse.headers.forEach((value, key) => {
|
|
559
|
+
if (key.toLowerCase() !== 'set-cookie') {
|
|
560
|
+
responseHeaders[key] = value;
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
const setCookies = webResponse.headers.getSetCookie();
|
|
564
|
+
if (setCookies.length > 0) {
|
|
565
|
+
responseHeaders['set-cookie'] = setCookies;
|
|
566
|
+
}
|
|
567
|
+
res.writeHead(webResponse.status, responseHeaders);
|
|
544
568
|
|
|
545
569
|
if (webResponse.body) {
|
|
546
570
|
const reader = webResponse.body.getReader();
|
|
547
|
-
|
|
571
|
+
|
|
572
|
+
// Cancel the reader when the client disconnects. This causes any
|
|
573
|
+
// pending reader.read() to reject, breaking the pump loop. Critical
|
|
574
|
+
// for SSE and other infinite streams — without this, disconnected
|
|
575
|
+
// clients leak readers.
|
|
576
|
+
let clientDisconnected = false;
|
|
577
|
+
const onClose = () => {
|
|
578
|
+
clientDisconnected = true;
|
|
579
|
+
reader.cancel('Client disconnected').catch(() => {});
|
|
580
|
+
};
|
|
581
|
+
res.on('close', onClose);
|
|
582
|
+
|
|
583
|
+
try {
|
|
548
584
|
while (true) {
|
|
549
585
|
const { done, value } = await reader.read();
|
|
550
|
-
if (done)
|
|
586
|
+
if (done) break;
|
|
551
587
|
res.write(value);
|
|
552
588
|
}
|
|
553
|
-
}
|
|
554
|
-
|
|
589
|
+
} catch (err) {
|
|
590
|
+
// reader.cancel() from the close handler causes read() to reject.
|
|
591
|
+
// This is expected on client disconnect — not an error.
|
|
592
|
+
if (!clientDisconnected) {
|
|
593
|
+
throw err;
|
|
594
|
+
}
|
|
595
|
+
} finally {
|
|
596
|
+
res.off('close', onClose);
|
|
597
|
+
reader.releaseLock();
|
|
598
|
+
if (!res.writableEnded) {
|
|
599
|
+
res.end();
|
|
600
|
+
}
|
|
601
|
+
}
|
|
555
602
|
} else {
|
|
556
603
|
res.end();
|
|
557
604
|
}
|
|
@@ -564,13 +611,49 @@ const server = createServer(async (req, res) => {
|
|
|
564
611
|
}
|
|
565
612
|
});
|
|
566
613
|
|
|
567
|
-
|
|
614
|
+
function listenWithBump(port, attempt = 0) {
|
|
615
|
+
return new Promise((resolveListen, rejectListen) => {
|
|
616
|
+
const onError = (err) => {
|
|
617
|
+
server.removeListener('listening', onListening);
|
|
618
|
+
if (err && err.code === 'EADDRINUSE' && !portIsExplicit && attempt < 100) {
|
|
619
|
+
if (attempt === 0) {
|
|
620
|
+
console.log(\` [timber] Port \${port} in use, trying \${port + 1}...\`);
|
|
621
|
+
}
|
|
622
|
+
listenWithBump(port + 1, attempt + 1).then(resolveListen, rejectListen);
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
rejectListen(err);
|
|
626
|
+
};
|
|
627
|
+
const onListening = () => {
|
|
628
|
+
server.removeListener('error', onError);
|
|
629
|
+
resolveListen(port);
|
|
630
|
+
};
|
|
631
|
+
server.once('error', onError);
|
|
632
|
+
server.once('listening', onListening);
|
|
633
|
+
server.listen(port, host);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
try {
|
|
638
|
+
boundPort = await listenWithBump(startPort);
|
|
639
|
+
if (boundPort !== startPort) {
|
|
640
|
+
console.log();
|
|
641
|
+
console.log(\` [timber] Port \${startPort} in use, using \${boundPort}\`);
|
|
642
|
+
}
|
|
568
643
|
console.log();
|
|
569
644
|
console.log(' ⚡ timber preview server running at:');
|
|
570
645
|
console.log();
|
|
571
|
-
console.log(\` ➜ http://\${host}:\${
|
|
646
|
+
console.log(\` ➜ http://\${host}:\${boundPort}\`);
|
|
572
647
|
console.log();
|
|
573
|
-
})
|
|
648
|
+
} catch (err) {
|
|
649
|
+
if (err && err.code === 'EADDRINUSE') {
|
|
650
|
+
console.error(\`[timber] Port \${startPort} is already in use. \` +
|
|
651
|
+
'Set PORT to a free port, or unset PORT to auto-pick.');
|
|
652
|
+
} else {
|
|
653
|
+
console.error('[timber] Failed to start preview server:', err);
|
|
654
|
+
}
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
574
657
|
`;
|
|
575
658
|
}
|
|
576
659
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Shared adapter utilities — leaf module with zero deps on server/, client/,
|
|
2
|
+
// or any Vite-dependent code.
|
|
3
|
+
//
|
|
4
|
+
// Adapters are loaded by Node at Vite startup time, before Vite's module
|
|
5
|
+
// resolver is available. This module uses only Node built-ins and can be
|
|
6
|
+
// imported by both adapters via a relative path.
|
|
7
|
+
//
|
|
8
|
+
// IMPORTANT: Do NOT add imports from ../server/, ../client/, ../plugins/,
|
|
9
|
+
// or any module that transitively depends on Vite. A test in
|
|
10
|
+
// tests/adapters/shared-no-forbidden-imports.test.ts enforces this.
|
|
11
|
+
|
|
12
|
+
// ─── Static asset cache headers ──────────────────────────────────────────
|
|
13
|
+
|
|
14
|
+
/** Cache-Control value for hashed (immutable) assets. */
|
|
15
|
+
export const IMMUTABLE_CACHE = 'public, max-age=31536000, immutable';
|
|
16
|
+
|
|
17
|
+
/** Cache-Control value for unhashed static assets. */
|
|
18
|
+
export const STATIC_CACHE = 'public, max-age=3600, must-revalidate';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generate a `_headers` file for static asset cache control.
|
|
22
|
+
*
|
|
23
|
+
* The `_headers` file is a platform convention supported by Cloudflare Workers
|
|
24
|
+
* Static Assets, Cloudflare Pages, and Netlify. It maps URL patterns to
|
|
25
|
+
* HTTP response headers.
|
|
26
|
+
*
|
|
27
|
+
* Vite places all hashed chunks under `/assets/` — these get immutable caching.
|
|
28
|
+
* Everything else (favicon.ico, robots.txt, etc.) gets a shorter cache.
|
|
29
|
+
*/
|
|
30
|
+
export function generateHeadersFile(): string {
|
|
31
|
+
return `# Auto-generated by @timber-js/app — static asset cache headers.
|
|
32
|
+
# See design/25-production-deployments.md §"CDN / Edge Cache"
|
|
33
|
+
|
|
34
|
+
/assets/*
|
|
35
|
+
Cache-Control: ${IMMUTABLE_CACHE}
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
Cache-Control: ${STATIC_CACHE}
|
|
39
|
+
`;
|
|
40
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CacheOptions } from './index';
|
|
2
|
+
import { createCache } from './timber-cache';
|
|
3
|
+
import { getCacheHandler } from './handler-store';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Public caching API: `cache(fn, opts)`.
|
|
7
|
+
*
|
|
8
|
+
* Wraps an async function with cross-request caching. Uses the configured
|
|
9
|
+
* cache handler (defaults to MemoryCacheHandler, overridable via timber.config.ts).
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { cache } from '@timber-js/app/cache';
|
|
13
|
+
*
|
|
14
|
+
* const getUser = cache(
|
|
15
|
+
* async (id: string) => db.users.findUnique({ where: { id } }),
|
|
16
|
+
* { ttl: 60, tags: (id) => [`user:${id}`] }
|
|
17
|
+
* );
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
export function cache<Fn extends (...args: any[]) => Promise<any>>(
|
|
22
|
+
fn: Fn,
|
|
23
|
+
opts: CacheOptions<Fn>
|
|
24
|
+
): Fn {
|
|
25
|
+
return createCache(fn, opts, getCacheHandler());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Invalidate cache entries by tag or key.
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* cache.invalidate({ tag: 'products' });
|
|
33
|
+
* cache.invalidate({ key: 'user:abc' });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
cache.invalidate = async function invalidate(opts: { key?: string; tag?: string }): Promise<void> {
|
|
37
|
+
await getCacheHandler().invalidate(opts);
|
|
38
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-level cache handler singleton.
|
|
3
|
+
*
|
|
4
|
+
* Lazily initialized to MemoryCacheHandler on first access. The framework
|
|
5
|
+
* replaces this at boot from timber.config.ts via setCacheHandler().
|
|
6
|
+
*
|
|
7
|
+
* This module avoids importing from ./index to prevent circular dependencies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Inline the interface to avoid circular import with index.ts
|
|
11
|
+
interface CacheHandlerLike {
|
|
12
|
+
get(key: string): Promise<{ value: unknown; stale: boolean } | null>;
|
|
13
|
+
set(key: string, value: unknown, opts: { ttl: number; tags: string[] }): Promise<void>;
|
|
14
|
+
invalidate(opts: { key?: string; tag?: string }): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let handler: CacheHandlerLike | null = null;
|
|
18
|
+
|
|
19
|
+
/** Replace the active cache handler. Called by the framework at boot. */
|
|
20
|
+
export function setCacheHandler(h: CacheHandlerLike): void {
|
|
21
|
+
handler = h;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get the active cache handler. Creates a default MemoryCacheHandler on
|
|
26
|
+
* first access if none has been set via setCacheHandler().
|
|
27
|
+
*/
|
|
28
|
+
export function getCacheHandler(): CacheHandlerLike {
|
|
29
|
+
if (!handler) {
|
|
30
|
+
// Inline a minimal LRU cache to avoid circular dep with index.ts.
|
|
31
|
+
// In production, the framework always calls setCacheHandler() at boot.
|
|
32
|
+
handler = createDefaultHandler();
|
|
33
|
+
}
|
|
34
|
+
return handler;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function createDefaultHandler(): CacheHandlerLike {
|
|
38
|
+
const store = new Map<string, { value: unknown; expiresAt: number; tags: string[] }>();
|
|
39
|
+
const maxEntries = 1000;
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
async get(key) {
|
|
43
|
+
const entry = store.get(key);
|
|
44
|
+
if (!entry) return null;
|
|
45
|
+
store.delete(key);
|
|
46
|
+
store.set(key, entry);
|
|
47
|
+
const stale = Date.now() > entry.expiresAt;
|
|
48
|
+
return { value: entry.value, stale };
|
|
49
|
+
},
|
|
50
|
+
async set(key, value, opts) {
|
|
51
|
+
if (store.has(key)) store.delete(key);
|
|
52
|
+
while (store.size >= maxEntries) {
|
|
53
|
+
const oldest = store.keys().next().value;
|
|
54
|
+
if (oldest !== undefined) store.delete(oldest);
|
|
55
|
+
else break;
|
|
56
|
+
}
|
|
57
|
+
store.set(key, { value, expiresAt: Date.now() + opts.ttl * 1000, tags: opts.tags });
|
|
58
|
+
},
|
|
59
|
+
async invalidate(opts) {
|
|
60
|
+
if (opts.key) store.delete(opts.key);
|
|
61
|
+
if (opts.tag) {
|
|
62
|
+
for (const [key, entry] of store) {
|
|
63
|
+
if (entry.tags.includes(opts.tag)) store.delete(key);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
package/src/cache/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// @timber-js/app/cache — Caching primitives
|
|
2
2
|
|
|
3
|
+
import { estimateByteSize } from './sizeof.js';
|
|
4
|
+
|
|
3
5
|
export interface CacheHandler {
|
|
4
6
|
get(key: string): Promise<{ value: unknown; stale: boolean } | null>;
|
|
5
7
|
set(key: string, value: unknown, opts: { ttl: number; tags: string[] }): Promise<void>;
|
|
@@ -12,19 +14,40 @@ export interface CacheOptions<Fn extends (...args: any[]) => any> {
|
|
|
12
14
|
key?: (...args: Parameters<Fn>) => string;
|
|
13
15
|
staleWhileRevalidate?: boolean;
|
|
14
16
|
tags?: string[] | ((...args: Parameters<Fn>) => string[]);
|
|
17
|
+
/** Timeout (ms) for singleflight-coalesced calls. Prevents hung fn() from
|
|
18
|
+
* permanently blocking all future callers for the same cache key. See TIM-518. */
|
|
19
|
+
timeoutMs?: number;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
export interface MemoryCacheHandlerOptions {
|
|
18
23
|
/** Maximum number of entries. Oldest accessed entries are evicted first. Default: 1000. */
|
|
24
|
+
maxEntries?: number;
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Use `maxEntries` instead. Will be removed in a future release.
|
|
27
|
+
* Alias for `maxEntries` — maximum number of entries (not bytes).
|
|
28
|
+
*/
|
|
19
29
|
maxSize?: number;
|
|
30
|
+
/** Maximum total byte budget for all cached values. Oldest entries are evicted when exceeded. Default: no limit. */
|
|
31
|
+
maxBytes?: number;
|
|
32
|
+
/** Maximum byte size for a single cache entry. Entries exceeding this are silently dropped. Default: no limit. */
|
|
33
|
+
maxEntryBytes?: number;
|
|
20
34
|
}
|
|
21
35
|
|
|
22
36
|
export class MemoryCacheHandler implements CacheHandler {
|
|
23
|
-
private store = new Map<
|
|
24
|
-
|
|
37
|
+
private store = new Map<
|
|
38
|
+
string,
|
|
39
|
+
{ value: unknown; expiresAt: number; tags: string[]; byteSize: number }
|
|
40
|
+
>();
|
|
41
|
+
private maxEntries: number;
|
|
42
|
+
private maxBytes: number | undefined;
|
|
43
|
+
private maxEntryBytes: number | undefined;
|
|
44
|
+
private currentBytes = 0;
|
|
25
45
|
|
|
26
46
|
constructor(opts?: MemoryCacheHandlerOptions) {
|
|
27
|
-
|
|
47
|
+
// maxEntries takes precedence over deprecated maxSize
|
|
48
|
+
this.maxEntries = opts?.maxEntries ?? opts?.maxSize ?? 1000;
|
|
49
|
+
this.maxBytes = opts?.maxBytes;
|
|
50
|
+
this.maxEntryBytes = opts?.maxEntryBytes;
|
|
28
51
|
}
|
|
29
52
|
|
|
30
53
|
async get(key: string) {
|
|
@@ -40,18 +63,33 @@ export class MemoryCacheHandler implements CacheHandler {
|
|
|
40
63
|
}
|
|
41
64
|
|
|
42
65
|
async set(key: string, value: unknown, opts: { ttl: number; tags: string[] }) {
|
|
43
|
-
|
|
66
|
+
const byteSize = estimateByteSize(value);
|
|
67
|
+
|
|
68
|
+
// Reject entries exceeding per-entry byte limit
|
|
69
|
+
if (this.maxEntryBytes !== undefined && byteSize > this.maxEntryBytes) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// If key already exists, delete first to refresh insertion order and reclaim bytes
|
|
44
74
|
if (this.store.has(key)) {
|
|
75
|
+
const existing = this.store.get(key)!;
|
|
76
|
+
this.currentBytes -= existing.byteSize;
|
|
45
77
|
this.store.delete(key);
|
|
46
78
|
}
|
|
47
79
|
|
|
48
|
-
// Evict oldest entries (front of Map) if at capacity
|
|
49
|
-
while (this.store.size >= this.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
80
|
+
// Evict oldest entries (front of Map) if at entry count capacity
|
|
81
|
+
while (this.store.size >= this.maxEntries) {
|
|
82
|
+
this.evictOldest();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Evict oldest entries if byte budget would be exceeded
|
|
86
|
+
if (this.maxBytes !== undefined) {
|
|
87
|
+
while (this.currentBytes + byteSize > this.maxBytes && this.store.size > 0) {
|
|
88
|
+
this.evictOldest();
|
|
89
|
+
}
|
|
90
|
+
// If the single entry exceeds the total byte budget, don't store it
|
|
91
|
+
if (this.currentBytes + byteSize > this.maxBytes) {
|
|
92
|
+
return;
|
|
55
93
|
}
|
|
56
94
|
}
|
|
57
95
|
|
|
@@ -59,16 +97,23 @@ export class MemoryCacheHandler implements CacheHandler {
|
|
|
59
97
|
value,
|
|
60
98
|
expiresAt: Date.now() + opts.ttl * 1000,
|
|
61
99
|
tags: opts.tags,
|
|
100
|
+
byteSize,
|
|
62
101
|
});
|
|
102
|
+
this.currentBytes += byteSize;
|
|
63
103
|
}
|
|
64
104
|
|
|
65
105
|
async invalidate(opts: { key?: string; tag?: string }) {
|
|
66
106
|
if (opts.key) {
|
|
67
|
-
this.store.
|
|
107
|
+
const entry = this.store.get(opts.key);
|
|
108
|
+
if (entry) {
|
|
109
|
+
this.currentBytes -= entry.byteSize;
|
|
110
|
+
this.store.delete(opts.key);
|
|
111
|
+
}
|
|
68
112
|
}
|
|
69
113
|
if (opts.tag) {
|
|
70
114
|
for (const [key, entry] of this.store) {
|
|
71
115
|
if (entry.tags.includes(opts.tag)) {
|
|
116
|
+
this.currentBytes -= entry.byteSize;
|
|
72
117
|
this.store.delete(key);
|
|
73
118
|
}
|
|
74
119
|
}
|
|
@@ -79,13 +124,31 @@ export class MemoryCacheHandler implements CacheHandler {
|
|
|
79
124
|
get size(): number {
|
|
80
125
|
return this.store.size;
|
|
81
126
|
}
|
|
127
|
+
|
|
128
|
+
/** Estimated total byte size of all cached values. */
|
|
129
|
+
get bytes(): number {
|
|
130
|
+
return this.currentBytes;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Evict the oldest entry (front of Map). */
|
|
134
|
+
private evictOldest(): void {
|
|
135
|
+
const oldest = this.store.keys().next().value;
|
|
136
|
+
if (oldest !== undefined) {
|
|
137
|
+
const entry = this.store.get(oldest)!;
|
|
138
|
+
this.currentBytes -= entry.byteSize;
|
|
139
|
+
this.store.delete(oldest);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
82
142
|
}
|
|
83
143
|
|
|
84
144
|
export { RedisCacheHandler } from './redis-handler';
|
|
85
145
|
export type { RedisClient } from './redis-handler';
|
|
86
|
-
export {
|
|
87
|
-
export {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
export {
|
|
91
|
-
|
|
146
|
+
export { cache } from './cache-api';
|
|
147
|
+
export { setCacheHandler, getCacheHandler } from './handler-store';
|
|
148
|
+
// NOTE: registerCachedFunction (runtime for 'use cache' directive) removed.
|
|
149
|
+
// Future feature pending design doc. See design/06-caching.md.
|
|
150
|
+
export { estimateByteSize } from './sizeof';
|
|
151
|
+
// stableStringify, createSingleflight, and SingleflightTimeoutError are
|
|
152
|
+
// internal utilities used by the cache implementation. They are not
|
|
153
|
+
// re-exported here — import directly from the source files if needed
|
|
154
|
+
// within the package. See TIM-720.
|