@warlock.js/cache 5.18.0 → 5.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,7 +4,13 @@ All notable changes to `@warlock.js/cache` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
- ## 5.17.0 (Unreleased)
7
+ ## 5.19.0 - 2026-09-23
8
+
9
+ ### Changed
10
+
11
+ - Refined package skill-discovery descriptions and regenerated the llms projections.
12
+
13
+ ## 5.17.0
8
14
 
9
15
  ### Changed
10
16
 
package/llms-full.txt CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  ---
10
10
  name: apply-cache-patterns
11
- description: 'Compose cache primitives into real-world patterns — remember() memoization, cross-node stampede protection via a distributed lock (onConflict: ''create''), negative caching, and per-tenant scoping. Triggers: `cache.remember`, `cache.set` with `onConflict: "create"`, `globalPrefix`; "memoize this function", "prevent cache stampede across nodes", "cache not-found results", "per-tenant cache scoping"; typical import `import { cache } from "@warlock.js/cache"`. Skip: counters — `@warlock.js/cache/use-cache-atomic/SKILL.md`; bulk get/set — `@warlock.js/cache/use-cache-bulk/SKILL.md`; TTL constants/utilities — `@warlock.js/cache/use-cache-utils/SKILL.md`; named lock wrapper — `@warlock.js/cache/use-cache-lock/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`.'
11
+ description: "Real-world caching patterns in @warlock.js/cache; use when you need to apply cache patterns."
12
12
  ---
13
13
 
14
14
  # Real-world caching patterns
@@ -109,7 +109,7 @@ await cache.tags([`tenant-${tenantId}`]).invalidate();
109
109
 
110
110
  ---
111
111
  name: cache-basics
112
- description: 'Start with @warlock.js/cache — the cache singleton, primary ops (set / get / pull / remove / many / forever / increment / remember), TTL shapes, init flow. Triggers: `cache`, `cache.setCacheConfigurations`, `cache.init`, `cache.set`, `cache.get`, `cache.remove`, `cache.remember`, `cache.flush`; "start with warlock cache", "wire up cache at startup", "which cache skill do I need"; typical import `import { cache } from "@warlock.js/cache"`. Skip: driver choice — `@warlock.js/cache/pick-cache-driver/SKILL.md`; set options — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`; native `Map`.'
112
+ description: "Start here for @warlock.js/cache drivers, key-value operations, and application cache configuration."
113
113
  ---
114
114
 
115
115
  # Cache basics
@@ -236,7 +236,7 @@ const user = await cache.remember("user.1", "1h", async () => db.users.find(1));
236
236
 
237
237
  ---
238
238
  name: configure-pg-cache
239
- description: 'Postgres cache driver setup — KV-only mode (default) or pgvector mode (opt in via options.pg.vector). Caller owns the pg.Pool, driver exposes driver.schema() for one-time DDL. Triggers: `PgCacheDriver`, `driver.schema`, `options.pg.vector`, `pg.Pool`, `hnsw`, `ivfflat`; "use Postgres as cache backend", "set up pgvector semantic cache", "DDL for warlock cache table"; typical import `import { cache, PgCacheDriver } from "@warlock.js/cache"`. Skip: cross-driver similarity API — `@warlock.js/cache/use-cache-similarity/SKILL.md`; driver picker — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `pg-mem`; raw `pg` / `node-postgres`.'
239
+ description: "pg cache driver — Postgres setup in @warlock.js/cache; use when you need to configure pg cache."
240
240
  ---
241
241
 
242
242
  # `pg` cache driver — Postgres setup
