@zudojs/cache 0.0.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.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/cache.d.ts +62 -0
  5. package/dist/cache.d.ts.map +1 -0
  6. package/dist/cache.js +135 -0
  7. package/dist/cache.js.map +1 -0
  8. package/dist/constants.d.ts +40 -0
  9. package/dist/constants.d.ts.map +1 -0
  10. package/dist/constants.js +61 -0
  11. package/dist/constants.js.map +1 -0
  12. package/dist/errors.d.ts +9 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +8 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/index.d.ts +35 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +42 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/invalidation.d.ts +68 -0
  21. package/dist/invalidation.d.ts.map +1 -0
  22. package/dist/invalidation.js +103 -0
  23. package/dist/invalidation.js.map +1 -0
  24. package/dist/key-builder.d.ts +36 -0
  25. package/dist/key-builder.d.ts.map +1 -0
  26. package/dist/key-builder.js +66 -0
  27. package/dist/key-builder.js.map +1 -0
  28. package/dist/lock.d.ts +30 -0
  29. package/dist/lock.d.ts.map +1 -0
  30. package/dist/lock.js +103 -0
  31. package/dist/lock.js.map +1 -0
  32. package/dist/memory.d.ts +37 -0
  33. package/dist/memory.d.ts.map +1 -0
  34. package/dist/memory.js +140 -0
  35. package/dist/memory.js.map +1 -0
  36. package/dist/metrics.d.ts +41 -0
  37. package/dist/metrics.d.ts.map +1 -0
  38. package/dist/metrics.js +96 -0
  39. package/dist/metrics.js.map +1 -0
  40. package/dist/serializer.d.ts +43 -0
  41. package/dist/serializer.d.ts.map +1 -0
  42. package/dist/serializer.js +74 -0
  43. package/dist/serializer.js.map +1 -0
  44. package/dist/store.d.ts +42 -0
  45. package/dist/store.d.ts.map +1 -0
  46. package/dist/store.js +180 -0
  47. package/dist/store.js.map +1 -0
  48. package/dist/tags.d.ts +37 -0
  49. package/dist/tags.d.ts.map +1 -0
  50. package/dist/tags.js +93 -0
  51. package/dist/tags.js.map +1 -0
  52. package/dist/types-adapter.d.ts +24 -0
  53. package/dist/types-adapter.d.ts.map +1 -0
  54. package/dist/types-adapter.js +2 -0
  55. package/dist/types-adapter.js.map +1 -0
  56. package/dist/types-config.d.ts +21 -0
  57. package/dist/types-config.d.ts.map +1 -0
  58. package/dist/types-config.js +2 -0
  59. package/dist/types-config.js.map +1 -0
  60. package/dist/types-events.d.ts +38 -0
  61. package/dist/types-events.d.ts.map +1 -0
  62. package/dist/types-events.js +2 -0
  63. package/dist/types-events.js.map +1 -0
  64. package/dist/types-health.d.ts +20 -0
  65. package/dist/types-health.d.ts.map +1 -0
  66. package/dist/types-health.js +2 -0
  67. package/dist/types-health.js.map +1 -0
  68. package/dist/types-keys.d.ts +15 -0
  69. package/dist/types-keys.d.ts.map +1 -0
  70. package/dist/types-keys.js +2 -0
  71. package/dist/types-keys.js.map +1 -0
  72. package/dist/types-lock.d.ts +22 -0
  73. package/dist/types-lock.d.ts.map +1 -0
  74. package/dist/types-lock.js +2 -0
  75. package/dist/types-lock.js.map +1 -0
  76. package/dist/types-metrics.d.ts +19 -0
  77. package/dist/types-metrics.d.ts.map +1 -0
  78. package/dist/types-metrics.js +2 -0
  79. package/dist/types-metrics.js.map +1 -0
  80. package/dist/types-operations.d.ts +39 -0
  81. package/dist/types-operations.d.ts.map +1 -0
  82. package/dist/types-operations.js +2 -0
  83. package/dist/types-operations.js.map +1 -0
  84. package/dist/types-results.d.ts +33 -0
  85. package/dist/types-results.d.ts.map +1 -0
  86. package/dist/types-results.js +2 -0
  87. package/dist/types-results.js.map +1 -0
  88. package/dist/types-tags.d.ts +13 -0
  89. package/dist/types-tags.d.ts.map +1 -0
  90. package/dist/types-tags.js +2 -0
  91. package/dist/types-tags.js.map +1 -0
  92. package/dist/types-utility.d.ts +31 -0
  93. package/dist/types-utility.d.ts.map +1 -0
  94. package/dist/types-utility.js +2 -0
  95. package/dist/types-utility.js.map +1 -0
  96. package/dist/types-values.d.ts +24 -0
  97. package/dist/types-values.d.ts.map +1 -0
  98. package/dist/types-values.js +2 -0
  99. package/dist/types-values.js.map +1 -0
  100. package/dist/types.d.ts +13 -0
  101. package/dist/types.d.ts.map +1 -0
  102. package/dist/types.js +2 -0
  103. package/dist/types.js.map +1 -0
  104. package/package.json +53 -0
