TieredStore

@atiproto/edge-resolver-cache

Implements SimpleStore by composing two stores into a read-through L1/L2 cache. On a cache miss, L2 is checked and a hit populates L1. Writes go to both tiers.

Constructor

typescript
new TieredStore<K, V>(l1: SimpleStore<K, V>, l2: SimpleStore<K, V>)
ParameterTypeDescription
l1SimpleStore<K, V>The fast, short-lived tier. Typically a SimpleStoreMemory instance. Checked first on reads.
l2SimpleStore<K, V>The durable, slower tier. Typically a CacheApiStore instance. Checked on L1 miss; results are backfilled to L1.

Read-Through Behavior

On get(key):

  1. Check L1 — return immediately on hit.
  2. Check L2 on L1 miss — backfill L1 and return on hit.
  3. Return undefined on L2 miss.

On set(key, value) and del(key): both tiers are written concurrently.

Example

typescript
import { CacheApiStore, TieredStore } from "@atiproto/edge-resolver-cache";
import { SimpleStoreMemory } from "@atproto-labs/simple-store-memory";
const tiered = new TieredStore(
new SimpleStoreMemory({ max: 1000, ttl: 3_600_000 }), // L1: 1hr, 1000 entries
new CacheApiStore({ prefix: "did:", ttlSeconds: 86400 }), // L2: 24hrs
);
await tiered.set("did:plc:abc123", didDocument);
const doc = await tiered.get("did:plc:abc123"); // hits L1

Factory Functions

For the common case of caching DID documents or handles, use the built-in factories which return pre-configured TieredStore instances:

typescript
import { createDidCache, createHandleCache } from "@atiproto/edge-resolver-cache";
// TieredStore with sane defaults for DID doc caching
const didCache = createDidCache({ cacheName: "my-cache" });
// TieredStore with sane defaults for handle caching
const handleCache = createHandleCache({ cacheName: "my-cache" });