/** Key-to-value map used by typed stores. */ export type StoreItemMap = Record; /** Result of an atomic store update. */ export type Change = { /** Leaves the value unchanged. */ op: 'noop'; /** Value returned by the update. */ result: result; } | { /** Replaces the stored value. */ op: 'set'; /** Value returned by the update. */ result: result; /** New stored value. */ value: value; } | { /** Deletes the stored value. */ op: 'delete'; /** Value returned by the update. */ result: result; }; /** Typed store with atomic read-modify-write support. */ export type AtomicStore = { /** Deletes a key. */ delete(key: key): Promise; /** Gets a typed value. */ get(key: key): Promise; /** Writes a typed value. */ put(key: key, value: itemMap[key]): Promise; /** Atomically updates a typed value. */ update(key: key, fn: (current: itemMap[key] | null) => Change): Promise; }; /** Minimal string store contract used by Tempo API internals. */ export type Store = { /** Deletes a key. */ delete(key: string): Promise; /** Deletes a key only when its value matches `expected`. */ deleteIf?: ((key: string, expected: null | string) => Promise) | undefined; /** Gets a string value. Returns `null` for missing or expired keys. */ get(key: string): Promise; /** * Optional native counter: increments an integer value and returns the new * count. A missing or expired key restarts at `1`; `ttl` applies like * {@link Store.put}. Implement when the backend can execute the * read-modify-write in one place (in-memory, inside a Durable Object); * consumers go through the {@link increment} helper, which falls back to a * get + put when this is absent. */ increment?: ((key: string, options?: Store.PutOptions) => Promise) | undefined; /** Lists keys. */ list(options?: { /** Restrict results to keys with this prefix. */ prefix?: string | undefined; }): Promise<{ /** Matching keys. */ keys: readonly { /** Key name. */ name: string; }[]; }>; /** Writes a string value, optionally with a time-to-live. */ put(key: string, value: string, options?: Store.PutOptions): Promise; /** * Optional atomic compare-and-swap: writes `next` only when the current * value equals `expected` (`null` = only-if-absent) and reports whether the * write happened. Implement when the backend can execute the compare and * write in one place (in-memory, inside a Durable Object); consumers go * through the {@link update} helper, which falls back to a get + put when * this is absent. */ swap?: ((key: string, expected: null | string, next: string, options?: Store.PutOptions) => Promise) | undefined; /** * Store kind discriminant. `'state'` marks an authoritative, enumerable * store ({@link State}); `'cache'` marks a cache (e.g. the Web Cache, * which cannot enumerate keys and silently drops entries). */ type: Store.Type; }; export declare namespace Store { /** Store kind: `'state'` (authoritative, enumerable) or `'cache'` (a cache). */ type Type = 'state' | 'cache'; /** Options for writing a value to a store. */ type PutOptions = { /** * Time-to-live in milliseconds. After this duration the key is treated as * absent. Production backends should map this to native expiration * (Redis `PEXPIRE`, Cloudflare `expirationTtl`, etc.). */ ttl?: number | undefined; }; } /** * An authoritative, enumerable {@link Store} for stateful features (webhook * subscriptions, rate-limit counters, …). Discriminated by `type: 'state'` so * stateful features can require it at the type level and reject cache adapters * like the Web Cache ({@link cache}, `type: 'cache'`), which cannot enumerate * keys and silently drops entries on eviction. `memory`, `cloudflareKv`, and * `durableObject` produce it. */ export type State = Store & { type: 'state'; }; /** Authoritative string state that also supports typed atomic operations. */ export type AtomicState = AtomicStore & State; /** * Wraps store operations into a {@link Store}, defaulting to an authoritative * {@link State} store. Omit `type` for the common authoritative case; pass * `type: 'cache'` to opt into a cache-kind store (non-enumerable, lossy — e.g. * the Web Cache). */ export declare function from(store: store): from.Output; export declare namespace from { /** Store operations with an optional kind discriminant (defaults to `'state'`). */ type Input = Omit & { /** Store kind; defaults to `'state'`. Pass `'cache'` for a cache-kind store. */ type?: Store.Type | undefined; }; /** Resolved store kind: {@link State} unless `type: 'cache'` is provided. */ type Output = store extends { type: 'cache'; } ? Store : State; } /** * Increments an integer counter on a store and returns the new value. A * missing or expired key restarts at `1`; `ttl` applies like {@link Store.put}. * * Uses the store's native {@link Store.increment} when implemented (atomic * where the backend executes it in one place — in-memory, inside a Durable * Object). Otherwise falls back to a get + put read-modify-write, which * costs two round trips on remote stores and can race under concurrency — * fine for dev/in-process backends, not for enforced distributed counters. */ export declare function increment(store: Store, key: string, options?: Store.PutOptions): Promise; /** * Atomically transforms a value on a store: reads the current value, applies * `fn`, and writes the result, returning the written value. * * Uses the store's native {@link Store.swap} compare-and-swap when implemented, * re-running `fn` on contention (optimistic concurrency, bounded by * `attempts`). Otherwise falls back to a get + put read-modify-write, which * can lose concurrent writes — fine for dev/in-process backends, not for * contended distributed state. */ export declare function update(store: Store, key: string, fn: (current: null | string) => string, options?: update.Options): Promise; export declare namespace update { /** Options for {@link update}. */ type Options = Store.PutOptions & { /** * Maximum compare-and-swap attempts before failing with * {@link UpdateContentionError}. * @default 8 */ attempts?: number | undefined; }; } /** Atomically applies a typed state transition without a get-and-put fallback. */ export declare function change(state: State, key: string, fn: (current: null | string) => Change, options?: change.Options): Promise; export declare namespace change { /** Options for one atomic state transition. */ type Options = update.Options; } /** Creates an in-memory store with TTL support. */ export declare function memory(options?: memory.Options): State; export declare namespace memory { /** Options for creating an in-memory store. */ type Options = { /** Initial entries. */ entries?: readonly (readonly [string, string])[] | undefined; }; } /** * Creates a store backed by a Web Cache API instance (e.g. Cloudflare's * colo-local `caches.default`). Values are stored as cache entries keyed by a * synthetic URL, with `ttl` mapped to `Cache-Control: max-age`. The Web Cache * cannot enumerate keys, so `list` returns no keys — use this for caching * (get/put/delete) only, e.g. the origin read cache and edge response cache. */ export declare function cache(webCache: cache.Cache): Store; export declare namespace cache { /** Minimal Web Cache API surface used by this adapter. */ type Cache = { /** Deletes a cache entry. */ delete(request: Request | string): Promise; /** Looks up a cache entry. */ match(request: Request | string): Promise; /** Stores a cache entry. */ put(request: Request | string, response: Response): Promise; }; } /** Creates a store backed by a Cloudflare Workers KV namespace. */ export declare function cloudflareKv(namespace: cloudflareKv.Namespace): State; export declare namespace cloudflareKv { /** Minimal Cloudflare Workers KV namespace shape used by this adapter. */ type Namespace = { /** Deletes a key. */ delete(key: string): Promise; /** Gets a text value. */ get(key: string): Promise; /** Lists keys. */ list(options?: { /** Restrict results to keys with this prefix. */ prefix?: string | undefined; /** Continue from a previous page. */ cursor?: string | undefined; }): Promise<{ /** Matching keys. */ keys: readonly { /** Key name. */ name: string; }[]; /** Whether every matching key was returned. */ list_complete: boolean; /** Cursor for the next page. */ cursor?: string | undefined; }>; /** Writes a text value. */ put(key: string, value: string, options?: { /** Native Cloudflare KV TTL in seconds. */ expirationTtl?: number | undefined; }): Promise; }; } /** Creates typed atomic state over namespace RPC, or raw object storage state. */ export declare function durableObject(namespace: durableObject.Namespace): durableObject.ReturnValue; export declare function durableObject(namespace: durableObject.Namespace, options: durableObject.Options): durableObject.ReturnValue; export declare function durableObject(namespace: durableObject.Namespace): AtomicState; export declare function durableObject(namespace: durableObject.Namespace, options: durableObject.Options): AtomicState; export declare function durableObject(storage: durableObject.Storage): State; export declare namespace durableObject { /** Durable Object state assignable to any typed item map. */ type ReturnValue = State & { /** Gets a contextually typed value. */ get(key: string): Promise; /** Writes a typed value. */ put(key: string, value: value, options?: Store.PutOptions): Promise; /** Atomically updates a contextually typed value. */ update(key: string, fn: (current: value | null) => Change): Promise; }; /** Minimal Durable Object namespace shape used by this adapter. */ type Namespace = { /** Gets the Durable Object stub for a stable object name. */ getByName(name: string): Stub; }; /** Options for creating a store from a Durable Object namespace. */ type Options = { /** Static pins all keys; a resolver shards them; omission shards by key. */ name?: string | ((key: string) => string) | undefined; }; /** Minimal Cloudflare Durable Object storage shape used by this adapter. */ type Storage = { /** Deletes a key. */ delete(key: string): Promise; /** Gets a stored value. */ get(key: string): Promise; /** Lists stored values. */ list(options?: { /** Restrict results to keys with this prefix. */ prefix?: string | undefined; }): Promise>; /** Writes a stored value. */ put(key: string, value: value): Promise; }; /** RPC store operations used by the namespace adapter. */ type Stub = Omit & { /** Atomically deletes a matching value inside the object. */ deleteIf(key: string, expected: null | string): Promise; /** Atomically increments an integer counter inside the object. */ increment(key: string, options?: Store.PutOptions): Promise; /** Atomically compares-and-swaps a value inside the object. */ swap(key: string, expected: null | string, next: string, options?: Store.PutOptions): Promise; }; } /** Associates request cache directives with a store used by request handlers. */ export declare function withRequest(store: Store, request: withRequest.Request, options?: withRequest.Options): Store; export declare namespace withRequest { /** Request-scoped cache behavior. */ type Options = { /** Keeps asynchronous cache persistence alive after the response returns. */ waitUntil?: ((promise: Promise) => void) | undefined; }; /** Request surface needed to read cache directives. */ type Request = { /** Reads one request header. */ header(name: string): string | undefined; }; } /** * Returns a cached value when present. Otherwise, runs `fetch` and stores its * result unless undefined or rejected by `shouldCache`. Cache persistence is * best-effort and never delays the fetched value. */ export declare function memoize(fetch: (signal?: AbortSignal) => Promise, options: memoize.Options): Promise; export declare namespace memoize { /** Options for {@link memoize}. */ type Options = { /** Maximum shared cache-miss flight duration in milliseconds. Defaults to 15 seconds. */ flightTimeout?: number | undefined; /** Cache key. Callers are responsible for namespacing/versioning. */ key: string; /** Returns whether a fetched value should be stored. Single-flight callers still share it. */ shouldCache?: ((value: value) => boolean) | undefined; /** Store used to persist cache entries. */ store: Store; /** Time-to-live in milliseconds. */ ttl: number; }; } /** Thrown when a shared memoized cache-miss flight exceeds its configured deadline. */ export declare class MemoizeTimeoutError extends Error { name: string; constructor(timeout: number); } /** Thrown when {@link update} exhausts its compare-and-swap attempts. */ export declare class UpdateContentionError extends Error { name: string; constructor(key: string, attempts: number); } /** Thrown when Durable Object state uses an unsupported codec. */ export declare class DurableObjectCodecError extends Error { name: string; constructor(version: unknown); } //# sourceMappingURL=Store.d.ts.map