@metamask-previews/phishing-controller 17.3.1-preview-4758e65ff → 17.3.1-preview-bbf9454b2
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 +0 -23
- package/dist/CacheManager.cjs +177 -0
- package/dist/CacheManager.cjs.map +1 -0
- package/dist/CacheManager.d.cts +104 -0
- package/dist/CacheManager.d.cts.map +1 -0
- package/dist/CacheManager.d.mts +104 -0
- package/dist/CacheManager.d.mts.map +1 -0
- package/dist/CacheManager.mjs +173 -0
- package/dist/CacheManager.mjs.map +1 -0
- package/dist/PhishingController.cjs +337 -134
- package/dist/PhishingController.cjs.map +1 -1
- package/dist/PhishingController.d.cts +196 -7
- package/dist/PhishingController.d.cts.map +1 -1
- package/dist/PhishingController.d.mts +196 -7
- package/dist/PhishingController.d.mts.map +1 -1
- package/dist/PhishingController.mjs +335 -114
- package/dist/PhishingController.mjs.map +1 -1
- package/dist/index.cjs +1 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs +1 -30
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +0 -155
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +0 -155
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +0 -29
- package/dist/types.mjs.map +1 -1
- package/dist/utils.cjs +52 -3
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +32 -2
- package/dist/utils.d.cts.map +1 -1
- package/dist/utils.d.mts +32 -2
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +48 -1
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -6
- package/dist/PhishingDataService-method-action-types.cjs +0 -7
- package/dist/PhishingDataService-method-action-types.cjs.map +0 -1
- package/dist/PhishingDataService-method-action-types.d.cts +0 -121
- package/dist/PhishingDataService-method-action-types.d.cts.map +0 -1
- package/dist/PhishingDataService-method-action-types.d.mts +0 -121
- package/dist/PhishingDataService-method-action-types.d.mts.map +0 -1
- package/dist/PhishingDataService-method-action-types.mjs +0 -6
- package/dist/PhishingDataService-method-action-types.mjs.map +0 -1
- package/dist/PhishingDataService.cjs +0 -498
- package/dist/PhishingDataService.cjs.map +0 -1
- package/dist/PhishingDataService.d.cts +0 -211
- package/dist/PhishingDataService.d.cts.map +0 -1
- package/dist/PhishingDataService.d.mts +0 -211
- package/dist/PhishingDataService.d.mts.map +0 -1
- package/dist/PhishingDataService.mjs +0 -494
- package/dist/PhishingDataService.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,33 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
### Added
|
|
11
|
-
|
|
12
|
-
- Add `PhishingDataService`, a `BaseDataService` subclass that now performs all network requests for `PhishingController` (stalelist, hotlist diffs, C2 domain blocklist, URL/token/address scans, and approvals)
|
|
13
|
-
- Exposes the messenger actions `PhishingDataService:getStalelist`, `PhishingDataService:getHotlistDiffs`, `PhishingDataService:getC2DomainBlocklist`, `PhishingDataService:scanUrl`, `PhishingDataService:bulkScanUrls`, `PhishingDataService:scanToken`, `PhishingDataService:bulkScanTokens`, `PhishingDataService:scanAddress`, and `PhishingDataService:getApprovals`, making query results available to the UI via `@metamask/react-data-query`
|
|
14
|
-
- Requests are wrapped in a shared retry policy, configurable via the `policyOptions` constructor option; circuit breaking is disabled by default because the service spans four independent API hosts and a broken circuit caused by one host would pause phishing-list updates from the others
|
|
15
|
-
- Scan results are cached per URL hostname, token, and address for `SCAN_RESULT_STALE_TIME` (1 minute, matching the previous cache TTLs); bulk scans only request items without a fresh cached result and coalesce them into batched API calls (up to 50 URLs / 100 tokens per request), and single and bulk URL scans share cache entries; approvals are never cached
|
|
16
|
-
- The query cache is persisted between sessions by default (`persistenceConfig`, max age 5 minutes), which requires the `StorageService:setItem`, `StorageService:getItem`, and `StorageService:removeItem` messenger actions and an `init` call during client initialization (automatic with `@metamask/wallet`); pass `persistenceConfig: null` to disable
|
|
17
|
-
|
|
18
|
-
- Export the `resolveChainName` utility, which maps chain IDs to the chain names used in scan query keys, enabling UI consumers to construct `PhishingDataService` query keys
|
|
19
|
-
|
|
20
10
|
### Changed
|
|
21
11
|
|
|
22
|
-
- **BREAKING:** `PhishingController` no longer performs network requests directly; a `PhishingDataService` must be registered and its method actions delegated to the controller's messenger
|
|
23
|
-
- `PhishingControllerMessenger` now requires the `PhishingDataService` method actions listed above as allowed actions
|
|
24
|
-
- **BREAKING:** Remove the `urlScanCache`, `tokenScanCache`, and `addressScanCache` properties from `PhishingControllerState`; scan results are now cached (and persisted) by `PhishingDataService`'s query cache
|
|
25
|
-
- Client state migrations should remove these properties from persisted `PhishingController` state
|
|
26
|
-
- **BREAKING:** Remove the `urlScanCacheTTL`, `urlScanCacheMaxSize`, `tokenScanCacheTTL`, `tokenScanCacheMaxSize`, `addressScanCacheTTL`, and `addressScanCacheMaxSize` options from `PhishingControllerOptions`; scan result freshness is now controlled by `SCAN_RESULT_STALE_TIME` in `PhishingDataService`
|
|
27
|
-
- Tokens for which the bulk scanning API returns no result are now negatively cached for `SCAN_RESULT_STALE_TIME` instead of being re-requested on every call
|
|
28
|
-
- `scanUrl` now reports the underlying error message in `fetchError` for network errors instead of `'timeout of 8000ms exceeded'`
|
|
29
|
-
- Malformed API responses (e.g. a stalelist without a numeric `lastUpdated`, or scan results without a `recommendedAction`/`result_type`) are now rejected and treated as request failures instead of being passed through
|
|
30
12
|
- Bump `@metamask/transaction-controller` from `^69.4.0` to `^69.5.2` ([#9780](https://github.com/MetaMask/core/pull/9780), [#9798](https://github.com/MetaMask/core/pull/9798), [#9823](https://github.com/MetaMask/core/pull/9823))
|
|
31
13
|
|
|
32
|
-
### Removed
|
|
33
|
-
|
|
34
|
-
- **BREAKING:** Remove the `CacheEntry` type; the custom cache manager has been replaced by `PhishingDataService`'s query cache
|
|
35
|
-
- **BREAKING:** Remove the `DEFAULT_URL_SCAN_CACHE_TTL`, `DEFAULT_URL_SCAN_CACHE_MAX_SIZE`, `DEFAULT_TOKEN_SCAN_CACHE_TTL`, `DEFAULT_TOKEN_SCAN_CACHE_MAX_SIZE`, `DEFAULT_ADDRESS_SCAN_CACHE_TTL`, and `DEFAULT_ADDRESS_SCAN_CACHE_MAX_SIZE` constants
|
|
36
|
-
|
|
37
14
|
## [17.3.1]
|
|
38
15
|
|
|
39
16
|
### Changed
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _CacheManager_instances, _CacheManager_cacheTTL, _CacheManager_maxCacheSize, _CacheManager_cache, _CacheManager_updateState, _CacheManager_persistCache, _CacheManager_evictEntries;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CacheManager = void 0;
|
|
16
|
+
const utils_js_1 = require("./utils.cjs");
|
|
17
|
+
/**
|
|
18
|
+
* Generic cache manager with TTL and size limit support
|
|
19
|
+
*
|
|
20
|
+
* @template T - The type of data to cache
|
|
21
|
+
*/
|
|
22
|
+
class CacheManager {
|
|
23
|
+
/**
|
|
24
|
+
* Constructor for CacheManager
|
|
25
|
+
*
|
|
26
|
+
* @param options - Cache configuration options
|
|
27
|
+
* @param options.cacheTTL - Time to live in seconds for cached entries
|
|
28
|
+
* @param options.maxCacheSize - Maximum number of entries in the cache
|
|
29
|
+
* @param options.initialCache - Initial cache state
|
|
30
|
+
* @param options.updateState - Function to update the state when cache changes
|
|
31
|
+
*/
|
|
32
|
+
constructor({ cacheTTL = 300, // 5 minutes default
|
|
33
|
+
maxCacheSize = 100, initialCache = {}, updateState, }) {
|
|
34
|
+
_CacheManager_instances.add(this);
|
|
35
|
+
_CacheManager_cacheTTL.set(this, void 0);
|
|
36
|
+
_CacheManager_maxCacheSize.set(this, void 0);
|
|
37
|
+
_CacheManager_cache.set(this, void 0);
|
|
38
|
+
_CacheManager_updateState.set(this, void 0);
|
|
39
|
+
__classPrivateFieldSet(this, _CacheManager_cacheTTL, cacheTTL, "f");
|
|
40
|
+
__classPrivateFieldSet(this, _CacheManager_maxCacheSize, maxCacheSize, "f");
|
|
41
|
+
__classPrivateFieldSet(this, _CacheManager_cache, new Map(Object.entries(initialCache)), "f");
|
|
42
|
+
__classPrivateFieldSet(this, _CacheManager_updateState, updateState, "f");
|
|
43
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Set the time-to-live for cached entries
|
|
47
|
+
*
|
|
48
|
+
* @param ttl - The TTL in seconds
|
|
49
|
+
*/
|
|
50
|
+
setTTL(ttl) {
|
|
51
|
+
__classPrivateFieldSet(this, _CacheManager_cacheTTL, ttl, "f");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the current TTL setting
|
|
55
|
+
*
|
|
56
|
+
* @returns The TTL in seconds
|
|
57
|
+
*/
|
|
58
|
+
getTTL() {
|
|
59
|
+
return __classPrivateFieldGet(this, _CacheManager_cacheTTL, "f");
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Set the maximum cache size
|
|
63
|
+
*
|
|
64
|
+
* @param maxSize - The maximum cache size
|
|
65
|
+
*/
|
|
66
|
+
setMaxSize(maxSize) {
|
|
67
|
+
__classPrivateFieldSet(this, _CacheManager_maxCacheSize, maxSize, "f");
|
|
68
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the current maximum cache size
|
|
72
|
+
*
|
|
73
|
+
* @returns The maximum cache size
|
|
74
|
+
*/
|
|
75
|
+
getMaxSize() {
|
|
76
|
+
return __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the current cache size
|
|
80
|
+
*
|
|
81
|
+
* @returns The current number of entries in the cache
|
|
82
|
+
*/
|
|
83
|
+
getSize() {
|
|
84
|
+
return __classPrivateFieldGet(this, _CacheManager_cache, "f").size;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Clear the cache
|
|
88
|
+
*/
|
|
89
|
+
clear() {
|
|
90
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").clear();
|
|
91
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get a cached result if it exists and is not expired
|
|
95
|
+
*
|
|
96
|
+
* @param key - The cache key
|
|
97
|
+
* @returns The cached data or undefined if not found or expired
|
|
98
|
+
*/
|
|
99
|
+
get(key) {
|
|
100
|
+
const cacheEntry = __classPrivateFieldGet(this, _CacheManager_cache, "f").get(key);
|
|
101
|
+
if (!cacheEntry) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
// Check if the entry is expired
|
|
105
|
+
const now = (0, utils_js_1.fetchTimeNow)();
|
|
106
|
+
if (now - cacheEntry.timestamp > __classPrivateFieldGet(this, _CacheManager_cacheTTL, "f")) {
|
|
107
|
+
// Entry expired, remove it from cache
|
|
108
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
109
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return cacheEntry.data;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Add an entry to the cache, evicting oldest entries if necessary
|
|
116
|
+
*
|
|
117
|
+
* @param key - The cache key
|
|
118
|
+
* @param data - The data to cache
|
|
119
|
+
*/
|
|
120
|
+
set(key, data) {
|
|
121
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").set(key, {
|
|
122
|
+
data,
|
|
123
|
+
timestamp: (0, utils_js_1.fetchTimeNow)(),
|
|
124
|
+
});
|
|
125
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
126
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Delete a specific entry from the cache
|
|
130
|
+
*
|
|
131
|
+
* @param key - The cache key
|
|
132
|
+
* @returns True if an entry was deleted
|
|
133
|
+
*/
|
|
134
|
+
delete(key) {
|
|
135
|
+
const result = __classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
136
|
+
if (result) {
|
|
137
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get all keys in the cache
|
|
143
|
+
*
|
|
144
|
+
* @returns Array of cache keys
|
|
145
|
+
*/
|
|
146
|
+
keys() {
|
|
147
|
+
return Array.from(__classPrivateFieldGet(this, _CacheManager_cache, "f").keys());
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get all entries in the cache (including expired ones)
|
|
151
|
+
* Useful for debugging or persistence
|
|
152
|
+
*
|
|
153
|
+
* @returns Record of all cache entries
|
|
154
|
+
*/
|
|
155
|
+
getAllEntries() {
|
|
156
|
+
return Object.fromEntries(__classPrivateFieldGet(this, _CacheManager_cache, "f"));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.CacheManager = CacheManager;
|
|
160
|
+
_CacheManager_cacheTTL = new WeakMap(), _CacheManager_maxCacheSize = new WeakMap(), _CacheManager_cache = new WeakMap(), _CacheManager_updateState = new WeakMap(), _CacheManager_instances = new WeakSet(), _CacheManager_persistCache = function _CacheManager_persistCache() {
|
|
161
|
+
__classPrivateFieldGet(this, _CacheManager_updateState, "f").call(this, Object.fromEntries(__classPrivateFieldGet(this, _CacheManager_cache, "f")));
|
|
162
|
+
}, _CacheManager_evictEntries = function _CacheManager_evictEntries() {
|
|
163
|
+
if (__classPrivateFieldGet(this, _CacheManager_cache, "f").size <= __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f")) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const entriesToRemove = __classPrivateFieldGet(this, _CacheManager_cache, "f").size - __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f");
|
|
167
|
+
let count = 0;
|
|
168
|
+
// Delete the oldest entries (Map maintains insertion order)
|
|
169
|
+
for (const key of __classPrivateFieldGet(this, _CacheManager_cache, "f").keys()) {
|
|
170
|
+
if (count >= entriesToRemove) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
174
|
+
count += 1;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=CacheManager.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheManager.cjs","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetchTimeNow } from './utils.js';\n\n/**\n * Generic cache entry type that wraps the data with a timestamp\n */\nexport type CacheEntry<T> = {\n data: T;\n timestamp: number;\n};\n\n/**\n * Configuration options for CacheManager\n */\nexport type CacheManagerOptions<T> = {\n cacheTTL?: number;\n maxCacheSize?: number;\n initialCache?: Record<string, CacheEntry<T>>;\n updateState: (cache: Record<string, CacheEntry<T>>) => void;\n};\n\n/**\n * Generic cache manager with TTL and size limit support\n *\n * @template T - The type of data to cache\n */\nexport class CacheManager<T> {\n #cacheTTL: number;\n\n #maxCacheSize: number;\n\n readonly #cache: Map<string, CacheEntry<T>>;\n\n readonly #updateState: (cache: Record<string, CacheEntry<T>>) => void;\n\n /**\n * Constructor for CacheManager\n *\n * @param options - Cache configuration options\n * @param options.cacheTTL - Time to live in seconds for cached entries\n * @param options.maxCacheSize - Maximum number of entries in the cache\n * @param options.initialCache - Initial cache state\n * @param options.updateState - Function to update the state when cache changes\n */\n constructor({\n cacheTTL = 300, // 5 minutes default\n maxCacheSize = 100,\n initialCache = {},\n updateState,\n }: CacheManagerOptions<T>) {\n this.#cacheTTL = cacheTTL;\n this.#maxCacheSize = maxCacheSize;\n this.#cache = new Map(Object.entries(initialCache));\n this.#updateState = updateState;\n this.#evictEntries();\n }\n\n /**\n * Set the time-to-live for cached entries\n *\n * @param ttl - The TTL in seconds\n */\n setTTL(ttl: number): void {\n this.#cacheTTL = ttl;\n }\n\n /**\n * Get the current TTL setting\n *\n * @returns The TTL in seconds\n */\n getTTL(): number {\n return this.#cacheTTL;\n }\n\n /**\n * Set the maximum cache size\n *\n * @param maxSize - The maximum cache size\n */\n setMaxSize(maxSize: number): void {\n this.#maxCacheSize = maxSize;\n this.#evictEntries();\n }\n\n /**\n * Get the current maximum cache size\n *\n * @returns The maximum cache size\n */\n getMaxSize(): number {\n return this.#maxCacheSize;\n }\n\n /**\n * Get the current cache size\n *\n * @returns The current number of entries in the cache\n */\n getSize(): number {\n return this.#cache.size;\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n this.#cache.clear();\n this.#persistCache();\n }\n\n /**\n * Get a cached result if it exists and is not expired\n *\n * @param key - The cache key\n * @returns The cached data or undefined if not found or expired\n */\n get(key: string): T | undefined {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return undefined;\n }\n\n // Check if the entry is expired\n const now = fetchTimeNow();\n if (now - cacheEntry.timestamp > this.#cacheTTL) {\n // Entry expired, remove it from cache\n this.#cache.delete(key);\n this.#persistCache();\n return undefined;\n }\n\n return cacheEntry.data;\n }\n\n /**\n * Add an entry to the cache, evicting oldest entries if necessary\n *\n * @param key - The cache key\n * @param data - The data to cache\n */\n set(key: string, data: T): void {\n this.#cache.set(key, {\n data,\n timestamp: fetchTimeNow(),\n });\n\n this.#evictEntries();\n this.#persistCache();\n }\n\n /**\n * Delete a specific entry from the cache\n *\n * @param key - The cache key\n * @returns True if an entry was deleted\n */\n delete(key: string): boolean {\n const result = this.#cache.delete(key);\n if (result) {\n this.#persistCache();\n }\n return result;\n }\n\n /**\n * Get all keys in the cache\n *\n * @returns Array of cache keys\n */\n keys(): string[] {\n return Array.from(this.#cache.keys());\n }\n\n /**\n * Get all entries in the cache (including expired ones)\n * Useful for debugging or persistence\n *\n * @returns Record of all cache entries\n */\n getAllEntries(): Record<string, CacheEntry<T>> {\n return Object.fromEntries(this.#cache);\n }\n\n /**\n * Persist the current cache state\n */\n #persistCache(): void {\n this.#updateState(Object.fromEntries(this.#cache));\n }\n\n /**\n * Evict oldest entries if cache exceeds max size\n */\n #evictEntries(): void {\n if (this.#cache.size <= this.#maxCacheSize) {\n return;\n }\n\n const entriesToRemove = this.#cache.size - this.#maxCacheSize;\n let count = 0;\n // Delete the oldest entries (Map maintains insertion order)\n for (const key of this.#cache.keys()) {\n if (count >= entriesToRemove) {\n break;\n }\n this.#cache.delete(key);\n count += 1;\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic cache entry type that wraps the data with a timestamp
|
|
3
|
+
*/
|
|
4
|
+
export type CacheEntry<T> = {
|
|
5
|
+
data: T;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for CacheManager
|
|
10
|
+
*/
|
|
11
|
+
export type CacheManagerOptions<T> = {
|
|
12
|
+
cacheTTL?: number;
|
|
13
|
+
maxCacheSize?: number;
|
|
14
|
+
initialCache?: Record<string, CacheEntry<T>>;
|
|
15
|
+
updateState: (cache: Record<string, CacheEntry<T>>) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Generic cache manager with TTL and size limit support
|
|
19
|
+
*
|
|
20
|
+
* @template T - The type of data to cache
|
|
21
|
+
*/
|
|
22
|
+
export declare class CacheManager<T> {
|
|
23
|
+
#private;
|
|
24
|
+
/**
|
|
25
|
+
* Constructor for CacheManager
|
|
26
|
+
*
|
|
27
|
+
* @param options - Cache configuration options
|
|
28
|
+
* @param options.cacheTTL - Time to live in seconds for cached entries
|
|
29
|
+
* @param options.maxCacheSize - Maximum number of entries in the cache
|
|
30
|
+
* @param options.initialCache - Initial cache state
|
|
31
|
+
* @param options.updateState - Function to update the state when cache changes
|
|
32
|
+
*/
|
|
33
|
+
constructor({ cacheTTL, // 5 minutes default
|
|
34
|
+
maxCacheSize, initialCache, updateState, }: CacheManagerOptions<T>);
|
|
35
|
+
/**
|
|
36
|
+
* Set the time-to-live for cached entries
|
|
37
|
+
*
|
|
38
|
+
* @param ttl - The TTL in seconds
|
|
39
|
+
*/
|
|
40
|
+
setTTL(ttl: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get the current TTL setting
|
|
43
|
+
*
|
|
44
|
+
* @returns The TTL in seconds
|
|
45
|
+
*/
|
|
46
|
+
getTTL(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Set the maximum cache size
|
|
49
|
+
*
|
|
50
|
+
* @param maxSize - The maximum cache size
|
|
51
|
+
*/
|
|
52
|
+
setMaxSize(maxSize: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the current maximum cache size
|
|
55
|
+
*
|
|
56
|
+
* @returns The maximum cache size
|
|
57
|
+
*/
|
|
58
|
+
getMaxSize(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Get the current cache size
|
|
61
|
+
*
|
|
62
|
+
* @returns The current number of entries in the cache
|
|
63
|
+
*/
|
|
64
|
+
getSize(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Clear the cache
|
|
67
|
+
*/
|
|
68
|
+
clear(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get a cached result if it exists and is not expired
|
|
71
|
+
*
|
|
72
|
+
* @param key - The cache key
|
|
73
|
+
* @returns The cached data or undefined if not found or expired
|
|
74
|
+
*/
|
|
75
|
+
get(key: string): T | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Add an entry to the cache, evicting oldest entries if necessary
|
|
78
|
+
*
|
|
79
|
+
* @param key - The cache key
|
|
80
|
+
* @param data - The data to cache
|
|
81
|
+
*/
|
|
82
|
+
set(key: string, data: T): void;
|
|
83
|
+
/**
|
|
84
|
+
* Delete a specific entry from the cache
|
|
85
|
+
*
|
|
86
|
+
* @param key - The cache key
|
|
87
|
+
* @returns True if an entry was deleted
|
|
88
|
+
*/
|
|
89
|
+
delete(key: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Get all keys in the cache
|
|
92
|
+
*
|
|
93
|
+
* @returns Array of cache keys
|
|
94
|
+
*/
|
|
95
|
+
keys(): string[];
|
|
96
|
+
/**
|
|
97
|
+
* Get all entries in the cache (including expired ones)
|
|
98
|
+
* Useful for debugging or persistence
|
|
99
|
+
*
|
|
100
|
+
* @returns Record of all cache entries
|
|
101
|
+
*/
|
|
102
|
+
getAllEntries(): Record<string, CacheEntry<T>>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=CacheManager.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheManager.d.cts","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC;;IASzB;;;;;;;;OAQG;gBACS,EACV,QAAc,EAAE,oBAAoB;IACpC,YAAkB,EAClB,YAAiB,EACjB,WAAW,GACZ,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzB;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;;OAIG;IACH,MAAM,IAAI,MAAM;IAIhB;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAkB/B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAU/B;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ5B;;;;OAIG;IACH,IAAI,IAAI,MAAM,EAAE;IAIhB;;;;;OAKG;IACH,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CA8B/C"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic cache entry type that wraps the data with a timestamp
|
|
3
|
+
*/
|
|
4
|
+
export type CacheEntry<T> = {
|
|
5
|
+
data: T;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Configuration options for CacheManager
|
|
10
|
+
*/
|
|
11
|
+
export type CacheManagerOptions<T> = {
|
|
12
|
+
cacheTTL?: number;
|
|
13
|
+
maxCacheSize?: number;
|
|
14
|
+
initialCache?: Record<string, CacheEntry<T>>;
|
|
15
|
+
updateState: (cache: Record<string, CacheEntry<T>>) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Generic cache manager with TTL and size limit support
|
|
19
|
+
*
|
|
20
|
+
* @template T - The type of data to cache
|
|
21
|
+
*/
|
|
22
|
+
export declare class CacheManager<T> {
|
|
23
|
+
#private;
|
|
24
|
+
/**
|
|
25
|
+
* Constructor for CacheManager
|
|
26
|
+
*
|
|
27
|
+
* @param options - Cache configuration options
|
|
28
|
+
* @param options.cacheTTL - Time to live in seconds for cached entries
|
|
29
|
+
* @param options.maxCacheSize - Maximum number of entries in the cache
|
|
30
|
+
* @param options.initialCache - Initial cache state
|
|
31
|
+
* @param options.updateState - Function to update the state when cache changes
|
|
32
|
+
*/
|
|
33
|
+
constructor({ cacheTTL, // 5 minutes default
|
|
34
|
+
maxCacheSize, initialCache, updateState, }: CacheManagerOptions<T>);
|
|
35
|
+
/**
|
|
36
|
+
* Set the time-to-live for cached entries
|
|
37
|
+
*
|
|
38
|
+
* @param ttl - The TTL in seconds
|
|
39
|
+
*/
|
|
40
|
+
setTTL(ttl: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get the current TTL setting
|
|
43
|
+
*
|
|
44
|
+
* @returns The TTL in seconds
|
|
45
|
+
*/
|
|
46
|
+
getTTL(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Set the maximum cache size
|
|
49
|
+
*
|
|
50
|
+
* @param maxSize - The maximum cache size
|
|
51
|
+
*/
|
|
52
|
+
setMaxSize(maxSize: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get the current maximum cache size
|
|
55
|
+
*
|
|
56
|
+
* @returns The maximum cache size
|
|
57
|
+
*/
|
|
58
|
+
getMaxSize(): number;
|
|
59
|
+
/**
|
|
60
|
+
* Get the current cache size
|
|
61
|
+
*
|
|
62
|
+
* @returns The current number of entries in the cache
|
|
63
|
+
*/
|
|
64
|
+
getSize(): number;
|
|
65
|
+
/**
|
|
66
|
+
* Clear the cache
|
|
67
|
+
*/
|
|
68
|
+
clear(): void;
|
|
69
|
+
/**
|
|
70
|
+
* Get a cached result if it exists and is not expired
|
|
71
|
+
*
|
|
72
|
+
* @param key - The cache key
|
|
73
|
+
* @returns The cached data or undefined if not found or expired
|
|
74
|
+
*/
|
|
75
|
+
get(key: string): T | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Add an entry to the cache, evicting oldest entries if necessary
|
|
78
|
+
*
|
|
79
|
+
* @param key - The cache key
|
|
80
|
+
* @param data - The data to cache
|
|
81
|
+
*/
|
|
82
|
+
set(key: string, data: T): void;
|
|
83
|
+
/**
|
|
84
|
+
* Delete a specific entry from the cache
|
|
85
|
+
*
|
|
86
|
+
* @param key - The cache key
|
|
87
|
+
* @returns True if an entry was deleted
|
|
88
|
+
*/
|
|
89
|
+
delete(key: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Get all keys in the cache
|
|
92
|
+
*
|
|
93
|
+
* @returns Array of cache keys
|
|
94
|
+
*/
|
|
95
|
+
keys(): string[];
|
|
96
|
+
/**
|
|
97
|
+
* Get all entries in the cache (including expired ones)
|
|
98
|
+
* Useful for debugging or persistence
|
|
99
|
+
*
|
|
100
|
+
* @returns Record of all cache entries
|
|
101
|
+
*/
|
|
102
|
+
getAllEntries(): Record<string, CacheEntry<T>>;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=CacheManager.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheManager.d.mts","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;IAC1B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC;;IASzB;;;;;;;;OAQG;gBACS,EACV,QAAc,EAAE,oBAAoB;IACpC,YAAkB,EAClB,YAAiB,EACjB,WAAW,GACZ,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAQzB;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB;;;;OAIG;IACH,MAAM,IAAI,MAAM;IAIhB;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC;;;;OAIG;IACH,UAAU,IAAI,MAAM;IAIpB;;;;OAIG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAkB/B;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAU/B;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ5B;;;;OAIG;IACH,IAAI,IAAI,MAAM,EAAE;IAIhB;;;;;OAKG;IACH,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CA8B/C"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _CacheManager_instances, _CacheManager_cacheTTL, _CacheManager_maxCacheSize, _CacheManager_cache, _CacheManager_updateState, _CacheManager_persistCache, _CacheManager_evictEntries;
|
|
13
|
+
import { fetchTimeNow } from "./utils.mjs";
|
|
14
|
+
/**
|
|
15
|
+
* Generic cache manager with TTL and size limit support
|
|
16
|
+
*
|
|
17
|
+
* @template T - The type of data to cache
|
|
18
|
+
*/
|
|
19
|
+
export class CacheManager {
|
|
20
|
+
/**
|
|
21
|
+
* Constructor for CacheManager
|
|
22
|
+
*
|
|
23
|
+
* @param options - Cache configuration options
|
|
24
|
+
* @param options.cacheTTL - Time to live in seconds for cached entries
|
|
25
|
+
* @param options.maxCacheSize - Maximum number of entries in the cache
|
|
26
|
+
* @param options.initialCache - Initial cache state
|
|
27
|
+
* @param options.updateState - Function to update the state when cache changes
|
|
28
|
+
*/
|
|
29
|
+
constructor({ cacheTTL = 300, // 5 minutes default
|
|
30
|
+
maxCacheSize = 100, initialCache = {}, updateState, }) {
|
|
31
|
+
_CacheManager_instances.add(this);
|
|
32
|
+
_CacheManager_cacheTTL.set(this, void 0);
|
|
33
|
+
_CacheManager_maxCacheSize.set(this, void 0);
|
|
34
|
+
_CacheManager_cache.set(this, void 0);
|
|
35
|
+
_CacheManager_updateState.set(this, void 0);
|
|
36
|
+
__classPrivateFieldSet(this, _CacheManager_cacheTTL, cacheTTL, "f");
|
|
37
|
+
__classPrivateFieldSet(this, _CacheManager_maxCacheSize, maxCacheSize, "f");
|
|
38
|
+
__classPrivateFieldSet(this, _CacheManager_cache, new Map(Object.entries(initialCache)), "f");
|
|
39
|
+
__classPrivateFieldSet(this, _CacheManager_updateState, updateState, "f");
|
|
40
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Set the time-to-live for cached entries
|
|
44
|
+
*
|
|
45
|
+
* @param ttl - The TTL in seconds
|
|
46
|
+
*/
|
|
47
|
+
setTTL(ttl) {
|
|
48
|
+
__classPrivateFieldSet(this, _CacheManager_cacheTTL, ttl, "f");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the current TTL setting
|
|
52
|
+
*
|
|
53
|
+
* @returns The TTL in seconds
|
|
54
|
+
*/
|
|
55
|
+
getTTL() {
|
|
56
|
+
return __classPrivateFieldGet(this, _CacheManager_cacheTTL, "f");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Set the maximum cache size
|
|
60
|
+
*
|
|
61
|
+
* @param maxSize - The maximum cache size
|
|
62
|
+
*/
|
|
63
|
+
setMaxSize(maxSize) {
|
|
64
|
+
__classPrivateFieldSet(this, _CacheManager_maxCacheSize, maxSize, "f");
|
|
65
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the current maximum cache size
|
|
69
|
+
*
|
|
70
|
+
* @returns The maximum cache size
|
|
71
|
+
*/
|
|
72
|
+
getMaxSize() {
|
|
73
|
+
return __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f");
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the current cache size
|
|
77
|
+
*
|
|
78
|
+
* @returns The current number of entries in the cache
|
|
79
|
+
*/
|
|
80
|
+
getSize() {
|
|
81
|
+
return __classPrivateFieldGet(this, _CacheManager_cache, "f").size;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Clear the cache
|
|
85
|
+
*/
|
|
86
|
+
clear() {
|
|
87
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").clear();
|
|
88
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get a cached result if it exists and is not expired
|
|
92
|
+
*
|
|
93
|
+
* @param key - The cache key
|
|
94
|
+
* @returns The cached data or undefined if not found or expired
|
|
95
|
+
*/
|
|
96
|
+
get(key) {
|
|
97
|
+
const cacheEntry = __classPrivateFieldGet(this, _CacheManager_cache, "f").get(key);
|
|
98
|
+
if (!cacheEntry) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
// Check if the entry is expired
|
|
102
|
+
const now = fetchTimeNow();
|
|
103
|
+
if (now - cacheEntry.timestamp > __classPrivateFieldGet(this, _CacheManager_cacheTTL, "f")) {
|
|
104
|
+
// Entry expired, remove it from cache
|
|
105
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
106
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return cacheEntry.data;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Add an entry to the cache, evicting oldest entries if necessary
|
|
113
|
+
*
|
|
114
|
+
* @param key - The cache key
|
|
115
|
+
* @param data - The data to cache
|
|
116
|
+
*/
|
|
117
|
+
set(key, data) {
|
|
118
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").set(key, {
|
|
119
|
+
data,
|
|
120
|
+
timestamp: fetchTimeNow(),
|
|
121
|
+
});
|
|
122
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_evictEntries).call(this);
|
|
123
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Delete a specific entry from the cache
|
|
127
|
+
*
|
|
128
|
+
* @param key - The cache key
|
|
129
|
+
* @returns True if an entry was deleted
|
|
130
|
+
*/
|
|
131
|
+
delete(key) {
|
|
132
|
+
const result = __classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
133
|
+
if (result) {
|
|
134
|
+
__classPrivateFieldGet(this, _CacheManager_instances, "m", _CacheManager_persistCache).call(this);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get all keys in the cache
|
|
140
|
+
*
|
|
141
|
+
* @returns Array of cache keys
|
|
142
|
+
*/
|
|
143
|
+
keys() {
|
|
144
|
+
return Array.from(__classPrivateFieldGet(this, _CacheManager_cache, "f").keys());
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get all entries in the cache (including expired ones)
|
|
148
|
+
* Useful for debugging or persistence
|
|
149
|
+
*
|
|
150
|
+
* @returns Record of all cache entries
|
|
151
|
+
*/
|
|
152
|
+
getAllEntries() {
|
|
153
|
+
return Object.fromEntries(__classPrivateFieldGet(this, _CacheManager_cache, "f"));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
_CacheManager_cacheTTL = new WeakMap(), _CacheManager_maxCacheSize = new WeakMap(), _CacheManager_cache = new WeakMap(), _CacheManager_updateState = new WeakMap(), _CacheManager_instances = new WeakSet(), _CacheManager_persistCache = function _CacheManager_persistCache() {
|
|
157
|
+
__classPrivateFieldGet(this, _CacheManager_updateState, "f").call(this, Object.fromEntries(__classPrivateFieldGet(this, _CacheManager_cache, "f")));
|
|
158
|
+
}, _CacheManager_evictEntries = function _CacheManager_evictEntries() {
|
|
159
|
+
if (__classPrivateFieldGet(this, _CacheManager_cache, "f").size <= __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f")) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const entriesToRemove = __classPrivateFieldGet(this, _CacheManager_cache, "f").size - __classPrivateFieldGet(this, _CacheManager_maxCacheSize, "f");
|
|
163
|
+
let count = 0;
|
|
164
|
+
// Delete the oldest entries (Map maintains insertion order)
|
|
165
|
+
for (const key of __classPrivateFieldGet(this, _CacheManager_cache, "f").keys()) {
|
|
166
|
+
if (count >= entriesToRemove) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
__classPrivateFieldGet(this, _CacheManager_cache, "f").delete(key);
|
|
170
|
+
count += 1;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=CacheManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheManager.mjs","sourceRoot":"","sources":["../src/CacheManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetchTimeNow } from './utils.js';\n\n/**\n * Generic cache entry type that wraps the data with a timestamp\n */\nexport type CacheEntry<T> = {\n data: T;\n timestamp: number;\n};\n\n/**\n * Configuration options for CacheManager\n */\nexport type CacheManagerOptions<T> = {\n cacheTTL?: number;\n maxCacheSize?: number;\n initialCache?: Record<string, CacheEntry<T>>;\n updateState: (cache: Record<string, CacheEntry<T>>) => void;\n};\n\n/**\n * Generic cache manager with TTL and size limit support\n *\n * @template T - The type of data to cache\n */\nexport class CacheManager<T> {\n #cacheTTL: number;\n\n #maxCacheSize: number;\n\n readonly #cache: Map<string, CacheEntry<T>>;\n\n readonly #updateState: (cache: Record<string, CacheEntry<T>>) => void;\n\n /**\n * Constructor for CacheManager\n *\n * @param options - Cache configuration options\n * @param options.cacheTTL - Time to live in seconds for cached entries\n * @param options.maxCacheSize - Maximum number of entries in the cache\n * @param options.initialCache - Initial cache state\n * @param options.updateState - Function to update the state when cache changes\n */\n constructor({\n cacheTTL = 300, // 5 minutes default\n maxCacheSize = 100,\n initialCache = {},\n updateState,\n }: CacheManagerOptions<T>) {\n this.#cacheTTL = cacheTTL;\n this.#maxCacheSize = maxCacheSize;\n this.#cache = new Map(Object.entries(initialCache));\n this.#updateState = updateState;\n this.#evictEntries();\n }\n\n /**\n * Set the time-to-live for cached entries\n *\n * @param ttl - The TTL in seconds\n */\n setTTL(ttl: number): void {\n this.#cacheTTL = ttl;\n }\n\n /**\n * Get the current TTL setting\n *\n * @returns The TTL in seconds\n */\n getTTL(): number {\n return this.#cacheTTL;\n }\n\n /**\n * Set the maximum cache size\n *\n * @param maxSize - The maximum cache size\n */\n setMaxSize(maxSize: number): void {\n this.#maxCacheSize = maxSize;\n this.#evictEntries();\n }\n\n /**\n * Get the current maximum cache size\n *\n * @returns The maximum cache size\n */\n getMaxSize(): number {\n return this.#maxCacheSize;\n }\n\n /**\n * Get the current cache size\n *\n * @returns The current number of entries in the cache\n */\n getSize(): number {\n return this.#cache.size;\n }\n\n /**\n * Clear the cache\n */\n clear(): void {\n this.#cache.clear();\n this.#persistCache();\n }\n\n /**\n * Get a cached result if it exists and is not expired\n *\n * @param key - The cache key\n * @returns The cached data or undefined if not found or expired\n */\n get(key: string): T | undefined {\n const cacheEntry = this.#cache.get(key);\n if (!cacheEntry) {\n return undefined;\n }\n\n // Check if the entry is expired\n const now = fetchTimeNow();\n if (now - cacheEntry.timestamp > this.#cacheTTL) {\n // Entry expired, remove it from cache\n this.#cache.delete(key);\n this.#persistCache();\n return undefined;\n }\n\n return cacheEntry.data;\n }\n\n /**\n * Add an entry to the cache, evicting oldest entries if necessary\n *\n * @param key - The cache key\n * @param data - The data to cache\n */\n set(key: string, data: T): void {\n this.#cache.set(key, {\n data,\n timestamp: fetchTimeNow(),\n });\n\n this.#evictEntries();\n this.#persistCache();\n }\n\n /**\n * Delete a specific entry from the cache\n *\n * @param key - The cache key\n * @returns True if an entry was deleted\n */\n delete(key: string): boolean {\n const result = this.#cache.delete(key);\n if (result) {\n this.#persistCache();\n }\n return result;\n }\n\n /**\n * Get all keys in the cache\n *\n * @returns Array of cache keys\n */\n keys(): string[] {\n return Array.from(this.#cache.keys());\n }\n\n /**\n * Get all entries in the cache (including expired ones)\n * Useful for debugging or persistence\n *\n * @returns Record of all cache entries\n */\n getAllEntries(): Record<string, CacheEntry<T>> {\n return Object.fromEntries(this.#cache);\n }\n\n /**\n * Persist the current cache state\n */\n #persistCache(): void {\n this.#updateState(Object.fromEntries(this.#cache));\n }\n\n /**\n * Evict oldest entries if cache exceeds max size\n */\n #evictEntries(): void {\n if (this.#cache.size <= this.#maxCacheSize) {\n return;\n }\n\n const entriesToRemove = this.#cache.size - this.#maxCacheSize;\n let count = 0;\n // Delete the oldest entries (Map maintains insertion order)\n for (const key of this.#cache.keys()) {\n if (count >= entriesToRemove) {\n break;\n }\n this.#cache.delete(key);\n count += 1;\n }\n }\n}\n"]}
|