UNPKG

@karmaniverous/cached-axios

Version:

Tag‑aware caching for Axios: stable cache IDs, simple tag invalidation, and a drop‑in Orval mutator on top of axios‑cache‑interceptor.

105 lines (99 loc) 5.02 kB
import { AxiosRequestConfig, AxiosResponse } from 'axios'; export { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; import { z } from 'zod'; import * as axios_cache_interceptor from 'axios-cache-interceptor'; export { CacheProperties, CacheRequestConfig } from 'axios-cache-interceptor'; export { OrvalBodyType, OrvalErrorType, orvalMutator } from './mutators/orval.js'; /** * Branded cache key types produced by {@link buildConfig}. * - `Id` is used for cache keys (stable, resource-specific). * - `Tag` groups cache ids for invalidation (coarse-grained). */ type Id = string & { readonly __brand: 'Id'; }; type Tag = string & { readonly __brand: 'Tag'; }; /** * Input config schema for {@link buildConfig}. * - Nested objects; leaves are `undefined`. * - The resulting structure mirrors the input and adds `id()`/`tag()` at every node. */ declare const ConfigInputSchema: z.ZodType<Record<string, unknown>>; type ConfigInput = z.output<typeof ConfigInputSchema>; /** Segment types accepted by id/tag */ type Segment = string | number; type SegInput = Segment | Segment[] | undefined; /** Methods at every node */ type WithFns = { id: (seg?: SegInput) => Id; tag: (seg?: SegInput) => Tag; }; type Leaf = undefined; type Shape = { readonly [k: string]: Shape | Leaf; }; type BuiltNode<T, P extends string[]> = WithFns & (T extends undefined ? {} : { readonly [K in keyof T]: BuiltNode<T[K], [...P, Extract<K, string>]>; }); /** * Build a strongly-typed configuration object from a nested shape. * - Validates input with {@link ConfigInputSchema}. * - Every node exposes `id(seg?)` and `tag(seg?)` to generate colon-delimited keys. * - See tests for usage patterns. * * @typeParam T The nested shape type, e.g. `{ user: { byId: undefined } }`. * @param input Nested object whose leaves are `undefined`. * @returns A structure mirroring `input` with `id()` and `tag()` at each node. */ declare const buildConfig: <T extends Shape>(input: T) => BuiltNode<T, []>; /** * Execute a GET-like call with a stable cache id and tag registration. * - Merges any object-valued `base.cache` into the helper's cache config. * - Registers the cache id under the provided tags for future invalidation. * - Leaves response shape intact; caller validates payload type. * * @typeParam T Expected response data type. * @param call Function that performs the request (e.g., `cachedAxios.request`). * @param id Stable cache id to use for this resource. * @param tags Tags to associate with `id` for future invalidation. * @param base Optional Axios config; shallow-merged into the final request. * @returns The AxiosResponse with data typed as T. */ declare const withQuery: <T>(call: (opts: AxiosRequestConfig) => Promise<AxiosResponse<unknown>>, id: Id, tags: Tag[], base?: AxiosRequestConfig) => Promise<AxiosResponse<T>>; /** * Execute a write-like call with tag-based invalidation. * - Builds an `update` map that tells ACI to delete affected ids. * - Clears tag buckets in the in-memory index after the call. * - Leaves response shape intact; caller validates payload type. * * @typeParam T Expected response data type. * @param call Function that performs the request (e.g., `cachedAxios.request`). * @param invalidate Tags whose registered ids should be invalidated. * @param base Optional Axios config; shallow-merged into the final request. * @returns The AxiosResponse with data typed as T. */ declare const withMutation: <T>(call: (opts: AxiosRequestConfig) => Promise<AxiosResponse<unknown>>, invalidate: Tag[], base?: AxiosRequestConfig) => Promise<AxiosResponse<T>>; /** Cache-aware Axios instance used by helpers and the Orval mutator. */ declare const cachedAxios: axios_cache_interceptor.AxiosCacheInstance; /** * Base Axios configuration for helper factories. * - May be a static object, a factory returning a config (or undefined), * or `undefined` to opt out. */ type BaseInput = AxiosRequestConfig | (() => AxiosRequestConfig | undefined) | undefined; /** * Create pre-bound cache helpers with a base Axios config. * - `query(call, id, tags, options?)` delegates to {@link withQuery}. * - `mutation(call, invalidate, options?)` delegates to {@link withMutation}. * - Both helpers shallow-merge `options` over the resolved `base`. * * @param base Base Axios config or factory. * @returns An object with `query` and `mutation` helpers. */ declare const makeCacheHelpers: (base?: BaseInput) => { query: <T>(call: (opts: AxiosRequestConfig) => Promise<AxiosResponse<unknown>>, id: Id, tags: Tag[], options?: AxiosRequestConfig) => Promise<AxiosResponse<T>>; mutation: <T>(call: (opts: AxiosRequestConfig) => Promise<AxiosResponse<unknown>>, invalidate: Tag[], options?: AxiosRequestConfig) => Promise<AxiosResponse<T>>; }; export { ConfigInputSchema, buildConfig, cachedAxios, makeCacheHelpers, withMutation, withQuery }; export type { BaseInput, BuiltNode, ConfigInput, Id, SegInput, Segment, Shape, Tag, WithFns };