@warlock.js/cache 5.28.0 → 5.30.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 +18 -0
- package/cjs/index.cjs +91 -47
- package/cjs/index.cjs.map +1 -1
- package/esm/cache-manager.d.mts +1 -1
- package/esm/cache-manager.d.mts.map +1 -1
- package/esm/cache-manager.mjs +1 -1
- package/esm/cache-manager.mjs.map +1 -1
- package/esm/cached/auto-key.d.mts +1 -1
- package/esm/cached/auto-key.d.mts.map +1 -1
- package/esm/cached/auto-key.mjs +1 -1
- package/esm/cached/auto-key.mjs.map +1 -1
- package/esm/cached/cached.d.mts +1 -1
- package/esm/cached/cached.d.mts.map +1 -1
- package/esm/cached/cached.mjs +1 -1
- package/esm/cached/cached.mjs.map +1 -1
- package/esm/cached/normalize-args.d.mts +1 -1
- package/esm/cached/normalize-args.d.mts.map +1 -1
- package/esm/cached/normalize-args.mjs +1 -1
- package/esm/cached/normalize-args.mjs.map +1 -1
- package/esm/drivers/base-cache-driver.d.mts +11 -5
- package/esm/drivers/base-cache-driver.d.mts.map +1 -1
- package/esm/drivers/base-cache-driver.mjs +29 -13
- package/esm/drivers/base-cache-driver.mjs.map +1 -1
- package/esm/drivers/file-cache-driver.d.mts +1 -1
- package/esm/drivers/file-cache-driver.d.mts.map +1 -1
- package/esm/drivers/file-cache-driver.mjs +2 -2
- package/esm/drivers/file-cache-driver.mjs.map +1 -1
- package/esm/drivers/in-memory-tag-index.d.mts +1 -1
- package/esm/drivers/in-memory-tag-index.d.mts.map +1 -1
- package/esm/drivers/in-memory-tag-index.mjs +1 -1
- package/esm/drivers/in-memory-tag-index.mjs.map +1 -1
- package/esm/drivers/index.d.mts +1 -1
- package/esm/drivers/index.mjs +1 -1
- package/esm/drivers/lru-memory-cache-driver.d.mts +1 -1
- package/esm/drivers/lru-memory-cache-driver.d.mts.map +1 -1
- package/esm/drivers/lru-memory-cache-driver.mjs +3 -2
- package/esm/drivers/lru-memory-cache-driver.mjs.map +1 -1
- package/esm/drivers/memory-cache-driver.d.mts +1 -1
- package/esm/drivers/memory-cache-driver.d.mts.map +1 -1
- package/esm/drivers/memory-cache-driver.mjs +3 -2
- package/esm/drivers/memory-cache-driver.mjs.map +1 -1
- package/esm/drivers/memory-extended-cache-driver.d.mts +1 -1
- package/esm/drivers/memory-extended-cache-driver.d.mts.map +1 -1
- package/esm/drivers/memory-extended-cache-driver.mjs +1 -1
- package/esm/drivers/memory-extended-cache-driver.mjs.map +1 -1
- package/esm/drivers/mock-cache-driver.d.mts +1 -1
- package/esm/drivers/mock-cache-driver.d.mts.map +1 -1
- package/esm/drivers/mock-cache-driver.mjs +3 -2
- package/esm/drivers/mock-cache-driver.mjs.map +1 -1
- package/esm/drivers/null-cache-driver.d.mts +5 -1
- package/esm/drivers/null-cache-driver.d.mts.map +1 -1
- package/esm/drivers/null-cache-driver.mjs +17 -10
- package/esm/drivers/null-cache-driver.mjs.map +1 -1
- package/esm/drivers/pg-cache-driver.d.mts +1 -1
- package/esm/drivers/pg-cache-driver.d.mts.map +1 -1
- package/esm/drivers/pg-cache-driver.mjs +3 -2
- package/esm/drivers/pg-cache-driver.mjs.map +1 -1
- package/esm/drivers/redis-cache-driver.d.mts +14 -2
- package/esm/drivers/redis-cache-driver.d.mts.map +1 -1
- package/esm/drivers/redis-cache-driver.mjs +24 -4
- package/esm/drivers/redis-cache-driver.mjs.map +1 -1
- package/esm/index.d.mts +2 -2
- package/esm/index.mjs +2 -2
- package/esm/list/memory-cache-list.d.mts +1 -1
- package/esm/list/memory-cache-list.d.mts.map +1 -1
- package/esm/list/memory-cache-list.mjs +1 -1
- package/esm/list/memory-cache-list.mjs.map +1 -1
- package/esm/metrics.d.mts +1 -1
- package/esm/metrics.d.mts.map +1 -1
- package/esm/metrics.mjs +1 -1
- package/esm/metrics.mjs.map +1 -1
- package/esm/scoped-cache.d.mts +1 -1
- package/esm/scoped-cache.d.mts.map +1 -1
- package/esm/scoped-cache.mjs +1 -1
- package/esm/scoped-cache.mjs.map +1 -1
- package/esm/tagged-cache.d.mts +1 -1
- package/esm/tagged-cache.d.mts.map +1 -1
- package/esm/tagged-cache.mjs +1 -1
- package/esm/tagged-cache.mjs.map +1 -1
- package/esm/tagged-scoped-cache.d.mts +1 -1
- package/esm/tagged-scoped-cache.d.mts.map +1 -1
- package/esm/tagged-scoped-cache.mjs +1 -1
- package/esm/tagged-scoped-cache.mjs.map +1 -1
- package/esm/types.d.mts +1 -1
- package/esm/types.d.mts.map +1 -1
- package/esm/types.mjs +1 -1
- package/esm/types.mjs.map +1 -1
- package/esm/utils.d.mts +1 -1
- package/esm/utils.d.mts.map +1 -1
- package/esm/utils.mjs +1 -1
- package/esm/utils.mjs.map +1 -1
- package/llms-full.txt +107 -103
- package/llms.txt +18 -18
- package/package.json +5 -4
- package/skills/apply-cache-patterns/SKILL.md +10 -10
- package/skills/cache-basics/SKILL.md +24 -20
- package/skills/configure-pg-cache/SKILL.md +5 -5
- package/skills/configure-set-options/SKILL.md +3 -3
- package/skills/handle-cache-errors/SKILL.md +3 -3
- package/skills/observe-cache/SKILL.md +1 -1
- package/skills/overview/SKILL.md +21 -21
- package/skills/pick-cache-driver/SKILL.md +4 -4
- package/skills/test-cache-code/SKILL.md +2 -2
- package/skills/use-cache-atomic/SKILL.md +5 -5
- package/skills/use-cache-bulk/SKILL.md +5 -5
- package/skills/use-cache-list/SKILL.md +2 -2
- package/skills/use-cache-lock/SKILL.md +2 -2
- package/skills/use-cache-namespace/SKILL.md +4 -4
- package/skills/use-cache-similarity/SKILL.md +2 -2
- package/skills/use-cache-tags/SKILL.md +4 -4
- package/skills/use-cache-update-merge/SKILL.md +1 -1
- package/skills/use-cache-utils/SKILL.md +4 -4
- package/skills/use-cached-hof/SKILL.md +2 -2
- package/skills/use-swr/SKILL.md +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ 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.30.0 - 2026-10-16
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Email addresses inside logged cache keys are masked (`user.member@example.com` logs as `u***@example.com`), in the base driver's operation log, in error lines (written even with logging off: SWR refresh failures, lock release, clone failures), in the "Cannot increment non-numeric value" error, and in the null driver (FW-04).
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`redis` driver `increment()` works on Redis 6.** With a default `ttl` configured it ran `EXPIRE … NX`, which only Redis 7+ accepts: on Redis 6 the call threw after the count had already gone up, which silently disabled login throttles and the cache-backed rate limiter. The increment and the default TTL are now applied together by one Lua script, and a TTL the counter already has is never shortened.
|
|
16
|
+
- The default `increment()` (file and null drivers) reads a counter's value and deadline in one read. A counter that expired between two separate reads used to be rewritten from its stale value with no expiry at all, and every increment rounded the remaining TTL up, pushing the deadline up to a second later each time.
|
|
17
|
+
- `file` driver: an entry stored without a TTL (its `expiresAt` is written to JSON as `null`) was read back by the internal entry reader as already expired, so `swr()` freshness checks and TTL-preserving writes treated it as missing.
|
|
18
|
+
|
|
19
|
+
## 5.29.0 - 2026-10-01
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Lockstep release; package APIs are unchanged. Skills refer to other topics by name instead of file paths, so cross-references keep working after `agent-kit` copies them into an app.
|
|
24
|
+
|
|
7
25
|
## 5.28.0 - 2026-10-01
|
|
8
26
|
|
|
9
27
|
### Changed
|
package/cjs/index.cjs
CHANGED
|
@@ -37,7 +37,7 @@ let _warlock_js_fs = require("@warlock.js/fs");
|
|
|
37
37
|
let path = require("path");
|
|
38
38
|
path = __toESM(path, 1);
|
|
39
39
|
|
|
40
|
-
//#region
|
|
40
|
+
//#region ../../packages/cache/src/metrics.ts
|
|
41
41
|
/**
|
|
42
42
|
* Default size of the circular latency-sample buffer. 1000 samples covers
|
|
43
43
|
* "tell me the current p95" for every realistic workload while keeping the
|
|
@@ -232,7 +232,7 @@ var CacheMetricsCollector = class {
|
|
|
232
232
|
};
|
|
233
233
|
|
|
234
234
|
//#endregion
|
|
235
|
-
//#region
|
|
235
|
+
//#region ../../packages/cache/src/types.ts
|
|
236
236
|
/**
|
|
237
237
|
* Base error class for cache-related errors
|
|
238
238
|
*/
|
|
@@ -292,7 +292,7 @@ var CacheConcurrencyError = class extends CacheError {
|
|
|
292
292
|
};
|
|
293
293
|
|
|
294
294
|
//#endregion
|
|
295
|
-
//#region
|
|
295
|
+
//#region ../../packages/cache/src/utils.ts
|
|
296
296
|
/**
|
|
297
297
|
* Make a proper key for the cache
|
|
298
298
|
*/
|
|
@@ -549,7 +549,7 @@ let CACHE_FOR = /* @__PURE__ */ function(CACHE_FOR) {
|
|
|
549
549
|
}({});
|
|
550
550
|
|
|
551
551
|
//#endregion
|
|
552
|
-
//#region
|
|
552
|
+
//#region ../../packages/cache/src/tagged-scoped-cache.ts
|
|
553
553
|
/**
|
|
554
554
|
* One-shot tagged write handle on top of a {@link ScopedCache}.
|
|
555
555
|
*
|
|
@@ -698,7 +698,7 @@ var TaggedScopedCache = class {
|
|
|
698
698
|
};
|
|
699
699
|
|
|
700
700
|
//#endregion
|
|
701
|
-
//#region
|
|
701
|
+
//#region ../../packages/cache/src/scoped-cache.ts
|
|
702
702
|
/**
|
|
703
703
|
* Scoped view over a cache source. Returned by `cache.namespace(prefix, options?)`.
|
|
704
704
|
*
|
|
@@ -979,7 +979,7 @@ var ScopedCache = class ScopedCache {
|
|
|
979
979
|
};
|
|
980
980
|
|
|
981
981
|
//#endregion
|
|
982
|
-
//#region
|
|
982
|
+
//#region ../../packages/cache/src/cache-manager.ts
|
|
983
983
|
var CacheManager = class {
|
|
984
984
|
constructor() {
|
|
985
985
|
this.loadedDrivers = {};
|
|
@@ -1477,7 +1477,7 @@ var CacheManager = class {
|
|
|
1477
1477
|
const cache = new CacheManager();
|
|
1478
1478
|
|
|
1479
1479
|
//#endregion
|
|
1480
|
-
//#region
|
|
1480
|
+
//#region ../../packages/cache/src/cached/auto-key.ts
|
|
1481
1481
|
/**
|
|
1482
1482
|
* Derive a cache key from a prefix and a set of function arguments.
|
|
1483
1483
|
*
|
|
@@ -1543,7 +1543,7 @@ function normalize(value, prefix, seen) {
|
|
|
1543
1543
|
}
|
|
1544
1544
|
|
|
1545
1545
|
//#endregion
|
|
1546
|
-
//#region
|
|
1546
|
+
//#region ../../packages/cache/src/cached/normalize-args.ts
|
|
1547
1547
|
/**
|
|
1548
1548
|
* Resolve the positional-or-options arguments of `cached()` into a single
|
|
1549
1549
|
* normalized config. Keeps the wrapper body free of shape-checks.
|
|
@@ -1565,7 +1565,7 @@ function normalizeCachedArgs(prefixOrOptions, maybeTtl) {
|
|
|
1565
1565
|
}
|
|
1566
1566
|
|
|
1567
1567
|
//#endregion
|
|
1568
|
-
//#region
|
|
1568
|
+
//#region ../../packages/cache/src/cached/cached.ts
|
|
1569
1569
|
function cached(fn, prefixOrOptions, maybeTtl) {
|
|
1570
1570
|
const config = normalizeCachedArgs(prefixOrOptions, maybeTtl);
|
|
1571
1571
|
const buildRememberOptions = () => ({
|
|
@@ -1589,7 +1589,7 @@ function cached(fn, prefixOrOptions, maybeTtl) {
|
|
|
1589
1589
|
}
|
|
1590
1590
|
|
|
1591
1591
|
//#endregion
|
|
1592
|
-
//#region
|
|
1592
|
+
//#region ../../packages/cache/src/list/memory-cache-list.ts
|
|
1593
1593
|
/**
|
|
1594
1594
|
* Generic array-backed {@link CacheListAccessor}.
|
|
1595
1595
|
*
|
|
@@ -1708,7 +1708,7 @@ var MemoryCacheList = class {
|
|
|
1708
1708
|
};
|
|
1709
1709
|
|
|
1710
1710
|
//#endregion
|
|
1711
|
-
//#region
|
|
1711
|
+
//#region ../../packages/cache/src/tagged-cache.ts
|
|
1712
1712
|
/**
|
|
1713
1713
|
* Tagged Cache Wrapper
|
|
1714
1714
|
* Wraps a cache driver to automatically manage tag relationships
|
|
@@ -1916,7 +1916,7 @@ var TaggedCache = class TaggedCache {
|
|
|
1916
1916
|
};
|
|
1917
1917
|
|
|
1918
1918
|
//#endregion
|
|
1919
|
-
//#region
|
|
1919
|
+
//#region ../../packages/cache/src/drivers/base-cache-driver.ts
|
|
1920
1920
|
const messages = {
|
|
1921
1921
|
clearing: "Clearing namespace",
|
|
1922
1922
|
cleared: "Namespace cleared",
|
|
@@ -2309,20 +2309,30 @@ var BaseCacheDriver = class {
|
|
|
2309
2309
|
* {@inheritdoc}
|
|
2310
2310
|
*
|
|
2311
2311
|
* Default implementation: read-add-write serialized per key in THIS process,
|
|
2312
|
-
* keeping the entry's
|
|
2313
|
-
*
|
|
2314
|
-
*
|
|
2312
|
+
* keeping the entry's deadline (a missing key starts from 0 with the driver
|
|
2313
|
+
* default TTL). Not atomic across servers: drivers with a native primitive
|
|
2314
|
+
* override it (redis `INCRBY`, pg single-statement upsert).
|
|
2315
|
+
*
|
|
2316
|
+
* The value and its deadline come from ONE read. Reading them separately
|
|
2317
|
+
* let a counter that expired in between be rewritten from its stale value
|
|
2318
|
+
* with no expiry at all (a login-throttle counter that then never resets).
|
|
2319
|
+
* The remaining TTL is rounded down, so repeated increments can never push
|
|
2320
|
+
* a window's deadline later.
|
|
2315
2321
|
*/
|
|
2316
2322
|
async increment(key, value = 1) {
|
|
2317
2323
|
const parsedKey = this.parseKey(key);
|
|
2318
2324
|
return this.runSerialized(parsedKey, async () => {
|
|
2319
|
-
const
|
|
2325
|
+
const entry = await this.getEntry(key);
|
|
2326
|
+
const now = Date.now();
|
|
2327
|
+
const expiresAt = entry?.expiresAt;
|
|
2328
|
+
const live = entry ? expiresAt == null || expiresAt > now : false;
|
|
2329
|
+
const current = entry && live ? entry.data : null;
|
|
2320
2330
|
const base = current === null || current === void 0 ? 0 : current;
|
|
2321
|
-
if (typeof base !== "number") throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);
|
|
2331
|
+
if (typeof base !== "number") throw new Error(`Cannot increment non-numeric value for key: ${(0, _warlock_js_logger.maskEmailsInText)(parsedKey)}`);
|
|
2322
2332
|
const newValue = base + value;
|
|
2323
|
-
|
|
2324
|
-
if (
|
|
2325
|
-
else await this.set(key, newValue);
|
|
2333
|
+
if (!live) await this.set(key, newValue);
|
|
2334
|
+
else if (expiresAt == null || expiresAt === Infinity) await this.set(key, newValue, { ttl: Infinity });
|
|
2335
|
+
else await this.set(key, newValue, { ttl: Math.max(1, Math.floor((expiresAt - now) / 1e3)) });
|
|
2326
2336
|
return newValue;
|
|
2327
2337
|
});
|
|
2328
2338
|
}
|
|
@@ -2349,7 +2359,7 @@ var BaseCacheDriver = class {
|
|
|
2349
2359
|
*/
|
|
2350
2360
|
log(operation, key) {
|
|
2351
2361
|
if (!this.shouldLog) return;
|
|
2352
|
-
if (typeof key === "string") key = key.replace(/\//g, ".");
|
|
2362
|
+
if (typeof key === "string") key = (0, _warlock_js_logger.maskEmailsInText)(key.replace(/\//g, "."));
|
|
2353
2363
|
if (operation === "connectionFailed") _warlock_js_logger.log.fatal(`cache.${this.name}`, operation, key);
|
|
2354
2364
|
if (operation == "notFound" || operation == "expired") return _warlock_js_logger.log.info("cache." + this.name, operation, (key ? key + " " : "") + messages[operation]);
|
|
2355
2365
|
if (operation.endsWith("ed")) return _warlock_js_logger.log.success("cache." + this.name, operation, (key ? key + " " : "") + messages[operation]);
|
|
@@ -2364,8 +2374,14 @@ var BaseCacheDriver = class {
|
|
|
2364
2374
|
* passed to the structured logger.
|
|
2365
2375
|
*/
|
|
2366
2376
|
logError(message, error) {
|
|
2367
|
-
|
|
2368
|
-
|
|
2377
|
+
const maskedMessage = (0, _warlock_js_logger.maskEmailsInText)(message);
|
|
2378
|
+
if (error) {
|
|
2379
|
+
const info = safeErrorInfo(error);
|
|
2380
|
+
_warlock_js_logger.log.error("cache." + this.name, "error", maskedMessage, {
|
|
2381
|
+
...info,
|
|
2382
|
+
message: (0, _warlock_js_logger.maskEmailsInText)(info.message)
|
|
2383
|
+
});
|
|
2384
|
+
} else _warlock_js_logger.log.error("cache." + this.name, "error", maskedMessage);
|
|
2369
2385
|
}
|
|
2370
2386
|
/**
|
|
2371
2387
|
* Get the default TTL in seconds. Parses human-readable strings (`"1h"`, `"30m"`)
|
|
@@ -2560,7 +2576,7 @@ var BaseCacheDriver = class {
|
|
|
2560
2576
|
};
|
|
2561
2577
|
|
|
2562
2578
|
//#endregion
|
|
2563
|
-
//#region
|
|
2579
|
+
//#region ../../packages/cache/src/drivers/file-cache-driver.ts
|
|
2564
2580
|
var FileCacheDriver = class extends BaseCacheDriver {
|
|
2565
2581
|
constructor(..._args) {
|
|
2566
2582
|
super(..._args);
|
|
@@ -2770,7 +2786,7 @@ var FileCacheDriver = class extends BaseCacheDriver {
|
|
|
2770
2786
|
try {
|
|
2771
2787
|
const entry = await (0, _warlock_js_fs.getJsonFileAsync)(path.default.resolve(fileDirectory, this.fileName));
|
|
2772
2788
|
if (!entry) return null;
|
|
2773
|
-
if (entry.expiresAt
|
|
2789
|
+
if (typeof entry.expiresAt === "number" && entry.expiresAt <= Date.now()) return null;
|
|
2774
2790
|
return entry;
|
|
2775
2791
|
} catch {
|
|
2776
2792
|
return null;
|
|
@@ -2837,7 +2853,7 @@ var FileCacheDriver = class extends BaseCacheDriver {
|
|
|
2837
2853
|
};
|
|
2838
2854
|
|
|
2839
2855
|
//#endregion
|
|
2840
|
-
//#region
|
|
2856
|
+
//#region ../../packages/cache/src/drivers/in-memory-tag-index.ts
|
|
2841
2857
|
/**
|
|
2842
2858
|
* Tag index for the in-process drivers (memory, memoryExtended, lru, mock).
|
|
2843
2859
|
*
|
|
@@ -2908,7 +2924,7 @@ var InMemoryTagIndex = class {
|
|
|
2908
2924
|
};
|
|
2909
2925
|
|
|
2910
2926
|
//#endregion
|
|
2911
|
-
//#region
|
|
2927
|
+
//#region ../../packages/cache/src/drivers/lru-memory-cache-driver.ts
|
|
2912
2928
|
var CacheNode = class {
|
|
2913
2929
|
constructor(key, value, ttl) {
|
|
2914
2930
|
this.key = key;
|
|
@@ -3120,7 +3136,7 @@ var LRUMemoryCacheDriver = class extends BaseCacheDriver {
|
|
|
3120
3136
|
const parsedKey = this.parseKey(key);
|
|
3121
3137
|
const node = this.liveNode(parsedKey);
|
|
3122
3138
|
const current = node ? node.value : 0;
|
|
3123
|
-
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);
|
|
3139
|
+
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${(0, _warlock_js_logger.maskEmailsInText)(parsedKey)}`);
|
|
3124
3140
|
const newValue = current + value;
|
|
3125
3141
|
if (node) {
|
|
3126
3142
|
node.value = newValue;
|
|
@@ -3315,7 +3331,7 @@ var LRUMemoryCacheDriver = class extends BaseCacheDriver {
|
|
|
3315
3331
|
};
|
|
3316
3332
|
|
|
3317
3333
|
//#endregion
|
|
3318
|
-
//#region
|
|
3334
|
+
//#region ../../packages/cache/src/drivers/memory-cache-driver.ts
|
|
3319
3335
|
/**
|
|
3320
3336
|
* Clone non-primitive values so cached state can't be mutated through
|
|
3321
3337
|
* references held by callers. Primitives are immutable and returned as-is.
|
|
@@ -3491,7 +3507,7 @@ var MemoryCacheDriver = class extends BaseCacheDriver {
|
|
|
3491
3507
|
const parsedKey = this.parseKey(key);
|
|
3492
3508
|
const entry = this.readLive(parsedKey);
|
|
3493
3509
|
const current = entry ? entry.data : 0;
|
|
3494
|
-
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);
|
|
3510
|
+
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${(0, _warlock_js_logger.maskEmailsInText)(parsedKey)}`);
|
|
3495
3511
|
const newValue = current + value;
|
|
3496
3512
|
if (entry) {
|
|
3497
3513
|
entry.data = newValue;
|
|
@@ -3674,7 +3690,7 @@ var MemoryCacheDriver = class extends BaseCacheDriver {
|
|
|
3674
3690
|
};
|
|
3675
3691
|
|
|
3676
3692
|
//#endregion
|
|
3677
|
-
//#region
|
|
3693
|
+
//#region ../../packages/cache/src/drivers/memory-extended-cache-driver.ts
|
|
3678
3694
|
/**
|
|
3679
3695
|
* Memory driver with a sliding ttl: every live read pushes the entry's
|
|
3680
3696
|
* expiration forward by its ttl. The sliding itself lives in
|
|
@@ -3691,7 +3707,7 @@ var MemoryExtendedCacheDriver = class extends MemoryCacheDriver {
|
|
|
3691
3707
|
};
|
|
3692
3708
|
|
|
3693
3709
|
//#endregion
|
|
3694
|
-
//#region
|
|
3710
|
+
//#region ../../packages/cache/src/drivers/mock-cache-driver.ts
|
|
3695
3711
|
/**
|
|
3696
3712
|
* In-memory cache driver with introspection helpers, intended for use as a
|
|
3697
3713
|
* test double in downstream packages.
|
|
@@ -3862,7 +3878,7 @@ var MockCacheDriver = class extends BaseCacheDriver {
|
|
|
3862
3878
|
this.recordCall("increment", parsedKey, [value]);
|
|
3863
3879
|
const entry = this.liveEntry(parsedKey);
|
|
3864
3880
|
const current = entry ? entry.data : 0;
|
|
3865
|
-
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);
|
|
3881
|
+
if (typeof current !== "number") throw new Error(`Cannot increment non-numeric value for key: ${(0, _warlock_js_logger.maskEmailsInText)(parsedKey)}`);
|
|
3866
3882
|
const newValue = current + value;
|
|
3867
3883
|
if (entry) entry.data = newValue;
|
|
3868
3884
|
else this.storage.set(parsedKey, this.prepareDataForStorage(newValue, this.ttl));
|
|
@@ -4009,7 +4025,7 @@ var MockCacheDriver = class extends BaseCacheDriver {
|
|
|
4009
4025
|
};
|
|
4010
4026
|
|
|
4011
4027
|
//#endregion
|
|
4012
|
-
//#region
|
|
4028
|
+
//#region ../../packages/cache/src/drivers/null-cache-driver.ts
|
|
4013
4029
|
var NullCacheDriver = class extends BaseCacheDriver {
|
|
4014
4030
|
/**
|
|
4015
4031
|
* {@inheritdoc}
|
|
@@ -4052,32 +4068,39 @@ var NullCacheDriver = class extends BaseCacheDriver {
|
|
|
4052
4068
|
* {@inheritdoc}
|
|
4053
4069
|
*/
|
|
4054
4070
|
async removeNamespace(namespace) {
|
|
4055
|
-
|
|
4056
|
-
_warlock_js_logger.log.
|
|
4071
|
+
const loggableNamespace = (0, _warlock_js_logger.maskEmailsInText)(namespace);
|
|
4072
|
+
_warlock_js_logger.log.info("cache", "clearing namespace", loggableNamespace);
|
|
4073
|
+
_warlock_js_logger.log.success("cache", "namespace cleared", loggableNamespace);
|
|
4057
4074
|
return this;
|
|
4058
4075
|
}
|
|
4059
4076
|
/**
|
|
4077
|
+
* The key as it may appear in a log line: parsed, with email addresses masked
|
|
4078
|
+
*/
|
|
4079
|
+
loggableKey(key) {
|
|
4080
|
+
return (0, _warlock_js_logger.maskEmailsInText)(this.parseKey(key));
|
|
4081
|
+
}
|
|
4082
|
+
/**
|
|
4060
4083
|
* {@inheritdoc}
|
|
4061
4084
|
*/
|
|
4062
4085
|
async set(key, _value, _ttlOrOptions) {
|
|
4063
|
-
_warlock_js_logger.log.info("cache", "setting key", key);
|
|
4064
|
-
_warlock_js_logger.log.success("cache", "key set", key);
|
|
4086
|
+
_warlock_js_logger.log.info("cache", "setting key", this.loggableKey(key));
|
|
4087
|
+
_warlock_js_logger.log.success("cache", "key set", this.loggableKey(key));
|
|
4065
4088
|
return this;
|
|
4066
4089
|
}
|
|
4067
4090
|
/**
|
|
4068
4091
|
* {@inheritdoc}
|
|
4069
4092
|
*/
|
|
4070
4093
|
async get(key) {
|
|
4071
|
-
_warlock_js_logger.log.info("cache", "fetching", key);
|
|
4072
|
-
_warlock_js_logger.log.success("cache", "fetched", key);
|
|
4094
|
+
_warlock_js_logger.log.info("cache", "fetching", this.loggableKey(key));
|
|
4095
|
+
_warlock_js_logger.log.success("cache", "fetched", this.loggableKey(key));
|
|
4073
4096
|
return null;
|
|
4074
4097
|
}
|
|
4075
4098
|
/**
|
|
4076
4099
|
* {@inheritdoc}
|
|
4077
4100
|
*/
|
|
4078
4101
|
async remove(key) {
|
|
4079
|
-
_warlock_js_logger.log.info("cache", "removing", key);
|
|
4080
|
-
_warlock_js_logger.log.success("cache", "removed", key);
|
|
4102
|
+
_warlock_js_logger.log.info("cache", "removing", this.loggableKey(key));
|
|
4103
|
+
_warlock_js_logger.log.success("cache", "removed", this.loggableKey(key));
|
|
4081
4104
|
}
|
|
4082
4105
|
/**
|
|
4083
4106
|
* {@inheritdoc}
|
|
@@ -4104,7 +4127,7 @@ var NullCacheDriver = class extends BaseCacheDriver {
|
|
|
4104
4127
|
};
|
|
4105
4128
|
|
|
4106
4129
|
//#endregion
|
|
4107
|
-
//#region
|
|
4130
|
+
//#region ../../packages/cache/src/drivers/pg-cache-driver.ts
|
|
4108
4131
|
/** Compare-and-set attempts before `update()` gives up under contention. */
|
|
4109
4132
|
const PG_UPDATE_MAX_ATTEMPTS = 10;
|
|
4110
4133
|
/**
|
|
@@ -4556,7 +4579,7 @@ var PgCacheDriver = class extends BaseCacheDriver {
|
|
|
4556
4579
|
value,
|
|
4557
4580
|
this.ttlToSeconds(this.ttl)
|
|
4558
4581
|
]);
|
|
4559
|
-
if (rows.length === 0) throw new Error(`Cannot increment non-numeric value for key: ${parsedKey}`);
|
|
4582
|
+
if (rows.length === 0) throw new Error(`Cannot increment non-numeric value for key: ${(0, _warlock_js_logger.maskEmailsInText)(parsedKey)}`);
|
|
4560
4583
|
const newValue = Number(this.decodeJson(rows[0].value));
|
|
4561
4584
|
await this.emit("set", {
|
|
4562
4585
|
key: parsedKey,
|
|
@@ -4757,7 +4780,7 @@ var PgCacheDriver = class extends BaseCacheDriver {
|
|
|
4757
4780
|
};
|
|
4758
4781
|
|
|
4759
4782
|
//#endregion
|
|
4760
|
-
//#region
|
|
4783
|
+
//#region ../../packages/cache/src/drivers/redis-cache-driver.ts
|
|
4761
4784
|
/**
|
|
4762
4785
|
* Cached Redis module (loaded once, reused)
|
|
4763
4786
|
*/
|
|
@@ -4821,6 +4844,23 @@ return 1`;
|
|
|
4821
4844
|
const REDIS_GET_DEL_SCRIPT = `local v = redis.call('GET', KEYS[1])
|
|
4822
4845
|
if v then redis.call('DEL', KEYS[1]) end
|
|
4823
4846
|
return v`;
|
|
4847
|
+
/**
|
|
4848
|
+
* Increment that gives a counter without an expiry the driver's default TTL,
|
|
4849
|
+
* in one round trip.
|
|
4850
|
+
*
|
|
4851
|
+
* KEYS[1]=key; ARGV[1]=amount; ARGV[2]=ttl seconds ('0' = none).
|
|
4852
|
+
*
|
|
4853
|
+
* Replaces `INCRBY` + `EXPIRE … NX`: the `NX` flag needs Redis >= 7.0, and on
|
|
4854
|
+
* Redis 6 the second command failed after the count had already gone up.
|
|
4855
|
+
* `TTL == -1` means "exists without an expiry", so a TTL set earlier (by
|
|
4856
|
+
* `set(..., { ttl })`) is never shortened or reset.
|
|
4857
|
+
*/
|
|
4858
|
+
const REDIS_INCREMENT_SCRIPT = `local v = redis.call('INCRBY', KEYS[1], ARGV[1])
|
|
4859
|
+
local ttl = tonumber(ARGV[2])
|
|
4860
|
+
if ttl > 0 and redis.call('TTL', KEYS[1]) == -1 then
|
|
4861
|
+
redis.call('EXPIRE', KEYS[1], ttl)
|
|
4862
|
+
end
|
|
4863
|
+
return v`;
|
|
4824
4864
|
/** Compare-and-set attempts before `update()` gives up under contention. */
|
|
4825
4865
|
const UPDATE_MAX_ATTEMPTS = 10;
|
|
4826
4866
|
/** Keys deleted per UNLINK/DEL while draining a namespace. */
|
|
@@ -5252,8 +5292,11 @@ var RedisCacheDriver = class extends BaseCacheDriver {
|
|
|
5252
5292
|
async increment(key, value = 1) {
|
|
5253
5293
|
const parsedKey = this.parseKey(key);
|
|
5254
5294
|
this.log("caching", parsedKey);
|
|
5255
|
-
const
|
|
5256
|
-
|
|
5295
|
+
const defaultTtl = Number.isFinite(this.ttl) && this.ttl > 0 ? Math.ceil(this.ttl) : 0;
|
|
5296
|
+
const result = defaultTtl > 0 ? Number(await this.client?.eval(REDIS_INCREMENT_SCRIPT, {
|
|
5297
|
+
keys: [parsedKey],
|
|
5298
|
+
arguments: [String(value), String(defaultTtl)]
|
|
5299
|
+
})) : await this.client?.incrBy(parsedKey, value);
|
|
5257
5300
|
this.log("cached", parsedKey);
|
|
5258
5301
|
await this.emit("set", {
|
|
5259
5302
|
key: parsedKey,
|
|
@@ -5327,6 +5370,7 @@ exports.PgCacheDriver = PgCacheDriver;
|
|
|
5327
5370
|
exports.REDIS_CAS_SET_SCRIPT = REDIS_CAS_SET_SCRIPT;
|
|
5328
5371
|
exports.REDIS_COMPARE_DELETE_SCRIPT = REDIS_COMPARE_DELETE_SCRIPT;
|
|
5329
5372
|
exports.REDIS_GET_DEL_SCRIPT = REDIS_GET_DEL_SCRIPT;
|
|
5373
|
+
exports.REDIS_INCREMENT_SCRIPT = REDIS_INCREMENT_SCRIPT;
|
|
5330
5374
|
exports.RedisCacheDriver = RedisCacheDriver;
|
|
5331
5375
|
exports.ScopedCache = ScopedCache;
|
|
5332
5376
|
exports.TaggedCache = TaggedCache;
|