npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@paykernel/store-redis

v0.1.1

Published

Redis/Valkey/Upstash stores for PayKernel lease-aware idempotency, webhook inbox, and reconciliation coordination.

Readme

@paykernel/store-redis

Redis / Valkey / Upstash stores for @paykernel/core lease-aware idempotency, webhook inbox, and reconciliation coordination (Phase 13).

Optional infrastructure. Redis is not required to use the SDK. Prefer PostgreSQL/D1/Turso when you already have durable SQL, or hybrid: Redis for claims/leases + SQL for long-term audit. PostgreSQL alone (@paykernel/store-postgres) can satisfy all Phase 9 contracts.

Install

bun add @paykernel/store-redis
# optional drivers (pick a binding):
bun add ioredis
# or
bun add redis
# or
bun add @upstash/redis
# Bun native Redis needs no npm peer — use the /bun subpath

Quick start (driver-free root)

import {
  createRedisIdempotencyStore,
  type RedisCommandPort,
} from "@paykernel/store-redis";

const port: RedisCommandPort = {
  async send(command, args) {
    // adapt any client that can run EVAL / HGETALL / ZRANGE …
    return client.send(command, args);
  },
};

const store = createRedisIdempotencyStore({ port });
const r = await store.reserve({
  key: "pay_123",
  fingerprint: "fp",
  owner: "worker-1",
  leaseMs: 30_000,
});

Driver subpaths

Root entry never statically imports optional drivers:

| Subpath | Package / runtime | Notes | |---------|-------------------|--------| | @paykernel/store-redis/bun | Bun.RedisClient (runtime-provided) | Prefer injected client; createBunRedisFromEnv / URL are convenience only. Rejects Cluster/Sentinel/clusterKeys. Uses send() for EVAL. | | @paykernel/store-redis/upstash | @upstash/redis | HTTP REST — serverless latency; EVAL still server-side Lua. | | @paykernel/store-redis/ioredis | ioredis | Prefer enableOfflineQueue: false (IOREDIS_STORE_CLIENT_DEFAULTS). Cluster + keys.clusterKeys. | | @paykernel/store-redis/node-redis | redis (node-redis) | Prefer disableOfflineQueue: true (NODE_REDIS_STORE_CLIENT_DEFAULTS). Cluster + hash tags. |

import {
  createRedisStoresFromBun,
  createBunRedisCommandPort,
} from "@paykernel/store-redis/bun";

// preferred: inject client
const stores = createRedisStoresFromBun({ redis: { client } });

// convenience only:
// createRedisStoresFromBun({ redis: { url: process.env.REDIS_URL! } });
// createRedisStoresFromBun({ redis: { fromEnv: true } });

Example (ioredis):

import Redis from "ioredis";
import { createRedisStoresFromIoredis } from "@paykernel/store-redis/ioredis";

const client = new Redis(process.env.PAYMENTS_SDK_REDIS_URL!, {
  enableOfflineQueue: false,
});
const stores = createRedisStoresFromIoredis({ client });

Full binding examples: docs/drivers.md.

Guarantees (honest)

| Axis | Value | |------|--------| | Coordination | multi-host when all workers share one Redis/Valkey | | Claims | strong (atomic Lua; never get-then-set) | | Durability | configuration-dependent (AOF/RDB / cloud persistence) | | Audit store | not the sole long-term audit store by default |

Four durability distinctions:

  1. Coordination-safe — multi-worker claims while Redis is up.
  2. Durable across process restart — keys still in Redis after app restart.
  3. Durable across Redis restart — only with correct AOF/RDB (or managed persistence).
  4. Only-audit-storenot recommended; hybrid with PostgreSQL/D1/Turso for history.

See docs/guarantees.md and docs/persistence.md.

Design notes

  • Injectable clock: now is passed as Lua ARGV so FakeClock conformance works.
  • generation++ + unguessable leaseToken on reserve/claim/renew.
  • Indeterminate idempotency rows block reserve (A4); deleteExpired never removes them by default.
  • Do not use Pub/Sub for webhook delivery correctness or retries.
  • Bun binding rejects Cluster / Sentinel configuration and clusterKeys: true.
  • Disable / control offline command queues for correctness-critical ops.
  • Does not depend on internal/sql-store (Redis is not relational).

Testing

# unit tests (no live Redis) — live suites skip cleanly
bun test packages/store-redis

# optional local Redis 7.2
docker compose -f packages/store-redis/docker-compose.yml up -d

# live integration / conformance (must run and pass when set)
export PAYMENTS_SDK_REDIS_URL=redis://127.0.0.1:33027
# or REDIS_URL / VALKEY_URL (prefer PAYMENTS_SDK_REDIS_URL)
bun test packages/store-redis

Live suites cover three-store conformance + FakeClock, multi-client concurrent claims, lease reclaim/stale token, deleteExpired, INFO server version, and binding parity (unit).

Details: docs/testing.md.

Documentation

See monorepo docs/adapter-selection.md for the Phase 18 capability matrix and decision tree.

| Doc | Topic | | --- | ----- | | docs/overview.md | Purpose, optional Redis, subpaths | | docs/crash-boundaries.md | Crash / reclaim / Redis restart | | docs/drivers.md | /bun /upstash /ioredis /node-redis | | docs/scripts-atomicity.md | Lua, tagged results, now ARGV | | docs/key-design.md | Prefixes, tenants, hash tags, TTL | | docs/persistence.md | Four durability distinctions | | docs/hybrid-examples.md | Hybrid and no-Redis scenarios | | docs/testing.md | Env, docker-compose, conformance | | docs/guarantees.md | REDIS_STORAGE_ADAPTER_MANIFEST | | store-contracts.md | Phase 9 contracts |

License

MIT