@fjell/cache 4.7.55 → 4.7.57
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/dist/Operations.d.ts.map +1 -1
- package/dist/browser/AsyncIndexDBCacheMap.d.ts +5 -1
- package/dist/browser/AsyncIndexDBCacheMap.d.ts.map +1 -1
- package/dist/browser/IndexDBCacheMap.d.ts +5 -1
- package/dist/browser/IndexDBCacheMap.d.ts.map +1 -1
- package/dist/browser/LocalStorageCacheMap.d.ts +5 -1
- package/dist/browser/LocalStorageCacheMap.d.ts.map +1 -1
- package/dist/browser/SessionStorageCacheMap.d.ts +5 -1
- package/dist/browser/SessionStorageCacheMap.d.ts.map +1 -1
- package/dist/cache/TwoLayerFactory.d.ts.map +1 -1
- package/dist/cache/layers/ItemCache.d.ts +0 -2
- package/dist/cache/layers/ItemCache.d.ts.map +1 -1
- package/dist/cache/layers/QueryCache.d.ts +0 -2
- package/dist/cache/layers/QueryCache.d.ts.map +1 -1
- package/dist/cache/layers/TwoLayerCacheMap.d.ts.map +1 -1
- package/dist/cache/types/TwoLayerTypes.d.ts +0 -1
- package/dist/cache/types/TwoLayerTypes.d.ts.map +1 -1
- package/dist/cache/warming/CacheWarmer.d.ts +0 -2
- package/dist/cache/warming/CacheWarmer.d.ts.map +1 -1
- package/dist/index.js +1038 -721
- package/dist/memory/EnhancedMemoryCacheMap.d.ts +5 -1
- package/dist/memory/EnhancedMemoryCacheMap.d.ts.map +1 -1
- package/dist/memory/MemoryCacheMap.d.ts +5 -1
- package/dist/memory/MemoryCacheMap.d.ts.map +1 -1
- package/dist/normalization.d.ts +1 -0
- package/dist/normalization.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/cache/TwoLayerDemo.d.ts +0 -29
- package/dist/cache/TwoLayerDemo.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -16,6 +16,12 @@ import Logging from "@fjell/logging";
|
|
|
16
16
|
var LibLogger = Logging.getLogger("@fjell/cache");
|
|
17
17
|
var logger_default = LibLogger;
|
|
18
18
|
|
|
19
|
+
// src/cache/layers/ItemCache.ts
|
|
20
|
+
var logger = logger_default.get("ItemCache");
|
|
21
|
+
|
|
22
|
+
// src/cache/layers/QueryCache.ts
|
|
23
|
+
var logger2 = logger_default.get("QueryCache");
|
|
24
|
+
|
|
19
25
|
// src/CacheMap.ts
|
|
20
26
|
var CacheMap = class {
|
|
21
27
|
types;
|
|
@@ -25,7 +31,7 @@ var CacheMap = class {
|
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
// src/cache/layers/TwoLayerCacheMap.ts
|
|
28
|
-
var
|
|
34
|
+
var logger3 = logger_default.get("TwoLayerCacheMap");
|
|
29
35
|
var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
30
36
|
constructor(underlyingCache, options = {}) {
|
|
31
37
|
super(underlyingCache.types);
|
|
@@ -35,18 +41,15 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
35
41
|
// 1 hour for items
|
|
36
42
|
queryTTL: options.queryTTL || 300,
|
|
37
43
|
// 5 minutes for complete queries
|
|
38
|
-
facetTTL: options.facetTTL || 60
|
|
44
|
+
facetTTL: options.facetTTL || 60
|
|
39
45
|
// 1 minute for partial queries
|
|
40
|
-
debug: options.debug || false
|
|
41
46
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
}
|
|
47
|
+
logger3.debug("TwoLayerCacheMap initialized", {
|
|
48
|
+
underlyingType: this.underlyingCache.implementationType,
|
|
49
|
+
itemTTL: this.options.itemTTL,
|
|
50
|
+
queryTTL: this.options.queryTTL,
|
|
51
|
+
facetTTL: this.options.facetTTL
|
|
52
|
+
});
|
|
50
53
|
}
|
|
51
54
|
options;
|
|
52
55
|
// Query metadata tracking for enhanced TTL and completeness
|
|
@@ -94,13 +97,11 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
94
97
|
* Set a query result with rich metadata for two-layer architecture
|
|
95
98
|
*/
|
|
96
99
|
async setQueryResult(queryHash, itemKeys) {
|
|
97
|
-
|
|
100
|
+
logger3.debug("QUERY_CACHE: TwoLayerCacheMap.setQueryResult() called", {
|
|
98
101
|
queryHash,
|
|
99
102
|
itemKeyCount: itemKeys.length,
|
|
100
103
|
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
101
104
|
});
|
|
102
|
-
await this.underlyingCache.setQueryResult(queryHash, itemKeys);
|
|
103
|
-
logger.debug("QUERY_CACHE: Stored query result in underlying cache", { queryHash });
|
|
104
105
|
const now = /* @__PURE__ */ new Date();
|
|
105
106
|
const isComplete = this.determineQueryCompleteness(queryHash, itemKeys);
|
|
106
107
|
const ttlSeconds = isComplete ? this.options.queryTTL : this.options.facetTTL;
|
|
@@ -114,7 +115,17 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
114
115
|
params: this.extractParams(queryHash)
|
|
115
116
|
};
|
|
116
117
|
this.queryMetadataMap.set(queryHash, metadata);
|
|
117
|
-
|
|
118
|
+
if ("setQueryResult" in this.underlyingCache) {
|
|
119
|
+
const setQueryResultFn = this.underlyingCache.setQueryResult;
|
|
120
|
+
if (setQueryResultFn.length >= 3) {
|
|
121
|
+
await this.underlyingCache.setQueryResult(queryHash, itemKeys, metadata);
|
|
122
|
+
logger3.debug("QUERY_CACHE: Stored query result with metadata in underlying cache", { queryHash });
|
|
123
|
+
} else {
|
|
124
|
+
await this.underlyingCache.setQueryResult(queryHash, itemKeys);
|
|
125
|
+
logger3.debug("QUERY_CACHE: Stored query result without metadata in underlying cache (not supported)", { queryHash });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
logger3.debug("QUERY_CACHE: Set query result with metadata", {
|
|
118
129
|
queryHash,
|
|
119
130
|
itemCount: itemKeys.length,
|
|
120
131
|
isComplete,
|
|
@@ -130,12 +141,27 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
130
141
|
* Get a query result with expiration checking
|
|
131
142
|
*/
|
|
132
143
|
async getQueryResult(queryHash) {
|
|
133
|
-
|
|
134
|
-
|
|
144
|
+
logger3.debug("QUERY_CACHE: TwoLayerCacheMap.getQueryResult() called", { queryHash });
|
|
145
|
+
let metadata = this.queryMetadataMap.get(queryHash);
|
|
146
|
+
if (!metadata && "getQueryResultWithMetadata" in this.underlyingCache) {
|
|
147
|
+
logger3.debug("QUERY_CACHE: Metadata not in memory, loading from underlying cache", { queryHash });
|
|
148
|
+
const resultWithMetadata = await this.underlyingCache.getQueryResultWithMetadata(queryHash);
|
|
149
|
+
if (resultWithMetadata?.metadata) {
|
|
150
|
+
const restoredMetadata = resultWithMetadata.metadata;
|
|
151
|
+
metadata = restoredMetadata;
|
|
152
|
+
this.queryMetadataMap.set(queryHash, restoredMetadata);
|
|
153
|
+
logger3.debug("QUERY_CACHE: Loaded metadata from underlying cache", {
|
|
154
|
+
queryHash,
|
|
155
|
+
expiresAt: restoredMetadata.expiresAt.toISOString(),
|
|
156
|
+
isComplete: restoredMetadata.isComplete,
|
|
157
|
+
queryType: restoredMetadata.queryType
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
135
161
|
if (metadata) {
|
|
136
162
|
const now = /* @__PURE__ */ new Date();
|
|
137
163
|
const isExpired = metadata.expiresAt < now;
|
|
138
|
-
|
|
164
|
+
logger3.debug("QUERY_CACHE: Query metadata found", {
|
|
139
165
|
queryHash,
|
|
140
166
|
isExpired,
|
|
141
167
|
expiresAt: metadata.expiresAt.toISOString(),
|
|
@@ -144,7 +170,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
144
170
|
queryType: metadata.queryType
|
|
145
171
|
});
|
|
146
172
|
if (isExpired) {
|
|
147
|
-
|
|
173
|
+
logger3.debug("QUERY_CACHE: Query result EXPIRED, removing", {
|
|
148
174
|
queryHash,
|
|
149
175
|
expiresAt: metadata.expiresAt.toISOString(),
|
|
150
176
|
now: now.toISOString()
|
|
@@ -153,19 +179,19 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
153
179
|
return null;
|
|
154
180
|
}
|
|
155
181
|
} else {
|
|
156
|
-
|
|
182
|
+
logger3.debug("QUERY_CACHE: No metadata found for query hash (neither in memory nor persistent)", { queryHash });
|
|
157
183
|
}
|
|
158
|
-
|
|
184
|
+
logger3.debug("QUERY_CACHE: Fetching query result from underlying cache", { queryHash });
|
|
159
185
|
const result = await this.underlyingCache.getQueryResult(queryHash);
|
|
160
186
|
if (result) {
|
|
161
|
-
|
|
187
|
+
logger3.debug("QUERY_CACHE: Query result retrieved from underlying cache", {
|
|
162
188
|
queryHash,
|
|
163
189
|
itemCount: result.length,
|
|
164
190
|
isComplete: metadata?.isComplete,
|
|
165
191
|
itemKeys: result.map((k) => JSON.stringify(k))
|
|
166
192
|
});
|
|
167
193
|
} else {
|
|
168
|
-
|
|
194
|
+
logger3.debug("QUERY_CACHE: No query result found in underlying cache", { queryHash });
|
|
169
195
|
}
|
|
170
196
|
return result;
|
|
171
197
|
}
|
|
@@ -180,12 +206,12 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
180
206
|
* Delete a query result and its metadata
|
|
181
207
|
*/
|
|
182
208
|
async deleteQueryResult(queryHash) {
|
|
183
|
-
|
|
209
|
+
logger3.debug("QUERY_CACHE: TwoLayerCacheMap.deleteQueryResult() called", { queryHash });
|
|
184
210
|
const hadMetadata = this.queryMetadataMap.has(queryHash);
|
|
185
211
|
const metadata = this.queryMetadataMap.get(queryHash);
|
|
186
212
|
await this.underlyingCache.deleteQueryResult(queryHash);
|
|
187
213
|
this.queryMetadataMap.delete(queryHash);
|
|
188
|
-
|
|
214
|
+
logger3.debug("QUERY_CACHE: Deleted query result", {
|
|
189
215
|
queryHash,
|
|
190
216
|
hadMetadata,
|
|
191
217
|
wasComplete: metadata?.isComplete,
|
|
@@ -197,11 +223,11 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
197
223
|
* Invalidate queries that are affected by item changes
|
|
198
224
|
*/
|
|
199
225
|
async invalidateQueriesForItem(itemKey) {
|
|
200
|
-
|
|
226
|
+
logger3.debug("QUERY_CACHE: Invalidating queries for item change", {
|
|
201
227
|
itemKey: JSON.stringify(itemKey)
|
|
202
228
|
});
|
|
203
229
|
const affectedQueries = await this.findQueriesContainingItem(itemKey);
|
|
204
|
-
|
|
230
|
+
logger3.debug("QUERY_CACHE: Found queries containing item", {
|
|
205
231
|
itemKey: JSON.stringify(itemKey),
|
|
206
232
|
affectedQueryCount: affectedQueries.length,
|
|
207
233
|
affectedQueries
|
|
@@ -210,13 +236,13 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
210
236
|
await this.deleteQueryResult(queryHash);
|
|
211
237
|
}
|
|
212
238
|
if (affectedQueries.length > 0) {
|
|
213
|
-
|
|
239
|
+
logger3.debug("QUERY_CACHE: Invalidated queries for item change", {
|
|
214
240
|
itemKey: JSON.stringify(itemKey),
|
|
215
241
|
queriesInvalidated: affectedQueries.length,
|
|
216
242
|
queryHashes: affectedQueries
|
|
217
243
|
});
|
|
218
244
|
} else {
|
|
219
|
-
|
|
245
|
+
logger3.debug("QUERY_CACHE: No queries found containing item", {
|
|
220
246
|
itemKey: JSON.stringify(itemKey)
|
|
221
247
|
});
|
|
222
248
|
}
|
|
@@ -240,13 +266,13 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
240
266
|
* Determine if a query result is complete or partial based on query hash
|
|
241
267
|
*/
|
|
242
268
|
determineQueryCompleteness(queryHash, itemKeys) {
|
|
243
|
-
if (queryHash.includes('"query":{}') || queryHash.includes('"query": {}')) {
|
|
244
|
-
return true;
|
|
245
|
-
}
|
|
246
269
|
if (queryHash.includes("facet:") || queryHash.includes("filter:")) {
|
|
247
270
|
return false;
|
|
248
271
|
}
|
|
249
|
-
if (queryHash.
|
|
272
|
+
if (queryHash.startsWith("all:") && (queryHash.includes("query:{}") || queryHash.includes('"query":{}') || queryHash.includes('"query": {}'))) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
if (queryHash.startsWith("all:") && !queryHash.includes("query:")) {
|
|
250
276
|
return true;
|
|
251
277
|
}
|
|
252
278
|
return false;
|
|
@@ -359,14 +385,14 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
359
385
|
const startTime = Date.now();
|
|
360
386
|
const now = /* @__PURE__ */ new Date();
|
|
361
387
|
const expiredQueries = [];
|
|
362
|
-
|
|
388
|
+
logger3.debug("TWO_LAYER: Starting query cleanup", {
|
|
363
389
|
totalQueries: this.queryMetadataMap.size,
|
|
364
390
|
now: now.toISOString()
|
|
365
391
|
});
|
|
366
392
|
for (const [queryHash, metadata] of this.queryMetadataMap.entries()) {
|
|
367
393
|
if (metadata.expiresAt < now) {
|
|
368
394
|
expiredQueries.push(queryHash);
|
|
369
|
-
|
|
395
|
+
logger3.debug("TWO_LAYER: Found expired query", {
|
|
370
396
|
queryHash,
|
|
371
397
|
queryType: metadata.queryType,
|
|
372
398
|
isComplete: metadata.isComplete,
|
|
@@ -380,13 +406,13 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
380
406
|
}
|
|
381
407
|
const duration = Date.now() - startTime;
|
|
382
408
|
if (expiredQueries.length > 0) {
|
|
383
|
-
|
|
409
|
+
logger3.debug("TWO_LAYER: Query cleanup completed", {
|
|
384
410
|
expiredCount: expiredQueries.length,
|
|
385
411
|
totalQueries: this.queryMetadataMap.size,
|
|
386
412
|
duration
|
|
387
413
|
});
|
|
388
414
|
} else {
|
|
389
|
-
|
|
415
|
+
logger3.debug("TWO_LAYER: Query cleanup - no expired queries", {
|
|
390
416
|
totalQueries: this.queryMetadataMap.size,
|
|
391
417
|
duration
|
|
392
418
|
});
|
|
@@ -402,7 +428,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
402
428
|
// ===== MISSING ABSTRACT METHODS FROM CacheMap =====
|
|
403
429
|
async invalidateItemKeys(keys) {
|
|
404
430
|
const startTime = Date.now();
|
|
405
|
-
|
|
431
|
+
logger3.debug("TWO_LAYER: Invalidating item keys", {
|
|
406
432
|
keyCount: keys.length,
|
|
407
433
|
keys: keys.map((k) => JSON.stringify(k))
|
|
408
434
|
});
|
|
@@ -417,14 +443,14 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
417
443
|
const invalidated = beforeCount - afterCount;
|
|
418
444
|
totalInvalidatedQueries += invalidated;
|
|
419
445
|
if (invalidated > 0) {
|
|
420
|
-
|
|
446
|
+
logger3.debug("TWO_LAYER: Invalidated queries for item", {
|
|
421
447
|
key: JSON.stringify(key),
|
|
422
448
|
queriesInvalidated: invalidated
|
|
423
449
|
});
|
|
424
450
|
}
|
|
425
451
|
}
|
|
426
452
|
const duration = Date.now() - startTime;
|
|
427
|
-
|
|
453
|
+
logger3.debug("TWO_LAYER: Item key invalidation completed", {
|
|
428
454
|
keyCount: keys.length,
|
|
429
455
|
totalQueriesInvalidated: totalInvalidatedQueries,
|
|
430
456
|
duration
|
|
@@ -433,7 +459,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
433
459
|
async invalidateLocation(locations) {
|
|
434
460
|
const startTime = Date.now();
|
|
435
461
|
const queryCountBefore = this.queryMetadataMap.size;
|
|
436
|
-
|
|
462
|
+
logger3.debug("TWO_LAYER: Invalidating location", {
|
|
437
463
|
locations: JSON.stringify(locations),
|
|
438
464
|
queryCountBefore
|
|
439
465
|
});
|
|
@@ -442,7 +468,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
442
468
|
}
|
|
443
469
|
this.queryMetadataMap.clear();
|
|
444
470
|
const duration = Date.now() - startTime;
|
|
445
|
-
|
|
471
|
+
logger3.debug("TWO_LAYER: Location invalidation completed", {
|
|
446
472
|
locations: JSON.stringify(locations),
|
|
447
473
|
queriesCleared: queryCountBefore,
|
|
448
474
|
duration
|
|
@@ -451,7 +477,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
451
477
|
async clearQueryResults() {
|
|
452
478
|
const startTime = Date.now();
|
|
453
479
|
const queryCountBefore = this.queryMetadataMap.size;
|
|
454
|
-
|
|
480
|
+
logger3.debug("TWO_LAYER: Clearing all query results", {
|
|
455
481
|
queryCountBefore
|
|
456
482
|
});
|
|
457
483
|
if ("clearQueryResults" in this.underlyingCache && typeof this.underlyingCache.clearQueryResults === "function") {
|
|
@@ -459,7 +485,7 @@ var TwoLayerCacheMap = class _TwoLayerCacheMap extends CacheMap {
|
|
|
459
485
|
}
|
|
460
486
|
this.queryMetadataMap.clear();
|
|
461
487
|
const duration = Date.now() - startTime;
|
|
462
|
-
|
|
488
|
+
logger3.debug("TWO_LAYER: Cleared all query results", {
|
|
463
489
|
queriesCleared: queryCountBefore,
|
|
464
490
|
duration
|
|
465
491
|
});
|
|
@@ -578,7 +604,11 @@ var createQueryHash = (pkType, query, locations) => {
|
|
|
578
604
|
query: sortedQuery,
|
|
579
605
|
locations: normalizedLocations
|
|
580
606
|
};
|
|
581
|
-
|
|
607
|
+
const hash = deterministicStringify(hashInput);
|
|
608
|
+
if (!hash || typeof hash !== "string" || hash.trim() === "") {
|
|
609
|
+
throw new Error(`Invalid query hash generated: hash is empty or invalid. Input: ${JSON.stringify({ pkType, query, locations })}`);
|
|
610
|
+
}
|
|
611
|
+
return hash;
|
|
582
612
|
};
|
|
583
613
|
var createFinderHash = (finder, params, locations) => {
|
|
584
614
|
const normalizedParams = JSON.parse(JSON.stringify(params || {}));
|
|
@@ -595,7 +625,11 @@ var createFinderHash = (finder, params, locations) => {
|
|
|
595
625
|
params: sortedParams,
|
|
596
626
|
locations: normalizedLocations
|
|
597
627
|
};
|
|
598
|
-
|
|
628
|
+
const hash = deterministicStringify(hashInput);
|
|
629
|
+
if (!hash || typeof hash !== "string" || hash.trim() === "") {
|
|
630
|
+
throw new Error(`Invalid finder hash generated: hash is empty or invalid. Input: ${JSON.stringify({ finder, params, locations })}`);
|
|
631
|
+
}
|
|
632
|
+
return hash;
|
|
599
633
|
};
|
|
600
634
|
|
|
601
635
|
// src/events/CacheEventFactory.ts
|
|
@@ -790,7 +824,7 @@ var CacheEventFactory = class {
|
|
|
790
824
|
};
|
|
791
825
|
|
|
792
826
|
// src/ops/all.ts
|
|
793
|
-
var
|
|
827
|
+
var logger4 = logger_default.get("all");
|
|
794
828
|
var inFlightRequests = /* @__PURE__ */ new Map();
|
|
795
829
|
var CLEANUP_INTERVAL = 3e4;
|
|
796
830
|
var REQUEST_TIMEOUT = 25e3;
|
|
@@ -798,14 +832,14 @@ setInterval(() => {
|
|
|
798
832
|
const now = Date.now();
|
|
799
833
|
inFlightRequests.forEach((request, key) => {
|
|
800
834
|
if (now - request.timestamp > REQUEST_TIMEOUT) {
|
|
801
|
-
|
|
835
|
+
logger4.debug("Cleaning up stale in-flight all() request", { key });
|
|
802
836
|
inFlightRequests.delete(key);
|
|
803
837
|
}
|
|
804
838
|
});
|
|
805
839
|
}, CLEANUP_INTERVAL);
|
|
806
840
|
var all = async (query = {}, locations = [], context, allOptions) => {
|
|
807
841
|
const { coordinate } = context;
|
|
808
|
-
|
|
842
|
+
logger4.default("all", { query, locations, allOptions });
|
|
809
843
|
const wrappedAll = createAllWrapper(
|
|
810
844
|
coordinate,
|
|
811
845
|
async (q, locs, opts) => {
|
|
@@ -829,27 +863,27 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
829
863
|
}
|
|
830
864
|
});
|
|
831
865
|
if (context.options?.bypassCache) {
|
|
832
|
-
|
|
866
|
+
logger4.debug("Cache bypass enabled, fetching directly from API", { query, locations });
|
|
833
867
|
try {
|
|
834
868
|
const ret = await api.all(query, locations, allOptions);
|
|
835
|
-
|
|
869
|
+
logger4.debug("API response received (not cached due to bypass)", { query, locations, itemCount: ret.items.length });
|
|
836
870
|
return ret;
|
|
837
871
|
} catch (error) {
|
|
838
|
-
|
|
872
|
+
logger4.error("API request failed", { query, locations, error });
|
|
839
873
|
throw error;
|
|
840
874
|
}
|
|
841
875
|
}
|
|
842
876
|
const queryHash = createQueryHash(pkType, query, locations);
|
|
843
|
-
|
|
877
|
+
logger4.debug("QUERY_CACHE: Generated query hash for all()", {
|
|
844
878
|
queryHash,
|
|
845
879
|
query: JSON.stringify(query),
|
|
846
880
|
locations: JSON.stringify(locations),
|
|
847
881
|
pkType
|
|
848
882
|
});
|
|
849
|
-
|
|
883
|
+
logger4.debug("QUERY_CACHE: Checking query cache for hash", { queryHash });
|
|
850
884
|
const cachedItemKeys = await cacheMap.getQueryResult(queryHash);
|
|
851
885
|
if (cachedItemKeys) {
|
|
852
|
-
|
|
886
|
+
logger4.debug("QUERY_CACHE: Cache HIT - Found cached query result", {
|
|
853
887
|
queryHash,
|
|
854
888
|
cachedKeyCount: cachedItemKeys.length,
|
|
855
889
|
itemKeys: cachedItemKeys.map((k) => JSON.stringify(k))
|
|
@@ -861,14 +895,14 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
861
895
|
const item = await cacheMap.get(itemKey);
|
|
862
896
|
if (item) {
|
|
863
897
|
cachedItems.push(item);
|
|
864
|
-
|
|
898
|
+
logger4.debug("QUERY_CACHE: Retrieved cached item", {
|
|
865
899
|
itemKey: JSON.stringify(itemKey),
|
|
866
900
|
itemKeyStr: JSON.stringify(item.key)
|
|
867
901
|
});
|
|
868
902
|
} else {
|
|
869
903
|
allItemsAvailable = false;
|
|
870
904
|
missingKeys.push(itemKey);
|
|
871
|
-
|
|
905
|
+
logger4.debug("QUERY_CACHE: Cached item MISSING from item cache", {
|
|
872
906
|
itemKey: JSON.stringify(itemKey),
|
|
873
907
|
queryHash
|
|
874
908
|
});
|
|
@@ -876,13 +910,13 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
876
910
|
}
|
|
877
911
|
}
|
|
878
912
|
if (allItemsAvailable) {
|
|
879
|
-
|
|
913
|
+
logger4.debug("QUERY_CACHE: All cached items available, returning from cache", {
|
|
880
914
|
queryHash,
|
|
881
915
|
itemCount: cachedItems.length
|
|
882
916
|
});
|
|
883
917
|
return createCachedResult(cachedItems);
|
|
884
918
|
} else {
|
|
885
|
-
|
|
919
|
+
logger4.debug("QUERY_CACHE: Some cached items missing, invalidating query cache", {
|
|
886
920
|
queryHash,
|
|
887
921
|
missingKeys: missingKeys.map((k) => JSON.stringify(k)),
|
|
888
922
|
foundCount: cachedItems.length,
|
|
@@ -891,11 +925,11 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
891
925
|
cacheMap.deleteQueryResult(queryHash);
|
|
892
926
|
}
|
|
893
927
|
} else {
|
|
894
|
-
|
|
928
|
+
logger4.debug("QUERY_CACHE: Cache MISS - No cached query result found", { queryHash });
|
|
895
929
|
}
|
|
896
930
|
const isEmptyQuery = Object.keys(query).length === 0 || (Object.keys(query).length === 1 && "limit" in query || "offset" in query);
|
|
897
931
|
if (!isEmptyQuery) {
|
|
898
|
-
|
|
932
|
+
logger4.debug("QUERY_CACHE: Attempting direct cache query using queryIn() for filtered query", {
|
|
899
933
|
queryHash,
|
|
900
934
|
query: JSON.stringify(query),
|
|
901
935
|
locations: JSON.stringify(locations)
|
|
@@ -903,35 +937,35 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
903
937
|
try {
|
|
904
938
|
const directCachedItems = await cacheMap.queryIn(query, locations);
|
|
905
939
|
if (directCachedItems && directCachedItems.length > 0) {
|
|
906
|
-
|
|
940
|
+
logger4.debug("QUERY_CACHE: Direct cache query SUCCESS - Found items in item cache", {
|
|
907
941
|
queryHash,
|
|
908
942
|
itemCount: directCachedItems.length,
|
|
909
943
|
itemKeys: directCachedItems.map((item) => JSON.stringify(item.key))
|
|
910
944
|
});
|
|
911
945
|
const itemKeys = directCachedItems.map((item) => item.key);
|
|
912
946
|
await cacheMap.setQueryResult(queryHash, itemKeys);
|
|
913
|
-
|
|
947
|
+
logger4.debug("QUERY_CACHE: Stored query result from direct cache hit", {
|
|
914
948
|
queryHash,
|
|
915
949
|
itemKeyCount: itemKeys.length,
|
|
916
950
|
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
917
951
|
});
|
|
918
952
|
return createCachedResult(directCachedItems);
|
|
919
953
|
} else {
|
|
920
|
-
|
|
954
|
+
logger4.debug("QUERY_CACHE: Direct cache query returned no items", { queryHash });
|
|
921
955
|
}
|
|
922
956
|
} catch (error) {
|
|
923
|
-
|
|
957
|
+
logger4.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
|
|
924
958
|
queryHash,
|
|
925
959
|
error: error instanceof Error ? error.message : String(error)
|
|
926
960
|
});
|
|
927
961
|
}
|
|
928
962
|
} else {
|
|
929
|
-
|
|
963
|
+
logger4.debug("QUERY_CACHE: Skipping direct cache query for empty/all query - cannot trust completeness", {
|
|
930
964
|
queryHash,
|
|
931
965
|
query: JSON.stringify(query)
|
|
932
966
|
});
|
|
933
967
|
}
|
|
934
|
-
|
|
968
|
+
logger4.debug("QUERY_CACHE: Fetching from API (cache miss or invalid)", {
|
|
935
969
|
queryHash,
|
|
936
970
|
query: JSON.stringify(query),
|
|
937
971
|
locations: JSON.stringify(locations)
|
|
@@ -939,7 +973,7 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
939
973
|
const timestamp = Date.now();
|
|
940
974
|
const existingRequest = inFlightRequests.get(queryHash);
|
|
941
975
|
if (existingRequest && timestamp - existingRequest.timestamp < REQUEST_TIMEOUT) {
|
|
942
|
-
|
|
976
|
+
logger4.debug("QUERY_CACHE: Using existing in-flight all() request", {
|
|
943
977
|
queryHash,
|
|
944
978
|
age: timestamp - existingRequest.timestamp
|
|
945
979
|
});
|
|
@@ -952,19 +986,19 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
952
986
|
const cleanup = () => inFlightRequests.delete(queryHash);
|
|
953
987
|
apiRequest.then(cleanup, cleanup);
|
|
954
988
|
apiResult = await apiRequest;
|
|
955
|
-
|
|
989
|
+
logger4.debug("QUERY_CACHE: API response received", {
|
|
956
990
|
queryHash,
|
|
957
991
|
itemCount: apiResult.items.length,
|
|
958
992
|
total: apiResult.metadata?.total,
|
|
959
993
|
itemKeys: apiResult.items.map((item) => JSON.stringify(item.key))
|
|
960
994
|
});
|
|
961
|
-
|
|
995
|
+
logger4.debug("QUERY_CACHE: Storing items in item cache", {
|
|
962
996
|
queryHash,
|
|
963
997
|
itemCount: apiResult.items.length
|
|
964
998
|
});
|
|
965
999
|
for (const v of apiResult.items) {
|
|
966
1000
|
await cacheMap.set(v.key, v);
|
|
967
|
-
|
|
1001
|
+
logger4.debug("QUERY_CACHE: Stored item in cache", {
|
|
968
1002
|
itemKey: JSON.stringify(v.key),
|
|
969
1003
|
queryHash
|
|
970
1004
|
});
|
|
@@ -974,7 +1008,7 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
974
1008
|
for (const evictedKey of evictedKeys) {
|
|
975
1009
|
const parsedKey = JSON.parse(evictedKey);
|
|
976
1010
|
await cacheMap.delete(parsedKey);
|
|
977
|
-
|
|
1011
|
+
logger4.debug("QUERY_CACHE: Evicted item due to cache limits", {
|
|
978
1012
|
evictedKey,
|
|
979
1013
|
queryHash
|
|
980
1014
|
});
|
|
@@ -982,29 +1016,29 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
982
1016
|
}
|
|
983
1017
|
const itemKeys = apiResult.items.map((item) => item.key);
|
|
984
1018
|
await cacheMap.setQueryResult(queryHash, itemKeys);
|
|
985
|
-
|
|
1019
|
+
logger4.debug("QUERY_CACHE: Stored query result in query cache", {
|
|
986
1020
|
queryHash,
|
|
987
1021
|
itemKeyCount: itemKeys.length,
|
|
988
1022
|
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
989
1023
|
});
|
|
990
1024
|
const event = CacheEventFactory.createQueryEvent(query, locations, apiResult.items);
|
|
991
1025
|
context.eventEmitter.emit(event);
|
|
992
|
-
|
|
1026
|
+
logger4.debug("QUERY_CACHE: Emitted query event", { queryHash });
|
|
993
1027
|
} catch (e) {
|
|
994
1028
|
inFlightRequests.delete(queryHash);
|
|
995
1029
|
if (e instanceof NotFoundError) {
|
|
996
|
-
|
|
1030
|
+
logger4.debug("QUERY_CACHE: API returned NotFoundError, caching empty result", { queryHash });
|
|
997
1031
|
await cacheMap.setQueryResult(queryHash, []);
|
|
998
|
-
|
|
1032
|
+
logger4.debug("QUERY_CACHE: Cached empty query result for not found", { queryHash });
|
|
999
1033
|
} else {
|
|
1000
|
-
|
|
1034
|
+
logger4.debug("QUERY_CACHE: API error occurred", {
|
|
1001
1035
|
queryHash,
|
|
1002
1036
|
error: e instanceof Error ? e.message : String(e)
|
|
1003
1037
|
});
|
|
1004
1038
|
throw e;
|
|
1005
1039
|
}
|
|
1006
1040
|
}
|
|
1007
|
-
|
|
1041
|
+
logger4.debug("QUERY_CACHE: all() operation completed", {
|
|
1008
1042
|
queryHash,
|
|
1009
1043
|
resultCount: apiResult.items.length,
|
|
1010
1044
|
total: apiResult.metadata?.total
|
|
@@ -1179,10 +1213,10 @@ function validateSizeConfig(config) {
|
|
|
1179
1213
|
}
|
|
1180
1214
|
|
|
1181
1215
|
// src/ops/one.ts
|
|
1182
|
-
var
|
|
1216
|
+
var logger5 = logger_default.get("one");
|
|
1183
1217
|
var one = async (query = {}, locations = [], context) => {
|
|
1184
1218
|
const { api, cacheMap, pkType, ttlManager, coordinate } = context;
|
|
1185
|
-
|
|
1219
|
+
logger5.default("one", { query, locations });
|
|
1186
1220
|
const wrappedOne = createOneWrapper(
|
|
1187
1221
|
coordinate,
|
|
1188
1222
|
async (q, locs) => {
|
|
@@ -1195,64 +1229,64 @@ var one = async (query = {}, locations = [], context) => {
|
|
|
1195
1229
|
async function executeOneLogic(query, locations, context) {
|
|
1196
1230
|
const { api, cacheMap, pkType, ttlManager } = context;
|
|
1197
1231
|
if (context.options?.bypassCache) {
|
|
1198
|
-
|
|
1232
|
+
logger5.debug("Cache bypass enabled, fetching directly from API", { query, locations });
|
|
1199
1233
|
try {
|
|
1200
1234
|
const retItem2 = await api.one(query, locations);
|
|
1201
1235
|
if (retItem2) {
|
|
1202
|
-
|
|
1236
|
+
logger5.debug("API response received (not cached due to bypass)", { query, locations });
|
|
1203
1237
|
return retItem2;
|
|
1204
1238
|
} else {
|
|
1205
|
-
|
|
1239
|
+
logger5.debug("API returned null", { query, locations });
|
|
1206
1240
|
return null;
|
|
1207
1241
|
}
|
|
1208
1242
|
} catch (error) {
|
|
1209
|
-
|
|
1243
|
+
logger5.error("API request failed", { query, locations, error });
|
|
1210
1244
|
throw error;
|
|
1211
1245
|
}
|
|
1212
1246
|
}
|
|
1213
1247
|
const queryHash = createQueryHash(pkType, query, locations);
|
|
1214
|
-
|
|
1248
|
+
logger5.debug("QUERY_CACHE: Generated query hash for one()", {
|
|
1215
1249
|
queryHash,
|
|
1216
1250
|
query: JSON.stringify(query),
|
|
1217
1251
|
locations: JSON.stringify(locations),
|
|
1218
1252
|
pkType
|
|
1219
1253
|
});
|
|
1220
|
-
|
|
1254
|
+
logger5.debug("QUERY_CACHE: Checking query cache for hash", { queryHash });
|
|
1221
1255
|
const cachedItemKeys = await cacheMap.getQueryResult(queryHash);
|
|
1222
1256
|
if (cachedItemKeys) {
|
|
1223
|
-
|
|
1257
|
+
logger5.debug("QUERY_CACHE: Cache HIT - Found cached query result", {
|
|
1224
1258
|
queryHash,
|
|
1225
1259
|
cachedKeyCount: cachedItemKeys.length,
|
|
1226
1260
|
itemKeys: cachedItemKeys.map((k) => JSON.stringify(k))
|
|
1227
1261
|
});
|
|
1228
1262
|
if (cachedItemKeys.length === 0) {
|
|
1229
|
-
|
|
1263
|
+
logger5.debug("QUERY_CACHE: Cached empty result (not found)", { queryHash });
|
|
1230
1264
|
return null;
|
|
1231
1265
|
}
|
|
1232
1266
|
const itemKey = cachedItemKeys[0];
|
|
1233
|
-
|
|
1267
|
+
logger5.debug("QUERY_CACHE: Retrieving first cached item", {
|
|
1234
1268
|
queryHash,
|
|
1235
1269
|
itemKey: JSON.stringify(itemKey)
|
|
1236
1270
|
});
|
|
1237
1271
|
const item = await cacheMap.get(itemKey);
|
|
1238
1272
|
if (item) {
|
|
1239
|
-
|
|
1273
|
+
logger5.debug("QUERY_CACHE: Retrieved cached item successfully", {
|
|
1240
1274
|
queryHash,
|
|
1241
1275
|
itemKey: JSON.stringify(itemKey),
|
|
1242
1276
|
itemKeyStr: JSON.stringify(item.key)
|
|
1243
1277
|
});
|
|
1244
1278
|
return item;
|
|
1245
1279
|
} else {
|
|
1246
|
-
|
|
1280
|
+
logger5.debug("QUERY_CACHE: Cached item MISSING from item cache, invalidating query cache", {
|
|
1247
1281
|
queryHash,
|
|
1248
1282
|
itemKey: JSON.stringify(itemKey)
|
|
1249
1283
|
});
|
|
1250
1284
|
cacheMap.deleteQueryResult(queryHash);
|
|
1251
1285
|
}
|
|
1252
1286
|
} else {
|
|
1253
|
-
|
|
1287
|
+
logger5.debug("QUERY_CACHE: Cache MISS - No cached query result found", { queryHash });
|
|
1254
1288
|
}
|
|
1255
|
-
|
|
1289
|
+
logger5.debug("QUERY_CACHE: Attempting direct cache query using queryIn()", {
|
|
1256
1290
|
queryHash,
|
|
1257
1291
|
query: JSON.stringify(query),
|
|
1258
1292
|
locations: JSON.stringify(locations)
|
|
@@ -1260,28 +1294,28 @@ async function executeOneLogic(query, locations, context) {
|
|
|
1260
1294
|
try {
|
|
1261
1295
|
const directCachedItems = await cacheMap.queryIn(query, locations);
|
|
1262
1296
|
if (directCachedItems && directCachedItems.length > 0) {
|
|
1263
|
-
|
|
1297
|
+
logger5.debug("QUERY_CACHE: Direct cache query SUCCESS - Found item in item cache", {
|
|
1264
1298
|
queryHash,
|
|
1265
1299
|
itemCount: directCachedItems.length,
|
|
1266
1300
|
itemKeys: directCachedItems.map((item) => JSON.stringify(item.key))
|
|
1267
1301
|
});
|
|
1268
1302
|
const foundItem = directCachedItems[0];
|
|
1269
1303
|
await cacheMap.setQueryResult(queryHash, [foundItem.key]);
|
|
1270
|
-
|
|
1304
|
+
logger5.debug("QUERY_CACHE: Stored query result from direct cache hit", {
|
|
1271
1305
|
queryHash,
|
|
1272
1306
|
itemKey: JSON.stringify(foundItem.key)
|
|
1273
1307
|
});
|
|
1274
1308
|
return foundItem;
|
|
1275
1309
|
} else {
|
|
1276
|
-
|
|
1310
|
+
logger5.debug("QUERY_CACHE: Direct cache query returned no items", { queryHash });
|
|
1277
1311
|
}
|
|
1278
1312
|
} catch (error) {
|
|
1279
|
-
|
|
1313
|
+
logger5.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
|
|
1280
1314
|
queryHash,
|
|
1281
1315
|
error: error instanceof Error ? error.message : String(error)
|
|
1282
1316
|
});
|
|
1283
1317
|
}
|
|
1284
|
-
|
|
1318
|
+
logger5.debug("QUERY_CACHE: Fetching from API (cache miss or invalid)", {
|
|
1285
1319
|
queryHash,
|
|
1286
1320
|
query: JSON.stringify(query),
|
|
1287
1321
|
locations: JSON.stringify(locations)
|
|
@@ -1290,11 +1324,11 @@ async function executeOneLogic(query, locations, context) {
|
|
|
1290
1324
|
try {
|
|
1291
1325
|
retItem = await api.one(query, locations);
|
|
1292
1326
|
if (retItem) {
|
|
1293
|
-
|
|
1327
|
+
logger5.debug("QUERY_CACHE: API response received", {
|
|
1294
1328
|
queryHash,
|
|
1295
1329
|
itemKey: JSON.stringify(retItem.key)
|
|
1296
1330
|
});
|
|
1297
|
-
|
|
1331
|
+
logger5.debug("QUERY_CACHE: Storing item in item cache", {
|
|
1298
1332
|
queryHash,
|
|
1299
1333
|
itemKey: JSON.stringify(retItem.key)
|
|
1300
1334
|
});
|
|
@@ -1317,35 +1351,35 @@ async function executeOneLogic(query, locations, context) {
|
|
|
1317
1351
|
for (const evictedKey of evictedKeys) {
|
|
1318
1352
|
const parsedKey = JSON.parse(evictedKey);
|
|
1319
1353
|
await cacheMap.delete(parsedKey);
|
|
1320
|
-
|
|
1354
|
+
logger5.debug("QUERY_CACHE: Evicted item due to cache limits", {
|
|
1321
1355
|
evictedKey,
|
|
1322
1356
|
queryHash
|
|
1323
1357
|
});
|
|
1324
1358
|
}
|
|
1325
1359
|
await cacheMap.setQueryResult(queryHash, [retItem.key]);
|
|
1326
|
-
|
|
1360
|
+
logger5.debug("QUERY_CACHE: Stored query result in query cache", {
|
|
1327
1361
|
queryHash,
|
|
1328
1362
|
itemKey: JSON.stringify(retItem.key)
|
|
1329
1363
|
});
|
|
1330
1364
|
} else {
|
|
1331
|
-
|
|
1365
|
+
logger5.debug("QUERY_CACHE: API returned null, caching empty result", { queryHash });
|
|
1332
1366
|
await cacheMap.setQueryResult(queryHash, []);
|
|
1333
|
-
|
|
1367
|
+
logger5.debug("QUERY_CACHE: Cached empty query result", { queryHash });
|
|
1334
1368
|
}
|
|
1335
1369
|
} catch (e) {
|
|
1336
1370
|
if (e instanceof NotFoundError2) {
|
|
1337
|
-
|
|
1371
|
+
logger5.debug("QUERY_CACHE: API returned NotFoundError, caching empty result", { queryHash });
|
|
1338
1372
|
await cacheMap.setQueryResult(queryHash, []);
|
|
1339
|
-
|
|
1373
|
+
logger5.debug("QUERY_CACHE: Cached empty query result for not found", { queryHash });
|
|
1340
1374
|
} else {
|
|
1341
|
-
|
|
1375
|
+
logger5.debug("QUERY_CACHE: API error occurred", {
|
|
1342
1376
|
queryHash,
|
|
1343
1377
|
error: e instanceof Error ? e.message : String(e)
|
|
1344
1378
|
});
|
|
1345
1379
|
throw e;
|
|
1346
1380
|
}
|
|
1347
1381
|
}
|
|
1348
|
-
|
|
1382
|
+
logger5.debug("QUERY_CACHE: one() operation completed", {
|
|
1349
1383
|
queryHash,
|
|
1350
1384
|
result: retItem ? JSON.stringify(retItem.key) : null
|
|
1351
1385
|
});
|
|
@@ -1356,10 +1390,10 @@ async function executeOneLogic(query, locations, context) {
|
|
|
1356
1390
|
import {
|
|
1357
1391
|
createCreateWrapper
|
|
1358
1392
|
} from "@fjell/core";
|
|
1359
|
-
var
|
|
1393
|
+
var logger6 = logger_default.get("create");
|
|
1360
1394
|
var create = async (v, locations = [], context) => {
|
|
1361
1395
|
const { coordinate } = context;
|
|
1362
|
-
|
|
1396
|
+
logger6.default("create", { v, locations });
|
|
1363
1397
|
const wrappedCreate = createCreateWrapper(
|
|
1364
1398
|
coordinate,
|
|
1365
1399
|
async (item, createOptions2) => {
|
|
@@ -1399,7 +1433,7 @@ import {
|
|
|
1399
1433
|
createGetWrapper,
|
|
1400
1434
|
isValidItemKey
|
|
1401
1435
|
} from "@fjell/core";
|
|
1402
|
-
var
|
|
1436
|
+
var logger7 = logger_default.get("get");
|
|
1403
1437
|
var inFlightRequests2 = /* @__PURE__ */ new Map();
|
|
1404
1438
|
var CLEANUP_TIMEOUT = 5 * 60 * 1e3;
|
|
1405
1439
|
var cleanupStaleRequests = () => {
|
|
@@ -1411,7 +1445,7 @@ var cleanupStaleRequests = () => {
|
|
|
1411
1445
|
}
|
|
1412
1446
|
});
|
|
1413
1447
|
keysToDelete.forEach((key) => {
|
|
1414
|
-
|
|
1448
|
+
logger7.debug("Cleaning up stale in-flight request", { key });
|
|
1415
1449
|
inFlightRequests2.delete(key);
|
|
1416
1450
|
});
|
|
1417
1451
|
};
|
|
@@ -1419,7 +1453,7 @@ var cleanupInterval = setInterval(cleanupStaleRequests, 60 * 1e3);
|
|
|
1419
1453
|
var keyToString = createNormalizedHashFunction();
|
|
1420
1454
|
var get = async (key, context) => {
|
|
1421
1455
|
const { api, cacheMap, pkType, ttlManager, statsManager, coordinate } = context;
|
|
1422
|
-
|
|
1456
|
+
logger7.default("get", { key, defaultTTL: ttlManager.getDefaultTTL() });
|
|
1423
1457
|
const wrappedGet = createGetWrapper(
|
|
1424
1458
|
coordinate,
|
|
1425
1459
|
async (k) => {
|
|
@@ -1433,7 +1467,7 @@ async function executeGetLogic(key, context) {
|
|
|
1433
1467
|
const startTime = Date.now();
|
|
1434
1468
|
const { api, cacheMap, pkType, ttlManager, statsManager } = context;
|
|
1435
1469
|
const keyStr = JSON.stringify(key);
|
|
1436
|
-
|
|
1470
|
+
logger7.debug("CACHE_OP: get() started", {
|
|
1437
1471
|
key: keyStr,
|
|
1438
1472
|
ttlEnabled: ttlManager.isTTLEnabled(),
|
|
1439
1473
|
defaultTTL: ttlManager.getDefaultTTL(),
|
|
@@ -1441,32 +1475,32 @@ async function executeGetLogic(key, context) {
|
|
|
1441
1475
|
});
|
|
1442
1476
|
statsManager.incrementRequests();
|
|
1443
1477
|
if (!isValidItemKey(key)) {
|
|
1444
|
-
|
|
1478
|
+
logger7.error("CACHE_OP: Invalid key for get", { key: keyStr });
|
|
1445
1479
|
throw new Error("Key for Get is not a valid ItemKey");
|
|
1446
1480
|
}
|
|
1447
1481
|
if (context.options?.bypassCache) {
|
|
1448
|
-
|
|
1482
|
+
logger7.debug("CACHE_OP: Cache bypass enabled, fetching directly from API", { key: keyStr });
|
|
1449
1483
|
statsManager.incrementMisses();
|
|
1450
1484
|
try {
|
|
1451
1485
|
const apiStartTime = Date.now();
|
|
1452
1486
|
const ret2 = await api.get(key);
|
|
1453
1487
|
const apiDuration = Date.now() - apiStartTime;
|
|
1454
1488
|
if (ret2) {
|
|
1455
|
-
|
|
1489
|
+
logger7.debug("CACHE_OP: API response received (bypass mode, not cached)", {
|
|
1456
1490
|
key: keyStr,
|
|
1457
1491
|
apiDuration,
|
|
1458
1492
|
totalDuration: Date.now() - startTime
|
|
1459
1493
|
});
|
|
1460
1494
|
return ret2;
|
|
1461
1495
|
} else {
|
|
1462
|
-
|
|
1496
|
+
logger7.debug("CACHE_OP: API returned null (bypass mode)", {
|
|
1463
1497
|
key: keyStr,
|
|
1464
1498
|
apiDuration
|
|
1465
1499
|
});
|
|
1466
1500
|
return null;
|
|
1467
1501
|
}
|
|
1468
1502
|
} catch (error) {
|
|
1469
|
-
|
|
1503
|
+
logger7.error("CACHE_OP: API request failed in bypass mode", {
|
|
1470
1504
|
key: keyStr,
|
|
1471
1505
|
duration: Date.now() - startTime,
|
|
1472
1506
|
error
|
|
@@ -1479,7 +1513,7 @@ async function executeGetLogic(key, context) {
|
|
|
1479
1513
|
const cachedItem = await cacheMap.get(key);
|
|
1480
1514
|
const cacheCheckDuration = Date.now() - cacheCheckStart;
|
|
1481
1515
|
if (cachedItem) {
|
|
1482
|
-
|
|
1516
|
+
logger7.debug("CACHE_OP: Item found in cache, checking TTL validity", {
|
|
1483
1517
|
key: keyStr,
|
|
1484
1518
|
cacheCheckDuration,
|
|
1485
1519
|
defaultTTL: ttlManager.getDefaultTTL()
|
|
@@ -1489,7 +1523,7 @@ async function executeGetLogic(key, context) {
|
|
|
1489
1523
|
const ttlCheckDuration = Date.now() - ttlCheckStart;
|
|
1490
1524
|
if (isValid) {
|
|
1491
1525
|
const totalDuration = Date.now() - startTime;
|
|
1492
|
-
|
|
1526
|
+
logger7.debug("CACHE_OP: Cache HIT with valid TTL", {
|
|
1493
1527
|
key: keyStr,
|
|
1494
1528
|
cacheCheckDuration,
|
|
1495
1529
|
ttlCheckDuration,
|
|
@@ -1499,7 +1533,7 @@ async function executeGetLogic(key, context) {
|
|
|
1499
1533
|
statsManager.incrementHits();
|
|
1500
1534
|
return cachedItem;
|
|
1501
1535
|
} else {
|
|
1502
|
-
|
|
1536
|
+
logger7.debug("CACHE_OP: Cache item EXPIRED, removing from cache", {
|
|
1503
1537
|
key: keyStr,
|
|
1504
1538
|
cacheCheckDuration,
|
|
1505
1539
|
ttlCheckDuration
|
|
@@ -1508,13 +1542,13 @@ async function executeGetLogic(key, context) {
|
|
|
1508
1542
|
statsManager.incrementMisses();
|
|
1509
1543
|
}
|
|
1510
1544
|
} else {
|
|
1511
|
-
|
|
1545
|
+
logger7.debug("CACHE_OP: Cache MISS (no item found)", {
|
|
1512
1546
|
key: keyStr,
|
|
1513
1547
|
cacheCheckDuration
|
|
1514
1548
|
});
|
|
1515
1549
|
statsManager.incrementMisses();
|
|
1516
1550
|
}
|
|
1517
|
-
|
|
1551
|
+
logger7.debug("CACHE_OP: Proceeding to API fetch (TTL-enabled cache miss or expired)", {
|
|
1518
1552
|
key: keyStr,
|
|
1519
1553
|
defaultTTL: ttlManager.getDefaultTTL()
|
|
1520
1554
|
});
|
|
@@ -1524,7 +1558,7 @@ async function executeGetLogic(key, context) {
|
|
|
1524
1558
|
const cacheCheckDuration = Date.now() - cacheCheckStart;
|
|
1525
1559
|
if (cachedItem) {
|
|
1526
1560
|
const totalDuration = Date.now() - startTime;
|
|
1527
|
-
|
|
1561
|
+
logger7.debug("CACHE_OP: Cache HIT (TTL disabled)", {
|
|
1528
1562
|
key: keyStr,
|
|
1529
1563
|
cacheCheckDuration,
|
|
1530
1564
|
totalDuration
|
|
@@ -1532,7 +1566,7 @@ async function executeGetLogic(key, context) {
|
|
|
1532
1566
|
statsManager.incrementHits();
|
|
1533
1567
|
return cachedItem;
|
|
1534
1568
|
} else {
|
|
1535
|
-
|
|
1569
|
+
logger7.debug("CACHE_OP: Cache MISS (TTL disabled)", {
|
|
1536
1570
|
key: keyStr,
|
|
1537
1571
|
cacheCheckDuration
|
|
1538
1572
|
});
|
|
@@ -1546,7 +1580,7 @@ async function executeGetLogic(key, context) {
|
|
|
1546
1580
|
let apiRequest;
|
|
1547
1581
|
const apiStartTime = Date.now();
|
|
1548
1582
|
if (!requestEntry) {
|
|
1549
|
-
|
|
1583
|
+
logger7.debug("CACHE_OP: Creating new API request", { key: keyStr });
|
|
1550
1584
|
apiRequest = api.get(key);
|
|
1551
1585
|
if (apiRequest && typeof apiRequest.then === "function") {
|
|
1552
1586
|
const timestamp = Date.now();
|
|
@@ -1559,7 +1593,7 @@ async function executeGetLogic(key, context) {
|
|
|
1559
1593
|
}
|
|
1560
1594
|
}
|
|
1561
1595
|
} else {
|
|
1562
|
-
|
|
1596
|
+
logger7.debug("CACHE_OP: Using existing in-flight request", {
|
|
1563
1597
|
key: keyStr,
|
|
1564
1598
|
requestAge: Date.now() - requestEntry.timestamp
|
|
1565
1599
|
});
|
|
@@ -1568,7 +1602,7 @@ async function executeGetLogic(key, context) {
|
|
|
1568
1602
|
ret = await apiRequest;
|
|
1569
1603
|
const apiDuration = Date.now() - apiStartTime;
|
|
1570
1604
|
if (ret) {
|
|
1571
|
-
|
|
1605
|
+
logger7.debug("CACHE_OP: API request successful, caching result", {
|
|
1572
1606
|
key: keyStr,
|
|
1573
1607
|
apiDuration,
|
|
1574
1608
|
itemKeyMatches: JSON.stringify(ret.key) === keyStr
|
|
@@ -1590,7 +1624,7 @@ async function executeGetLogic(key, context) {
|
|
|
1590
1624
|
estimatedSize
|
|
1591
1625
|
};
|
|
1592
1626
|
await cacheMap.setMetadata(itemKeyStr, baseMetadata);
|
|
1593
|
-
|
|
1627
|
+
logger7.debug("CACHE_OP: Created base metadata for cached item", {
|
|
1594
1628
|
key: itemKeyStr,
|
|
1595
1629
|
estimatedSize
|
|
1596
1630
|
});
|
|
@@ -1600,7 +1634,7 @@ async function executeGetLogic(key, context) {
|
|
|
1600
1634
|
const evictedKeys = await context.evictionManager.onItemAdded(itemKeyStr, ret, cacheMap);
|
|
1601
1635
|
const evictionDuration = Date.now() - evictionStart;
|
|
1602
1636
|
if (evictedKeys.length > 0) {
|
|
1603
|
-
|
|
1637
|
+
logger7.debug("CACHE_OP: Eviction triggered by new item", {
|
|
1604
1638
|
key: itemKeyStr,
|
|
1605
1639
|
evictedCount: evictedKeys.length,
|
|
1606
1640
|
evictedKeys
|
|
@@ -1612,12 +1646,12 @@ async function executeGetLogic(key, context) {
|
|
|
1612
1646
|
for (const evictedKey of evictedKeys) {
|
|
1613
1647
|
const parsedKey = JSON.parse(evictedKey);
|
|
1614
1648
|
await cacheMap.delete(parsedKey);
|
|
1615
|
-
|
|
1649
|
+
logger7.debug("CACHE_OP: Removed evicted item", { evictedKey });
|
|
1616
1650
|
}
|
|
1617
1651
|
const event = CacheEventFactory.itemRetrieved(ret.key, ret, "api");
|
|
1618
1652
|
context.eventEmitter.emit(event);
|
|
1619
1653
|
const totalDuration = Date.now() - startTime;
|
|
1620
|
-
|
|
1654
|
+
logger7.debug("CACHE_OP: get() completed successfully (cache miss)", {
|
|
1621
1655
|
key: keyStr,
|
|
1622
1656
|
apiDuration,
|
|
1623
1657
|
cacheSetDuration,
|
|
@@ -1628,7 +1662,7 @@ async function executeGetLogic(key, context) {
|
|
|
1628
1662
|
evictedCount: evictedKeys.length
|
|
1629
1663
|
});
|
|
1630
1664
|
} else {
|
|
1631
|
-
|
|
1665
|
+
logger7.debug("CACHE_OP: API returned null", {
|
|
1632
1666
|
key: keyStr,
|
|
1633
1667
|
apiDuration,
|
|
1634
1668
|
totalDuration: Date.now() - startTime
|
|
@@ -1637,7 +1671,7 @@ async function executeGetLogic(key, context) {
|
|
|
1637
1671
|
} catch (e) {
|
|
1638
1672
|
inFlightRequests2.delete(requestKeyStr);
|
|
1639
1673
|
const duration = Date.now() - startTime;
|
|
1640
|
-
|
|
1674
|
+
logger7.error("CACHE_OP: Error in get() operation", {
|
|
1641
1675
|
key: keyStr,
|
|
1642
1676
|
duration,
|
|
1643
1677
|
message: e.message,
|
|
@@ -1652,24 +1686,24 @@ async function executeGetLogic(key, context) {
|
|
|
1652
1686
|
import {
|
|
1653
1687
|
isValidItemKey as isValidItemKey2
|
|
1654
1688
|
} from "@fjell/core";
|
|
1655
|
-
var
|
|
1689
|
+
var logger8 = logger_default.get("retrieve");
|
|
1656
1690
|
var retrieve = async (key, context) => {
|
|
1657
1691
|
const startTime = Date.now();
|
|
1658
1692
|
const { cacheMap, pkType, statsManager } = context;
|
|
1659
1693
|
const keyStr = JSON.stringify(key);
|
|
1660
|
-
|
|
1661
|
-
|
|
1694
|
+
logger8.default("retrieve", { key });
|
|
1695
|
+
logger8.debug("CACHE_OP: retrieve() started", {
|
|
1662
1696
|
key: keyStr,
|
|
1663
1697
|
cacheType: cacheMap.implementationType,
|
|
1664
1698
|
bypassEnabled: !!context.options?.bypassCache
|
|
1665
1699
|
});
|
|
1666
1700
|
statsManager.incrementRequests();
|
|
1667
1701
|
if (!isValidItemKey2(key)) {
|
|
1668
|
-
|
|
1702
|
+
logger8.error("CACHE_OP: Invalid key for retrieve", { key: keyStr });
|
|
1669
1703
|
throw new Error("Key for Retrieve is not a valid ItemKey");
|
|
1670
1704
|
}
|
|
1671
1705
|
if (context.options?.bypassCache) {
|
|
1672
|
-
|
|
1706
|
+
logger8.debug("CACHE_OP: Cache bypass enabled, fetching directly from API", { key: keyStr });
|
|
1673
1707
|
statsManager.incrementMisses();
|
|
1674
1708
|
try {
|
|
1675
1709
|
const apiStartTime = Date.now();
|
|
@@ -1677,14 +1711,14 @@ var retrieve = async (key, context) => {
|
|
|
1677
1711
|
const retrieved2 = await api.get(key);
|
|
1678
1712
|
const apiDuration = Date.now() - apiStartTime;
|
|
1679
1713
|
if (retrieved2) {
|
|
1680
|
-
|
|
1714
|
+
logger8.debug("CACHE_OP: API response received (bypass mode)", {
|
|
1681
1715
|
key: keyStr,
|
|
1682
1716
|
apiDuration,
|
|
1683
1717
|
hasValue: true
|
|
1684
1718
|
});
|
|
1685
1719
|
return [null, retrieved2];
|
|
1686
1720
|
} else {
|
|
1687
|
-
|
|
1721
|
+
logger8.debug("CACHE_OP: API returned null (bypass mode)", {
|
|
1688
1722
|
key: keyStr,
|
|
1689
1723
|
apiDuration
|
|
1690
1724
|
});
|
|
@@ -1692,7 +1726,7 @@ var retrieve = async (key, context) => {
|
|
|
1692
1726
|
}
|
|
1693
1727
|
} catch (error) {
|
|
1694
1728
|
const duration = Date.now() - startTime;
|
|
1695
|
-
|
|
1729
|
+
logger8.error("CACHE_OP: API request failed in bypass mode", {
|
|
1696
1730
|
key: keyStr,
|
|
1697
1731
|
duration,
|
|
1698
1732
|
error
|
|
@@ -1701,36 +1735,36 @@ var retrieve = async (key, context) => {
|
|
|
1701
1735
|
}
|
|
1702
1736
|
}
|
|
1703
1737
|
const containsItemKey = await cacheMap.includesKey(key);
|
|
1704
|
-
|
|
1738
|
+
logger8.debug("CACHE_OP: Cache key check completed", {
|
|
1705
1739
|
key: keyStr,
|
|
1706
1740
|
exists: containsItemKey
|
|
1707
1741
|
});
|
|
1708
1742
|
let retrieved;
|
|
1709
1743
|
let contextToReturn;
|
|
1710
1744
|
if (containsItemKey) {
|
|
1711
|
-
|
|
1712
|
-
|
|
1745
|
+
logger8.default("Looking for Object in Cache", key);
|
|
1746
|
+
logger8.debug("CACHE_OP: Cache HIT - retrieving from cache", { key: keyStr });
|
|
1713
1747
|
const getStartTime = Date.now();
|
|
1714
1748
|
retrieved = await cacheMap.get(key);
|
|
1715
1749
|
const getDuration = Date.now() - getStartTime;
|
|
1716
1750
|
contextToReturn = null;
|
|
1717
1751
|
statsManager.incrementHits();
|
|
1718
1752
|
const totalDuration = Date.now() - startTime;
|
|
1719
|
-
|
|
1753
|
+
logger8.debug("CACHE_OP: retrieve() completed (cache hit)", {
|
|
1720
1754
|
key: keyStr,
|
|
1721
1755
|
getDuration,
|
|
1722
1756
|
totalDuration,
|
|
1723
1757
|
hasValue: !!retrieved
|
|
1724
1758
|
});
|
|
1725
1759
|
} else {
|
|
1726
|
-
|
|
1727
|
-
|
|
1760
|
+
logger8.default("Object Not Found in Cache, Retrieving from Server API", { key });
|
|
1761
|
+
logger8.debug("CACHE_OP: Cache MISS - fetching from API", { key: keyStr });
|
|
1728
1762
|
statsManager.incrementMisses();
|
|
1729
1763
|
const apiStartTime = Date.now();
|
|
1730
1764
|
[contextToReturn, retrieved] = await get(key, context);
|
|
1731
1765
|
const apiDuration = Date.now() - apiStartTime;
|
|
1732
1766
|
const totalDuration = Date.now() - startTime;
|
|
1733
|
-
|
|
1767
|
+
logger8.debug("CACHE_OP: retrieve() completed (cache miss)", {
|
|
1734
1768
|
key: keyStr,
|
|
1735
1769
|
apiDuration,
|
|
1736
1770
|
totalDuration,
|
|
@@ -1749,10 +1783,10 @@ import {
|
|
|
1749
1783
|
createRemoveWrapper,
|
|
1750
1784
|
isValidItemKey as isValidItemKey3
|
|
1751
1785
|
} from "@fjell/core";
|
|
1752
|
-
var
|
|
1786
|
+
var logger9 = logger_default.get("remove");
|
|
1753
1787
|
var remove = async (key, context) => {
|
|
1754
1788
|
const { coordinate } = context;
|
|
1755
|
-
|
|
1789
|
+
logger9.default("remove", { key });
|
|
1756
1790
|
const wrappedRemove = createRemoveWrapper(
|
|
1757
1791
|
coordinate,
|
|
1758
1792
|
async (k) => {
|
|
@@ -1765,7 +1799,7 @@ var remove = async (key, context) => {
|
|
|
1765
1799
|
async function executeRemoveLogic(key, context) {
|
|
1766
1800
|
const { api, cacheMap } = context;
|
|
1767
1801
|
if (!isValidItemKey3(key)) {
|
|
1768
|
-
|
|
1802
|
+
logger9.error("Key for Remove is not a valid ItemKey: %j", key);
|
|
1769
1803
|
throw new Error("Key for Remove is not a valid ItemKey");
|
|
1770
1804
|
}
|
|
1771
1805
|
try {
|
|
@@ -1783,9 +1817,9 @@ async function executeRemoveLogic(key, context) {
|
|
|
1783
1817
|
{ source: "operation", context: { operation: "remove" } }
|
|
1784
1818
|
);
|
|
1785
1819
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
1786
|
-
|
|
1820
|
+
logger9.debug("Successfully removed item from API and cache", { key });
|
|
1787
1821
|
} catch (e) {
|
|
1788
|
-
|
|
1822
|
+
logger9.error("Error deleting item", { error: e });
|
|
1789
1823
|
throw e;
|
|
1790
1824
|
}
|
|
1791
1825
|
}
|
|
@@ -1795,10 +1829,10 @@ import {
|
|
|
1795
1829
|
createUpdateWrapper,
|
|
1796
1830
|
isValidItemKey as isValidItemKey4
|
|
1797
1831
|
} from "@fjell/core";
|
|
1798
|
-
var
|
|
1832
|
+
var logger10 = logger_default.get("update");
|
|
1799
1833
|
var update = async (key, v, context) => {
|
|
1800
1834
|
const { coordinate } = context;
|
|
1801
|
-
|
|
1835
|
+
logger10.default("update", { key, v });
|
|
1802
1836
|
const wrappedUpdate = createUpdateWrapper(
|
|
1803
1837
|
coordinate,
|
|
1804
1838
|
async (k, item) => {
|
|
@@ -1811,16 +1845,16 @@ var update = async (key, v, context) => {
|
|
|
1811
1845
|
async function executeUpdateLogic(key, v, context) {
|
|
1812
1846
|
const { api, cacheMap, pkType } = context;
|
|
1813
1847
|
if (!isValidItemKey4(key)) {
|
|
1814
|
-
|
|
1848
|
+
logger10.error("Key for Update is not a valid ItemKey: %j", key);
|
|
1815
1849
|
throw new Error("Key for Update is not a valid ItemKey");
|
|
1816
1850
|
}
|
|
1817
|
-
|
|
1851
|
+
logger10.debug("Invalidating item key before update", { key });
|
|
1818
1852
|
cacheMap.invalidateItemKeys([key]);
|
|
1819
1853
|
await cacheMap.clearQueryResults();
|
|
1820
1854
|
try {
|
|
1821
1855
|
const previousItem = await cacheMap.get(key);
|
|
1822
1856
|
const updated = await api.update(key, v);
|
|
1823
|
-
|
|
1857
|
+
logger10.debug("Caching update result", { updatedKey: updated.key });
|
|
1824
1858
|
await cacheMap.set(updated.key, updated);
|
|
1825
1859
|
const cachedItem = await cacheMap.get(updated.key);
|
|
1826
1860
|
const keyStr = JSON.stringify(updated.key);
|
|
@@ -1853,7 +1887,7 @@ async function executeUpdateLogic(key, v, context) {
|
|
|
1853
1887
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
1854
1888
|
return updated;
|
|
1855
1889
|
} catch (e) {
|
|
1856
|
-
|
|
1890
|
+
logger10.error("Error updating item", { error: e });
|
|
1857
1891
|
throw e;
|
|
1858
1892
|
}
|
|
1859
1893
|
}
|
|
@@ -1866,7 +1900,7 @@ import {
|
|
|
1866
1900
|
|
|
1867
1901
|
// src/utils/cacheInvalidation.ts
|
|
1868
1902
|
import { toKeyTypeArray } from "@fjell/core";
|
|
1869
|
-
var
|
|
1903
|
+
var logger11 = logger_default.get("cache", "utils", "cacheInvalidation");
|
|
1870
1904
|
var extractKeysAndKeyTypesFromActionResult = (affectedItems) => {
|
|
1871
1905
|
const keys = [];
|
|
1872
1906
|
const keyTypeArrays = [];
|
|
@@ -1883,7 +1917,7 @@ var extractKeysAndKeyTypesFromActionResult = (affectedItems) => {
|
|
|
1883
1917
|
return { keys, keyTypeArrays };
|
|
1884
1918
|
};
|
|
1885
1919
|
var invalidateCachesByKeysAndKeyTypes = async (registry, keys, keyTypeArrays) => {
|
|
1886
|
-
|
|
1920
|
+
logger11.debug("Invalidating caches by keys and key types", {
|
|
1887
1921
|
keysCount: keys.length,
|
|
1888
1922
|
keyTypeArrays
|
|
1889
1923
|
});
|
|
@@ -1901,22 +1935,22 @@ var invalidateCachesByKeysAndKeyTypes = async (registry, keys, keyTypeArrays) =>
|
|
|
1901
1935
|
try {
|
|
1902
1936
|
const cacheInstance = registry.get(keyTypes);
|
|
1903
1937
|
if (cacheInstance && isCache(cacheInstance)) {
|
|
1904
|
-
|
|
1938
|
+
logger11.debug("Found cache instance for targeted invalidation", {
|
|
1905
1939
|
keyTypes,
|
|
1906
1940
|
cacheType: cacheInstance.coordinate.kta,
|
|
1907
1941
|
keysToInvalidate: cacheKeys.length
|
|
1908
1942
|
});
|
|
1909
1943
|
await cacheInstance.cacheMap.invalidateItemKeys(cacheKeys);
|
|
1910
1944
|
await cacheInstance.cacheMap.clearQueryResults();
|
|
1911
|
-
|
|
1945
|
+
logger11.debug("Successfully invalidated specific items in cache", {
|
|
1912
1946
|
keyTypes,
|
|
1913
1947
|
invalidatedCount: cacheKeys.length
|
|
1914
1948
|
});
|
|
1915
1949
|
} else {
|
|
1916
|
-
|
|
1950
|
+
logger11.debug("No cache instance found for key types", { keyTypes });
|
|
1917
1951
|
}
|
|
1918
1952
|
} catch (error) {
|
|
1919
|
-
|
|
1953
|
+
logger11.warning("Failed to invalidate cache for key types", {
|
|
1920
1954
|
keyTypes,
|
|
1921
1955
|
error: error instanceof Error ? error.message : String(error)
|
|
1922
1956
|
});
|
|
@@ -1926,12 +1960,12 @@ var invalidateCachesByKeysAndKeyTypes = async (registry, keys, keyTypeArrays) =>
|
|
|
1926
1960
|
try {
|
|
1927
1961
|
const cacheInstance = registry.get(keyTypes);
|
|
1928
1962
|
if (cacheInstance && isCache(cacheInstance)) {
|
|
1929
|
-
|
|
1963
|
+
logger11.debug("Handling location-based invalidation", { keyTypes });
|
|
1930
1964
|
await cacheInstance.cacheMap.clearQueryResults();
|
|
1931
|
-
|
|
1965
|
+
logger11.debug("Successfully cleared query results for location", { keyTypes });
|
|
1932
1966
|
}
|
|
1933
1967
|
} catch (error) {
|
|
1934
|
-
|
|
1968
|
+
logger11.warning("Failed to handle location-based invalidation", {
|
|
1935
1969
|
keyTypes,
|
|
1936
1970
|
error: error instanceof Error ? error.message : String(error)
|
|
1937
1971
|
});
|
|
@@ -1942,7 +1976,7 @@ function isCache(instance) {
|
|
|
1942
1976
|
return instance !== null && typeof instance === "object" && "operations" in instance && "cacheMap" in instance && typeof instance.cacheMap.invalidateItemKeys === "function";
|
|
1943
1977
|
}
|
|
1944
1978
|
var handleActionCacheInvalidation = async (registry, affectedItems) => {
|
|
1945
|
-
|
|
1979
|
+
logger11.debug("Handling action cache invalidation", {
|
|
1946
1980
|
affectedItemsCount: affectedItems.length
|
|
1947
1981
|
});
|
|
1948
1982
|
const { keys, keyTypeArrays } = extractKeysAndKeyTypesFromActionResult(affectedItems);
|
|
@@ -1950,10 +1984,10 @@ var handleActionCacheInvalidation = async (registry, affectedItems) => {
|
|
|
1950
1984
|
};
|
|
1951
1985
|
|
|
1952
1986
|
// src/ops/action.ts
|
|
1953
|
-
var
|
|
1987
|
+
var logger12 = logger_default.get("action");
|
|
1954
1988
|
var action = async (key, action2, body = {}, context) => {
|
|
1955
1989
|
const { coordinate } = context;
|
|
1956
|
-
|
|
1990
|
+
logger12.default("action", { key, action: action2, body });
|
|
1957
1991
|
const wrappedAction = createActionWrapper(
|
|
1958
1992
|
coordinate,
|
|
1959
1993
|
async (k, a, b) => {
|
|
@@ -1966,28 +2000,28 @@ var action = async (key, action2, body = {}, context) => {
|
|
|
1966
2000
|
async function executeActionLogic(key, action2, body, context) {
|
|
1967
2001
|
const { api, cacheMap, pkType, registry } = context;
|
|
1968
2002
|
if (!isValidItemKey5(key)) {
|
|
1969
|
-
|
|
2003
|
+
logger12.error("Key for Action is not a valid ItemKey: %j", key);
|
|
1970
2004
|
throw new Error("Key for Action is not a valid ItemKey");
|
|
1971
2005
|
}
|
|
1972
|
-
|
|
2006
|
+
logger12.debug("Invalidating item key before action", { key });
|
|
1973
2007
|
cacheMap.invalidateItemKeys([key]);
|
|
1974
2008
|
const result = await api.action(key, action2, body);
|
|
1975
2009
|
const updated = result[0];
|
|
1976
2010
|
const affectedItems = result[1];
|
|
1977
2011
|
if (affectedItems && affectedItems.length > 0) {
|
|
1978
|
-
|
|
2012
|
+
logger12.debug("Handling cache invalidation for affected items", {
|
|
1979
2013
|
affectedItemsCount: affectedItems.length
|
|
1980
2014
|
});
|
|
1981
2015
|
try {
|
|
1982
2016
|
await handleActionCacheInvalidation(registry, affectedItems);
|
|
1983
2017
|
} catch (error) {
|
|
1984
|
-
|
|
2018
|
+
logger12.warning("Failed to handle cache invalidation for affected items", {
|
|
1985
2019
|
error: error instanceof Error ? error.message : String(error),
|
|
1986
2020
|
affectedItems
|
|
1987
2021
|
});
|
|
1988
2022
|
}
|
|
1989
2023
|
}
|
|
1990
|
-
|
|
2024
|
+
logger12.debug("Caching action result", { updatedKey: updated.key });
|
|
1991
2025
|
cacheMap.set(updated.key, updated);
|
|
1992
2026
|
const keyStr = JSON.stringify(updated.key);
|
|
1993
2027
|
context.ttlManager.onItemAdded(keyStr, cacheMap);
|
|
@@ -1997,19 +2031,19 @@ async function executeActionLogic(key, action2, body, context) {
|
|
|
1997
2031
|
const parsedKey = JSON.parse(evictedKey);
|
|
1998
2032
|
await cacheMap.delete(parsedKey);
|
|
1999
2033
|
} catch (error) {
|
|
2000
|
-
|
|
2034
|
+
logger12.error("Failed to parse evicted key during deletion", {
|
|
2001
2035
|
evictedKey,
|
|
2002
2036
|
error: error instanceof Error ? error.message : String(error)
|
|
2003
2037
|
});
|
|
2004
2038
|
}
|
|
2005
2039
|
}
|
|
2006
|
-
|
|
2040
|
+
logger12.debug("Emitting itemUpdated event after action", {
|
|
2007
2041
|
key: updated.key,
|
|
2008
2042
|
action: action2
|
|
2009
2043
|
});
|
|
2010
2044
|
const itemEvent = CacheEventFactory.itemUpdated(updated.key, updated, null, "api");
|
|
2011
2045
|
context.eventEmitter.emit(itemEvent);
|
|
2012
|
-
|
|
2046
|
+
logger12.debug("Emitting queryInvalidatedEvent after action", {
|
|
2013
2047
|
eventType: "query_invalidated",
|
|
2014
2048
|
reason: "item_changed",
|
|
2015
2049
|
action: action2
|
|
@@ -2029,10 +2063,10 @@ import {
|
|
|
2029
2063
|
createAllActionWrapper
|
|
2030
2064
|
} from "@fjell/core";
|
|
2031
2065
|
import { NotFoundError as NotFoundError3 } from "@fjell/http-api";
|
|
2032
|
-
var
|
|
2066
|
+
var logger13 = logger_default.get("allAction");
|
|
2033
2067
|
var allAction = async (action2, body = {}, locations = [], context) => {
|
|
2034
2068
|
const { coordinate } = context;
|
|
2035
|
-
|
|
2069
|
+
logger13.default("allAction", { action: action2, body, locations });
|
|
2036
2070
|
const wrappedAllAction = createAllActionWrapper(
|
|
2037
2071
|
coordinate,
|
|
2038
2072
|
async (a, b, locs) => {
|
|
@@ -2052,10 +2086,10 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2052
2086
|
existingItems.push(...cachedItems);
|
|
2053
2087
|
}
|
|
2054
2088
|
} catch (error) {
|
|
2055
|
-
|
|
2089
|
+
logger13.debug("Could not retrieve existing items for comparison", { error });
|
|
2056
2090
|
}
|
|
2057
2091
|
}
|
|
2058
|
-
|
|
2092
|
+
logger13.debug("Invalidating location before allAction", { locations });
|
|
2059
2093
|
await cacheMap.invalidateLocation(locations);
|
|
2060
2094
|
let ret = [];
|
|
2061
2095
|
let affectedItems = [];
|
|
@@ -2065,7 +2099,7 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2065
2099
|
ret = result[0];
|
|
2066
2100
|
affectedItems = result[1];
|
|
2067
2101
|
} else {
|
|
2068
|
-
|
|
2102
|
+
logger13.warning("Unexpected result format from allAction", {
|
|
2069
2103
|
resultType: typeof result,
|
|
2070
2104
|
isArray: Array.isArray(result),
|
|
2071
2105
|
resultLength: Array.isArray(result) ? result.length : "not array"
|
|
@@ -2074,19 +2108,19 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2074
2108
|
affectedItems = [];
|
|
2075
2109
|
}
|
|
2076
2110
|
if (affectedItems && affectedItems.length > 0) {
|
|
2077
|
-
|
|
2111
|
+
logger13.debug("Handling cache invalidation for affected items", {
|
|
2078
2112
|
affectedItemsCount: affectedItems.length
|
|
2079
2113
|
});
|
|
2080
2114
|
try {
|
|
2081
2115
|
await handleActionCacheInvalidation(registry, affectedItems);
|
|
2082
2116
|
} catch (error) {
|
|
2083
|
-
|
|
2117
|
+
logger13.warning("Failed to handle cache invalidation for affected items", {
|
|
2084
2118
|
error: error instanceof Error ? error.message : String(error),
|
|
2085
2119
|
affectedItems
|
|
2086
2120
|
});
|
|
2087
2121
|
}
|
|
2088
2122
|
}
|
|
2089
|
-
|
|
2123
|
+
logger13.debug("Caching allAction results", { resultCount: ret.length });
|
|
2090
2124
|
const modifiedItems = [];
|
|
2091
2125
|
const newItems = [];
|
|
2092
2126
|
for (const v of ret) {
|
|
@@ -2108,7 +2142,7 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2108
2142
|
}
|
|
2109
2143
|
}
|
|
2110
2144
|
for (const item of modifiedItems) {
|
|
2111
|
-
|
|
2145
|
+
logger13.debug("Emitting item_updated event for modified item", { key: item.key });
|
|
2112
2146
|
const itemEvent = CacheEventFactory.itemUpdated(
|
|
2113
2147
|
item.key,
|
|
2114
2148
|
item,
|
|
@@ -2119,7 +2153,7 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2119
2153
|
eventEmitter.emit(itemEvent);
|
|
2120
2154
|
}
|
|
2121
2155
|
for (const item of newItems) {
|
|
2122
|
-
|
|
2156
|
+
logger13.debug("Emitting item_created event for new item", { key: item.key });
|
|
2123
2157
|
const itemEvent = CacheEventFactory.itemCreated(
|
|
2124
2158
|
item.key,
|
|
2125
2159
|
item,
|
|
@@ -2129,14 +2163,14 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2129
2163
|
}
|
|
2130
2164
|
if (modifiedItems.length > 0) {
|
|
2131
2165
|
const modifiedKeys = modifiedItems.map((item) => item.key);
|
|
2132
|
-
|
|
2166
|
+
logger13.debug("Invalidating individual item keys for modified items", {
|
|
2133
2167
|
keyCount: modifiedKeys.length,
|
|
2134
2168
|
keys: modifiedKeys
|
|
2135
2169
|
});
|
|
2136
2170
|
await cacheMap.invalidateItemKeys(modifiedKeys);
|
|
2137
2171
|
}
|
|
2138
2172
|
await cacheMap.clearQueryResults();
|
|
2139
|
-
|
|
2173
|
+
logger13.debug("Emitting query_invalidated event after allAction", {
|
|
2140
2174
|
eventType: "query_invalidated",
|
|
2141
2175
|
reason: "item_changed",
|
|
2142
2176
|
action: action2,
|
|
@@ -2169,10 +2203,10 @@ async function executeAllActionLogic(action2, body, locations, context) {
|
|
|
2169
2203
|
import {
|
|
2170
2204
|
createFacetWrapper
|
|
2171
2205
|
} from "@fjell/core";
|
|
2172
|
-
var
|
|
2206
|
+
var logger14 = logger_default.get("facet");
|
|
2173
2207
|
var facet = async (key, facet2, params = {}, context) => {
|
|
2174
2208
|
const { coordinate, api } = context;
|
|
2175
|
-
|
|
2209
|
+
logger14.default("facet", { key, facet: facet2 });
|
|
2176
2210
|
const wrappedFacet = createFacetWrapper(
|
|
2177
2211
|
coordinate,
|
|
2178
2212
|
async (k, f, p) => {
|
|
@@ -2186,10 +2220,10 @@ var facet = async (key, facet2, params = {}, context) => {
|
|
|
2186
2220
|
import {
|
|
2187
2221
|
createAllFacetWrapper
|
|
2188
2222
|
} from "@fjell/core";
|
|
2189
|
-
var
|
|
2223
|
+
var logger15 = logger_default.get("allFacet");
|
|
2190
2224
|
var allFacet = async (facet2, params = {}, locations = [], context) => {
|
|
2191
2225
|
const { api, coordinate } = context;
|
|
2192
|
-
|
|
2226
|
+
logger15.default("allFacet", { facet: facet2, params, locations });
|
|
2193
2227
|
const wrappedAllFacet = createAllFacetWrapper(
|
|
2194
2228
|
coordinate,
|
|
2195
2229
|
async (f, p, locs) => {
|
|
@@ -2203,10 +2237,10 @@ var allFacet = async (facet2, params = {}, locations = [], context) => {
|
|
|
2203
2237
|
import {
|
|
2204
2238
|
createFindWrapper
|
|
2205
2239
|
} from "@fjell/core";
|
|
2206
|
-
var
|
|
2240
|
+
var logger16 = logger_default.get("find");
|
|
2207
2241
|
var find = async (finder, params = {}, locations = [], context, findOptions) => {
|
|
2208
2242
|
const { coordinate } = context;
|
|
2209
|
-
|
|
2243
|
+
logger16.default("find", { finder, params, locations, findOptions });
|
|
2210
2244
|
const wrappedFind = createFindWrapper(
|
|
2211
2245
|
coordinate,
|
|
2212
2246
|
async (f, p, locs, opts) => {
|
|
@@ -2236,90 +2270,97 @@ async function executeFindLogic(finder, params, locations, context, findOptions)
|
|
|
2236
2270
|
}
|
|
2237
2271
|
});
|
|
2238
2272
|
if (context.options?.bypassCache) {
|
|
2239
|
-
|
|
2273
|
+
logger16.debug("Cache bypass enabled, fetching directly from API", { finder, params, locations, findOptions });
|
|
2240
2274
|
try {
|
|
2241
2275
|
const ret2 = await api.find(finder, params, locations, findOptions);
|
|
2242
|
-
|
|
2276
|
+
logger16.debug("API response received (not cached due to bypass)", { finder, params, locations, itemCount: ret2.items.length, total: ret2.metadata.total });
|
|
2243
2277
|
return ret2;
|
|
2244
2278
|
} catch (error) {
|
|
2245
|
-
|
|
2279
|
+
logger16.error("API request failed", { finder, params, locations, findOptions, error });
|
|
2246
2280
|
throw error;
|
|
2247
2281
|
}
|
|
2248
2282
|
}
|
|
2249
2283
|
const queryHash = createFinderHash(finder, params, locations);
|
|
2250
|
-
|
|
2284
|
+
logger16.debug("QUERY_CACHE: Generated query hash for find()", {
|
|
2251
2285
|
queryHash,
|
|
2252
2286
|
finder,
|
|
2253
2287
|
params: JSON.stringify(params),
|
|
2254
2288
|
locations: JSON.stringify(locations)
|
|
2255
2289
|
});
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
cachedKeyCount: cachedItemKeys.length,
|
|
2262
|
-
itemKeys: cachedItemKeys.map((k) => JSON.stringify(k))
|
|
2263
|
-
});
|
|
2264
|
-
const cachedItems = [];
|
|
2265
|
-
let allItemsAvailable = true;
|
|
2266
|
-
const missingKeys = [];
|
|
2267
|
-
for (const itemKey of cachedItemKeys) {
|
|
2268
|
-
const item = await cacheMap.get(itemKey);
|
|
2269
|
-
if (item) {
|
|
2270
|
-
cachedItems.push(item);
|
|
2271
|
-
logger14.debug("QUERY_CACHE: Retrieved cached item", {
|
|
2272
|
-
itemKey: JSON.stringify(itemKey),
|
|
2273
|
-
itemKeyStr: JSON.stringify(item.key)
|
|
2274
|
-
});
|
|
2275
|
-
} else {
|
|
2276
|
-
allItemsAvailable = false;
|
|
2277
|
-
missingKeys.push(itemKey);
|
|
2278
|
-
logger14.debug("QUERY_CACHE: Cached item MISSING from item cache", {
|
|
2279
|
-
itemKey: JSON.stringify(itemKey),
|
|
2280
|
-
queryHash
|
|
2281
|
-
});
|
|
2282
|
-
break;
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2285
|
-
if (allItemsAvailable) {
|
|
2286
|
-
logger14.debug("QUERY_CACHE: All cached items available, returning from cache", {
|
|
2290
|
+
logger16.debug("QUERY_CACHE: Checking query cache for hash", { queryHash });
|
|
2291
|
+
try {
|
|
2292
|
+
const cachedItemKeys = await cacheMap.getQueryResult(queryHash);
|
|
2293
|
+
if (cachedItemKeys) {
|
|
2294
|
+
logger16.debug("QUERY_CACHE: Cache HIT - Found cached query result", {
|
|
2287
2295
|
queryHash,
|
|
2288
|
-
|
|
2296
|
+
cachedKeyCount: cachedItemKeys.length,
|
|
2297
|
+
itemKeys: cachedItemKeys.map((k) => JSON.stringify(k))
|
|
2289
2298
|
});
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
const
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2299
|
+
const cachedItems = [];
|
|
2300
|
+
let allItemsAvailable = true;
|
|
2301
|
+
const missingKeys = [];
|
|
2302
|
+
for (const itemKey of cachedItemKeys) {
|
|
2303
|
+
const item = await cacheMap.get(itemKey);
|
|
2304
|
+
if (item) {
|
|
2305
|
+
cachedItems.push(item);
|
|
2306
|
+
logger16.debug("QUERY_CACHE: Retrieved cached item", {
|
|
2307
|
+
itemKey: JSON.stringify(itemKey),
|
|
2308
|
+
itemKeyStr: JSON.stringify(item.key)
|
|
2309
|
+
});
|
|
2310
|
+
} else {
|
|
2311
|
+
allItemsAvailable = false;
|
|
2312
|
+
missingKeys.push(itemKey);
|
|
2313
|
+
logger16.debug("QUERY_CACHE: Cached item MISSING from item cache", {
|
|
2314
|
+
itemKey: JSON.stringify(itemKey),
|
|
2315
|
+
queryHash
|
|
2316
|
+
});
|
|
2317
|
+
break;
|
|
2318
|
+
}
|
|
2298
2319
|
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2320
|
+
if (allItemsAvailable) {
|
|
2321
|
+
logger16.debug("QUERY_CACHE: All cached items available, returning from cache", {
|
|
2322
|
+
queryHash,
|
|
2323
|
+
itemCount: cachedItems.length
|
|
2324
|
+
});
|
|
2325
|
+
let paginatedItems = cachedItems;
|
|
2326
|
+
const offset = findOptions?.offset ?? 0;
|
|
2327
|
+
const limit = findOptions?.limit;
|
|
2328
|
+
if (offset > 0) {
|
|
2329
|
+
paginatedItems = paginatedItems.slice(offset);
|
|
2308
2330
|
}
|
|
2309
|
-
|
|
2331
|
+
if (limit != null && limit >= 0) {
|
|
2332
|
+
paginatedItems = paginatedItems.slice(0, limit);
|
|
2333
|
+
}
|
|
2334
|
+
return {
|
|
2335
|
+
items: paginatedItems,
|
|
2336
|
+
metadata: {
|
|
2337
|
+
total: cachedItems.length,
|
|
2338
|
+
// Total before pagination
|
|
2339
|
+
returned: paginatedItems.length,
|
|
2340
|
+
offset,
|
|
2341
|
+
limit,
|
|
2342
|
+
hasMore: limit != null && offset + paginatedItems.length < cachedItems.length
|
|
2343
|
+
}
|
|
2344
|
+
};
|
|
2345
|
+
} else {
|
|
2346
|
+
logger16.debug("QUERY_CACHE: Some cached items missing, invalidating query cache", {
|
|
2347
|
+
queryHash,
|
|
2348
|
+
missingKeys: missingKeys.map((k) => JSON.stringify(k)),
|
|
2349
|
+
foundCount: cachedItems.length,
|
|
2350
|
+
expectedCount: cachedItemKeys.length
|
|
2351
|
+
});
|
|
2352
|
+
cacheMap.deleteQueryResult(queryHash);
|
|
2353
|
+
}
|
|
2310
2354
|
} else {
|
|
2311
|
-
|
|
2312
|
-
queryHash,
|
|
2313
|
-
missingKeys: missingKeys.map((k) => JSON.stringify(k)),
|
|
2314
|
-
foundCount: cachedItems.length,
|
|
2315
|
-
expectedCount: cachedItemKeys.length
|
|
2316
|
-
});
|
|
2317
|
-
cacheMap.deleteQueryResult(queryHash);
|
|
2355
|
+
logger16.debug("QUERY_CACHE: Cache MISS - No cached query result found", { queryHash });
|
|
2318
2356
|
}
|
|
2319
|
-
}
|
|
2320
|
-
|
|
2357
|
+
} catch (error) {
|
|
2358
|
+
logger16.error("QUERY_CACHE: Error checking query cache, falling back to API", {
|
|
2359
|
+
queryHash,
|
|
2360
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2361
|
+
});
|
|
2321
2362
|
}
|
|
2322
|
-
|
|
2363
|
+
logger16.debug("QUERY_CACHE: Fetching from API (cache miss or invalid)", {
|
|
2323
2364
|
queryHash,
|
|
2324
2365
|
finder,
|
|
2325
2366
|
params: JSON.stringify(params),
|
|
@@ -2327,19 +2368,19 @@ async function executeFindLogic(finder, params, locations, context, findOptions)
|
|
|
2327
2368
|
findOptions
|
|
2328
2369
|
});
|
|
2329
2370
|
const ret = await api.find(finder, params, locations, findOptions);
|
|
2330
|
-
|
|
2371
|
+
logger16.debug("QUERY_CACHE: API response received", {
|
|
2331
2372
|
queryHash,
|
|
2332
2373
|
itemCount: ret.items.length,
|
|
2333
2374
|
total: ret.metadata.total,
|
|
2334
2375
|
itemKeys: ret.items.map((item) => JSON.stringify(item.key))
|
|
2335
2376
|
});
|
|
2336
|
-
|
|
2377
|
+
logger16.debug("QUERY_CACHE: Storing items in item cache", {
|
|
2337
2378
|
queryHash,
|
|
2338
2379
|
itemCount: ret.items.length
|
|
2339
2380
|
});
|
|
2340
2381
|
for (const v of ret.items) {
|
|
2341
2382
|
await cacheMap.set(v.key, v);
|
|
2342
|
-
|
|
2383
|
+
logger16.debug("QUERY_CACHE: Stored item in cache", {
|
|
2343
2384
|
itemKey: JSON.stringify(v.key),
|
|
2344
2385
|
queryHash
|
|
2345
2386
|
});
|
|
@@ -2349,7 +2390,7 @@ async function executeFindLogic(finder, params, locations, context, findOptions)
|
|
|
2349
2390
|
for (const evictedKey of evictedKeys) {
|
|
2350
2391
|
const parsedKey = JSON.parse(evictedKey);
|
|
2351
2392
|
await cacheMap.delete(parsedKey);
|
|
2352
|
-
|
|
2393
|
+
logger16.debug("QUERY_CACHE: Evicted item due to cache limits", {
|
|
2353
2394
|
evictedKey,
|
|
2354
2395
|
queryHash
|
|
2355
2396
|
});
|
|
@@ -2357,15 +2398,15 @@ async function executeFindLogic(finder, params, locations, context, findOptions)
|
|
|
2357
2398
|
}
|
|
2358
2399
|
const itemKeys = ret.items.map((item) => item.key);
|
|
2359
2400
|
await cacheMap.setQueryResult(queryHash, itemKeys);
|
|
2360
|
-
|
|
2401
|
+
logger16.debug("QUERY_CACHE: Stored query result in query cache", {
|
|
2361
2402
|
queryHash,
|
|
2362
2403
|
itemKeyCount: itemKeys.length,
|
|
2363
2404
|
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
2364
2405
|
});
|
|
2365
2406
|
const event = CacheEventFactory.createQueryEvent(params, locations, ret.items);
|
|
2366
2407
|
eventEmitter.emit(event);
|
|
2367
|
-
|
|
2368
|
-
|
|
2408
|
+
logger16.debug("QUERY_CACHE: Emitted query event", { queryHash });
|
|
2409
|
+
logger16.debug("QUERY_CACHE: find() operation completed", {
|
|
2369
2410
|
queryHash,
|
|
2370
2411
|
resultCount: ret.items.length,
|
|
2371
2412
|
total: ret.metadata.total
|
|
@@ -2377,10 +2418,10 @@ async function executeFindLogic(finder, params, locations, context, findOptions)
|
|
|
2377
2418
|
import {
|
|
2378
2419
|
createFindOneWrapper
|
|
2379
2420
|
} from "@fjell/core";
|
|
2380
|
-
var
|
|
2421
|
+
var logger17 = logger_default.get("findOne");
|
|
2381
2422
|
var findOne = async (finder, finderParams = {}, locations = [], context) => {
|
|
2382
2423
|
const { coordinate } = context;
|
|
2383
|
-
|
|
2424
|
+
logger17.default("findOne", { finder, finderParams, locations });
|
|
2384
2425
|
const wrappedFindOne = createFindOneWrapper(
|
|
2385
2426
|
coordinate,
|
|
2386
2427
|
async (f, p, locs) => {
|
|
@@ -2393,58 +2434,58 @@ var findOne = async (finder, finderParams = {}, locations = [], context) => {
|
|
|
2393
2434
|
async function executeFindOneLogic(finder, finderParams, locations, context) {
|
|
2394
2435
|
const { api, cacheMap, pkType, ttlManager, eventEmitter } = context;
|
|
2395
2436
|
if (context.options?.bypassCache) {
|
|
2396
|
-
|
|
2437
|
+
logger17.debug("Cache bypass enabled, fetching directly from API", { finder, finderParams, locations });
|
|
2397
2438
|
try {
|
|
2398
2439
|
const ret2 = await api.findOne(finder, finderParams, locations);
|
|
2399
2440
|
if (ret2 === null) {
|
|
2400
2441
|
throw new Error(`findOne returned null for finder: ${finder}`);
|
|
2401
2442
|
}
|
|
2402
|
-
|
|
2443
|
+
logger17.debug("API response received (not cached due to bypass)", { finder, finderParams, locations });
|
|
2403
2444
|
return ret2;
|
|
2404
2445
|
} catch (error) {
|
|
2405
|
-
|
|
2446
|
+
logger17.error("API request failed", { finder, finderParams, locations, error });
|
|
2406
2447
|
throw error;
|
|
2407
2448
|
}
|
|
2408
2449
|
}
|
|
2409
2450
|
const queryHash = createFinderHash(finder, finderParams, locations);
|
|
2410
|
-
|
|
2451
|
+
logger17.debug("QUERY_CACHE: Generated query hash for findOne()", {
|
|
2411
2452
|
queryHash,
|
|
2412
2453
|
finder,
|
|
2413
2454
|
finderParams: JSON.stringify(finderParams),
|
|
2414
2455
|
locations: JSON.stringify(locations)
|
|
2415
2456
|
});
|
|
2416
|
-
|
|
2457
|
+
logger17.debug("QUERY_CACHE: Checking query cache for hash", { queryHash });
|
|
2417
2458
|
const cachedItemKeys = await cacheMap.getQueryResult(queryHash);
|
|
2418
2459
|
if (cachedItemKeys && cachedItemKeys.length > 0) {
|
|
2419
|
-
|
|
2460
|
+
logger17.debug("QUERY_CACHE: Cache HIT - Found cached query result", {
|
|
2420
2461
|
queryHash,
|
|
2421
2462
|
cachedKeyCount: cachedItemKeys.length,
|
|
2422
2463
|
itemKeys: cachedItemKeys.map((k) => JSON.stringify(k))
|
|
2423
2464
|
});
|
|
2424
2465
|
const itemKey = cachedItemKeys[0];
|
|
2425
|
-
|
|
2466
|
+
logger17.debug("QUERY_CACHE: Retrieving first cached item", {
|
|
2426
2467
|
queryHash,
|
|
2427
2468
|
itemKey: JSON.stringify(itemKey)
|
|
2428
2469
|
});
|
|
2429
2470
|
const item = await cacheMap.get(itemKey);
|
|
2430
2471
|
if (item) {
|
|
2431
|
-
|
|
2472
|
+
logger17.debug("QUERY_CACHE: Retrieved cached item successfully", {
|
|
2432
2473
|
queryHash,
|
|
2433
2474
|
itemKey: JSON.stringify(itemKey),
|
|
2434
2475
|
itemKeyStr: JSON.stringify(item.key)
|
|
2435
2476
|
});
|
|
2436
2477
|
return item;
|
|
2437
2478
|
} else {
|
|
2438
|
-
|
|
2479
|
+
logger17.debug("QUERY_CACHE: Cached item MISSING from item cache, invalidating query cache", {
|
|
2439
2480
|
queryHash,
|
|
2440
2481
|
itemKey: JSON.stringify(itemKey)
|
|
2441
2482
|
});
|
|
2442
2483
|
cacheMap.deleteQueryResult(queryHash);
|
|
2443
2484
|
}
|
|
2444
2485
|
} else {
|
|
2445
|
-
|
|
2486
|
+
logger17.debug("QUERY_CACHE: Cache MISS - No cached query result found", { queryHash });
|
|
2446
2487
|
}
|
|
2447
|
-
|
|
2488
|
+
logger17.debug("QUERY_CACHE: Fetching from API (cache miss or invalid)", {
|
|
2448
2489
|
queryHash,
|
|
2449
2490
|
finder,
|
|
2450
2491
|
finderParams: JSON.stringify(finderParams),
|
|
@@ -2452,14 +2493,14 @@ async function executeFindOneLogic(finder, finderParams, locations, context) {
|
|
|
2452
2493
|
});
|
|
2453
2494
|
const ret = await api.findOne(finder, finderParams, locations);
|
|
2454
2495
|
if (ret === null) {
|
|
2455
|
-
|
|
2496
|
+
logger17.debug("QUERY_CACHE: API returned null, throwing error", { queryHash, finder });
|
|
2456
2497
|
throw new Error(`findOne returned null for finder: ${finder}`);
|
|
2457
2498
|
}
|
|
2458
|
-
|
|
2499
|
+
logger17.debug("QUERY_CACHE: API response received", {
|
|
2459
2500
|
queryHash,
|
|
2460
2501
|
itemKey: JSON.stringify(ret.key)
|
|
2461
2502
|
});
|
|
2462
|
-
|
|
2503
|
+
logger17.debug("QUERY_CACHE: Storing item in item cache", {
|
|
2463
2504
|
queryHash,
|
|
2464
2505
|
itemKey: JSON.stringify(ret.key)
|
|
2465
2506
|
});
|
|
@@ -2470,20 +2511,20 @@ async function executeFindOneLogic(finder, finderParams, locations, context) {
|
|
|
2470
2511
|
for (const evictedKey of evictedKeys) {
|
|
2471
2512
|
const parsedKey = JSON.parse(evictedKey);
|
|
2472
2513
|
await cacheMap.delete(parsedKey);
|
|
2473
|
-
|
|
2514
|
+
logger17.debug("QUERY_CACHE: Evicted item due to cache limits", {
|
|
2474
2515
|
evictedKey,
|
|
2475
2516
|
queryHash
|
|
2476
2517
|
});
|
|
2477
2518
|
}
|
|
2478
2519
|
await cacheMap.setQueryResult(queryHash, [ret.key]);
|
|
2479
|
-
|
|
2520
|
+
logger17.debug("QUERY_CACHE: Stored query result in query cache", {
|
|
2480
2521
|
queryHash,
|
|
2481
2522
|
itemKey: JSON.stringify(ret.key)
|
|
2482
2523
|
});
|
|
2483
2524
|
const event = CacheEventFactory.createQueryEvent(finderParams, locations, [ret]);
|
|
2484
2525
|
eventEmitter.emit(event);
|
|
2485
|
-
|
|
2486
|
-
|
|
2526
|
+
logger17.debug("QUERY_CACHE: Emitted query event", { queryHash });
|
|
2527
|
+
logger17.debug("QUERY_CACHE: findOne() operation completed", {
|
|
2487
2528
|
queryHash,
|
|
2488
2529
|
itemKey: JSON.stringify(ret.key)
|
|
2489
2530
|
});
|
|
@@ -2495,7 +2536,7 @@ import {
|
|
|
2495
2536
|
isItemKeyEqual,
|
|
2496
2537
|
isValidItemKey as isValidItemKey6
|
|
2497
2538
|
} from "@fjell/core";
|
|
2498
|
-
var
|
|
2539
|
+
var logger18 = logger_default.get("set");
|
|
2499
2540
|
var normalizeKeyValue2 = (value) => {
|
|
2500
2541
|
return String(value);
|
|
2501
2542
|
};
|
|
@@ -2547,17 +2588,17 @@ var set = async (key, v, context) => {
|
|
|
2547
2588
|
const startTime = Date.now();
|
|
2548
2589
|
const { cacheMap, pkType, ttlManager, evictionManager, eventEmitter } = context;
|
|
2549
2590
|
const keyStr = JSON.stringify(key);
|
|
2550
|
-
|
|
2551
|
-
|
|
2591
|
+
logger18.default("set", { key, v });
|
|
2592
|
+
logger18.debug("CACHE_OP: set() started", {
|
|
2552
2593
|
key: keyStr,
|
|
2553
2594
|
cacheType: cacheMap.implementationType
|
|
2554
2595
|
});
|
|
2555
2596
|
if (!isValidItemKey6(key)) {
|
|
2556
|
-
|
|
2597
|
+
logger18.error("CACHE_OP: Invalid key for set", { key: keyStr });
|
|
2557
2598
|
throw new Error("Key for Set is not a valid ItemKey");
|
|
2558
2599
|
}
|
|
2559
2600
|
if (!isItemKeyEqualNormalized(key, v.key)) {
|
|
2560
|
-
|
|
2601
|
+
logger18.error("CACHE_OP: Key mismatch in set", {
|
|
2561
2602
|
providedKey: keyStr,
|
|
2562
2603
|
itemKey: JSON.stringify(v.key)
|
|
2563
2604
|
});
|
|
@@ -2566,7 +2607,7 @@ var set = async (key, v, context) => {
|
|
|
2566
2607
|
const checkStartTime = Date.now();
|
|
2567
2608
|
const previousItem = await cacheMap.get(key);
|
|
2568
2609
|
const checkDuration = Date.now() - checkStartTime;
|
|
2569
|
-
|
|
2610
|
+
logger18.debug("CACHE_OP: Previous item check", {
|
|
2570
2611
|
key: keyStr,
|
|
2571
2612
|
hadPreviousItem: !!previousItem,
|
|
2572
2613
|
checkDuration
|
|
@@ -2587,12 +2628,12 @@ var set = async (key, v, context) => {
|
|
|
2587
2628
|
estimatedSize
|
|
2588
2629
|
};
|
|
2589
2630
|
await cacheMap.setMetadata(keyStr, baseMetadata);
|
|
2590
|
-
|
|
2631
|
+
logger18.debug("CACHE_OP: Created base metadata", {
|
|
2591
2632
|
key: keyStr,
|
|
2592
2633
|
estimatedSize
|
|
2593
2634
|
});
|
|
2594
2635
|
} else {
|
|
2595
|
-
|
|
2636
|
+
logger18.debug("CACHE_OP: Metadata already exists", {
|
|
2596
2637
|
key: keyStr,
|
|
2597
2638
|
addedAt: new Date(metadata.addedAt).toISOString(),
|
|
2598
2639
|
accessCount: metadata.accessCount
|
|
@@ -2606,7 +2647,7 @@ var set = async (key, v, context) => {
|
|
|
2606
2647
|
const evictedKeys = await evictionManager.onItemAdded(keyStr, v, cacheMap);
|
|
2607
2648
|
const evictionDuration = Date.now() - evictionStartTime;
|
|
2608
2649
|
if (evictedKeys.length > 0) {
|
|
2609
|
-
|
|
2650
|
+
logger18.debug("CACHE_OP: Eviction triggered by set", {
|
|
2610
2651
|
key: keyStr,
|
|
2611
2652
|
evictedCount: evictedKeys.length,
|
|
2612
2653
|
evictedKeys
|
|
@@ -2615,12 +2656,12 @@ var set = async (key, v, context) => {
|
|
|
2615
2656
|
for (const evictedKey of evictedKeys) {
|
|
2616
2657
|
const parsedKey = JSON.parse(evictedKey);
|
|
2617
2658
|
await cacheMap.delete(parsedKey);
|
|
2618
|
-
|
|
2659
|
+
logger18.debug("CACHE_OP: Removed evicted item", { evictedKey });
|
|
2619
2660
|
}
|
|
2620
2661
|
const event = CacheEventFactory.itemSet(key, v, previousItem);
|
|
2621
2662
|
eventEmitter.emit(event);
|
|
2622
2663
|
const totalDuration = Date.now() - startTime;
|
|
2623
|
-
|
|
2664
|
+
logger18.debug("CACHE_OP: set() completed", {
|
|
2624
2665
|
key: keyStr,
|
|
2625
2666
|
checkDuration,
|
|
2626
2667
|
setDuration,
|
|
@@ -2639,7 +2680,7 @@ import {
|
|
|
2639
2680
|
isComKey,
|
|
2640
2681
|
isQueryMatch
|
|
2641
2682
|
} from "@fjell/core";
|
|
2642
|
-
var
|
|
2683
|
+
var logger19 = logger_default.get("MemoryCacheMap");
|
|
2643
2684
|
var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
2644
2685
|
implementationType = "memory/memory";
|
|
2645
2686
|
map = {};
|
|
@@ -2657,13 +2698,13 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2657
2698
|
const key = JSON.parse(keyStr);
|
|
2658
2699
|
this.set(key, value);
|
|
2659
2700
|
} catch (error) {
|
|
2660
|
-
|
|
2701
|
+
logger19.error("Failed to parse initial data key", { keyStr, error });
|
|
2661
2702
|
}
|
|
2662
2703
|
}
|
|
2663
2704
|
}
|
|
2664
2705
|
}
|
|
2665
2706
|
async get(key) {
|
|
2666
|
-
|
|
2707
|
+
logger19.trace("get", { key });
|
|
2667
2708
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2668
2709
|
const entry = this.map[hashedKey];
|
|
2669
2710
|
if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {
|
|
@@ -2678,7 +2719,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2678
2719
|
return null;
|
|
2679
2720
|
}
|
|
2680
2721
|
async set(key, value) {
|
|
2681
|
-
|
|
2722
|
+
logger19.trace("set", { key, value });
|
|
2682
2723
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2683
2724
|
const keyStr = JSON.stringify(key);
|
|
2684
2725
|
this.map[hashedKey] = { originalKey: key, value };
|
|
@@ -2705,7 +2746,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2705
2746
|
return !!entry && this.normalizedHashFunction(entry.originalKey) === hashedKey;
|
|
2706
2747
|
}
|
|
2707
2748
|
async delete(key) {
|
|
2708
|
-
|
|
2749
|
+
logger19.trace("delete", { key });
|
|
2709
2750
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2710
2751
|
const entry = this.map[hashedKey];
|
|
2711
2752
|
if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {
|
|
@@ -2734,10 +2775,10 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2734
2775
|
async allIn(locations) {
|
|
2735
2776
|
const allValues = await this.values();
|
|
2736
2777
|
if (locations.length === 0) {
|
|
2737
|
-
|
|
2778
|
+
logger19.debug("Returning all items, LocKeys is empty");
|
|
2738
2779
|
return allValues;
|
|
2739
2780
|
} else {
|
|
2740
|
-
|
|
2781
|
+
logger19.debug("allIn", { locations, count: allValues.length });
|
|
2741
2782
|
return allValues.filter((item) => {
|
|
2742
2783
|
const key = item.key;
|
|
2743
2784
|
if (key && isComKey(key)) {
|
|
@@ -2749,12 +2790,12 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2749
2790
|
}
|
|
2750
2791
|
}
|
|
2751
2792
|
async contains(query, locations) {
|
|
2752
|
-
|
|
2793
|
+
logger19.debug("contains", { query, locations });
|
|
2753
2794
|
const items = await this.allIn(locations);
|
|
2754
2795
|
return items.some((item) => isQueryMatch(item, query));
|
|
2755
2796
|
}
|
|
2756
2797
|
async queryIn(query, locations = []) {
|
|
2757
|
-
|
|
2798
|
+
logger19.debug("queryIn", { query, locations });
|
|
2758
2799
|
const items = await this.allIn(locations);
|
|
2759
2800
|
return items.filter((item) => isQueryMatch(item, query));
|
|
2760
2801
|
}
|
|
@@ -2776,32 +2817,45 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2776
2817
|
return clone;
|
|
2777
2818
|
}
|
|
2778
2819
|
// Query result caching methods implementation
|
|
2779
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
2780
|
-
|
|
2820
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
2821
|
+
logger19.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
2781
2822
|
const entry = {
|
|
2782
|
-
itemKeys: [...itemKeys]
|
|
2823
|
+
itemKeys: [...itemKeys],
|
|
2783
2824
|
// Create a copy to avoid external mutations
|
|
2825
|
+
metadata
|
|
2784
2826
|
};
|
|
2785
2827
|
this.queryResultCache[queryHash] = entry;
|
|
2786
2828
|
}
|
|
2787
2829
|
async getQueryResult(queryHash) {
|
|
2788
|
-
|
|
2830
|
+
logger19.trace("getQueryResult", { queryHash });
|
|
2789
2831
|
const entry = this.queryResultCache[queryHash];
|
|
2790
2832
|
if (!entry) {
|
|
2791
2833
|
return null;
|
|
2792
2834
|
}
|
|
2793
2835
|
return [...entry.itemKeys];
|
|
2794
2836
|
}
|
|
2837
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
2838
|
+
logger19.trace("getQueryResultWithMetadata", { queryHash });
|
|
2839
|
+
const entry = this.queryResultCache[queryHash];
|
|
2840
|
+
if (!entry) {
|
|
2841
|
+
return null;
|
|
2842
|
+
}
|
|
2843
|
+
return {
|
|
2844
|
+
itemKeys: [...entry.itemKeys],
|
|
2845
|
+
// Return a copy to avoid external mutations
|
|
2846
|
+
metadata: entry.metadata
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2795
2849
|
async hasQueryResult(queryHash) {
|
|
2796
2850
|
const entry = this.queryResultCache[queryHash];
|
|
2797
2851
|
return !!entry;
|
|
2798
2852
|
}
|
|
2799
2853
|
async deleteQueryResult(queryHash) {
|
|
2800
|
-
|
|
2854
|
+
logger19.trace("deleteQueryResult", { queryHash });
|
|
2801
2855
|
delete this.queryResultCache[queryHash];
|
|
2802
2856
|
}
|
|
2803
2857
|
async invalidateItemKeys(keys) {
|
|
2804
|
-
|
|
2858
|
+
logger19.debug("invalidateItemKeys", { keys });
|
|
2805
2859
|
if (keys.length === 0) {
|
|
2806
2860
|
return;
|
|
2807
2861
|
}
|
|
@@ -2832,14 +2886,14 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2832
2886
|
queriesToRemove.forEach((queryHash) => {
|
|
2833
2887
|
this.deleteQueryResult(queryHash);
|
|
2834
2888
|
});
|
|
2835
|
-
|
|
2889
|
+
logger19.debug("Selectively invalidated queries referencing affected keys", {
|
|
2836
2890
|
affectedKeys: keys.length,
|
|
2837
2891
|
queriesRemoved: queriesToRemove.length,
|
|
2838
2892
|
totalQueries: Object.keys(this.queryResultCache).length
|
|
2839
2893
|
});
|
|
2840
2894
|
}
|
|
2841
2895
|
async invalidateLocation(locations) {
|
|
2842
|
-
|
|
2896
|
+
logger19.debug("invalidateLocation", { locations });
|
|
2843
2897
|
let keysToInvalidate = [];
|
|
2844
2898
|
if (locations.length === 0) {
|
|
2845
2899
|
const allKeys = await this.keys();
|
|
@@ -2852,7 +2906,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2852
2906
|
await this.invalidateItemKeys(keysToInvalidate);
|
|
2853
2907
|
}
|
|
2854
2908
|
async clearQueryResults() {
|
|
2855
|
-
|
|
2909
|
+
logger19.trace("clearQueryResults");
|
|
2856
2910
|
this.queryResultCache = {};
|
|
2857
2911
|
}
|
|
2858
2912
|
// CacheMapMetadataProvider implementation
|
|
@@ -2894,7 +2948,7 @@ import {
|
|
|
2894
2948
|
isComKey as isComKey2,
|
|
2895
2949
|
isQueryMatch as isQueryMatch2
|
|
2896
2950
|
} from "@fjell/core";
|
|
2897
|
-
var
|
|
2951
|
+
var logger20 = logger_default.get("EnhancedMemoryCacheMap");
|
|
2898
2952
|
var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
2899
2953
|
implementationType = "memory/enhanced";
|
|
2900
2954
|
map = {};
|
|
@@ -2913,11 +2967,11 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2913
2967
|
this.normalizedHashFunction = createNormalizedHashFunction();
|
|
2914
2968
|
if (sizeConfig?.maxSizeBytes) {
|
|
2915
2969
|
this.maxSizeBytes = parseSizeString(sizeConfig.maxSizeBytes);
|
|
2916
|
-
|
|
2970
|
+
logger20.debug("Cache size limit set", { maxSizeBytes: this.maxSizeBytes });
|
|
2917
2971
|
}
|
|
2918
2972
|
if (sizeConfig?.maxItems) {
|
|
2919
2973
|
this.maxItems = sizeConfig.maxItems;
|
|
2920
|
-
|
|
2974
|
+
logger20.debug("Cache item limit set", { maxItems: this.maxItems });
|
|
2921
2975
|
}
|
|
2922
2976
|
if (initialData) {
|
|
2923
2977
|
for (const [keyStr, value] of Object.entries(initialData)) {
|
|
@@ -2925,13 +2979,13 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2925
2979
|
const key = JSON.parse(keyStr);
|
|
2926
2980
|
this.set(key, value);
|
|
2927
2981
|
} catch (error) {
|
|
2928
|
-
|
|
2982
|
+
logger20.error("Failed to parse initial data key", { keyStr, error });
|
|
2929
2983
|
}
|
|
2930
2984
|
}
|
|
2931
2985
|
}
|
|
2932
2986
|
}
|
|
2933
2987
|
async get(key) {
|
|
2934
|
-
|
|
2988
|
+
logger20.trace("get", { key });
|
|
2935
2989
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2936
2990
|
const entry = this.map[hashedKey];
|
|
2937
2991
|
if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey && entry.value !== null) {
|
|
@@ -2940,7 +2994,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2940
2994
|
return null;
|
|
2941
2995
|
}
|
|
2942
2996
|
async set(key, value) {
|
|
2943
|
-
|
|
2997
|
+
logger20.trace("set", { key, value });
|
|
2944
2998
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2945
2999
|
const estimatedSize = estimateValueSize(value);
|
|
2946
3000
|
const existingEntry = this.map[hashedKey];
|
|
@@ -2951,7 +3005,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2951
3005
|
const oldValue = existingEntry.value;
|
|
2952
3006
|
existingEntry.value = value;
|
|
2953
3007
|
existingEntry.metadata.estimatedSize = estimatedSize;
|
|
2954
|
-
|
|
3008
|
+
logger20.trace("Updated existing cache entry", {
|
|
2955
3009
|
key: hashedKey,
|
|
2956
3010
|
sizeDiff,
|
|
2957
3011
|
currentSize: this.currentSizeBytes,
|
|
@@ -2972,7 +3026,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2972
3026
|
};
|
|
2973
3027
|
this.currentSizeBytes += estimatedSize;
|
|
2974
3028
|
this.currentItemCount++;
|
|
2975
|
-
|
|
3029
|
+
logger20.trace("Added new cache entry", {
|
|
2976
3030
|
key: hashedKey,
|
|
2977
3031
|
size: estimatedSize,
|
|
2978
3032
|
currentSize: this.currentSizeBytes,
|
|
@@ -2989,14 +3043,14 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
2989
3043
|
this.deleteInternal(key, true, "filter");
|
|
2990
3044
|
}
|
|
2991
3045
|
deleteInternal(key, invalidateQueries = false, invalidationMode = "remove") {
|
|
2992
|
-
|
|
3046
|
+
logger20.trace("delete", { key });
|
|
2993
3047
|
const hashedKey = this.normalizedHashFunction(key);
|
|
2994
3048
|
const entry = this.map[hashedKey];
|
|
2995
3049
|
if (entry && this.normalizedHashFunction(entry.originalKey) === hashedKey) {
|
|
2996
3050
|
this.currentSizeBytes -= entry.metadata.estimatedSize;
|
|
2997
3051
|
this.currentItemCount--;
|
|
2998
3052
|
delete this.map[hashedKey];
|
|
2999
|
-
|
|
3053
|
+
logger20.trace("Deleted cache entry", {
|
|
3000
3054
|
key: hashedKey,
|
|
3001
3055
|
freedSize: entry.metadata.estimatedSize,
|
|
3002
3056
|
currentSize: this.currentSizeBytes,
|
|
@@ -3018,7 +3072,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3018
3072
|
return Object.values(this.map).filter((entry) => entry.value !== null).map((entry) => entry.value);
|
|
3019
3073
|
}
|
|
3020
3074
|
async clear() {
|
|
3021
|
-
|
|
3075
|
+
logger20.debug("Clearing cache", {
|
|
3022
3076
|
itemsCleared: this.currentItemCount,
|
|
3023
3077
|
bytesFreed: this.currentSizeBytes
|
|
3024
3078
|
});
|
|
@@ -3029,10 +3083,10 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3029
3083
|
async allIn(locations) {
|
|
3030
3084
|
const allValues = await this.values();
|
|
3031
3085
|
if (locations.length === 0) {
|
|
3032
|
-
|
|
3086
|
+
logger20.debug("Returning all items, LocKeys is empty");
|
|
3033
3087
|
return allValues;
|
|
3034
3088
|
} else {
|
|
3035
|
-
|
|
3089
|
+
logger20.debug("allIn", { locations, count: allValues.length });
|
|
3036
3090
|
return allValues.filter((item) => {
|
|
3037
3091
|
const key = item.key;
|
|
3038
3092
|
if (key && isComKey2(key)) {
|
|
@@ -3043,12 +3097,12 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3043
3097
|
}
|
|
3044
3098
|
}
|
|
3045
3099
|
async contains(query, locations) {
|
|
3046
|
-
|
|
3100
|
+
logger20.debug("contains", { query, locations });
|
|
3047
3101
|
const items = await this.allIn(locations);
|
|
3048
3102
|
return items.some((item) => isQueryMatch2(item, query));
|
|
3049
3103
|
}
|
|
3050
3104
|
async queryIn(query, locations = []) {
|
|
3051
|
-
|
|
3105
|
+
logger20.debug("queryIn", { query, locations });
|
|
3052
3106
|
const items = await this.allIn(locations);
|
|
3053
3107
|
return items.filter((item) => isQueryMatch2(item, query));
|
|
3054
3108
|
}
|
|
@@ -3093,26 +3147,39 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3093
3147
|
return stats;
|
|
3094
3148
|
}
|
|
3095
3149
|
// Query result caching methods
|
|
3096
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
3097
|
-
|
|
3150
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
3151
|
+
logger20.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
3098
3152
|
if (queryHash in this.queryResultCache) {
|
|
3099
3153
|
this.removeQueryResultFromSizeTracking(queryHash);
|
|
3100
3154
|
}
|
|
3101
3155
|
const entry = {
|
|
3102
|
-
itemKeys: [...itemKeys]
|
|
3156
|
+
itemKeys: [...itemKeys],
|
|
3103
3157
|
// Create a copy to avoid external mutations
|
|
3158
|
+
metadata
|
|
3104
3159
|
};
|
|
3105
3160
|
this.queryResultCache[queryHash] = entry;
|
|
3106
3161
|
this.addQueryResultToSizeTracking(queryHash, entry);
|
|
3107
3162
|
}
|
|
3108
3163
|
async getQueryResult(queryHash) {
|
|
3109
|
-
|
|
3164
|
+
logger20.trace("getQueryResult", { queryHash });
|
|
3110
3165
|
const entry = this.queryResultCache[queryHash];
|
|
3111
3166
|
if (!entry) {
|
|
3112
3167
|
return null;
|
|
3113
3168
|
}
|
|
3114
3169
|
return [...entry.itemKeys];
|
|
3115
3170
|
}
|
|
3171
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
3172
|
+
logger20.trace("getQueryResultWithMetadata", { queryHash });
|
|
3173
|
+
const entry = this.queryResultCache[queryHash];
|
|
3174
|
+
if (!entry) {
|
|
3175
|
+
return null;
|
|
3176
|
+
}
|
|
3177
|
+
return {
|
|
3178
|
+
itemKeys: [...entry.itemKeys],
|
|
3179
|
+
// Return a copy to avoid external mutations
|
|
3180
|
+
metadata: entry.metadata
|
|
3181
|
+
};
|
|
3182
|
+
}
|
|
3116
3183
|
async hasQueryResult(queryHash) {
|
|
3117
3184
|
const entry = this.queryResultCache[queryHash];
|
|
3118
3185
|
return !!entry;
|
|
@@ -3128,7 +3195,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3128
3195
|
this.queryResultsCacheSize = 0;
|
|
3129
3196
|
}
|
|
3130
3197
|
async invalidateItemKeys(keys) {
|
|
3131
|
-
|
|
3198
|
+
logger20.debug("invalidateItemKeys", { keys });
|
|
3132
3199
|
if (keys.length === 0) {
|
|
3133
3200
|
return;
|
|
3134
3201
|
}
|
|
@@ -3178,7 +3245,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3178
3245
|
});
|
|
3179
3246
|
}
|
|
3180
3247
|
async invalidateLocation(locations) {
|
|
3181
|
-
|
|
3248
|
+
logger20.debug("invalidateLocation", { locations });
|
|
3182
3249
|
let keysToInvalidate = [];
|
|
3183
3250
|
if (locations.length === 0) {
|
|
3184
3251
|
const allKeys = await this.keys();
|
|
@@ -3198,7 +3265,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3198
3265
|
const itemKeysSize = estimateValueSize(entry.itemKeys);
|
|
3199
3266
|
const totalSize = hashSize + itemKeysSize;
|
|
3200
3267
|
this.queryResultsCacheSize += totalSize;
|
|
3201
|
-
|
|
3268
|
+
logger20.trace("Added query result to size tracking", {
|
|
3202
3269
|
queryHash,
|
|
3203
3270
|
estimatedSize: totalSize,
|
|
3204
3271
|
totalQueryCacheSize: this.queryResultsCacheSize
|
|
@@ -3214,7 +3281,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3214
3281
|
const itemKeysSize = estimateValueSize(entry.itemKeys);
|
|
3215
3282
|
const totalSize = hashSize + itemKeysSize;
|
|
3216
3283
|
this.queryResultsCacheSize = Math.max(0, this.queryResultsCacheSize - totalSize);
|
|
3217
|
-
|
|
3284
|
+
logger20.trace("Removed query result from size tracking", {
|
|
3218
3285
|
queryHash,
|
|
3219
3286
|
estimatedSize: totalSize,
|
|
3220
3287
|
totalQueryCacheSize: this.queryResultsCacheSize
|
|
@@ -3299,7 +3366,7 @@ import {
|
|
|
3299
3366
|
isComKey as isComKey3,
|
|
3300
3367
|
isQueryMatch as isQueryMatch3
|
|
3301
3368
|
} from "@fjell/core";
|
|
3302
|
-
var
|
|
3369
|
+
var logger21 = logger_default.get("LocalStorageCacheMap");
|
|
3303
3370
|
var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
3304
3371
|
implementationType = "browser/localStorage";
|
|
3305
3372
|
keyPrefix;
|
|
@@ -3314,6 +3381,10 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3314
3381
|
}
|
|
3315
3382
|
getStorageKey(key) {
|
|
3316
3383
|
const hashedKey = this.normalizedHashFunction(key);
|
|
3384
|
+
if (!hashedKey || typeof hashedKey !== "string" || hashedKey.trim() === "") {
|
|
3385
|
+
logger21.error("Invalid storage key generated from normalizedHashFunction", { key, hashedKey });
|
|
3386
|
+
throw new Error(`Invalid storage key generated for key: ${JSON.stringify(key)}`);
|
|
3387
|
+
}
|
|
3317
3388
|
return `${this.keyPrefix}:${hashedKey}`;
|
|
3318
3389
|
}
|
|
3319
3390
|
isQuotaExceededError(error) {
|
|
@@ -3330,7 +3401,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3330
3401
|
}
|
|
3331
3402
|
return keys;
|
|
3332
3403
|
} catch (error) {
|
|
3333
|
-
|
|
3404
|
+
logger21.error("Error getting keys by prefix from localStorage", { prefix, error });
|
|
3334
3405
|
throw error;
|
|
3335
3406
|
}
|
|
3336
3407
|
}
|
|
@@ -3338,12 +3409,12 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3338
3409
|
try {
|
|
3339
3410
|
const allEntries = this.collectCacheEntries();
|
|
3340
3411
|
if (allEntries.length === 0) {
|
|
3341
|
-
|
|
3412
|
+
logger21.debug("No entries to clean up");
|
|
3342
3413
|
return false;
|
|
3343
3414
|
}
|
|
3344
3415
|
return this.removeOldestEntries(allEntries, aggressive);
|
|
3345
3416
|
} catch (error) {
|
|
3346
|
-
|
|
3417
|
+
logger21.error("Failed to cleanup old localStorage entries", { error });
|
|
3347
3418
|
return false;
|
|
3348
3419
|
}
|
|
3349
3420
|
}
|
|
@@ -3369,7 +3440,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3369
3440
|
}
|
|
3370
3441
|
}
|
|
3371
3442
|
} catch (error) {
|
|
3372
|
-
|
|
3443
|
+
logger21.debug("Found corrupted entry during cleanup", { key, error });
|
|
3373
3444
|
allEntries.push({ key, timestamp: 0, size: 0 });
|
|
3374
3445
|
}
|
|
3375
3446
|
}
|
|
@@ -3388,12 +3459,12 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3388
3459
|
removedCount++;
|
|
3389
3460
|
removedSize += allEntries[i].size;
|
|
3390
3461
|
} catch (error) {
|
|
3391
|
-
|
|
3462
|
+
logger21.error("Failed to remove entry during cleanup", { key: allEntries[i].key, error });
|
|
3392
3463
|
}
|
|
3393
3464
|
}
|
|
3394
3465
|
if (removedCount > 0) {
|
|
3395
3466
|
const cleanupType = aggressive ? "aggressive" : "normal";
|
|
3396
|
-
|
|
3467
|
+
logger21.info(`Cleaned up ${removedCount} old localStorage entries (${removedSize} bytes) using ${cleanupType} cleanup to free space`);
|
|
3397
3468
|
}
|
|
3398
3469
|
return removedCount > 0;
|
|
3399
3470
|
}
|
|
@@ -3401,7 +3472,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3401
3472
|
return this.getAllKeysStartingWith(`${this.keyPrefix}:`);
|
|
3402
3473
|
}
|
|
3403
3474
|
async get(key) {
|
|
3404
|
-
|
|
3475
|
+
logger21.trace("get", { key });
|
|
3405
3476
|
try {
|
|
3406
3477
|
const storageKey = this.getStorageKey(key);
|
|
3407
3478
|
let stored = localStorage.getItem(storageKey);
|
|
@@ -3416,18 +3487,18 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3416
3487
|
return parsed.value;
|
|
3417
3488
|
}
|
|
3418
3489
|
} catch (parseError) {
|
|
3419
|
-
|
|
3490
|
+
logger21.debug("Failed to parse stored value", { key, error: parseError });
|
|
3420
3491
|
return null;
|
|
3421
3492
|
}
|
|
3422
3493
|
}
|
|
3423
3494
|
return null;
|
|
3424
3495
|
} catch (error) {
|
|
3425
|
-
|
|
3496
|
+
logger21.error("Error retrieving from localStorage", { key, error });
|
|
3426
3497
|
return null;
|
|
3427
3498
|
}
|
|
3428
3499
|
}
|
|
3429
3500
|
async set(key, value) {
|
|
3430
|
-
|
|
3501
|
+
logger21.trace("set", { key, value });
|
|
3431
3502
|
for (let attempt = 0; attempt < this.MAX_RETRY_ATTEMPTS; attempt++) {
|
|
3432
3503
|
try {
|
|
3433
3504
|
const storageKey = this.getStorageKey(key);
|
|
@@ -3438,12 +3509,12 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3438
3509
|
};
|
|
3439
3510
|
localStorage.setItem(storageKey, JSON.stringify(toStore));
|
|
3440
3511
|
if (attempt > 0) {
|
|
3441
|
-
|
|
3512
|
+
logger21.info(`Successfully stored item after ${attempt} retries`);
|
|
3442
3513
|
}
|
|
3443
3514
|
return;
|
|
3444
3515
|
} catch (error) {
|
|
3445
3516
|
const isLastAttempt = attempt === this.MAX_RETRY_ATTEMPTS - 1;
|
|
3446
|
-
|
|
3517
|
+
logger21.error(`Error storing to localStorage (attempt ${attempt + 1}/${this.MAX_RETRY_ATTEMPTS})`, {
|
|
3447
3518
|
key,
|
|
3448
3519
|
value,
|
|
3449
3520
|
error,
|
|
@@ -3470,30 +3541,30 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3470
3541
|
const parsed = JSON.parse(stored);
|
|
3471
3542
|
return this.normalizedHashFunction(parsed.originalKey) === this.normalizedHashFunction(key);
|
|
3472
3543
|
} catch (parseError) {
|
|
3473
|
-
|
|
3544
|
+
logger21.debug("Failed to parse stored value in includesKey", { key, error: parseError });
|
|
3474
3545
|
return false;
|
|
3475
3546
|
}
|
|
3476
3547
|
}
|
|
3477
3548
|
return false;
|
|
3478
3549
|
} catch (error) {
|
|
3479
|
-
|
|
3550
|
+
logger21.error("Error checking key in localStorage", { key, error });
|
|
3480
3551
|
return false;
|
|
3481
3552
|
}
|
|
3482
3553
|
}
|
|
3483
3554
|
async delete(key) {
|
|
3484
|
-
|
|
3555
|
+
logger21.trace("delete", { key });
|
|
3485
3556
|
try {
|
|
3486
3557
|
const storageKey = this.getStorageKey(key);
|
|
3487
3558
|
localStorage.removeItem(storageKey);
|
|
3488
3559
|
} catch (error) {
|
|
3489
|
-
|
|
3560
|
+
logger21.error("Error deleting from localStorage", { key, error });
|
|
3490
3561
|
throw error;
|
|
3491
3562
|
}
|
|
3492
3563
|
}
|
|
3493
3564
|
async allIn(locations) {
|
|
3494
3565
|
const allKeys = this.keys();
|
|
3495
3566
|
if (locations.length === 0) {
|
|
3496
|
-
|
|
3567
|
+
logger21.debug("Returning all items, LocKeys is empty");
|
|
3497
3568
|
const items = [];
|
|
3498
3569
|
for (const key of await allKeys) {
|
|
3499
3570
|
const item = await this.get(key);
|
|
@@ -3505,10 +3576,10 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3505
3576
|
} else {
|
|
3506
3577
|
const locKeys = locations;
|
|
3507
3578
|
const resolvedKeys = await allKeys;
|
|
3508
|
-
|
|
3579
|
+
logger21.debug("allIn", { locKeys, keys: resolvedKeys.length });
|
|
3509
3580
|
const filteredKeys = resolvedKeys.filter((key) => key && isComKey3(key)).filter((key) => {
|
|
3510
3581
|
const ComKey16 = key;
|
|
3511
|
-
|
|
3582
|
+
logger21.debug("Comparing Location Keys", {
|
|
3512
3583
|
locKeys,
|
|
3513
3584
|
ComKey: ComKey16
|
|
3514
3585
|
});
|
|
@@ -3525,12 +3596,12 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3525
3596
|
}
|
|
3526
3597
|
}
|
|
3527
3598
|
async contains(query, locations) {
|
|
3528
|
-
|
|
3599
|
+
logger21.debug("contains", { query, locations });
|
|
3529
3600
|
const items = await this.allIn(locations);
|
|
3530
3601
|
return items.some((item) => isQueryMatch3(item, query));
|
|
3531
3602
|
}
|
|
3532
3603
|
async queryIn(query, locations = []) {
|
|
3533
|
-
|
|
3604
|
+
logger21.debug("queryIn", { query, locations });
|
|
3534
3605
|
const items = await this.allIn(locations);
|
|
3535
3606
|
return items.filter((item) => isQueryMatch3(item, query));
|
|
3536
3607
|
}
|
|
@@ -3544,7 +3615,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3544
3615
|
return JSON.parse(stored);
|
|
3545
3616
|
}
|
|
3546
3617
|
} catch (parseError) {
|
|
3547
|
-
|
|
3618
|
+
logger21.debug("Skipping corrupted localStorage entry", { storageKey, error: parseError });
|
|
3548
3619
|
}
|
|
3549
3620
|
return null;
|
|
3550
3621
|
}
|
|
@@ -3559,7 +3630,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3559
3630
|
}
|
|
3560
3631
|
}
|
|
3561
3632
|
} catch (error) {
|
|
3562
|
-
|
|
3633
|
+
logger21.error("Error getting keys from localStorage", { error });
|
|
3563
3634
|
}
|
|
3564
3635
|
return keys;
|
|
3565
3636
|
}
|
|
@@ -3574,37 +3645,46 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3574
3645
|
}
|
|
3575
3646
|
}
|
|
3576
3647
|
} catch (error) {
|
|
3577
|
-
|
|
3648
|
+
logger21.error("Error getting values from localStorage", { error });
|
|
3578
3649
|
}
|
|
3579
3650
|
return values;
|
|
3580
3651
|
}
|
|
3581
3652
|
async clear() {
|
|
3582
|
-
|
|
3653
|
+
logger21.debug("Clearing localStorage cache");
|
|
3583
3654
|
try {
|
|
3584
3655
|
const storageKeys = this.getAllStorageKeys();
|
|
3585
3656
|
for (const storageKey of storageKeys) {
|
|
3586
3657
|
localStorage.removeItem(storageKey);
|
|
3587
3658
|
}
|
|
3588
3659
|
} catch (error) {
|
|
3589
|
-
|
|
3660
|
+
logger21.error("Error clearing localStorage cache", { error });
|
|
3590
3661
|
throw error;
|
|
3591
3662
|
}
|
|
3592
3663
|
}
|
|
3593
3664
|
// Query result caching methods implementation
|
|
3594
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
3595
|
-
|
|
3665
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
3666
|
+
logger21.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
3667
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3668
|
+
logger21.error("Invalid queryHash provided to setQueryResult", { queryHash, itemKeys });
|
|
3669
|
+
throw new Error(`Invalid queryHash: ${JSON.stringify(queryHash)}`);
|
|
3670
|
+
}
|
|
3596
3671
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3597
3672
|
const entry = {
|
|
3598
|
-
itemKeys
|
|
3673
|
+
itemKeys,
|
|
3674
|
+
metadata
|
|
3599
3675
|
};
|
|
3600
3676
|
try {
|
|
3601
3677
|
localStorage.setItem(queryKey, JSON.stringify(entry));
|
|
3602
3678
|
} catch (error) {
|
|
3603
|
-
|
|
3679
|
+
logger21.error("Failed to store query result in localStorage", { queryHash, error });
|
|
3604
3680
|
}
|
|
3605
3681
|
}
|
|
3606
3682
|
async getQueryResult(queryHash) {
|
|
3607
|
-
|
|
3683
|
+
logger21.trace("getQueryResult", { queryHash });
|
|
3684
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3685
|
+
logger21.error("Invalid queryHash provided to getQueryResult", { queryHash });
|
|
3686
|
+
return null;
|
|
3687
|
+
}
|
|
3608
3688
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3609
3689
|
try {
|
|
3610
3690
|
const data = localStorage.getItem(queryKey);
|
|
@@ -3617,30 +3697,71 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3617
3697
|
}
|
|
3618
3698
|
return entry.itemKeys || null;
|
|
3619
3699
|
} catch (error) {
|
|
3620
|
-
|
|
3700
|
+
logger21.error("Failed to retrieve query result from localStorage", { queryHash, error });
|
|
3701
|
+
return null;
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
3705
|
+
logger21.trace("getQueryResultWithMetadata", { queryHash });
|
|
3706
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3707
|
+
logger21.error("Invalid queryHash provided to getQueryResultWithMetadata", { queryHash });
|
|
3708
|
+
return null;
|
|
3709
|
+
}
|
|
3710
|
+
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3711
|
+
try {
|
|
3712
|
+
const data = localStorage.getItem(queryKey);
|
|
3713
|
+
if (!data) {
|
|
3714
|
+
return null;
|
|
3715
|
+
}
|
|
3716
|
+
const entry = JSON.parse(data);
|
|
3717
|
+
if (Array.isArray(entry)) {
|
|
3718
|
+
return { itemKeys: entry, metadata: void 0 };
|
|
3719
|
+
}
|
|
3720
|
+
if (entry.metadata) {
|
|
3721
|
+
if (entry.metadata.createdAt) {
|
|
3722
|
+
entry.metadata.createdAt = new Date(entry.metadata.createdAt);
|
|
3723
|
+
}
|
|
3724
|
+
if (entry.metadata.expiresAt) {
|
|
3725
|
+
entry.metadata.expiresAt = new Date(entry.metadata.expiresAt);
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
return {
|
|
3729
|
+
itemKeys: entry.itemKeys || [],
|
|
3730
|
+
metadata: entry.metadata
|
|
3731
|
+
};
|
|
3732
|
+
} catch (error) {
|
|
3733
|
+
logger21.error("Failed to retrieve query result with metadata from localStorage", { queryHash, error });
|
|
3621
3734
|
return null;
|
|
3622
3735
|
}
|
|
3623
3736
|
}
|
|
3624
3737
|
async hasQueryResult(queryHash) {
|
|
3738
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3739
|
+
logger21.error("Invalid queryHash provided to hasQueryResult", { queryHash });
|
|
3740
|
+
return false;
|
|
3741
|
+
}
|
|
3625
3742
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3626
3743
|
try {
|
|
3627
3744
|
return localStorage.getItem(queryKey) !== null;
|
|
3628
3745
|
} catch (error) {
|
|
3629
|
-
|
|
3746
|
+
logger21.error("Failed to check query result in localStorage", { queryHash, error });
|
|
3630
3747
|
return false;
|
|
3631
3748
|
}
|
|
3632
3749
|
}
|
|
3633
3750
|
async deleteQueryResult(queryHash) {
|
|
3634
|
-
|
|
3751
|
+
logger21.trace("deleteQueryResult", { queryHash });
|
|
3752
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3753
|
+
logger21.error("Invalid queryHash provided to deleteQueryResult", { queryHash });
|
|
3754
|
+
return;
|
|
3755
|
+
}
|
|
3635
3756
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3636
3757
|
try {
|
|
3637
3758
|
localStorage.removeItem(queryKey);
|
|
3638
3759
|
} catch (error) {
|
|
3639
|
-
|
|
3760
|
+
logger21.error("Failed to delete query result from localStorage", { queryHash, error });
|
|
3640
3761
|
}
|
|
3641
3762
|
}
|
|
3642
3763
|
async invalidateItemKeys(keys) {
|
|
3643
|
-
|
|
3764
|
+
logger21.debug("invalidateItemKeys", { keys });
|
|
3644
3765
|
if (keys.length === 0) {
|
|
3645
3766
|
return;
|
|
3646
3767
|
}
|
|
@@ -3678,24 +3799,24 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3678
3799
|
}
|
|
3679
3800
|
}
|
|
3680
3801
|
} catch (error) {
|
|
3681
|
-
|
|
3802
|
+
logger21.debug("Failed to parse query result", { queryKey, error });
|
|
3682
3803
|
}
|
|
3683
3804
|
}
|
|
3684
3805
|
queriesToRemove.forEach((queryKey) => {
|
|
3685
3806
|
localStorage.removeItem(queryKey);
|
|
3686
3807
|
});
|
|
3687
|
-
|
|
3808
|
+
logger21.debug("Selectively invalidated queries referencing affected keys", {
|
|
3688
3809
|
affectedKeys: keys.length,
|
|
3689
3810
|
queriesRemoved: queriesToRemove.length,
|
|
3690
3811
|
totalQueries: queryKeys.length
|
|
3691
3812
|
});
|
|
3692
3813
|
} catch (error) {
|
|
3693
|
-
|
|
3814
|
+
logger21.error("Error during selective query invalidation, falling back to clearing all queries", { error });
|
|
3694
3815
|
await this.clearQueryResults();
|
|
3695
3816
|
}
|
|
3696
3817
|
}
|
|
3697
3818
|
async invalidateLocation(locations) {
|
|
3698
|
-
|
|
3819
|
+
logger21.debug("invalidateLocation", { locations });
|
|
3699
3820
|
let keysToInvalidate = [];
|
|
3700
3821
|
if (locations.length === 0) {
|
|
3701
3822
|
const allKeys = await this.keys();
|
|
@@ -3710,7 +3831,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3710
3831
|
}
|
|
3711
3832
|
}
|
|
3712
3833
|
async clearQueryResults() {
|
|
3713
|
-
|
|
3834
|
+
logger21.trace("clearQueryResults");
|
|
3714
3835
|
const queryPrefix = `${this.keyPrefix}:query:`;
|
|
3715
3836
|
try {
|
|
3716
3837
|
const keysToRemove = this.getAllKeysStartingWith(queryPrefix);
|
|
@@ -3718,11 +3839,11 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3718
3839
|
try {
|
|
3719
3840
|
localStorage.removeItem(key);
|
|
3720
3841
|
} catch (error) {
|
|
3721
|
-
|
|
3842
|
+
logger21.error("Failed to remove query result from localStorage", { key, error });
|
|
3722
3843
|
}
|
|
3723
3844
|
}
|
|
3724
3845
|
} catch (error) {
|
|
3725
|
-
|
|
3846
|
+
logger21.error("Failed to clear query results from localStorage", { error });
|
|
3726
3847
|
}
|
|
3727
3848
|
}
|
|
3728
3849
|
// CacheMapMetadataProvider implementation
|
|
@@ -3734,13 +3855,13 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3734
3855
|
try {
|
|
3735
3856
|
return JSON.parse(stored);
|
|
3736
3857
|
} catch (e) {
|
|
3737
|
-
|
|
3858
|
+
logger21.debug("Invalid metadata JSON, treating as null", { key, error: e });
|
|
3738
3859
|
return null;
|
|
3739
3860
|
}
|
|
3740
3861
|
}
|
|
3741
3862
|
return null;
|
|
3742
3863
|
} catch (error) {
|
|
3743
|
-
|
|
3864
|
+
logger21.error("Error getting metadata from localStorage", { key, error });
|
|
3744
3865
|
throw error;
|
|
3745
3866
|
}
|
|
3746
3867
|
}
|
|
@@ -3750,12 +3871,12 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3750
3871
|
const metadataKey = `${this.keyPrefix}:metadata:${key}`;
|
|
3751
3872
|
localStorage.setItem(metadataKey, JSON.stringify(metadata));
|
|
3752
3873
|
if (attempt > 0) {
|
|
3753
|
-
|
|
3874
|
+
logger21.info(`Successfully stored metadata after ${attempt} retries`);
|
|
3754
3875
|
}
|
|
3755
3876
|
return;
|
|
3756
3877
|
} catch (error) {
|
|
3757
3878
|
const isLastAttempt = attempt === this.MAX_RETRY_ATTEMPTS - 1;
|
|
3758
|
-
|
|
3879
|
+
logger21.error(`Error storing metadata to localStorage (attempt ${attempt + 1}/${this.MAX_RETRY_ATTEMPTS})`, {
|
|
3759
3880
|
key,
|
|
3760
3881
|
error,
|
|
3761
3882
|
isLastAttempt
|
|
@@ -3777,7 +3898,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3777
3898
|
const metadataKey = `${this.keyPrefix}:metadata:${key}`;
|
|
3778
3899
|
localStorage.removeItem(metadataKey);
|
|
3779
3900
|
} catch (error) {
|
|
3780
|
-
|
|
3901
|
+
logger21.error("Error deleting metadata from localStorage", { key, error });
|
|
3781
3902
|
throw error;
|
|
3782
3903
|
}
|
|
3783
3904
|
}
|
|
@@ -3796,11 +3917,11 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3796
3917
|
metadata.set(metadataKey, parsed);
|
|
3797
3918
|
}
|
|
3798
3919
|
} catch (error) {
|
|
3799
|
-
|
|
3920
|
+
logger21.debug("Skipping invalid metadata entry", { key, error });
|
|
3800
3921
|
}
|
|
3801
3922
|
}
|
|
3802
3923
|
} catch (error) {
|
|
3803
|
-
|
|
3924
|
+
logger21.error("Error getting metadata from localStorage", { error });
|
|
3804
3925
|
throw error;
|
|
3805
3926
|
}
|
|
3806
3927
|
return metadata;
|
|
@@ -3811,7 +3932,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3811
3932
|
const keysToDelete = this.getAllKeysStartingWith(metadataPrefix);
|
|
3812
3933
|
keysToDelete.forEach((key) => localStorage.removeItem(key));
|
|
3813
3934
|
} catch (error) {
|
|
3814
|
-
|
|
3935
|
+
logger21.error("Error clearing metadata from localStorage", { error });
|
|
3815
3936
|
throw error;
|
|
3816
3937
|
}
|
|
3817
3938
|
}
|
|
@@ -3838,16 +3959,16 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3838
3959
|
itemCount++;
|
|
3839
3960
|
}
|
|
3840
3961
|
} catch (error) {
|
|
3841
|
-
|
|
3962
|
+
logger21.debug("Invalid entry in getCurrentSize", { key, error });
|
|
3842
3963
|
}
|
|
3843
3964
|
}
|
|
3844
3965
|
} catch (error) {
|
|
3845
|
-
|
|
3966
|
+
logger21.debug("Size calculation failed, using string length", { key, error });
|
|
3846
3967
|
sizeBytes += value.length;
|
|
3847
3968
|
}
|
|
3848
3969
|
}
|
|
3849
3970
|
} catch (error) {
|
|
3850
|
-
|
|
3971
|
+
logger21.error("Error calculating size from localStorage", { error });
|
|
3851
3972
|
throw error;
|
|
3852
3973
|
}
|
|
3853
3974
|
return { itemCount, sizeBytes };
|
|
@@ -3868,7 +3989,7 @@ import {
|
|
|
3868
3989
|
isQueryMatch as isQueryMatch4
|
|
3869
3990
|
} from "@fjell/core";
|
|
3870
3991
|
import safeStringify2 from "fast-safe-stringify";
|
|
3871
|
-
var
|
|
3992
|
+
var logger22 = logger_default.get("SessionStorageCacheMap");
|
|
3872
3993
|
var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
3873
3994
|
implementationType = "browser/sessionStorage";
|
|
3874
3995
|
keyPrefix;
|
|
@@ -3883,6 +4004,10 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3883
4004
|
}
|
|
3884
4005
|
getStorageKey(key) {
|
|
3885
4006
|
const hashedKey = this.normalizedHashFunction(key);
|
|
4007
|
+
if (!hashedKey || typeof hashedKey !== "string" || hashedKey.trim() === "") {
|
|
4008
|
+
logger22.error("Invalid storage key generated from normalizedHashFunction", { key, hashedKey });
|
|
4009
|
+
throw new Error(`Invalid storage key generated for key: ${JSON.stringify(key)}`);
|
|
4010
|
+
}
|
|
3886
4011
|
return `${this.keyPrefix}:${hashedKey}`;
|
|
3887
4012
|
}
|
|
3888
4013
|
// Using flatted for safe circular serialization; no manual replacer needed
|
|
@@ -3896,7 +4021,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3896
4021
|
}
|
|
3897
4022
|
}
|
|
3898
4023
|
} catch (error) {
|
|
3899
|
-
|
|
4024
|
+
logger22.error("Error getting keys from sessionStorage", { error });
|
|
3900
4025
|
}
|
|
3901
4026
|
return keys;
|
|
3902
4027
|
}
|
|
@@ -3919,7 +4044,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3919
4044
|
}
|
|
3920
4045
|
}
|
|
3921
4046
|
async get(key) {
|
|
3922
|
-
|
|
4047
|
+
logger22.trace("get", { key });
|
|
3923
4048
|
try {
|
|
3924
4049
|
const currentHash = this.normalizedHashFunction(key);
|
|
3925
4050
|
if (this.hasCollisionForHash(currentHash)) {
|
|
@@ -3939,14 +4064,14 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3939
4064
|
}
|
|
3940
4065
|
return null;
|
|
3941
4066
|
} catch (error) {
|
|
3942
|
-
|
|
4067
|
+
logger22.error("Error retrieving from sessionStorage", { key, error });
|
|
3943
4068
|
return null;
|
|
3944
4069
|
}
|
|
3945
4070
|
}
|
|
3946
4071
|
async set(key, value) {
|
|
3947
4072
|
try {
|
|
3948
4073
|
const storageKey = this.getStorageKey(key);
|
|
3949
|
-
|
|
4074
|
+
logger22.trace("set", { storageKey });
|
|
3950
4075
|
const toStore = {
|
|
3951
4076
|
originalKey: key,
|
|
3952
4077
|
value,
|
|
@@ -3956,7 +4081,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3956
4081
|
const jsonString = safeStringify2(toStore);
|
|
3957
4082
|
sessionStorage.setItem(storageKey, jsonString);
|
|
3958
4083
|
} catch (error) {
|
|
3959
|
-
|
|
4084
|
+
logger22.error("Error storing to sessionStorage", { errorMessage: error?.message });
|
|
3960
4085
|
throw new Error(`Failed to store item in sessionStorage: ${error}`);
|
|
3961
4086
|
}
|
|
3962
4087
|
}
|
|
@@ -3977,23 +4102,23 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
3977
4102
|
}
|
|
3978
4103
|
return false;
|
|
3979
4104
|
} catch (error) {
|
|
3980
|
-
|
|
4105
|
+
logger22.error("Error checking key in sessionStorage", { key, error });
|
|
3981
4106
|
return false;
|
|
3982
4107
|
}
|
|
3983
4108
|
}
|
|
3984
4109
|
async delete(key) {
|
|
3985
|
-
|
|
4110
|
+
logger22.trace("delete", { key });
|
|
3986
4111
|
try {
|
|
3987
4112
|
const storageKey = this.getStorageKey(key);
|
|
3988
4113
|
sessionStorage.removeItem(storageKey);
|
|
3989
4114
|
} catch (error) {
|
|
3990
|
-
|
|
4115
|
+
logger22.error("Error deleting from sessionStorage", { key, error });
|
|
3991
4116
|
}
|
|
3992
4117
|
}
|
|
3993
4118
|
async allIn(locations) {
|
|
3994
4119
|
const allKeys = this.keys();
|
|
3995
4120
|
if (locations.length === 0) {
|
|
3996
|
-
|
|
4121
|
+
logger22.debug("Returning all items, LocKeys is empty");
|
|
3997
4122
|
const items = [];
|
|
3998
4123
|
for (const key of await allKeys) {
|
|
3999
4124
|
const item = await this.get(key);
|
|
@@ -4005,10 +4130,10 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4005
4130
|
} else {
|
|
4006
4131
|
const locKeys = locations;
|
|
4007
4132
|
const resolvedKeys = await allKeys;
|
|
4008
|
-
|
|
4133
|
+
logger22.debug("allIn", { locKeys, keys: resolvedKeys.length });
|
|
4009
4134
|
const filteredKeys = resolvedKeys.filter((key) => key && isComKey4(key)).filter((key) => {
|
|
4010
4135
|
const ComKey16 = key;
|
|
4011
|
-
|
|
4136
|
+
logger22.debug("Comparing Location Keys", {
|
|
4012
4137
|
locKeys,
|
|
4013
4138
|
ComKey: ComKey16
|
|
4014
4139
|
});
|
|
@@ -4025,12 +4150,12 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4025
4150
|
}
|
|
4026
4151
|
}
|
|
4027
4152
|
async contains(query, locations) {
|
|
4028
|
-
|
|
4153
|
+
logger22.debug("contains", { query, locations });
|
|
4029
4154
|
const items = await this.allIn(locations);
|
|
4030
4155
|
return items.some((item) => isQueryMatch4(item, query));
|
|
4031
4156
|
}
|
|
4032
4157
|
async queryIn(query, locations = []) {
|
|
4033
|
-
|
|
4158
|
+
logger22.debug("queryIn", { query, locations });
|
|
4034
4159
|
const items = await this.allIn(locations);
|
|
4035
4160
|
return items.filter((item) => isQueryMatch4(item, query));
|
|
4036
4161
|
}
|
|
@@ -4050,11 +4175,11 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4050
4175
|
keys.push(parsed.originalKey);
|
|
4051
4176
|
}
|
|
4052
4177
|
} catch (itemError) {
|
|
4053
|
-
|
|
4178
|
+
logger22.trace("Skipping invalid storage item", { storageKey, error: itemError });
|
|
4054
4179
|
}
|
|
4055
4180
|
}
|
|
4056
4181
|
} catch (error) {
|
|
4057
|
-
|
|
4182
|
+
logger22.error("Error getting keys from sessionStorage", { error });
|
|
4058
4183
|
}
|
|
4059
4184
|
return keys;
|
|
4060
4185
|
}
|
|
@@ -4071,41 +4196,50 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4071
4196
|
values.push(parsed.value);
|
|
4072
4197
|
}
|
|
4073
4198
|
} catch (itemError) {
|
|
4074
|
-
|
|
4199
|
+
logger22.trace("Skipping invalid storage item for values", { storageKey, error: itemError });
|
|
4075
4200
|
}
|
|
4076
4201
|
}
|
|
4077
4202
|
} catch (error) {
|
|
4078
|
-
|
|
4203
|
+
logger22.error("Error getting values from sessionStorage", { error });
|
|
4079
4204
|
}
|
|
4080
4205
|
return values;
|
|
4081
4206
|
}
|
|
4082
4207
|
async clear() {
|
|
4083
|
-
|
|
4208
|
+
logger22.debug("Clearing sessionStorage cache");
|
|
4084
4209
|
try {
|
|
4085
4210
|
const storageKeys = this.getAllStorageKeys();
|
|
4086
4211
|
for (const storageKey of storageKeys) {
|
|
4087
4212
|
sessionStorage.removeItem(storageKey);
|
|
4088
4213
|
}
|
|
4089
4214
|
} catch (error) {
|
|
4090
|
-
|
|
4215
|
+
logger22.error("Error clearing sessionStorage cache", { error });
|
|
4091
4216
|
}
|
|
4092
4217
|
}
|
|
4093
4218
|
// Query result caching methods implementation
|
|
4094
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
4095
|
-
|
|
4219
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
4220
|
+
logger22.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
4221
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4222
|
+
logger22.error("Invalid queryHash provided to setQueryResult", { queryHash, itemKeys });
|
|
4223
|
+
throw new Error(`Invalid queryHash: ${JSON.stringify(queryHash)}`);
|
|
4224
|
+
}
|
|
4096
4225
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
4097
4226
|
const entry = {
|
|
4098
|
-
itemKeys
|
|
4227
|
+
itemKeys,
|
|
4228
|
+
metadata
|
|
4099
4229
|
};
|
|
4100
4230
|
try {
|
|
4101
4231
|
const jsonString = safeStringify2(entry);
|
|
4102
4232
|
sessionStorage.setItem(queryKey, jsonString);
|
|
4103
4233
|
} catch (error) {
|
|
4104
|
-
|
|
4234
|
+
logger22.error("Failed to store query result in sessionStorage", { queryHash, error });
|
|
4105
4235
|
}
|
|
4106
4236
|
}
|
|
4107
4237
|
async getQueryResult(queryHash) {
|
|
4108
|
-
|
|
4238
|
+
logger22.trace("getQueryResult", { queryHash });
|
|
4239
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4240
|
+
logger22.error("Invalid queryHash provided to getQueryResult", { queryHash });
|
|
4241
|
+
return null;
|
|
4242
|
+
}
|
|
4109
4243
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
4110
4244
|
try {
|
|
4111
4245
|
const data = sessionStorage.getItem(queryKey);
|
|
@@ -4118,30 +4252,71 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4118
4252
|
}
|
|
4119
4253
|
return entry.itemKeys || null;
|
|
4120
4254
|
} catch (error) {
|
|
4121
|
-
|
|
4255
|
+
logger22.error("Failed to retrieve query result from sessionStorage", { queryHash, error });
|
|
4256
|
+
return null;
|
|
4257
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
4260
|
+
logger22.trace("getQueryResultWithMetadata", { queryHash });
|
|
4261
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4262
|
+
logger22.error("Invalid queryHash provided to getQueryResultWithMetadata", { queryHash });
|
|
4263
|
+
return null;
|
|
4264
|
+
}
|
|
4265
|
+
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
4266
|
+
try {
|
|
4267
|
+
const data = sessionStorage.getItem(queryKey);
|
|
4268
|
+
if (!data) {
|
|
4269
|
+
return null;
|
|
4270
|
+
}
|
|
4271
|
+
const entry = JSON.parse(data);
|
|
4272
|
+
if (Array.isArray(entry)) {
|
|
4273
|
+
return { itemKeys: entry, metadata: void 0 };
|
|
4274
|
+
}
|
|
4275
|
+
if (entry.metadata) {
|
|
4276
|
+
if (entry.metadata.createdAt) {
|
|
4277
|
+
entry.metadata.createdAt = new Date(entry.metadata.createdAt);
|
|
4278
|
+
}
|
|
4279
|
+
if (entry.metadata.expiresAt) {
|
|
4280
|
+
entry.metadata.expiresAt = new Date(entry.metadata.expiresAt);
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
return {
|
|
4284
|
+
itemKeys: entry.itemKeys || [],
|
|
4285
|
+
metadata: entry.metadata
|
|
4286
|
+
};
|
|
4287
|
+
} catch (error) {
|
|
4288
|
+
logger22.error("Failed to retrieve query result with metadata from sessionStorage", { queryHash, error });
|
|
4122
4289
|
return null;
|
|
4123
4290
|
}
|
|
4124
4291
|
}
|
|
4125
4292
|
async hasQueryResult(queryHash) {
|
|
4293
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4294
|
+
logger22.error("Invalid queryHash provided to hasQueryResult", { queryHash });
|
|
4295
|
+
return false;
|
|
4296
|
+
}
|
|
4126
4297
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
4127
4298
|
try {
|
|
4128
4299
|
return sessionStorage.getItem(queryKey) !== null;
|
|
4129
4300
|
} catch (error) {
|
|
4130
|
-
|
|
4301
|
+
logger22.error("Failed to check query result in sessionStorage", { queryHash, error });
|
|
4131
4302
|
return false;
|
|
4132
4303
|
}
|
|
4133
4304
|
}
|
|
4134
4305
|
async deleteQueryResult(queryHash) {
|
|
4135
|
-
|
|
4306
|
+
logger22.trace("deleteQueryResult", { queryHash });
|
|
4307
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4308
|
+
logger22.error("Invalid queryHash provided to deleteQueryResult", { queryHash });
|
|
4309
|
+
return;
|
|
4310
|
+
}
|
|
4136
4311
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
4137
4312
|
try {
|
|
4138
4313
|
sessionStorage.removeItem(queryKey);
|
|
4139
4314
|
} catch (error) {
|
|
4140
|
-
|
|
4315
|
+
logger22.error("Failed to delete query result from sessionStorage", { queryHash, error });
|
|
4141
4316
|
}
|
|
4142
4317
|
}
|
|
4143
4318
|
async clearQueryResults() {
|
|
4144
|
-
|
|
4319
|
+
logger22.trace("clearQueryResults");
|
|
4145
4320
|
const queryPrefix = `${this.keyPrefix}:query:`;
|
|
4146
4321
|
try {
|
|
4147
4322
|
const keysToRemove = [];
|
|
@@ -4153,7 +4328,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4153
4328
|
}
|
|
4154
4329
|
keysToRemove.forEach((key) => sessionStorage.removeItem(key));
|
|
4155
4330
|
} catch (error) {
|
|
4156
|
-
|
|
4331
|
+
logger22.error("Failed to clear query results from sessionStorage", { error });
|
|
4157
4332
|
}
|
|
4158
4333
|
}
|
|
4159
4334
|
// CacheMapMetadataProvider implementation
|
|
@@ -4200,7 +4375,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4200
4375
|
}
|
|
4201
4376
|
return metadata;
|
|
4202
4377
|
} catch (error) {
|
|
4203
|
-
|
|
4378
|
+
logger22.error("Error getting all metadata from sessionStorage", { error });
|
|
4204
4379
|
return metadata;
|
|
4205
4380
|
}
|
|
4206
4381
|
}
|
|
@@ -4220,7 +4395,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4220
4395
|
}
|
|
4221
4396
|
// Invalidation methods
|
|
4222
4397
|
async invalidateItemKeys(keys) {
|
|
4223
|
-
|
|
4398
|
+
logger22.debug("invalidateItemKeys", { keys });
|
|
4224
4399
|
if (keys.length === 0) {
|
|
4225
4400
|
return;
|
|
4226
4401
|
}
|
|
@@ -4264,24 +4439,24 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4264
4439
|
}
|
|
4265
4440
|
}
|
|
4266
4441
|
} catch (error) {
|
|
4267
|
-
|
|
4442
|
+
logger22.debug("Failed to parse query result", { queryKey, error });
|
|
4268
4443
|
}
|
|
4269
4444
|
}
|
|
4270
4445
|
queriesToRemove.forEach((queryKey) => {
|
|
4271
4446
|
sessionStorage.removeItem(queryKey);
|
|
4272
4447
|
});
|
|
4273
|
-
|
|
4448
|
+
logger22.debug("Selectively invalidated queries referencing affected keys", {
|
|
4274
4449
|
affectedKeys: keys.length,
|
|
4275
4450
|
queriesRemoved: queriesToRemove.length,
|
|
4276
4451
|
totalQueries: queryKeys.length
|
|
4277
4452
|
});
|
|
4278
4453
|
} catch (error) {
|
|
4279
|
-
|
|
4454
|
+
logger22.error("Error during selective query invalidation, falling back to clearing all queries", { error });
|
|
4280
4455
|
await this.clearQueryResults();
|
|
4281
4456
|
}
|
|
4282
4457
|
}
|
|
4283
4458
|
async invalidateLocation(locations) {
|
|
4284
|
-
|
|
4459
|
+
logger22.debug("invalidateLocation", { locations });
|
|
4285
4460
|
let keysToInvalidate = [];
|
|
4286
4461
|
if (locations.length === 0) {
|
|
4287
4462
|
const allKeys = await this.keys();
|
|
@@ -4347,7 +4522,7 @@ import {
|
|
|
4347
4522
|
isQueryMatch as isQueryMatch5
|
|
4348
4523
|
} from "@fjell/core";
|
|
4349
4524
|
import safeStringify3 from "fast-safe-stringify";
|
|
4350
|
-
var
|
|
4525
|
+
var logger23 = logger_default.get("AsyncIndexDBCacheMap");
|
|
4351
4526
|
var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
4352
4527
|
types;
|
|
4353
4528
|
dbName;
|
|
@@ -4373,19 +4548,19 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4373
4548
|
}
|
|
4374
4549
|
const request = indexedDB.open(this.dbName, this.version);
|
|
4375
4550
|
request.onerror = () => {
|
|
4376
|
-
|
|
4551
|
+
logger23.error("Error opening IndexedDB", { error: request.error });
|
|
4377
4552
|
reject(request.error);
|
|
4378
4553
|
};
|
|
4379
4554
|
request.onsuccess = () => {
|
|
4380
|
-
|
|
4555
|
+
logger23.debug("IndexedDB opened successfully");
|
|
4381
4556
|
resolve(request.result);
|
|
4382
4557
|
};
|
|
4383
4558
|
request.onupgradeneeded = (event) => {
|
|
4384
|
-
|
|
4559
|
+
logger23.debug("IndexedDB upgrade needed");
|
|
4385
4560
|
const db = event.target.result;
|
|
4386
4561
|
if (!db.objectStoreNames.contains(this.storeName)) {
|
|
4387
4562
|
db.createObjectStore(this.storeName);
|
|
4388
|
-
|
|
4563
|
+
logger23.debug("Created object store", { storeName: this.storeName });
|
|
4389
4564
|
}
|
|
4390
4565
|
};
|
|
4391
4566
|
});
|
|
@@ -4393,32 +4568,48 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4393
4568
|
return this.dbPromise;
|
|
4394
4569
|
}
|
|
4395
4570
|
getStorageKey(key) {
|
|
4396
|
-
|
|
4571
|
+
const storageKey = this.normalizedHashFunction(key);
|
|
4572
|
+
if (!storageKey || typeof storageKey !== "string" || storageKey.trim() === "") {
|
|
4573
|
+
logger23.error("Invalid storage key generated from normalizedHashFunction", { key, storageKey });
|
|
4574
|
+
throw new Error(`Invalid storage key generated for key: ${JSON.stringify(key)}`);
|
|
4575
|
+
}
|
|
4576
|
+
return storageKey;
|
|
4397
4577
|
}
|
|
4398
4578
|
async get(key) {
|
|
4399
|
-
|
|
4579
|
+
logger23.trace("get", { key });
|
|
4400
4580
|
try {
|
|
4401
4581
|
const db = await this.getDB();
|
|
4402
4582
|
const transaction = db.transaction([this.storeName], "readonly");
|
|
4403
4583
|
const store = transaction.objectStore(this.storeName);
|
|
4404
|
-
|
|
4584
|
+
let storageKey;
|
|
4585
|
+
try {
|
|
4586
|
+
storageKey = this.getStorageKey(key);
|
|
4587
|
+
} catch (keyError) {
|
|
4588
|
+
logger23.error("Failed to generate storage key", { key, error: keyError });
|
|
4589
|
+
return null;
|
|
4590
|
+
}
|
|
4405
4591
|
return new Promise((resolve, reject) => {
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4592
|
+
try {
|
|
4593
|
+
const request = store.get(storageKey);
|
|
4594
|
+
request.onerror = () => {
|
|
4595
|
+
logger23.error("Error getting from IndexedDB", { key, storageKey, error: request.error });
|
|
4596
|
+
reject(request.error);
|
|
4597
|
+
};
|
|
4598
|
+
request.onsuccess = () => {
|
|
4599
|
+
const stored = request.result;
|
|
4600
|
+
if (stored && this.normalizedHashFunction(stored.originalKey) === this.normalizedHashFunction(key)) {
|
|
4601
|
+
resolve(stored.value);
|
|
4602
|
+
} else {
|
|
4603
|
+
resolve(null);
|
|
4604
|
+
}
|
|
4605
|
+
};
|
|
4606
|
+
} catch (requestError) {
|
|
4607
|
+
logger23.error("Error creating IndexedDB request", { key, storageKey, error: requestError });
|
|
4608
|
+
reject(requestError);
|
|
4609
|
+
}
|
|
4419
4610
|
});
|
|
4420
4611
|
} catch (error) {
|
|
4421
|
-
|
|
4612
|
+
logger23.error("Error in IndexedDB get operation", { key, error });
|
|
4422
4613
|
return null;
|
|
4423
4614
|
}
|
|
4424
4615
|
}
|
|
@@ -4426,42 +4617,59 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4426
4617
|
* Get both the value and metadata for an item
|
|
4427
4618
|
*/
|
|
4428
4619
|
async getWithMetadata(key) {
|
|
4429
|
-
|
|
4620
|
+
logger23.trace("getWithMetadata", { key });
|
|
4430
4621
|
try {
|
|
4431
4622
|
const db = await this.getDB();
|
|
4432
4623
|
const transaction = db.transaction([this.storeName], "readonly");
|
|
4433
4624
|
const store = transaction.objectStore(this.storeName);
|
|
4434
|
-
|
|
4625
|
+
let storageKey;
|
|
4626
|
+
try {
|
|
4627
|
+
storageKey = this.getStorageKey(key);
|
|
4628
|
+
} catch (keyError) {
|
|
4629
|
+
logger23.error("Failed to generate storage key for getWithMetadata", { key, error: keyError });
|
|
4630
|
+
return null;
|
|
4631
|
+
}
|
|
4435
4632
|
return new Promise((resolve, reject) => {
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4633
|
+
try {
|
|
4634
|
+
const request = store.get(storageKey);
|
|
4635
|
+
request.onerror = () => {
|
|
4636
|
+
logger23.error("Error getting from IndexedDB", { key, storageKey, error: request.error });
|
|
4637
|
+
reject(request.error);
|
|
4638
|
+
};
|
|
4639
|
+
request.onsuccess = () => {
|
|
4640
|
+
const stored = request.result;
|
|
4641
|
+
if (stored && this.normalizedHashFunction(stored.originalKey) === this.normalizedHashFunction(key)) {
|
|
4642
|
+
resolve({
|
|
4643
|
+
value: stored.value,
|
|
4644
|
+
metadata: stored.metadata
|
|
4645
|
+
});
|
|
4646
|
+
} else {
|
|
4647
|
+
resolve(null);
|
|
4648
|
+
}
|
|
4649
|
+
};
|
|
4650
|
+
} catch (requestError) {
|
|
4651
|
+
logger23.error("Error creating IndexedDB request for getWithMetadata", { key, storageKey, error: requestError });
|
|
4652
|
+
reject(requestError);
|
|
4653
|
+
}
|
|
4452
4654
|
});
|
|
4453
4655
|
} catch (error) {
|
|
4454
|
-
|
|
4656
|
+
logger23.error("Error in IndexedDB getWithMetadata operation", { key, error });
|
|
4455
4657
|
return null;
|
|
4456
4658
|
}
|
|
4457
4659
|
}
|
|
4458
4660
|
async set(key, value, metadata) {
|
|
4459
|
-
|
|
4661
|
+
logger23.trace("set", { key, value, hasMetadata: !!metadata });
|
|
4460
4662
|
try {
|
|
4461
4663
|
const db = await this.getDB();
|
|
4462
4664
|
const transaction = db.transaction([this.storeName], "readwrite");
|
|
4463
4665
|
const store = transaction.objectStore(this.storeName);
|
|
4464
|
-
|
|
4666
|
+
let storageKey;
|
|
4667
|
+
try {
|
|
4668
|
+
storageKey = this.getStorageKey(key);
|
|
4669
|
+
} catch (keyError) {
|
|
4670
|
+
logger23.error("Failed to generate storage key for set", { key, error: keyError });
|
|
4671
|
+
throw new Error(`Failed to generate storage key: ${keyError}`);
|
|
4672
|
+
}
|
|
4465
4673
|
const storedItem = {
|
|
4466
4674
|
originalKey: key,
|
|
4467
4675
|
value,
|
|
@@ -4469,17 +4677,22 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4469
4677
|
version: _AsyncIndexDBCacheMap.CURRENT_VERSION
|
|
4470
4678
|
};
|
|
4471
4679
|
return new Promise((resolve, reject) => {
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4680
|
+
try {
|
|
4681
|
+
const request = store.put(storedItem, storageKey);
|
|
4682
|
+
request.onerror = () => {
|
|
4683
|
+
logger23.error("Error setting in IndexedDB", { key, storageKey, value, error: request.error });
|
|
4684
|
+
reject(request.error);
|
|
4685
|
+
};
|
|
4686
|
+
request.onsuccess = () => {
|
|
4687
|
+
resolve();
|
|
4688
|
+
};
|
|
4689
|
+
} catch (requestError) {
|
|
4690
|
+
logger23.error("Error creating IndexedDB put request", { key, storageKey, error: requestError });
|
|
4691
|
+
reject(requestError);
|
|
4692
|
+
}
|
|
4480
4693
|
});
|
|
4481
4694
|
} catch (error) {
|
|
4482
|
-
|
|
4695
|
+
logger23.error("Error in IndexedDB set operation", { key, value, error });
|
|
4483
4696
|
throw new Error(`Failed to store item in IndexedDB: ${error}`);
|
|
4484
4697
|
}
|
|
4485
4698
|
}
|
|
@@ -4487,16 +4700,16 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4487
4700
|
* Update only the metadata for an existing item
|
|
4488
4701
|
*/
|
|
4489
4702
|
async setMetadata(key, metadata) {
|
|
4490
|
-
|
|
4703
|
+
logger23.trace("setMetadata", { key, metadata });
|
|
4491
4704
|
try {
|
|
4492
4705
|
const existing = await this.getWithMetadata(key);
|
|
4493
4706
|
if (existing) {
|
|
4494
4707
|
await this.set(key, existing.value, metadata);
|
|
4495
4708
|
} else {
|
|
4496
|
-
|
|
4709
|
+
logger23.warning("Attempted to set metadata for non-existent item", { key });
|
|
4497
4710
|
}
|
|
4498
4711
|
} catch (error) {
|
|
4499
|
-
|
|
4712
|
+
logger23.error("Error in IndexedDB setMetadata operation", { key, error });
|
|
4500
4713
|
throw new Error(`Failed to update metadata in IndexedDB: ${error}`);
|
|
4501
4714
|
}
|
|
4502
4715
|
}
|
|
@@ -4505,62 +4718,84 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4505
4718
|
const db = await this.getDB();
|
|
4506
4719
|
const transaction = db.transaction([this.storeName], "readonly");
|
|
4507
4720
|
const store = transaction.objectStore(this.storeName);
|
|
4508
|
-
|
|
4721
|
+
let storageKey;
|
|
4722
|
+
try {
|
|
4723
|
+
storageKey = this.getStorageKey(key);
|
|
4724
|
+
} catch (keyError) {
|
|
4725
|
+
logger23.error("Failed to generate storage key for includesKey", { key, error: keyError });
|
|
4726
|
+
return false;
|
|
4727
|
+
}
|
|
4509
4728
|
return new Promise((resolve, reject) => {
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4729
|
+
try {
|
|
4730
|
+
const request = store.get(storageKey);
|
|
4731
|
+
request.onerror = () => {
|
|
4732
|
+
logger23.error("Error checking key in IndexedDB", { key, storageKey, error: request.error });
|
|
4733
|
+
reject(request.error);
|
|
4734
|
+
};
|
|
4735
|
+
request.onsuccess = () => {
|
|
4736
|
+
const stored = request.result;
|
|
4737
|
+
if (stored) {
|
|
4738
|
+
const matches = this.normalizedHashFunction(stored.originalKey) === this.normalizedHashFunction(key);
|
|
4739
|
+
resolve(matches);
|
|
4740
|
+
} else {
|
|
4741
|
+
resolve(false);
|
|
4742
|
+
}
|
|
4743
|
+
};
|
|
4744
|
+
} catch (requestError) {
|
|
4745
|
+
logger23.error("Error creating IndexedDB request for includesKey", { key, storageKey, error: requestError });
|
|
4746
|
+
reject(requestError);
|
|
4747
|
+
}
|
|
4524
4748
|
});
|
|
4525
4749
|
} catch (error) {
|
|
4526
|
-
|
|
4750
|
+
logger23.error("Error in IndexedDB includesKey operation", { key, error });
|
|
4527
4751
|
return false;
|
|
4528
4752
|
}
|
|
4529
4753
|
}
|
|
4530
4754
|
async delete(key) {
|
|
4531
|
-
|
|
4755
|
+
logger23.trace("delete", { key });
|
|
4532
4756
|
try {
|
|
4533
4757
|
const db = await this.getDB();
|
|
4534
4758
|
const transaction = db.transaction([this.storeName], "readwrite");
|
|
4535
4759
|
const store = transaction.objectStore(this.storeName);
|
|
4536
|
-
|
|
4760
|
+
let storageKey;
|
|
4761
|
+
try {
|
|
4762
|
+
storageKey = this.getStorageKey(key);
|
|
4763
|
+
} catch (keyError) {
|
|
4764
|
+
logger23.error("Failed to generate storage key for delete", { key, error: keyError });
|
|
4765
|
+
return;
|
|
4766
|
+
}
|
|
4537
4767
|
return new Promise((resolve, reject) => {
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4768
|
+
try {
|
|
4769
|
+
const request = store.delete(storageKey);
|
|
4770
|
+
request.onerror = () => {
|
|
4771
|
+
logger23.error("Error deleting from IndexedDB", { key, storageKey, error: request.error });
|
|
4772
|
+
reject(request.error);
|
|
4773
|
+
};
|
|
4774
|
+
request.onsuccess = () => {
|
|
4775
|
+
resolve();
|
|
4776
|
+
};
|
|
4777
|
+
} catch (requestError) {
|
|
4778
|
+
logger23.error("Error creating IndexedDB delete request", { key, storageKey, error: requestError });
|
|
4779
|
+
reject(requestError);
|
|
4780
|
+
}
|
|
4546
4781
|
});
|
|
4547
4782
|
} catch (error) {
|
|
4548
|
-
|
|
4783
|
+
logger23.error("Error in IndexedDB delete operation", { key, error });
|
|
4549
4784
|
}
|
|
4550
4785
|
}
|
|
4551
4786
|
async allIn(locations) {
|
|
4552
4787
|
const allKeys = await this.keys();
|
|
4553
4788
|
if (locations.length === 0) {
|
|
4554
|
-
|
|
4789
|
+
logger23.debug("Returning all items, LocKeys is empty");
|
|
4555
4790
|
const promises = allKeys.map((key) => this.get(key));
|
|
4556
4791
|
const results = await Promise.all(promises);
|
|
4557
4792
|
return results.filter((item) => item !== null);
|
|
4558
4793
|
} else {
|
|
4559
4794
|
const locKeys = locations;
|
|
4560
|
-
|
|
4795
|
+
logger23.debug("allIn", { locKeys, keys: allKeys.length });
|
|
4561
4796
|
const filteredKeys = allKeys.filter((key) => key && isComKey5(key)).filter((key) => {
|
|
4562
4797
|
const ComKey16 = key;
|
|
4563
|
-
|
|
4798
|
+
logger23.debug("Comparing Location Keys", {
|
|
4564
4799
|
locKeys,
|
|
4565
4800
|
ComKey: ComKey16
|
|
4566
4801
|
});
|
|
@@ -4572,12 +4807,12 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4572
4807
|
}
|
|
4573
4808
|
}
|
|
4574
4809
|
async contains(query, locations) {
|
|
4575
|
-
|
|
4810
|
+
logger23.debug("contains", { query, locations });
|
|
4576
4811
|
const items = await this.allIn(locations);
|
|
4577
4812
|
return items.some((item) => isQueryMatch5(item, query));
|
|
4578
4813
|
}
|
|
4579
4814
|
async queryIn(query, locations = []) {
|
|
4580
|
-
|
|
4815
|
+
logger23.debug("queryIn", { query, locations });
|
|
4581
4816
|
const items = await this.allIn(locations);
|
|
4582
4817
|
return items.filter((item) => isQueryMatch5(item, query));
|
|
4583
4818
|
}
|
|
@@ -4593,7 +4828,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4593
4828
|
return new Promise((resolve, reject) => {
|
|
4594
4829
|
const request = store.openCursor();
|
|
4595
4830
|
request.onerror = () => {
|
|
4596
|
-
|
|
4831
|
+
logger23.error("Error getting keys from IndexedDB", { error: request.error });
|
|
4597
4832
|
reject(request.error);
|
|
4598
4833
|
};
|
|
4599
4834
|
request.onsuccess = (event) => {
|
|
@@ -4608,7 +4843,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4608
4843
|
};
|
|
4609
4844
|
});
|
|
4610
4845
|
} catch (error) {
|
|
4611
|
-
|
|
4846
|
+
logger23.error("Error in IndexedDB keys operation", { error });
|
|
4612
4847
|
return [];
|
|
4613
4848
|
}
|
|
4614
4849
|
}
|
|
@@ -4624,7 +4859,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4624
4859
|
return new Promise((resolve, reject) => {
|
|
4625
4860
|
const request = store.openCursor();
|
|
4626
4861
|
request.onerror = () => {
|
|
4627
|
-
|
|
4862
|
+
logger23.error("Error getting metadata from IndexedDB", { error: request.error });
|
|
4628
4863
|
reject(request.error);
|
|
4629
4864
|
};
|
|
4630
4865
|
request.onsuccess = (event) => {
|
|
@@ -4642,7 +4877,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4642
4877
|
};
|
|
4643
4878
|
});
|
|
4644
4879
|
} catch (error) {
|
|
4645
|
-
|
|
4880
|
+
logger23.error("Error in IndexedDB getAllMetadata operation", { error });
|
|
4646
4881
|
return metadataMap;
|
|
4647
4882
|
}
|
|
4648
4883
|
}
|
|
@@ -4655,7 +4890,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4655
4890
|
return new Promise((resolve, reject) => {
|
|
4656
4891
|
const request = store.openCursor();
|
|
4657
4892
|
request.onerror = () => {
|
|
4658
|
-
|
|
4893
|
+
logger23.error("Error getting values from IndexedDB", { error: request.error });
|
|
4659
4894
|
reject(request.error);
|
|
4660
4895
|
};
|
|
4661
4896
|
request.onsuccess = (event) => {
|
|
@@ -4670,12 +4905,12 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4670
4905
|
};
|
|
4671
4906
|
});
|
|
4672
4907
|
} catch (error) {
|
|
4673
|
-
|
|
4908
|
+
logger23.error("Error in IndexedDB values operation", { error });
|
|
4674
4909
|
return [];
|
|
4675
4910
|
}
|
|
4676
4911
|
}
|
|
4677
4912
|
async clear() {
|
|
4678
|
-
|
|
4913
|
+
logger23.debug("Clearing IndexedDB cache");
|
|
4679
4914
|
try {
|
|
4680
4915
|
const db = await this.getDB();
|
|
4681
4916
|
const transaction = db.transaction([this.storeName], "readwrite");
|
|
@@ -4683,7 +4918,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4683
4918
|
return new Promise((resolve, reject) => {
|
|
4684
4919
|
const request = store.clear();
|
|
4685
4920
|
request.onerror = () => {
|
|
4686
|
-
|
|
4921
|
+
logger23.error("Error clearing IndexedDB cache", { error: request.error });
|
|
4687
4922
|
reject(request.error);
|
|
4688
4923
|
};
|
|
4689
4924
|
request.onsuccess = () => {
|
|
@@ -4691,59 +4926,61 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4691
4926
|
};
|
|
4692
4927
|
});
|
|
4693
4928
|
} catch (error) {
|
|
4694
|
-
|
|
4929
|
+
logger23.error("Error in IndexedDB clear operation", { error });
|
|
4695
4930
|
}
|
|
4696
4931
|
}
|
|
4697
4932
|
// Async Query result caching methods
|
|
4698
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
4699
|
-
|
|
4933
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
4934
|
+
logger23.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
4935
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4936
|
+
logger23.error("Invalid queryHash provided to setQueryResult", { queryHash, itemKeys });
|
|
4937
|
+
throw new Error(`Invalid queryHash: ${JSON.stringify(queryHash)}`);
|
|
4938
|
+
}
|
|
4700
4939
|
try {
|
|
4940
|
+
const db = await this.getDB();
|
|
4941
|
+
const transaction = db.transaction([this.storeName], "readwrite");
|
|
4942
|
+
const store = transaction.objectStore(this.storeName);
|
|
4943
|
+
const entry = {
|
|
4944
|
+
itemKeys,
|
|
4945
|
+
metadata: metadata || void 0
|
|
4946
|
+
};
|
|
4947
|
+
const queryKey = `query:${queryHash}`;
|
|
4701
4948
|
return new Promise((resolve, reject) => {
|
|
4702
|
-
|
|
4703
|
-
request.onerror = () => {
|
|
4704
|
-
logger21.error("Failed to open database for setQueryResult", { error: request.error });
|
|
4705
|
-
reject(request.error);
|
|
4706
|
-
};
|
|
4707
|
-
request.onsuccess = () => {
|
|
4708
|
-
const db = request.result;
|
|
4709
|
-
const transaction = db.transaction([this.storeName], "readwrite");
|
|
4710
|
-
const store = transaction.objectStore(this.storeName);
|
|
4711
|
-
const entry = {
|
|
4712
|
-
itemKeys
|
|
4713
|
-
};
|
|
4714
|
-
const queryKey = `query:${queryHash}`;
|
|
4949
|
+
try {
|
|
4715
4950
|
const putRequest = store.put(safeStringify3(entry), queryKey);
|
|
4716
4951
|
putRequest.onerror = () => {
|
|
4717
|
-
|
|
4952
|
+
logger23.error("Failed to store query result", { queryHash, error: putRequest.error });
|
|
4718
4953
|
reject(putRequest.error);
|
|
4719
4954
|
};
|
|
4720
4955
|
putRequest.onsuccess = () => {
|
|
4721
4956
|
resolve();
|
|
4722
4957
|
};
|
|
4723
|
-
}
|
|
4958
|
+
} catch (requestError) {
|
|
4959
|
+
logger23.error("Error creating IndexedDB put request for query result", { queryHash, queryKey, error: requestError });
|
|
4960
|
+
reject(requestError);
|
|
4961
|
+
}
|
|
4724
4962
|
});
|
|
4725
4963
|
} catch (error) {
|
|
4726
|
-
|
|
4964
|
+
logger23.error("Error in setQueryResult", { queryHash, error });
|
|
4727
4965
|
throw error;
|
|
4728
4966
|
}
|
|
4729
4967
|
}
|
|
4730
4968
|
async getQueryResult(queryHash) {
|
|
4731
|
-
|
|
4969
|
+
logger23.trace("getQueryResult", { queryHash });
|
|
4970
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
4971
|
+
logger23.error("Invalid queryHash provided to getQueryResult", { queryHash });
|
|
4972
|
+
return null;
|
|
4973
|
+
}
|
|
4732
4974
|
try {
|
|
4975
|
+
const db = await this.getDB();
|
|
4976
|
+
const transaction = db.transaction([this.storeName], "readonly");
|
|
4977
|
+
const store = transaction.objectStore(this.storeName);
|
|
4978
|
+
const queryKey = `query:${queryHash}`;
|
|
4733
4979
|
return new Promise((resolve, reject) => {
|
|
4734
|
-
|
|
4735
|
-
request.onerror = () => {
|
|
4736
|
-
logger21.error("Failed to open database for getQueryResult", { error: request.error });
|
|
4737
|
-
reject(request.error);
|
|
4738
|
-
};
|
|
4739
|
-
request.onsuccess = () => {
|
|
4740
|
-
const db = request.result;
|
|
4741
|
-
const transaction = db.transaction([this.storeName], "readonly");
|
|
4742
|
-
const store = transaction.objectStore(this.storeName);
|
|
4743
|
-
const queryKey = `query:${queryHash}`;
|
|
4980
|
+
try {
|
|
4744
4981
|
const getRequest = store.get(queryKey);
|
|
4745
4982
|
getRequest.onerror = () => {
|
|
4746
|
-
|
|
4983
|
+
logger23.error("Failed to retrieve query result", { queryHash, error: getRequest.error });
|
|
4747
4984
|
reject(getRequest.error);
|
|
4748
4985
|
};
|
|
4749
4986
|
getRequest.onsuccess = () => {
|
|
@@ -4760,58 +4997,120 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4760
4997
|
}
|
|
4761
4998
|
resolve(entry.itemKeys || null);
|
|
4762
4999
|
} catch (parseError) {
|
|
4763
|
-
|
|
5000
|
+
logger23.error("Failed to parse query result", { queryHash, error: parseError });
|
|
4764
5001
|
resolve(null);
|
|
4765
5002
|
}
|
|
4766
5003
|
};
|
|
4767
|
-
}
|
|
5004
|
+
} catch (requestError) {
|
|
5005
|
+
logger23.error("Error creating IndexedDB get request for query result", { queryHash, queryKey, error: requestError });
|
|
5006
|
+
reject(requestError);
|
|
5007
|
+
}
|
|
5008
|
+
});
|
|
5009
|
+
} catch (error) {
|
|
5010
|
+
logger23.error("Error in getQueryResult", { queryHash, error });
|
|
5011
|
+
return null;
|
|
5012
|
+
}
|
|
5013
|
+
}
|
|
5014
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
5015
|
+
logger23.trace("getQueryResultWithMetadata", { queryHash });
|
|
5016
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
5017
|
+
logger23.error("Invalid queryHash provided to getQueryResultWithMetadata", { queryHash });
|
|
5018
|
+
return null;
|
|
5019
|
+
}
|
|
5020
|
+
try {
|
|
5021
|
+
const db = await this.getDB();
|
|
5022
|
+
const transaction = db.transaction([this.storeName], "readonly");
|
|
5023
|
+
const store = transaction.objectStore(this.storeName);
|
|
5024
|
+
const queryKey = `query:${queryHash}`;
|
|
5025
|
+
return new Promise((resolve, reject) => {
|
|
5026
|
+
try {
|
|
5027
|
+
const getRequest = store.get(queryKey);
|
|
5028
|
+
getRequest.onerror = () => {
|
|
5029
|
+
logger23.error("Failed to retrieve query result with metadata", { queryHash, error: getRequest.error });
|
|
5030
|
+
reject(getRequest.error);
|
|
5031
|
+
};
|
|
5032
|
+
getRequest.onsuccess = () => {
|
|
5033
|
+
try {
|
|
5034
|
+
const result = getRequest.result;
|
|
5035
|
+
if (!result) {
|
|
5036
|
+
resolve(null);
|
|
5037
|
+
return;
|
|
5038
|
+
}
|
|
5039
|
+
const entry = JSON.parse(result);
|
|
5040
|
+
if (Array.isArray(entry)) {
|
|
5041
|
+
resolve({ itemKeys: entry, metadata: void 0 });
|
|
5042
|
+
return;
|
|
5043
|
+
}
|
|
5044
|
+
if (entry.metadata) {
|
|
5045
|
+
if (entry.metadata.createdAt) {
|
|
5046
|
+
entry.metadata.createdAt = new Date(entry.metadata.createdAt);
|
|
5047
|
+
}
|
|
5048
|
+
if (entry.metadata.expiresAt) {
|
|
5049
|
+
entry.metadata.expiresAt = new Date(entry.metadata.expiresAt);
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
5052
|
+
resolve({
|
|
5053
|
+
itemKeys: entry.itemKeys || [],
|
|
5054
|
+
metadata: entry.metadata
|
|
5055
|
+
});
|
|
5056
|
+
} catch (parseError) {
|
|
5057
|
+
logger23.error("Failed to parse query result with metadata", { queryHash, error: parseError });
|
|
5058
|
+
resolve(null);
|
|
5059
|
+
}
|
|
5060
|
+
};
|
|
5061
|
+
} catch (requestError) {
|
|
5062
|
+
logger23.error("Error creating IndexedDB get request for query result with metadata", { queryHash, queryKey, error: requestError });
|
|
5063
|
+
reject(requestError);
|
|
5064
|
+
}
|
|
4768
5065
|
});
|
|
4769
5066
|
} catch (error) {
|
|
4770
|
-
|
|
5067
|
+
logger23.error("Error in getQueryResultWithMetadata", { queryHash, error });
|
|
4771
5068
|
return null;
|
|
4772
5069
|
}
|
|
4773
5070
|
}
|
|
4774
5071
|
async hasQueryResult(queryHash) {
|
|
4775
|
-
|
|
5072
|
+
logger23.trace("hasQueryResult", { queryHash });
|
|
4776
5073
|
try {
|
|
4777
5074
|
const result = await this.getQueryResult(queryHash);
|
|
4778
5075
|
return result !== null;
|
|
4779
5076
|
} catch (error) {
|
|
4780
|
-
|
|
5077
|
+
logger23.error("Error in hasQueryResult", { queryHash, error });
|
|
4781
5078
|
return false;
|
|
4782
5079
|
}
|
|
4783
5080
|
}
|
|
4784
5081
|
async deleteQueryResult(queryHash) {
|
|
4785
|
-
|
|
5082
|
+
logger23.trace("deleteQueryResult", { queryHash });
|
|
5083
|
+
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
5084
|
+
logger23.error("Invalid queryHash provided to deleteQueryResult", { queryHash });
|
|
5085
|
+
return;
|
|
5086
|
+
}
|
|
4786
5087
|
try {
|
|
5088
|
+
const db = await this.getDB();
|
|
5089
|
+
const transaction = db.transaction([this.storeName], "readwrite");
|
|
5090
|
+
const store = transaction.objectStore(this.storeName);
|
|
5091
|
+
const queryKey = `query:${queryHash}`;
|
|
4787
5092
|
return new Promise((resolve, reject) => {
|
|
4788
|
-
|
|
4789
|
-
request.onerror = () => {
|
|
4790
|
-
logger21.error("Failed to open database for deleteQueryResult", { error: request.error });
|
|
4791
|
-
reject(request.error);
|
|
4792
|
-
};
|
|
4793
|
-
request.onsuccess = () => {
|
|
4794
|
-
const db = request.result;
|
|
4795
|
-
const transaction = db.transaction([this.storeName], "readwrite");
|
|
4796
|
-
const store = transaction.objectStore(this.storeName);
|
|
4797
|
-
const queryKey = `query:${queryHash}`;
|
|
5093
|
+
try {
|
|
4798
5094
|
const deleteRequest = store.delete(queryKey);
|
|
4799
5095
|
deleteRequest.onerror = () => {
|
|
4800
|
-
|
|
5096
|
+
logger23.error("Failed to delete query result", { queryHash, error: deleteRequest.error });
|
|
4801
5097
|
reject(deleteRequest.error);
|
|
4802
5098
|
};
|
|
4803
5099
|
deleteRequest.onsuccess = () => {
|
|
4804
5100
|
resolve();
|
|
4805
5101
|
};
|
|
4806
|
-
}
|
|
5102
|
+
} catch (requestError) {
|
|
5103
|
+
logger23.error("Error creating IndexedDB delete request for query result", { queryHash, queryKey, error: requestError });
|
|
5104
|
+
reject(requestError);
|
|
5105
|
+
}
|
|
4807
5106
|
});
|
|
4808
5107
|
} catch (error) {
|
|
4809
|
-
|
|
5108
|
+
logger23.error("Error in deleteQueryResult", { queryHash, error });
|
|
4810
5109
|
throw error;
|
|
4811
5110
|
}
|
|
4812
5111
|
}
|
|
4813
5112
|
async invalidateItemKeys(keys) {
|
|
4814
|
-
|
|
5113
|
+
logger23.debug("invalidateItemKeys", { keys });
|
|
4815
5114
|
if (keys.length === 0) {
|
|
4816
5115
|
return;
|
|
4817
5116
|
}
|
|
@@ -4848,7 +5147,7 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4848
5147
|
queryResults2[queryHash] = itemKeys;
|
|
4849
5148
|
}
|
|
4850
5149
|
} catch (error) {
|
|
4851
|
-
|
|
5150
|
+
logger23.debug("Failed to parse query result", { key: item.key, error });
|
|
4852
5151
|
}
|
|
4853
5152
|
}
|
|
4854
5153
|
}
|
|
@@ -4876,18 +5175,18 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4876
5175
|
});
|
|
4877
5176
|
}
|
|
4878
5177
|
}
|
|
4879
|
-
|
|
5178
|
+
logger23.debug("Selectively invalidated queries referencing affected keys", {
|
|
4880
5179
|
affectedKeys: keys.length,
|
|
4881
5180
|
queriesRemoved: queriesToRemove.length,
|
|
4882
5181
|
totalQueries: Object.keys(queryResults).length
|
|
4883
5182
|
});
|
|
4884
5183
|
} catch (error) {
|
|
4885
|
-
|
|
5184
|
+
logger23.error("Error during selective query invalidation, falling back to clearing all queries", { error });
|
|
4886
5185
|
await this.clearQueryResults();
|
|
4887
5186
|
}
|
|
4888
5187
|
}
|
|
4889
5188
|
async invalidateLocation(locations) {
|
|
4890
|
-
|
|
5189
|
+
logger23.debug("invalidateLocation", { locations });
|
|
4891
5190
|
let keysToInvalidate = [];
|
|
4892
5191
|
if (locations.length === 0) {
|
|
4893
5192
|
await this.clearQueryResults();
|
|
@@ -4900,68 +5199,61 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4900
5199
|
}
|
|
4901
5200
|
}
|
|
4902
5201
|
async clearQueryResults() {
|
|
4903
|
-
|
|
5202
|
+
logger23.trace("clearQueryResults");
|
|
4904
5203
|
try {
|
|
5204
|
+
const db = await this.getDB();
|
|
5205
|
+
const transaction = db.transaction([this.storeName], "readwrite");
|
|
5206
|
+
const store = transaction.objectStore(this.storeName);
|
|
4905
5207
|
return new Promise((resolve, reject) => {
|
|
4906
|
-
const
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
5208
|
+
const cursorRequest = store.openCursor();
|
|
5209
|
+
const keysToDelete = [];
|
|
5210
|
+
cursorRequest.onerror = () => {
|
|
5211
|
+
logger23.error("Failed to open cursor for clearQueryResults", { error: cursorRequest.error });
|
|
5212
|
+
reject(cursorRequest.error);
|
|
4910
5213
|
};
|
|
4911
|
-
|
|
4912
|
-
const
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
cursorRequest.onerror = () => {
|
|
4918
|
-
logger21.error("Failed to open cursor for clearQueryResults", { error: cursorRequest.error });
|
|
4919
|
-
reject(cursorRequest.error);
|
|
4920
|
-
};
|
|
4921
|
-
cursorRequest.onsuccess = () => {
|
|
4922
|
-
const cursor = cursorRequest.result;
|
|
4923
|
-
if (cursor) {
|
|
4924
|
-
const key = cursor.key;
|
|
4925
|
-
if (typeof key === "string" && key.startsWith("query:")) {
|
|
4926
|
-
keysToDelete.push(key);
|
|
4927
|
-
}
|
|
4928
|
-
cursor.continue();
|
|
4929
|
-
} else {
|
|
4930
|
-
if (keysToDelete.length === 0) {
|
|
4931
|
-
resolve();
|
|
4932
|
-
return;
|
|
4933
|
-
}
|
|
4934
|
-
let deletedCount = 0;
|
|
4935
|
-
const totalToDelete = keysToDelete.length;
|
|
4936
|
-
keysToDelete.forEach((queryKey) => {
|
|
4937
|
-
const deleteRequest = store.delete(queryKey);
|
|
4938
|
-
deleteRequest.onerror = () => {
|
|
4939
|
-
logger21.error("Failed to delete query key", { queryKey, error: deleteRequest.error });
|
|
4940
|
-
deletedCount++;
|
|
4941
|
-
if (deletedCount === totalToDelete) {
|
|
4942
|
-
resolve();
|
|
4943
|
-
}
|
|
4944
|
-
};
|
|
4945
|
-
deleteRequest.onsuccess = () => {
|
|
4946
|
-
deletedCount++;
|
|
4947
|
-
if (deletedCount === totalToDelete) {
|
|
4948
|
-
resolve();
|
|
4949
|
-
}
|
|
4950
|
-
};
|
|
4951
|
-
});
|
|
5214
|
+
cursorRequest.onsuccess = () => {
|
|
5215
|
+
const cursor = cursorRequest.result;
|
|
5216
|
+
if (cursor) {
|
|
5217
|
+
const key = cursor.key;
|
|
5218
|
+
if (typeof key === "string" && key.startsWith("query:")) {
|
|
5219
|
+
keysToDelete.push(key);
|
|
4952
5220
|
}
|
|
4953
|
-
|
|
5221
|
+
cursor.continue();
|
|
5222
|
+
} else {
|
|
5223
|
+
if (keysToDelete.length === 0) {
|
|
5224
|
+
resolve();
|
|
5225
|
+
return;
|
|
5226
|
+
}
|
|
5227
|
+
let deletedCount = 0;
|
|
5228
|
+
const totalToDelete = keysToDelete.length;
|
|
5229
|
+
keysToDelete.forEach((queryKey) => {
|
|
5230
|
+
const deleteRequest = store.delete(queryKey);
|
|
5231
|
+
deleteRequest.onerror = () => {
|
|
5232
|
+
logger23.error("Failed to delete query key", { queryKey, error: deleteRequest.error });
|
|
5233
|
+
deletedCount++;
|
|
5234
|
+
if (deletedCount === totalToDelete) {
|
|
5235
|
+
resolve();
|
|
5236
|
+
}
|
|
5237
|
+
};
|
|
5238
|
+
deleteRequest.onsuccess = () => {
|
|
5239
|
+
deletedCount++;
|
|
5240
|
+
if (deletedCount === totalToDelete) {
|
|
5241
|
+
resolve();
|
|
5242
|
+
}
|
|
5243
|
+
};
|
|
5244
|
+
});
|
|
5245
|
+
}
|
|
4954
5246
|
};
|
|
4955
5247
|
});
|
|
4956
5248
|
} catch (error) {
|
|
4957
|
-
|
|
5249
|
+
logger23.error("Error in clearQueryResults", { error });
|
|
4958
5250
|
throw error;
|
|
4959
5251
|
}
|
|
4960
5252
|
}
|
|
4961
5253
|
};
|
|
4962
5254
|
|
|
4963
5255
|
// src/browser/IndexDBCacheMap.ts
|
|
4964
|
-
var
|
|
5256
|
+
var logger24 = logger_default.get("IndexDBCacheMap");
|
|
4965
5257
|
var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
4966
5258
|
implementationType = "browser/indexedDB";
|
|
4967
5259
|
// Memory storage
|
|
@@ -5125,15 +5417,37 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5125
5417
|
return candidates.filter((item) => isQueryMatch6(item, query));
|
|
5126
5418
|
}
|
|
5127
5419
|
// Query result caching methods
|
|
5128
|
-
async setQueryResult(queryHash, itemKeys) {
|
|
5420
|
+
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
5129
5421
|
this.queryResultCache[queryHash] = {
|
|
5130
|
-
itemKeys
|
|
5422
|
+
itemKeys,
|
|
5423
|
+
metadata
|
|
5131
5424
|
};
|
|
5425
|
+
await this.asyncCache.setQueryResult(queryHash, itemKeys, metadata);
|
|
5132
5426
|
}
|
|
5133
5427
|
async getQueryResult(queryHash) {
|
|
5134
5428
|
const entry = this.queryResultCache[queryHash];
|
|
5135
5429
|
return entry ? entry.itemKeys : null;
|
|
5136
5430
|
}
|
|
5431
|
+
async getQueryResultWithMetadata(queryHash) {
|
|
5432
|
+
let entry = this.queryResultCache[queryHash];
|
|
5433
|
+
if (!entry) {
|
|
5434
|
+
const persistedResult = await this.asyncCache.getQueryResultWithMetadata(queryHash);
|
|
5435
|
+
if (persistedResult) {
|
|
5436
|
+
this.queryResultCache[queryHash] = {
|
|
5437
|
+
itemKeys: persistedResult.itemKeys,
|
|
5438
|
+
metadata: persistedResult.metadata
|
|
5439
|
+
};
|
|
5440
|
+
entry = this.queryResultCache[queryHash];
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
if (!entry) {
|
|
5444
|
+
return null;
|
|
5445
|
+
}
|
|
5446
|
+
return {
|
|
5447
|
+
itemKeys: entry.itemKeys,
|
|
5448
|
+
metadata: entry.metadata
|
|
5449
|
+
};
|
|
5450
|
+
}
|
|
5137
5451
|
async hasQueryResult(queryHash) {
|
|
5138
5452
|
return queryHash in this.queryResultCache;
|
|
5139
5453
|
}
|
|
@@ -5145,7 +5459,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5145
5459
|
}
|
|
5146
5460
|
// Invalidation methods
|
|
5147
5461
|
async invalidateItemKeys(keys) {
|
|
5148
|
-
|
|
5462
|
+
logger24.debug("invalidateItemKeys", { keys });
|
|
5149
5463
|
if (keys.length === 0) {
|
|
5150
5464
|
return;
|
|
5151
5465
|
}
|
|
@@ -5175,7 +5489,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5175
5489
|
queriesToRemove.forEach((queryHash) => {
|
|
5176
5490
|
delete this.queryResultCache[queryHash];
|
|
5177
5491
|
});
|
|
5178
|
-
|
|
5492
|
+
logger24.debug("Selectively invalidated queries referencing affected keys", {
|
|
5179
5493
|
affectedKeys: keys.length,
|
|
5180
5494
|
queriesRemoved: queriesToRemove.length,
|
|
5181
5495
|
totalQueries: Object.keys(this.queryResultCache).length
|
|
@@ -5667,8 +5981,11 @@ var highTrafficTTLConfig = {
|
|
|
5667
5981
|
}
|
|
5668
5982
|
};
|
|
5669
5983
|
|
|
5984
|
+
// src/cache/warming/CacheWarmer.ts
|
|
5985
|
+
var logger25 = logger_default.get("CacheWarmer");
|
|
5986
|
+
|
|
5670
5987
|
// src/Operations.ts
|
|
5671
|
-
var
|
|
5988
|
+
var logger26 = logger_default.get("Operations");
|
|
5672
5989
|
var CacheMapOperations = class {
|
|
5673
5990
|
constructor(api, coordinate, cacheMap, pkType, options, eventEmitter, ttlManager, evictionManager, statsManager, registry) {
|
|
5674
5991
|
this.api = api;
|
|
@@ -5682,7 +5999,7 @@ var CacheMapOperations = class {
|
|
|
5682
5999
|
this.statsManager = statsManager;
|
|
5683
6000
|
this.registry = registry;
|
|
5684
6001
|
if (this.options.enableDebugLogging) {
|
|
5685
|
-
|
|
6002
|
+
logger26.debug("CacheMapOperations initialized", {
|
|
5686
6003
|
cacheType: this.cacheMap.implementationType,
|
|
5687
6004
|
isTwoLayer: this.cacheMap instanceof TwoLayerCacheMap
|
|
5688
6005
|
});
|
|
@@ -5775,7 +6092,7 @@ var createOperations = (api, coordinate, cacheMap, pkType, options, eventEmitter
|
|
|
5775
6092
|
};
|
|
5776
6093
|
|
|
5777
6094
|
// src/eviction/EvictionManager.ts
|
|
5778
|
-
var
|
|
6095
|
+
var logger27 = logger_default.get("EvictionManager");
|
|
5779
6096
|
var EvictionManager = class {
|
|
5780
6097
|
evictionStrategy;
|
|
5781
6098
|
constructor(evictionStrategy) {
|
|
@@ -5787,7 +6104,7 @@ var EvictionManager = class {
|
|
|
5787
6104
|
*/
|
|
5788
6105
|
setEvictionStrategy(strategy) {
|
|
5789
6106
|
this.evictionStrategy = strategy;
|
|
5790
|
-
|
|
6107
|
+
logger27.debug("Eviction strategy updated", {
|
|
5791
6108
|
strategy: strategy?.getStrategyName() || "none"
|
|
5792
6109
|
});
|
|
5793
6110
|
}
|
|
@@ -5808,13 +6125,13 @@ var EvictionManager = class {
|
|
|
5808
6125
|
return;
|
|
5809
6126
|
}
|
|
5810
6127
|
try {
|
|
5811
|
-
|
|
6128
|
+
logger27.debug("EVICTION: Item accessed, updating metadata", {
|
|
5812
6129
|
key,
|
|
5813
6130
|
strategy: this.evictionStrategy.getStrategyName()
|
|
5814
6131
|
});
|
|
5815
6132
|
await this.evictionStrategy.onItemAccessed(key, metadataProvider);
|
|
5816
6133
|
} catch (error) {
|
|
5817
|
-
|
|
6134
|
+
logger27.error("EVICTION: Error in eviction strategy onItemAccessed", {
|
|
5818
6135
|
key,
|
|
5819
6136
|
error,
|
|
5820
6137
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -5832,12 +6149,12 @@ var EvictionManager = class {
|
|
|
5832
6149
|
const startTime = Date.now();
|
|
5833
6150
|
const evictedKeys = [];
|
|
5834
6151
|
if (!this.evictionStrategy) {
|
|
5835
|
-
|
|
6152
|
+
logger27.debug("EVICTION: No eviction strategy configured", { key });
|
|
5836
6153
|
return evictedKeys;
|
|
5837
6154
|
}
|
|
5838
6155
|
try {
|
|
5839
6156
|
const estimatedSize = estimateValueSize(value);
|
|
5840
|
-
|
|
6157
|
+
logger27.debug("EVICTION: Item addition started", {
|
|
5841
6158
|
key,
|
|
5842
6159
|
estimatedSize,
|
|
5843
6160
|
strategy: this.evictionStrategy.getStrategyName()
|
|
@@ -5845,7 +6162,7 @@ var EvictionManager = class {
|
|
|
5845
6162
|
const contextStartTime = Date.now();
|
|
5846
6163
|
const context = await this.createEvictionContext(metadataProvider, estimatedSize);
|
|
5847
6164
|
const contextDuration = Date.now() - contextStartTime;
|
|
5848
|
-
|
|
6165
|
+
logger27.debug("EVICTION: Current cache state", {
|
|
5849
6166
|
key,
|
|
5850
6167
|
currentItemCount: context.currentSize.itemCount,
|
|
5851
6168
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
@@ -5858,7 +6175,7 @@ var EvictionManager = class {
|
|
|
5858
6175
|
const keysToEvict = await this.evictionStrategy.selectForEviction(metadataProvider, context);
|
|
5859
6176
|
const selectionDuration = Date.now() - selectionStartTime;
|
|
5860
6177
|
if (keysToEvict.length > 0) {
|
|
5861
|
-
|
|
6178
|
+
logger27.debug("EVICTION: Items selected for eviction", {
|
|
5862
6179
|
key,
|
|
5863
6180
|
evictCount: keysToEvict.length,
|
|
5864
6181
|
keysToEvict,
|
|
@@ -5870,7 +6187,7 @@ var EvictionManager = class {
|
|
|
5870
6187
|
for (const evictKey of keysToEvict) {
|
|
5871
6188
|
await this.evictionStrategy.onItemRemoved(evictKey, metadataProvider);
|
|
5872
6189
|
evictedKeys.push(evictKey);
|
|
5873
|
-
|
|
6190
|
+
logger27.debug("EVICTION: Marked item for eviction", {
|
|
5874
6191
|
evictedKey: evictKey,
|
|
5875
6192
|
newKey: key
|
|
5876
6193
|
});
|
|
@@ -5881,7 +6198,7 @@ var EvictionManager = class {
|
|
|
5881
6198
|
const addMetadataDuration = Date.now() - addMetadataStart;
|
|
5882
6199
|
const totalDuration = Date.now() - startTime;
|
|
5883
6200
|
if (evictedKeys.length > 0) {
|
|
5884
|
-
|
|
6201
|
+
logger27.debug("EVICTION: Eviction completed", {
|
|
5885
6202
|
newKey: key,
|
|
5886
6203
|
evictedCount: evictedKeys.length,
|
|
5887
6204
|
evictedKeys,
|
|
@@ -5892,14 +6209,14 @@ var EvictionManager = class {
|
|
|
5892
6209
|
totalDuration
|
|
5893
6210
|
});
|
|
5894
6211
|
} else {
|
|
5895
|
-
|
|
6212
|
+
logger27.debug("EVICTION: No eviction needed", {
|
|
5896
6213
|
newKey: key,
|
|
5897
6214
|
estimatedSize,
|
|
5898
6215
|
totalDuration
|
|
5899
6216
|
});
|
|
5900
6217
|
}
|
|
5901
6218
|
} catch (error) {
|
|
5902
|
-
|
|
6219
|
+
logger27.error("EVICTION: Error in eviction strategy onItemAdded", {
|
|
5903
6220
|
key,
|
|
5904
6221
|
error,
|
|
5905
6222
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -5919,7 +6236,7 @@ var EvictionManager = class {
|
|
|
5919
6236
|
try {
|
|
5920
6237
|
this.evictionStrategy.onItemRemoved(key, metadataProvider);
|
|
5921
6238
|
} catch (error) {
|
|
5922
|
-
|
|
6239
|
+
logger27.error("Error in eviction strategy onItemRemoved", { key, error });
|
|
5923
6240
|
}
|
|
5924
6241
|
}
|
|
5925
6242
|
/**
|
|
@@ -5931,15 +6248,15 @@ var EvictionManager = class {
|
|
|
5931
6248
|
const startTime = Date.now();
|
|
5932
6249
|
const evictedKeys = [];
|
|
5933
6250
|
if (!this.evictionStrategy) {
|
|
5934
|
-
|
|
6251
|
+
logger27.debug("EVICTION: No eviction strategy configured for manual eviction");
|
|
5935
6252
|
return evictedKeys;
|
|
5936
6253
|
}
|
|
5937
6254
|
try {
|
|
5938
|
-
|
|
6255
|
+
logger27.debug("EVICTION: Manual eviction started", {
|
|
5939
6256
|
strategy: this.evictionStrategy.getStrategyName()
|
|
5940
6257
|
});
|
|
5941
6258
|
const context = await this.createEvictionContext(metadataProvider);
|
|
5942
|
-
|
|
6259
|
+
logger27.debug("EVICTION: Manual eviction - current cache state", {
|
|
5943
6260
|
currentItemCount: context.currentSize.itemCount,
|
|
5944
6261
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
5945
6262
|
maxItems: context.limits.maxItems,
|
|
@@ -5952,20 +6269,20 @@ var EvictionManager = class {
|
|
|
5952
6269
|
}
|
|
5953
6270
|
const duration = Date.now() - startTime;
|
|
5954
6271
|
if (evictedKeys.length > 0) {
|
|
5955
|
-
|
|
6272
|
+
logger27.debug("EVICTION: Manual eviction completed", {
|
|
5956
6273
|
evictedCount: evictedKeys.length,
|
|
5957
6274
|
evictedKeys,
|
|
5958
6275
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
5959
6276
|
duration
|
|
5960
6277
|
});
|
|
5961
6278
|
} else {
|
|
5962
|
-
|
|
6279
|
+
logger27.debug("EVICTION: Manual eviction - no items to evict", {
|
|
5963
6280
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
5964
6281
|
duration
|
|
5965
6282
|
});
|
|
5966
6283
|
}
|
|
5967
6284
|
} catch (error) {
|
|
5968
|
-
|
|
6285
|
+
logger27.error("EVICTION: Error in manual eviction", {
|
|
5969
6286
|
error,
|
|
5970
6287
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
5971
6288
|
});
|
|
@@ -5988,7 +6305,7 @@ var EvictionManager = class {
|
|
|
5988
6305
|
this.evictionStrategy.reset();
|
|
5989
6306
|
}
|
|
5990
6307
|
}
|
|
5991
|
-
|
|
6308
|
+
logger27.debug("Eviction manager cleared");
|
|
5992
6309
|
}
|
|
5993
6310
|
/**
|
|
5994
6311
|
* Create eviction context from current cache state
|
|
@@ -7326,7 +7643,7 @@ function createEvictionStrategy(policy, maxCacheSize, config) {
|
|
|
7326
7643
|
}
|
|
7327
7644
|
|
|
7328
7645
|
// src/ttl/TTLManager.ts
|
|
7329
|
-
var
|
|
7646
|
+
var logger28 = logger_default.get("TTLManager");
|
|
7330
7647
|
var TTLManager = class {
|
|
7331
7648
|
config;
|
|
7332
7649
|
cleanupTimer;
|
|
@@ -7338,7 +7655,7 @@ var TTLManager = class {
|
|
|
7338
7655
|
validateOnAccess: true,
|
|
7339
7656
|
...config
|
|
7340
7657
|
};
|
|
7341
|
-
|
|
7658
|
+
logger28.debug("TTL_DEBUG: TTLManager created", {
|
|
7342
7659
|
config: this.config,
|
|
7343
7660
|
isTTLEnabled: this.isTTLEnabled(),
|
|
7344
7661
|
defaultTTL: this.config.defaultTTL
|
|
@@ -7371,13 +7688,13 @@ var TTLManager = class {
|
|
|
7371
7688
|
this.startAutoCleanup();
|
|
7372
7689
|
}
|
|
7373
7690
|
}
|
|
7374
|
-
|
|
7691
|
+
logger28.debug("TTL configuration updated", { config: this.config });
|
|
7375
7692
|
}
|
|
7376
7693
|
/**
|
|
7377
7694
|
* Set TTL metadata for an item when it's added
|
|
7378
7695
|
*/
|
|
7379
7696
|
async onItemAdded(key, metadataProvider, itemTTL) {
|
|
7380
|
-
|
|
7697
|
+
logger28.debug("TTL_DEBUG: onItemAdded called", {
|
|
7381
7698
|
key,
|
|
7382
7699
|
itemTTL,
|
|
7383
7700
|
isTTLEnabled: this.isTTLEnabled(),
|
|
@@ -7385,19 +7702,19 @@ var TTLManager = class {
|
|
|
7385
7702
|
metadataProviderType: metadataProvider?.constructor?.name
|
|
7386
7703
|
});
|
|
7387
7704
|
if (!this.isTTLEnabled() && !itemTTL) {
|
|
7388
|
-
|
|
7705
|
+
logger28.debug("TTL_DEBUG: No TTL configured for item - returning early", { key });
|
|
7389
7706
|
return;
|
|
7390
7707
|
}
|
|
7391
|
-
|
|
7708
|
+
logger28.debug("TTL_DEBUG: Getting metadata for key", { key });
|
|
7392
7709
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7393
|
-
|
|
7710
|
+
logger28.debug("TTL_DEBUG: Retrieved metadata", {
|
|
7394
7711
|
key,
|
|
7395
7712
|
hasMetadata: !!metadata,
|
|
7396
7713
|
metadataKeys: metadata ? Object.keys(metadata) : null,
|
|
7397
7714
|
metadata
|
|
7398
7715
|
});
|
|
7399
7716
|
if (!metadata) {
|
|
7400
|
-
|
|
7717
|
+
logger28.debug("TTL_DEBUG: No metadata found for item when setting TTL", {
|
|
7401
7718
|
key,
|
|
7402
7719
|
metadataProviderType: metadataProvider?.constructor?.name,
|
|
7403
7720
|
metadataProviderMethods: metadataProvider ? Object.getOwnPropertyNames(Object.getPrototypeOf(metadataProvider)) : null
|
|
@@ -7405,7 +7722,7 @@ var TTLManager = class {
|
|
|
7405
7722
|
return;
|
|
7406
7723
|
}
|
|
7407
7724
|
const ttl = itemTTL || this.config.defaultTTL;
|
|
7408
|
-
|
|
7725
|
+
logger28.debug("TTL_DEBUG: Calculated TTL value", {
|
|
7409
7726
|
key,
|
|
7410
7727
|
itemTTL,
|
|
7411
7728
|
defaultTTL: this.config.defaultTTL,
|
|
@@ -7418,7 +7735,7 @@ var TTLManager = class {
|
|
|
7418
7735
|
expiresAt: metadata.addedAt + ttl,
|
|
7419
7736
|
ttl
|
|
7420
7737
|
};
|
|
7421
|
-
|
|
7738
|
+
logger28.debug("TTL_DEBUG: Setting TTL metadata", {
|
|
7422
7739
|
key,
|
|
7423
7740
|
ttl,
|
|
7424
7741
|
addedAt: metadata.addedAt,
|
|
@@ -7426,9 +7743,9 @@ var TTLManager = class {
|
|
|
7426
7743
|
ttlMetadata
|
|
7427
7744
|
});
|
|
7428
7745
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7429
|
-
|
|
7746
|
+
logger28.trace("TTL_DEBUG: TTL set for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7430
7747
|
} else {
|
|
7431
|
-
|
|
7748
|
+
logger28.debug("TTL_DEBUG: No TTL set - invalid TTL value", { key, ttl });
|
|
7432
7749
|
}
|
|
7433
7750
|
}
|
|
7434
7751
|
/**
|
|
@@ -7437,14 +7754,14 @@ var TTLManager = class {
|
|
|
7437
7754
|
async isExpired(key, metadataProvider) {
|
|
7438
7755
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7439
7756
|
if (!metadata || !metadata.expiresAt) {
|
|
7440
|
-
|
|
7757
|
+
logger28.debug("TTL_CHECK: No TTL set for item", { key, hasMetadata: !!metadata });
|
|
7441
7758
|
return false;
|
|
7442
7759
|
}
|
|
7443
7760
|
const now = Date.now();
|
|
7444
7761
|
const expired = now >= metadata.expiresAt;
|
|
7445
7762
|
const remainingMs = metadata.expiresAt - now;
|
|
7446
7763
|
if (expired) {
|
|
7447
|
-
|
|
7764
|
+
logger28.debug("TTL_CHECK: Item EXPIRED", {
|
|
7448
7765
|
key,
|
|
7449
7766
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7450
7767
|
now: new Date(now).toISOString(),
|
|
@@ -7452,7 +7769,7 @@ var TTLManager = class {
|
|
|
7452
7769
|
ttl: metadata.ttl
|
|
7453
7770
|
});
|
|
7454
7771
|
} else {
|
|
7455
|
-
|
|
7772
|
+
logger28.debug("TTL_CHECK: Item still valid", {
|
|
7456
7773
|
key,
|
|
7457
7774
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7458
7775
|
remainingMs,
|
|
@@ -7468,17 +7785,17 @@ var TTLManager = class {
|
|
|
7468
7785
|
*/
|
|
7469
7786
|
async validateItem(key, metadataProvider) {
|
|
7470
7787
|
if (!this.config.validateOnAccess) {
|
|
7471
|
-
|
|
7788
|
+
logger28.debug("TTL_VALIDATE: Validation disabled, skipping check", { key });
|
|
7472
7789
|
return true;
|
|
7473
7790
|
}
|
|
7474
|
-
|
|
7791
|
+
logger28.debug("TTL_VALIDATE: Validating item", {
|
|
7475
7792
|
key,
|
|
7476
7793
|
ttlEnabled: this.isTTLEnabled(),
|
|
7477
7794
|
defaultTTL: this.config.defaultTTL
|
|
7478
7795
|
});
|
|
7479
7796
|
const isExpired = await this.isExpired(key, metadataProvider);
|
|
7480
7797
|
const isValid = !isExpired;
|
|
7481
|
-
|
|
7798
|
+
logger28.debug("TTL_VALIDATE: Validation result", {
|
|
7482
7799
|
key,
|
|
7483
7800
|
isValid,
|
|
7484
7801
|
isExpired
|
|
@@ -7512,7 +7829,7 @@ var TTLManager = class {
|
|
|
7512
7829
|
const expiredKeys = [];
|
|
7513
7830
|
const allMetadata = await metadataProvider.getAllMetadata();
|
|
7514
7831
|
const now = Date.now();
|
|
7515
|
-
|
|
7832
|
+
logger28.debug("TTL_CLEANUP: Scanning for expired items", {
|
|
7516
7833
|
totalItems: allMetadata.size,
|
|
7517
7834
|
now: new Date(now).toISOString()
|
|
7518
7835
|
});
|
|
@@ -7523,7 +7840,7 @@ var TTLManager = class {
|
|
|
7523
7840
|
itemsWithTTL++;
|
|
7524
7841
|
if (now >= ttlMetadata.expiresAt) {
|
|
7525
7842
|
expiredKeys.push(key);
|
|
7526
|
-
|
|
7843
|
+
logger28.debug("TTL_CLEANUP: Found expired item", {
|
|
7527
7844
|
key,
|
|
7528
7845
|
expiresAt: new Date(ttlMetadata.expiresAt).toISOString(),
|
|
7529
7846
|
expiredByMs: now - ttlMetadata.expiresAt
|
|
@@ -7533,7 +7850,7 @@ var TTLManager = class {
|
|
|
7533
7850
|
}
|
|
7534
7851
|
const duration = Date.now() - startTime;
|
|
7535
7852
|
if (expiredKeys.length > 0) {
|
|
7536
|
-
|
|
7853
|
+
logger28.debug("TTL_CLEANUP: Expired items found", {
|
|
7537
7854
|
expiredCount: expiredKeys.length,
|
|
7538
7855
|
totalItems: allMetadata.size,
|
|
7539
7856
|
itemsWithTTL,
|
|
@@ -7541,7 +7858,7 @@ var TTLManager = class {
|
|
|
7541
7858
|
duration
|
|
7542
7859
|
});
|
|
7543
7860
|
} else {
|
|
7544
|
-
|
|
7861
|
+
logger28.debug("TTL_CLEANUP: No expired items found", {
|
|
7545
7862
|
totalItems: allMetadata.size,
|
|
7546
7863
|
itemsWithTTL,
|
|
7547
7864
|
duration
|
|
@@ -7573,7 +7890,7 @@ var TTLManager = class {
|
|
|
7573
7890
|
}
|
|
7574
7891
|
metadata.expiresAt += additionalTTL;
|
|
7575
7892
|
await metadataProvider.setMetadata(key, metadata);
|
|
7576
|
-
|
|
7893
|
+
logger28.trace("TTL extended for item", { key, additionalTTL, newExpiresAt: metadata.expiresAt });
|
|
7577
7894
|
return true;
|
|
7578
7895
|
}
|
|
7579
7896
|
/**
|
|
@@ -7595,7 +7912,7 @@ var TTLManager = class {
|
|
|
7595
7912
|
ttl
|
|
7596
7913
|
};
|
|
7597
7914
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7598
|
-
|
|
7915
|
+
logger28.trace("TTL refreshed for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7599
7916
|
return true;
|
|
7600
7917
|
}
|
|
7601
7918
|
/**
|
|
@@ -7607,9 +7924,9 @@ var TTLManager = class {
|
|
|
7607
7924
|
}
|
|
7608
7925
|
if (this.config.cleanupInterval) {
|
|
7609
7926
|
this.cleanupTimer = setInterval(() => {
|
|
7610
|
-
|
|
7927
|
+
logger28.trace("Auto cleanup timer triggered");
|
|
7611
7928
|
}, this.config.cleanupInterval);
|
|
7612
|
-
|
|
7929
|
+
logger28.debug("Auto cleanup started", { interval: this.config.cleanupInterval });
|
|
7613
7930
|
}
|
|
7614
7931
|
}
|
|
7615
7932
|
/**
|
|
@@ -7619,7 +7936,7 @@ var TTLManager = class {
|
|
|
7619
7936
|
if (this.cleanupTimer) {
|
|
7620
7937
|
clearInterval(this.cleanupTimer);
|
|
7621
7938
|
this.cleanupTimer = null;
|
|
7622
|
-
|
|
7939
|
+
logger28.debug("Auto cleanup stopped");
|
|
7623
7940
|
}
|
|
7624
7941
|
}
|
|
7625
7942
|
/**
|
|
@@ -7627,14 +7944,14 @@ var TTLManager = class {
|
|
|
7627
7944
|
*/
|
|
7628
7945
|
clear() {
|
|
7629
7946
|
this.stopAutoCleanup();
|
|
7630
|
-
|
|
7947
|
+
logger28.debug("TTL manager cleared");
|
|
7631
7948
|
}
|
|
7632
7949
|
/**
|
|
7633
7950
|
* Cleanup resources
|
|
7634
7951
|
*/
|
|
7635
7952
|
destroy() {
|
|
7636
7953
|
this.stopAutoCleanup();
|
|
7637
|
-
|
|
7954
|
+
logger28.debug("TTL manager destroyed");
|
|
7638
7955
|
}
|
|
7639
7956
|
};
|
|
7640
7957
|
|
|
@@ -8034,9 +8351,9 @@ var CacheStatsManager = class {
|
|
|
8034
8351
|
};
|
|
8035
8352
|
|
|
8036
8353
|
// src/Cache.ts
|
|
8037
|
-
var
|
|
8354
|
+
var logger29 = logger_default.get("Cache");
|
|
8038
8355
|
var createCache = (api, coordinate, registry, options) => {
|
|
8039
|
-
|
|
8356
|
+
logger29.debug("createCache", { coordinate, registry, options });
|
|
8040
8357
|
const completeOptions = createOptions(options);
|
|
8041
8358
|
const cacheMap = createCacheMap(coordinate.kta, completeOptions);
|
|
8042
8359
|
const pkType = coordinate.kta[0];
|
|
@@ -8116,13 +8433,13 @@ var isCache2 = (cache) => {
|
|
|
8116
8433
|
};
|
|
8117
8434
|
|
|
8118
8435
|
// src/InstanceFactory.ts
|
|
8119
|
-
var
|
|
8436
|
+
var logger30 = logger_default.get("InstanceFactory");
|
|
8120
8437
|
var createInstanceFactory = (api, options) => {
|
|
8121
8438
|
const templateOptions = createOptions(options);
|
|
8122
8439
|
validateOptions(templateOptions);
|
|
8123
8440
|
return (coordinate, context) => {
|
|
8124
8441
|
const instanceOptions = createOptions(options);
|
|
8125
|
-
|
|
8442
|
+
logger30.debug("Creating cache instance", {
|
|
8126
8443
|
coordinate,
|
|
8127
8444
|
registry: context.registry,
|
|
8128
8445
|
api,
|
|
@@ -8189,9 +8506,9 @@ var createInstanceFactory = (api, options) => {
|
|
|
8189
8506
|
};
|
|
8190
8507
|
|
|
8191
8508
|
// src/Instance.ts
|
|
8192
|
-
var
|
|
8509
|
+
var logger31 = logger_default.get("Instance");
|
|
8193
8510
|
var createInstance = (registry, coordinate, api, options) => {
|
|
8194
|
-
|
|
8511
|
+
logger31.debug("createInstance", { coordinate, api, registry, options });
|
|
8195
8512
|
return createCache(api, coordinate, registry, options);
|
|
8196
8513
|
};
|
|
8197
8514
|
var isInstance = (instance) => {
|
|
@@ -8199,7 +8516,7 @@ var isInstance = (instance) => {
|
|
|
8199
8516
|
};
|
|
8200
8517
|
|
|
8201
8518
|
// src/Aggregator.ts
|
|
8202
|
-
var
|
|
8519
|
+
var logger32 = logger_default.get("ItemAggregator");
|
|
8203
8520
|
var toCacheConfig = (config) => {
|
|
8204
8521
|
let cacheConfig;
|
|
8205
8522
|
if (config.optional === void 0) {
|
|
@@ -8211,22 +8528,22 @@ var toCacheConfig = (config) => {
|
|
|
8211
8528
|
};
|
|
8212
8529
|
var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
8213
8530
|
const populate = async (item) => {
|
|
8214
|
-
|
|
8531
|
+
logger32.default("populate", { item });
|
|
8215
8532
|
for (const key in aggregates) {
|
|
8216
8533
|
await populateAggregate(key, item);
|
|
8217
8534
|
}
|
|
8218
8535
|
for (const key in events) {
|
|
8219
8536
|
await populateEvent(key, item);
|
|
8220
8537
|
}
|
|
8221
|
-
|
|
8538
|
+
logger32.default("populate done", { item });
|
|
8222
8539
|
return item;
|
|
8223
8540
|
};
|
|
8224
8541
|
const populateAggregate = async (key, item) => {
|
|
8225
|
-
|
|
8542
|
+
logger32.default("populate aggregate key", { key });
|
|
8226
8543
|
const cacheConfig = toCacheConfig(aggregates[key]);
|
|
8227
8544
|
if (item.refs === void 0) {
|
|
8228
8545
|
if (cacheConfig.optional === false) {
|
|
8229
|
-
|
|
8546
|
+
logger32.error("Item does not have refs an is not optional ", { item });
|
|
8230
8547
|
throw new Error("Item does not have refs an is not optional " + JSON.stringify(item));
|
|
8231
8548
|
} else {
|
|
8232
8549
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
@@ -8235,7 +8552,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8235
8552
|
}
|
|
8236
8553
|
} else if (item.refs[key] === void 0) {
|
|
8237
8554
|
if (cacheConfig.optional === false) {
|
|
8238
|
-
|
|
8555
|
+
logger32.error("Item does not have mandatory ref with key, not optional ", { key, item });
|
|
8239
8556
|
throw new Error("Item does not have mandatory ref with key, not optional " + key + " " + JSON.stringify(item));
|
|
8240
8557
|
} else {
|
|
8241
8558
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
@@ -8244,7 +8561,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8244
8561
|
}
|
|
8245
8562
|
} else {
|
|
8246
8563
|
const ref = item.refs[key];
|
|
8247
|
-
|
|
8564
|
+
logger32.default("AGG Retrieving Item in Populate", { key: ref });
|
|
8248
8565
|
const newItem = await cacheConfig.cache.operations.retrieve(ref);
|
|
8249
8566
|
if (newItem) {
|
|
8250
8567
|
if (item.aggs === void 0) {
|
|
@@ -8261,25 +8578,25 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8261
8578
|
}
|
|
8262
8579
|
};
|
|
8263
8580
|
const populateEvent = async (key, item) => {
|
|
8264
|
-
|
|
8581
|
+
logger32.default("populate event key", { key });
|
|
8265
8582
|
const cacheConfig = toCacheConfig(events[key]);
|
|
8266
8583
|
if (item.events === void 0) {
|
|
8267
8584
|
throw new Error("Item does not have events " + JSON.stringify(item));
|
|
8268
8585
|
} else if (item.events[key] === void 0) {
|
|
8269
8586
|
if (cacheConfig.optional === false) {
|
|
8270
|
-
|
|
8587
|
+
logger32.error("Item does not have mandatory event with key", { key, item });
|
|
8271
8588
|
throw new Error("Item does not have mandatory event with key " + key + " " + JSON.stringify(item));
|
|
8272
8589
|
}
|
|
8273
8590
|
} else {
|
|
8274
8591
|
const event = item.events[key];
|
|
8275
8592
|
if (event.by === void 0) {
|
|
8276
|
-
|
|
8593
|
+
logger32.error(
|
|
8277
8594
|
"populateEvent with an Event that does not have by",
|
|
8278
8595
|
{ event, ik: item.key, eventKey: key }
|
|
8279
8596
|
);
|
|
8280
8597
|
throw new Error("populateEvent with an Event that does not have by: " + JSON.stringify({ key }));
|
|
8281
8598
|
}
|
|
8282
|
-
|
|
8599
|
+
logger32.default("EVENT Retrieving Item in Populate", { key: event.by });
|
|
8283
8600
|
const newItem = await cacheConfig.cache.operations.retrieve(event.by);
|
|
8284
8601
|
if (newItem) {
|
|
8285
8602
|
event.agg = newItem;
|
|
@@ -8287,13 +8604,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8287
8604
|
}
|
|
8288
8605
|
};
|
|
8289
8606
|
const all2 = async (query = {}, locations = []) => {
|
|
8290
|
-
|
|
8607
|
+
logger32.default("all", { query, locations });
|
|
8291
8608
|
const result = await cache.operations.all(query, locations);
|
|
8292
8609
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8293
8610
|
return populatedItems;
|
|
8294
8611
|
};
|
|
8295
8612
|
const one2 = async (query = {}, locations = []) => {
|
|
8296
|
-
|
|
8613
|
+
logger32.default("one", { query, locations });
|
|
8297
8614
|
const item = await cache.operations.one(query, locations);
|
|
8298
8615
|
let populatedItem = null;
|
|
8299
8616
|
if (item) {
|
|
@@ -8302,30 +8619,30 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8302
8619
|
return populatedItem;
|
|
8303
8620
|
};
|
|
8304
8621
|
const action2 = async (key, action3, body = {}) => {
|
|
8305
|
-
|
|
8622
|
+
logger32.default("action", { key, action: action3, body });
|
|
8306
8623
|
const [item, affectedItems] = await cache.operations.action(key, action3, body);
|
|
8307
8624
|
const populatedItem = await populate(item);
|
|
8308
8625
|
return [populatedItem, affectedItems];
|
|
8309
8626
|
};
|
|
8310
8627
|
const allAction2 = async (action3, body = {}, locations = []) => {
|
|
8311
|
-
|
|
8628
|
+
logger32.default("action", { action: action3, body, locations });
|
|
8312
8629
|
const [items, affectedItems] = await cache.operations.allAction(action3, body, locations);
|
|
8313
8630
|
const populatedItems = await Promise.all(items.map(async (item) => populate(item)));
|
|
8314
8631
|
return [populatedItems, affectedItems];
|
|
8315
8632
|
};
|
|
8316
8633
|
const allFacet2 = async (facet3, params = {}, locations = []) => {
|
|
8317
|
-
|
|
8634
|
+
logger32.default("allFacet", { facet: facet3, params, locations });
|
|
8318
8635
|
const response = await cache.operations.allFacet(facet3, params, locations);
|
|
8319
8636
|
return response;
|
|
8320
8637
|
};
|
|
8321
8638
|
const create2 = async (v, locations = []) => {
|
|
8322
|
-
|
|
8639
|
+
logger32.default("create", { v, locations });
|
|
8323
8640
|
const item = locations.length === 0 ? await cache.operations.create(v) : await cache.operations.create(v, { locations });
|
|
8324
8641
|
const populatedItem = await populate(item);
|
|
8325
8642
|
return populatedItem;
|
|
8326
8643
|
};
|
|
8327
8644
|
const get2 = async (key) => {
|
|
8328
|
-
|
|
8645
|
+
logger32.default("get", { key });
|
|
8329
8646
|
const item = await cache.operations.get(key);
|
|
8330
8647
|
let populatedItem = null;
|
|
8331
8648
|
if (item) {
|
|
@@ -8334,7 +8651,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8334
8651
|
return populatedItem;
|
|
8335
8652
|
};
|
|
8336
8653
|
const retrieve2 = async (key) => {
|
|
8337
|
-
|
|
8654
|
+
logger32.default("retrieve", { key });
|
|
8338
8655
|
const item = await cache.operations.retrieve(key);
|
|
8339
8656
|
let populatedItem = null;
|
|
8340
8657
|
if (item) {
|
|
@@ -8343,22 +8660,22 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8343
8660
|
return populatedItem;
|
|
8344
8661
|
};
|
|
8345
8662
|
const remove2 = async (key) => {
|
|
8346
|
-
|
|
8663
|
+
logger32.default("remove", { key });
|
|
8347
8664
|
await cache.operations.remove(key);
|
|
8348
8665
|
};
|
|
8349
8666
|
const update2 = async (key, v) => {
|
|
8350
|
-
|
|
8667
|
+
logger32.default("update", { key, v });
|
|
8351
8668
|
const item = await cache.operations.update(key, v);
|
|
8352
8669
|
const populatedItem = await populate(item);
|
|
8353
8670
|
return populatedItem;
|
|
8354
8671
|
};
|
|
8355
8672
|
const facet2 = async (key, facet3) => {
|
|
8356
|
-
|
|
8673
|
+
logger32.default("facet", { key, facet: facet3 });
|
|
8357
8674
|
const response = await cache.operations.facet(key, facet3);
|
|
8358
8675
|
return response;
|
|
8359
8676
|
};
|
|
8360
8677
|
const find2 = async (finder, finderParams = {}, locations = [], findOptions) => {
|
|
8361
|
-
|
|
8678
|
+
logger32.default("find", { finder, finderParams, locations, findOptions });
|
|
8362
8679
|
const result = await cache.operations.find(finder, finderParams, locations, findOptions);
|
|
8363
8680
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8364
8681
|
return {
|
|
@@ -8367,7 +8684,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8367
8684
|
};
|
|
8368
8685
|
};
|
|
8369
8686
|
const findOne2 = async (finder, finderParams = {}, locations = []) => {
|
|
8370
|
-
|
|
8687
|
+
logger32.default("find", { finder, finderParams, locations });
|
|
8371
8688
|
const item = await cache.operations.findOne(finder, finderParams, locations);
|
|
8372
8689
|
if (!item) {
|
|
8373
8690
|
return null;
|
|
@@ -8376,7 +8693,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8376
8693
|
return populatedItem;
|
|
8377
8694
|
};
|
|
8378
8695
|
const set2 = async (key, v) => {
|
|
8379
|
-
|
|
8696
|
+
logger32.default("set", { key, v });
|
|
8380
8697
|
const item = await cache.operations.set(key, v);
|
|
8381
8698
|
const populatedItem = await populate(item);
|
|
8382
8699
|
return populatedItem;
|
|
@@ -8428,13 +8745,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8428
8745
|
import {
|
|
8429
8746
|
createRegistry as createBaseRegistry
|
|
8430
8747
|
} from "@fjell/registry";
|
|
8431
|
-
var
|
|
8748
|
+
var logger33 = logger_default.get("Registry");
|
|
8432
8749
|
var createRegistryFactory = () => {
|
|
8433
8750
|
return (type, registryHub) => {
|
|
8434
8751
|
if (type !== "cache") {
|
|
8435
8752
|
throw new Error(`Cache registry factory can only create 'cache' type registries, got: ${type}`);
|
|
8436
8753
|
}
|
|
8437
|
-
|
|
8754
|
+
logger33.debug("Creating cache registry", { type, registryHub });
|
|
8438
8755
|
const baseRegistry = createBaseRegistry(type, registryHub);
|
|
8439
8756
|
return baseRegistry;
|
|
8440
8757
|
};
|