@@ -0,0 +1,66 @@
1
+ /**
2
+ * @zudojs/cache — Key Builder
3
+ *
4
+ * Builds fully qualified cache keys from key parts, namespaces,
5
+ * and prefixes. Ensures keys are well-formed and consistently formatted.
6
+ */
7
+ import { CACHE_KEY_PATTERN, DEFAULT_PREFIX, DEFAULT_SEPARATOR, MAX_KEY_LENGTH, } from "./constants.js";
8
+ import { cacheInvalidKeyError } from "./errors.js";
9
+ /* -------------------------------------------------------------------------- */
10
+ /* Default Key Builder */
11
+ /* -------------------------------------------------------------------------- */
12
+ /**
13
+ * Default implementation of the `CacheKeyBuilder` contract.
14
+ *
15
+ * Keys are built as: `[prefix:][namespace:]key`
16
+ */
17
+ export class DefaultKeyBuilder {
18
+ globalPrefix;
19
+ globalSeparator;
20
+ currentNamespace;
21
+ constructor(options) {
22
+ this.globalPrefix = options?.prefix ?? DEFAULT_PREFIX;
23
+ this.globalSeparator = options?.separator ?? DEFAULT_SEPARATOR;
24
+ this.currentNamespace = options?.namespace;
25
+ }
26
+ build(key, options) {
27
+ const separator = options?.separator ?? this.globalSeparator;
28
+ const namespace = options?.namespace ?? this.currentNamespace;
29
+ const prefix = options?.prefix ?? this.globalPrefix;
30
+ const parts = [];
31
+ if (prefix) {
32
+ parts.push(prefix);
33
+ }
34
+ if (namespace) {
35
+ parts.push(namespace);
36
+ }
37
+ parts.push(key);
38
+ const fullKey = parts.join(separator);
39
+ if (fullKey.length > MAX_KEY_LENGTH) {
40
+ throw cacheInvalidKeyError(fullKey, `Cache key exceeds maximum length of ${MAX_KEY_LENGTH} characters.`);
41
+ }
42
+ if (!CACHE_KEY_PATTERN.test(fullKey)) {
43
+ throw cacheInvalidKeyError(fullKey);
44
+ }
45
+ return fullKey;
46
+ }
47
+ namespace(namespace) {
48
+ return new DefaultKeyBuilder({
49
+ prefix: this.globalPrefix,
50
+ separator: this.globalSeparator,
51
+ namespace,
52
+ });
53
+ }
54
+ }
55
+ /* -------------------------------------------------------------------------- */
56
+ /* Factory */
57
+ /* -------------------------------------------------------------------------- */
58
+ /**
59
+ * Creates a new `DefaultKeyBuilder` with the given options.
60
+ */
61
+ export function createKeyBuilder(options) {
62
+ return new DefaultKeyBuilder(options);
63
+ }
64
+ /** Default key builder singleton. */
65
+ export const defaultKeyBuilder = new DefaultKeyBuilder();
66
+ //# sourceMappingURL=key-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-builder.js","sourceRoot":"","sources":["../src/key-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IACX,YAAY,CAAS;IACrB,eAAe,CAAS;IACxB,gBAAgB,CAAkB;IAEnD,YAAY,OAIX;QACC,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,IAAI,cAAc,CAAC;QACtD,IAAI,CAAC,eAAe,GAAG,OAAO,EAAE,SAAS,IAAI,iBAAiB,CAAC;QAC/D,IAAI,CAAC,gBAAgB,GAAG,OAAO,EAAE,SAAS,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,OAAyB;QAC1C,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,eAAe,CAAC;QAC7D,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAC9D,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC;QAEpD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEtC,IAAI,OAAO,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;YACpC,MAAM,oBAAoB,CACxB,OAAO,EACP,uCAAuC,cAAc,cAAc,CACpE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,SAAyB;QACjC,OAAO,IAAI,iBAAiB,CAAC;YAC3B,MAAM,EAAE,IAAI,CAAC,YAAY;YACzB,SAAS,EAAE,IAAI,CAAC,eAAe;YAC/B,SAAS;SACV,CAAC,CAAC;IACL,CAAC;CACF;AAED,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAIhC;IACC,OAAO,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
package/dist/lock.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @zudojs/cache — Lock Manager
3
+ * Distributed lock manager for preventing concurrent cache operations.
4
+ */
5
+ import type { CacheLock, CacheLockOptions, CacheLockStore } from "./types.js";
6
+ export declare class InMemoryLockStore implements CacheLockStore {
7
+ private readonly locks;
8
+ acquire(key: string, options?: CacheLockOptions): Promise<CacheLock | null>;
9
+ get size(): number;
10
+ clear(): void;
11
+ }
12
+ export declare class CacheLockManager {
13
+ private readonly store;
14
+ private readonly retryAttempts;
15
+ private readonly retryDelayMs;
16
+ constructor(options?: {
17
+ readonly store?: CacheLockStore;
18
+ readonly retryAttempts?: number;
19
+ readonly retryDelayMs?: number;
20
+ });
21
+ acquire(key: string, options?: CacheLockOptions): Promise<CacheLock | null>;
22
+ withLock<T>(key: string, fn: () => Promise<T>, options?: CacheLockOptions): Promise<T>;
23
+ }
24
+ export declare function createLockManager(options?: {
25
+ readonly store?: CacheLockStore;
26
+ readonly retryAttempts?: number;
27
+ readonly retryDelayMs?: number;
28
+ }): CacheLockManager;
29
+ export declare const defaultLockStore: InMemoryLockStore;
30
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EAEf,MAAM,YAAY,CAAC;AAepB,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAGlB;IAEE,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAgC3B;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,KAAK,IAAI,IAAI,CAEZ;CACF;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,YAAY,OAAO,CAAC,EAAE;QACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;QAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;KAChC,EAIA;IAEK,OAAO,CACX,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAiB3B;IAEK,QAAQ,CAAC,CAAC,EACd,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,CAAC,CAAC,CAYZ;CACF;AAMD,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC,GAAG,gBAAgB,CAEnB;AAED,eAAO,MAAM,gBAAgB,mBAA0B,CAAC"}
package/dist/lock.js ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @zudojs/cache — Lock Manager
3
+ * Distributed lock manager for preventing concurrent cache operations.
4
+ */
5
+ import { randomBytes, randomUUID } from "node:crypto";
6
+ import { DEFAULT_LOCK_RETRY_ATTEMPTS, DEFAULT_LOCK_RETRY_DELAY_MS, DEFAULT_LOCK_TTL_MS, } from "./constants.js";
7
+ import { CacheError, CacheOperation } from "./errors.js";
8
+ function generateToken() {
9
+ if (typeof randomUUID === "function") {
10
+ return randomUUID();
11
+ }
12
+ return randomBytes(16).toString("hex");
13
+ }
14
+ export class InMemoryLockStore {
15
+ locks = new Map();
16
+ async acquire(key, options) {
17
+ const ttl = options?.ttl ?? DEFAULT_LOCK_TTL_MS;
18
+ const token = generateToken();
19
+ const now = Date.now();
20
+ const expiresAt = now + ttl;
21
+ const existing = this.locks.get(key);
22
+ if (existing && existing.expiresAt !== null && now > existing.expiresAt)
23
+ this.locks.delete(key);
24
+ if (this.locks.has(key))
25
+ return null;
26
+ this.locks.set(key, { token, expiresAt });
27
+ return {
28
+ key,
29
+ token,
30
+ acquiredAt: new Date(now),
31
+ expiresAt: new Date(expiresAt),
32
+ release: async () => {
33
+ const current = this.locks.get(key);
34
+ if (current && current.token === token) {
35
+ this.locks.delete(key);
36
+ return true;
37
+ }
38
+ return false;
39
+ },
40
+ extend: async (newTtl) => {
41
+ const current = this.locks.get(key);
42
+ if (current && current.token === token) {
43
+ this.locks.set(key, { ...current, expiresAt: Date.now() + newTtl });
44
+ return true;
45
+ }
46
+ return false;
47
+ },
48
+ };
49
+ }
50
+ get size() {
51
+ return this.locks.size;
52
+ }
53
+ clear() {
54
+ this.locks.clear();
55
+ }
56
+ }
57
+ export class CacheLockManager {
58
+ store;
59
+ retryAttempts;
60
+ retryDelayMs;
61
+ constructor(options) {
62
+ this.store = options?.store ?? new InMemoryLockStore();
63
+ this.retryAttempts = options?.retryAttempts ?? DEFAULT_LOCK_RETRY_ATTEMPTS;
64
+ this.retryDelayMs = options?.retryDelayMs ?? DEFAULT_LOCK_RETRY_DELAY_MS;
65
+ }
66
+ async acquire(key, options) {
67
+ let lastError;
68
+ for (let attempt = 0; attempt <= this.retryAttempts; attempt++) {
69
+ try {
70
+ const lock = await this.store.acquire(key, options);
71
+ if (lock)
72
+ return lock;
73
+ }
74
+ catch (error) {
75
+ lastError = error;
76
+ }
77
+ if (attempt < this.retryAttempts)
78
+ await sleep(this.retryDelayMs);
79
+ }
80
+ if (lastError)
81
+ throw new CacheError(`Failed to acquire lock "${key}" after ${this.retryAttempts} retries.`, { cause: lastError, operation: CacheOperation.LOCK_ACQUIRE, key });
82
+ return null;
83
+ }
84
+ async withLock(key, fn, options) {
85
+ const lock = await this.acquire(key, options);
86
+ if (!lock)
87
+ throw new CacheError(`Could not acquire lock "${key}" for exclusive operation.`, { operation: CacheOperation.LOCK_ACQUIRE, key, statusCode: 409 });
88
+ try {
89
+ return await fn();
90
+ }
91
+ finally {
92
+ await lock.release();
93
+ }
94
+ }
95
+ }
96
+ function sleep(ms) {
97
+ return new Promise((resolve) => setTimeout(resolve, ms));
98
+ }
99
+ export function createLockManager(options) {
100
+ return new CacheLockManager(options);
101
+ }
102
+ export const defaultLockStore = new InMemoryLockStore();
103
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @zudojs/cache — Memory Adapter
3
+ * In-memory cache adapter using a Map. Suitable for development, testing, and single-process deployments.
4
+ */
5
+ import type { CacheAdapter, CacheClearOptions, CacheClearResult, CacheDeleteResult, CacheGetResult, CacheKeysOptions, CacheSetManyOptions, CacheSetOptions, CacheSetResult, CacheTTL } from "./types.js";
6
+ export declare class MemoryCacheAdapter implements CacheAdapter {
7
+ readonly name = "memory";
8
+ private readonly store;
9
+ private readonly maxEntries;
10
+ private readonly defaultTtl;
11
+ constructor(options?: {
12
+ readonly maxEntries?: number;
13
+ readonly defaultTtl?: CacheTTL;
14
+ });
15
+ get<TValue = unknown>(key: string): Promise<CacheGetResult<TValue>>;
16
+ set<TValue = unknown>(key: string, value: TValue, options?: CacheSetOptions): Promise<CacheSetResult>;
17
+ delete(key: string): Promise<CacheDeleteResult>;
18
+ has(key: string): Promise<boolean>;
19
+ clear(options?: CacheClearOptions): Promise<CacheClearResult>;
20
+ keys(options?: CacheKeysOptions): Promise<readonly string[]>;
21
+ getMany<TValue = unknown>(keys: readonly string[]): Promise<ReadonlyMap<string, CacheGetResult<TValue>>>;
22
+ setMany<TValue = unknown>(entries: ReadonlyMap<string, TValue>, options?: CacheSetManyOptions): Promise<readonly CacheSetResult[]>;
23
+ deleteMany(keys: readonly string[]): Promise<{
24
+ readonly deleted: number;
25
+ readonly keys: readonly string[];
26
+ }>;
27
+ ttl(key: string): Promise<number | null>;
28
+ expire(key: string, ttl: CacheTTL): Promise<boolean>;
29
+ private isExpired;
30
+ private evictIfNeeded;
31
+ private patternToRegex;
32
+ }
33
+ export declare function createMemoryCacheAdapter(options?: {
34
+ readonly maxEntries?: number;
35
+ readonly defaultTtl?: CacheTTL;
36
+ }): MemoryCacheAdapter;
37
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAEhB,iBAAiB,EAGjB,cAAc,EAEd,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,QAAQ,EACT,MAAM,YAAY,CAAC;AAWpB,qBAAa,kBAAmB,YAAW,YAAY;IACrD,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkC;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IAEtC,YAAY,OAAO,CAAC,EAAE;QACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC;KAChC,EAGA;IAEK,GAAG,CAAC,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAQxE;IAEK,GAAG,CAAC,MAAM,GAAG,OAAO,EACxB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAgBzB;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAIpD;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvC;IAEK,KAAK,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAelE;IAEK,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CASjE;IAEK,OAAO,CAAC,MAAM,GAAG,OAAO,EAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAItD;IAEK,OAAO,CAAC,MAAM,GAAG,OAAO,EAC5B,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAKpC;IAEK,UAAU,CACd,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,OAAO,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC,CAWzE;IAEK,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAK7C;IAEK,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAKzD;IAED,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,cAAc;CAKvB;AAED,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC;CAChC,GAAG,kBAAkB,CAErB"}
package/dist/memory.js ADDED
@@ -0,0 +1,140 @@
1
+ /**
2
+ * @zudojs/cache — Memory Adapter
3
+ * In-memory cache adapter using a Map. Suitable for development, testing, and single-process deployments.
4
+ */
5
+ import { DEFAULT_MAX_ENTRIES, DEFAULT_TTL_MS } from "./constants.js";
6
+ export class MemoryCacheAdapter {
7
+ name = "memory";
8
+ store = new Map();
9
+ maxEntries;
10
+ defaultTtl;
11
+ constructor(options) {
12
+ this.maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
13
+ this.defaultTtl = options?.defaultTtl ?? DEFAULT_TTL_MS;
14
+ }
15
+ async get(key) {
16
+ const entry = this.store.get(key);
17
+ if (!entry)
18
+ return { hit: false, value: null };
19
+ if (this.isExpired(entry)) {
20
+ this.store.delete(key);
21
+ return { hit: false, value: null };
22
+ }
23
+ return { hit: true, value: entry.value };
24
+ }
25
+ async set(key, value, options) {
26
+ this.evictIfNeeded();
27
+ const ttl = options?.ttl ?? this.defaultTtl;
28
+ const now = Date.now();
29
+ this.store.set(key, {
30
+ value,
31
+ createdAt: now,
32
+ expiresAt: ttl !== null ? now + ttl : null,
33
+ tags: options?.tags ?? [],
34
+ metadata: options?.metadata ?? {},
35
+ });
36
+ return {
37
+ success: true,
38
+ key,
39
+ expiresAt: ttl !== null ? new Date(now + ttl) : null,
40
+ };
41
+ }
42
+ async delete(key) {
43
+ const existed = this.store.has(key);
44
+ this.store.delete(key);
45
+ return { deleted: existed, key };
46
+ }
47
+ async has(key) {
48
+ const entry = this.store.get(key);
49
+ if (!entry)
50
+ return false;
51
+ if (this.isExpired(entry)) {
52
+ this.store.delete(key);
53
+ return false;
54
+ }
55
+ return true;
56
+ }
57
+ async clear(options) {
58
+ if (!options?.pattern) {
59
+ const size = this.store.size;
60
+ this.store.clear();
61
+ return { cleared: size };
62
+ }
63
+ let cleared = 0;
64
+ const regex = this.patternToRegex(options.pattern);
65
+ for (const key of [...this.store.keys()]) {
66
+ if (regex.test(key)) {
67
+ this.store.delete(key);
68
+ cleared++;
69
+ }
70
+ }
71
+ return { cleared };
72
+ }
73
+ async keys(options) {
74
+ let filtered = [...this.store.keys()];
75
+ if (options?.pattern) {
76
+ const regex = this.patternToRegex(options.pattern);
77
+ filtered = filtered.filter((k) => regex.test(k));
78
+ }
79
+ if (options?.limit !== undefined)
80
+ filtered = filtered.slice(0, options.limit);
81
+ return filtered;
82
+ }
83
+ async getMany(keys) {
84
+ const results = new Map();
85
+ for (const key of keys)
86
+ results.set(key, await this.get(key));
87
+ return results;
88
+ }
89
+ async setMany(entries, options) {
90
+ const results = [];
91
+ for (const [key, value] of entries)
92
+ results.push(await this.set(key, value, options));
93
+ return results;
94
+ }
95
+ async deleteMany(keys) {
96
+ let deleted = 0;
97
+ const deletedKeys = [];
98
+ for (const key of keys) {
99
+ const result = await this.delete(key);
100
+ if (result.deleted) {
101
+ deleted++;
102
+ deletedKeys.push(key);
103
+ }
104
+ }
105
+ return { deleted, keys: deletedKeys };
106
+ }
107
+ async ttl(key) {
108
+ const entry = this.store.get(key);
109
+ if (!entry || entry.expiresAt === null)
110
+ return null;
111
+ const remaining = entry.expiresAt - Date.now();
112
+ return remaining > 0 ? remaining : null;
113
+ }
114
+ async expire(key, ttl) {
115
+ const entry = this.store.get(key);
116
+ if (!entry)
117
+ return false;
118
+ this.store.set(key, { ...entry, expiresAt: Date.now() + ttl });
119
+ return true;
120
+ }
121
+ isExpired(entry) {
122
+ return entry.expiresAt !== null && Date.now() > entry.expiresAt;
123
+ }
124
+ evictIfNeeded() {
125
+ if (this.store.size >= this.maxEntries) {
126
+ const firstKey = this.store.keys().next().value;
127
+ if (firstKey !== undefined)
128
+ this.store.delete(firstKey);
129
+ }
130
+ }
131
+ patternToRegex(pattern) {
132
+ const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
133
+ const regexStr = escaped.replace(/\\\*/g, ".*").replace(/\\\?/g, ".");
134
+ return new RegExp(`^${regexStr}$`);
135
+ }
136
+ }
137
+ export function createMemoryCacheAdapter(options) {
138
+ return new MemoryCacheAdapter(options);
139
+ }
140
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAkBH,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAUrE,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,QAAQ,CAAC;IACR,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IACvC,UAAU,CAAS;IACnB,UAAU,CAAW;IAEtC,YAAY,OAGX;QACC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,mBAAmB,CAAC;QAC7D,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,cAAc,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,GAAG,CAAmB,GAAW;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC/C,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACrC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAe,EAAE,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW,EACX,KAAa,EACb,OAAyB;QAEzB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI;YAC1C,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;YACzB,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,EAAE;SAClC,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,IAAI;YACb,GAAG;YACH,SAAS,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;SACrD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAA2B;QACrC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACzC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAA0B;QACnC,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS;YAC9B,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO,CACX,IAAuB;QAEvB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;QAC1D,KAAK,MAAM,GAAG,IAAI,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,GAAG,CAAS,GAAG,CAAC,CAAC,CAAC;QACtE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAAoC,EACpC,OAA6B;QAE7B,MAAM,OAAO,GAAqB,EAAE,CAAC;QACrC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO;YAChC,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAS,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,UAAU,CACd,IAAuB;QAEvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,EAAE,CAAC;gBACV,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACpD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/C,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,GAAa;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,SAAS,CAAC,KAAkB;QAClC,OAAO,KAAK,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;IAClE,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAChD,IAAI,QAAQ,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,OAAe;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACtE,OAAO,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,OAGxC;IACC,OAAO,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @zudojs/cache — Metrics
3
+ * Tracks cache operation metrics including hit/miss ratios, latency histograms, and error counts.
4
+ */
5
+ import type { CacheKey, CacheMetrics, CacheOperation, CacheStats } from "./types.js";
6
+ export declare class InMemoryCacheMetrics implements CacheMetrics {
7
+ private hits;
8
+ private misses;
9
+ private sets;
10
+ private deletes;
11
+ private errors;
12
+ private readonly keyHits;
13
+ private readonly latencies;
14
+ incrementHit(key?: CacheKey): void;
15
+ incrementMiss(_key?: CacheKey): void;
16
+ incrementSet(_key?: CacheKey): void;
17
+ incrementDelete(_key?: CacheKey): void;
18
+ incrementError(_key?: CacheKey): void;
19
+ observeLatency(operation: CacheOperation, latencyMs: number): void;
20
+ getStats(): CacheStats;
21
+ getLatencyStats(operation: CacheOperation): {
22
+ readonly count: number;
23
+ readonly min: number;
24
+ readonly max: number;
25
+ readonly mean: number;
26
+ readonly p50: number;
27
+ readonly p95: number;
28
+ readonly p99: number;
29
+ };
30
+ getHotKeys(topN?: number): readonly {
31
+ readonly key: CacheKey;
32
+ readonly hits: number;
33
+ }[];
34
+ getLatencyHistogram(operation: CacheOperation): readonly {
35
+ readonly bucket: number;
36
+ readonly count: number;
37
+ }[];
38
+ reset(): void;
39
+ }
40
+ export declare function createCacheMetrics(): InMemoryCacheMetrics;
41
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,UAAU,EACX,MAAM,YAAY,CAAC;AAGpB,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IAEjE,YAAY,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAGjC;IACD,aAAa,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAEnC;IACD,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAElC;IACD,eAAe,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAErC;IACD,cAAc,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAEpC;IAED,cAAc,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAMjE;IAED,QAAQ,IAAI,UAAU,CAUrB;IAED,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG;QAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;KACtB,CAgBA;IAED,UAAU,CACR,IAAI,SAAK,GACR,SAAS;QAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAK9D;IAED,mBAAmB,CACjB,SAAS,EAAE,cAAc,GACxB,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAMhE;IAED,KAAK,IAAI,IAAI,CAQZ;CACF;AAOD,wBAAgB,kBAAkB,IAAI,oBAAoB,CAEzD"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * @zudojs/cache — Metrics
3
+ * Tracks cache operation metrics including hit/miss ratios, latency histograms, and error counts.
4
+ */
5
+ import { LATENCY_BUCKETS, MAX_LATENCY_SAMPLES } from "./constants.js";
6
+ export class InMemoryCacheMetrics {
7
+ hits = 0;
8
+ misses = 0;
9
+ sets = 0;
10
+ deletes = 0;
11
+ errors = 0;
12
+ keyHits = new Map();
13
+ latencies = new Map();
14
+ incrementHit(key) {
15
+ this.hits++;
16
+ if (key)
17
+ this.keyHits.set(key, (this.keyHits.get(key) ?? 0) + 1);
18
+ }
19
+ incrementMiss(_key) {
20
+ this.misses++;
21
+ }
22
+ incrementSet(_key) {
23
+ this.sets++;
24
+ }
25
+ incrementDelete(_key) {
26
+ this.deletes++;
27
+ }
28
+ incrementError(_key) {
29
+ this.errors++;
30
+ }
31
+ observeLatency(operation, latencyMs) {
32
+ if (!this.latencies.has(operation))
33
+ this.latencies.set(operation, []);
34
+ const samples = this.latencies.get(operation);
35
+ samples.push(latencyMs);
36
+ if (samples.length > MAX_LATENCY_SAMPLES)
37
+ samples.splice(0, samples.length - MAX_LATENCY_SAMPLES);
38
+ }
39
+ getStats() {
40
+ const total = this.hits + this.misses;
41
+ return {
42
+ hits: this.hits,
43
+ misses: this.misses,
44
+ sets: this.sets,
45
+ deletes: this.deletes,
46
+ errors: this.errors,
47
+ hitRate: total > 0 ? this.hits / total : 0,
48
+ };
49
+ }
50
+ getLatencyStats(operation) {
51
+ const samples = [...(this.latencies.get(operation) ?? [])].sort((a, b) => a - b);
52
+ if (samples.length === 0)
53
+ return { count: 0, min: 0, max: 0, mean: 0, p50: 0, p95: 0, p99: 0 };
54
+ const sum = samples.reduce((a, b) => a + b, 0);
55
+ return {
56
+ count: samples.length,
57
+ min: samples[0],
58
+ max: samples[samples.length - 1],
59
+ mean: sum / samples.length,
60
+ p50: percentile(samples, 50),
61
+ p95: percentile(samples, 95),
62
+ p99: percentile(samples, 99),
63
+ };
64
+ }
65
+ getHotKeys(topN = 10) {
66
+ return [...this.keyHits.entries()]
67
+ .sort((a, b) => b[1] - a[1])
68
+ .slice(0, topN)
69
+ .map(([key, hits]) => ({ key, hits }));
70
+ }
71
+ getLatencyHistogram(operation) {
72
+ const samples = this.latencies.get(operation) ?? [];
73
+ return LATENCY_BUCKETS.map((boundary) => ({
74
+ bucket: boundary,
75
+ count: samples.filter((s) => s <= boundary).length,
76
+ }));
77
+ }
78
+ reset() {
79
+ this.hits = 0;
80
+ this.misses = 0;
81
+ this.sets = 0;
82
+ this.deletes = 0;
83
+ this.errors = 0;
84
+ this.keyHits.clear();
85
+ this.latencies.clear();
86
+ }
87
+ }
88
+ function percentile(sorted, p) {
89
+ if (sorted.length === 0)
90
+ return 0;
91
+ return sorted[Math.max(0, Math.ceil((p / 100) * sorted.length) - 1)];
92
+ }
93
+ export function createCacheMetrics() {
94
+ return new InMemoryCacheMetrics();
95
+ }
96
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @zudojs/cache — Serializer
3
+ *
4
+ * Provides serializer implementations for converting cache values
5
+ * to and from storable representations. Delegates to @zudojs/serialization
6
+ * for the actual JSON serialization with type preservation.
7
+ */
8
+ import type { CacheSerializer } from "./types.js";
9
+ /**
10
+ * Serializes values to JSON strings and deserializes them back.
11
+ *
12
+ * Uses @zudojs/serialization's JSONSerializer for type preservation
13
+ * (Date, BigInt, Map, Set, Uint8Array) when configured.
14
+ */
15
+ export declare class JsonCacheSerializer implements CacheSerializer<unknown, string> {
16
+ private readonly inner;
17
+ private readonly preserveTypes;
18
+ constructor(options?: {
19
+ readonly preserveTypes?: boolean;
20
+ });
21
+ serialize(value: unknown): string;
22
+ deserialize(value: string): unknown;
23
+ }
24
+ /**
25
+ * Pass-through serializer for values that are already in
26
+ * their storable form (e.g., strings, numbers).
27
+ */
28
+ export declare class RawCacheSerializer implements CacheSerializer<unknown, unknown> {
29
+ serialize(value: unknown): unknown;
30
+ deserialize(value: unknown): unknown;
31
+ }
32
+ /** Default JSON serializer instance. */
33
+ export declare const defaultSerializer: JsonCacheSerializer;
34
+ /** Default raw (pass-through) serializer instance. */
35
+ export declare const rawSerializer: RawCacheSerializer;
36
+ /**
37
+ * Returns the appropriate serializer for the given value type.
38
+ *
39
+ * - Objects, arrays, dates → JSON serializer
40
+ * - Strings, numbers, booleans, null → raw serializer
41
+ */
42
+ export declare function getSerializer(value: unknown): CacheSerializer<unknown, unknown>;
43
+ //# sourceMappingURL=serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAOlD;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC;IAC1E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IAExC,YAAY,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,EAGzD;IAED,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIhC;IAED,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIlC;CACF;AAMD;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1E,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEjC;IAED,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEnC;CACF;AAMD,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,qBAA4B,CAAC;AAE3D,sDAAsD;AACtD,eAAO,MAAM,aAAa,oBAA2B,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,GACb,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAYnC"}