@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
package/src/cache/index.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
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
|
-
set(
|
|
7
|
+
set(
|
|
8
|
+
key: string,
|
|
9
|
+
value: unknown,
|
|
10
|
+
opts: { ttl: number; tags: string[]; generation?: number }
|
|
11
|
+
): Promise<void>;
|
|
6
12
|
invalidate(opts: { key?: string; tag?: string }): Promise<void>;
|
|
7
13
|
}
|
|
8
14
|
|
|
@@ -12,19 +18,43 @@ export interface CacheOptions<Fn extends (...args: any[]) => any> {
|
|
|
12
18
|
key?: (...args: Parameters<Fn>) => string;
|
|
13
19
|
staleWhileRevalidate?: boolean;
|
|
14
20
|
tags?: string[] | ((...args: Parameters<Fn>) => string[]);
|
|
21
|
+
/** Timeout (ms) for singleflight-coalesced calls. Prevents hung fn() from
|
|
22
|
+
* permanently blocking all future callers for the same cache key. See TIM-518. */
|
|
23
|
+
timeoutMs?: number;
|
|
15
24
|
}
|
|
16
25
|
|
|
17
26
|
export interface MemoryCacheHandlerOptions {
|
|
18
27
|
/** Maximum number of entries. Oldest accessed entries are evicted first. Default: 1000. */
|
|
28
|
+
maxEntries?: number;
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated Use `maxEntries` instead. Will be removed in a future release.
|
|
31
|
+
* Alias for `maxEntries` — maximum number of entries (not bytes).
|
|
32
|
+
*/
|
|
19
33
|
maxSize?: number;
|
|
34
|
+
/** Maximum total byte budget for all cached values. Oldest entries are evicted when exceeded. Default: no limit. */
|
|
35
|
+
maxBytes?: number;
|
|
36
|
+
/** Maximum byte size for a single cache entry. Entries exceeding this are silently dropped. Default: no limit. */
|
|
37
|
+
maxEntryBytes?: number;
|
|
20
38
|
}
|
|
21
39
|
|
|
22
40
|
export class MemoryCacheHandler implements CacheHandler {
|
|
23
|
-
private store = new Map<
|
|
24
|
-
|
|
41
|
+
private store = new Map<
|
|
42
|
+
string,
|
|
43
|
+
{ value: unknown; expiresAt: number; tags: string[]; byteSize: number }
|
|
44
|
+
>();
|
|
45
|
+
private generations = new Map<string, number>();
|
|
46
|
+
private maxEntries: number;
|
|
47
|
+
private maxBytes: number | undefined;
|
|
48
|
+
private maxEntryBytes: number | undefined;
|
|
49
|
+
private currentBytes = 0;
|
|
50
|
+
private readonly _trackBytes: boolean;
|
|
25
51
|
|
|
26
52
|
constructor(opts?: MemoryCacheHandlerOptions) {
|
|
27
|
-
|
|
53
|
+
// maxEntries takes precedence over deprecated maxSize
|
|
54
|
+
this.maxEntries = opts?.maxEntries ?? opts?.maxSize ?? 1000;
|
|
55
|
+
this.maxBytes = opts?.maxBytes;
|
|
56
|
+
this.maxEntryBytes = opts?.maxEntryBytes;
|
|
57
|
+
this._trackBytes = this.maxBytes !== undefined || this.maxEntryBytes !== undefined;
|
|
28
58
|
}
|
|
29
59
|
|
|
30
60
|
async get(key: string) {
|
|
@@ -39,37 +69,76 @@ export class MemoryCacheHandler implements CacheHandler {
|
|
|
39
69
|
return { value: entry.value, stale };
|
|
40
70
|
}
|
|
41
71
|
|
|
42
|
-
async set(
|
|
43
|
-
|
|
72
|
+
async set(
|
|
73
|
+
key: string,
|
|
74
|
+
value: unknown,
|
|
75
|
+
opts: { ttl: number; tags: string[]; generation?: number }
|
|
76
|
+
) {
|
|
77
|
+
// CAS guard: skip write if a newer generation has already been written
|
|
78
|
+
if (opts.generation !== undefined) {
|
|
79
|
+
const current = this.generations.get(key) ?? 0;
|
|
80
|
+
if (opts.generation < current) return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const byteSize = this._trackBytes ? estimateByteSize(value) : 0;
|
|
84
|
+
|
|
85
|
+
// Reject entries exceeding per-entry byte limit
|
|
86
|
+
if (this.maxEntryBytes !== undefined && byteSize > this.maxEntryBytes) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// If key already exists, delete first to refresh insertion order and reclaim bytes
|
|
44
91
|
if (this.store.has(key)) {
|
|
92
|
+
const existing = this.store.get(key)!;
|
|
93
|
+
this.currentBytes -= existing.byteSize;
|
|
45
94
|
this.store.delete(key);
|
|
46
95
|
}
|
|
47
96
|
|
|
48
|
-
// Evict oldest entries (front of Map) if at capacity
|
|
49
|
-
while (this.store.size >= this.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
97
|
+
// Evict oldest entries (front of Map) if at entry count capacity
|
|
98
|
+
while (this.store.size >= this.maxEntries) {
|
|
99
|
+
this.evictOldest();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Evict oldest entries if byte budget would be exceeded
|
|
103
|
+
if (this.maxBytes !== undefined) {
|
|
104
|
+
while (this.currentBytes + byteSize > this.maxBytes && this.store.size > 0) {
|
|
105
|
+
this.evictOldest();
|
|
106
|
+
}
|
|
107
|
+
// If the single entry exceeds the total byte budget, don't store it
|
|
108
|
+
if (this.currentBytes + byteSize > this.maxBytes) {
|
|
109
|
+
return;
|
|
55
110
|
}
|
|
56
111
|
}
|
|
57
112
|
|
|
113
|
+
// Record generation only after all admission checks pass
|
|
114
|
+
if (opts.generation !== undefined) {
|
|
115
|
+
this.generations.set(key, opts.generation);
|
|
116
|
+
}
|
|
117
|
+
|
|
58
118
|
this.store.set(key, {
|
|
59
119
|
value,
|
|
60
120
|
expiresAt: Date.now() + opts.ttl * 1000,
|
|
61
121
|
tags: opts.tags,
|
|
122
|
+
byteSize,
|
|
62
123
|
});
|
|
124
|
+
this.currentBytes += byteSize;
|
|
63
125
|
}
|
|
64
126
|
|
|
65
127
|
async invalidate(opts: { key?: string; tag?: string }) {
|
|
66
128
|
if (opts.key) {
|
|
67
|
-
this.store.
|
|
129
|
+
const entry = this.store.get(opts.key);
|
|
130
|
+
if (entry) {
|
|
131
|
+
this.currentBytes -= entry.byteSize;
|
|
132
|
+
this.store.delete(opts.key);
|
|
133
|
+
}
|
|
134
|
+
this.generations.delete(opts.key);
|
|
68
135
|
}
|
|
69
136
|
if (opts.tag) {
|
|
70
137
|
for (const [key, entry] of this.store) {
|
|
71
138
|
if (entry.tags.includes(opts.tag)) {
|
|
139
|
+
this.currentBytes -= entry.byteSize;
|
|
72
140
|
this.store.delete(key);
|
|
141
|
+
this.generations.delete(key);
|
|
73
142
|
}
|
|
74
143
|
}
|
|
75
144
|
}
|
|
@@ -79,13 +148,37 @@ export class MemoryCacheHandler implements CacheHandler {
|
|
|
79
148
|
get size(): number {
|
|
80
149
|
return this.store.size;
|
|
81
150
|
}
|
|
151
|
+
|
|
152
|
+
/** Estimated total byte size of all cached values. Only tracked when maxBytes or maxEntryBytes is configured; returns 0 otherwise. */
|
|
153
|
+
get bytes(): number {
|
|
154
|
+
return this.currentBytes;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Evict the oldest entry (front of Map). */
|
|
158
|
+
private evictOldest(): void {
|
|
159
|
+
const oldest = this.store.keys().next().value;
|
|
160
|
+
if (oldest !== undefined) {
|
|
161
|
+
const entry = this.store.get(oldest)!;
|
|
162
|
+
this.currentBytes -= entry.byteSize;
|
|
163
|
+
this.store.delete(oldest);
|
|
164
|
+
this.generations.delete(oldest);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
82
167
|
}
|
|
83
168
|
|
|
84
169
|
export { RedisCacheHandler } from './redis-handler';
|
|
85
|
-
export type { RedisClient } from './redis-handler';
|
|
86
|
-
export {
|
|
87
|
-
export {
|
|
88
|
-
export
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
export
|
|
170
|
+
export type { RedisClient, RedisWriteOp } from './redis-handler';
|
|
171
|
+
export { cache } from './cache-api';
|
|
172
|
+
export { setCacheHandler, getCacheHandler } from './handler-store';
|
|
173
|
+
export { setDefaultSingleflightTimeout } from './timber-cache';
|
|
174
|
+
// NOTE: registerCachedFunction (runtime for 'use cache' directive) removed.
|
|
175
|
+
// Future feature pending design doc. See design/06-caching.md.
|
|
176
|
+
export { estimateByteSize } from './sizeof';
|
|
177
|
+
|
|
178
|
+
// --- Cache Store layering (design/46) ---
|
|
179
|
+
export { TagAwareCacheHandler } from './tag-aware-handler';
|
|
180
|
+
export type { CacheStore } from './store';
|
|
181
|
+
// stableStringify, createSingleflight, and SingleflightTimeoutError are
|
|
182
|
+
// internal utilities used by the cache implementation. They are not
|
|
183
|
+
// re-exported here — import directly from the source files if needed
|
|
184
|
+
// within the package. See TIM-720.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-process invalidation epoch tracking for timber.cache (TIM-1028).
|
|
3
|
+
*
|
|
4
|
+
* handler.set for a cache miss runs after `fn()` resolves. An explicit
|
|
5
|
+
* `cache.invalidate({ tag })` / `revalidateTag` that lands while fn is in
|
|
6
|
+
* flight would otherwise be silently undone — the just-invalidated value
|
|
7
|
+
* re-stored as fresh for the full TTL, resurrecting pre-mutation data.
|
|
8
|
+
*
|
|
9
|
+
* Every invalidation bumps a monotonic epoch and records it against the
|
|
10
|
+
* invalidated key/tag. Before storing a result, the cache wrapper checks
|
|
11
|
+
* whether its key or any of its tags were invalidated after fn started and
|
|
12
|
+
* skips the write if so. Skipping is always safe: the only cost is one
|
|
13
|
+
* extra cache miss on the next call.
|
|
14
|
+
*
|
|
15
|
+
* Scope: per-process, like the singleflight map. An invalidation issued by
|
|
16
|
+
* another instance against a shared handler (Redis/KV) during fn flight is
|
|
17
|
+
* not observable here — closing that window fully would require store-level
|
|
18
|
+
* versioning, which no CacheHandler backend offers.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
let epoch = 0;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Last-invalidated epoch per `key:<k>` / `tag:<t>` entry. Insertion order is
|
|
25
|
+
* epoch order (entries are re-inserted on update), so the oldest entry is
|
|
26
|
+
* always first — pruning evicts lowest epochs.
|
|
27
|
+
*/
|
|
28
|
+
const lastInvalidated = new Map<string, number>();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Bound on tracked entries so high-cardinality tag invalidation (e.g.
|
|
32
|
+
* per-user tags) cannot grow this map without limit.
|
|
33
|
+
*/
|
|
34
|
+
const MAX_TRACKED_ENTRIES = 10_000;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Highest epoch evicted from the map. Any execution that started at or
|
|
38
|
+
* before this epoch conservatively counts as invalidated — history was
|
|
39
|
+
* truncated, so we can no longer prove it wasn't.
|
|
40
|
+
*/
|
|
41
|
+
let evictedEpochFloor = 0;
|
|
42
|
+
|
|
43
|
+
/** The current epoch. Capture before running fn(), pass to wasInvalidatedSince. */
|
|
44
|
+
export function currentInvalidationEpoch(): number {
|
|
45
|
+
return epoch;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Record an invalidation. Call BEFORE handler.invalidate() so an execution
|
|
50
|
+
* whose set-check races the invalidation errs toward skipping the write.
|
|
51
|
+
*/
|
|
52
|
+
export function recordInvalidation(opts: { key?: string; tag?: string }): void {
|
|
53
|
+
epoch++;
|
|
54
|
+
if (opts.key) track(`key:${opts.key}`);
|
|
55
|
+
if (opts.tag) track(`tag:${opts.tag}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function track(entry: string): void {
|
|
59
|
+
lastInvalidated.delete(entry);
|
|
60
|
+
lastInvalidated.set(entry, epoch);
|
|
61
|
+
while (lastInvalidated.size > MAX_TRACKED_ENTRIES) {
|
|
62
|
+
const oldest = lastInvalidated.entries().next().value;
|
|
63
|
+
if (oldest === undefined) break;
|
|
64
|
+
evictedEpochFloor = Math.max(evictedEpochFloor, oldest[1]);
|
|
65
|
+
lastInvalidated.delete(oldest[0]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether the key or any tag was invalidated after `startEpoch` (the epoch
|
|
71
|
+
* captured when fn started executing).
|
|
72
|
+
*/
|
|
73
|
+
export function wasInvalidatedSince(startEpoch: number, key: string, tags: string[]): boolean {
|
|
74
|
+
return lastInvalidationEpochFor(key, tags) > startEpoch;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The highest epoch at which the key or any of the tags was invalidated
|
|
79
|
+
* (0 if never). Used to scope the singleflight key: callers arriving after
|
|
80
|
+
* an invalidation must not coalesce onto a flight that started before it —
|
|
81
|
+
* they would receive the pre-invalidation result the invalidation was
|
|
82
|
+
* issued to discard.
|
|
83
|
+
*/
|
|
84
|
+
export function lastInvalidationEpochFor(key: string, tags: string[]): number {
|
|
85
|
+
let last = evictedEpochFloor;
|
|
86
|
+
const keyEpoch = lastInvalidated.get(`key:${key}`);
|
|
87
|
+
if (keyEpoch !== undefined && keyEpoch > last) last = keyEpoch;
|
|
88
|
+
for (const tag of tags) {
|
|
89
|
+
const tagEpoch = lastInvalidated.get(`tag:${tag}`);
|
|
90
|
+
if (tagEpoch !== undefined && tagEpoch > last) last = tagEpoch;
|
|
91
|
+
}
|
|
92
|
+
return last;
|
|
93
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const LOSSY_TYPES = ['Date', 'Map', 'Set', 'BigInt'] as const;
|
|
2
|
+
|
|
3
|
+
let hasWarned = false;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dev-mode warning when a cache value contains types that lose fidelity
|
|
7
|
+
* through JSON round-trip. Only runs in development — no-op in production.
|
|
8
|
+
*
|
|
9
|
+
* Detects: Date (→ ISO string), Map/Set (→ {}), BigInt (→ throws).
|
|
10
|
+
* Emits once per process to avoid log spam.
|
|
11
|
+
*/
|
|
12
|
+
export function warnLossyJsonValue(value: unknown, cacheKey: string): void {
|
|
13
|
+
if (hasWarned) return;
|
|
14
|
+
if (process.env.NODE_ENV === 'production') return;
|
|
15
|
+
|
|
16
|
+
const lossy = findLossyTypes(value, new Set(), 0);
|
|
17
|
+
if (lossy.size === 0) return;
|
|
18
|
+
|
|
19
|
+
hasWarned = true;
|
|
20
|
+
const types = [...lossy].join(', ');
|
|
21
|
+
console.warn(
|
|
22
|
+
`[timber] cache value for key "${cacheKey}" contains ${types} — ` +
|
|
23
|
+
'these types lose fidelity through JSON serialization in Redis/KV cache handlers. ' +
|
|
24
|
+
'Date becomes an ISO string, Map/Set become {}, BigInt throws. ' +
|
|
25
|
+
'The MemoryCacheHandler preserves them. Consider transforming values ' +
|
|
26
|
+
'to JSON-safe types before caching, or use MemoryCacheHandler for ' +
|
|
27
|
+
'values that require type preservation.'
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function findLossyTypes(value: unknown, seen: Set<unknown>, depth: number): Set<string> {
|
|
32
|
+
const lossy = new Set<string>();
|
|
33
|
+
if (depth > 8 || value === null || value === undefined) return lossy;
|
|
34
|
+
if (typeof value === 'bigint') {
|
|
35
|
+
lossy.add('BigInt');
|
|
36
|
+
return lossy;
|
|
37
|
+
}
|
|
38
|
+
if (typeof value !== 'object' && typeof value !== 'function') return lossy;
|
|
39
|
+
if (seen.has(value)) return lossy;
|
|
40
|
+
seen.add(value);
|
|
41
|
+
|
|
42
|
+
if (value instanceof Date) {
|
|
43
|
+
lossy.add('Date');
|
|
44
|
+
return lossy;
|
|
45
|
+
}
|
|
46
|
+
if (value instanceof Map) {
|
|
47
|
+
lossy.add('Map');
|
|
48
|
+
return lossy;
|
|
49
|
+
}
|
|
50
|
+
if (value instanceof Set) {
|
|
51
|
+
lossy.add('Set');
|
|
52
|
+
return lossy;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (Array.isArray(value)) {
|
|
56
|
+
for (const item of value) {
|
|
57
|
+
for (const t of findLossyTypes(item, seen, depth + 1)) lossy.add(t);
|
|
58
|
+
if (lossy.size === LOSSY_TYPES.length) return lossy;
|
|
59
|
+
}
|
|
60
|
+
return lossy;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const k of Object.keys(value as Record<string, unknown>)) {
|
|
64
|
+
for (const t of findLossyTypes((value as Record<string, unknown>)[k], seen, depth + 1)) {
|
|
65
|
+
lossy.add(t);
|
|
66
|
+
}
|
|
67
|
+
if (lossy.size === LOSSY_TYPES.length) return lossy;
|
|
68
|
+
}
|
|
69
|
+
return lossy;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Reset warning state — for tests only. */
|
|
73
|
+
export function _resetLossyWarning(): void {
|
|
74
|
+
hasWarned = false;
|
|
75
|
+
}
|
|
@@ -1,16 +1,132 @@
|
|
|
1
1
|
import type { CacheHandler } from './index';
|
|
2
|
+
import { warnLossyJsonValue } from './json-lossy-check.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* Minimal Redis client
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Minimal Redis client contract for `RedisCacheHandler`.
|
|
6
|
+
*
|
|
7
|
+
* This is deliberately NOT the native shape of any client library. ioredis,
|
|
8
|
+
* node-redis v4, and @upstash/redis all disagree on TTL argument shapes
|
|
9
|
+
* (positional `'EX'` vs `{ EX }` vs `{ ex }`), method casing (`sadd` vs
|
|
10
|
+
* `sAdd`), and array handling in `del` — a contract that pattern-matches one
|
|
11
|
+
* client lets another silently drop the expiry (TIM-1030: node-redis ignored
|
|
12
|
+
* the positional `'EX'` and wrote keys with no TTL). Instead, TTL semantics
|
|
13
|
+
* are explicit in the signature and you adapt your client with a thin
|
|
14
|
+
* wrapper, so a mismatch is a type error rather than silent unbounded
|
|
15
|
+
* keyspace growth.
|
|
16
|
+
*
|
|
17
|
+
* @example ioredis
|
|
18
|
+
* ```ts
|
|
19
|
+
* import Redis from 'ioredis';
|
|
20
|
+
* const redis = new Redis(process.env.REDIS_URL);
|
|
21
|
+
* const client: RedisClient = {
|
|
22
|
+
* get: (k) => redis.get(k),
|
|
23
|
+
* set: (k, v, ttl) => redis.set(k, v, 'EX', ttl),
|
|
24
|
+
* expireNX: (k, s) => redis.expire(k, s, 'NX'),
|
|
25
|
+
* expireGT: (k, s) => redis.expire(k, s, 'GT'),
|
|
26
|
+
* del: (k) => redis.del(k),
|
|
27
|
+
* sadd: (k, ...m) => redis.sadd(k, ...m),
|
|
28
|
+
* srem: (k, ...m) => redis.srem(k, ...m),
|
|
29
|
+
* smembers: (k) => redis.smembers(k),
|
|
30
|
+
* ttl: (k) => redis.ttl(k),
|
|
31
|
+
* execMulti: async (ops) => {
|
|
32
|
+
* const p = redis.multi();
|
|
33
|
+
* for (const op of ops) {
|
|
34
|
+
* switch (op.op) {
|
|
35
|
+
* case 'set': p.set(op.key, op.value, 'EX', op.ttlSeconds); break;
|
|
36
|
+
* case 'sadd': p.sadd(op.key, ...op.members); break;
|
|
37
|
+
* case 'expireNX': p.expire(op.key, op.seconds, 'NX'); break;
|
|
38
|
+
* case 'expireGT': p.expire(op.key, op.seconds, 'GT'); break;
|
|
39
|
+
* case 'del': p.del(op.key); break;
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* await p.exec();
|
|
43
|
+
* },
|
|
44
|
+
* };
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example node-redis v4
|
|
48
|
+
* ```ts
|
|
49
|
+
* import { createClient } from 'redis';
|
|
50
|
+
* const redis = createClient({ url: process.env.REDIS_URL });
|
|
51
|
+
* await redis.connect();
|
|
52
|
+
* const client: RedisClient = {
|
|
53
|
+
* get: (k) => redis.get(k),
|
|
54
|
+
* set: (k, v, ttl) => redis.set(k, v, { EX: ttl }),
|
|
55
|
+
* expireNX: (k, s) => redis.expire(k, s, 'NX'),
|
|
56
|
+
* expireGT: (k, s) => redis.expire(k, s, 'GT'),
|
|
57
|
+
* del: (k) => redis.del(k),
|
|
58
|
+
* sadd: (k, ...m) => redis.sAdd(k, m),
|
|
59
|
+
* srem: (k, ...m) => redis.sRem(k, m),
|
|
60
|
+
* smembers: (k) => redis.sMembers(k),
|
|
61
|
+
* ttl: (k) => redis.ttl(k),
|
|
62
|
+
* };
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example @upstash/redis
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { Redis } from '@upstash/redis';
|
|
68
|
+
* // automaticDeserialization must be off: the handler stores JSON strings
|
|
69
|
+
* // and parses them itself — auto-parsing would hand back objects.
|
|
70
|
+
* const redis = new Redis({ url, token, automaticDeserialization: false });
|
|
71
|
+
* const client: RedisClient = {
|
|
72
|
+
* get: (k) => redis.get(k),
|
|
73
|
+
* set: (k, v, ttl) => redis.set(k, v, { ex: ttl }),
|
|
74
|
+
* expireNX: (k, s) => redis.expire(k, s, 'NX'),
|
|
75
|
+
* expireGT: (k, s) => redis.expire(k, s, 'GT'),
|
|
76
|
+
* del: (k) => redis.del(k),
|
|
77
|
+
* sadd: (k, ...m) => redis.sadd(k, m[0], ...m.slice(1)),
|
|
78
|
+
* srem: (k, ...m) => redis.srem(k, m[0], ...m.slice(1)),
|
|
79
|
+
* smembers: (k) => redis.smembers(k),
|
|
80
|
+
* ttl: (k) => redis.ttl(k),
|
|
81
|
+
* };
|
|
82
|
+
* ```
|
|
7
83
|
*/
|
|
84
|
+
export type RedisWriteOp =
|
|
85
|
+
| { op: 'set'; key: string; value: string; ttlSeconds: number }
|
|
86
|
+
| { op: 'sadd'; key: string; members: string[] }
|
|
87
|
+
| { op: 'expireNX'; key: string; seconds: number }
|
|
88
|
+
| { op: 'expireGT'; key: string; seconds: number }
|
|
89
|
+
| { op: 'del'; key: string };
|
|
90
|
+
|
|
8
91
|
export interface RedisClient {
|
|
92
|
+
/** `GET key` — the stored string, or null when absent. */
|
|
9
93
|
get(key: string): Promise<string | null>;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
94
|
+
/**
|
|
95
|
+
* `SET key value EX ttlSeconds` — store with an expiry. The TTL is a
|
|
96
|
+
* required positional argument so no adapter can forget it.
|
|
97
|
+
*/
|
|
98
|
+
set(key: string, value: string, ttlSeconds: number): Promise<unknown>;
|
|
99
|
+
/**
|
|
100
|
+
* `EXPIRE key seconds NX` — set the TTL only if the key has no existing
|
|
101
|
+
* expiry (Redis 7.0+). Used to set the initial TTL on new tag sets.
|
|
102
|
+
*/
|
|
103
|
+
expireNX(key: string, seconds: number): Promise<unknown>;
|
|
104
|
+
/**
|
|
105
|
+
* `EXPIRE key seconds GT` — update the TTL only if the new value is greater
|
|
106
|
+
* than the current one (Redis 7.0+). Used to extend tag set TTLs without
|
|
107
|
+
* allowing a short-TTL writer to shrink them.
|
|
108
|
+
*/
|
|
109
|
+
expireGT(key: string, seconds: number): Promise<unknown>;
|
|
110
|
+
/** `DEL key` — delete a single key. Multi-key deletes loop per key. */
|
|
111
|
+
del(key: string): Promise<unknown>;
|
|
112
|
+
/** `SADD key member [member ...]` — add members to a set. */
|
|
113
|
+
sadd(key: string, ...members: string[]): Promise<unknown>;
|
|
114
|
+
/** `SREM key member [member ...]` — remove members from a set. */
|
|
115
|
+
srem(key: string, ...members: string[]): Promise<unknown>;
|
|
116
|
+
/** `SMEMBERS key` — all members of a set. */
|
|
13
117
|
smembers(key: string): Promise<string[]>;
|
|
118
|
+
/**
|
|
119
|
+
* `TTL key` — remaining time-to-live in seconds. Returns -2 if the key does
|
|
120
|
+
* not exist, -1 if the key exists but has no expiry.
|
|
121
|
+
*/
|
|
122
|
+
ttl(key: string): Promise<number>;
|
|
123
|
+
/**
|
|
124
|
+
* Execute a batch of write operations atomically via `MULTI/EXEC`.
|
|
125
|
+
* When provided, `set()` uses this to make tag-index writes and the data
|
|
126
|
+
* write atomic — no `invalidate({tag})` can interleave. Optional: when
|
|
127
|
+
* absent, operations run sequentially (correct but not race-free).
|
|
128
|
+
*/
|
|
129
|
+
execMulti?(ops: RedisWriteOp[]): Promise<void>;
|
|
14
130
|
}
|
|
15
131
|
|
|
16
132
|
const KEY_PREFIX = 'timber:cache:';
|
|
@@ -23,8 +139,9 @@ const TAG_PREFIX = 'timber:tag:';
|
|
|
23
139
|
* invalidations. Tag-based invalidation uses Redis Sets to track which keys
|
|
24
140
|
* belong to which tags.
|
|
25
141
|
*
|
|
26
|
-
* Bring your own Redis client
|
|
27
|
-
* interface
|
|
142
|
+
* Bring your own Redis client wrapped to the {@link RedisClient} contract —
|
|
143
|
+
* see the adapter examples on the interface for ioredis, node-redis v4, and
|
|
144
|
+
* @upstash/redis.
|
|
28
145
|
*/
|
|
29
146
|
export class RedisCacheHandler implements CacheHandler {
|
|
30
147
|
private client: RedisClient;
|
|
@@ -52,26 +169,71 @@ export class RedisCacheHandler implements CacheHandler {
|
|
|
52
169
|
return { value: entry.value, stale };
|
|
53
170
|
}
|
|
54
171
|
|
|
55
|
-
async set(
|
|
172
|
+
async set(
|
|
173
|
+
key: string,
|
|
174
|
+
value: unknown,
|
|
175
|
+
opts: { ttl: number; tags: string[]; generation?: number }
|
|
176
|
+
): Promise<void> {
|
|
177
|
+
warnLossyJsonValue(value, key);
|
|
56
178
|
const ck = this.cacheKey(key);
|
|
57
179
|
const expiresAt = Date.now() + opts.ttl * 1000;
|
|
58
|
-
|
|
180
|
+
|
|
181
|
+
// Serialize upfront so BigInt/non-serializable errors throw before any
|
|
182
|
+
// writes — prevents tag indexes pointing at stale data from a prior set().
|
|
183
|
+
const payload = JSON.stringify({ value, expiresAt, tags: opts.tags });
|
|
59
184
|
|
|
60
185
|
// Redis TTL with generous margin beyond the logical TTL to allow SWR reads
|
|
61
186
|
// on stale entries. The logical staleness is determined by expiresAt.
|
|
62
187
|
// We use 2x TTL + 60s as the Redis expiry so stale entries remain
|
|
63
188
|
// available for SWR background refetches.
|
|
64
189
|
const redisTtlSeconds = Math.max(opts.ttl * 2 + 60, 120);
|
|
65
|
-
await this.client.set(ck, payload, 'EX', redisTtlSeconds);
|
|
66
190
|
|
|
67
|
-
|
|
191
|
+
const writeOps: RedisWriteOp[] = [];
|
|
68
192
|
for (const tag of opts.tags) {
|
|
69
|
-
|
|
193
|
+
writeOps.push({ op: 'sadd', key: this.tagKey(tag), members: [key] });
|
|
194
|
+
writeOps.push({ op: 'expireNX', key: this.tagKey(tag), seconds: redisTtlSeconds });
|
|
195
|
+
writeOps.push({ op: 'expireGT', key: this.tagKey(tag), seconds: redisTtlSeconds });
|
|
196
|
+
}
|
|
197
|
+
writeOps.push({ op: 'set', key: ck, value: payload, ttlSeconds: redisTtlSeconds });
|
|
198
|
+
|
|
199
|
+
if (this.client.execMulti) {
|
|
200
|
+
await this.client.execMulti(writeOps);
|
|
201
|
+
} else {
|
|
202
|
+
for (const op of writeOps) {
|
|
203
|
+
await this.execOp(op);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private async execOp(op: RedisWriteOp): Promise<void> {
|
|
209
|
+
switch (op.op) {
|
|
210
|
+
case 'set':
|
|
211
|
+
await this.client.set(op.key, op.value, op.ttlSeconds);
|
|
212
|
+
break;
|
|
213
|
+
case 'sadd':
|
|
214
|
+
await this.client.sadd(op.key, ...op.members);
|
|
215
|
+
break;
|
|
216
|
+
case 'expireNX':
|
|
217
|
+
await this.client.expireNX(op.key, op.seconds);
|
|
218
|
+
break;
|
|
219
|
+
case 'expireGT':
|
|
220
|
+
await this.client.expireGT(op.key, op.seconds);
|
|
221
|
+
break;
|
|
222
|
+
case 'del':
|
|
223
|
+
await this.client.del(op.key);
|
|
224
|
+
break;
|
|
70
225
|
}
|
|
71
226
|
}
|
|
72
227
|
|
|
73
228
|
async invalidate(opts: { key?: string; tag?: string }): Promise<void> {
|
|
74
229
|
if (opts.key) {
|
|
230
|
+
const raw = await this.client.get(this.cacheKey(opts.key));
|
|
231
|
+
if (raw !== null) {
|
|
232
|
+
const entry = JSON.parse(raw) as { tags?: string[] };
|
|
233
|
+
if (entry.tags) {
|
|
234
|
+
await Promise.all(entry.tags.map((tag) => this.client.srem(this.tagKey(tag), opts.key!)));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
75
237
|
await this.client.del(this.cacheKey(opts.key));
|
|
76
238
|
}
|
|
77
239
|
|
|
@@ -79,13 +241,29 @@ export class RedisCacheHandler implements CacheHandler {
|
|
|
79
241
|
const tk = this.tagKey(opts.tag);
|
|
80
242
|
const keys = await this.client.smembers(tk);
|
|
81
243
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
244
|
+
// Re-check each member before deleting — the tag set can contain stale
|
|
245
|
+
// memberships from entries whose tags changed since they were added.
|
|
246
|
+
// Mirrors TagAwareCacheHandler's eager strategy (tag-aware-handler.ts:183-198).
|
|
247
|
+
await Promise.all(
|
|
248
|
+
keys.map(async (k) => {
|
|
249
|
+
const raw = await this.client.get(this.cacheKey(k));
|
|
250
|
+
if (raw === null) {
|
|
251
|
+
await this.client.srem(tk, k);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const entry = JSON.parse(raw) as { tags?: string[] };
|
|
255
|
+
if (entry.tags?.includes(opts.tag!)) {
|
|
256
|
+
await this.client.del(this.cacheKey(k));
|
|
257
|
+
}
|
|
258
|
+
await this.client.srem(tk, k);
|
|
259
|
+
})
|
|
260
|
+
);
|
|
86
261
|
|
|
87
|
-
// Clean up the tag set
|
|
88
|
-
await this.client.
|
|
262
|
+
// Clean up the now-empty tag set so it doesn't consume memory
|
|
263
|
+
const remaining = await this.client.smembers(tk);
|
|
264
|
+
if (remaining.length === 0) {
|
|
265
|
+
await this.client.del(tk);
|
|
266
|
+
}
|
|
89
267
|
}
|
|
90
268
|
}
|
|
91
269
|
}
|