@timber-js/app 0.2.0-alpha.19 → 0.2.0-alpha.190
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/agent-skill.md +344 -0
- package/dist/_chunks/actions-35jnMdeJ.js +318 -0
- package/dist/_chunks/actions-35jnMdeJ.js.map +1 -0
- package/dist/_chunks/als-registry-C6kcfprT.js +41 -0
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js +26 -0
- package/dist/_chunks/als-slots-BEEIPKYm.js.map +1 -0
- package/dist/_chunks/base-path-DaQrzbez.js +80 -0
- package/dist/_chunks/base-path-DaQrzbez.js.map +1 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js +86 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +1 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js +369 -0
- package/dist/_chunks/build-output-helper-C3DrfzZR.js.map +1 -0
- package/dist/_chunks/cache-api-DjNrIWRR.js +1196 -0
- package/dist/_chunks/cache-api-DjNrIWRR.js.map +1 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js +256 -0
- package/dist/_chunks/cli-check-CpmN7Nh-.js.map +1 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js +298 -0
- package/dist/_chunks/cli-schema-sync-CGMp_Psg.js.map +1 -0
- package/dist/_chunks/cloudflare-CGP6BZKO.js +1284 -0
- package/dist/_chunks/cloudflare-CGP6BZKO.js.map +1 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js +21 -0
- package/dist/_chunks/codec-registry-oOUxugz3.js.map +1 -0
- package/dist/_chunks/convention-lint-kXsgc_-7.js +784 -0
- package/dist/_chunks/convention-lint-kXsgc_-7.js.map +1 -0
- package/dist/_chunks/dist-BA3u1z3W.js +423 -0
- package/dist/_chunks/dist-BA3u1z3W.js.map +1 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js +353 -0
- package/dist/_chunks/error-boundary-D-ODYX41.js.map +1 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js +41 -0
- package/dist/_chunks/fast-hash-C-tVYrLb.js.map +1 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js +454 -0
- package/dist/_chunks/file-cache-DmX7OqZP.js.map +1 -0
- package/dist/_chunks/format-CfwjgPz9.js +14 -0
- package/dist/_chunks/format-CfwjgPz9.js.map +1 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js +208 -0
- package/dist/_chunks/fs-identity-D7vb6GdI.js.map +1 -0
- package/dist/_chunks/href-validation-CMc5JRls.js +141 -0
- package/dist/_chunks/href-validation-CMc5JRls.js.map +1 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js +63 -0
- package/dist/_chunks/json-lossy-check-ClNvBM_3.js.map +1 -0
- package/dist/_chunks/logger-D8xJZXIN.js +1451 -0
- package/dist/_chunks/logger-D8xJZXIN.js.map +1 -0
- package/dist/_chunks/mdx-file-C005ay-P.js +25 -0
- package/dist/_chunks/mdx-file-C005ay-P.js.map +1 -0
- package/dist/_chunks/plugin-context-rCinWLiE.js +321 -0
- package/dist/_chunks/plugin-context-rCinWLiE.js.map +1 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js +14 -0
- package/dist/_chunks/purge-store-Byr8XOjU.js.map +1 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js +50 -0
- package/dist/_chunks/resolve-schema-CBR6Lm4i.js.map +1 -0
- package/dist/_chunks/router-ref-DuYuV_0Q.js +28 -0
- package/dist/_chunks/router-ref-DuYuV_0Q.js.map +1 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js +243 -0
- package/dist/_chunks/rsc-cache-key-DD0fl_-s.js.map +1 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js +40 -0
- package/dist/_chunks/rsc-error-envelope-tT5PJs4q.js.map +1 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js +46 -0
- package/dist/_chunks/rsc-media-type-DRqE_lD_.js.map +1 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js +48 -0
- package/dist/_chunks/rsc-payload-path-B_LBodc2.js.map +1 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js +1564 -0
- package/dist/_chunks/scanner-C8b0Gcw3.js.map +1 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js +199 -0
- package/dist/_chunks/schema-bridge-C83xa9lT.js.map +1 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js +197 -0
- package/dist/_chunks/segment-classify-C539Pa2O.js.map +1 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js +97 -0
- package/dist/_chunks/segment-context-CjOlyB8Y.js.map +1 -0
- package/dist/_chunks/segment-keys-BawYuNFO.js +307 -0
- package/dist/_chunks/segment-keys-BawYuNFO.js.map +1 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js +35 -0
- package/dist/_chunks/sizeof-lXffQ1Vr.js.map +1 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js +76 -0
- package/dist/_chunks/slot-params-BCTmZkQB.js.map +1 -0
- package/dist/_chunks/{ssr-data-MjmprTmO.js → ssr-data-14MXm7Pj.js} +17 -2
- package/dist/_chunks/ssr-data-14MXm7Pj.js.map +1 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js +226 -0
- package/dist/_chunks/use-query-states-I3JMng6J.js.map +1 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js +398 -0
- package/dist/_chunks/use-segment-params-C4r4BD9T.js.map +1 -0
- package/dist/_chunks/walkers-RzN6AFjr.js +141 -0
- package/dist/_chunks/walkers-RzN6AFjr.js.map +1 -0
- package/dist/adapters/build-output-helper.d.ts +72 -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 +65 -0
- package/dist/adapters/cloudflare-kv-cache.d.ts.map +1 -0
- package/dist/adapters/cloudflare-kv-cache.js +124 -0
- package/dist/adapters/cloudflare-kv-cache.js.map +1 -0
- package/dist/adapters/cloudflare.d.ts +199 -21
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +2 -188
- package/dist/adapters/compress-module.d.ts +17 -4
- package/dist/adapters/compress-module.d.ts.map +1 -1
- package/dist/adapters/fs-identity.d.ts +64 -0
- package/dist/adapters/fs-identity.d.ts.map +1 -0
- package/dist/adapters/nitro.d.ts +55 -3
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js +287 -171
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/adapters/shared.d.ts +62 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/types.d.ts +28 -6
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/cache/cache-api.d.ts +48 -0
- package/dist/cache/cache-api.d.ts.map +1 -0
- package/dist/cache/fast-hash.d.ts +5 -0
- package/dist/cache/fast-hash.d.ts.map +1 -1
- package/dist/cache/handler-store.d.ts +33 -0
- package/dist/cache/handler-store.d.ts.map +1 -0
- package/dist/cache/index.d.ts +31 -8
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +3 -326
- package/dist/cache/invalidation-epoch.d.ts +43 -0
- package/dist/cache/invalidation-epoch.d.ts.map +1 -0
- package/dist/cache/json-lossy-check.d.ts +11 -0
- package/dist/cache/json-lossy-check.d.ts.map +1 -0
- package/dist/cache/redis-handler.d.ts +140 -8
- package/dist/cache/redis-handler.d.ts.map +1 -1
- package/dist/cache/singleflight.d.ts +19 -2
- 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/stable-stringify.d.ts +9 -0
- package/dist/cache/stable-stringify.d.ts.map +1 -1
- package/dist/cache/store.d.ts +53 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.d.ts +38 -0
- package/dist/cache/stores/cloudflare-kv.d.ts.map +1 -0
- package/dist/cache/stores/cloudflare-kv.js +29 -0
- package/dist/cache/stores/cloudflare-kv.js.map +1 -0
- package/dist/cache/stores/memory.d.ts +42 -0
- package/dist/cache/stores/memory.d.ts.map +1 -0
- package/dist/cache/stores/memory.js +90 -0
- package/dist/cache/stores/memory.js.map +1 -0
- package/dist/cache/stores/redis.d.ts +69 -0
- package/dist/cache/stores/redis.d.ts.map +1 -0
- package/dist/cache/stores/redis.js +35 -0
- package/dist/cache/stores/redis.js.map +1 -0
- package/dist/cache/stores/vercel.d.ts +36 -0
- package/dist/cache/stores/vercel.d.ts.map +1 -0
- package/dist/cache/stores/vercel.js +33 -0
- package/dist/cache/stores/vercel.js.map +1 -0
- package/dist/cache/tag-aware-handler.d.ts +52 -0
- package/dist/cache/tag-aware-handler.d.ts.map +1 -0
- package/dist/cache/timber-cache.d.ts +20 -10
- package/dist/cache/timber-cache.d.ts.map +1 -1
- package/dist/cdn/cloudflare-purge.d.ts +23 -0
- package/dist/cdn/cloudflare-purge.d.ts.map +1 -0
- package/dist/cdn/cloudflare-purge.js +30 -0
- package/dist/cdn/cloudflare-purge.js.map +1 -0
- package/dist/cdn/fastly-purge.d.ts +25 -0
- package/dist/cdn/fastly-purge.d.ts.map +1 -0
- package/dist/cdn/fastly-purge.js +33 -0
- package/dist/cdn/fastly-purge.js.map +1 -0
- package/dist/cdn/headers.d.ts +97 -0
- package/dist/cdn/headers.d.ts.map +1 -0
- package/dist/cdn/index.d.ts +5 -0
- package/dist/cdn/index.d.ts.map +1 -0
- package/dist/cdn/index.js +94 -0
- package/dist/cdn/index.js.map +1 -0
- package/dist/cdn/purge-store.d.ts +23 -0
- package/dist/cdn/purge-store.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.d.ts +16 -0
- package/dist/cdn/workers-cache-purge.d.ts.map +1 -0
- package/dist/cdn/workers-cache-purge.js +35 -0
- package/dist/cdn/workers-cache-purge.js.map +1 -0
- package/dist/cli-check.d.ts +153 -0
- package/dist/cli-check.d.ts.map +1 -0
- package/dist/cli-schema-sync.d.ts +59 -0
- package/dist/cli-schema-sync.d.ts.map +1 -0
- package/dist/cli.d.ts +66 -7
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +151 -47
- package/dist/cli.js.map +1 -1
- package/dist/client/browser-dev.d.ts +37 -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 +57 -0
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -0
- package/dist/client/browser-entry/index.d.ts +29 -0
- package/dist/client/browser-entry/index.d.ts.map +1 -0
- package/dist/client/browser-entry/post-hydration.d.ts +29 -0
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -0
- package/dist/client/browser-entry/router-init.d.ts +30 -0
- package/dist/client/browser-entry/router-init.d.ts.map +1 -0
- package/dist/client/browser-entry/rsc-stream.d.ts +32 -0
- package/dist/client/browser-entry/rsc-stream.d.ts.map +1 -0
- package/dist/client/browser-entry/scroll.d.ts +28 -0
- package/dist/client/browser-entry/scroll.d.ts.map +1 -0
- package/dist/client/error-boundary.d.ts +19 -5
- package/dist/client/error-boundary.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -125
- package/dist/client/error-reconstituter.d.ts +61 -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 +29 -7
- package/dist/client/history.d.ts.map +1 -1
- package/dist/client/index.d.ts +11 -24
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +186 -1134
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +20 -0
- package/dist/client/internal.d.ts.map +1 -0
- package/dist/client/internal.js +1624 -0
- package/dist/client/internal.js.map +1 -0
- package/dist/client/link.d.ts +63 -60
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/navigation-api.d.ts +121 -0
- package/dist/client/navigation-api.d.ts.map +1 -0
- package/dist/client/navigation-commit.d.ts +87 -0
- package/dist/client/navigation-commit.d.ts.map +1 -0
- package/dist/client/navigation-context.d.ts +38 -20
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +159 -0
- package/dist/client/navigation-root.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts +1 -1
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +81 -0
- package/dist/client/params-context.d.ts.map +1 -0
- package/dist/client/router-effects.d.ts +129 -0
- package/dist/client/router-effects.d.ts.map +1 -0
- package/dist/client/router-lifecycle.d.ts +55 -0
- package/dist/client/router-lifecycle.d.ts.map +1 -0
- package/dist/client/router-pipeline.d.ts +84 -0
- package/dist/client/router-pipeline.d.ts.map +1 -0
- package/dist/client/router-ref.d.ts +2 -2
- package/dist/client/router-ref.d.ts.map +1 -1
- package/dist/client/router-skew.d.ts +21 -0
- package/dist/client/router-skew.d.ts.map +1 -0
- package/dist/client/router-types.d.ts +207 -0
- package/dist/client/router-types.d.ts.map +1 -0
- package/dist/client/router.d.ts +1 -97
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/rsc-fetch.d.ts +113 -26
- package/dist/client/rsc-fetch.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +107 -25
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +57 -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/slot-context.d.ts +31 -0
- package/dist/client/slot-context.d.ts.map +1 -0
- package/dist/client/slot-outlet.d.ts +16 -0
- package/dist/client/slot-outlet.d.ts.map +1 -0
- package/dist/client/slot-provider.d.ts +25 -0
- package/dist/client/slot-provider.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +19 -4
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/stale-client.d.ts +69 -0
- package/dist/client/stale-client.d.ts.map +1 -0
- package/dist/client/state.d.ts +11 -2
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/top-loader.d.ts +7 -6
- package/dist/client/top-loader.d.ts.map +1 -1
- package/dist/client/unload-guard.d.ts +5 -0
- package/dist/client/unload-guard.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 +10 -4
- package/dist/client/use-query-states.d.ts.map +1 -1
- package/dist/client/use-router.d.ts +2 -2
- package/dist/client/use-router.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +12 -5
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/{use-params.d.ts → use-segment-params.d.ts} +26 -14
- 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 +76 -0
- package/dist/codec.js.map +1 -0
- package/dist/config-types.d.ts +284 -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 +257 -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 +50 -0
- package/dist/dev-tools/404-page.d.ts.map +1 -0
- package/dist/dev-tools/browser-logs.d.ts +40 -0
- package/dist/dev-tools/browser-logs.d.ts.map +1 -0
- package/dist/dev-tools/dev-page-shell.d.ts +78 -0
- package/dist/dev-tools/dev-page-shell.d.ts.map +1 -0
- package/dist/dev-tools/error-page.d.ts +32 -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/hydration-overlay.d.ts +11 -0
- package/dist/dev-tools/hydration-overlay.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/dev-tools/instrumentation.d.ts +59 -0
- 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} +17 -3
- 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/fonts/ast-walk.d.ts +68 -0
- package/dist/fonts/ast-walk.d.ts.map +1 -0
- package/dist/fonts/ast.d.ts +110 -6
- package/dist/fonts/ast.d.ts.map +1 -1
- package/dist/fonts/bundle.d.ts +50 -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/fallbacks.d.ts +0 -7
- package/dist/fonts/fallbacks.d.ts.map +1 -1
- package/dist/fonts/google.d.ts +4 -2
- package/dist/fonts/google.d.ts.map +1 -1
- package/dist/fonts/local.d.ts +4 -4
- package/dist/fonts/local.d.ts.map +1 -1
- package/dist/fonts/paths.d.ts +43 -0
- package/dist/fonts/paths.d.ts.map +1 -0
- package/dist/fonts/pipeline.d.ts +177 -0
- package/dist/fonts/pipeline.d.ts.map +1 -0
- package/dist/fonts/transform.d.ts +82 -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 +77 -0
- package/dist/fonts/virtual-modules.d.ts.map +1 -0
- package/dist/index.d.ts +50 -181
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9805 -14134
- 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 +276 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugins/adapter-build.d.ts +21 -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 +47 -10
- package/dist/plugins/build-report.d.ts.map +1 -1
- package/dist/plugins/cache.d.ts +64 -0
- package/dist/plugins/cache.d.ts.map +1 -0
- package/dist/plugins/callsite-ast.d.ts +117 -0
- package/dist/plugins/callsite-ast.d.ts.map +1 -0
- package/dist/plugins/callsite-jsx.d.ts +35 -0
- package/dist/plugins/callsite-jsx.d.ts.map +1 -0
- package/dist/plugins/chunks.d.ts +11 -4
- package/dist/plugins/chunks.d.ts.map +1 -1
- package/dist/plugins/client-chunks.d.ts +40 -0
- package/dist/plugins/client-chunks.d.ts.map +1 -0
- package/dist/plugins/cloudflare-wasm.d.ts +21 -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 +17 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts +28 -4
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/fonts.d.ts +16 -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/prebuilt-capture.d.ts +60 -0
- package/dist/plugins/prebuilt-capture.d.ts.map +1 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts +40 -0
- package/dist/plugins/prebuilt-options-analysis.d.ts.map +1 -0
- package/dist/plugins/prebuilt.d.ts +82 -0
- package/dist/plugins/prebuilt.d.ts.map +1 -0
- package/dist/plugins/prerender-sugar.d.ts +42 -0
- package/dist/plugins/prerender-sugar.d.ts.map +1 -0
- package/dist/plugins/request-dep/analysis.d.ts +106 -0
- package/dist/plugins/request-dep/analysis.d.ts.map +1 -0
- package/dist/plugins/request-dep/index.d.ts +75 -0
- package/dist/plugins/request-dep/index.d.ts.map +1 -0
- package/dist/plugins/request-dep/origin.d.ts +61 -0
- package/dist/plugins/request-dep/origin.d.ts.map +1 -0
- 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 +29 -5
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +218 -21
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-shared.d.ts +26 -0
- package/dist/routing/codegen-shared.d.ts.map +1 -0
- package/dist/routing/codegen-types.d.ts +61 -0
- package/dist/routing/codegen-types.d.ts.map +1 -0
- package/dist/routing/codegen-write.d.ts +51 -0
- package/dist/routing/codegen-write.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/collision-probe.d.ts +104 -0
- package/dist/routing/collision-probe.d.ts.map +1 -0
- package/dist/routing/collision-spaces.d.ts +26 -0
- package/dist/routing/collision-spaces.d.ts.map +1 -0
- package/dist/routing/convention-lint.d.ts +55 -0
- package/dist/routing/convention-lint.d.ts.map +1 -0
- package/dist/routing/export-detect.d.ts +72 -0
- package/dist/routing/export-detect.d.ts.map +1 -0
- package/dist/routing/file-cache.d.ts +8 -0
- package/dist/routing/file-cache.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 +5 -2
- package/dist/routing/interception.d.ts +234 -10
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/routing/link-codegen.d.ts +105 -0
- package/dist/routing/link-codegen.d.ts.map +1 -0
- package/dist/routing/manifest-codegen.d.ts +26 -0
- package/dist/routing/manifest-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 +114 -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/segment-keys.d.ts +117 -0
- package/dist/routing/segment-keys.d.ts.map +1 -0
- package/dist/routing/slot-placement.d.ts +48 -0
- package/dist/routing/slot-placement.d.ts.map +1 -0
- package/dist/routing/types.d.ts +74 -26
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/walkers.d.ts +57 -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 +145 -0
- package/dist/schema-bridge.d.ts.map +1 -0
- package/dist/search-params/define.d.ts +262 -0
- package/dist/search-params/define.d.ts.map +1 -0
- package/dist/search-params/index.d.ts +3 -7
- package/dist/search-params/index.d.ts.map +1 -1
- package/dist/search-params/index.js +179 -360
- package/dist/search-params/index.js.map +1 -1
- package/dist/search-params/parse-total.d.ts +81 -0
- package/dist/search-params/parse-total.d.ts.map +1 -0
- package/dist/search-params/serialize-equal.d.ts +9 -0
- package/dist/search-params/serialize-equal.d.ts.map +1 -0
- package/dist/search-params/wrappers.d.ts +76 -0
- package/dist/search-params/wrappers.d.ts.map +1 -0
- package/dist/server/access-gate.d.ts +26 -10
- package/dist/server/access-gate.d.ts.map +1 -1
- package/dist/server/action-client.d.ts +42 -7
- 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 +12 -33
- package/dist/server/actions.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +110 -11
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/asset-headers.d.ts +8 -18
- 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 +25 -30
- package/dist/server/build-manifest.d.ts.map +1 -1
- package/dist/server/canonicalize.d.ts +10 -0
- package/dist/server/canonicalize.d.ts.map +1 -1
- package/dist/server/chain-url-parts.d.ts +81 -0
- package/dist/server/chain-url-parts.d.ts.map +1 -0
- package/dist/server/children-interception.d.ts +49 -0
- package/dist/server/children-interception.d.ts.map +1 -0
- package/dist/server/coalesce-tick.d.ts +40 -0
- package/dist/server/coalesce-tick.d.ts.map +1 -0
- package/dist/server/compress.d.ts.map +1 -1
- 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 +65 -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/default-status-page.d.ts +45 -0
- package/dist/server/default-status-page.d.ts.map +1 -0
- package/dist/server/deny-boundary.d.ts +247 -0
- package/dist/server/deny-boundary.d.ts.map +1 -0
- package/dist/server/deny-renderer.d.ts +16 -5
- 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 +86 -10
- 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/form-data.d.ts +41 -0
- package/dist/server/form-data.d.ts.map +1 -1
- package/dist/server/head-response.d.ts +35 -0
- package/dist/server/head-response.d.ts.map +1 -0
- package/dist/server/html-injector-core.d.ts +242 -0
- package/dist/server/html-injector-core.d.ts.map +1 -0
- package/dist/server/html-injectors.d.ts +82 -41
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.d.ts +10 -47
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +183 -2906
- package/dist/server/index.js.map +1 -1
- package/dist/server/internal.d.ts +51 -0
- package/dist/server/internal.d.ts.map +1 -0
- package/dist/server/internal.js +4154 -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-collector.d.ts +52 -0
- package/dist/server/metadata-collector.d.ts.map +1 -0
- package/dist/server/metadata-routes.d.ts +60 -11
- package/dist/server/metadata-routes.d.ts.map +1 -1
- package/dist/server/metadata.d.ts +8 -0
- package/dist/server/metadata.d.ts.map +1 -1
- package/dist/server/middleware-runner.d.ts +19 -4
- package/dist/server/middleware-runner.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +119 -0
- package/dist/server/node-stream-transforms.d.ts.map +1 -0
- package/dist/server/param-coercion.d.ts +70 -0
- package/dist/server/param-coercion.d.ts.map +1 -0
- package/dist/server/pipeline-helpers.d.ts +77 -0
- package/dist/server/pipeline-helpers.d.ts.map +1 -0
- package/dist/server/pipeline-interception.d.ts +59 -9
- 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 +59 -0
- package/dist/server/pipeline-phases.d.ts.map +1 -0
- package/dist/server/pipeline.d.ts +151 -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/prebuilt/cache-key.d.ts +62 -0
- package/dist/server/prebuilt/cache-key.d.ts.map +1 -0
- package/dist/server/prebuilt/capture-state.d.ts +57 -0
- package/dist/server/prebuilt/capture-state.d.ts.map +1 -0
- package/dist/server/prebuilt/key-discipline.d.ts +23 -0
- package/dist/server/prebuilt/key-discipline.d.ts.map +1 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts +27 -0
- package/dist/server/prebuilt/manifest-tag-index.d.ts.map +1 -0
- package/dist/server/prebuilt/overlay.d.ts +100 -0
- package/dist/server/prebuilt/overlay.d.ts.map +1 -0
- package/dist/server/prebuilt/payload-source.d.ts +78 -0
- package/dist/server/prebuilt/payload-source.d.ts.map +1 -0
- package/dist/server/prebuilt/slots.d.ts +99 -0
- package/dist/server/prebuilt/slots.d.ts.map +1 -0
- package/dist/server/prebuilt/synthetic-store.d.ts +66 -0
- package/dist/server/prebuilt/synthetic-store.d.ts.map +1 -0
- package/dist/server/prebuilt-builder.d.ts +120 -0
- package/dist/server/prebuilt-builder.d.ts.map +1 -0
- package/dist/server/prebuilt-runtime.d.ts +111 -0
- package/dist/server/prebuilt-runtime.d.ts.map +1 -0
- package/dist/server/primitives.d.ts +100 -44
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/publish-params.d.ts +33 -0
- package/dist/server/publish-params.d.ts.map +1 -0
- package/dist/server/render-timeout.d.ts +51 -0
- package/dist/server/render-timeout.d.ts.map +1 -0
- package/dist/server/render-utils.d.ts +25 -0
- package/dist/server/render-utils.d.ts.map +1 -0
- package/dist/server/request-context.d.ts +109 -106
- package/dist/server/request-context.d.ts.map +1 -1
- package/dist/server/request-dep.d.ts +15 -0
- package/dist/server/request-dep.d.ts.map +1 -0
- package/dist/server/route-element-builder.d.ts +74 -27
- 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 +38 -36
- package/dist/server/route-matcher.d.ts.map +1 -1
- package/dist/server/rsc-cache-key-guard.d.ts +78 -0
- package/dist/server/rsc-cache-key-guard.d.ts.map +1 -0
- 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/deny-fallback.d.ts +29 -0
- package/dist/server/rsc-entry/deny-fallback.d.ts.map +1 -0
- package/dist/server/rsc-entry/error-renderer.d.ts +38 -13
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/helpers.d.ts +59 -42
- package/dist/server/rsc-entry/helpers.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts +39 -6
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/render-route.d.ts +51 -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 +5 -6
- package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
- package/dist/server/rsc-entry/rsc-stream.d.ts +40 -3
- 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 +36 -4
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/wrap-action-dispatch.d.ts +89 -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/skippable-prefix.d.ts +26 -0
- package/dist/server/skippable-prefix.d.ts.map +1 -0
- package/dist/server/slot-interception.d.ts +80 -0
- package/dist/server/slot-interception.d.ts.map +1 -0
- package/dist/server/slot-resolver.d.ts +139 -5
- package/dist/server/slot-resolver.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +138 -0
- package/dist/server/ssr-bridge-types.d.ts.map +1 -0
- package/dist/server/ssr-entry.d.ts +1 -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 +61 -0
- package/dist/server/ssr-wrappers.d.ts.map +1 -0
- package/dist/server/state-tree-diff.d.ts +44 -9
- package/dist/server/state-tree-diff.d.ts.map +1 -1
- package/dist/server/static-generator.d.ts +112 -0
- package/dist/server/static-generator.d.ts.map +1 -0
- package/dist/server/static-not-found.d.ts +52 -0
- package/dist/server/static-not-found.d.ts.map +1 -0
- package/dist/server/status-code-resolver.d.ts +26 -15
- package/dist/server/status-code-resolver.d.ts.map +1 -1
- package/dist/server/stream-utils.d.ts +47 -0
- package/dist/server/stream-utils.d.ts.map +1 -0
- package/dist/server/tracing.d.ts +44 -9
- package/dist/server/tracing.d.ts.map +1 -1
- package/dist/server/tree-builder.d.ts +66 -42
- 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 +76 -6
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/utils/element-type.d.ts +40 -0
- package/dist/server/utils/element-type.d.ts.map +1 -0
- package/dist/server/utils/escape-html.d.ts +14 -0
- package/dist/server/utils/escape-html.d.ts.map +1 -0
- package/dist/server/utils/mdx-file.d.ts +15 -0
- package/dist/server/utils/mdx-file.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/server/workers-cache-bridge.d.ts +26 -0
- package/dist/server/workers-cache-bridge.d.ts.map +1 -0
- package/dist/shared/als-slots.d.ts +41 -0
- package/dist/shared/als-slots.d.ts.map +1 -0
- package/dist/shared/base-path.d.ts +56 -0
- package/dist/shared/base-path.d.ts.map +1 -0
- package/dist/shared/href-validation.d.ts +49 -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/shared/param-value.d.ts +80 -0
- package/dist/shared/param-value.d.ts.map +1 -0
- package/dist/shared/payload-root.d.ts +108 -0
- package/dist/shared/payload-root.d.ts.map +1 -0
- package/dist/shared/redirect-type.d.ts +17 -0
- package/dist/shared/redirect-type.d.ts.map +1 -0
- package/dist/shared/rsc-cache-key.d.ts +163 -0
- package/dist/shared/rsc-cache-key.d.ts.map +1 -0
- package/dist/shared/rsc-error-envelope.d.ts +25 -0
- package/dist/shared/rsc-error-envelope.d.ts.map +1 -0
- package/dist/shared/rsc-manifest.d.ts +28 -0
- package/dist/shared/rsc-manifest.d.ts.map +1 -0
- package/dist/shared/rsc-media-type.d.ts +40 -0
- package/dist/shared/rsc-media-type.d.ts.map +1 -0
- package/dist/shared/rsc-payload-path.d.ts +42 -0
- package/dist/shared/rsc-payload-path.d.ts.map +1 -0
- package/dist/shared/segment-info.d.ts +66 -0
- package/dist/shared/segment-info.d.ts.map +1 -0
- package/dist/shared/slot-params.d.ts +51 -0
- package/dist/shared/slot-params.d.ts.map +1 -0
- package/dist/shared/static-platform-files.d.ts +71 -0
- package/dist/shared/static-platform-files.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 +53 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/image.d.ts +120 -120
- package/dist/shims/image.d.ts.map +1 -1
- package/dist/shims/navigation-client.d.ts +25 -12
- package/dist/shims/navigation-client.d.ts.map +1 -1
- package/dist/shims/navigation.d.ts +10 -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/docs/api/30-api-server.mdx +233 -0
- package/docs/api/31-api-client.mdx +163 -0
- package/docs/api/32-api-cache.mdx +311 -0
- package/docs/api/33-api-search-params.mdx +176 -0
- package/docs/api/34-api-config.mdx +325 -0
- package/docs/api/35-api-typescript.mdx +170 -0
- package/docs/api/36-cli.mdx +170 -0
- package/docs/learn/00-introduction.mdx +109 -0
- package/docs/learn/01-quick-start.mdx +94 -0
- package/docs/learn/02-pages-and-layouts.mdx +147 -0
- package/docs/learn/03-fetching-data.mdx +211 -0
- package/docs/learn/03b-access-control.mdx +130 -0
- package/docs/learn/04-loading-states.mdx +67 -0
- package/docs/learn/04b-the-flush-point.mdx +115 -0
- package/docs/learn/05-typed-params.mdx +275 -0
- package/docs/learn/06-forms-and-actions.mdx +146 -0
- package/docs/learn/07-typed-routes.mdx +132 -0
- package/docs/learn/08-streaming.mdx +146 -0
- package/docs/learn/09-caching.mdx +252 -0
- package/docs/learn/10-middleware.mdx +157 -0
- package/docs/learn/11-error-handling.mdx +173 -0
- package/docs/learn/12-client-navigation.mdx +176 -0
- package/docs/learn/13-configuration.mdx +166 -0
- package/docs/learn/14-deploying.mdx +287 -0
- package/docs/more/01-advanced-routing.mdx +343 -0
- package/docs/more/02-advanced-forms.mdx +137 -0
- package/docs/more/03-coming-from-nextjs.mdx +186 -0
- package/docs/more/04-metadata-and-fonts.mdx +193 -0
- package/docs/more/04b-mdx.mdx +209 -0
- package/docs/more/05-content-collections.mdx +90 -0
- package/docs/more/06-instrumentation.mdx +214 -0
- package/docs/more/07-security.mdx +129 -0
- package/docs/more/08-developer-experience.mdx +134 -0
- package/docs/more/40-why-timber.mdx +50 -0
- package/docs/more/41-timber-vs-nextjs.mdx +81 -0
- package/docs/more/42-timber-vs-others.mdx +68 -0
- package/docs/more/50-ai-agent-instructions.mdx +171 -0
- package/llms.txt +55 -0
- package/package.json +108 -26
- package/src/adapters/build-output-helper.ts +351 -0
- package/src/adapters/cloudflare-dev.ts +177 -0
- package/src/adapters/cloudflare-kv-cache.ts +204 -0
- package/src/adapters/cloudflare.ts +740 -129
- package/src/adapters/compress-module.ts +101 -88
- package/src/adapters/fs-identity.ts +156 -0
- package/src/adapters/nitro.ts +320 -120
- package/src/adapters/raw-imports.d.ts +5 -0
- package/src/adapters/shared.ts +274 -0
- package/src/adapters/types.ts +28 -7
- package/src/adapters/wrangler.d.ts +7 -0
- package/src/cache/cache-api.ts +107 -0
- package/src/cache/fast-hash.ts +5 -0
- package/src/cache/handler-store.ts +76 -0
- package/src/cache/index.ts +114 -21
- package/src/cache/invalidation-epoch.ts +93 -0
- package/src/cache/json-lossy-check.ts +75 -0
- package/src/cache/redis-handler.ts +197 -19
- package/src/cache/singleflight.ts +64 -6
- package/src/cache/sizeof.ts +33 -0
- package/src/cache/stable-stringify.ts +65 -2
- package/src/cache/store.ts +71 -0
- package/src/cache/stores/cloudflare-kv.ts +52 -0
- package/src/cache/stores/memory.ts +125 -0
- package/src/cache/stores/redis.ts +97 -0
- package/src/cache/stores/vercel.ts +59 -0
- package/src/cache/tag-aware-handler.ts +237 -0
- package/src/cache/timber-cache.ts +161 -36
- package/src/cdn/cloudflare-purge.ts +50 -0
- package/src/cdn/fastly-purge.ts +63 -0
- package/src/cdn/headers.ts +153 -0
- package/src/cdn/index.ts +17 -0
- package/src/cdn/purge-store.ts +34 -0
- package/src/cdn/workers-cache-purge.ts +30 -0
- package/src/cli-check.ts +458 -0
- package/src/cli-schema-sync.ts +401 -0
- package/src/cli.ts +221 -53
- package/src/client/browser-dev.ts +156 -1
- package/src/client/browser-entry/action-dispatch.ts +130 -0
- package/src/client/browser-entry/hmr.ts +70 -0
- package/src/client/browser-entry/hydrate.ts +198 -0
- package/src/client/browser-entry/index.ts +121 -0
- package/src/client/browser-entry/post-hydration.ts +122 -0
- package/src/client/browser-entry/router-init.ts +342 -0
- package/src/client/browser-entry/rsc-stream.ts +166 -0
- package/src/client/browser-entry/scroll.ts +50 -0
- package/src/client/error-boundary.tsx +210 -36
- package/src/client/error-reconstituter.tsx +79 -0
- package/src/client/form.tsx +31 -32
- package/src/client/history.ts +29 -7
- package/src/client/index.ts +78 -45
- package/src/client/internal.ts +59 -0
- package/src/client/link.tsx +397 -150
- package/src/client/navigation-api.ts +345 -0
- package/src/client/navigation-commit.ts +197 -0
- package/src/client/navigation-context.ts +43 -62
- package/src/client/navigation-root.tsx +580 -0
- package/src/client/nuqs-adapter.tsx +16 -3
- package/src/client/params-context.ts +192 -0
- package/src/client/router-effects.ts +231 -0
- package/src/client/router-lifecycle.ts +288 -0
- package/src/client/router-pipeline.ts +393 -0
- package/src/client/router-ref.ts +2 -2
- package/src/client/router-skew.ts +30 -0
- package/src/client/router-types.ts +230 -0
- package/src/client/router.ts +339 -410
- package/src/client/rsc-fetch.ts +530 -73
- package/src/client/segment-cache.ts +224 -38
- package/src/client/segment-outlet.tsx +141 -0
- package/src/client/segment-update-context.ts +42 -0
- package/src/client/shallow-url.ts +22 -0
- package/src/client/slot-context.ts +50 -0
- package/src/client/slot-outlet.tsx +22 -0
- package/src/client/slot-provider.tsx +32 -0
- package/src/client/ssr-data.ts +19 -5
- package/src/client/stale-client.ts +191 -0
- package/src/client/state.ts +16 -3
- package/src/client/top-loader.tsx +13 -10
- package/src/client/unload-guard.ts +34 -2
- package/src/client/use-cookie.ts +69 -17
- 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 +206 -36
- package/src/client/use-router.ts +5 -2
- package/src/client/use-search-params.ts +31 -44
- package/src/client/{use-params.ts → use-segment-params.ts} +49 -23
- package/src/codec.ts +149 -0
- package/src/config-types.ts +282 -0
- package/src/config-validation.ts +330 -0
- package/src/content/index.ts +5 -13
- package/src/cookies/define-cookie.ts +222 -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 +286 -0
- package/src/dev-tools/browser-logs.ts +55 -0
- package/src/dev-tools/dev-page-shell.ts +260 -0
- package/src/dev-tools/error-page.ts +331 -0
- package/src/dev-tools/holding-server.ts +187 -0
- package/src/dev-tools/hydration-overlay.ts +158 -0
- package/src/dev-tools/index.ts +83 -0
- package/src/dev-tools/instrumentation.ts +213 -0
- package/src/{server/dev-logger.ts → dev-tools/logger.ts} +33 -51
- package/src/{plugins/dev-logs.ts → dev-tools/logs.ts} +122 -26
- package/src/dev-tools/overlay.ts +469 -0
- package/src/dev-tools/stack-classifier.ts +75 -0
- package/src/dev-tools/terminal.ts +182 -0
- package/src/fonts/ast-walk.ts +235 -0
- package/src/fonts/ast.ts +477 -126
- package/src/fonts/bundle.ts +138 -0
- package/src/fonts/dev-middleware.ts +85 -0
- package/src/fonts/fallbacks.ts +0 -23
- package/src/fonts/google.ts +100 -18
- package/src/fonts/local.ts +9 -8
- package/src/fonts/paths.ts +58 -0
- package/src/fonts/pipeline.ts +348 -0
- package/src/fonts/transform.ts +311 -0
- package/src/fonts/types.ts +52 -1
- package/src/fonts/virtual-modules.ts +179 -0
- package/src/index.ts +468 -353
- 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 +84 -0
- package/src/plugin-context.ts +503 -0
- package/src/plugins/adapter-build.ts +229 -7
- package/src/plugins/build-manifest.ts +201 -26
- package/src/plugins/build-report.ts +259 -47
- package/src/plugins/cache.ts +243 -0
- package/src/plugins/callsite-ast.ts +472 -0
- package/src/plugins/callsite-jsx.ts +243 -0
- package/src/plugins/chunks.ts +74 -5
- package/src/plugins/client-chunks.ts +185 -0
- package/src/plugins/cloudflare-wasm.ts +141 -0
- package/src/plugins/content.ts +1 -1
- package/src/plugins/dev-server.ts +284 -94
- package/src/plugins/entries.ts +138 -16
- package/src/plugins/fonts.ts +228 -660
- package/src/plugins/mdx.ts +47 -10
- package/src/plugins/prebuilt-capture.ts +217 -0
- package/src/plugins/prebuilt-options-analysis.ts +175 -0
- package/src/plugins/prebuilt.ts +655 -0
- package/src/plugins/prerender-sugar.ts +328 -0
- package/src/plugins/request-dep/analysis.ts +447 -0
- package/src/plugins/request-dep/index.ts +376 -0
- package/src/plugins/request-dep/origin.ts +310 -0
- package/src/plugins/routing.ts +268 -277
- package/src/plugins/server-bundle.ts +89 -12
- package/src/plugins/shims.ts +240 -64
- package/src/plugins/static-build.ts +704 -66
- package/src/routing/codegen-shared.ts +39 -0
- package/src/routing/codegen-types.ts +62 -0
- package/src/routing/codegen-write.ts +139 -0
- package/src/routing/codegen.ts +339 -231
- package/src/routing/collision-probe.ts +438 -0
- package/src/routing/collision-spaces.ts +281 -0
- package/src/routing/convention-lint.ts +493 -0
- package/src/routing/export-detect.ts +448 -0
- package/src/routing/file-cache.ts +23 -0
- package/src/routing/index.ts +10 -1
- package/src/routing/interception.ts +894 -67
- package/src/routing/link-codegen.ts +280 -0
- package/src/routing/manifest-codegen.ts +226 -0
- package/src/routing/scanner.ts +368 -218
- package/src/routing/schema-validation.ts +155 -0
- package/src/routing/segment-classify.ts +280 -0
- package/src/routing/segment-codegen.ts +98 -0
- package/src/routing/segment-keys.ts +183 -0
- package/src/routing/slot-placement.ts +97 -0
- package/src/routing/types.ts +75 -26
- package/src/routing/walkers.ts +98 -0
- package/src/rsc-runtime/rsc.ts +9 -0
- package/src/rsc-runtime/ssr.ts +50 -0
- package/src/rsc-runtime/vendor-types.d.ts +7 -0
- package/src/schema-bridge.ts +380 -0
- package/src/search-params/define.ts +677 -0
- package/src/search-params/index.ts +14 -20
- package/src/search-params/parse-total.ts +91 -0
- package/src/search-params/serialize-equal.ts +14 -0
- package/src/search-params/wrappers.ts +150 -0
- package/src/server/access-gate.tsx +121 -51
- package/src/server/action-client.ts +120 -29
- package/src/server/action-encryption.ts +144 -0
- package/src/server/action-handler.ts +127 -38
- package/src/server/actions.ts +54 -57
- package/src/server/als-registry.ts +154 -20
- package/src/server/asset-headers.ts +15 -37
- package/src/server/body-limits.ts +10 -2
- package/src/server/build-manifest.ts +33 -57
- package/src/server/canonicalize.ts +6 -3
- package/src/server/chain-url-parts.ts +162 -0
- package/src/server/children-interception.ts +115 -0
- package/src/server/coalesce-tick.ts +75 -0
- package/src/server/compress.ts +43 -8
- package/src/server/cookie-context.ts +484 -0
- package/src/server/cookie-parsing.ts +163 -0
- package/src/server/csrf.ts +39 -6
- package/src/server/default-logger.ts +99 -0
- package/src/server/default-status-page.ts +127 -0
- package/src/server/deny-boundary.ts +516 -0
- package/src/server/deny-renderer.ts +181 -101
- package/src/server/dev-source-map.ts +31 -0
- package/src/server/early-hints-sender.ts +3 -2
- package/src/server/early-hints.ts +37 -27
- package/src/server/error-boundary-wrapper.ts +170 -44
- package/src/server/fallback-error.ts +79 -102
- package/src/server/flight-injection-state.ts +113 -0
- package/src/server/flight-scripts.ts +62 -0
- package/src/server/form-data.ts +124 -12
- package/src/server/head-response.ts +54 -0
- package/src/server/html-injector-core.ts +495 -0
- package/src/server/html-injectors.ts +271 -254
- package/src/server/index.ts +29 -185
- package/src/server/internal.ts +181 -0
- package/src/server/logger.ts +72 -36
- package/src/server/metadata-collector.ts +115 -0
- package/src/server/metadata-routes.ts +205 -24
- package/src/server/metadata.ts +21 -0
- package/src/server/middleware-runner.ts +31 -4
- package/src/server/node-stream-transforms.ts +336 -0
- package/src/server/param-coercion.ts +189 -0
- package/src/server/pipeline-helpers.ts +159 -0
- package/src/server/pipeline-interception.ts +109 -33
- package/src/server/pipeline-metadata.ts +14 -0
- package/src/server/pipeline-outcome.ts +196 -0
- package/src/server/pipeline-phases.ts +597 -0
- package/src/server/pipeline.ts +321 -382
- package/src/server/port-resolution.ts +215 -0
- package/src/server/prebuilt/cache-key.ts +298 -0
- package/src/server/prebuilt/capture-state.ts +89 -0
- package/src/server/prebuilt/key-discipline.ts +53 -0
- package/src/server/prebuilt/manifest-tag-index.ts +46 -0
- package/src/server/prebuilt/overlay.ts +256 -0
- package/src/server/prebuilt/payload-source.ts +201 -0
- package/src/server/prebuilt/slots.ts +190 -0
- package/src/server/prebuilt/synthetic-store.ts +121 -0
- package/src/server/prebuilt-builder.ts +803 -0
- package/src/server/prebuilt-runtime.ts +815 -0
- package/src/server/primitives.ts +174 -90
- package/src/server/publish-params.ts +42 -0
- package/src/server/render-timeout.ts +108 -0
- package/src/server/render-utils.ts +31 -0
- package/src/server/request-context.ts +245 -333
- package/src/server/request-dep.ts +37 -0
- package/src/server/route-element-builder.ts +687 -307
- package/src/server/route-handler.ts +39 -12
- package/src/server/route-matcher.ts +162 -269
- package/src/server/rsc-cache-key-guard.ts +164 -0
- package/src/server/rsc-entry/action-middleware-runner.ts +167 -0
- package/src/server/rsc-entry/api-handler.ts +67 -32
- package/src/server/rsc-entry/deny-fallback.ts +93 -0
- package/src/server/rsc-entry/error-renderer.ts +370 -94
- package/src/server/rsc-entry/helpers.ts +226 -95
- package/src/server/rsc-entry/index.ts +357 -330
- package/src/server/rsc-entry/render-route.ts +308 -0
- package/src/server/rsc-entry/revalidate-renderer.ts +350 -0
- package/src/server/rsc-entry/rsc-payload.ts +188 -55
- package/src/server/rsc-entry/rsc-stream.ts +122 -18
- package/src/server/rsc-entry/ssr-bridge.ts +18 -5
- package/src/server/rsc-entry/ssr-renderer.ts +299 -80
- package/src/server/rsc-entry/wrap-action-dispatch.ts +186 -0
- package/src/server/safe-load.ts +60 -0
- package/src/server/sensitive-fields.ts +230 -0
- package/src/server/server-only-guard-noop.js +3 -0
- package/src/server/sitemap-generator.ts +339 -0
- package/src/server/sitemap-handler.ts +157 -0
- package/src/server/skippable-prefix.ts +74 -0
- package/src/server/slot-interception.ts +168 -0
- package/src/server/slot-resolver.ts +677 -294
- package/src/server/ssr-bridge-types.ts +142 -0
- package/src/server/ssr-entry.ts +216 -78
- package/src/server/ssr-render.ts +345 -82
- package/src/server/ssr-wrappers.tsx +142 -0
- package/src/server/state-tree-diff.ts +85 -30
- package/src/server/static-generator.ts +715 -0
- package/src/server/static-not-found.ts +134 -0
- package/src/server/status-code-resolver.ts +107 -148
- package/src/server/stream-utils.ts +288 -0
- package/src/server/tracing.ts +126 -14
- package/src/server/tree-builder.ts +99 -168
- package/src/server/tree-match.ts +262 -0
- package/src/server/types.ts +83 -9
- package/src/server/utils/element-type.ts +72 -0
- package/src/server/utils/escape-html.ts +20 -0
- package/src/server/utils/mdx-file.ts +22 -0
- package/src/server/version-skew.ts +104 -0
- package/src/server/workers-cache-bridge.ts +33 -0
- package/src/shared/als-slots.ts +72 -0
- package/src/shared/base-path.ts +80 -0
- package/src/shared/href-validation.ts +159 -0
- package/src/shared/merge-search-params.ts +55 -0
- package/src/shared/param-value.ts +244 -0
- package/src/shared/payload-root.ts +151 -0
- package/src/shared/redirect-type.ts +17 -0
- package/src/shared/rsc-cache-key.ts +269 -0
- package/src/shared/rsc-error-envelope.ts +31 -0
- package/src/shared/rsc-manifest.ts +29 -0
- package/src/shared/rsc-media-type.ts +43 -0
- package/src/shared/rsc-payload-path.ts +45 -0
- package/src/shared/segment-info.ts +67 -0
- package/src/shared/slot-params.ts +111 -0
- package/src/shared/static-platform-files.ts +75 -0
- package/src/shims/font-google.ts +1 -1
- package/src/shims/font-local.ts +34 -0
- package/src/shims/headers.ts +122 -1
- package/src/shims/navigation-client.ts +36 -32
- package/src/shims/navigation.ts +10 -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-B3Gypr3D.js +0 -108
- package/dist/_chunks/debug-B3Gypr3D.js.map +0 -1
- package/dist/_chunks/format-RyoGQL74.js +0 -164
- 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 +0 -153
- 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 +0 -109
- package/dist/_chunks/use-query-states-D5KaffOK.js.map +0 -1
- package/dist/adapters/cloudflare.js.map +0 -1
- package/dist/cache/index.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/error-boundary.js.map +0 -1
- package/dist/client/head.d.ts +0 -16
- package/dist/client/head.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/stale-reload.d.ts +0 -44
- package/dist/client/stale-reload.d.ts.map +0 -1
- package/dist/client/transition-root.d.ts +0 -74
- 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/search-params/registry.d.ts +0 -20
- package/dist/search-params/registry.d.ts.map +0 -1
- package/dist/server/client-module-map.d.ts +0 -47
- package/dist/server/client-module-map.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 +0 -29
- package/dist/server/dev-span-processor.d.ts.map +0 -1
- package/dist/server/dev-warnings.d.ts +0 -129
- package/dist/server/dev-warnings.d.ts.map +0 -1
- package/dist/server/flush.d.ts +0 -74
- package/dist/server/flush.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/head.ts +0 -61
- package/src/client/link-status-provider.tsx +0 -30
- package/src/client/segment-merger.ts +0 -339
- package/src/client/stale-reload.ts +0 -87
- 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/codecs.ts +0 -153
- package/src/search-params/create.ts +0 -321
- package/src/search-params/registry.ts +0 -31
- package/src/server/client-module-map.ts +0 -58
- package/src/server/dev-fetch-instrumentation.ts +0 -96
- package/src/server/dev-span-processor.ts +0 -78
- package/src/server/dev-warnings.ts +0 -283
- package/src/server/flush.ts +0 -182
- package/src/server/manifest-status-resolver.ts +0 -215
- package/src/server/prerender.ts +0 -139
- package/src/utils/directive-parser.ts +0 -529
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TagAwareCacheHandler — wraps any CacheStore and adds tag-based invalidation.
|
|
3
|
+
*
|
|
4
|
+
* Three strategies, selected by store capabilities (best available wins):
|
|
5
|
+
*
|
|
6
|
+
* 1. **Native** (store has setWithTags + invalidateTag): Delegates entirely.
|
|
7
|
+
* The store owns tag indexing. Used for Vercel Runtime Cache, DO-backed
|
|
8
|
+
* stores, or any platform with first-class tag support.
|
|
9
|
+
*
|
|
10
|
+
* 2. **Eager** (store has sadd/smembers/srem/sdel): Maintains an inverted
|
|
11
|
+
* index via atomic set operations. Invalidation enumerates the set and
|
|
12
|
+
* deletes entries. Used for Redis.
|
|
13
|
+
*
|
|
14
|
+
* 3. **Lazy** (bare get/set/del only): Version-stamps entries with tag
|
|
15
|
+
* counters. Invalidation bumps a counter (O(1)). Reads validate stored
|
|
16
|
+
* versions against current. Race-free, correct under eventual consistency.
|
|
17
|
+
* Used for Cloudflare KV.
|
|
18
|
+
*
|
|
19
|
+
* Implements the CacheHandler interface consumed by timber-cache.ts.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { CacheHandler } from './index';
|
|
23
|
+
import type { CacheStore } from './store';
|
|
24
|
+
|
|
25
|
+
const DATA_PREFIX = 'd:';
|
|
26
|
+
const TAG_SET_PREFIX = 'ts:';
|
|
27
|
+
const TAG_VERSION_PREFIX = 'tv:';
|
|
28
|
+
|
|
29
|
+
type Strategy = 'native' | 'eager' | 'lazy';
|
|
30
|
+
|
|
31
|
+
/** Stored entry format for eager strategy. */
|
|
32
|
+
interface EagerEntry {
|
|
33
|
+
value: unknown;
|
|
34
|
+
expiresAt: number;
|
|
35
|
+
tags: string[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Stored entry format for lazy (version-stamp) strategy. */
|
|
39
|
+
interface LazyEntry {
|
|
40
|
+
value: unknown;
|
|
41
|
+
expiresAt: number;
|
|
42
|
+
tags: string[];
|
|
43
|
+
tagVersions: Record<string, number>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function detectStrategy(store: CacheStore): Strategy {
|
|
47
|
+
if (store.setWithTags && store.invalidateTag) return 'native';
|
|
48
|
+
if (store.sadd && store.smembers && store.srem && store.sdel) return 'eager';
|
|
49
|
+
return 'lazy';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class TagAwareCacheHandler implements CacheHandler {
|
|
53
|
+
private store: CacheStore;
|
|
54
|
+
private prefix: string;
|
|
55
|
+
private strategy: Strategy;
|
|
56
|
+
|
|
57
|
+
constructor(store: CacheStore, opts?: { prefix?: string }) {
|
|
58
|
+
this.store = store;
|
|
59
|
+
this.prefix = opts?.prefix ?? 'timber:';
|
|
60
|
+
this.strategy = detectStrategy(store);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get consistency(): 'strong' | 'eventual' | 'local' {
|
|
64
|
+
return this.store.consistency;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private dataKey(key: string): string {
|
|
68
|
+
return `${this.prefix}${DATA_PREFIX}${key}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Namespace tags for native stores so prefix isolates shared stores. */
|
|
72
|
+
private prefixTags(tags: string[]): string[] {
|
|
73
|
+
return tags.map((t) => `${this.prefix}${t}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private tagSetKey(tag: string): string {
|
|
77
|
+
return `${this.prefix}${TAG_SET_PREFIX}${tag}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private tagVersionKey(tag: string): string {
|
|
81
|
+
return `${this.prefix}${TAG_VERSION_PREFIX}${tag}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async get(key: string): Promise<{ value: unknown; stale: boolean } | null> {
|
|
85
|
+
const raw = await this.store.get(this.dataKey(key));
|
|
86
|
+
if (raw === null) return null;
|
|
87
|
+
|
|
88
|
+
if (this.strategy === 'native' || this.strategy === 'eager') {
|
|
89
|
+
const entry = JSON.parse(raw) as EagerEntry;
|
|
90
|
+
const stale = Date.now() > entry.expiresAt;
|
|
91
|
+
return { value: entry.value, stale };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Lazy: validate tag versions before returning
|
|
95
|
+
const entry = JSON.parse(raw) as LazyEntry;
|
|
96
|
+
if (entry.tags.length > 0) {
|
|
97
|
+
const currentVersions = await this.getTagVersions(entry.tags);
|
|
98
|
+
for (const tag of entry.tags) {
|
|
99
|
+
const stored = entry.tagVersions[tag] ?? 0;
|
|
100
|
+
const current = currentVersions[tag] ?? 0;
|
|
101
|
+
if (current > stored) return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const stale = Date.now() > entry.expiresAt;
|
|
105
|
+
return { value: entry.value, stale };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async set(
|
|
109
|
+
key: string,
|
|
110
|
+
value: unknown,
|
|
111
|
+
opts: { ttl: number; tags: string[]; generation?: number }
|
|
112
|
+
): Promise<void> {
|
|
113
|
+
const physicalTtl = Math.max(opts.ttl * 2 + 60, 120);
|
|
114
|
+
|
|
115
|
+
if (this.strategy === 'native') {
|
|
116
|
+
const entry: EagerEntry = {
|
|
117
|
+
value,
|
|
118
|
+
expiresAt: Date.now() + opts.ttl * 1000,
|
|
119
|
+
tags: opts.tags,
|
|
120
|
+
};
|
|
121
|
+
const payload = JSON.stringify(entry);
|
|
122
|
+
if (opts.tags.length > 0) {
|
|
123
|
+
await this.store.setWithTags!(
|
|
124
|
+
this.dataKey(key),
|
|
125
|
+
payload,
|
|
126
|
+
physicalTtl,
|
|
127
|
+
this.prefixTags(opts.tags)
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
await this.store.set(this.dataKey(key), payload, physicalTtl);
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (this.strategy === 'eager') {
|
|
136
|
+
const entry: EagerEntry = {
|
|
137
|
+
value,
|
|
138
|
+
expiresAt: Date.now() + opts.ttl * 1000,
|
|
139
|
+
tags: opts.tags,
|
|
140
|
+
};
|
|
141
|
+
await this.store.set(this.dataKey(key), JSON.stringify(entry), physicalTtl);
|
|
142
|
+
if (opts.tags.length > 0) {
|
|
143
|
+
await Promise.all(
|
|
144
|
+
opts.tags.map((tag) => this.store.sadd!(this.tagSetKey(tag), [key], physicalTtl))
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Lazy: snapshot current tag versions into the entry
|
|
151
|
+
const tagVersions = opts.tags.length > 0 ? await this.getTagVersions(opts.tags) : {};
|
|
152
|
+
const entry: LazyEntry = {
|
|
153
|
+
value,
|
|
154
|
+
expiresAt: Date.now() + opts.ttl * 1000,
|
|
155
|
+
tags: opts.tags,
|
|
156
|
+
tagVersions,
|
|
157
|
+
};
|
|
158
|
+
await this.store.set(this.dataKey(key), JSON.stringify(entry), physicalTtl);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async invalidate(opts: { key?: string; tag?: string }): Promise<void> {
|
|
162
|
+
if (opts.key) {
|
|
163
|
+
if (this.strategy === 'eager') {
|
|
164
|
+
const raw = await this.store.get(this.dataKey(opts.key));
|
|
165
|
+
if (raw !== null) {
|
|
166
|
+
const entry = JSON.parse(raw) as EagerEntry;
|
|
167
|
+
if (entry.tags.length > 0) {
|
|
168
|
+
await Promise.all(
|
|
169
|
+
entry.tags.map((tag) => this.store.srem!(this.tagSetKey(tag), [opts.key!]))
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
await this.store.del(this.dataKey(opts.key));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (opts.tag) {
|
|
178
|
+
const tag = opts.tag;
|
|
179
|
+
if (this.strategy === 'native') {
|
|
180
|
+
await this.store.invalidateTag!(`${this.prefix}${tag}`);
|
|
181
|
+
} else if (this.strategy === 'eager') {
|
|
182
|
+
const members = await this.store.smembers!(this.tagSetKey(tag));
|
|
183
|
+
// Verify each member still carries the tag before deleting — the set
|
|
184
|
+
// can contain stale memberships from overwritten entries or LRU eviction.
|
|
185
|
+
// Remove only the snapshot members (via srem, not sdel) so concurrent
|
|
186
|
+
// writes that add new members between smembers() and cleanup are preserved.
|
|
187
|
+
await Promise.all(
|
|
188
|
+
members.map(async (k) => {
|
|
189
|
+
const raw = await this.store.get(this.dataKey(k));
|
|
190
|
+
if (raw === null) {
|
|
191
|
+
await this.store.srem!(this.tagSetKey(tag), [k]);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const entry = JSON.parse(raw) as EagerEntry;
|
|
195
|
+
if (entry.tags.includes(tag)) {
|
|
196
|
+
await this.store.del(this.dataKey(k));
|
|
197
|
+
await this.store.srem!(this.tagSetKey(tag), [k]);
|
|
198
|
+
} else {
|
|
199
|
+
await this.store.srem!(this.tagSetKey(tag), [k]);
|
|
200
|
+
}
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
} else {
|
|
204
|
+
await this.bumpTagVersion(opts.tag);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// --- Lazy strategy helpers ---
|
|
210
|
+
|
|
211
|
+
private async getTagVersions(tags: string[]): Promise<Record<string, number>> {
|
|
212
|
+
const versions: Record<string, number> = {};
|
|
213
|
+
await Promise.all(
|
|
214
|
+
tags.map(async (tag) => {
|
|
215
|
+
const raw = await this.store.get(this.tagVersionKey(tag));
|
|
216
|
+
versions[tag] = raw !== null ? parseInt(raw, 10) : 0;
|
|
217
|
+
})
|
|
218
|
+
);
|
|
219
|
+
return versions;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private async bumpTagVersion(tag: string): Promise<void> {
|
|
223
|
+
const key = this.tagVersionKey(tag);
|
|
224
|
+
const raw = await this.store.get(key);
|
|
225
|
+
const stored = raw !== null ? parseInt(raw, 10) : 0;
|
|
226
|
+
// max(stored, now) + 1: strictly advancing even within the same
|
|
227
|
+
// millisecond (two bumps in 1ms produce N, N+1 not N, N). On
|
|
228
|
+
// eventually-consistent stores the read can be stale, but Date.now()
|
|
229
|
+
// provides a floor — regression only if BOTH the read is stale AND the
|
|
230
|
+
// clock is behind, bounded by the store's propagation window (~60s).
|
|
231
|
+
const version = Math.max(stored, Date.now()) + 1;
|
|
232
|
+
// Version keys must outlive all data entries stamped with them. Data
|
|
233
|
+
// entries use physical TTL of max(ttl*2+60, 120); 365 days exceeds any
|
|
234
|
+
// practical cache lifetime.
|
|
235
|
+
await this.store.set(key, String(version), 365 * 86400);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -1,10 +1,43 @@
|
|
|
1
1
|
import type { CacheHandler, CacheOptions } from './index';
|
|
2
2
|
import { stableStringify } from './stable-stringify';
|
|
3
3
|
import { createSingleflight } from './singleflight';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
currentInvalidationEpoch,
|
|
6
|
+
lastInvalidationEpochFor,
|
|
7
|
+
wasInvalidatedSince,
|
|
8
|
+
} from './invalidation-epoch';
|
|
9
|
+
import { addSpanEventSync } from '../server/tracing.js';
|
|
10
|
+
import { logSwrRefetchFailed, swallow } from '../server/logger.js';
|
|
11
|
+
import { getWaitUntil } from '../server/waituntil-bridge.js';
|
|
5
12
|
import { fnv1aHash } from './fast-hash.js';
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
let defaultSingleflight = createSingleflight();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Per-key monotonic generation counter for CAS writes (TIM-1158).
|
|
18
|
+
*
|
|
19
|
+
* Unbounded, like the singleflight map — the key space is the same set of
|
|
20
|
+
* cache keys the handler already tracks. Pruning was removed because it
|
|
21
|
+
* desyncs from MemoryCacheHandler.generations: a pruned key restarts at 1
|
|
22
|
+
* while the handler still holds the old higher generation, causing fresh
|
|
23
|
+
* writes to be rejected as stale.
|
|
24
|
+
*/
|
|
25
|
+
const writeGenerations = new Map<string, number>();
|
|
26
|
+
function nextGeneration(key: string): number {
|
|
27
|
+
const gen = (writeGenerations.get(key) ?? 0) + 1;
|
|
28
|
+
writeGenerations.set(key, gen);
|
|
29
|
+
return gen;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set the timeout for the module-level default singleflight.
|
|
34
|
+
* Called at framework boot with renderTimeoutMs from timber.config.ts so that
|
|
35
|
+
* cache calls without a per-call timeoutMs still get deadlock protection.
|
|
36
|
+
* See design/06-caching.md §"Singleflight Timeout — Deadlock Risk".
|
|
37
|
+
*/
|
|
38
|
+
export function setDefaultSingleflightTimeout(timeoutMs: number): void {
|
|
39
|
+
defaultSingleflight = createSingleflight({ timeoutMs });
|
|
40
|
+
}
|
|
8
41
|
|
|
9
42
|
/**
|
|
10
43
|
* Generate a cache key from function identity and serialized args.
|
|
@@ -33,17 +66,62 @@ function resolveTags<Fn extends (...args: any[]) => any>(
|
|
|
33
66
|
return opts.tags(...args);
|
|
34
67
|
}
|
|
35
68
|
|
|
36
|
-
|
|
37
|
-
|
|
69
|
+
/** Per-process count of byte-identical fn sources seen by deriveFallbackFnId. */
|
|
70
|
+
const fallbackIdOccurrences = new Map<string, number>();
|
|
71
|
+
let hasWarnedFallbackId = false;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Derive a fallback fnId for callsites the timber-cache-transform Vite plugin
|
|
75
|
+
* could not statically detect (aliased bindings, user re-export wrappers).
|
|
76
|
+
*
|
|
77
|
+
* The base is fnv1a(fn.toString()) — deterministic across instances and cold
|
|
78
|
+
* starts of the same build, so two *different* functions can never swap fnIds
|
|
79
|
+
* by module-evaluation order (the TIM-997 poisoning scenario that the old
|
|
80
|
+
* process-local counter allowed; see TIM-1054). A per-process occurrence
|
|
81
|
+
* suffix disambiguates byte-identical duplicate sources. That residue is the
|
|
82
|
+
* one remaining hazard: closures produced by the same factory share source
|
|
83
|
+
* text but capture different values, and their occurrence order may differ
|
|
84
|
+
* across instances — such callsites need an explicit `key` option.
|
|
85
|
+
*/
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
function deriveFallbackFnId(fn: (...args: any[]) => any): string {
|
|
88
|
+
const sourceHash = fnv1aHash(fn.toString());
|
|
89
|
+
const occurrence = fallbackIdOccurrences.get(sourceHash) ?? 0;
|
|
90
|
+
fallbackIdOccurrences.set(sourceHash, occurrence + 1);
|
|
91
|
+
|
|
92
|
+
if (!hasWarnedFallbackId && typeof process !== 'undefined' && process.env?.NODE_ENV !== 'test') {
|
|
93
|
+
hasWarnedFallbackId = true;
|
|
94
|
+
console.warn(
|
|
95
|
+
'[timber] cache() callsite has no build-time stable ID and no explicit `key` option — ' +
|
|
96
|
+
'the call is not statically visible to the timber Vite plugin (e.g. an aliased ' +
|
|
97
|
+
'binding like `const c = cache` or a re-export wrapper module). Falling back to a ' +
|
|
98
|
+
'function-source hash for the cache key. With a shared CacheHandler (Redis/KV) this ' +
|
|
99
|
+
'is safe for distinct functions, but byte-identical closures from a factory can swap ' +
|
|
100
|
+
'cache entries across instances. Provide an explicit `key` option to make the cache ' +
|
|
101
|
+
'key contract stable and auditable.'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return `timber-cache:fn:${sourceHash}:${occurrence}`;
|
|
106
|
+
}
|
|
38
107
|
|
|
39
108
|
/**
|
|
40
109
|
* Creates a cached wrapper around an async function.
|
|
41
110
|
*
|
|
42
|
-
* -
|
|
43
|
-
* - Singleflight: concurrent misses → single execution
|
|
111
|
+
* - FNV-1a default keys with normalized JSON args
|
|
112
|
+
* - Singleflight: concurrent misses → single execution AND single
|
|
113
|
+
* handler.set — the write happens inside the coalesced callback (TIM-1028)
|
|
114
|
+
* - Writes are skipped when the key/tags were invalidated while fn was in
|
|
115
|
+
* flight, so explicit invalidation is never silently undone (TIM-1028)
|
|
44
116
|
* - SWR: serve stale immediately, background refetch
|
|
45
117
|
* - Tags as string[] or function of args
|
|
46
|
-
* -
|
|
118
|
+
* - The handler is resolved per invocation via `getHandler`, never captured
|
|
119
|
+
* at wrapper-creation time — module-scope cache() wrappers created before
|
|
120
|
+
* the framework's boot wiring calls setCacheHandler() still use the
|
|
121
|
+
* configured handler once it arrives (TIM-1029)
|
|
122
|
+
* - No ALS dependency for correctness — cache() works outside a request
|
|
123
|
+
* context. The waitUntil ALS bridge is read optionally so the SWR
|
|
124
|
+
* background refetch survives handler return on Workers/Lambda.
|
|
47
125
|
*
|
|
48
126
|
* Cache hits/misses are recorded as OTEL span events on the enclosing
|
|
49
127
|
* span (not child spans). The DevSpanProcessor reads these for dev log output.
|
|
@@ -52,15 +130,30 @@ let fnIdCounter = 0;
|
|
|
52
130
|
export function createCache<Fn extends (...args: any[]) => Promise<any>>(
|
|
53
131
|
fn: Fn,
|
|
54
132
|
opts: CacheOptions<Fn>,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
133
|
+
getHandler: () => CacheHandler,
|
|
134
|
+
stableId?: string
|
|
135
|
+
): Fn {
|
|
136
|
+
// With an explicit `key` option the fnId never reaches key generation, so
|
|
137
|
+
// no fallback derivation (or warning) is needed in that case.
|
|
138
|
+
const fnId = stableId ?? (opts.key ? undefined : deriveFallbackFnId(fn));
|
|
139
|
+
|
|
140
|
+
// Per-call timeoutMs gets a dedicated singleflight instance. Otherwise
|
|
141
|
+
// resolve defaultSingleflight per invocation (not captured at creation
|
|
142
|
+
// time) so wrappers created before boot pick up the timeout once
|
|
143
|
+
// setDefaultSingleflightTimeout is called (TIM-1032, same rationale as
|
|
144
|
+
// getCacheHandler for TIM-1029).
|
|
145
|
+
const perCallSf =
|
|
146
|
+
opts.timeoutMs !== undefined ? createSingleflight({ timeoutMs: opts.timeoutMs }) : undefined;
|
|
58
147
|
|
|
59
|
-
|
|
60
|
-
|
|
148
|
+
// Cast to Fn to preserve the original function's generic call signature.
|
|
149
|
+
// Without this, generic type parameters (e.g. <T> in apiFetch<T>) are
|
|
150
|
+
// erased and callers lose type safety on the return type.
|
|
151
|
+
return (async (...args: Parameters<Fn>): Promise<Awaited<ReturnType<Fn>>> => {
|
|
152
|
+
const sf = perCallSf ?? defaultSingleflight;
|
|
153
|
+
const key = opts.key ? opts.key(...args) : defaultKeyGenerator(fnId as string, args);
|
|
61
154
|
|
|
62
155
|
const cacheStart = performance.now();
|
|
63
|
-
const cached = await
|
|
156
|
+
const cached = await getHandler().get(key);
|
|
64
157
|
|
|
65
158
|
if (cached && !cached.stale) {
|
|
66
159
|
// Record as OTEL span event on enclosing span (not a child span).
|
|
@@ -72,6 +165,43 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
|
|
|
72
165
|
return cached.value as Awaited<ReturnType<Fn>>;
|
|
73
166
|
}
|
|
74
167
|
|
|
168
|
+
// From here fn() will execute (SWR refetch or miss). Scope the
|
|
169
|
+
// singleflight key by the last invalidation epoch affecting this
|
|
170
|
+
// key/tags: a caller arriving after an invalidation must not coalesce
|
|
171
|
+
// onto a flight that started before it — it would receive the
|
|
172
|
+
// pre-invalidation result the invalidation was issued to discard.
|
|
173
|
+
// NUL separator: cannot collide with user-provided key strings.
|
|
174
|
+
const tags = resolveTags(opts, args);
|
|
175
|
+
const flightKey = `${key}\u0000${lastInvalidationEpochFor(key, tags)}`;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Run fn and store the result — exactly once per coalesced execution,
|
|
179
|
+
* inside the singleflight callback. The write is skipped when:
|
|
180
|
+
* - the key/tags were invalidated after fn started (TIM-1028), or
|
|
181
|
+
* - the singleflight timed out (signal aborted) — the timed-out
|
|
182
|
+
* flight's write could overwrite a newer value from a subsequent
|
|
183
|
+
* flight (TIM-1092), or
|
|
184
|
+
* - the handler rejects the write because a newer generation has
|
|
185
|
+
* already been stored (TIM-1158 CAS guard).
|
|
186
|
+
*/
|
|
187
|
+
const executeAndStore = async (signal: AbortSignal): Promise<Awaited<ReturnType<Fn>>> => {
|
|
188
|
+
const startEpoch = currentInvalidationEpoch();
|
|
189
|
+
const generation = nextGeneration(key);
|
|
190
|
+
const result = await fn(...args);
|
|
191
|
+
if (!signal.aborted && !wasInvalidatedSince(startEpoch, key, tags)) {
|
|
192
|
+
try {
|
|
193
|
+
await getHandler().set(key, result, { ttl: opts.ttl, tags, generation });
|
|
194
|
+
} catch (err) {
|
|
195
|
+
// Cache-write failure must not fail the request (TIM-1046).
|
|
196
|
+
// JSON-serializing handlers (Redis, KV) throw on BigInt; network
|
|
197
|
+
// errors can surface from any shared handler. The result is valid
|
|
198
|
+
// — serve it uncached rather than rejecting a successful fn().
|
|
199
|
+
swallow(err, `cache set failed for key "${key}"`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
};
|
|
204
|
+
|
|
75
205
|
if (cached && cached.stale && opts.staleWhileRevalidate) {
|
|
76
206
|
// Record stale cache hit as OTEL span event (fire-and-forget).
|
|
77
207
|
addSpanEventSync('timber.cache.hit', {
|
|
@@ -80,27 +210,32 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
|
|
|
80
210
|
stale: true,
|
|
81
211
|
});
|
|
82
212
|
// Serve stale immediately, trigger background refetch
|
|
83
|
-
|
|
84
|
-
.do(`swr:${
|
|
213
|
+
const refetch = sf
|
|
214
|
+
.do(`swr:${flightKey}`, async (signal) => {
|
|
85
215
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
await handler.set(key, fresh, { ttl: opts.ttl, tags });
|
|
89
|
-
} catch {
|
|
216
|
+
await executeAndStore(signal);
|
|
217
|
+
} catch (err) {
|
|
90
218
|
// Failed refetch — stale entry continues to be served.
|
|
91
|
-
|
|
219
|
+
logSwrRefetchFailed({ cacheKey: key, error: err });
|
|
92
220
|
}
|
|
93
221
|
})
|
|
94
222
|
.catch(() => {
|
|
95
223
|
// Singleflight promise rejection handled — stale continues.
|
|
96
224
|
});
|
|
225
|
+
// Platforms that cancel work when the handler returns (Cloudflare
|
|
226
|
+
// Workers, Lambda) would otherwise kill the refetch mid-flight —
|
|
227
|
+
// stale data re-served forever. Register the (never-rejecting)
|
|
228
|
+
// refetch with the request's waitUntil; undefined outside a request
|
|
229
|
+
// context or on platforms without lifecycle extension (Node servers
|
|
230
|
+
// keep floating promises alive, so behavior there is unchanged).
|
|
231
|
+
getWaitUntil()?.(refetch);
|
|
97
232
|
return cached.value as Awaited<ReturnType<Fn>>;
|
|
98
233
|
}
|
|
99
234
|
|
|
100
|
-
// Cache miss (or stale without SWR) — execute with singleflight
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
235
|
+
// Cache miss (or stale without SWR) — execute with singleflight.
|
|
236
|
+
// The handler.set lives inside the coalesced callback, so N concurrent
|
|
237
|
+
// misses produce exactly one write (TIM-1028).
|
|
238
|
+
const result = await sf.do(flightKey, executeAndStore);
|
|
104
239
|
|
|
105
240
|
// Record cache miss as OTEL span event (fire-and-forget).
|
|
106
241
|
addSpanEventSync('timber.cache.miss', {
|
|
@@ -108,16 +243,6 @@ export function createCache<Fn extends (...args: any[]) => Promise<any>>(
|
|
|
108
243
|
duration_ms: Math.round(performance.now() - cacheStart),
|
|
109
244
|
});
|
|
110
245
|
|
|
111
|
-
return result
|
|
112
|
-
};
|
|
246
|
+
return result;
|
|
247
|
+
}) as unknown as Fn;
|
|
113
248
|
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Invalidate cache entries by tag or key.
|
|
117
|
-
*/
|
|
118
|
-
createCache.invalidate = async function invalidate(
|
|
119
|
-
handler: CacheHandler,
|
|
120
|
-
opts: { key?: string; tag?: string }
|
|
121
|
-
): Promise<void> {
|
|
122
|
-
await handler.invalidate(opts);
|
|
123
|
-
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare CDN purge handler — purges by cache tag via the Cloudflare API.
|
|
3
|
+
*
|
|
4
|
+
* Requires Cloudflare Enterprise for tag-based purging.
|
|
5
|
+
* See https://developers.cloudflare.com/cache/how-to/purge-cache/purge-by-tags/
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { CdnPurgeHandler } from './purge-store';
|
|
9
|
+
|
|
10
|
+
export interface CloudflarePurgeOptions {
|
|
11
|
+
/** Cloudflare zone ID. */
|
|
12
|
+
zoneId: string;
|
|
13
|
+
/** API token with Cache Purge permission. */
|
|
14
|
+
apiToken: string;
|
|
15
|
+
/** Override fetch for testing. */
|
|
16
|
+
fetch?: typeof globalThis.fetch;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class CloudflarePurge implements CdnPurgeHandler {
|
|
20
|
+
private readonly zoneId: string;
|
|
21
|
+
private readonly apiToken: string;
|
|
22
|
+
private readonly _fetch: typeof globalThis.fetch;
|
|
23
|
+
|
|
24
|
+
constructor(opts: CloudflarePurgeOptions) {
|
|
25
|
+
this.zoneId = opts.zoneId;
|
|
26
|
+
this.apiToken = opts.apiToken;
|
|
27
|
+
this._fetch = opts.fetch ?? globalThis.fetch;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async purgeTags(tags: string[]): Promise<void> {
|
|
31
|
+
if (tags.length === 0) return;
|
|
32
|
+
|
|
33
|
+
const res = await this._fetch(
|
|
34
|
+
`https://api.cloudflare.com/client/v4/zones/${this.zoneId}/purge_cache`,
|
|
35
|
+
{
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
'Authorization': `Bearer ${this.apiToken}`,
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({ tags }),
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (!res.ok) {
|
|
46
|
+
const body = await res.text();
|
|
47
|
+
throw new Error(`Cloudflare purge failed (${res.status}): ${body}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fastly CDN purge handler — purges by surrogate key via the Fastly API.
|
|
3
|
+
*
|
|
4
|
+
* See https://www.fastly.com/documentation/reference/api/purging/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { CdnPurgeHandler } from './purge-store';
|
|
8
|
+
|
|
9
|
+
export interface FastlyPurgeOptions {
|
|
10
|
+
/** Fastly service ID. */
|
|
11
|
+
serviceId: string;
|
|
12
|
+
/** Fastly API token with purge permission. */
|
|
13
|
+
apiToken: string;
|
|
14
|
+
/** Use soft purge (marks as stale instead of immediate delete). Default: false. */
|
|
15
|
+
softPurge?: boolean;
|
|
16
|
+
/** Override fetch for testing. */
|
|
17
|
+
fetch?: typeof globalThis.fetch;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class FastlyPurge implements CdnPurgeHandler {
|
|
21
|
+
private readonly serviceId: string;
|
|
22
|
+
private readonly apiToken: string;
|
|
23
|
+
private readonly softPurge: boolean;
|
|
24
|
+
private readonly _fetch: typeof globalThis.fetch;
|
|
25
|
+
|
|
26
|
+
constructor(opts: FastlyPurgeOptions) {
|
|
27
|
+
this.serviceId = opts.serviceId;
|
|
28
|
+
this.apiToken = opts.apiToken;
|
|
29
|
+
this.softPurge = opts.softPurge ?? false;
|
|
30
|
+
this._fetch = opts.fetch ?? globalThis.fetch;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async purgeTags(tags: string[]): Promise<void> {
|
|
34
|
+
if (tags.length === 0) return;
|
|
35
|
+
|
|
36
|
+
const results = await Promise.allSettled(
|
|
37
|
+
tags.map((tag) =>
|
|
38
|
+
this._fetch(
|
|
39
|
+
`https://api.fastly.com/service/${this.serviceId}/purge/${encodeURIComponent(tag)}`,
|
|
40
|
+
{
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: {
|
|
43
|
+
'Fastly-Key': this.apiToken,
|
|
44
|
+
...(this.softPurge ? { 'Fastly-Soft-Purge': '1' } : {}),
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
).then(async (res) => {
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
const body = await res.text();
|
|
50
|
+
throw new Error(`Fastly purge failed for tag "${tag}" (${res.status}): ${body}`);
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const failures = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');
|
|
57
|
+
if (failures.length > 0) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Fastly purge failed for ${failures.length}/${tags.length} tags: ${failures.map((f) => f.reason?.message).join('; ')}`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|