@dcsv-io/d2-caching-abstractions 0.1.1
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/LICENSE +190 -0
- package/README.md +263 -0
- package/dist/i-cache-atomic.d.ts +69 -0
- package/dist/i-cache-atomic.d.ts.map +1 -0
- package/dist/i-cache-atomic.js +5 -0
- package/dist/i-cache-atomic.js.map +1 -0
- package/dist/i-cache-basic.d.ts +90 -0
- package/dist/i-cache-basic.d.ts.map +1 -0
- package/dist/i-cache-basic.js +5 -0
- package/dist/i-cache-basic.js.map +1 -0
- package/dist/i-cache-broadcast.d.ts +47 -0
- package/dist/i-cache-broadcast.d.ts.map +1 -0
- package/dist/i-cache-broadcast.js +5 -0
- package/dist/i-cache-broadcast.js.map +1 -0
- package/dist/i-cache-invalidation-backplane.d.ts +73 -0
- package/dist/i-cache-invalidation-backplane.d.ts.map +1 -0
- package/dist/i-cache-invalidation-backplane.js +5 -0
- package/dist/i-cache-invalidation-backplane.js.map +1 -0
- package/dist/i-cache-serializer.d.ts +35 -0
- package/dist/i-cache-serializer.d.ts.map +1 -0
- package/dist/i-cache-serializer.js +5 -0
- package/dist/i-cache-serializer.js.map +1 -0
- package/dist/i-cache-set.d.ts +59 -0
- package/dist/i-cache-set.d.ts.map +1 -0
- package/dist/i-cache-set.js +5 -0
- package/dist/i-cache-set.js.map +1 -0
- package/dist/i-distributed-cache.d.ts +25 -0
- package/dist/i-distributed-cache.d.ts.map +1 -0
- package/dist/i-distributed-cache.js +5 -0
- package/dist/i-distributed-cache.js.map +1 -0
- package/dist/i-local-cache.d.ts +18 -0
- package/dist/i-local-cache.d.ts.map +1 -0
- package/dist/i-local-cache.js +5 -0
- package/dist/i-local-cache.js.map +1 -0
- package/dist/i-tiered-cache.d.ts +31 -0
- package/dist/i-tiered-cache.d.ts.map +1 -0
- package/dist/i-tiered-cache.js +5 -0
- package/dist/i-tiered-cache.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/input-failures.d.ts +27 -0
- package/dist/input-failures.d.ts.map +1 -0
- package/dist/input-failures.js +45 -0
- package/dist/input-failures.js.map +1 -0
- package/dist/local-cache-options.d.ts +40 -0
- package/dist/local-cache-options.d.ts.map +1 -0
- package/dist/local-cache-options.js +22 -0
- package/dist/local-cache-options.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { D2Result } from "@dcsv-io/d2-result";
|
|
2
|
+
/**
|
|
3
|
+
* Write surface that publishes invalidation messages via a registered
|
|
4
|
+
* {@link ICacheInvalidationBackplane} after the underlying write
|
|
5
|
+
* completes. Subscribers (typically tiered caches in other instances)
|
|
6
|
+
* drop their L1 copy of the affected key on receipt.
|
|
7
|
+
*
|
|
8
|
+
* Implemented by both {@link IDistributedCache} (so callers writing
|
|
9
|
+
* directly to L2 can still bust other instances' L1) and
|
|
10
|
+
* {@link ITieredCache} (which writes both tiers and broadcasts in one
|
|
11
|
+
* call).
|
|
12
|
+
*
|
|
13
|
+
* **Registration error carve-out:** `*AndBroadcast*` methods **throw**
|
|
14
|
+
* (not `D2Result`) when no `ICacheInvalidationBackplane` was registered
|
|
15
|
+
* with the cache. Registration error is a construction-time / wiring
|
|
16
|
+
* concern, not a per-call failure. Use the plain `set` / `remove` if
|
|
17
|
+
* you don't intend to broadcast.
|
|
18
|
+
*/
|
|
19
|
+
export interface ICacheBroadcast {
|
|
20
|
+
/**
|
|
21
|
+
* Writes a value AND publishes an invalidation message via the
|
|
22
|
+
* registered {@link ICacheInvalidationBackplane}.
|
|
23
|
+
*
|
|
24
|
+
* @throws When no backplane was registered with the cache.
|
|
25
|
+
*/
|
|
26
|
+
setAndBroadcast<T>(key: string, value: T, expirationMs?: number, signal?: AbortSignal): Promise<D2Result>;
|
|
27
|
+
/**
|
|
28
|
+
* Bulk-write counterpart of {@link setAndBroadcast}.
|
|
29
|
+
*
|
|
30
|
+
* @throws When no backplane was registered with the cache.
|
|
31
|
+
*/
|
|
32
|
+
setManyAndBroadcast<T>(entries: ReadonlyMap<string, T>, expirationMs?: number, signal?: AbortSignal): Promise<D2Result>;
|
|
33
|
+
/**
|
|
34
|
+
* Removes a key AND publishes an invalidation message so other
|
|
35
|
+
* instances drop their L1 copies.
|
|
36
|
+
*
|
|
37
|
+
* @throws When no backplane was registered with the cache.
|
|
38
|
+
*/
|
|
39
|
+
removeAndBroadcast(key: string, signal?: AbortSignal): Promise<D2Result>;
|
|
40
|
+
/**
|
|
41
|
+
* Bulk-remove + broadcast invalidation per key.
|
|
42
|
+
*
|
|
43
|
+
* @throws When no backplane was registered with the cache.
|
|
44
|
+
*/
|
|
45
|
+
removeManyAndBroadcast(keys: readonly string[], signal?: AbortSignal): Promise<D2Result>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=i-cache-broadcast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-broadcast.d.ts","sourceRoot":"","sources":["../src/i-cache-broadcast.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,CAAC,EACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,CAAC,EACR,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB;;;;OAIG;IACH,mBAAmB,CAAC,CAAC,EACnB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,EAC/B,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;IAErB;;;;;OAKG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEzE;;;;OAIG;IACH,sBAAsB,CACpB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-cache-broadcast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-broadcast.js","sourceRoot":"","sources":["../src/i-cache-broadcast.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { D2Result } from "@dcsv-io/d2-result";
|
|
2
|
+
/**
|
|
3
|
+
* Pub/sub backplane for cross-instance cache invalidation. Publishers
|
|
4
|
+
* fire when a caller uses one of the `*AndBroadcast*` variants on
|
|
5
|
+
* {@link ITieredCache} or {@link IDistributedCache}, or when any code
|
|
6
|
+
* calls {@link publishInvalidation} directly. Subscribers (typically
|
|
7
|
+
* tiered caches in other instances) receive the key and act on it —
|
|
8
|
+
* usually by dropping the named entry from their L1.
|
|
9
|
+
*
|
|
10
|
+
* Extends {@link AsyncDisposable}. Runtime: Node ≥ 20 (global
|
|
11
|
+
* `Symbol.asyncDispose`). Package `lib` includes `ESNext.Disposable`
|
|
12
|
+
* so the types resolve.
|
|
13
|
+
*
|
|
14
|
+
* **Contract (twin of .NET `ICacheInvalidationBackplane` remarks):**
|
|
15
|
+
*
|
|
16
|
+
* 1. **Everyone acts** — no sender-ID filter; the publisher receives
|
|
17
|
+
* its own messages.
|
|
18
|
+
* 2. **At-most-once** delivery (missed message → next read hits L2).
|
|
19
|
+
* 3. **Dispose unsubscribes** — disposing a subscription **removes that
|
|
20
|
+
* handler from fan-out** and **stops further invalidation key
|
|
21
|
+
* delivery** to it (primary .NET Subscribe law). Signal abort alone
|
|
22
|
+
* is **not** sufficient — unsubscribe is the delivery-stop guarantee.
|
|
23
|
+
* 4. **Signal-on-dispose** — the handler's `AbortSignal` is aborted when
|
|
24
|
+
* the **subscription** is disposed (accompanies unsubscribe; does not
|
|
25
|
+
* replace it).
|
|
26
|
+
* 5. **Handler isolation** — one handler throw must not break delivery
|
|
27
|
+
* to other handlers.
|
|
28
|
+
* 6. **Multi-sub independence** — each `subscribe` returns its own
|
|
29
|
+
* disposable; subscriptions are independent.
|
|
30
|
+
* 7. **Dispose idempotency** — disposing a subscription (or the
|
|
31
|
+
* backplane) more than once is safe (no throw).
|
|
32
|
+
* 8. **Backplane dispose cascade** — disposing the backplane tears down
|
|
33
|
+
* shared provider resources, unsubscribes remaining handlers, and
|
|
34
|
+
* cancels in-flight handler work.
|
|
35
|
+
*
|
|
36
|
+
* Provider-agnostic — Redis pub/sub is the default implementation, but
|
|
37
|
+
* the same interface can wrap Postgres LISTEN/NOTIFY, an in-process
|
|
38
|
+
* channel for tests, etc.
|
|
39
|
+
*/
|
|
40
|
+
export interface ICacheInvalidationBackplane extends AsyncDisposable {
|
|
41
|
+
/**
|
|
42
|
+
* Subscribes to receive invalidation messages. The handler is invoked
|
|
43
|
+
* once per received key (including keys this instance published).
|
|
44
|
+
* Implementations isolate errors per handler — one handler throwing
|
|
45
|
+
* does not affect delivery to other handlers.
|
|
46
|
+
*
|
|
47
|
+
* @param handler - Callback invoked for every received invalidation
|
|
48
|
+
* key. Receives the key and an optional `AbortSignal` tied to
|
|
49
|
+
* subscription lifetime (aborted when the returned subscription is
|
|
50
|
+
* disposed).
|
|
51
|
+
* @returns Disposable subscription. Dispose to **unsubscribe** (stop
|
|
52
|
+
* further key delivery to this handler); typically held as a field
|
|
53
|
+
* on the subscriber and disposed in the subscriber's own disposal
|
|
54
|
+
* so the subscription lifetime matches the subscriber.
|
|
55
|
+
*/
|
|
56
|
+
subscribe(handler: (key: string, signal?: AbortSignal) => void | Promise<void>): AsyncDisposable;
|
|
57
|
+
/**
|
|
58
|
+
* Publishes an invalidation message for a single key. Every
|
|
59
|
+
* subscriber (across every connected instance, including this one)
|
|
60
|
+
* receives the key.
|
|
61
|
+
*
|
|
62
|
+
* @returns `ok`; failure on backplane error.
|
|
63
|
+
*/
|
|
64
|
+
publishInvalidation(key: string, signal?: AbortSignal): Promise<D2Result>;
|
|
65
|
+
/**
|
|
66
|
+
* Bulk-publish counterpart of {@link publishInvalidation}.
|
|
67
|
+
* Implementations may pipeline the publishes for fewer round-trips.
|
|
68
|
+
*
|
|
69
|
+
* @returns `ok`; failure on backplane error.
|
|
70
|
+
*/
|
|
71
|
+
publishInvalidationMany(keys: readonly string[], signal?: AbortSignal): Promise<D2Result>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=i-cache-invalidation-backplane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-invalidation-backplane.d.ts","sourceRoot":"","sources":["../src/i-cache-invalidation-backplane.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,WAAW,2BAA4B,SAAQ,eAAe;IAClE;;;;;;;;;;;;;;OAcG;IACH,SAAS,CACP,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnE,eAAe,CAAC;IAEnB;;;;;;OAMG;IACH,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE1E;;;;;OAKG;IACH,uBAAuB,CACrB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-cache-invalidation-backplane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-invalidation-backplane.js","sourceRoot":"","sources":["../src/i-cache-invalidation-backplane.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { D2Result } from "@dcsv-io/d2-result";
|
|
2
|
+
/**
|
|
3
|
+
* Pluggable serialization seam for distributed caches. Local caches
|
|
4
|
+
* store objects directly and do not need this. This package owns the
|
|
5
|
+
* port only; a default JSON implementation is part of the
|
|
6
|
+
* `@dcsv-io/d2-caching-distributed-redis` package surface. Provider-specific
|
|
7
|
+
* impls may swap in MessagePack, Protobuf, etc., for size or perf wins.
|
|
8
|
+
*
|
|
9
|
+
* Impl failure codes (not defined here — reuse existing catalogs when
|
|
10
|
+
* implementing): `COULD_NOT_BE_SERIALIZED` /
|
|
11
|
+
* `COULD_NOT_BE_DESERIALIZED`.
|
|
12
|
+
*/
|
|
13
|
+
export interface ICacheSerializer {
|
|
14
|
+
/**
|
|
15
|
+
* Stable identifier for the serialization format (free string, e.g.
|
|
16
|
+
* `"application/json"`). Allows mixed-serializer DLQs / archive
|
|
17
|
+
* blobs to round-trip safely.
|
|
18
|
+
*/
|
|
19
|
+
readonly contentType: string;
|
|
20
|
+
/**
|
|
21
|
+
* Serializes `value` to bytes.
|
|
22
|
+
*
|
|
23
|
+
* @returns `ok(bytes)`; failure with a serialize error code on
|
|
24
|
+
* serializer error.
|
|
25
|
+
*/
|
|
26
|
+
serialize<T>(value: T): D2Result<Uint8Array>;
|
|
27
|
+
/**
|
|
28
|
+
* Deserializes `bytes` back to a value.
|
|
29
|
+
*
|
|
30
|
+
* @returns `ok(value)`; failure with a deserialize error code on
|
|
31
|
+
* deserializer error.
|
|
32
|
+
*/
|
|
33
|
+
deserialize<T>(bytes: Uint8Array): D2Result<T>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=i-cache-serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-serializer.d.ts","sourceRoot":"","sources":["../src/i-cache-serializer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE7C;;;;;OAKG;IACH,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;CAChD"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-cache-serializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-serializer.js","sourceRoot":"","sources":["../src/i-cache-serializer.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { D2Result } from "@dcsv-io/d2-result";
|
|
2
|
+
/**
|
|
3
|
+
* Distributed-set primitives — add-to-set, cardinality, membership.
|
|
4
|
+
* Maps to Redis SADD / SCARD / SREM / SISMEMBER. Only on
|
|
5
|
+
* {@link IDistributedCache}; per-process set-cardinality has no
|
|
6
|
+
* realistic use case (it's a single-instance counter that can't
|
|
7
|
+
* aggregate across the cluster), and tiered composition would silently
|
|
8
|
+
* hide the cluster-wide nature of the operation.
|
|
9
|
+
*
|
|
10
|
+
* The motivating use case is rate-limiting "fingerprint too common"
|
|
11
|
+
* detection: track distinct IPs ever observed for a given fingerprint,
|
|
12
|
+
* compare cardinality against a threshold to decide whether the
|
|
13
|
+
* fingerprint is shared widely enough to be unreliable. Other
|
|
14
|
+
* plausible uses include distinct-user counts per feature flag,
|
|
15
|
+
* active-session tracking by org, and any bounded-cardinality
|
|
16
|
+
* "have I seen X for Y" check.
|
|
17
|
+
*
|
|
18
|
+
* **Counter width:** `number` (not `bigint`) is an intentional TS
|
|
19
|
+
* ergonomic delta vs .NET `long`. Implementations must stay within
|
|
20
|
+
* `Number.MAX_SAFE_INTEGER`.
|
|
21
|
+
*/
|
|
22
|
+
export interface ICacheSet {
|
|
23
|
+
/**
|
|
24
|
+
* Adds a member to the set at `key`. The set is created on first
|
|
25
|
+
* add.
|
|
26
|
+
*
|
|
27
|
+
* **TTL-on-create-only:** optional `expirationMs` is applied **only
|
|
28
|
+
* when the set is created**; subsequent adds on an existing set
|
|
29
|
+
* **preserve the existing TTL**.
|
|
30
|
+
*
|
|
31
|
+
* @returns `ok(true)` if the member was newly added. `ok(false)` if
|
|
32
|
+
* the member already existed in the set. Failure on backing-store
|
|
33
|
+
* error.
|
|
34
|
+
*/
|
|
35
|
+
setAdd(key: string, member: string, expirationMs?: number, signal?: AbortSignal): Promise<D2Result<boolean>>;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the cardinality (number of distinct members) of the set at
|
|
38
|
+
* `key`. Absent set → `ok(0)`.
|
|
39
|
+
*
|
|
40
|
+
* @returns `ok(count)`. Failure on backing-store error.
|
|
41
|
+
*/
|
|
42
|
+
setCardinality(key: string, signal?: AbortSignal): Promise<D2Result<number>>;
|
|
43
|
+
/**
|
|
44
|
+
* Removes a member from the set at `key`. **Idempotent** — succeeds
|
|
45
|
+
* whether the member existed or not.
|
|
46
|
+
*
|
|
47
|
+
* @returns `ok(true)` if the member was present and removed.
|
|
48
|
+
* `ok(false)` if the member was absent. Failure on backing-store
|
|
49
|
+
* error.
|
|
50
|
+
*/
|
|
51
|
+
setRemove(key: string, member: string, signal?: AbortSignal): Promise<D2Result<boolean>>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns whether `member` is in the set at `key`.
|
|
54
|
+
*
|
|
55
|
+
* @returns `ok(true|false)`. Failure on backing-store error.
|
|
56
|
+
*/
|
|
57
|
+
setContains(key: string, member: string, signal?: AbortSignal): Promise<D2Result<boolean>>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=i-cache-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-set.d.ts","sourceRoot":"","sources":["../src/i-cache-set.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;;OAWG;IACH,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9B;;;;;OAKG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7E;;;;;;;OAOG;IACH,SAAS,CACP,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAE9B;;;;OAIG;IACH,WAAW,CACT,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;CAC/B"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-cache-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-cache-set.js","sourceRoot":"","sources":["../src/i-cache-set.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ICacheAtomic } from "./i-cache-atomic.js";
|
|
2
|
+
import type { ICacheBasic } from "./i-cache-basic.js";
|
|
3
|
+
import type { ICacheBroadcast } from "./i-cache-broadcast.js";
|
|
4
|
+
import type { ICacheSet } from "./i-cache-set.js";
|
|
5
|
+
/**
|
|
6
|
+
* Cluster-scoped cache backed by a remote store (e.g. Redis). Atomic
|
|
7
|
+
* primitives coordinate cluster-wide. The {@link ICacheBroadcast}
|
|
8
|
+
* surface coordinates with tiered consumers in other instances so
|
|
9
|
+
* their L1 entries get busted in lockstep.
|
|
10
|
+
*
|
|
11
|
+
* Composes {@link ICacheBasic} + {@link ICacheAtomic} +
|
|
12
|
+
* {@link ICacheBroadcast} + {@link ICacheSet}.
|
|
13
|
+
*
|
|
14
|
+
* **Marker vs {@link ITieredCache}:** shared building blocks
|
|
15
|
+
* (Basic + Atomic + Broadcast) are method-identical. **`ICacheSet` is
|
|
16
|
+
* only on `IDistributedCache`** (not full structural identity). The
|
|
17
|
+
* marker name carries behavioral intent at the dependency site: reading
|
|
18
|
+
* `IDistributedCache` tells you the cache talks to the remote store on
|
|
19
|
+
* every read (no L1), so freshness matters more than read speed for
|
|
20
|
+
* this consumer (e.g. rate-limit counters, lock state, ephemeral
|
|
21
|
+
* session data).
|
|
22
|
+
*/
|
|
23
|
+
export interface IDistributedCache extends ICacheBasic, ICacheAtomic, ICacheBroadcast, ICacheSet {
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=i-distributed-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-distributed-cache.d.ts","sourceRoot":"","sources":["../src/i-distributed-cache.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,iBACf,SAAQ,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS;CAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-distributed-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-distributed-cache.js","sourceRoot":"","sources":["../src/i-distributed-cache.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ICacheAtomic } from "./i-cache-atomic.js";
|
|
2
|
+
import type { ICacheBasic } from "./i-cache-basic.js";
|
|
3
|
+
/**
|
|
4
|
+
* Per-process in-memory cache. Atomic primitives operate at process
|
|
5
|
+
* scope — they do not coordinate across instances. There is no
|
|
6
|
+
* broadcast surface because nothing outside this process can observe
|
|
7
|
+
* local cache state.
|
|
8
|
+
*
|
|
9
|
+
* The interface name documents the cache scope at the dependency site.
|
|
10
|
+
* Reading `ILocalCache` at an inject site tells you, without looking
|
|
11
|
+
* at registration, that this cache lives in process memory and dies
|
|
12
|
+
* with the process.
|
|
13
|
+
*
|
|
14
|
+
* Composes {@link ICacheBasic} + {@link ICacheAtomic} only.
|
|
15
|
+
*/
|
|
16
|
+
export interface ILocalCache extends ICacheBasic, ICacheAtomic {
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=i-local-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-local-cache.d.ts","sourceRoot":"","sources":["../src/i-local-cache.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAY,SAAQ,WAAW,EAAE,YAAY;CAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-local-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-local-cache.js","sourceRoot":"","sources":["../src/i-local-cache.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ICacheAtomic } from "./i-cache-atomic.js";
|
|
2
|
+
import type { ICacheBasic } from "./i-cache-basic.js";
|
|
3
|
+
import type { ICacheBroadcast } from "./i-cache-broadcast.js";
|
|
4
|
+
/**
|
|
5
|
+
* Composed L1 (in-process) + L2 (remote) cache. Reads check L1 first,
|
|
6
|
+
* fall through to L2 on miss, populate L1 with whatever L2 returned.
|
|
7
|
+
* Writes go L2-first — L1 only writes if L2 succeeded — so partial-write
|
|
8
|
+
* states are impossible and the result is binary (success or the L2
|
|
9
|
+
* failure bubbled up). Atomic primitives route through L2 (the source
|
|
10
|
+
* of truth) and invalidate / refresh L1 as a side effect.
|
|
11
|
+
*
|
|
12
|
+
* Composes {@link ICacheBasic} + {@link ICacheAtomic} +
|
|
13
|
+
* {@link ICacheBroadcast}. **Does NOT compose {@link ICacheSet}** —
|
|
14
|
+
* set primitives are cluster-only and tiered composition would
|
|
15
|
+
* silently hide their cluster-wide nature. Callers needing
|
|
16
|
+
* SADD/SCARD inject {@link IDistributedCache} directly.
|
|
17
|
+
*
|
|
18
|
+
* **Marker vs {@link IDistributedCache}:** shared building blocks
|
|
19
|
+
* (Basic + Atomic + Broadcast) are method-identical. The marker name
|
|
20
|
+
* carries behavioral intent: reading `ITieredCache` tells you reads
|
|
21
|
+
* served from L1 are sub-microsecond, L1 stays cluster-coherent via
|
|
22
|
+
* the broadcast backplane, and per-tier expirations are kept in
|
|
23
|
+
* lockstep so L1 never outlives L2.
|
|
24
|
+
*
|
|
25
|
+
* Use this for read-heavy entity data where freshness within a few
|
|
26
|
+
* seconds is acceptable. Prefer {@link IDistributedCache} when every
|
|
27
|
+
* read must hit the canonical store.
|
|
28
|
+
*/
|
|
29
|
+
export interface ITieredCache extends ICacheBasic, ICacheAtomic, ICacheBroadcast {
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=i-tiered-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-tiered-cache.d.ts","sourceRoot":"","sources":["../src/i-tiered-cache.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,WAAW,YACf,SAAQ,WAAW,EAAE,YAAY,EAAE,eAAe;CAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=i-tiered-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i-tiered-cache.js","sourceRoot":"","sources":["../src/i-tiered-cache.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type { ICacheBasic } from "./i-cache-basic.js";
|
|
2
|
+
export type { ICacheAtomic } from "./i-cache-atomic.js";
|
|
3
|
+
export type { ICacheBroadcast } from "./i-cache-broadcast.js";
|
|
4
|
+
export type { ICacheSet } from "./i-cache-set.js";
|
|
5
|
+
export type { ILocalCache } from "./i-local-cache.js";
|
|
6
|
+
export type { IDistributedCache } from "./i-distributed-cache.js";
|
|
7
|
+
export type { ITieredCache } from "./i-tiered-cache.js";
|
|
8
|
+
export type { ICacheInvalidationBackplane } from "./i-cache-invalidation-backplane.js";
|
|
9
|
+
export type { ICacheSerializer } from "./i-cache-serializer.js";
|
|
10
|
+
export type { LocalCacheOptions } from "./local-cache-options.js";
|
|
11
|
+
export { LOCAL_CACHE_DEFAULTS, createLocalCacheOptions, } from "./local-cache-options.js";
|
|
12
|
+
export { InputFailures } from "./input-failures.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AACvF,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
export { LOCAL_CACHE_DEFAULTS, createLocalCacheOptions, } from "./local-cache-options.js";
|
|
5
|
+
export { InputFailures } from "./input-failures.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E;AAY1E,OAAO,EACL,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type D2Result } from "@dcsv-io/d2-result";
|
|
2
|
+
export declare const InputFailures: {
|
|
3
|
+
/**
|
|
4
|
+
* Builds a `D2Result` / `D2Result<T>` input failure for a missing
|
|
5
|
+
* (null / empty / falsey) required parameter.
|
|
6
|
+
*
|
|
7
|
+
* @param paramName - Parameter name (use a string literal matching
|
|
8
|
+
* the call-site argument name).
|
|
9
|
+
*/
|
|
10
|
+
required: {
|
|
11
|
+
(paramName: string): D2Result;
|
|
12
|
+
<T>(paramName: string): D2Result<T>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Builds a `D2Result` / `D2Result<T>` input failure for a present but
|
|
16
|
+
* invalid parameter value (range, non-finite, non-safe-integer, etc.).
|
|
17
|
+
* Does **not** use `NOT_NULL_VIOLATION` — the value is present.
|
|
18
|
+
*
|
|
19
|
+
* @param paramName - Parameter name (use a string literal matching
|
|
20
|
+
* the call-site argument name).
|
|
21
|
+
*/
|
|
22
|
+
invalid: {
|
|
23
|
+
(paramName: string): D2Result;
|
|
24
|
+
<T>(paramName: string): D2Result<T>;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=input-failures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-failures.d.ts","sourceRoot":"","sources":["../src/input-failures.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAwB5B,eAAO,MAAM,aAAa;IACxB;;;;;;OAMG;cACuB;QACxB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC9B,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;KACrC;IAED;;;;;;;OAOG;aACqB;QACtB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC9B,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;KACrC;CACF,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
import { TK } from "@dcsv-io/d2-i18n-keys";
|
|
5
|
+
import { inputError, validationFailed, } from "@dcsv-io/d2-result";
|
|
6
|
+
/**
|
|
7
|
+
* Pre-built `D2Result` input-failure responses for cache impls.
|
|
8
|
+
* Keeps the cache surface pure errors-as-values instead of mixing in
|
|
9
|
+
* throws for caller mistakes.
|
|
10
|
+
*
|
|
11
|
+
* Constructors / DI registration still throw — that is a different
|
|
12
|
+
* lifecycle concern from per-call input validation.
|
|
13
|
+
*
|
|
14
|
+
* Twin of .NET `DcsvIo.D2.Caching.InputFailures`.
|
|
15
|
+
*/
|
|
16
|
+
function requiredImpl(paramName) {
|
|
17
|
+
return validationFailed({
|
|
18
|
+
inputErrors: [inputError(paramName, [TK.common.errors.NOT_NULL_VIOLATION])],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function invalidImpl(paramName) {
|
|
22
|
+
return validationFailed({
|
|
23
|
+
inputErrors: [inputError(paramName, [TK.common.errors.VALIDATION_FAILED])],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export const InputFailures = {
|
|
27
|
+
/**
|
|
28
|
+
* Builds a `D2Result` / `D2Result<T>` input failure for a missing
|
|
29
|
+
* (null / empty / falsey) required parameter.
|
|
30
|
+
*
|
|
31
|
+
* @param paramName - Parameter name (use a string literal matching
|
|
32
|
+
* the call-site argument name).
|
|
33
|
+
*/
|
|
34
|
+
required: requiredImpl,
|
|
35
|
+
/**
|
|
36
|
+
* Builds a `D2Result` / `D2Result<T>` input failure for a present but
|
|
37
|
+
* invalid parameter value (range, non-finite, non-safe-integer, etc.).
|
|
38
|
+
* Does **not** use `NOT_NULL_VIOLATION` — the value is present.
|
|
39
|
+
*
|
|
40
|
+
* @param paramName - Parameter name (use a string literal matching
|
|
41
|
+
* the call-site argument name).
|
|
42
|
+
*/
|
|
43
|
+
invalid: invalidImpl,
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=input-failures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-failures.js","sourceRoot":"","sources":["../src/input-failures.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E;AAE1E,OAAO,EAAE,EAAE,EAAE,MAAM,uBAAuB,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;GASG;AACH,SAAS,YAAY,CAAW,SAAiB;IAC/C,OAAO,gBAAgB,CAAI;QACzB,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;KAC5E,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAW,SAAiB;IAC9C,OAAO,gBAAgB,CAAI;QACzB,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;KAC3E,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B;;;;;;OAMG;IACH,QAAQ,EAAE,YAGT;IAED;;;;;;;OAOG;IACH,OAAO,EAAE,WAGR;CACF,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration knobs for an {@link ILocalCache} implementation.
|
|
3
|
+
* Defaults are tuned for typical microservice workloads (100K entries,
|
|
4
|
+
* 1-hour default TTL).
|
|
5
|
+
*
|
|
6
|
+
* Per-entry size accounting is intentionally NOT exposed — the default
|
|
7
|
+
* implementation always counts entries as size 1 so `maxEntries`
|
|
8
|
+
* behaves as the literal entry-count cap most callers expect.
|
|
9
|
+
*
|
|
10
|
+
* No options validation on this POCO (mirrors .NET — no range check /
|
|
11
|
+
* ValidateOnStart). The factory does not fail on absurd values;
|
|
12
|
+
* enforcement belongs in the local-default implementation.
|
|
13
|
+
*/
|
|
14
|
+
export interface LocalCacheOptions {
|
|
15
|
+
/**
|
|
16
|
+
* Maximum number of entries before LRU-ish eviction kicks in.
|
|
17
|
+
* Default 100_000.
|
|
18
|
+
*/
|
|
19
|
+
maxEntries: number;
|
|
20
|
+
/**
|
|
21
|
+
* Default TTL (milliseconds) applied to entries written without an
|
|
22
|
+
* explicit expiration. Default 3_600_000 (1 hour).
|
|
23
|
+
*/
|
|
24
|
+
defaultExpirationMs: number;
|
|
25
|
+
/**
|
|
26
|
+
* Optional key prefix automatically prepended to every cache key.
|
|
27
|
+
* Useful when multiple caches share a process and the caller wants
|
|
28
|
+
* namespace isolation (e.g. `"jwks:"`) without coordinating keys
|
|
29
|
+
* explicitly. Default is empty string (no prefix).
|
|
30
|
+
*/
|
|
31
|
+
keyPrefix: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const LOCAL_CACHE_DEFAULTS: Readonly<LocalCacheOptions>;
|
|
34
|
+
/**
|
|
35
|
+
* Builds a mutable {@link LocalCacheOptions} by merging an optional
|
|
36
|
+
* partial over {@link LOCAL_CACHE_DEFAULTS}. Always returns a fresh
|
|
37
|
+
* object (not shared with the defaults constant).
|
|
38
|
+
*/
|
|
39
|
+
export declare function createLocalCacheOptions(partial?: Partial<LocalCacheOptions>): LocalCacheOptions;
|
|
40
|
+
//# sourceMappingURL=local-cache-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-cache-options.d.ts","sourceRoot":"","sources":["../src/local-cache-options.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,iBAAiB,CAI5D,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GACnC,iBAAiB,CAOnB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------
|
|
2
|
+
// Copyright (c) DCSV. Licensed under the Apache License, Version 2.0.
|
|
3
|
+
// -----------------------------------------------------------------------
|
|
4
|
+
// Numeric twin of .NET LocalCacheOptions (MaxEntries=100_000, DefaultExpiration=1h, KeyPrefix="").
|
|
5
|
+
export const LOCAL_CACHE_DEFAULTS = {
|
|
6
|
+
maxEntries: 100_000,
|
|
7
|
+
defaultExpirationMs: 3_600_000,
|
|
8
|
+
keyPrefix: "",
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Builds a mutable {@link LocalCacheOptions} by merging an optional
|
|
12
|
+
* partial over {@link LOCAL_CACHE_DEFAULTS}. Always returns a fresh
|
|
13
|
+
* object (not shared with the defaults constant).
|
|
14
|
+
*/
|
|
15
|
+
export function createLocalCacheOptions(partial) {
|
|
16
|
+
return {
|
|
17
|
+
maxEntries: partial?.maxEntries ?? LOCAL_CACHE_DEFAULTS.maxEntries,
|
|
18
|
+
defaultExpirationMs: partial?.defaultExpirationMs ?? LOCAL_CACHE_DEFAULTS.defaultExpirationMs,
|
|
19
|
+
keyPrefix: partial?.keyPrefix ?? LOCAL_CACHE_DEFAULTS.keyPrefix,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=local-cache-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-cache-options.js","sourceRoot":"","sources":["../src/local-cache-options.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E;AAqC1E,mGAAmG;AACnG,MAAM,CAAC,MAAM,oBAAoB,GAAgC;IAC/D,UAAU,EAAE,OAAO;IACnB,mBAAmB,EAAE,SAAS;IAC9B,SAAS,EAAE,EAAE;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAoC;IAEpC,OAAO;QACL,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,oBAAoB,CAAC,UAAU;QAClE,mBAAmB,EACjB,OAAO,EAAE,mBAAmB,IAAI,oBAAoB,CAAC,mBAAmB;QAC1E,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,oBAAoB,CAAC,SAAS;KAChE,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dcsv-io/d2-caching-abstractions",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@dcsv-io/d2-i18n-keys": "0.1.1",
|
|
18
|
+
"@dcsv-io/d2-result": "0.1.1"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@vitest/coverage-v8": "4.0.18",
|
|
22
|
+
"typescript": "5.9.3",
|
|
23
|
+
"vitest": "4.0.18"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -b",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:coverage": "vitest run --coverage",
|
|
29
|
+
"type-check:test": "tsc -p tsconfig.test.json"
|
|
30
|
+
}
|
|
31
|
+
}
|