@@ -355,7 +355,7 @@ See [`@warlock.js/cache/handle-cache-errors/SKILL.md`](@warlock.js/cache/handle-
355
355
 
356
356
  ---
357
357
  name: configure-set-options
358
- description: 'Configure cache.set''s third argument — ttl, expiresAt, tags, onConflict (create / update / upsert), driver, vector. Triggers: `cache.set`, `ttl`, `expiresAt`, `tags`, `onConflict`, `driver`, `vector`, `CacheSetResult`, `wasSet`; "set a key only if missing", "set with absolute deadline", "attach tags inline", "route one cache call to redis"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag fluent API — `@warlock.js/cache/use-cache-tags/SKILL.md`; vector queries — `@warlock.js/cache/use-cache-similarity/SKILL.md`; competing libs `keyv`, `ioredis`.'
358
+ description: "The set options object in @warlock.js/cache; use when you need to configure set options."
359
359
  ---
360
360
 
361
361
  # The `set` options object
@@ -455,7 +455,7 @@ await cache.set("k", v, undefined); // same as no TTL
455
455
 
456
456
  ---
457
457
  name: handle-cache-errors
458
- description: 'Cache error classes — CacheError base, CacheConfigurationError, CacheConnectionError, CacheDriverNotInitializedError, CacheUnsupportedError, CacheConcurrencyError. Triggers: `CacheError`, `CacheConfigurationError`, `CacheConnectionError`, `CacheDriverNotInitializedError`, `CacheUnsupportedError`, `CacheConcurrencyError`; "catch cache errors at the boundary", "degrade when update or merge throws", "what does CacheUnsupportedError mean", "fall back when redis is down"; typical import `import { CacheError, CacheConfigurationError, CacheUnsupportedError } from "@warlock.js/cache"`. Skip: choosing a supported driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; observing errors via events — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs ignore — generic `Error` patterns.'
458
+ description: "Error classes in @warlock.js/cache; use when you need to handle cache errors."
459
459
  ---
460
460
 
461
461
  # Error classes
@@ -551,7 +551,7 @@ try {
551
551
 
552
552
  ---
553
553
  name: observe-cache
554
- description: 'Cache observability — cache.metrics() for aggregate hit rate / latency p50/p95/p99 + event bus (cache.on(''hit'' / ''miss'' / ''set'' / ''removed'' / ''flushed'' / ''expired'' / ''error'', ...)). Triggers: `cache.metrics`, `cache.resetMetrics`, `cache.on`, `hit`, `miss`, `removed`, `flushed`, `error`, `hitRate`, `latencyMs`; "show cache hit rate", "page on cache errors", "is my cache being hit", "export metrics to prometheus"; typical import `import { cache } from "@warlock.js/cache"`. Skip: error classes — `@warlock.js/cache/handle-cache-errors/SKILL.md`; competing libs `prom-client`, `statsd-client`.'
554
+ description: "Cache observability — cache.metrics() and the event bus in @warlock.js/cache; use when you need to observe cache."
555
555
  ---
556
556
 
557
557
  # Cache observability — `cache.metrics()` and the event bus
@@ -658,7 +658,7 @@ Drivers that never fire events stay absent from `byDriver` — guard with `?.` a
658
658
 
659
659
  ---
660
660
  name: overview
661
- description: 'Front-door orientation for `@warlock.js/cache` — multi-driver caching (memory / memoryExtended / lru / file / redis / pg / null / mock) with a single `cache` API: get/set/has/pull/remember, TTL shapes, tag-based invalidation, key namespaces, distributed locks, stale-while-revalidate, atomic update/merge, cache lists, vector similarity, metrics + events, and the `cached()` HOF. TRIGGER when: code imports from `@warlock.js/cache` (`cache`, `cached`, `setCacheConfigurations`, a `*CacheDriver`); user asks "what does @warlock.js/cache do", "which cache driver", "cache TTL / tags / invalidation", "distributed lock", "stale-while-revalidate", "semantic / vector cache", "compare with node-cache / keyv / cache-manager"; package.json adds `@warlock.js/cache`. Skip: specific task already known — load the matching task skill directly (`cache-basics`, `pick-cache-driver`, `configure-set-options`, `use-cache-tags`, `use-cache-namespace`, `use-cache-list`, `use-cache-lock`, `use-swr`, `use-cached-hof`, `use-cache-similarity`, `use-cache-update-merge`, `use-cache-atomic`, `use-cache-bulk`, `use-cache-utils`, `apply-cache-patterns`, `observe-cache`, `handle-cache-errors`, `configure-pg-cache`, `test-cache-code`).'
661
+ description: "@warlock.js/cache overview for orientation and choosing the focused skill for the task."
662
662
  ---
663
663
 
664
664
  # `@warlock.js/cache` — overview
@@ -731,7 +731,7 @@ Nineteen task skills. Most apps start with `cache-basics` + `pick-cache-driver`
731
731
 
732
732
  ---
733
733
  name: pick-cache-driver
734
- description: 'Pick a cache driver — null / memory / memoryExtended / lru / file / redis / pg / mock — and configure it. Triggers: `cache.setCacheConfigurations`, `BaseCacheDriver`, `cache.use`, `cache.load`, `cache.driver`, `globalPrefix`; "which cache driver should I use", "configure redis driver", "register custom cache driver", "multi-tenant scoping"; typical import `import { cache, BaseCacheDriver } from "@warlock.js/cache"`. Skip: cache CRUD — `@warlock.js/cache/cache-basics/SKILL.md`; pg setup — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`, `ioredis`; native `Map`.'
734
+ description: "Cache drivers — pick the right one in @warlock.js/cache; use when you need to choose cache driver."
735
735
  ---
736
736
 
737
737
  # Cache drivers — pick the right one
@@ -858,7 +858,7 @@ The manager loads (and connects) the override driver lazily on first use, then r
858
858
 
859
859
  ---
860
860
  name: test-cache-code
861
- description: 'Test code that touches cache — MockCacheDriver (behavioral assertions with wasCalled / callLog), MemoryCacheDriver (full-stack), NullCacheDriver (graceful-degradation). Triggers: `MockCacheDriver`, `MemoryCacheDriver`, `NullCacheDriver`, `wasCalled`, `callLog`, `getStored`, `reset`, `cache.on`; "assert cache was invalidated", "test code that uses cache.set", "mock cache in vitest", "test similarity without a real embedder", "stub the pg cache driver"; typical import `import { cache, MockCacheDriver, MemoryCacheDriver } from "@warlock.js/cache"`. Skip: real driver picks — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `jest-mock`, `sinon`, `redis-mock`; native `vi.fn`.'
861
+ description: "Testing code that touches cache in @warlock.js/cache; use when you need to test cache code."
862
862
  ---
863
863
 
864
864
  # Testing code that touches cache
@@ -1081,7 +1081,7 @@ The `pg` driver accepts any object satisfying `PgClientLike` (`{ query(text, val
1081
1081
 
1082
1082
  ---
1083
1083
  name: use-cache-atomic
1084
- description: 'Atomic counters via cache.increment(key, by=1) / cache.decrement(key, by=1) — returns the new number, throws on non-numeric values. Triggers: `cache.increment`, `cache.decrement`, "view counter", "page views", "atomic counter", "decrement stock", "rate-limit counter", "INCRBY"; typical import `import { cache } from "@warlock.js/cache"`. Skip: read-modify-write of objects — `@warlock.js/cache/use-cache-update-merge/SKILL.md`; named-lock coordination — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `ioredis` `INCR`, native counters in a `Map`.'
1084
+ description: "Atomic counters — cache.increment / cache.decrement in @warlock.js/cache; use when you need to use cache atomic."
1085
1085
  ---
1086
1086
 
1087
1087
  # Atomic counters — `cache.increment` / `cache.decrement`
@@ -1152,7 +1152,7 @@ if (remaining < 0) {
1152
1152
 
1153
1153
  ---
1154
1154
  name: use-cache-bulk
1155
- description: 'Bulk reads/writes via cache.many(keys[]) → values[] (nulls for misses, order preserved) and cache.setMany(record, ttl?) → void. Triggers: `cache.many`, `cache.setMany`, "get multiple keys at once", "batch read cache", "warm the cache", "preload many keys", "mget", "mset"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk invalidation — `@warlock.js/cache/use-cache-tags/SKILL.md`; single-key ops — `@warlock.js/cache/cache-basics/SKILL.md`; competing libs `ioredis` `MGET`/`MSET`.'
1155
+ description: "Bulk operations — cache.many / cache.setMany in @warlock.js/cache; use when you need to use cache bulk."
1156
1156
  ---
1157
1157
 
1158
1158
  # Bulk operations — `cache.many` / `cache.setMany`
@@ -1213,7 +1213,7 @@ returned promise rejects.
1213
1213
 
1214
1214
  ---
1215
1215
  name: use-cache-list
1216
- description: 'Ordered collections via cache.list<T>(key) — push / unshift / pop / shift / slice / all / length / trim / clear. Triggers: `cache.list`, `push`, `unshift`, `pop`, `shift`, `slice`, `trim`, `clear`; "job queue in cache", "keep most recent N events", "audit log buffer", "FIFO queue"; typical import `import { cache } from "@warlock.js/cache"`. Skip: locking around list writes — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `bullmq`, `bee-queue`, `bull`, `ioredis` `LPUSH`; native `Array.push`.'
1216
+ description: "Lists — the cache.list<T>(key) sub-API in @warlock.js/cache; use when you need to use cache list."
1217
1217
  ---
1218
1218
 
1219
1219
  # Lists — the `cache.list<T>(key)` sub-API
@@ -1302,7 +1302,7 @@ These are tracked as candidates for v3.
1302
1302
 
1303
1303
  ---
1304
1304
  name: use-cache-lock
1305
- description: 'Distributed lock via cache.lock(key, ttl, fn) — acquire, run fn, auto-release. Returns {acquired: true, value} or {acquired: false}. Triggers: `cache.lock`, `LockOutcome`, `acquired`, `owner`; "run cron on only one server", "idempotent webhook handler", "dedup payment processing", "lock a task across nodes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: raw `onConflict: "create"` recipe — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; memoization — `@warlock.js/cache/use-cached-hof/SKILL.md`; competing libs `redlock`, `async-mutex`, `proper-lockfile`.'
1305
+ description: "cache.lock() — distributed locks with auto-release in @warlock.js/cache; use when you need to use cache lock."
1306
1306
  ---
1307
1307
 
1308
1308
  # `cache.lock()` — distributed locks with auto-release
@@ -1410,7 +1410,7 @@ await cache.lock(
1410
1410
 
1411
1411
  ---
1412
1412
  name: use-cache-namespace
1413
- description: 'Scope cache keys via cache.namespace(prefix, options?) — every key auto-prefixed, scope-level ttl / tags defaults, nested scopes, .clear() sugar. Triggers: `cache.namespace`, `cache.removeNamespace`, `clear`, `globalPrefix`; "scope cache keys under a prefix", "share TTL across a whole prefix", "drop every key under user.1", "nested cache scopes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; multi-tenant driver-level prefix — `@warlock.js/cache/pick-cache-driver/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `keyv` namespaces.'
1413
+ description: "Scoped caches — cache.namespace(prefix, options?) in @warlock.js/cache; use when you need to use cache namespace."
1414
1414
  ---
1415
1415
 
1416
1416
  # Scoped caches — `cache.namespace(prefix, options?)`
@@ -1502,7 +1502,7 @@ Note: scope `ttl` defaults are NOT applied to SWR — `freshTtl` / `staleTtl` al
1502
1502
 
1503
1503
  ---
1504
1504
  name: use-cache-similarity
1505
- description: 'Vector retrieval via cache.similar(vector, {topK, threshold?, tags?}) — index with set(k, v, {vector}), query nearest by cosine similarity. Triggers: `cache.similar`, `cache.set` with `vector`, `topK`, `threshold`, `tags`, `cosineSimilarity`; "build a semantic cache for an LLM", "RAG retrieval from cache", "nearest-neighbor over cached entries", "skip the LLM when a similar answer exists"; typical import `import { cache } from "@warlock.js/cache"`. Skip: pgvector setup specifics — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `pinecone`, `weaviate`, `chromadb`, `lancedb`, `faiss-node`.'
1505
+ description: "cache.similar() — vector-based retrieval in @warlock.js/cache; use when you need to use cache similarity."
1506
1506
  ---
1507
1507
 
1508
1508
  # `cache.similar()` — vector-based retrieval
@@ -1600,7 +1600,7 @@ See [`@warlock.js/cache/configure-pg-cache/SKILL.md`](@warlock.js/cache/configur
1600
1600
 
1601
1601
  ---
1602
1602
  name: use-cache-tags
1603
- description: 'Tag-based invalidation — attach tags on write, then cache.tags([...]).invalidate() drops every key bound to any of those tags. Triggers: `cache.tags`, `invalidate`, `cache.set` with `tags`; "invalidate every key tagged users", "drop everything for tenant 42", "bulk cache invalidation without knowing keys", "tag a cached value"; typical import `import { cache } from "@warlock.js/cache"`. Skip: prefix-based drop — `@warlock.js/cache/use-cache-namespace/SKILL.md`; HOF memoization with tags — `@warlock.js/cache/use-cached-hof/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `cache-manager` tags, Next.js `revalidateTag`.'
1603
+ description: "Tag-based invalidation in @warlock.js/cache; use when you need to use cache tags."
1604
1604
  ---
1605
1605
 
1606
1606
  # Tag-based invalidation
@@ -1689,7 +1689,7 @@ See [`@warlock.js/cache/use-cached-hof/SKILL.md`](@warlock.js/cache/use-cached-h
1689
1689
 
1690
1690
  ---
1691
1691
  name: use-cache-update-merge
1692
- description: 'Atomic read-modify-write via cache.update(key, fn) (callback receives current) or cache.merge(key, partial) (shallow merge). Per-key chain lock serializes concurrent in-process callers. Triggers: `cache.update`, `cache.merge`, `cache.increment`, `cache.pull`; "atomically update a cached counter", "change one field on a cached object", "avoid get-spread-set race", "serialize concurrent cache writers"; typical import `import { cache } from "@warlock.js/cache"`. Skip: cross-process locking — `@warlock.js/cache/use-cache-lock/SKILL.md`; conditional create/update — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lodash.merge`, raw redis `WATCH`/`MULTI`.'
1692
+ description: "update and merge — atomic read-modify-write in @warlock.js/cache; use when you need to use cache update merge."
1693
1693
  ---
1694
1694
 
1695
1695
  # `update` and `merge` — atomic read-modify-write
@@ -1777,7 +1777,7 @@ The per-key lock map lives on the driver instance and is cleared after each chai
1777
1777
 
1778
1778
  ---
1779
1779
  name: use-cache-utils
1780
- description: 'Low-level cache utilities re-exported from @warlock.js/cache — parseTtl, expiresAtToTtl, resolveTtl, normalizeToOptions, normalizeToRememberOptions, parseCacheKey, mergeTagSets, injectTags, cosineSimilarity, and the CACHE_FOR TTL enum. Triggers: `parseTtl`, `parseCacheKey`, `resolveTtl`, `expiresAtToTtl`, `cosineSimilarity`, `mergeTagSets`, `injectTags`, `CACHE_FOR`; "parse a duration to seconds", "build a cache key from an object", "score two vectors", "common TTL constant"; typical import `import { parseTtl, CACHE_FOR } from "@warlock.js/cache"`. Skip: building a whole custom driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; the high-level set API — `@warlock.js/cache/configure-set-options/SKILL.md`.'
1780
+ description: "Cache utilities in @warlock.js/cache; use when you need to use cache utils."
1781
1781
  ---
1782
1782
 
1783
1783
  # Cache utilities
@@ -1870,7 +1870,7 @@ For most call sites the duration string (`"1h"`, `"7d"`) reads better.
1870
1870
 
1871
1871
  ---
1872
1872
  name: use-cached-hof
1873
- description: 'Wrap an async function with cached(fn, options) — declare the caching strategy once, call from many sites, get a bound .invalidate(...args) helper. Triggers: `cached`, `invalidate`, `key`, `ttl`, `tags`, `driver`; "wrap a DB lookup with caching", "memoize a function and invalidate by args", "one declaration many call sites", "auto-derive cache key from args"; typical import `import { cached } from "@warlock.js/cache"`. Skip: one-shot memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md` (`cache.remember`); tag bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; competing libs `p-memoize`, `mem`, `lodash.memoize`.'
1873
+ description: "cached() — function-memoization wrapper in @warlock.js/cache; use when you need to use cached hof."
1874
1874
  ---
1875
1875
 
1876
1876
  # `cached()` — function-memoization wrapper
@@ -1976,7 +1976,7 @@ const getCategoryMeta = cached(
1976
1976
 
1977
1977
  ---
1978
1978
  name: use-swr
1979
- description: 'Stale-while-revalidate via cache.swr(key, {freshTtl, staleTtl}, fn) — returns cached instantly when fresh, returns cached + background refresh when stale, blocks only when fully expired. Triggers: `cache.swr`, `freshTtl`, `staleTtl`, `tags`, `driver`, `stale_at`; "serve stale while refreshing", "degrade when upstream is down", "never block on cache miss"; typical import `import { cache } from "@warlock.js/cache"`. Skip: block-until-fresh memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; observing refresh failures — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs `swr` (React, client-side).'
1979
+ description: "Stale-while-revalidate — cache.swr(key, options, fn) in @warlock.js/cache; use when you need to use swr."
1980
1980
  ---
1981
1981
 
1982
1982
  # Stale-while-revalidate — `cache.swr(key, options, fn)`
package/llms.txt CHANGED
@@ -6,23 +6,23 @@
6
6
 
7
7
  ## Skills
8
8
 
9
- - [apply-cache-patterns](@warlock.js/cache/apply-cache-patterns/SKILL.md): Compose cache primitives into real-world patterns — remember() memoization, cross-node stampede protection via a distributed lock (onConflict: 'create'), negative caching, and per-tenant scoping. Triggers: `cache.remember`, `cache.set` with `onConflict: "create"`, `globalPrefix`; "memoize this function", "prevent cache stampede across nodes", "cache not-found results", "per-tenant cache scoping"; typical import `import { cache } from "@warlock.js/cache"`. Skip: counters — `@warlock.js/cache/use-cache-atomic/SKILL.md`; bulk get/set — `@warlock.js/cache/use-cache-bulk/SKILL.md`; TTL constants/utilities — `@warlock.js/cache/use-cache-utils/SKILL.md`; named lock wrapper — `@warlock.js/cache/use-cache-lock/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`.
10
- - [cache-basics](@warlock.js/cache/cache-basics/SKILL.md): Start with @warlock.js/cache — the cache singleton, primary ops (set / get / pull / remove / many / forever / increment / remember), TTL shapes, init flow. Triggers: `cache`, `cache.setCacheConfigurations`, `cache.init`, `cache.set`, `cache.get`, `cache.remove`, `cache.remember`, `cache.flush`; "start with warlock cache", "wire up cache at startup", "which cache skill do I need"; typical import `import { cache } from "@warlock.js/cache"`. Skip: driver choice — `@warlock.js/cache/pick-cache-driver/SKILL.md`; set options — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`; native `Map`.
11
- - [configure-pg-cache](@warlock.js/cache/configure-pg-cache/SKILL.md): Postgres cache driver setup — KV-only mode (default) or pgvector mode (opt in via options.pg.vector). Caller owns the pg.Pool, driver exposes driver.schema() for one-time DDL. Triggers: `PgCacheDriver`, `driver.schema`, `options.pg.vector`, `pg.Pool`, `hnsw`, `ivfflat`; "use Postgres as cache backend", "set up pgvector semantic cache", "DDL for warlock cache table"; typical import `import { cache, PgCacheDriver } from "@warlock.js/cache"`. Skip: cross-driver similarity API — `@warlock.js/cache/use-cache-similarity/SKILL.md`; driver picker — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `pg-mem`; raw `pg` / `node-postgres`.
12
- - [configure-set-options](@warlock.js/cache/configure-set-options/SKILL.md): Configure cache.set's third argument — ttl, expiresAt, tags, onConflict (create / update / upsert), driver, vector. Triggers: `cache.set`, `ttl`, `expiresAt`, `tags`, `onConflict`, `driver`, `vector`, `CacheSetResult`, `wasSet`; "set a key only if missing", "set with absolute deadline", "attach tags inline", "route one cache call to redis"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag fluent API — `@warlock.js/cache/use-cache-tags/SKILL.md`; vector queries — `@warlock.js/cache/use-cache-similarity/SKILL.md`; competing libs `keyv`, `ioredis`.
13
- - [handle-cache-errors](@warlock.js/cache/handle-cache-errors/SKILL.md): Cache error classes — CacheError base, CacheConfigurationError, CacheConnectionError, CacheDriverNotInitializedError, CacheUnsupportedError, CacheConcurrencyError. Triggers: `CacheError`, `CacheConfigurationError`, `CacheConnectionError`, `CacheDriverNotInitializedError`, `CacheUnsupportedError`, `CacheConcurrencyError`; "catch cache errors at the boundary", "degrade when update or merge throws", "what does CacheUnsupportedError mean", "fall back when redis is down"; typical import `import { CacheError, CacheConfigurationError, CacheUnsupportedError } from "@warlock.js/cache"`. Skip: choosing a supported driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; observing errors via events — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs ignore — generic `Error` patterns.
14
- - [observe-cache](@warlock.js/cache/observe-cache/SKILL.md): Cache observability — cache.metrics() for aggregate hit rate / latency p50/p95/p99 + event bus (cache.on('hit' / 'miss' / 'set' / 'removed' / 'flushed' / 'expired' / 'error', ...)). Triggers: `cache.metrics`, `cache.resetMetrics`, `cache.on`, `hit`, `miss`, `removed`, `flushed`, `error`, `hitRate`, `latencyMs`; "show cache hit rate", "page on cache errors", "is my cache being hit", "export metrics to prometheus"; typical import `import { cache } from "@warlock.js/cache"`. Skip: error classes — `@warlock.js/cache/handle-cache-errors/SKILL.md`; competing libs `prom-client`, `statsd-client`.
15
- - [overview](@warlock.js/cache/overview/SKILL.md): Front-door orientation for `@warlock.js/cache` — multi-driver caching (memory / memoryExtended / lru / file / redis / pg / null / mock) with a single `cache` API: get/set/has/pull/remember, TTL shapes, tag-based invalidation, key namespaces, distributed locks, stale-while-revalidate, atomic update/merge, cache lists, vector similarity, metrics + events, and the `cached()` HOF. TRIGGER when: code imports from `@warlock.js/cache` (`cache`, `cached`, `setCacheConfigurations`, a `*CacheDriver`); user asks "what does @warlock.js/cache do", "which cache driver", "cache TTL / tags / invalidation", "distributed lock", "stale-while-revalidate", "semantic / vector cache", "compare with node-cache / keyv / cache-manager"; package.json adds `@warlock.js/cache`. Skip: specific task already known — load the matching task skill directly (`cache-basics`, `pick-cache-driver`, `configure-set-options`, `use-cache-tags`, `use-cache-namespace`, `use-cache-list`, `use-cache-lock`, `use-swr`, `use-cached-hof`, `use-cache-similarity`, `use-cache-update-merge`, `use-cache-atomic`, `use-cache-bulk`, `use-cache-utils`, `apply-cache-patterns`, `observe-cache`, `handle-cache-errors`, `configure-pg-cache`, `test-cache-code`).
16
- - [pick-cache-driver](@warlock.js/cache/pick-cache-driver/SKILL.md): Pick a cache driver — null / memory / memoryExtended / lru / file / redis / pg / mock — and configure it. Triggers: `cache.setCacheConfigurations`, `BaseCacheDriver`, `cache.use`, `cache.load`, `cache.driver`, `globalPrefix`; "which cache driver should I use", "configure redis driver", "register custom cache driver", "multi-tenant scoping"; typical import `import { cache, BaseCacheDriver } from "@warlock.js/cache"`. Skip: cache CRUD — `@warlock.js/cache/cache-basics/SKILL.md`; pg setup — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`, `ioredis`; native `Map`.
17
- - [test-cache-code](@warlock.js/cache/test-cache-code/SKILL.md): Test code that touches cache — MockCacheDriver (behavioral assertions with wasCalled / callLog), MemoryCacheDriver (full-stack), NullCacheDriver (graceful-degradation). Triggers: `MockCacheDriver`, `MemoryCacheDriver`, `NullCacheDriver`, `wasCalled`, `callLog`, `getStored`, `reset`, `cache.on`; "assert cache was invalidated", "test code that uses cache.set", "mock cache in vitest", "test similarity without a real embedder", "stub the pg cache driver"; typical import `import { cache, MockCacheDriver, MemoryCacheDriver } from "@warlock.js/cache"`. Skip: real driver picks — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `jest-mock`, `sinon`, `redis-mock`; native `vi.fn`.
18
- - [use-cache-atomic](@warlock.js/cache/use-cache-atomic/SKILL.md): Atomic counters via cache.increment(key, by=1) / cache.decrement(key, by=1) — returns the new number, throws on non-numeric values. Triggers: `cache.increment`, `cache.decrement`, "view counter", "page views", "atomic counter", "decrement stock", "rate-limit counter", "INCRBY"; typical import `import { cache } from "@warlock.js/cache"`. Skip: read-modify-write of objects — `@warlock.js/cache/use-cache-update-merge/SKILL.md`; named-lock coordination — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `ioredis` `INCR`, native counters in a `Map`.
19
- - [use-cache-bulk](@warlock.js/cache/use-cache-bulk/SKILL.md): Bulk reads/writes via cache.many(keys[]) → values[] (nulls for misses, order preserved) and cache.setMany(record, ttl?) → void. Triggers: `cache.many`, `cache.setMany`, "get multiple keys at once", "batch read cache", "warm the cache", "preload many keys", "mget", "mset"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk invalidation — `@warlock.js/cache/use-cache-tags/SKILL.md`; single-key ops — `@warlock.js/cache/cache-basics/SKILL.md`; competing libs `ioredis` `MGET`/`MSET`.
20
- - [use-cache-list](@warlock.js/cache/use-cache-list/SKILL.md): Ordered collections via cache.list<T>(key) — push / unshift / pop / shift / slice / all / length / trim / clear. Triggers: `cache.list`, `push`, `unshift`, `pop`, `shift`, `slice`, `trim`, `clear`; "job queue in cache", "keep most recent N events", "audit log buffer", "FIFO queue"; typical import `import { cache } from "@warlock.js/cache"`. Skip: locking around list writes — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `bullmq`, `bee-queue`, `bull`, `ioredis` `LPUSH`; native `Array.push`.
21
- - [use-cache-lock](@warlock.js/cache/use-cache-lock/SKILL.md): Distributed lock via cache.lock(key, ttl, fn) — acquire, run fn, auto-release. Returns {acquired: true, value} or {acquired: false}. Triggers: `cache.lock`, `LockOutcome`, `acquired`, `owner`; "run cron on only one server", "idempotent webhook handler", "dedup payment processing", "lock a task across nodes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: raw `onConflict: "create"` recipe — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; memoization — `@warlock.js/cache/use-cached-hof/SKILL.md`; competing libs `redlock`, `async-mutex`, `proper-lockfile`.
22
- - [use-cache-namespace](@warlock.js/cache/use-cache-namespace/SKILL.md): Scope cache keys via cache.namespace(prefix, options?) — every key auto-prefixed, scope-level ttl / tags defaults, nested scopes, .clear() sugar. Triggers: `cache.namespace`, `cache.removeNamespace`, `clear`, `globalPrefix`; "scope cache keys under a prefix", "share TTL across a whole prefix", "drop every key under user.1", "nested cache scopes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; multi-tenant driver-level prefix — `@warlock.js/cache/pick-cache-driver/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `keyv` namespaces.
23
- - [use-cache-similarity](@warlock.js/cache/use-cache-similarity/SKILL.md): Vector retrieval via cache.similar(vector, {topK, threshold?, tags?}) — index with set(k, v, {vector}), query nearest by cosine similarity. Triggers: `cache.similar`, `cache.set` with `vector`, `topK`, `threshold`, `tags`, `cosineSimilarity`; "build a semantic cache for an LLM", "RAG retrieval from cache", "nearest-neighbor over cached entries", "skip the LLM when a similar answer exists"; typical import `import { cache } from "@warlock.js/cache"`. Skip: pgvector setup specifics — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `pinecone`, `weaviate`, `chromadb`, `lancedb`, `faiss-node`.
24
- - [use-cache-tags](@warlock.js/cache/use-cache-tags/SKILL.md): Tag-based invalidation — attach tags on write, then cache.tags([...]).invalidate() drops every key bound to any of those tags. Triggers: `cache.tags`, `invalidate`, `cache.set` with `tags`; "invalidate every key tagged users", "drop everything for tenant 42", "bulk cache invalidation without knowing keys", "tag a cached value"; typical import `import { cache } from "@warlock.js/cache"`. Skip: prefix-based drop — `@warlock.js/cache/use-cache-namespace/SKILL.md`; HOF memoization with tags — `@warlock.js/cache/use-cached-hof/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `cache-manager` tags, Next.js `revalidateTag`.
25
- - [use-cache-update-merge](@warlock.js/cache/use-cache-update-merge/SKILL.md): Atomic read-modify-write via cache.update(key, fn) (callback receives current) or cache.merge(key, partial) (shallow merge). Per-key chain lock serializes concurrent in-process callers. Triggers: `cache.update`, `cache.merge`, `cache.increment`, `cache.pull`; "atomically update a cached counter", "change one field on a cached object", "avoid get-spread-set race", "serialize concurrent cache writers"; typical import `import { cache } from "@warlock.js/cache"`. Skip: cross-process locking — `@warlock.js/cache/use-cache-lock/SKILL.md`; conditional create/update — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lodash.merge`, raw redis `WATCH`/`MULTI`.
26
- - [use-cache-utils](@warlock.js/cache/use-cache-utils/SKILL.md): Low-level cache utilities re-exported from @warlock.js/cache — parseTtl, expiresAtToTtl, resolveTtl, normalizeToOptions, normalizeToRememberOptions, parseCacheKey, mergeTagSets, injectTags, cosineSimilarity, and the CACHE_FOR TTL enum. Triggers: `parseTtl`, `parseCacheKey`, `resolveTtl`, `expiresAtToTtl`, `cosineSimilarity`, `mergeTagSets`, `injectTags`, `CACHE_FOR`; "parse a duration to seconds", "build a cache key from an object", "score two vectors", "common TTL constant"; typical import `import { parseTtl, CACHE_FOR } from "@warlock.js/cache"`. Skip: building a whole custom driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; the high-level set API — `@warlock.js/cache/configure-set-options/SKILL.md`.
27
- - [use-cached-hof](@warlock.js/cache/use-cached-hof/SKILL.md): Wrap an async function with cached(fn, options) — declare the caching strategy once, call from many sites, get a bound .invalidate(...args) helper. Triggers: `cached`, `invalidate`, `key`, `ttl`, `tags`, `driver`; "wrap a DB lookup with caching", "memoize a function and invalidate by args", "one declaration many call sites", "auto-derive cache key from args"; typical import `import { cached } from "@warlock.js/cache"`. Skip: one-shot memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md` (`cache.remember`); tag bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; competing libs `p-memoize`, `mem`, `lodash.memoize`.
28
- - [use-swr](@warlock.js/cache/use-swr/SKILL.md): Stale-while-revalidate via cache.swr(key, {freshTtl, staleTtl}, fn) — returns cached instantly when fresh, returns cached + background refresh when stale, blocks only when fully expired. Triggers: `cache.swr`, `freshTtl`, `staleTtl`, `tags`, `driver`, `stale_at`; "serve stale while refreshing", "degrade when upstream is down", "never block on cache miss"; typical import `import { cache } from "@warlock.js/cache"`. Skip: block-until-fresh memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; observing refresh failures — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs `swr` (React, client-side).
9
+ - [apply-cache-patterns](@warlock.js/cache/apply-cache-patterns/SKILL.md): Real-world caching patterns in @warlock.js/cache; use when you need to apply cache patterns.
10
+ - [cache-basics](@warlock.js/cache/cache-basics/SKILL.md): Start here for @warlock.js/cache drivers, key-value operations, and application cache configuration.
11
+ - [configure-pg-cache](@warlock.js/cache/configure-pg-cache/SKILL.md): pg cache driver — Postgres setup in @warlock.js/cache; use when you need to configure pg cache.
12
+ - [configure-set-options](@warlock.js/cache/configure-set-options/SKILL.md): The set options object in @warlock.js/cache; use when you need to configure set options.
13
+ - [handle-cache-errors](@warlock.js/cache/handle-cache-errors/SKILL.md): Error classes in @warlock.js/cache; use when you need to handle cache errors.
14
+ - [observe-cache](@warlock.js/cache/observe-cache/SKILL.md): Cache observability — cache.metrics() and the event bus in @warlock.js/cache; use when you need to observe cache.
15
+ - [overview](@warlock.js/cache/overview/SKILL.md): @warlock.js/cache overview for orientation and choosing the focused skill for the task.
16
+ - [pick-cache-driver](@warlock.js/cache/pick-cache-driver/SKILL.md): Cache drivers — pick the right one in @warlock.js/cache; use when you need to choose cache driver.
17
+ - [test-cache-code](@warlock.js/cache/test-cache-code/SKILL.md): Testing code that touches cache in @warlock.js/cache; use when you need to test cache code.
18
+ - [use-cache-atomic](@warlock.js/cache/use-cache-atomic/SKILL.md): Atomic counters — cache.increment / cache.decrement in @warlock.js/cache; use when you need to use cache atomic.
19
+ - [use-cache-bulk](@warlock.js/cache/use-cache-bulk/SKILL.md): Bulk operations — cache.many / cache.setMany in @warlock.js/cache; use when you need to use cache bulk.
20
+ - [use-cache-list](@warlock.js/cache/use-cache-list/SKILL.md): Lists — the cache.list<T>(key) sub-API in @warlock.js/cache; use when you need to use cache list.
21
+ - [use-cache-lock](@warlock.js/cache/use-cache-lock/SKILL.md): cache.lock() — distributed locks with auto-release in @warlock.js/cache; use when you need to use cache lock.
22
+ - [use-cache-namespace](@warlock.js/cache/use-cache-namespace/SKILL.md): Scoped caches — cache.namespace(prefix, options?) in @warlock.js/cache; use when you need to use cache namespace.
23
+ - [use-cache-similarity](@warlock.js/cache/use-cache-similarity/SKILL.md): cache.similar() — vector-based retrieval in @warlock.js/cache; use when you need to use cache similarity.
24
+ - [use-cache-tags](@warlock.js/cache/use-cache-tags/SKILL.md): Tag-based invalidation in @warlock.js/cache; use when you need to use cache tags.
25
+ - [use-cache-update-merge](@warlock.js/cache/use-cache-update-merge/SKILL.md): update and merge — atomic read-modify-write in @warlock.js/cache; use when you need to use cache update merge.
26
+ - [use-cache-utils](@warlock.js/cache/use-cache-utils/SKILL.md): Cache utilities in @warlock.js/cache; use when you need to use cache utils.
27
+ - [use-cached-hof](@warlock.js/cache/use-cached-hof/SKILL.md): cached() — function-memoization wrapper in @warlock.js/cache; use when you need to use cached hof.
28
+ - [use-swr](@warlock.js/cache/use-swr/SKILL.md): Stale-while-revalidate — cache.swr(key, options, fn) in @warlock.js/cache; use when you need to use swr.
package/package.json CHANGED
@@ -5,9 +5,9 @@
5
5
  "environment": "server"
6
6
  },
7
7
  "dependencies": {
8
- "@warlock.js/fs": "5.18.0",
8
+ "@warlock.js/fs": "5.19.0",
9
9
  "@mongez/reinforcements": "^4.0.1",
10
- "@warlock.js/logger": "5.18.0",
10
+ "@warlock.js/logger": "5.19.0",
11
11
  "ms": "^2.1.3"
12
12
  },
13
13
  "peerDependencies": {
@@ -46,7 +46,7 @@
46
46
  ],
47
47
  "author": "hassanzohdy",
48
48
  "license": "MIT",
49
- "version": "5.18.0",
49
+ "version": "5.19.0",
50
50
  "main": "./cjs/index.cjs",
51
51
  "module": "./esm/index.mjs",
52
52
  "types": "./esm/index.d.mts",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: apply-cache-patterns
3
- description: 'Compose cache primitives into real-world patterns — remember() memoization, cross-node stampede protection via a distributed lock (onConflict: ''create''), negative caching, and per-tenant scoping. Triggers: `cache.remember`, `cache.set` with `onConflict: "create"`, `globalPrefix`; "memoize this function", "prevent cache stampede across nodes", "cache not-found results", "per-tenant cache scoping"; typical import `import { cache } from "@warlock.js/cache"`. Skip: counters — `@warlock.js/cache/use-cache-atomic/SKILL.md`; bulk get/set — `@warlock.js/cache/use-cache-bulk/SKILL.md`; TTL constants/utilities — `@warlock.js/cache/use-cache-utils/SKILL.md`; named lock wrapper — `@warlock.js/cache/use-cache-lock/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`.'
3
+ description: "Real-world caching patterns in @warlock.js/cache; use when you need to apply cache patterns."
4
4
  ---
5
5
 
6
6
  # Real-world caching patterns
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: cache-basics
3
- description: 'Start with @warlock.js/cache — the cache singleton, primary ops (set / get / pull / remove / many / forever / increment / remember), TTL shapes, init flow. Triggers: `cache`, `cache.setCacheConfigurations`, `cache.init`, `cache.set`, `cache.get`, `cache.remove`, `cache.remember`, `cache.flush`; "start with warlock cache", "wire up cache at startup", "which cache skill do I need"; typical import `import { cache } from "@warlock.js/cache"`. Skip: driver choice — `@warlock.js/cache/pick-cache-driver/SKILL.md`; set options — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`; native `Map`.'
3
+ description: "Start here for @warlock.js/cache drivers, key-value operations, and application cache configuration."
4
4
  ---
5
5
 
6
6
  # Cache basics
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: configure-pg-cache
3
- description: 'Postgres cache driver setup — KV-only mode (default) or pgvector mode (opt in via options.pg.vector). Caller owns the pg.Pool, driver exposes driver.schema() for one-time DDL. Triggers: `PgCacheDriver`, `driver.schema`, `options.pg.vector`, `pg.Pool`, `hnsw`, `ivfflat`; "use Postgres as cache backend", "set up pgvector semantic cache", "DDL for warlock cache table"; typical import `import { cache, PgCacheDriver } from "@warlock.js/cache"`. Skip: cross-driver similarity API — `@warlock.js/cache/use-cache-similarity/SKILL.md`; driver picker — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `pg-mem`; raw `pg` / `node-postgres`.'
3
+ description: "pg cache driver — Postgres setup in @warlock.js/cache; use when you need to configure pg cache."
4
4
  ---
5
5
 
6
6
  # `pg` cache driver — Postgres setup
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: configure-set-options
3
- description: 'Configure cache.set''s third argument — ttl, expiresAt, tags, onConflict (create / update / upsert), driver, vector. Triggers: `cache.set`, `ttl`, `expiresAt`, `tags`, `onConflict`, `driver`, `vector`, `CacheSetResult`, `wasSet`; "set a key only if missing", "set with absolute deadline", "attach tags inline", "route one cache call to redis"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag fluent API — `@warlock.js/cache/use-cache-tags/SKILL.md`; vector queries — `@warlock.js/cache/use-cache-similarity/SKILL.md`; competing libs `keyv`, `ioredis`.'
3
+ description: "The set options object in @warlock.js/cache; use when you need to configure set options."
4
4
  ---
5
5
 
6
6
  # The `set` options object
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: handle-cache-errors
3
- description: 'Cache error classes — CacheError base, CacheConfigurationError, CacheConnectionError, CacheDriverNotInitializedError, CacheUnsupportedError, CacheConcurrencyError. Triggers: `CacheError`, `CacheConfigurationError`, `CacheConnectionError`, `CacheDriverNotInitializedError`, `CacheUnsupportedError`, `CacheConcurrencyError`; "catch cache errors at the boundary", "degrade when update or merge throws", "what does CacheUnsupportedError mean", "fall back when redis is down"; typical import `import { CacheError, CacheConfigurationError, CacheUnsupportedError } from "@warlock.js/cache"`. Skip: choosing a supported driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; observing errors via events — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs ignore — generic `Error` patterns.'
3
+ description: "Error classes in @warlock.js/cache; use when you need to handle cache errors."
4
4
  ---
5
5
 
6
6
  # Error classes
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: observe-cache
3
- description: 'Cache observability — cache.metrics() for aggregate hit rate / latency p50/p95/p99 + event bus (cache.on(''hit'' / ''miss'' / ''set'' / ''removed'' / ''flushed'' / ''expired'' / ''error'', ...)). Triggers: `cache.metrics`, `cache.resetMetrics`, `cache.on`, `hit`, `miss`, `removed`, `flushed`, `error`, `hitRate`, `latencyMs`; "show cache hit rate", "page on cache errors", "is my cache being hit", "export metrics to prometheus"; typical import `import { cache } from "@warlock.js/cache"`. Skip: error classes — `@warlock.js/cache/handle-cache-errors/SKILL.md`; competing libs `prom-client`, `statsd-client`.'
3
+ description: "Cache observability — cache.metrics() and the event bus in @warlock.js/cache; use when you need to observe cache."
4
4
  ---
5
5
 
6
6
  # Cache observability — `cache.metrics()` and the event bus
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: overview
3
- description: 'Front-door orientation for `@warlock.js/cache` — multi-driver caching (memory / memoryExtended / lru / file / redis / pg / null / mock) with a single `cache` API: get/set/has/pull/remember, TTL shapes, tag-based invalidation, key namespaces, distributed locks, stale-while-revalidate, atomic update/merge, cache lists, vector similarity, metrics + events, and the `cached()` HOF. TRIGGER when: code imports from `@warlock.js/cache` (`cache`, `cached`, `setCacheConfigurations`, a `*CacheDriver`); user asks "what does @warlock.js/cache do", "which cache driver", "cache TTL / tags / invalidation", "distributed lock", "stale-while-revalidate", "semantic / vector cache", "compare with node-cache / keyv / cache-manager"; package.json adds `@warlock.js/cache`. Skip: specific task already known — load the matching task skill directly (`cache-basics`, `pick-cache-driver`, `configure-set-options`, `use-cache-tags`, `use-cache-namespace`, `use-cache-list`, `use-cache-lock`, `use-swr`, `use-cached-hof`, `use-cache-similarity`, `use-cache-update-merge`, `use-cache-atomic`, `use-cache-bulk`, `use-cache-utils`, `apply-cache-patterns`, `observe-cache`, `handle-cache-errors`, `configure-pg-cache`, `test-cache-code`).'
3
+ description: "@warlock.js/cache overview for orientation and choosing the focused skill for the task."
4
4
  ---
5
5
 
6
6
  # `@warlock.js/cache` — overview
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: pick-cache-driver
3
- description: 'Pick a cache driver — null / memory / memoryExtended / lru / file / redis / pg / mock — and configure it. Triggers: `cache.setCacheConfigurations`, `BaseCacheDriver`, `cache.use`, `cache.load`, `cache.driver`, `globalPrefix`; "which cache driver should I use", "configure redis driver", "register custom cache driver", "multi-tenant scoping"; typical import `import { cache, BaseCacheDriver } from "@warlock.js/cache"`. Skip: cache CRUD — `@warlock.js/cache/cache-basics/SKILL.md`; pg setup — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `lru-cache`, `node-cache`, `keyv`, `ioredis`; native `Map`.'
3
+ description: "Cache drivers — pick the right one in @warlock.js/cache; use when you need to choose cache driver."
4
4
  ---
5
5
 
6
6
  # Cache drivers — pick the right one
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: test-cache-code
3
- description: 'Test code that touches cache — MockCacheDriver (behavioral assertions with wasCalled / callLog), MemoryCacheDriver (full-stack), NullCacheDriver (graceful-degradation). Triggers: `MockCacheDriver`, `MemoryCacheDriver`, `NullCacheDriver`, `wasCalled`, `callLog`, `getStored`, `reset`, `cache.on`; "assert cache was invalidated", "test code that uses cache.set", "mock cache in vitest", "test similarity without a real embedder", "stub the pg cache driver"; typical import `import { cache, MockCacheDriver, MemoryCacheDriver } from "@warlock.js/cache"`. Skip: real driver picks — `@warlock.js/cache/pick-cache-driver/SKILL.md`; competing libs `jest-mock`, `sinon`, `redis-mock`; native `vi.fn`.'
3
+ description: "Testing code that touches cache in @warlock.js/cache; use when you need to test cache code."
4
4
  ---
5
5
 
6
6
  # Testing code that touches cache
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-atomic
3
- description: 'Atomic counters via cache.increment(key, by=1) / cache.decrement(key, by=1) — returns the new number, throws on non-numeric values. Triggers: `cache.increment`, `cache.decrement`, "view counter", "page views", "atomic counter", "decrement stock", "rate-limit counter", "INCRBY"; typical import `import { cache } from "@warlock.js/cache"`. Skip: read-modify-write of objects — `@warlock.js/cache/use-cache-update-merge/SKILL.md`; named-lock coordination — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `ioredis` `INCR`, native counters in a `Map`.'
3
+ description: "Atomic counters — cache.increment / cache.decrement in @warlock.js/cache; use when you need to use cache atomic."
4
4
  ---
5
5
 
6
6
  # Atomic counters — `cache.increment` / `cache.decrement`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-bulk
3
- description: 'Bulk reads/writes via cache.many(keys[]) → values[] (nulls for misses, order preserved) and cache.setMany(record, ttl?) → void. Triggers: `cache.many`, `cache.setMany`, "get multiple keys at once", "batch read cache", "warm the cache", "preload many keys", "mget", "mset"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk invalidation — `@warlock.js/cache/use-cache-tags/SKILL.md`; single-key ops — `@warlock.js/cache/cache-basics/SKILL.md`; competing libs `ioredis` `MGET`/`MSET`.'
3
+ description: "Bulk operations — cache.many / cache.setMany in @warlock.js/cache; use when you need to use cache bulk."
4
4
  ---
5
5
 
6
6
  # Bulk operations — `cache.many` / `cache.setMany`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-list
3
- description: 'Ordered collections via cache.list<T>(key) — push / unshift / pop / shift / slice / all / length / trim / clear. Triggers: `cache.list`, `push`, `unshift`, `pop`, `shift`, `slice`, `trim`, `clear`; "job queue in cache", "keep most recent N events", "audit log buffer", "FIFO queue"; typical import `import { cache } from "@warlock.js/cache"`. Skip: locking around list writes — `@warlock.js/cache/use-cache-lock/SKILL.md`; competing libs `bullmq`, `bee-queue`, `bull`, `ioredis` `LPUSH`; native `Array.push`.'
3
+ description: "Lists — the cache.list<T>(key) sub-API in @warlock.js/cache; use when you need to use cache list."
4
4
  ---
5
5
 
6
6
  # Lists — the `cache.list<T>(key)` sub-API
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-lock
3
- description: 'Distributed lock via cache.lock(key, ttl, fn) — acquire, run fn, auto-release. Returns {acquired: true, value} or {acquired: false}. Triggers: `cache.lock`, `LockOutcome`, `acquired`, `owner`; "run cron on only one server", "idempotent webhook handler", "dedup payment processing", "lock a task across nodes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: raw `onConflict: "create"` recipe — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; memoization — `@warlock.js/cache/use-cached-hof/SKILL.md`; competing libs `redlock`, `async-mutex`, `proper-lockfile`.'
3
+ description: "cache.lock() — distributed locks with auto-release in @warlock.js/cache; use when you need to use cache lock."
4
4
  ---
5
5
 
6
6
  # `cache.lock()` — distributed locks with auto-release
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-namespace
3
- description: 'Scope cache keys via cache.namespace(prefix, options?) — every key auto-prefixed, scope-level ttl / tags defaults, nested scopes, .clear() sugar. Triggers: `cache.namespace`, `cache.removeNamespace`, `clear`, `globalPrefix`; "scope cache keys under a prefix", "share TTL across a whole prefix", "drop every key under user.1", "nested cache scopes"; typical import `import { cache } from "@warlock.js/cache"`. Skip: tag-based bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; multi-tenant driver-level prefix — `@warlock.js/cache/pick-cache-driver/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `keyv` namespaces.'
3
+ description: "Scoped caches — cache.namespace(prefix, options?) in @warlock.js/cache; use when you need to use cache namespace."
4
4
  ---
5
5
 
6
6
  # Scoped caches — `cache.namespace(prefix, options?)`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-similarity
3
- description: 'Vector retrieval via cache.similar(vector, {topK, threshold?, tags?}) — index with set(k, v, {vector}), query nearest by cosine similarity. Triggers: `cache.similar`, `cache.set` with `vector`, `topK`, `threshold`, `tags`, `cosineSimilarity`; "build a semantic cache for an LLM", "RAG retrieval from cache", "nearest-neighbor over cached entries", "skip the LLM when a similar answer exists"; typical import `import { cache } from "@warlock.js/cache"`. Skip: pgvector setup specifics — `@warlock.js/cache/configure-pg-cache/SKILL.md`; competing libs `pinecone`, `weaviate`, `chromadb`, `lancedb`, `faiss-node`.'
3
+ description: "cache.similar() — vector-based retrieval in @warlock.js/cache; use when you need to use cache similarity."
4
4
  ---
5
5
 
6
6
  # `cache.similar()` — vector-based retrieval
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-tags
3
- description: 'Tag-based invalidation — attach tags on write, then cache.tags([...]).invalidate() drops every key bound to any of those tags. Triggers: `cache.tags`, `invalidate`, `cache.set` with `tags`; "invalidate every key tagged users", "drop everything for tenant 42", "bulk cache invalidation without knowing keys", "tag a cached value"; typical import `import { cache } from "@warlock.js/cache"`. Skip: prefix-based drop — `@warlock.js/cache/use-cache-namespace/SKILL.md`; HOF memoization with tags — `@warlock.js/cache/use-cached-hof/SKILL.md`; SWR — `@warlock.js/cache/use-swr/SKILL.md`; competing libs `cache-manager` tags, Next.js `revalidateTag`.'
3
+ description: "Tag-based invalidation in @warlock.js/cache; use when you need to use cache tags."
4
4
  ---
5
5
 
6
6
  # Tag-based invalidation
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-update-merge
3
- description: 'Atomic read-modify-write via cache.update(key, fn) (callback receives current) or cache.merge(key, partial) (shallow merge). Per-key chain lock serializes concurrent in-process callers. Triggers: `cache.update`, `cache.merge`, `cache.increment`, `cache.pull`; "atomically update a cached counter", "change one field on a cached object", "avoid get-spread-set race", "serialize concurrent cache writers"; typical import `import { cache } from "@warlock.js/cache"`. Skip: cross-process locking — `@warlock.js/cache/use-cache-lock/SKILL.md`; conditional create/update — `@warlock.js/cache/configure-set-options/SKILL.md`; competing libs `lodash.merge`, raw redis `WATCH`/`MULTI`.'
3
+ description: "update and merge — atomic read-modify-write in @warlock.js/cache; use when you need to use cache update merge."
4
4
  ---
5
5
 
6
6
  # `update` and `merge` — atomic read-modify-write
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cache-utils
3
- description: 'Low-level cache utilities re-exported from @warlock.js/cache — parseTtl, expiresAtToTtl, resolveTtl, normalizeToOptions, normalizeToRememberOptions, parseCacheKey, mergeTagSets, injectTags, cosineSimilarity, and the CACHE_FOR TTL enum. Triggers: `parseTtl`, `parseCacheKey`, `resolveTtl`, `expiresAtToTtl`, `cosineSimilarity`, `mergeTagSets`, `injectTags`, `CACHE_FOR`; "parse a duration to seconds", "build a cache key from an object", "score two vectors", "common TTL constant"; typical import `import { parseTtl, CACHE_FOR } from "@warlock.js/cache"`. Skip: building a whole custom driver — `@warlock.js/cache/pick-cache-driver/SKILL.md`; the high-level set API — `@warlock.js/cache/configure-set-options/SKILL.md`.'
3
+ description: "Cache utilities in @warlock.js/cache; use when you need to use cache utils."
4
4
  ---
5
5
 
6
6
  # Cache utilities
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-cached-hof
3
- description: 'Wrap an async function with cached(fn, options) — declare the caching strategy once, call from many sites, get a bound .invalidate(...args) helper. Triggers: `cached`, `invalidate`, `key`, `ttl`, `tags`, `driver`; "wrap a DB lookup with caching", "memoize a function and invalidate by args", "one declaration many call sites", "auto-derive cache key from args"; typical import `import { cached } from "@warlock.js/cache"`. Skip: one-shot memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md` (`cache.remember`); tag bulk drop — `@warlock.js/cache/use-cache-tags/SKILL.md`; competing libs `p-memoize`, `mem`, `lodash.memoize`.'
3
+ description: "cached() — function-memoization wrapper in @warlock.js/cache; use when you need to use cached hof."
4
4
  ---
5
5
 
6
6
  # `cached()` — function-memoization wrapper
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: use-swr
3
- description: 'Stale-while-revalidate via cache.swr(key, {freshTtl, staleTtl}, fn) — returns cached instantly when fresh, returns cached + background refresh when stale, blocks only when fully expired. Triggers: `cache.swr`, `freshTtl`, `staleTtl`, `tags`, `driver`, `stale_at`; "serve stale while refreshing", "degrade when upstream is down", "never block on cache miss"; typical import `import { cache } from "@warlock.js/cache"`. Skip: block-until-fresh memoization — `@warlock.js/cache/apply-cache-patterns/SKILL.md`; observing refresh failures — `@warlock.js/cache/observe-cache/SKILL.md`; competing libs `swr` (React, client-side).'
3
+ description: "Stale-while-revalidate — cache.swr(key, options, fn) in @warlock.js/cache; use when you need to use swr."
4
4
  ---
5
5
 
6
6
  # Stale-while-revalidate — `cache.swr(key, options, fn)`