Files
skills/docs/foundation/flow/idempotency/README.md
2026-05-29 08:20:56 +01:00

14 KiB

@suaveplan/idempotency - Idempotency key guard and dedup: store adapters (memory, database, redis), distributed locking, middleware, key generation, metrics, OTel instrumentation.

Summary

Idempotency key guard and deduplication for async operations. The package provides a complete pending → completed | failed state machine, three store backends (memory, database, Redis), distributed locking across multiple processes, request middleware, key generation with payload fingerprinting, version history management, and OTel metrics instrumentation. It is designed to protect any operation that must not execute more than once per request — payment charges, email sends, record creation — regardless of retries or race conditions.

Documentation tree

  • distributed-guard — Provides distributed idempotency protection via a pluggable LockProvider that serializes concurrent access across mul…
  • redis-lock-provider — Provides a Redis-backed implementation of the LockProvider interface using atomic SET NX (set-if-not-exists) operat…
  • error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…
    • error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…
  • errors — (no submodules)
  • guard — (no submodules)
  • key — (no submodules)
  • metrics — (no submodules)
  • middleware — (no submodules)
  • database-store — Provides a persistent IdempotencyStoreAdapter<T> backed by any relational database via the `IdempotencyDatabaseAdapte…
  • memory-store — Provides an in-memory implementation of IdempotencyStoreAdapter<T> backed by a Map. It is the default store for uni…
  • redis-store — Provides a Redis-backed IdempotencyStoreAdapter<T> with automatic key expiration using Redis native TTL. By accepting…
  • versioning — (no submodules)
- [idempotency-error](./src/errors/idempotency-error.md) — _(no submodules)_- [guard](./src/guard/idempotency-guard.md) — _(no submodules)_- [idempotency-guard](./src/guard/idempotency-guard.md) — _(no submodules)_- [key](./src/key/key-generator.md) — _(no submodules)_- [key-generator](./src/key/key-generator.md) — _(no submodules)_- [metrics](./src/metrics/idempotency-metrics.md) — _(no submodules)_- [idempotency-metrics](./src/metrics/idempotency-metrics.md) — _(no submodules)_- [middleware](./src/middleware/idempotency-middleware.md) — _(no submodules)_- [idempotency-middleware](./src/middleware/idempotency-middleware.md) — _(no submodules)_- [database-store](./src/store/database-store.md) — Provides a persistent `IdempotencyStoreAdapter` backed by any relational database via the `IdempotencyDatabaseAdapte…
  • memory-store — Provides an in-memory implementation of IdempotencyStoreAdapter<T> backed by a Map. It is the default store for uni…
  • redis-store — Provides a Redis-backed IdempotencyStoreAdapter<T> with automatic key expiration using Redis native TTL. By accepting…
  • versioning — (no submodules)- key-versioning — (no submodules)- error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…
  • idempotency-error — (no submodules)- guard — (no submodules)- idempotency-guard — (no submodules)- key — (no submodules)- key-generator — (no submodules)- metrics — (no submodules)- idempotency-metrics — (no submodules)- middleware — (no submodules)- idempotency-middleware — (no submodules)- database-store — Provides a persistent IdempotencyStoreAdapter<T> backed by any relational database via the `IdempotencyDatabaseAdapte…
  • memory-store — Provides an in-memory implementation of IdempotencyStoreAdapter<T> backed by a Map. It is the default store for uni…
  • redis-store — Provides a Redis-backed IdempotencyStoreAdapter<T> with automatic key expiration using Redis native TTL. By accepting…
  • versioning — (no submodules)- key-versioning — (no submodules)- error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…
  • idempotency-error — (no submodules)- guard — (no submodules)- idempotency-guard — (no submodules)- key — (no submodules)- key-generator — (no submodules)- metrics — (no submodules)- idempotency-metrics — (no submodules)- middleware — (no submodules)- idempotency-middleware — (no submodules)- database-store — Provides a persistent IdempotencyStoreAdapter<T> backed by any relational database via the `IdempotencyDatabaseAdapte…
  • memory-store — Provides an in-memory implementation of IdempotencyStoreAdapter<T> backed by a Map. It is the default store for uni…
  • redis-store — Provides a Redis-backed IdempotencyStoreAdapter<T> with automatic key expiration using Redis native TTL. By accepting…
  • versioning — (no submodules)- key-versioning — (no submodules)- error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…
  • idempotency-error — (no submodules)- guard — (no submodules) - idempotency-guard — (no submodules)- key — (no submodules) - key-generator — (no submodules)- metrics — (no submodules) - idempotency-metrics — (no submodules)- middleware — (no submodules) - idempotency-middleware — (no submodules)- database-store — Provides a persistent IdempotencyStoreAdapter<T> backed by any relational database via the `IdempotencyDatabaseAdapte…
  • memory-store — Provides an in-memory implementation of IdempotencyStoreAdapter<T> backed by a Map. It is the default store for uni…
  • redis-store — Provides a Redis-backed IdempotencyStoreAdapter<T> with automatic key expiration using Redis native TTL. By accepting…
  • versioning — (no submodules) - key-versioning — (no submodules)- error-codes — Defines and registers all stable error codes and their HTTP/retry metadata for the @suaveplan/idempotency package. Ev…

Install

bun add @suaveplan/idempotency

Quick start

import { IdempotencyGuard } from "@suaveplan/idempotency/guard";
import { MemoryIdempotencyStore } from "@suaveplan/idempotency/store";

const guard = new IdempotencyGuard({
  store: new MemoryIdempotencyStore(),
  ttlMs: 3_600_000, // 1 hour
});

// First call: executes the handler and caches the result
const result = await guard.execute("order-42", () => createOrder(payload));

// Subsequent calls with the same key: return the cached result immediately
const again = await guard.execute("order-42", () => createOrder(payload));
// result === again — handler was not called again

// With payload fingerprinting and AbortSignal
const controller = new AbortController();
const safe = await guard.execute(
  "charge-99",
  () => chargeCard(payload),
  { input: payload, signal: controller.signal }
);

Modules

Module Description
src/guard/idempotency-guard.md IdempotencyGuard — single-node idempotency guard with full state machine, injectable clock, AbortSignal support, and OTel instrumentation
src/distributed/distributed-guard.md DistributedIdempotencyGuard — multi-node guard backed by a pluggable LockProvider; MemoryLockProvider for tests; RedisLockProvider for production
src/distributed/redis-lock-provider.md RedisLockProvider — Redis-backed distributed lock provider with TTL and exponential back-off
src/store/memory-store.md MemoryIdempotencyStore — in-memory store for tests and single-process deployments; lazy TTL expiration
src/store/database-store.md DatabaseIdempotencyStore — SQL-backed store via a generic IdempotencyDatabaseAdapter; auto-creates table; supports upsert
src/store/redis-store.md RedisIdempotencyStore — Redis-backed store with native key TTL and configurable namespace prefix
src/key/key-generator.md Key generation utilities: generateIdempotencyKey, compositeKey, fingerprintPayload, fingerprintPayloadAsync
src/middleware/idempotency-middleware.md createIdempotencyMiddleware — framework-agnostic middleware factory for Express, Fastify, Hono, or custom request types
src/metrics/idempotency-metrics.md IdempotencyMetrics — aggregate and rolling-window counters, OTel counter/histogram instruments, periodic reporter
src/versioning/key-versioning.md KeyVersioning — multi-version record management with reject, overwrite, and version conflict strategies
src/errors/idempotency-error.md Structured error hierarchy: IdempotencyConflictError, IdempotencyMismatchError, LockAcquisitionError, VersionConflictError
src/error-codes.md Stable IDEMPOTENCY.* error code registry