@fjell/cache 4.7.60 → 4.7.62
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/Aggregator.d.ts +1 -1
- package/dist/Aggregator.d.ts.map +1 -1
- package/dist/Cache.d.ts +1 -2
- package/dist/Cache.d.ts.map +1 -1
- package/dist/CacheContext.d.ts +1 -2
- package/dist/CacheContext.d.ts.map +1 -1
- package/dist/CacheMap.d.ts +1 -1
- package/dist/CacheMap.d.ts.map +1 -1
- package/dist/CacheStats.d.ts +6 -0
- package/dist/CacheStats.d.ts.map +1 -1
- package/dist/Instance.d.ts +1 -2
- package/dist/Instance.d.ts.map +1 -1
- package/dist/InstanceFactory.d.ts +1 -1
- package/dist/InstanceFactory.d.ts.map +1 -1
- package/dist/Operations.d.ts +4 -3
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Options.d.ts +1 -1
- package/dist/Options.d.ts.map +1 -1
- package/dist/browser/AsyncIndexDBCacheMap.d.ts +1 -1
- package/dist/browser/AsyncIndexDBCacheMap.d.ts.map +1 -1
- package/dist/browser/IndexDBCacheMap.d.ts +1 -1
- package/dist/browser/IndexDBCacheMap.d.ts.map +1 -1
- package/dist/browser/LocalStorageCacheMap.d.ts +1 -1
- package/dist/browser/LocalStorageCacheMap.d.ts.map +1 -1
- package/dist/browser/SessionStorageCacheMap.d.ts +1 -1
- package/dist/browser/SessionStorageCacheMap.d.ts.map +1 -1
- package/dist/cache/TwoLayerFactory.d.ts +1 -1
- package/dist/cache/TwoLayerFactory.d.ts.map +1 -1
- package/dist/cache/layers/TwoLayerCacheMap.d.ts +1 -1
- package/dist/cache/layers/TwoLayerCacheMap.d.ts.map +1 -1
- package/dist/events/CacheEventEmitter.d.ts +1 -1
- package/dist/events/CacheEventEmitter.d.ts.map +1 -1
- package/dist/events/CacheEventFactory.d.ts +1 -1
- package/dist/events/CacheEventFactory.d.ts.map +1 -1
- package/dist/events/CacheEventTypes.d.ts +1 -1
- package/dist/events/CacheEventTypes.d.ts.map +1 -1
- package/dist/eviction/EvictionStrategyValidation.d.ts.map +1 -1
- package/dist/index.js +849 -229
- package/dist/memory/EnhancedMemoryCacheMap.d.ts +1 -1
- package/dist/memory/EnhancedMemoryCacheMap.d.ts.map +1 -1
- package/dist/memory/MemoryCacheMap.d.ts +1 -1
- package/dist/memory/MemoryCacheMap.d.ts.map +1 -1
- package/dist/normalization.d.ts +1 -1
- package/dist/normalization.d.ts.map +1 -1
- package/dist/ops/action.d.ts +1 -1
- package/dist/ops/action.d.ts.map +1 -1
- package/dist/ops/all.d.ts +1 -1
- package/dist/ops/all.d.ts.map +1 -1
- package/dist/ops/allAction.d.ts +1 -1
- package/dist/ops/allAction.d.ts.map +1 -1
- package/dist/ops/allFacet.d.ts +1 -1
- package/dist/ops/allFacet.d.ts.map +1 -1
- package/dist/ops/create.d.ts +1 -1
- package/dist/ops/create.d.ts.map +1 -1
- package/dist/ops/facet.d.ts +1 -1
- package/dist/ops/facet.d.ts.map +1 -1
- package/dist/ops/find.d.ts +1 -1
- package/dist/ops/find.d.ts.map +1 -1
- package/dist/ops/findOne.d.ts +1 -1
- package/dist/ops/findOne.d.ts.map +1 -1
- package/dist/ops/get.d.ts +1 -1
- package/dist/ops/get.d.ts.map +1 -1
- package/dist/ops/one.d.ts +1 -1
- package/dist/ops/one.d.ts.map +1 -1
- package/dist/ops/remove.d.ts +1 -1
- package/dist/ops/remove.d.ts.map +1 -1
- package/dist/ops/reset.d.ts +1 -1
- package/dist/ops/reset.d.ts.map +1 -1
- package/dist/ops/retrieve.d.ts +1 -1
- package/dist/ops/retrieve.d.ts.map +1 -1
- package/dist/ops/set.d.ts +1 -1
- package/dist/ops/set.d.ts.map +1 -1
- package/dist/ops/update.d.ts +1 -1
- package/dist/ops/update.d.ts.map +1 -1
- package/dist/ttl/TTLCalculator.d.ts.map +1 -1
- package/dist/ttl/TTLConfig.d.ts.map +1 -1
- package/dist/ttl/TTLManager.d.ts.map +1 -1
- package/dist/utils/cacheInvalidation.d.ts +1 -1
- package/dist/utils/cacheInvalidation.d.ts.map +1 -1
- package/package.json +9 -7
package/dist/index.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
// src/Operations.ts
|
|
2
|
-
import {
|
|
3
|
-
createAllFacetWrapper as createAllFacetWrapper2,
|
|
4
|
-
createAllWrapper as createAllWrapper2,
|
|
5
|
-
createCreateWrapper as createCreateWrapper2,
|
|
6
|
-
createGetWrapper as createGetWrapper2,
|
|
7
|
-
createOneWrapper as createOneWrapper2,
|
|
8
|
-
createRemoveWrapper as createRemoveWrapper2,
|
|
9
|
-
createUpdateWrapper as createUpdateWrapper2,
|
|
10
|
-
isOperationComKey as isComKey7,
|
|
11
|
-
isOperationPriKey as isPriKey
|
|
12
|
-
} from "@fjell/core";
|
|
2
|
+
import { createAllFacetWrapper as createAllFacetWrapper2, createAllWrapper as createAllWrapper2, createCreateWrapper as createCreateWrapper2, createGetWrapper as createGetWrapper2, createOneWrapper as createOneWrapper2, createRemoveWrapper as createRemoveWrapper2, createUpdateWrapper as createUpdateWrapper2, isComKey as isComKey8, isPriKey } from "@fjell/core";
|
|
13
3
|
|
|
14
4
|
// src/logger.ts
|
|
15
5
|
import Logging from "@fjell/logging";
|
|
@@ -606,7 +596,20 @@ var createQueryHash = (pkType, query, locations) => {
|
|
|
606
596
|
};
|
|
607
597
|
const hash = deterministicStringify(hashInput);
|
|
608
598
|
if (!hash || typeof hash !== "string" || hash.trim() === "") {
|
|
609
|
-
|
|
599
|
+
const errorContext = {
|
|
600
|
+
component: "cache",
|
|
601
|
+
subcomponent: "normalization",
|
|
602
|
+
operation: "createQueryHash",
|
|
603
|
+
pkType,
|
|
604
|
+
query: JSON.stringify(query),
|
|
605
|
+
locations: JSON.stringify(locations),
|
|
606
|
+
hashResult: hash,
|
|
607
|
+
suggestion: "This indicates a bug in query normalization. Check query and location structures."
|
|
608
|
+
};
|
|
609
|
+
console.error("Invalid query hash generated:", JSON.stringify(errorContext, null, 2));
|
|
610
|
+
throw new Error(
|
|
611
|
+
`Invalid query hash generated: hash is empty or invalid. Input: ${JSON.stringify({ pkType, query, locations })}. This indicates a bug in query normalization logic.`
|
|
612
|
+
);
|
|
610
613
|
}
|
|
611
614
|
return hash;
|
|
612
615
|
};
|
|
@@ -866,10 +869,27 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
866
869
|
logger4.debug("Cache bypass enabled, fetching directly from API", { query, locations });
|
|
867
870
|
try {
|
|
868
871
|
const ret = await api.all(query, locations, allOptions);
|
|
869
|
-
logger4.debug("API response received (not cached due to bypass)", {
|
|
872
|
+
logger4.debug("API response received (not cached due to bypass)", {
|
|
873
|
+
operation: "all",
|
|
874
|
+
mode: "bypass",
|
|
875
|
+
query,
|
|
876
|
+
locations,
|
|
877
|
+
itemCount: ret.items.length,
|
|
878
|
+
metadata: ret.metadata
|
|
879
|
+
});
|
|
870
880
|
return ret;
|
|
871
881
|
} catch (error) {
|
|
872
|
-
logger4.error("API request failed
|
|
882
|
+
logger4.error("API request failed in bypass mode", {
|
|
883
|
+
operation: "all",
|
|
884
|
+
mode: "bypass",
|
|
885
|
+
query,
|
|
886
|
+
locations,
|
|
887
|
+
errorType: error.constructor?.name || typeof error,
|
|
888
|
+
errorMessage: error.message,
|
|
889
|
+
errorCode: error.code || error.errorInfo?.code,
|
|
890
|
+
suggestion: "Verify API endpoint is accessible, query syntax is correct, and locations are valid",
|
|
891
|
+
error
|
|
892
|
+
});
|
|
873
893
|
throw error;
|
|
874
894
|
}
|
|
875
895
|
}
|
|
@@ -955,8 +975,15 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
955
975
|
}
|
|
956
976
|
} catch (error) {
|
|
957
977
|
logger4.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
|
|
978
|
+
operation: "all",
|
|
979
|
+
phase: "cache-query",
|
|
958
980
|
queryHash,
|
|
959
|
-
|
|
981
|
+
query: JSON.stringify(query),
|
|
982
|
+
locations: JSON.stringify(locations),
|
|
983
|
+
errorType: error.constructor?.name || typeof error,
|
|
984
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
985
|
+
cacheType: cacheMap.implementationType,
|
|
986
|
+
note: "This is expected behavior - falling back to API when cache query fails"
|
|
960
987
|
});
|
|
961
988
|
}
|
|
962
989
|
} else {
|
|
@@ -1031,9 +1058,19 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
1031
1058
|
await cacheMap.setQueryResult(queryHash, []);
|
|
1032
1059
|
logger4.debug("QUERY_CACHE: Cached empty query result for not found", { queryHash });
|
|
1033
1060
|
} else {
|
|
1034
|
-
logger4.
|
|
1061
|
+
logger4.error("QUERY_CACHE: API error occurred during all() operation", {
|
|
1062
|
+
operation: "all",
|
|
1063
|
+
phase: "api-fetch",
|
|
1035
1064
|
queryHash,
|
|
1036
|
-
|
|
1065
|
+
query: JSON.stringify(query),
|
|
1066
|
+
locations: JSON.stringify(locations),
|
|
1067
|
+
errorType: e instanceof Error ? e.constructor.name : typeof e,
|
|
1068
|
+
errorMessage: e instanceof Error ? e.message : String(e),
|
|
1069
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1070
|
+
cacheType: cacheMap.implementationType,
|
|
1071
|
+
inFlightRequestsCount: inFlightRequests.size,
|
|
1072
|
+
suggestion: "Check API connectivity, query syntax, location keys, and network connectivity",
|
|
1073
|
+
error: e
|
|
1037
1074
|
});
|
|
1038
1075
|
throw e;
|
|
1039
1076
|
}
|
|
@@ -1405,27 +1442,63 @@ var create = async (v, locations = [], context) => {
|
|
|
1405
1442
|
return [context, result];
|
|
1406
1443
|
};
|
|
1407
1444
|
async function executeCreateLogic(v, locations, context) {
|
|
1445
|
+
const startTime = Date.now();
|
|
1408
1446
|
const { api, cacheMap, pkType, eventEmitter, ttlManager, evictionManager } = context;
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1447
|
+
try {
|
|
1448
|
+
logger6.debug("CACHE_OP: create() started", {
|
|
1449
|
+
operation: "create",
|
|
1450
|
+
itemType: pkType,
|
|
1451
|
+
hasLocations: locations.length > 0,
|
|
1452
|
+
locationCount: locations.length,
|
|
1453
|
+
itemData: JSON.stringify(v)
|
|
1454
|
+
});
|
|
1455
|
+
const created = await api.create(v, locations.length > 0 ? { locations } : void 0);
|
|
1456
|
+
const apiDuration = Date.now() - startTime;
|
|
1457
|
+
cacheMap.set(created.key, created);
|
|
1458
|
+
const keyStr = JSON.stringify(created.key);
|
|
1459
|
+
ttlManager.onItemAdded(keyStr, cacheMap);
|
|
1460
|
+
const evictedKeys = await evictionManager.onItemAdded(keyStr, created, cacheMap);
|
|
1461
|
+
for (const evictedKey of evictedKeys) {
|
|
1462
|
+
const parsedKey = JSON.parse(evictedKey);
|
|
1463
|
+
await cacheMap.delete(parsedKey);
|
|
1464
|
+
}
|
|
1465
|
+
await cacheMap.clearQueryResults();
|
|
1466
|
+
const itemEvent = CacheEventFactory.itemCreated(created.key, created, "api");
|
|
1467
|
+
eventEmitter.emit(itemEvent);
|
|
1468
|
+
const queryInvalidatedEvent = CacheEventFactory.createQueryInvalidatedEvent(
|
|
1469
|
+
[],
|
|
1470
|
+
// We don't track which specific queries were invalidated
|
|
1471
|
+
"item_changed",
|
|
1472
|
+
{ source: "operation", context: { operation: "create" } }
|
|
1473
|
+
);
|
|
1474
|
+
eventEmitter.emit(queryInvalidatedEvent);
|
|
1475
|
+
const totalDuration = Date.now() - startTime;
|
|
1476
|
+
logger6.debug("CACHE_OP: create() completed successfully", {
|
|
1477
|
+
operation: "create",
|
|
1478
|
+
itemType: pkType,
|
|
1479
|
+
key: keyStr,
|
|
1480
|
+
evictedCount: evictedKeys.length,
|
|
1481
|
+
apiDuration,
|
|
1482
|
+
totalDuration
|
|
1483
|
+
});
|
|
1484
|
+
return created;
|
|
1485
|
+
} catch (e) {
|
|
1486
|
+
const duration = Date.now() - startTime;
|
|
1487
|
+
logger6.error("CACHE_OP: create() operation failed", {
|
|
1488
|
+
operation: "create",
|
|
1489
|
+
itemType: pkType,
|
|
1490
|
+
itemData: JSON.stringify(v),
|
|
1491
|
+
locations: JSON.stringify(locations),
|
|
1492
|
+
duration,
|
|
1493
|
+
errorType: e.constructor?.name || typeof e,
|
|
1494
|
+
errorMessage: e.message,
|
|
1495
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1496
|
+
cacheType: cacheMap.implementationType,
|
|
1497
|
+
suggestion: "Check validation errors, duplicate constraints, required fields, and API connectivity",
|
|
1498
|
+
stack: e.stack
|
|
1499
|
+
});
|
|
1500
|
+
throw e;
|
|
1417
1501
|
}
|
|
1418
|
-
await cacheMap.clearQueryResults();
|
|
1419
|
-
const itemEvent = CacheEventFactory.itemCreated(created.key, created, "api");
|
|
1420
|
-
eventEmitter.emit(itemEvent);
|
|
1421
|
-
const queryInvalidatedEvent = CacheEventFactory.createQueryInvalidatedEvent(
|
|
1422
|
-
[],
|
|
1423
|
-
// We don't track which specific queries were invalidated
|
|
1424
|
-
"item_changed",
|
|
1425
|
-
{ source: "operation", context: { operation: "create" } }
|
|
1426
|
-
);
|
|
1427
|
-
eventEmitter.emit(queryInvalidatedEvent);
|
|
1428
|
-
return created;
|
|
1429
1502
|
}
|
|
1430
1503
|
|
|
1431
1504
|
// src/ops/get.ts
|
|
@@ -1474,9 +1547,19 @@ async function executeGetLogic(key, context) {
|
|
|
1474
1547
|
cacheType: cacheMap.implementationType
|
|
1475
1548
|
});
|
|
1476
1549
|
statsManager.incrementRequests();
|
|
1550
|
+
if (key === null) {
|
|
1551
|
+
throw new Error("Key cannot be null");
|
|
1552
|
+
}
|
|
1477
1553
|
if (!isValidItemKey(key)) {
|
|
1478
|
-
logger7.error("CACHE_OP: Invalid key for get", {
|
|
1479
|
-
|
|
1554
|
+
logger7.error("CACHE_OP: Invalid key for get operation", {
|
|
1555
|
+
key: keyStr,
|
|
1556
|
+
keyType: typeof key,
|
|
1557
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1558
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }",
|
|
1559
|
+
itemType: pkType,
|
|
1560
|
+
coordinate: JSON.stringify(context.coordinate)
|
|
1561
|
+
});
|
|
1562
|
+
throw new Error(`Invalid key for get operation: ${keyStr}. Expected valid PriKey or ComKey structure.`);
|
|
1480
1563
|
}
|
|
1481
1564
|
if (context.options?.bypassCache) {
|
|
1482
1565
|
logger7.debug("CACHE_OP: Cache bypass enabled, fetching directly from API", { key: keyStr });
|
|
@@ -1501,8 +1584,15 @@ async function executeGetLogic(key, context) {
|
|
|
1501
1584
|
}
|
|
1502
1585
|
} catch (error) {
|
|
1503
1586
|
logger7.error("CACHE_OP: API request failed in bypass mode", {
|
|
1587
|
+
operation: "get",
|
|
1588
|
+
mode: "bypass",
|
|
1504
1589
|
key: keyStr,
|
|
1590
|
+
itemType: pkType,
|
|
1505
1591
|
duration: Date.now() - startTime,
|
|
1592
|
+
errorType: error.constructor?.name || typeof error,
|
|
1593
|
+
errorMessage: error.message,
|
|
1594
|
+
errorCode: error.code || error.errorInfo?.code,
|
|
1595
|
+
suggestion: "Verify API endpoint is accessible and key exists. Cache bypass mode does not retry.",
|
|
1506
1596
|
error
|
|
1507
1597
|
});
|
|
1508
1598
|
throw error;
|
|
@@ -1671,10 +1761,19 @@ async function executeGetLogic(key, context) {
|
|
|
1671
1761
|
} catch (e) {
|
|
1672
1762
|
inFlightRequests2.delete(requestKeyStr);
|
|
1673
1763
|
const duration = Date.now() - startTime;
|
|
1674
|
-
logger7.error("CACHE_OP:
|
|
1764
|
+
logger7.error("CACHE_OP: get() operation failed", {
|
|
1765
|
+
operation: "get",
|
|
1675
1766
|
key: keyStr,
|
|
1767
|
+
itemType: pkType,
|
|
1676
1768
|
duration,
|
|
1677
|
-
|
|
1769
|
+
errorType: e.constructor?.name || typeof e,
|
|
1770
|
+
errorMessage: e.message,
|
|
1771
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1772
|
+
cacheType: cacheMap.implementationType,
|
|
1773
|
+
ttlEnabled: ttlManager.isTTLEnabled(),
|
|
1774
|
+
bypassMode: context.options?.bypassCache || false,
|
|
1775
|
+
inFlightRequestsCount: inFlightRequests2.size,
|
|
1776
|
+
suggestion: "Check API connectivity, key validity, and cache configuration",
|
|
1678
1777
|
stack: e.stack
|
|
1679
1778
|
});
|
|
1680
1779
|
throw e;
|
|
@@ -1698,6 +1797,9 @@ var retrieve = async (key, context) => {
|
|
|
1698
1797
|
bypassEnabled: !!context.options?.bypassCache
|
|
1699
1798
|
});
|
|
1700
1799
|
statsManager.incrementRequests();
|
|
1800
|
+
if (key === null) {
|
|
1801
|
+
throw new Error("Key cannot be null");
|
|
1802
|
+
}
|
|
1701
1803
|
if (!isValidItemKey2(key)) {
|
|
1702
1804
|
logger8.error("CACHE_OP: Invalid key for retrieve", { key: keyStr });
|
|
1703
1805
|
throw new Error("Key for Retrieve is not a valid ItemKey");
|
|
@@ -1798,13 +1900,30 @@ var remove = async (key, context) => {
|
|
|
1798
1900
|
};
|
|
1799
1901
|
async function executeRemoveLogic(key, context) {
|
|
1800
1902
|
const { api, cacheMap } = context;
|
|
1903
|
+
const keyStr = JSON.stringify(key);
|
|
1904
|
+
if (key === null) {
|
|
1905
|
+
throw new Error("Key cannot be null");
|
|
1906
|
+
}
|
|
1801
1907
|
if (!isValidItemKey3(key)) {
|
|
1802
|
-
logger9.error("
|
|
1803
|
-
|
|
1908
|
+
logger9.error("CACHE_OP: Invalid key for remove operation", {
|
|
1909
|
+
operation: "remove",
|
|
1910
|
+
key: keyStr,
|
|
1911
|
+
keyType: typeof key,
|
|
1912
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1913
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }"
|
|
1914
|
+
});
|
|
1915
|
+
throw new Error(`Invalid key for remove operation: ${keyStr}. Expected valid PriKey or ComKey structure.`);
|
|
1804
1916
|
}
|
|
1917
|
+
const startTime = Date.now();
|
|
1805
1918
|
try {
|
|
1919
|
+
logger9.debug("CACHE_OP: remove() started", {
|
|
1920
|
+
operation: "remove",
|
|
1921
|
+
key: keyStr,
|
|
1922
|
+
cacheType: cacheMap.implementationType
|
|
1923
|
+
});
|
|
1806
1924
|
const previousItem = await cacheMap.get(key);
|
|
1807
1925
|
await api.remove(key);
|
|
1926
|
+
const apiDuration = Date.now() - startTime;
|
|
1808
1927
|
cacheMap.delete(key);
|
|
1809
1928
|
await cacheMap.clearQueryResults();
|
|
1810
1929
|
if (previousItem) {
|
|
@@ -1817,9 +1936,27 @@ async function executeRemoveLogic(key, context) {
|
|
|
1817
1936
|
{ source: "operation", context: { operation: "remove" } }
|
|
1818
1937
|
);
|
|
1819
1938
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
1820
|
-
|
|
1939
|
+
const totalDuration = Date.now() - startTime;
|
|
1940
|
+
logger9.debug("CACHE_OP: remove() completed successfully", {
|
|
1941
|
+
operation: "remove",
|
|
1942
|
+
key: keyStr,
|
|
1943
|
+
hadCachedItem: !!previousItem,
|
|
1944
|
+
apiDuration,
|
|
1945
|
+
totalDuration
|
|
1946
|
+
});
|
|
1821
1947
|
} catch (e) {
|
|
1822
|
-
|
|
1948
|
+
const duration = Date.now() - startTime;
|
|
1949
|
+
logger9.error("CACHE_OP: remove() operation failed", {
|
|
1950
|
+
operation: "remove",
|
|
1951
|
+
key: keyStr,
|
|
1952
|
+
duration,
|
|
1953
|
+
errorType: e.constructor?.name || typeof e,
|
|
1954
|
+
errorMessage: e.message,
|
|
1955
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1956
|
+
cacheType: cacheMap.implementationType,
|
|
1957
|
+
suggestion: "Check item exists, delete permissions, referential integrity constraints, and API connectivity",
|
|
1958
|
+
stack: e.stack
|
|
1959
|
+
});
|
|
1823
1960
|
throw e;
|
|
1824
1961
|
}
|
|
1825
1962
|
}
|
|
@@ -1844,34 +1981,56 @@ var update = async (key, v, context) => {
|
|
|
1844
1981
|
};
|
|
1845
1982
|
async function executeUpdateLogic(key, v, context) {
|
|
1846
1983
|
const { api, cacheMap, pkType } = context;
|
|
1984
|
+
if (key === null) {
|
|
1985
|
+
throw new Error("Key cannot be null");
|
|
1986
|
+
}
|
|
1847
1987
|
if (!isValidItemKey4(key)) {
|
|
1848
|
-
logger10.error("
|
|
1849
|
-
|
|
1988
|
+
logger10.error("CACHE_OP: Invalid key for update operation", {
|
|
1989
|
+
operation: "update",
|
|
1990
|
+
key: JSON.stringify(key),
|
|
1991
|
+
keyType: typeof key,
|
|
1992
|
+
itemType: pkType,
|
|
1993
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1994
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }"
|
|
1995
|
+
});
|
|
1996
|
+
throw new Error(`Invalid key for update operation: ${JSON.stringify(key)}. Expected valid PriKey or ComKey structure.`);
|
|
1850
1997
|
}
|
|
1851
1998
|
logger10.debug("Invalidating item key before update", { key });
|
|
1852
1999
|
cacheMap.invalidateItemKeys([key]);
|
|
1853
2000
|
await cacheMap.clearQueryResults();
|
|
2001
|
+
const startTime = Date.now();
|
|
2002
|
+
const keyStr = JSON.stringify(key);
|
|
1854
2003
|
try {
|
|
2004
|
+
logger10.debug("CACHE_OP: update() started", {
|
|
2005
|
+
operation: "update",
|
|
2006
|
+
key: keyStr,
|
|
2007
|
+
itemType: pkType,
|
|
2008
|
+
updateData: JSON.stringify(v)
|
|
2009
|
+
});
|
|
1855
2010
|
const previousItem = await cacheMap.get(key);
|
|
1856
2011
|
const updated = await api.update(key, v);
|
|
1857
|
-
|
|
2012
|
+
const apiDuration = Date.now() - startTime;
|
|
2013
|
+
logger10.debug("CACHE_OP: Caching update result", {
|
|
2014
|
+
operation: "update",
|
|
2015
|
+
updatedKey: JSON.stringify(updated.key)
|
|
2016
|
+
});
|
|
1858
2017
|
await cacheMap.set(updated.key, updated);
|
|
1859
2018
|
const cachedItem = await cacheMap.get(updated.key);
|
|
1860
|
-
const
|
|
1861
|
-
const metadata = await cacheMap.getMetadata(
|
|
2019
|
+
const updatedKeyStr = JSON.stringify(updated.key);
|
|
2020
|
+
const metadata = await cacheMap.getMetadata(updatedKeyStr);
|
|
1862
2021
|
if (!metadata) {
|
|
1863
2022
|
const now = Date.now();
|
|
1864
2023
|
const baseMetadata = {
|
|
1865
|
-
key:
|
|
2024
|
+
key: updatedKeyStr,
|
|
1866
2025
|
addedAt: now,
|
|
1867
2026
|
lastAccessedAt: now,
|
|
1868
2027
|
accessCount: 1,
|
|
1869
2028
|
estimatedSize: estimateValueSize(updated)
|
|
1870
2029
|
};
|
|
1871
|
-
await cacheMap.setMetadata(
|
|
2030
|
+
await cacheMap.setMetadata(updatedKeyStr, baseMetadata);
|
|
1872
2031
|
}
|
|
1873
|
-
await context.ttlManager.onItemAdded(
|
|
1874
|
-
const evictedKeys = await context.evictionManager.onItemAdded(
|
|
2032
|
+
await context.ttlManager.onItemAdded(updatedKeyStr, cacheMap);
|
|
2033
|
+
const evictedKeys = await context.evictionManager.onItemAdded(updatedKeyStr, updated, cacheMap);
|
|
1875
2034
|
for (const evictedKey of evictedKeys) {
|
|
1876
2035
|
const parsedKey = JSON.parse(evictedKey);
|
|
1877
2036
|
await cacheMap.delete(parsedKey);
|
|
@@ -1885,9 +2044,31 @@ async function executeUpdateLogic(key, v, context) {
|
|
|
1885
2044
|
{ source: "operation", context: { operation: "update" } }
|
|
1886
2045
|
);
|
|
1887
2046
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
2047
|
+
const totalDuration = Date.now() - startTime;
|
|
2048
|
+
logger10.debug("CACHE_OP: update() completed successfully", {
|
|
2049
|
+
operation: "update",
|
|
2050
|
+
key: updatedKeyStr,
|
|
2051
|
+
itemType: pkType,
|
|
2052
|
+
evictedCount: evictedKeys.length,
|
|
2053
|
+
apiDuration,
|
|
2054
|
+
totalDuration
|
|
2055
|
+
});
|
|
1888
2056
|
return updated;
|
|
1889
2057
|
} catch (e) {
|
|
1890
|
-
|
|
2058
|
+
const duration = Date.now() - startTime;
|
|
2059
|
+
logger10.error("CACHE_OP: update() operation failed", {
|
|
2060
|
+
operation: "update",
|
|
2061
|
+
key: keyStr,
|
|
2062
|
+
itemType: pkType,
|
|
2063
|
+
updateData: JSON.stringify(v),
|
|
2064
|
+
duration,
|
|
2065
|
+
errorType: e.constructor?.name || typeof e,
|
|
2066
|
+
errorMessage: e.message,
|
|
2067
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
2068
|
+
cacheType: cacheMap.implementationType,
|
|
2069
|
+
suggestion: "Check item exists, validation rules, update permissions, and API connectivity",
|
|
2070
|
+
stack: e.stack
|
|
2071
|
+
});
|
|
1891
2072
|
throw e;
|
|
1892
2073
|
}
|
|
1893
2074
|
}
|
|
@@ -1899,7 +2080,7 @@ import {
|
|
|
1899
2080
|
} from "@fjell/core";
|
|
1900
2081
|
|
|
1901
2082
|
// src/utils/cacheInvalidation.ts
|
|
1902
|
-
import { toKeyTypeArray } from "@fjell/core";
|
|
2083
|
+
import { isComKey, toKeyTypeArray } from "@fjell/core";
|
|
1903
2084
|
var logger11 = logger_default.get("cache", "utils", "cacheInvalidation");
|
|
1904
2085
|
var extractKeysAndKeyTypesFromActionResult = (affectedItems) => {
|
|
1905
2086
|
const keys = [];
|
|
@@ -1923,7 +2104,7 @@ var invalidateCachesByKeysAndKeyTypes = async (registry, keys, keyTypeArrays) =>
|
|
|
1923
2104
|
});
|
|
1924
2105
|
const keysByKeyTypes = /* @__PURE__ */ new Map();
|
|
1925
2106
|
for (const key of keys) {
|
|
1926
|
-
const keyTypes =
|
|
2107
|
+
const keyTypes = isComKey(key) ? [key.kt, ...key.loc.map((locKey) => locKey.kt)] : [key.kt];
|
|
1927
2108
|
const keyTypesKey = keyTypes.join("|");
|
|
1928
2109
|
if (!keysByKeyTypes.has(keyTypesKey)) {
|
|
1929
2110
|
keysByKeyTypes.set(keyTypesKey, []);
|
|
@@ -1999,6 +2180,9 @@ var action = async (key, action2, body = {}, context) => {
|
|
|
1999
2180
|
};
|
|
2000
2181
|
async function executeActionLogic(key, action2, body, context) {
|
|
2001
2182
|
const { api, cacheMap, pkType, registry } = context;
|
|
2183
|
+
if (key === null) {
|
|
2184
|
+
throw new Error("Key cannot be null");
|
|
2185
|
+
}
|
|
2002
2186
|
if (!isValidItemKey5(key)) {
|
|
2003
2187
|
logger12.error("Key for Action is not a valid ItemKey: %j", key);
|
|
2004
2188
|
throw new Error("Key for Action is not a valid ItemKey");
|
|
@@ -2585,14 +2769,19 @@ var normalizeKey = (key) => {
|
|
|
2585
2769
|
return key;
|
|
2586
2770
|
};
|
|
2587
2771
|
var set = async (key, v, context) => {
|
|
2772
|
+
if (key === null) {
|
|
2773
|
+
throw new Error("Key cannot be null");
|
|
2774
|
+
}
|
|
2775
|
+
if (typeof key === "undefined") {
|
|
2776
|
+
throw new Error("Key for Set is not a valid ItemKey");
|
|
2777
|
+
}
|
|
2588
2778
|
const startTime = Date.now();
|
|
2589
2779
|
const { cacheMap, pkType, ttlManager, evictionManager, eventEmitter } = context;
|
|
2590
2780
|
const keyStr = JSON.stringify(key);
|
|
2781
|
+
if (v === null || typeof v === "undefined") {
|
|
2782
|
+
throw new Error("Item cannot be null");
|
|
2783
|
+
}
|
|
2591
2784
|
logger18.default("set", { key, v });
|
|
2592
|
-
logger18.debug("CACHE_OP: set() started", {
|
|
2593
|
-
key: keyStr,
|
|
2594
|
-
cacheType: cacheMap.implementationType
|
|
2595
|
-
});
|
|
2596
2785
|
if (!isValidItemKey6(key)) {
|
|
2597
2786
|
logger18.error("CACHE_OP: Invalid key for set", { key: keyStr });
|
|
2598
2787
|
throw new Error("Key for Set is not a valid ItemKey");
|
|
@@ -2677,7 +2866,7 @@ var set = async (key, v, context) => {
|
|
|
2677
2866
|
|
|
2678
2867
|
// src/memory/MemoryCacheMap.ts
|
|
2679
2868
|
import {
|
|
2680
|
-
isComKey,
|
|
2869
|
+
isComKey as isComKey2,
|
|
2681
2870
|
isQueryMatch
|
|
2682
2871
|
} from "@fjell/core";
|
|
2683
2872
|
var logger19 = logger_default.get("MemoryCacheMap");
|
|
@@ -2781,7 +2970,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2781
2970
|
logger19.debug("allIn", { locations, count: allValues.length });
|
|
2782
2971
|
return allValues.filter((item) => {
|
|
2783
2972
|
const key = item.key;
|
|
2784
|
-
if (key &&
|
|
2973
|
+
if (key && isComKey2(key)) {
|
|
2785
2974
|
const comKey = key;
|
|
2786
2975
|
return isLocKeyArrayEqual(locations, comKey.loc);
|
|
2787
2976
|
}
|
|
@@ -2897,7 +3086,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2897
3086
|
let keysToInvalidate = [];
|
|
2898
3087
|
if (locations.length === 0) {
|
|
2899
3088
|
const allKeys = await this.keys();
|
|
2900
|
-
const primaryKeys = allKeys.filter((key) => !
|
|
3089
|
+
const primaryKeys = allKeys.filter((key) => !isComKey2(key));
|
|
2901
3090
|
keysToInvalidate = primaryKeys;
|
|
2902
3091
|
} else {
|
|
2903
3092
|
const itemsInLocation = await this.allIn(locations);
|
|
@@ -2945,7 +3134,7 @@ var MemoryCacheMap = class _MemoryCacheMap extends CacheMap {
|
|
|
2945
3134
|
|
|
2946
3135
|
// src/memory/EnhancedMemoryCacheMap.ts
|
|
2947
3136
|
import {
|
|
2948
|
-
isComKey as
|
|
3137
|
+
isComKey as isComKey3,
|
|
2949
3138
|
isQueryMatch as isQueryMatch2
|
|
2950
3139
|
} from "@fjell/core";
|
|
2951
3140
|
var logger20 = logger_default.get("EnhancedMemoryCacheMap");
|
|
@@ -3089,7 +3278,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3089
3278
|
logger20.debug("allIn", { locations, count: allValues.length });
|
|
3090
3279
|
return allValues.filter((item) => {
|
|
3091
3280
|
const key = item.key;
|
|
3092
|
-
if (key &&
|
|
3281
|
+
if (key && isComKey3(key)) {
|
|
3093
3282
|
return isLocKeyArrayEqual(locations, key.loc);
|
|
3094
3283
|
}
|
|
3095
3284
|
return false;
|
|
@@ -3249,7 +3438,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3249
3438
|
let keysToInvalidate = [];
|
|
3250
3439
|
if (locations.length === 0) {
|
|
3251
3440
|
const allKeys = await this.keys();
|
|
3252
|
-
const primaryKeys = allKeys.filter((key) => !
|
|
3441
|
+
const primaryKeys = allKeys.filter((key) => !isComKey3(key));
|
|
3253
3442
|
keysToInvalidate = primaryKeys;
|
|
3254
3443
|
} else {
|
|
3255
3444
|
const itemsInLocation = await this.allIn(locations);
|
|
@@ -3363,7 +3552,7 @@ var EnhancedMemoryCacheMap = class _EnhancedMemoryCacheMap extends CacheMap {
|
|
|
3363
3552
|
|
|
3364
3553
|
// src/browser/LocalStorageCacheMap.ts
|
|
3365
3554
|
import {
|
|
3366
|
-
isComKey as
|
|
3555
|
+
isComKey as isComKey4,
|
|
3367
3556
|
isQueryMatch as isQueryMatch3
|
|
3368
3557
|
} from "@fjell/core";
|
|
3369
3558
|
var logger21 = logger_default.get("LocalStorageCacheMap");
|
|
@@ -3524,7 +3713,17 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3524
3713
|
const useAggressiveCleanup = attempt > 0;
|
|
3525
3714
|
this.tryCleanupOldEntries(useAggressiveCleanup);
|
|
3526
3715
|
if (isLastAttempt) {
|
|
3527
|
-
|
|
3716
|
+
logger21.error("LocalStorage quota exceeded after all cleanup attempts", {
|
|
3717
|
+
component: "cache",
|
|
3718
|
+
subcomponent: "LocalStorageCacheMap",
|
|
3719
|
+
operation: "set",
|
|
3720
|
+
key: JSON.stringify(key),
|
|
3721
|
+
retryAttempts: attempt + 1,
|
|
3722
|
+
suggestion: "Reduce cache size limits, clear more data, or use IndexedDB for larger storage needs"
|
|
3723
|
+
});
|
|
3724
|
+
throw new Error(
|
|
3725
|
+
"Failed to store item in localStorage: storage quota exceeded even after multiple cleanup attempts. Suggestion: Reduce maxItems in memoryConfig, clear old data, or switch to IndexedDB for larger storage."
|
|
3726
|
+
);
|
|
3528
3727
|
}
|
|
3529
3728
|
continue;
|
|
3530
3729
|
}
|
|
@@ -3577,13 +3776,13 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3577
3776
|
const locKeys = locations;
|
|
3578
3777
|
const resolvedKeys = await allKeys;
|
|
3579
3778
|
logger21.debug("allIn", { locKeys, keys: resolvedKeys.length });
|
|
3580
|
-
const filteredKeys = resolvedKeys.filter((key) => key &&
|
|
3581
|
-
const
|
|
3779
|
+
const filteredKeys = resolvedKeys.filter((key) => key && isComKey4(key)).filter((key) => {
|
|
3780
|
+
const ComKey = key;
|
|
3582
3781
|
logger21.debug("Comparing Location Keys", {
|
|
3583
3782
|
locKeys,
|
|
3584
|
-
ComKey
|
|
3783
|
+
ComKey
|
|
3585
3784
|
});
|
|
3586
|
-
return isLocKeyArrayEqual(locKeys,
|
|
3785
|
+
return isLocKeyArrayEqual(locKeys, ComKey.loc);
|
|
3587
3786
|
});
|
|
3588
3787
|
const items = [];
|
|
3589
3788
|
for (const key of filteredKeys) {
|
|
@@ -3665,8 +3864,18 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3665
3864
|
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
3666
3865
|
logger21.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
3667
3866
|
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3668
|
-
logger21.error("Invalid queryHash provided to setQueryResult", {
|
|
3669
|
-
|
|
3867
|
+
logger21.error("Invalid queryHash provided to setQueryResult", {
|
|
3868
|
+
component: "cache",
|
|
3869
|
+
subcomponent: "LocalStorageCacheMap",
|
|
3870
|
+
operation: "setQueryResult",
|
|
3871
|
+
queryHash,
|
|
3872
|
+
queryHashType: typeof queryHash,
|
|
3873
|
+
itemKeys,
|
|
3874
|
+
suggestion: "Ensure queryHash is a non-empty string generated from query normalization"
|
|
3875
|
+
});
|
|
3876
|
+
throw new Error(
|
|
3877
|
+
`Invalid queryHash provided to setQueryResult: ${JSON.stringify(queryHash)}. Expected non-empty string, got ${typeof queryHash}. This usually indicates a bug in query hash generation.`
|
|
3878
|
+
);
|
|
3670
3879
|
}
|
|
3671
3880
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3672
3881
|
const entry = {
|
|
@@ -3820,7 +4029,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3820
4029
|
let keysToInvalidate = [];
|
|
3821
4030
|
if (locations.length === 0) {
|
|
3822
4031
|
const allKeys = await this.keys();
|
|
3823
|
-
const primaryKeys = allKeys.filter((key) => !
|
|
4032
|
+
const primaryKeys = allKeys.filter((key) => !isComKey4(key));
|
|
3824
4033
|
keysToInvalidate = primaryKeys;
|
|
3825
4034
|
} else {
|
|
3826
4035
|
const itemsInLocation = await this.allIn(locations);
|
|
@@ -3985,7 +4194,7 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3985
4194
|
|
|
3986
4195
|
// src/browser/SessionStorageCacheMap.ts
|
|
3987
4196
|
import {
|
|
3988
|
-
isComKey as
|
|
4197
|
+
isComKey as isComKey5,
|
|
3989
4198
|
isQueryMatch as isQueryMatch4
|
|
3990
4199
|
} from "@fjell/core";
|
|
3991
4200
|
import safeStringify2 from "fast-safe-stringify";
|
|
@@ -4081,8 +4290,19 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4081
4290
|
const jsonString = safeStringify2(toStore);
|
|
4082
4291
|
sessionStorage.setItem(storageKey, jsonString);
|
|
4083
4292
|
} catch (error) {
|
|
4084
|
-
|
|
4085
|
-
|
|
4293
|
+
const isQuotaError = error?.name === "QuotaExceededError" || error?.message?.includes("quota") || error?.code === 22;
|
|
4294
|
+
logger22.error("Error storing to sessionStorage", {
|
|
4295
|
+
component: "cache",
|
|
4296
|
+
subcomponent: "SessionStorageCacheMap",
|
|
4297
|
+
operation: "set",
|
|
4298
|
+
key: JSON.stringify(key),
|
|
4299
|
+
errorType: error?.name,
|
|
4300
|
+
errorMessage: error?.message,
|
|
4301
|
+
isQuotaError,
|
|
4302
|
+
suggestion: isQuotaError ? "SessionStorage quota exceeded. Clear old data, reduce cache size, or use IndexedDB instead." : "Check browser sessionStorage support and data serializability."
|
|
4303
|
+
});
|
|
4304
|
+
const errorMsg = isQuotaError ? "SessionStorage quota exceeded. Try clearing old cache data or reducing cache size." : `Failed to store item in sessionStorage: ${error?.message || error}`;
|
|
4305
|
+
throw new Error(errorMsg);
|
|
4086
4306
|
}
|
|
4087
4307
|
}
|
|
4088
4308
|
async includesKey(key) {
|
|
@@ -4131,13 +4351,13 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4131
4351
|
const locKeys = locations;
|
|
4132
4352
|
const resolvedKeys = await allKeys;
|
|
4133
4353
|
logger22.debug("allIn", { locKeys, keys: resolvedKeys.length });
|
|
4134
|
-
const filteredKeys = resolvedKeys.filter((key) => key &&
|
|
4135
|
-
const
|
|
4354
|
+
const filteredKeys = resolvedKeys.filter((key) => key && isComKey5(key)).filter((key) => {
|
|
4355
|
+
const ComKey = key;
|
|
4136
4356
|
logger22.debug("Comparing Location Keys", {
|
|
4137
4357
|
locKeys,
|
|
4138
|
-
ComKey
|
|
4358
|
+
ComKey
|
|
4139
4359
|
});
|
|
4140
|
-
return isLocKeyArrayEqual(locKeys,
|
|
4360
|
+
return isLocKeyArrayEqual(locKeys, ComKey.loc);
|
|
4141
4361
|
});
|
|
4142
4362
|
const items = [];
|
|
4143
4363
|
for (const key of filteredKeys) {
|
|
@@ -4460,7 +4680,7 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4460
4680
|
let keysToInvalidate = [];
|
|
4461
4681
|
if (locations.length === 0) {
|
|
4462
4682
|
const allKeys = await this.keys();
|
|
4463
|
-
const primaryKeys = allKeys.filter((key) => !
|
|
4683
|
+
const primaryKeys = allKeys.filter((key) => !isComKey5(key));
|
|
4464
4684
|
keysToInvalidate = primaryKeys;
|
|
4465
4685
|
} else {
|
|
4466
4686
|
const itemsInLocation = await this.allIn(locations);
|
|
@@ -4512,13 +4732,13 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4512
4732
|
|
|
4513
4733
|
// src/browser/IndexDBCacheMap.ts
|
|
4514
4734
|
import {
|
|
4515
|
-
isComKey as
|
|
4735
|
+
isComKey as isComKey7,
|
|
4516
4736
|
isQueryMatch as isQueryMatch6
|
|
4517
4737
|
} from "@fjell/core";
|
|
4518
4738
|
|
|
4519
4739
|
// src/browser/AsyncIndexDBCacheMap.ts
|
|
4520
4740
|
import {
|
|
4521
|
-
isComKey as
|
|
4741
|
+
isComKey as isComKey6,
|
|
4522
4742
|
isQueryMatch as isQueryMatch5
|
|
4523
4743
|
} from "@fjell/core";
|
|
4524
4744
|
import safeStringify3 from "fast-safe-stringify";
|
|
@@ -4667,8 +4887,18 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4667
4887
|
try {
|
|
4668
4888
|
storageKey = this.getStorageKey(key);
|
|
4669
4889
|
} catch (keyError) {
|
|
4670
|
-
logger23.
|
|
4671
|
-
|
|
4890
|
+
logger23.error("Storage key generation failed", {
|
|
4891
|
+
component: "cache",
|
|
4892
|
+
subcomponent: "AsyncIndexDBCacheMap",
|
|
4893
|
+
operation: "set",
|
|
4894
|
+
key: JSON.stringify(key),
|
|
4895
|
+
errorType: keyError?.constructor?.name,
|
|
4896
|
+
errorMessage: keyError?.message,
|
|
4897
|
+
suggestion: "Check key structure and normalization logic"
|
|
4898
|
+
});
|
|
4899
|
+
throw new Error(
|
|
4900
|
+
`Failed to generate storage key for IndexedDB: ${keyError?.message || keyError}. Key: ${JSON.stringify(key)}. This indicates a key normalization issue.`
|
|
4901
|
+
);
|
|
4672
4902
|
}
|
|
4673
4903
|
const storedItem = {
|
|
4674
4904
|
originalKey: key,
|
|
@@ -4692,8 +4922,19 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4692
4922
|
}
|
|
4693
4923
|
});
|
|
4694
4924
|
} catch (error) {
|
|
4695
|
-
|
|
4696
|
-
|
|
4925
|
+
const isQuotaError = error?.name === "QuotaExceededError" || error?.message?.includes("quota");
|
|
4926
|
+
logger23.error("Error in IndexedDB set operation", {
|
|
4927
|
+
component: "cache",
|
|
4928
|
+
subcomponent: "AsyncIndexDBCacheMap",
|
|
4929
|
+
operation: "set",
|
|
4930
|
+
key: JSON.stringify(key),
|
|
4931
|
+
errorType: error?.name,
|
|
4932
|
+
errorMessage: error?.message,
|
|
4933
|
+
isQuotaError,
|
|
4934
|
+
suggestion: isQuotaError ? "IndexedDB quota exceeded. Clear old data, reduce cache size, or request more storage quota." : "Check IndexedDB support, permissions, and data serializability."
|
|
4935
|
+
});
|
|
4936
|
+
const errorMsg = isQuotaError ? "IndexedDB quota exceeded. Try clearing old cache data or reducing cache size." : `Failed to store item in IndexedDB: ${error?.message || error}`;
|
|
4937
|
+
throw new Error(errorMsg);
|
|
4697
4938
|
}
|
|
4698
4939
|
}
|
|
4699
4940
|
/**
|
|
@@ -4793,13 +5034,13 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4793
5034
|
} else {
|
|
4794
5035
|
const locKeys = locations;
|
|
4795
5036
|
logger23.debug("allIn", { locKeys, keys: allKeys.length });
|
|
4796
|
-
const filteredKeys = allKeys.filter((key) => key &&
|
|
4797
|
-
const
|
|
5037
|
+
const filteredKeys = allKeys.filter((key) => key && isComKey6(key)).filter((key) => {
|
|
5038
|
+
const ComKey = key;
|
|
4798
5039
|
logger23.debug("Comparing Location Keys", {
|
|
4799
5040
|
locKeys,
|
|
4800
|
-
ComKey
|
|
5041
|
+
ComKey
|
|
4801
5042
|
});
|
|
4802
|
-
return isLocKeyArrayEqual(locKeys,
|
|
5043
|
+
return isLocKeyArrayEqual(locKeys, ComKey.loc);
|
|
4803
5044
|
});
|
|
4804
5045
|
const promises = filteredKeys.map((key) => this.get(key));
|
|
4805
5046
|
const results = await Promise.all(promises);
|
|
@@ -5412,7 +5653,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5412
5653
|
const key = entry.originalKey;
|
|
5413
5654
|
if (locations.length === 0) {
|
|
5414
5655
|
result.push(entry.value);
|
|
5415
|
-
} else if (
|
|
5656
|
+
} else if (isComKey7(key)) {
|
|
5416
5657
|
if (isLocKeyArrayEqual(key.loc, locations)) {
|
|
5417
5658
|
result.push(entry.value);
|
|
5418
5659
|
}
|
|
@@ -5514,7 +5755,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5514
5755
|
const itemsToDelete = [];
|
|
5515
5756
|
for (const entry of Object.values(this.memoryMap)) {
|
|
5516
5757
|
const key = entry.originalKey;
|
|
5517
|
-
if (
|
|
5758
|
+
if (isComKey7(key) && isLocKeyArrayEqual(key.loc, locations)) {
|
|
5518
5759
|
itemsToDelete.push(key);
|
|
5519
5760
|
}
|
|
5520
5761
|
}
|
|
@@ -5573,6 +5814,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5573
5814
|
};
|
|
5574
5815
|
|
|
5575
5816
|
// src/Options.ts
|
|
5817
|
+
var logger25 = logger_default.get("Options");
|
|
5576
5818
|
var DEFAULT_CACHE_OPTIONS = {
|
|
5577
5819
|
cacheType: "memory",
|
|
5578
5820
|
enableDebugLogging: false,
|
|
@@ -5676,12 +5918,29 @@ var createCacheMap = (kta, options) => {
|
|
|
5676
5918
|
break;
|
|
5677
5919
|
case "custom":
|
|
5678
5920
|
if (!options.customCacheMapFactory) {
|
|
5679
|
-
|
|
5921
|
+
logger25.error("Custom cache map factory missing", {
|
|
5922
|
+
component: "cache",
|
|
5923
|
+
operation: "createCacheMap",
|
|
5924
|
+
cacheType: "custom",
|
|
5925
|
+
suggestion: 'Provide customCacheMapFactory function in cache options when using cacheType: "custom"'
|
|
5926
|
+
});
|
|
5927
|
+
throw new Error(
|
|
5928
|
+
'Custom cache map factory is required when cacheType is "custom". Provide customCacheMapFactory in cache options.'
|
|
5929
|
+
);
|
|
5680
5930
|
}
|
|
5681
5931
|
underlyingCache = options.customCacheMapFactory(kta);
|
|
5682
5932
|
break;
|
|
5683
5933
|
default:
|
|
5684
|
-
|
|
5934
|
+
logger25.error("Unsupported cache type", {
|
|
5935
|
+
component: "cache",
|
|
5936
|
+
operation: "createCacheMap",
|
|
5937
|
+
cacheType: options.cacheType,
|
|
5938
|
+
validTypes: ["memory", "localStorage", "sessionStorage", "indexedDB", "asyncIndexedDB", "custom"],
|
|
5939
|
+
suggestion: "Use one of: memory, localStorage, sessionStorage, indexedDB, asyncIndexedDB, or custom"
|
|
5940
|
+
});
|
|
5941
|
+
throw new Error(
|
|
5942
|
+
`Unsupported cache type: ${options.cacheType}. Valid types: memory, localStorage, sessionStorage, indexedDB, asyncIndexedDB, custom.`
|
|
5943
|
+
);
|
|
5685
5944
|
}
|
|
5686
5945
|
if (options.twoLayer && Object.keys(options.twoLayer).length > 0) {
|
|
5687
5946
|
return new TwoLayerCacheMap(underlyingCache, options.twoLayer);
|
|
@@ -5762,19 +6021,29 @@ Did you mean: ${suggestions.join(", ")}?`;
|
|
|
5762
6021
|
throw new Error(errorMessage);
|
|
5763
6022
|
}
|
|
5764
6023
|
if (options.cacheType === "custom" && !options.customCacheMapFactory) {
|
|
5765
|
-
throw new Error(
|
|
6024
|
+
throw new Error(
|
|
6025
|
+
'customCacheMapFactory is required when cacheType is "custom". Provide a factory function that creates your custom CacheMap implementation.'
|
|
6026
|
+
);
|
|
5766
6027
|
}
|
|
5767
6028
|
if (typeof options.maxRetries === "number" && options.maxRetries < 0) {
|
|
5768
|
-
throw new Error(
|
|
6029
|
+
throw new Error(
|
|
6030
|
+
`maxRetries must be non-negative, got ${options.maxRetries}. Suggestion: Use 0 or positive integer for retry attempts.`
|
|
6031
|
+
);
|
|
5769
6032
|
}
|
|
5770
6033
|
if (typeof options.retryDelay === "number" && options.retryDelay < 0) {
|
|
5771
|
-
throw new Error(
|
|
6034
|
+
throw new Error(
|
|
6035
|
+
`retryDelay must be non-negative, got ${options.retryDelay}ms. Suggestion: Use 0 or positive number for delay in milliseconds.`
|
|
6036
|
+
);
|
|
5772
6037
|
}
|
|
5773
6038
|
if (typeof options.ttl === "number" && options.ttl <= 0) {
|
|
5774
|
-
throw new Error(
|
|
6039
|
+
throw new Error(
|
|
6040
|
+
`ttl must be positive, got ${options.ttl}. Suggestion: Use positive number for TTL in seconds, or 0 to disable TTL.`
|
|
6041
|
+
);
|
|
5775
6042
|
}
|
|
5776
6043
|
if (typeof options.memoryConfig?.maxItems === "number" && options.memoryConfig.maxItems <= 0) {
|
|
5777
|
-
throw new Error(
|
|
6044
|
+
throw new Error(
|
|
6045
|
+
`memoryConfig.maxItems must be positive, got ${options.memoryConfig.maxItems}. Suggestion: Use positive integer for maximum cache items.`
|
|
6046
|
+
);
|
|
5778
6047
|
}
|
|
5779
6048
|
if (options.memoryConfig?.size) {
|
|
5780
6049
|
validateSizeConfig(options.memoryConfig.size);
|
|
@@ -5874,16 +6143,43 @@ Did you mean: ${suggestions.join(", ")}?`);
|
|
|
5874
6143
|
if (["localStorage", "sessionStorage"].includes(options.cacheType)) {
|
|
5875
6144
|
const isRealBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement === "function";
|
|
5876
6145
|
if (!isRealBrowser) {
|
|
5877
|
-
|
|
6146
|
+
logger25.error("Browser cache type used in non-browser environment", {
|
|
6147
|
+
component: "cache",
|
|
6148
|
+
operation: "validateOptions",
|
|
6149
|
+
cacheType: options.cacheType,
|
|
6150
|
+
environment: typeof window === "undefined" ? "node" : "unknown",
|
|
6151
|
+
suggestion: 'Use cacheType: "memory" for Node.js/server environments, or ensure code runs in browser'
|
|
6152
|
+
});
|
|
6153
|
+
throw new Error(
|
|
6154
|
+
`${options.cacheType} is not available in non-browser environments. Detected environment: ${typeof window === "undefined" ? "Node.js/server" : "non-browser"}. Suggestion: Use cacheType: "memory" for server-side caching.`
|
|
6155
|
+
);
|
|
5878
6156
|
}
|
|
5879
6157
|
}
|
|
5880
6158
|
if (options.cacheType === "indexedDB") {
|
|
5881
6159
|
if (typeof window === "undefined" || !window.indexedDB) {
|
|
5882
|
-
|
|
6160
|
+
logger25.error("IndexedDB not available", {
|
|
6161
|
+
component: "cache",
|
|
6162
|
+
operation: "validateOptions",
|
|
6163
|
+
cacheType: "indexedDB",
|
|
6164
|
+
hasWindow: typeof window !== "undefined",
|
|
6165
|
+
hasIndexedDB: typeof window !== "undefined" && !!window.indexedDB,
|
|
6166
|
+
suggestion: "Use memory cache for Node.js, or check browser IndexedDB support"
|
|
6167
|
+
});
|
|
6168
|
+
throw new Error(
|
|
6169
|
+
`IndexedDB is not available in this environment. Browser support required. Suggestion: Use cacheType: "memory" for server-side or unsupported browsers.`
|
|
6170
|
+
);
|
|
5883
6171
|
}
|
|
5884
6172
|
}
|
|
5885
6173
|
if (options.cacheType === "asyncIndexedDB") {
|
|
5886
|
-
|
|
6174
|
+
logger25.error("AsyncIndexedDB cannot be used with sync factory", {
|
|
6175
|
+
component: "cache",
|
|
6176
|
+
operation: "validateOptions",
|
|
6177
|
+
cacheType: "asyncIndexedDB",
|
|
6178
|
+
suggestion: 'Use AsyncIndexDBCacheMap directly for async operations, or use cacheType: "indexedDB" for sync wrapper'
|
|
6179
|
+
});
|
|
6180
|
+
throw new Error(
|
|
6181
|
+
'asyncIndexedDB cannot be used with synchronous cache factory. Use AsyncIndexDBCacheMap directly for async operations, or use cacheType: "indexedDB" for the sync wrapper.'
|
|
6182
|
+
);
|
|
5887
6183
|
}
|
|
5888
6184
|
};
|
|
5889
6185
|
|
|
@@ -5898,7 +6194,11 @@ var reset = async (coordinate, options) => {
|
|
|
5898
6194
|
}
|
|
5899
6195
|
};
|
|
5900
6196
|
|
|
6197
|
+
// src/ttl/TTLCalculator.ts
|
|
6198
|
+
var logger26 = logger_default.get("TTLCalculator");
|
|
6199
|
+
|
|
5901
6200
|
// src/ttl/TTLConfig.ts
|
|
6201
|
+
var logger27 = logger_default.get("TTLConfig");
|
|
5902
6202
|
var defaultTTLConfig = {
|
|
5903
6203
|
item: {
|
|
5904
6204
|
default: 3600,
|
|
@@ -5997,10 +6297,10 @@ var highTrafficTTLConfig = {
|
|
|
5997
6297
|
};
|
|
5998
6298
|
|
|
5999
6299
|
// src/cache/warming/CacheWarmer.ts
|
|
6000
|
-
var
|
|
6300
|
+
var logger28 = logger_default.get("CacheWarmer");
|
|
6001
6301
|
|
|
6002
6302
|
// src/Operations.ts
|
|
6003
|
-
var
|
|
6303
|
+
var logger29 = logger_default.get("Operations");
|
|
6004
6304
|
var CacheMapOperations = class {
|
|
6005
6305
|
constructor(api, coordinate, cacheMap, pkType, options, eventEmitter, ttlManager, evictionManager, statsManager, registry) {
|
|
6006
6306
|
this.api = api;
|
|
@@ -6014,7 +6314,7 @@ var CacheMapOperations = class {
|
|
|
6014
6314
|
this.statsManager = statsManager;
|
|
6015
6315
|
this.registry = registry;
|
|
6016
6316
|
if (this.options.enableDebugLogging) {
|
|
6017
|
-
|
|
6317
|
+
logger29.debug("CacheMapOperations initialized", {
|
|
6018
6318
|
cacheType: this.cacheMap.implementationType,
|
|
6019
6319
|
isTwoLayer: this.cacheMap instanceof TwoLayerCacheMap
|
|
6020
6320
|
});
|
|
@@ -6107,7 +6407,7 @@ var createOperations = (api, coordinate, cacheMap, pkType, options, eventEmitter
|
|
|
6107
6407
|
};
|
|
6108
6408
|
|
|
6109
6409
|
// src/eviction/EvictionManager.ts
|
|
6110
|
-
var
|
|
6410
|
+
var logger30 = logger_default.get("EvictionManager");
|
|
6111
6411
|
var EvictionManager = class {
|
|
6112
6412
|
evictionStrategy;
|
|
6113
6413
|
constructor(evictionStrategy) {
|
|
@@ -6119,7 +6419,7 @@ var EvictionManager = class {
|
|
|
6119
6419
|
*/
|
|
6120
6420
|
setEvictionStrategy(strategy) {
|
|
6121
6421
|
this.evictionStrategy = strategy;
|
|
6122
|
-
|
|
6422
|
+
logger30.debug("Eviction strategy updated", {
|
|
6123
6423
|
strategy: strategy?.getStrategyName() || "none"
|
|
6124
6424
|
});
|
|
6125
6425
|
}
|
|
@@ -6140,13 +6440,13 @@ var EvictionManager = class {
|
|
|
6140
6440
|
return;
|
|
6141
6441
|
}
|
|
6142
6442
|
try {
|
|
6143
|
-
|
|
6443
|
+
logger30.debug("EVICTION: Item accessed, updating metadata", {
|
|
6144
6444
|
key,
|
|
6145
6445
|
strategy: this.evictionStrategy.getStrategyName()
|
|
6146
6446
|
});
|
|
6147
6447
|
await this.evictionStrategy.onItemAccessed(key, metadataProvider);
|
|
6148
6448
|
} catch (error) {
|
|
6149
|
-
|
|
6449
|
+
logger30.error("EVICTION: Error in eviction strategy onItemAccessed", {
|
|
6150
6450
|
key,
|
|
6151
6451
|
error,
|
|
6152
6452
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -6164,12 +6464,12 @@ var EvictionManager = class {
|
|
|
6164
6464
|
const startTime = Date.now();
|
|
6165
6465
|
const evictedKeys = [];
|
|
6166
6466
|
if (!this.evictionStrategy) {
|
|
6167
|
-
|
|
6467
|
+
logger30.debug("EVICTION: No eviction strategy configured", { key });
|
|
6168
6468
|
return evictedKeys;
|
|
6169
6469
|
}
|
|
6170
6470
|
try {
|
|
6171
6471
|
const estimatedSize = estimateValueSize(value);
|
|
6172
|
-
|
|
6472
|
+
logger30.debug("EVICTION: Item addition started", {
|
|
6173
6473
|
key,
|
|
6174
6474
|
estimatedSize,
|
|
6175
6475
|
strategy: this.evictionStrategy.getStrategyName()
|
|
@@ -6177,7 +6477,7 @@ var EvictionManager = class {
|
|
|
6177
6477
|
const contextStartTime = Date.now();
|
|
6178
6478
|
const context = await this.createEvictionContext(metadataProvider, estimatedSize);
|
|
6179
6479
|
const contextDuration = Date.now() - contextStartTime;
|
|
6180
|
-
|
|
6480
|
+
logger30.debug("EVICTION: Current cache state", {
|
|
6181
6481
|
key,
|
|
6182
6482
|
currentItemCount: context.currentSize.itemCount,
|
|
6183
6483
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
@@ -6190,7 +6490,7 @@ var EvictionManager = class {
|
|
|
6190
6490
|
const keysToEvict = await this.evictionStrategy.selectForEviction(metadataProvider, context);
|
|
6191
6491
|
const selectionDuration = Date.now() - selectionStartTime;
|
|
6192
6492
|
if (keysToEvict.length > 0) {
|
|
6193
|
-
|
|
6493
|
+
logger30.debug("EVICTION: Items selected for eviction", {
|
|
6194
6494
|
key,
|
|
6195
6495
|
evictCount: keysToEvict.length,
|
|
6196
6496
|
keysToEvict,
|
|
@@ -6202,7 +6502,7 @@ var EvictionManager = class {
|
|
|
6202
6502
|
for (const evictKey of keysToEvict) {
|
|
6203
6503
|
await this.evictionStrategy.onItemRemoved(evictKey, metadataProvider);
|
|
6204
6504
|
evictedKeys.push(evictKey);
|
|
6205
|
-
|
|
6505
|
+
logger30.debug("EVICTION: Marked item for eviction", {
|
|
6206
6506
|
evictedKey: evictKey,
|
|
6207
6507
|
newKey: key
|
|
6208
6508
|
});
|
|
@@ -6213,7 +6513,7 @@ var EvictionManager = class {
|
|
|
6213
6513
|
const addMetadataDuration = Date.now() - addMetadataStart;
|
|
6214
6514
|
const totalDuration = Date.now() - startTime;
|
|
6215
6515
|
if (evictedKeys.length > 0) {
|
|
6216
|
-
|
|
6516
|
+
logger30.debug("EVICTION: Eviction completed", {
|
|
6217
6517
|
newKey: key,
|
|
6218
6518
|
evictedCount: evictedKeys.length,
|
|
6219
6519
|
evictedKeys,
|
|
@@ -6224,14 +6524,14 @@ var EvictionManager = class {
|
|
|
6224
6524
|
totalDuration
|
|
6225
6525
|
});
|
|
6226
6526
|
} else {
|
|
6227
|
-
|
|
6527
|
+
logger30.debug("EVICTION: No eviction needed", {
|
|
6228
6528
|
newKey: key,
|
|
6229
6529
|
estimatedSize,
|
|
6230
6530
|
totalDuration
|
|
6231
6531
|
});
|
|
6232
6532
|
}
|
|
6233
6533
|
} catch (error) {
|
|
6234
|
-
|
|
6534
|
+
logger30.error("EVICTION: Error in eviction strategy onItemAdded", {
|
|
6235
6535
|
key,
|
|
6236
6536
|
error,
|
|
6237
6537
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -6251,7 +6551,7 @@ var EvictionManager = class {
|
|
|
6251
6551
|
try {
|
|
6252
6552
|
this.evictionStrategy.onItemRemoved(key, metadataProvider);
|
|
6253
6553
|
} catch (error) {
|
|
6254
|
-
|
|
6554
|
+
logger30.error("Error in eviction strategy onItemRemoved", { key, error });
|
|
6255
6555
|
}
|
|
6256
6556
|
}
|
|
6257
6557
|
/**
|
|
@@ -6263,15 +6563,15 @@ var EvictionManager = class {
|
|
|
6263
6563
|
const startTime = Date.now();
|
|
6264
6564
|
const evictedKeys = [];
|
|
6265
6565
|
if (!this.evictionStrategy) {
|
|
6266
|
-
|
|
6566
|
+
logger30.debug("EVICTION: No eviction strategy configured for manual eviction");
|
|
6267
6567
|
return evictedKeys;
|
|
6268
6568
|
}
|
|
6269
6569
|
try {
|
|
6270
|
-
|
|
6570
|
+
logger30.debug("EVICTION: Manual eviction started", {
|
|
6271
6571
|
strategy: this.evictionStrategy.getStrategyName()
|
|
6272
6572
|
});
|
|
6273
6573
|
const context = await this.createEvictionContext(metadataProvider);
|
|
6274
|
-
|
|
6574
|
+
logger30.debug("EVICTION: Manual eviction - current cache state", {
|
|
6275
6575
|
currentItemCount: context.currentSize.itemCount,
|
|
6276
6576
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
6277
6577
|
maxItems: context.limits.maxItems,
|
|
@@ -6284,20 +6584,20 @@ var EvictionManager = class {
|
|
|
6284
6584
|
}
|
|
6285
6585
|
const duration = Date.now() - startTime;
|
|
6286
6586
|
if (evictedKeys.length > 0) {
|
|
6287
|
-
|
|
6587
|
+
logger30.debug("EVICTION: Manual eviction completed", {
|
|
6288
6588
|
evictedCount: evictedKeys.length,
|
|
6289
6589
|
evictedKeys,
|
|
6290
6590
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
6291
6591
|
duration
|
|
6292
6592
|
});
|
|
6293
6593
|
} else {
|
|
6294
|
-
|
|
6594
|
+
logger30.debug("EVICTION: Manual eviction - no items to evict", {
|
|
6295
6595
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
6296
6596
|
duration
|
|
6297
6597
|
});
|
|
6298
6598
|
}
|
|
6299
6599
|
} catch (error) {
|
|
6300
|
-
|
|
6600
|
+
logger30.error("EVICTION: Error in manual eviction", {
|
|
6301
6601
|
error,
|
|
6302
6602
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
6303
6603
|
});
|
|
@@ -6320,7 +6620,7 @@ var EvictionManager = class {
|
|
|
6320
6620
|
this.evictionStrategy.reset();
|
|
6321
6621
|
}
|
|
6322
6622
|
}
|
|
6323
|
-
|
|
6623
|
+
logger30.debug("Eviction manager cleared");
|
|
6324
6624
|
}
|
|
6325
6625
|
/**
|
|
6326
6626
|
* Create eviction context from current cache state
|
|
@@ -6458,61 +6758,149 @@ var LRUEvictionStrategy = class extends EvictionStrategy {
|
|
|
6458
6758
|
// src/eviction/EvictionStrategyValidation.ts
|
|
6459
6759
|
function validateNumberRange(value, min, max, fieldName) {
|
|
6460
6760
|
if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
|
|
6461
|
-
throw new Error(
|
|
6761
|
+
throw new Error(
|
|
6762
|
+
`${fieldName} must be a finite number, got ${typeof value} (${value}). Suggestion: Provide a valid numeric value for ${fieldName}.`
|
|
6763
|
+
);
|
|
6462
6764
|
}
|
|
6463
6765
|
if (value < min || value > max) {
|
|
6464
|
-
throw new Error(
|
|
6766
|
+
throw new Error(
|
|
6767
|
+
`${fieldName} must be between ${min} and ${max}, got ${value}. Suggestion: Adjust ${fieldName} to be within the valid range.`
|
|
6768
|
+
);
|
|
6465
6769
|
}
|
|
6466
6770
|
}
|
|
6467
6771
|
function validatePositiveInteger(value, fieldName) {
|
|
6468
6772
|
if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
|
|
6469
|
-
throw new Error(
|
|
6773
|
+
throw new Error(
|
|
6774
|
+
`${fieldName} must be a finite number, got ${typeof value} (${value}). Suggestion: Provide a valid numeric value for ${fieldName}.`
|
|
6775
|
+
);
|
|
6470
6776
|
}
|
|
6471
6777
|
if (!Number.isInteger(value) || value <= 0) {
|
|
6472
|
-
throw new Error(
|
|
6778
|
+
throw new Error(
|
|
6779
|
+
`${fieldName} must be a positive integer, got ${value}. Suggestion: Use a positive whole number (1, 2, 3, ...) for ${fieldName}.`
|
|
6780
|
+
);
|
|
6473
6781
|
}
|
|
6474
6782
|
}
|
|
6475
6783
|
function sanitizeLFUConfig(config) {
|
|
6476
6784
|
const sanitized = { ...config };
|
|
6477
6785
|
if (typeof sanitized.decayFactor === "number") {
|
|
6478
6786
|
if (sanitized.decayFactor < 0) {
|
|
6479
|
-
|
|
6787
|
+
const warning = {
|
|
6788
|
+
component: "cache",
|
|
6789
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6790
|
+
operation: "sanitizeLFUConfig",
|
|
6791
|
+
field: "decayFactor",
|
|
6792
|
+
invalidValue: sanitized.decayFactor,
|
|
6793
|
+
correctedValue: 0,
|
|
6794
|
+
validRange: "0-1",
|
|
6795
|
+
note: "Auto-correcting invalid configuration value"
|
|
6796
|
+
};
|
|
6797
|
+
console.warn("Invalid decayFactor corrected:", JSON.stringify(warning, null, 2));
|
|
6480
6798
|
sanitized.decayFactor = 0;
|
|
6481
6799
|
} else if (sanitized.decayFactor > 1) {
|
|
6482
|
-
|
|
6800
|
+
const warning = {
|
|
6801
|
+
component: "cache",
|
|
6802
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6803
|
+
operation: "sanitizeLFUConfig",
|
|
6804
|
+
field: "decayFactor",
|
|
6805
|
+
invalidValue: sanitized.decayFactor,
|
|
6806
|
+
correctedValue: 1,
|
|
6807
|
+
validRange: "0-1",
|
|
6808
|
+
note: "Auto-correcting invalid configuration value"
|
|
6809
|
+
};
|
|
6810
|
+
console.warn("Invalid decayFactor corrected:", JSON.stringify(warning, null, 2));
|
|
6483
6811
|
sanitized.decayFactor = 1;
|
|
6484
6812
|
}
|
|
6485
6813
|
}
|
|
6486
6814
|
if (typeof sanitized.decayInterval === "number" && sanitized.decayInterval <= 0) {
|
|
6487
|
-
|
|
6815
|
+
const warning = {
|
|
6816
|
+
component: "cache",
|
|
6817
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6818
|
+
operation: "sanitizeLFUConfig",
|
|
6819
|
+
field: "decayInterval",
|
|
6820
|
+
invalidValue: sanitized.decayInterval,
|
|
6821
|
+
correctedValue: 3e5,
|
|
6822
|
+
minimumValue: 1,
|
|
6823
|
+
note: "Auto-correcting to 5 minutes (300000ms) default"
|
|
6824
|
+
};
|
|
6825
|
+
console.warn("Invalid decayInterval corrected:", JSON.stringify(warning, null, 2));
|
|
6488
6826
|
sanitized.decayInterval = 3e5;
|
|
6489
6827
|
}
|
|
6490
6828
|
if (typeof sanitized.sketchWidth === "number") {
|
|
6491
6829
|
if (sanitized.sketchWidth <= 0) {
|
|
6492
|
-
console.warn(
|
|
6830
|
+
console.warn("Invalid sketchWidth corrected:", JSON.stringify({
|
|
6831
|
+
component: "cache",
|
|
6832
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6833
|
+
field: "sketchWidth",
|
|
6834
|
+
invalidValue: sanitized.sketchWidth,
|
|
6835
|
+
correctedValue: 1024,
|
|
6836
|
+
note: "Auto-correcting invalid configuration"
|
|
6837
|
+
}, null, 2));
|
|
6493
6838
|
sanitized.sketchWidth = 1024;
|
|
6494
6839
|
} else if (sanitized.sketchWidth < 16) {
|
|
6495
|
-
console.warn(
|
|
6840
|
+
console.warn("Suboptimal sketchWidth corrected:", JSON.stringify({
|
|
6841
|
+
component: "cache",
|
|
6842
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6843
|
+
field: "sketchWidth",
|
|
6844
|
+
invalidValue: sanitized.sketchWidth,
|
|
6845
|
+
correctedValue: 16,
|
|
6846
|
+
minimumRecommended: 16,
|
|
6847
|
+
note: "Correcting for optimal performance"
|
|
6848
|
+
}, null, 2));
|
|
6496
6849
|
sanitized.sketchWidth = 16;
|
|
6497
6850
|
} else if (sanitized.sketchWidth > 65536) {
|
|
6498
|
-
console.warn(
|
|
6851
|
+
console.warn("Excessive sketchWidth corrected:", JSON.stringify({
|
|
6852
|
+
component: "cache",
|
|
6853
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6854
|
+
field: "sketchWidth",
|
|
6855
|
+
invalidValue: sanitized.sketchWidth,
|
|
6856
|
+
correctedValue: 65536,
|
|
6857
|
+
maximumRecommended: 65536,
|
|
6858
|
+
note: "Correcting for optimal performance"
|
|
6859
|
+
}, null, 2));
|
|
6499
6860
|
sanitized.sketchWidth = 65536;
|
|
6500
6861
|
}
|
|
6501
6862
|
}
|
|
6502
6863
|
if (typeof sanitized.sketchDepth === "number") {
|
|
6503
6864
|
if (sanitized.sketchDepth <= 0) {
|
|
6504
|
-
console.warn(
|
|
6865
|
+
console.warn("Invalid sketchDepth corrected:", JSON.stringify({
|
|
6866
|
+
component: "cache",
|
|
6867
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6868
|
+
field: "sketchDepth",
|
|
6869
|
+
invalidValue: sanitized.sketchDepth,
|
|
6870
|
+
correctedValue: 4
|
|
6871
|
+
}, null, 2));
|
|
6505
6872
|
sanitized.sketchDepth = 4;
|
|
6506
6873
|
} else if (sanitized.sketchDepth < 1) {
|
|
6507
|
-
console.warn(
|
|
6874
|
+
console.warn("Suboptimal sketchDepth corrected:", JSON.stringify({
|
|
6875
|
+
component: "cache",
|
|
6876
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6877
|
+
field: "sketchDepth",
|
|
6878
|
+
invalidValue: sanitized.sketchDepth,
|
|
6879
|
+
correctedValue: 1,
|
|
6880
|
+
minimumRecommended: 1
|
|
6881
|
+
}, null, 2));
|
|
6508
6882
|
sanitized.sketchDepth = 1;
|
|
6509
6883
|
} else if (sanitized.sketchDepth > 16) {
|
|
6510
|
-
console.warn(
|
|
6884
|
+
console.warn("Excessive sketchDepth corrected:", JSON.stringify({
|
|
6885
|
+
component: "cache",
|
|
6886
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6887
|
+
field: "sketchDepth",
|
|
6888
|
+
invalidValue: sanitized.sketchDepth,
|
|
6889
|
+
correctedValue: 16,
|
|
6890
|
+
maximumRecommended: 16
|
|
6891
|
+
}, null, 2));
|
|
6511
6892
|
sanitized.sketchDepth = 16;
|
|
6512
6893
|
}
|
|
6513
6894
|
}
|
|
6514
6895
|
if (typeof sanitized.minFrequencyThreshold === "number" && sanitized.minFrequencyThreshold <= 0) {
|
|
6515
|
-
console.warn(
|
|
6896
|
+
console.warn("Invalid minFrequencyThreshold corrected:", JSON.stringify({
|
|
6897
|
+
component: "cache",
|
|
6898
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6899
|
+
field: "minFrequencyThreshold",
|
|
6900
|
+
invalidValue: sanitized.minFrequencyThreshold,
|
|
6901
|
+
correctedValue: 1,
|
|
6902
|
+
minimumValue: 1
|
|
6903
|
+
}, null, 2));
|
|
6516
6904
|
sanitized.minFrequencyThreshold = 1;
|
|
6517
6905
|
}
|
|
6518
6906
|
return sanitized;
|
|
@@ -6543,32 +6931,86 @@ function validateLFUConfig(config) {
|
|
|
6543
6931
|
function sanitizeARCConfig(config) {
|
|
6544
6932
|
const sanitized = { ...config };
|
|
6545
6933
|
if (typeof sanitized.maxCacheSize === "number" && sanitized.maxCacheSize <= 0) {
|
|
6546
|
-
console.warn(
|
|
6934
|
+
console.warn("Invalid maxCacheSize corrected:", JSON.stringify({
|
|
6935
|
+
component: "cache",
|
|
6936
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6937
|
+
operation: "sanitizeARCConfig",
|
|
6938
|
+
field: "maxCacheSize",
|
|
6939
|
+
invalidValue: sanitized.maxCacheSize,
|
|
6940
|
+
correctedValue: 1e3
|
|
6941
|
+
}, null, 2));
|
|
6547
6942
|
sanitized.maxCacheSize = 1e3;
|
|
6548
6943
|
}
|
|
6549
6944
|
if (typeof sanitized.frequencyThreshold === "number" && sanitized.frequencyThreshold <= 0) {
|
|
6550
|
-
console.warn(
|
|
6945
|
+
console.warn("Invalid frequencyThreshold corrected:", JSON.stringify({
|
|
6946
|
+
component: "cache",
|
|
6947
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6948
|
+
operation: "sanitizeARCConfig",
|
|
6949
|
+
field: "frequencyThreshold",
|
|
6950
|
+
invalidValue: sanitized.frequencyThreshold,
|
|
6951
|
+
correctedValue: 2
|
|
6952
|
+
}, null, 2));
|
|
6551
6953
|
sanitized.frequencyThreshold = 2;
|
|
6552
6954
|
}
|
|
6553
6955
|
if (typeof sanitized.frequencyDecayFactor === "number") {
|
|
6554
6956
|
if (sanitized.frequencyDecayFactor < 0) {
|
|
6555
|
-
console.warn(
|
|
6957
|
+
console.warn("Invalid frequencyDecayFactor corrected:", JSON.stringify({
|
|
6958
|
+
component: "cache",
|
|
6959
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6960
|
+
operation: "sanitizeARCConfig",
|
|
6961
|
+
field: "frequencyDecayFactor",
|
|
6962
|
+
invalidValue: sanitized.frequencyDecayFactor,
|
|
6963
|
+
correctedValue: 0,
|
|
6964
|
+
validRange: "0-1"
|
|
6965
|
+
}, null, 2));
|
|
6556
6966
|
sanitized.frequencyDecayFactor = 0;
|
|
6557
6967
|
} else if (sanitized.frequencyDecayFactor > 1) {
|
|
6558
|
-
console.warn(
|
|
6968
|
+
console.warn("Invalid frequencyDecayFactor corrected:", JSON.stringify({
|
|
6969
|
+
component: "cache",
|
|
6970
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6971
|
+
operation: "sanitizeARCConfig",
|
|
6972
|
+
field: "frequencyDecayFactor",
|
|
6973
|
+
invalidValue: sanitized.frequencyDecayFactor,
|
|
6974
|
+
correctedValue: 1,
|
|
6975
|
+
validRange: "0-1"
|
|
6976
|
+
}, null, 2));
|
|
6559
6977
|
sanitized.frequencyDecayFactor = 1;
|
|
6560
6978
|
}
|
|
6561
6979
|
}
|
|
6562
6980
|
if (typeof sanitized.frequencyDecayInterval === "number" && sanitized.frequencyDecayInterval <= 0) {
|
|
6563
|
-
console.warn(
|
|
6981
|
+
console.warn("Invalid frequencyDecayInterval corrected:", JSON.stringify({
|
|
6982
|
+
component: "cache",
|
|
6983
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6984
|
+
operation: "sanitizeARCConfig",
|
|
6985
|
+
field: "frequencyDecayInterval",
|
|
6986
|
+
invalidValue: sanitized.frequencyDecayInterval,
|
|
6987
|
+
correctedValue: 6e4,
|
|
6988
|
+
note: "Corrected to 1 minute default"
|
|
6989
|
+
}, null, 2));
|
|
6564
6990
|
sanitized.frequencyDecayInterval = 6e4;
|
|
6565
6991
|
}
|
|
6566
6992
|
if (typeof sanitized.adaptiveLearningRate === "number") {
|
|
6567
6993
|
if (sanitized.adaptiveLearningRate < 0) {
|
|
6568
|
-
console.warn(
|
|
6994
|
+
console.warn("Invalid adaptiveLearningRate corrected:", JSON.stringify({
|
|
6995
|
+
component: "cache",
|
|
6996
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6997
|
+
operation: "sanitizeARCConfig",
|
|
6998
|
+
field: "adaptiveLearningRate",
|
|
6999
|
+
invalidValue: sanitized.adaptiveLearningRate,
|
|
7000
|
+
correctedValue: 0,
|
|
7001
|
+
validRange: "0-10"
|
|
7002
|
+
}, null, 2));
|
|
6569
7003
|
sanitized.adaptiveLearningRate = 0;
|
|
6570
7004
|
} else if (sanitized.adaptiveLearningRate > 10) {
|
|
6571
|
-
console.warn(
|
|
7005
|
+
console.warn("Invalid adaptiveLearningRate corrected:", JSON.stringify({
|
|
7006
|
+
component: "cache",
|
|
7007
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7008
|
+
operation: "sanitizeARCConfig",
|
|
7009
|
+
field: "adaptiveLearningRate",
|
|
7010
|
+
invalidValue: sanitized.adaptiveLearningRate,
|
|
7011
|
+
correctedValue: 10,
|
|
7012
|
+
validRange: "0-10"
|
|
7013
|
+
}, null, 2));
|
|
6572
7014
|
sanitized.adaptiveLearningRate = 10;
|
|
6573
7015
|
}
|
|
6574
7016
|
}
|
|
@@ -6594,24 +7036,62 @@ function validateARCConfig(config) {
|
|
|
6594
7036
|
function sanitizeTwoQueueConfig(config) {
|
|
6595
7037
|
const sanitized = { ...config };
|
|
6596
7038
|
if (typeof sanitized.maxCacheSize === "number" && sanitized.maxCacheSize <= 0) {
|
|
6597
|
-
console.warn(
|
|
7039
|
+
console.warn("Invalid maxCacheSize corrected:", JSON.stringify({
|
|
7040
|
+
component: "cache",
|
|
7041
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7042
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7043
|
+
field: "maxCacheSize",
|
|
7044
|
+
invalidValue: sanitized.maxCacheSize,
|
|
7045
|
+
correctedValue: 1e3
|
|
7046
|
+
}, null, 2));
|
|
6598
7047
|
sanitized.maxCacheSize = 1e3;
|
|
6599
7048
|
}
|
|
6600
7049
|
if (typeof sanitized.promotionThreshold === "number" && sanitized.promotionThreshold <= 0) {
|
|
6601
|
-
console.warn(
|
|
7050
|
+
console.warn("Invalid promotionThreshold corrected:", JSON.stringify({
|
|
7051
|
+
component: "cache",
|
|
7052
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7053
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7054
|
+
field: "promotionThreshold",
|
|
7055
|
+
invalidValue: sanitized.promotionThreshold,
|
|
7056
|
+
correctedValue: 2
|
|
7057
|
+
}, null, 2));
|
|
6602
7058
|
sanitized.promotionThreshold = 2;
|
|
6603
7059
|
}
|
|
6604
7060
|
if (typeof sanitized.hotQueueDecayFactor === "number") {
|
|
6605
7061
|
if (sanitized.hotQueueDecayFactor < 0) {
|
|
6606
|
-
console.warn(
|
|
7062
|
+
console.warn("Invalid hotQueueDecayFactor corrected:", JSON.stringify({
|
|
7063
|
+
component: "cache",
|
|
7064
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7065
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7066
|
+
field: "hotQueueDecayFactor",
|
|
7067
|
+
invalidValue: sanitized.hotQueueDecayFactor,
|
|
7068
|
+
correctedValue: 0,
|
|
7069
|
+
validRange: "0-1"
|
|
7070
|
+
}, null, 2));
|
|
6607
7071
|
sanitized.hotQueueDecayFactor = 0;
|
|
6608
7072
|
} else if (sanitized.hotQueueDecayFactor > 1) {
|
|
6609
|
-
console.warn(
|
|
7073
|
+
console.warn("Invalid hotQueueDecayFactor corrected:", JSON.stringify({
|
|
7074
|
+
component: "cache",
|
|
7075
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7076
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7077
|
+
field: "hotQueueDecayFactor",
|
|
7078
|
+
invalidValue: sanitized.hotQueueDecayFactor,
|
|
7079
|
+
correctedValue: 1,
|
|
7080
|
+
validRange: "0-1"
|
|
7081
|
+
}, null, 2));
|
|
6610
7082
|
sanitized.hotQueueDecayFactor = 1;
|
|
6611
7083
|
}
|
|
6612
7084
|
}
|
|
6613
7085
|
if (typeof sanitized.hotQueueDecayInterval === "number" && sanitized.hotQueueDecayInterval <= 0) {
|
|
6614
|
-
console.warn(
|
|
7086
|
+
console.warn("Invalid hotQueueDecayInterval corrected:", JSON.stringify({
|
|
7087
|
+
component: "cache",
|
|
7088
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7089
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7090
|
+
field: "hotQueueDecayInterval",
|
|
7091
|
+
invalidValue: sanitized.hotQueueDecayInterval,
|
|
7092
|
+
correctedValue: 3e5,
|
|
7093
|
+
note: "Corrected to 5 minutes default"
|
|
7094
|
+
}, null, 2));
|
|
6615
7095
|
sanitized.hotQueueDecayInterval = 3e5;
|
|
6616
7096
|
}
|
|
6617
7097
|
return sanitized;
|
|
@@ -7658,7 +8138,7 @@ function createEvictionStrategy(policy, maxCacheSize, config) {
|
|
|
7658
8138
|
}
|
|
7659
8139
|
|
|
7660
8140
|
// src/ttl/TTLManager.ts
|
|
7661
|
-
var
|
|
8141
|
+
var logger31 = logger_default.get("TTLManager");
|
|
7662
8142
|
var TTLManager = class {
|
|
7663
8143
|
config;
|
|
7664
8144
|
cleanupTimer;
|
|
@@ -7670,7 +8150,7 @@ var TTLManager = class {
|
|
|
7670
8150
|
validateOnAccess: true,
|
|
7671
8151
|
...config
|
|
7672
8152
|
};
|
|
7673
|
-
|
|
8153
|
+
logger31.debug("TTL_DEBUG: TTLManager created", {
|
|
7674
8154
|
config: this.config,
|
|
7675
8155
|
isTTLEnabled: this.isTTLEnabled(),
|
|
7676
8156
|
defaultTTL: this.config.defaultTTL
|
|
@@ -7703,13 +8183,13 @@ var TTLManager = class {
|
|
|
7703
8183
|
this.startAutoCleanup();
|
|
7704
8184
|
}
|
|
7705
8185
|
}
|
|
7706
|
-
|
|
8186
|
+
logger31.debug("TTL configuration updated", { config: this.config });
|
|
7707
8187
|
}
|
|
7708
8188
|
/**
|
|
7709
8189
|
* Set TTL metadata for an item when it's added
|
|
7710
8190
|
*/
|
|
7711
8191
|
async onItemAdded(key, metadataProvider, itemTTL) {
|
|
7712
|
-
|
|
8192
|
+
logger31.debug("TTL_DEBUG: onItemAdded called", {
|
|
7713
8193
|
key,
|
|
7714
8194
|
itemTTL,
|
|
7715
8195
|
isTTLEnabled: this.isTTLEnabled(),
|
|
@@ -7717,19 +8197,19 @@ var TTLManager = class {
|
|
|
7717
8197
|
metadataProviderType: metadataProvider?.constructor?.name
|
|
7718
8198
|
});
|
|
7719
8199
|
if (!this.isTTLEnabled() && !itemTTL) {
|
|
7720
|
-
|
|
8200
|
+
logger31.debug("TTL_DEBUG: No TTL configured for item - returning early", { key });
|
|
7721
8201
|
return;
|
|
7722
8202
|
}
|
|
7723
|
-
|
|
8203
|
+
logger31.debug("TTL_DEBUG: Getting metadata for key", { key });
|
|
7724
8204
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7725
|
-
|
|
8205
|
+
logger31.debug("TTL_DEBUG: Retrieved metadata", {
|
|
7726
8206
|
key,
|
|
7727
8207
|
hasMetadata: !!metadata,
|
|
7728
8208
|
metadataKeys: metadata ? Object.keys(metadata) : null,
|
|
7729
8209
|
metadata
|
|
7730
8210
|
});
|
|
7731
8211
|
if (!metadata) {
|
|
7732
|
-
|
|
8212
|
+
logger31.debug("TTL_DEBUG: No metadata found for item when setting TTL", {
|
|
7733
8213
|
key,
|
|
7734
8214
|
metadataProviderType: metadataProvider?.constructor?.name,
|
|
7735
8215
|
metadataProviderMethods: metadataProvider ? Object.getOwnPropertyNames(Object.getPrototypeOf(metadataProvider)) : null
|
|
@@ -7737,7 +8217,7 @@ var TTLManager = class {
|
|
|
7737
8217
|
return;
|
|
7738
8218
|
}
|
|
7739
8219
|
const ttl = itemTTL || this.config.defaultTTL;
|
|
7740
|
-
|
|
8220
|
+
logger31.debug("TTL_DEBUG: Calculated TTL value", {
|
|
7741
8221
|
key,
|
|
7742
8222
|
itemTTL,
|
|
7743
8223
|
defaultTTL: this.config.defaultTTL,
|
|
@@ -7750,7 +8230,7 @@ var TTLManager = class {
|
|
|
7750
8230
|
expiresAt: metadata.addedAt + ttl,
|
|
7751
8231
|
ttl
|
|
7752
8232
|
};
|
|
7753
|
-
|
|
8233
|
+
logger31.debug("TTL_DEBUG: Setting TTL metadata", {
|
|
7754
8234
|
key,
|
|
7755
8235
|
ttl,
|
|
7756
8236
|
addedAt: metadata.addedAt,
|
|
@@ -7758,9 +8238,9 @@ var TTLManager = class {
|
|
|
7758
8238
|
ttlMetadata
|
|
7759
8239
|
});
|
|
7760
8240
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7761
|
-
|
|
8241
|
+
logger31.trace("TTL_DEBUG: TTL set for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7762
8242
|
} else {
|
|
7763
|
-
|
|
8243
|
+
logger31.debug("TTL_DEBUG: No TTL set - invalid TTL value", { key, ttl });
|
|
7764
8244
|
}
|
|
7765
8245
|
}
|
|
7766
8246
|
/**
|
|
@@ -7769,14 +8249,14 @@ var TTLManager = class {
|
|
|
7769
8249
|
async isExpired(key, metadataProvider) {
|
|
7770
8250
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7771
8251
|
if (!metadata || !metadata.expiresAt) {
|
|
7772
|
-
|
|
8252
|
+
logger31.debug("TTL_CHECK: No TTL set for item", { key, hasMetadata: !!metadata });
|
|
7773
8253
|
return false;
|
|
7774
8254
|
}
|
|
7775
8255
|
const now = Date.now();
|
|
7776
8256
|
const expired = now >= metadata.expiresAt;
|
|
7777
8257
|
const remainingMs = metadata.expiresAt - now;
|
|
7778
8258
|
if (expired) {
|
|
7779
|
-
|
|
8259
|
+
logger31.debug("TTL_CHECK: Item EXPIRED", {
|
|
7780
8260
|
key,
|
|
7781
8261
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7782
8262
|
now: new Date(now).toISOString(),
|
|
@@ -7784,7 +8264,7 @@ var TTLManager = class {
|
|
|
7784
8264
|
ttl: metadata.ttl
|
|
7785
8265
|
});
|
|
7786
8266
|
} else {
|
|
7787
|
-
|
|
8267
|
+
logger31.debug("TTL_CHECK: Item still valid", {
|
|
7788
8268
|
key,
|
|
7789
8269
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7790
8270
|
remainingMs,
|
|
@@ -7800,17 +8280,17 @@ var TTLManager = class {
|
|
|
7800
8280
|
*/
|
|
7801
8281
|
async validateItem(key, metadataProvider) {
|
|
7802
8282
|
if (!this.config.validateOnAccess) {
|
|
7803
|
-
|
|
8283
|
+
logger31.debug("TTL_VALIDATE: Validation disabled, skipping check", { key });
|
|
7804
8284
|
return true;
|
|
7805
8285
|
}
|
|
7806
|
-
|
|
8286
|
+
logger31.debug("TTL_VALIDATE: Validating item", {
|
|
7807
8287
|
key,
|
|
7808
8288
|
ttlEnabled: this.isTTLEnabled(),
|
|
7809
8289
|
defaultTTL: this.config.defaultTTL
|
|
7810
8290
|
});
|
|
7811
8291
|
const isExpired = await this.isExpired(key, metadataProvider);
|
|
7812
8292
|
const isValid = !isExpired;
|
|
7813
|
-
|
|
8293
|
+
logger31.debug("TTL_VALIDATE: Validation result", {
|
|
7814
8294
|
key,
|
|
7815
8295
|
isValid,
|
|
7816
8296
|
isExpired
|
|
@@ -7844,7 +8324,7 @@ var TTLManager = class {
|
|
|
7844
8324
|
const expiredKeys = [];
|
|
7845
8325
|
const allMetadata = await metadataProvider.getAllMetadata();
|
|
7846
8326
|
const now = Date.now();
|
|
7847
|
-
|
|
8327
|
+
logger31.debug("TTL_CLEANUP: Scanning for expired items", {
|
|
7848
8328
|
totalItems: allMetadata.size,
|
|
7849
8329
|
now: new Date(now).toISOString()
|
|
7850
8330
|
});
|
|
@@ -7855,7 +8335,7 @@ var TTLManager = class {
|
|
|
7855
8335
|
itemsWithTTL++;
|
|
7856
8336
|
if (now >= ttlMetadata.expiresAt) {
|
|
7857
8337
|
expiredKeys.push(key);
|
|
7858
|
-
|
|
8338
|
+
logger31.debug("TTL_CLEANUP: Found expired item", {
|
|
7859
8339
|
key,
|
|
7860
8340
|
expiresAt: new Date(ttlMetadata.expiresAt).toISOString(),
|
|
7861
8341
|
expiredByMs: now - ttlMetadata.expiresAt
|
|
@@ -7865,7 +8345,7 @@ var TTLManager = class {
|
|
|
7865
8345
|
}
|
|
7866
8346
|
const duration = Date.now() - startTime;
|
|
7867
8347
|
if (expiredKeys.length > 0) {
|
|
7868
|
-
|
|
8348
|
+
logger31.debug("TTL_CLEANUP: Expired items found", {
|
|
7869
8349
|
expiredCount: expiredKeys.length,
|
|
7870
8350
|
totalItems: allMetadata.size,
|
|
7871
8351
|
itemsWithTTL,
|
|
@@ -7873,7 +8353,7 @@ var TTLManager = class {
|
|
|
7873
8353
|
duration
|
|
7874
8354
|
});
|
|
7875
8355
|
} else {
|
|
7876
|
-
|
|
8356
|
+
logger31.debug("TTL_CLEANUP: No expired items found", {
|
|
7877
8357
|
totalItems: allMetadata.size,
|
|
7878
8358
|
itemsWithTTL,
|
|
7879
8359
|
duration
|
|
@@ -7905,7 +8385,7 @@ var TTLManager = class {
|
|
|
7905
8385
|
}
|
|
7906
8386
|
metadata.expiresAt += additionalTTL;
|
|
7907
8387
|
await metadataProvider.setMetadata(key, metadata);
|
|
7908
|
-
|
|
8388
|
+
logger31.trace("TTL extended for item", { key, additionalTTL, newExpiresAt: metadata.expiresAt });
|
|
7909
8389
|
return true;
|
|
7910
8390
|
}
|
|
7911
8391
|
/**
|
|
@@ -7927,7 +8407,7 @@ var TTLManager = class {
|
|
|
7927
8407
|
ttl
|
|
7928
8408
|
};
|
|
7929
8409
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7930
|
-
|
|
8410
|
+
logger31.trace("TTL refreshed for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7931
8411
|
return true;
|
|
7932
8412
|
}
|
|
7933
8413
|
/**
|
|
@@ -7939,9 +8419,9 @@ var TTLManager = class {
|
|
|
7939
8419
|
}
|
|
7940
8420
|
if (this.config.cleanupInterval) {
|
|
7941
8421
|
this.cleanupTimer = setInterval(() => {
|
|
7942
|
-
|
|
8422
|
+
logger31.trace("Auto cleanup timer triggered");
|
|
7943
8423
|
}, this.config.cleanupInterval);
|
|
7944
|
-
|
|
8424
|
+
logger31.debug("Auto cleanup started", { interval: this.config.cleanupInterval });
|
|
7945
8425
|
}
|
|
7946
8426
|
}
|
|
7947
8427
|
/**
|
|
@@ -7951,7 +8431,7 @@ var TTLManager = class {
|
|
|
7951
8431
|
if (this.cleanupTimer) {
|
|
7952
8432
|
clearInterval(this.cleanupTimer);
|
|
7953
8433
|
this.cleanupTimer = null;
|
|
7954
|
-
|
|
8434
|
+
logger31.debug("Auto cleanup stopped");
|
|
7955
8435
|
}
|
|
7956
8436
|
}
|
|
7957
8437
|
/**
|
|
@@ -7959,18 +8439,31 @@ var TTLManager = class {
|
|
|
7959
8439
|
*/
|
|
7960
8440
|
clear() {
|
|
7961
8441
|
this.stopAutoCleanup();
|
|
7962
|
-
|
|
8442
|
+
logger31.debug("TTL manager cleared");
|
|
7963
8443
|
}
|
|
7964
8444
|
/**
|
|
7965
8445
|
* Cleanup resources
|
|
7966
8446
|
*/
|
|
7967
8447
|
destroy() {
|
|
8448
|
+
logger31.debug("TTL manager destroy started", {
|
|
8449
|
+
component: "cache",
|
|
8450
|
+
subcomponent: "TTLManager",
|
|
8451
|
+
operation: "destroy",
|
|
8452
|
+
autoCleanupEnabled: !!this.config.cleanupInterval,
|
|
8453
|
+
note: "Stopping auto-cleanup and clearing TTL data"
|
|
8454
|
+
});
|
|
7968
8455
|
this.stopAutoCleanup();
|
|
7969
|
-
|
|
8456
|
+
logger31.debug("TTL manager destroyed", {
|
|
8457
|
+
component: "cache",
|
|
8458
|
+
subcomponent: "TTLManager",
|
|
8459
|
+
operation: "destroy",
|
|
8460
|
+
note: "All TTL tracking data cleared"
|
|
8461
|
+
});
|
|
7970
8462
|
}
|
|
7971
8463
|
};
|
|
7972
8464
|
|
|
7973
8465
|
// src/events/CacheEventEmitter.ts
|
|
8466
|
+
var logger32 = logger_default.get("CacheEventEmitter");
|
|
7974
8467
|
var CacheEventEmitter = class {
|
|
7975
8468
|
subscriptions = /* @__PURE__ */ new Map();
|
|
7976
8469
|
nextSubscriptionId = 1;
|
|
@@ -8071,9 +8564,17 @@ var CacheEventEmitter = class {
|
|
|
8071
8564
|
*/
|
|
8072
8565
|
emit(event) {
|
|
8073
8566
|
if (this.isDestroyed) {
|
|
8567
|
+
logger32.debug("Event emission skipped - emitter is destroyed", {
|
|
8568
|
+
component: "cache",
|
|
8569
|
+
subcomponent: "CacheEventEmitter",
|
|
8570
|
+
eventType: event.type,
|
|
8571
|
+
suggestion: "This is expected during cleanup. Ensure emitter is not used after destroy()."
|
|
8572
|
+
});
|
|
8074
8573
|
return;
|
|
8075
8574
|
}
|
|
8076
8575
|
let emittedCount = 0;
|
|
8576
|
+
const totalSubscriptions = this.subscriptions.size;
|
|
8577
|
+
const activeSubscriptions = Array.from(this.subscriptions.values()).filter((s) => s.isActive).length;
|
|
8077
8578
|
for (const subscription of this.subscriptions.values()) {
|
|
8078
8579
|
if (!subscription.isActive) {
|
|
8079
8580
|
continue;
|
|
@@ -8083,6 +8584,17 @@ var CacheEventEmitter = class {
|
|
|
8083
8584
|
emittedCount++;
|
|
8084
8585
|
}
|
|
8085
8586
|
}
|
|
8587
|
+
logger32.trace("Event emitted to subscriptions", {
|
|
8588
|
+
component: "cache",
|
|
8589
|
+
subcomponent: "CacheEventEmitter",
|
|
8590
|
+
eventType: event.type,
|
|
8591
|
+
eventSource: event.source,
|
|
8592
|
+
eventKey: "key" in event ? JSON.stringify(event.key) : void 0,
|
|
8593
|
+
totalSubscriptions,
|
|
8594
|
+
activeSubscriptions,
|
|
8595
|
+
emittedCount,
|
|
8596
|
+
note: emittedCount === 0 ? "No subscriptions matched this event" : void 0
|
|
8597
|
+
});
|
|
8086
8598
|
}
|
|
8087
8599
|
/**
|
|
8088
8600
|
* Get count of active subscriptions
|
|
@@ -8287,20 +8799,36 @@ var CacheEventEmitter = class {
|
|
|
8287
8799
|
*/
|
|
8288
8800
|
handleListenerError(error, event, subscription) {
|
|
8289
8801
|
const errorObj = error instanceof Error ? error : new Error(String(error));
|
|
8802
|
+
const errorContext = {
|
|
8803
|
+
component: "CacheEventEmitter",
|
|
8804
|
+
operation: "event-listener",
|
|
8805
|
+
eventType: event.type,
|
|
8806
|
+
eventKey: "key" in event ? JSON.stringify(event.key) : void 0,
|
|
8807
|
+
subscriptionId: subscription.id,
|
|
8808
|
+
errorType: errorObj.constructor.name,
|
|
8809
|
+
errorMessage: errorObj.message,
|
|
8810
|
+
suggestion: "Review event listener implementation for errors. Consider adding error handling in the listener.",
|
|
8811
|
+
stack: errorObj.stack
|
|
8812
|
+
};
|
|
8290
8813
|
if (subscription.options.onError) {
|
|
8291
8814
|
try {
|
|
8292
8815
|
subscription.options.onError(errorObj, event);
|
|
8293
8816
|
} catch (handlerError) {
|
|
8294
|
-
console.error("Error in cache event listener:",
|
|
8817
|
+
console.error("Error in cache event listener:", JSON.stringify(errorContext, null, 2));
|
|
8818
|
+
console.error("Original error:", errorObj);
|
|
8295
8819
|
console.error("Error in error handler:", handlerError);
|
|
8820
|
+
console.error("Critical: Both the event listener and its error handler failed. Review error handling logic.");
|
|
8296
8821
|
}
|
|
8297
8822
|
} else {
|
|
8298
|
-
console.error("Error in cache event listener:",
|
|
8823
|
+
console.error("Error in cache event listener (no error handler configured):", JSON.stringify(errorContext, null, 2));
|
|
8824
|
+
console.error("Original error:", errorObj);
|
|
8825
|
+
console.error("Suggestion: Add an onError handler to your subscription to handle listener errors gracefully.");
|
|
8299
8826
|
}
|
|
8300
8827
|
}
|
|
8301
8828
|
};
|
|
8302
8829
|
|
|
8303
8830
|
// src/CacheStats.ts
|
|
8831
|
+
var logger33 = logger_default.get("CacheStats");
|
|
8304
8832
|
var CacheStatsManager = class {
|
|
8305
8833
|
stats = {
|
|
8306
8834
|
numRequests: 0,
|
|
@@ -8310,11 +8838,22 @@ var CacheStatsManager = class {
|
|
|
8310
8838
|
numUnsubscriptions: 0,
|
|
8311
8839
|
activeSubscriptions: 0
|
|
8312
8840
|
};
|
|
8841
|
+
lastLoggedStats = {
|
|
8842
|
+
numRequests: 0,
|
|
8843
|
+
numMisses: 0,
|
|
8844
|
+
numHits: 0,
|
|
8845
|
+
numSubscriptions: 0,
|
|
8846
|
+
numUnsubscriptions: 0,
|
|
8847
|
+
activeSubscriptions: 0
|
|
8848
|
+
};
|
|
8849
|
+
LOG_THRESHOLD = 100;
|
|
8850
|
+
// Log every 100 requests
|
|
8313
8851
|
/**
|
|
8314
8852
|
* Increment the request counter
|
|
8315
8853
|
*/
|
|
8316
8854
|
incrementRequests() {
|
|
8317
8855
|
this.stats.numRequests++;
|
|
8856
|
+
this.maybeLogStats();
|
|
8318
8857
|
}
|
|
8319
8858
|
/**
|
|
8320
8859
|
* Increment the cache hit counter
|
|
@@ -8328,6 +8867,27 @@ var CacheStatsManager = class {
|
|
|
8328
8867
|
incrementMisses() {
|
|
8329
8868
|
this.stats.numMisses++;
|
|
8330
8869
|
}
|
|
8870
|
+
/**
|
|
8871
|
+
* Log statistics periodically for monitoring
|
|
8872
|
+
*/
|
|
8873
|
+
maybeLogStats() {
|
|
8874
|
+
const requestsSinceLastLog = this.stats.numRequests - this.lastLoggedStats.numRequests;
|
|
8875
|
+
if (requestsSinceLastLog >= this.LOG_THRESHOLD) {
|
|
8876
|
+
const hitRate = this.stats.numRequests > 0 ? (this.stats.numHits / this.stats.numRequests * 100).toFixed(2) : "0.00";
|
|
8877
|
+
logger33.debug("Cache statistics update", {
|
|
8878
|
+
component: "cache",
|
|
8879
|
+
subcomponent: "CacheStatsManager",
|
|
8880
|
+
totalRequests: this.stats.numRequests,
|
|
8881
|
+
hits: this.stats.numHits,
|
|
8882
|
+
misses: this.stats.numMisses,
|
|
8883
|
+
hitRate: `${hitRate}%`,
|
|
8884
|
+
activeSubscriptions: this.stats.activeSubscriptions,
|
|
8885
|
+
requestsSinceLastLog,
|
|
8886
|
+
note: `Statistics logged every ${this.LOG_THRESHOLD} requests for monitoring`
|
|
8887
|
+
});
|
|
8888
|
+
this.lastLoggedStats = { ...this.stats };
|
|
8889
|
+
}
|
|
8890
|
+
}
|
|
8331
8891
|
/**
|
|
8332
8892
|
* Increment the subscription counter
|
|
8333
8893
|
*/
|
|
@@ -8366,9 +8926,17 @@ var CacheStatsManager = class {
|
|
|
8366
8926
|
};
|
|
8367
8927
|
|
|
8368
8928
|
// src/Cache.ts
|
|
8369
|
-
var
|
|
8929
|
+
var logger34 = logger_default.get("Cache");
|
|
8370
8930
|
var createCache = (api, coordinate, registry, options) => {
|
|
8371
|
-
|
|
8931
|
+
logger34.debug("createCache", {
|
|
8932
|
+
component: "cache",
|
|
8933
|
+
operation: "createCache",
|
|
8934
|
+
itemType: coordinate.kta[0],
|
|
8935
|
+
hierarchy: coordinate.kta,
|
|
8936
|
+
cacheType: options?.cacheType,
|
|
8937
|
+
hasRegistry: !!registry,
|
|
8938
|
+
note: "Cache creation started"
|
|
8939
|
+
});
|
|
8372
8940
|
const completeOptions = createOptions(options);
|
|
8373
8941
|
const cacheMap = createCacheMap(coordinate.kta, completeOptions);
|
|
8374
8942
|
const pkType = coordinate.kta[0];
|
|
@@ -8448,18 +9016,24 @@ var isCache2 = (cache) => {
|
|
|
8448
9016
|
};
|
|
8449
9017
|
|
|
8450
9018
|
// src/InstanceFactory.ts
|
|
8451
|
-
var
|
|
9019
|
+
var logger35 = logger_default.get("InstanceFactory");
|
|
8452
9020
|
var createInstanceFactory = (api, options) => {
|
|
8453
9021
|
const templateOptions = createOptions(options);
|
|
8454
9022
|
validateOptions(templateOptions);
|
|
8455
9023
|
return (coordinate, context) => {
|
|
8456
9024
|
const instanceOptions = createOptions(options);
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
9025
|
+
logger35.debug("Creating cache instance", {
|
|
9026
|
+
component: "cache",
|
|
9027
|
+
operation: "createInstance",
|
|
9028
|
+
itemType: coordinate.kta[0],
|
|
9029
|
+
hierarchy: coordinate.kta,
|
|
8461
9030
|
cacheType: instanceOptions.cacheType,
|
|
8462
|
-
|
|
9031
|
+
ttlEnabled: !!instanceOptions.ttl,
|
|
9032
|
+
ttlValue: instanceOptions.ttl,
|
|
9033
|
+
evictionEnabled: !!instanceOptions.evictionConfig,
|
|
9034
|
+
evictionStrategy: instanceOptions.evictionConfig?.type,
|
|
9035
|
+
twoLayerEnabled: !!instanceOptions.twoLayer,
|
|
9036
|
+
note: "Cache instance initialization started"
|
|
8463
9037
|
});
|
|
8464
9038
|
const cacheMap = createCacheMap(coordinate.kta, instanceOptions);
|
|
8465
9039
|
const pkType = coordinate.kta[0];
|
|
@@ -8521,9 +9095,9 @@ var createInstanceFactory = (api, options) => {
|
|
|
8521
9095
|
};
|
|
8522
9096
|
|
|
8523
9097
|
// src/Instance.ts
|
|
8524
|
-
var
|
|
9098
|
+
var logger36 = logger_default.get("Instance");
|
|
8525
9099
|
var createInstance = (registry, coordinate, api, options) => {
|
|
8526
|
-
|
|
9100
|
+
logger36.debug("createInstance", { coordinate, api, registry, options });
|
|
8527
9101
|
return createCache(api, coordinate, registry, options);
|
|
8528
9102
|
};
|
|
8529
9103
|
var isInstance = (instance) => {
|
|
@@ -8531,7 +9105,7 @@ var isInstance = (instance) => {
|
|
|
8531
9105
|
};
|
|
8532
9106
|
|
|
8533
9107
|
// src/Aggregator.ts
|
|
8534
|
-
var
|
|
9108
|
+
var logger37 = logger_default.get("ItemAggregator");
|
|
8535
9109
|
var toCacheConfig = (config) => {
|
|
8536
9110
|
let cacheConfig;
|
|
8537
9111
|
if (config.optional === void 0) {
|
|
@@ -8543,23 +9117,32 @@ var toCacheConfig = (config) => {
|
|
|
8543
9117
|
};
|
|
8544
9118
|
var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
8545
9119
|
const populate = async (item) => {
|
|
8546
|
-
|
|
9120
|
+
logger37.default("populate", { item });
|
|
8547
9121
|
for (const key in aggregates) {
|
|
8548
9122
|
await populateAggregate(key, item);
|
|
8549
9123
|
}
|
|
8550
9124
|
for (const key in events) {
|
|
8551
9125
|
await populateEvent(key, item);
|
|
8552
9126
|
}
|
|
8553
|
-
|
|
9127
|
+
logger37.default("populate done", { item });
|
|
8554
9128
|
return item;
|
|
8555
9129
|
};
|
|
8556
9130
|
const populateAggregate = async (key, item) => {
|
|
8557
|
-
|
|
9131
|
+
logger37.default("populate aggregate key", { key });
|
|
8558
9132
|
const cacheConfig = toCacheConfig(aggregates[key]);
|
|
8559
9133
|
if (item.refs === void 0) {
|
|
8560
9134
|
if (cacheConfig.optional === false) {
|
|
8561
|
-
|
|
8562
|
-
|
|
9135
|
+
logger37.error("Item missing required refs property", {
|
|
9136
|
+
component: "cache",
|
|
9137
|
+
subcomponent: "Aggregator",
|
|
9138
|
+
operation: "populateRef",
|
|
9139
|
+
refKey: key,
|
|
9140
|
+
item: JSON.stringify(item),
|
|
9141
|
+
suggestion: "Ensure the item has a refs property or mark this reference as optional in cache configuration"
|
|
9142
|
+
});
|
|
9143
|
+
throw new Error(
|
|
9144
|
+
`Item missing required refs property for reference '${key}'. Item: ${JSON.stringify(item)}. Suggestion: Add refs property to item or set optional: true in cache config.`
|
|
9145
|
+
);
|
|
8563
9146
|
} else {
|
|
8564
9147
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
8565
9148
|
delete item.events[key];
|
|
@@ -8567,8 +9150,18 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8567
9150
|
}
|
|
8568
9151
|
} else if (item.refs[key] === void 0) {
|
|
8569
9152
|
if (cacheConfig.optional === false) {
|
|
8570
|
-
|
|
8571
|
-
|
|
9153
|
+
logger37.error("Item missing required reference", {
|
|
9154
|
+
component: "cache",
|
|
9155
|
+
subcomponent: "Aggregator",
|
|
9156
|
+
operation: "populateRef",
|
|
9157
|
+
refKey: key,
|
|
9158
|
+
availableRefs: Object.keys(item.refs || {}),
|
|
9159
|
+
item: JSON.stringify(item),
|
|
9160
|
+
suggestion: `Ensure the item has refs.${key} property or mark this reference as optional in cache configuration`
|
|
9161
|
+
});
|
|
9162
|
+
throw new Error(
|
|
9163
|
+
`Item missing required reference '${key}'. Available refs: [${Object.keys(item.refs || {}).join(", ")}]. Item: ${JSON.stringify(item)}. Suggestion: Add refs.${key} to item or set optional: true in cache config.`
|
|
9164
|
+
);
|
|
8572
9165
|
} else {
|
|
8573
9166
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
8574
9167
|
delete item.events[key];
|
|
@@ -8576,7 +9169,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8576
9169
|
}
|
|
8577
9170
|
} else {
|
|
8578
9171
|
const ref = item.refs[key];
|
|
8579
|
-
|
|
9172
|
+
logger37.default("AGG Retrieving Item in Populate", { key: ref });
|
|
8580
9173
|
const newItem = await cacheConfig.cache.operations.retrieve(ref);
|
|
8581
9174
|
if (newItem) {
|
|
8582
9175
|
if (item.aggs === void 0) {
|
|
@@ -8593,25 +9186,52 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8593
9186
|
}
|
|
8594
9187
|
};
|
|
8595
9188
|
const populateEvent = async (key, item) => {
|
|
8596
|
-
|
|
9189
|
+
logger37.default("populate event key", { key });
|
|
8597
9190
|
const cacheConfig = toCacheConfig(events[key]);
|
|
8598
9191
|
if (item.events === void 0) {
|
|
8599
|
-
|
|
9192
|
+
logger37.error("Item missing events property", {
|
|
9193
|
+
component: "cache",
|
|
9194
|
+
subcomponent: "Aggregator",
|
|
9195
|
+
operation: "populateEvent",
|
|
9196
|
+
eventKey: key,
|
|
9197
|
+
item: JSON.stringify(item),
|
|
9198
|
+
suggestion: "Ensure the item has an events property with event data"
|
|
9199
|
+
});
|
|
9200
|
+
throw new Error(
|
|
9201
|
+
`Item missing events property for event '${key}'. Item: ${JSON.stringify(item)}. Suggestion: Ensure events are properly tracked on this item type.`
|
|
9202
|
+
);
|
|
8600
9203
|
} else if (item.events[key] === void 0) {
|
|
8601
9204
|
if (cacheConfig.optional === false) {
|
|
8602
|
-
|
|
8603
|
-
|
|
9205
|
+
logger37.error("Item missing required event", {
|
|
9206
|
+
component: "cache",
|
|
9207
|
+
subcomponent: "Aggregator",
|
|
9208
|
+
operation: "populateEvent",
|
|
9209
|
+
eventKey: key,
|
|
9210
|
+
availableEvents: Object.keys(item.events || {}),
|
|
9211
|
+
item: JSON.stringify(item),
|
|
9212
|
+
suggestion: `Ensure the item has events.${key} property or mark this event as optional`
|
|
9213
|
+
});
|
|
9214
|
+
throw new Error(
|
|
9215
|
+
`Item missing required event '${key}'. Available events: [${Object.keys(item.events || {}).join(", ")}]. Item: ${JSON.stringify(item)}. Suggestion: Add events.${key} to item or set optional: true in cache config.`
|
|
9216
|
+
);
|
|
8604
9217
|
}
|
|
8605
9218
|
} else {
|
|
8606
9219
|
const event = item.events[key];
|
|
8607
9220
|
if (event.by === void 0) {
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
9221
|
+
logger37.error('Event missing required "by" field', {
|
|
9222
|
+
component: "cache",
|
|
9223
|
+
subcomponent: "Aggregator",
|
|
9224
|
+
operation: "populateEvent",
|
|
9225
|
+
eventKey: key,
|
|
9226
|
+
event,
|
|
9227
|
+
itemKey: item.key,
|
|
9228
|
+
suggestion: 'Ensure event has a "by" field with the user/actor who triggered the event'
|
|
9229
|
+
});
|
|
9230
|
+
throw new Error(
|
|
9231
|
+
`Event '${key}' missing required "by" field. Event: ${JSON.stringify(event)}. Item: ${JSON.stringify(item.key)}. Suggestion: Events must include a "by" field to track who performed the action.`
|
|
8611
9232
|
);
|
|
8612
|
-
throw new Error("populateEvent with an Event that does not have by: " + JSON.stringify({ key }));
|
|
8613
9233
|
}
|
|
8614
|
-
|
|
9234
|
+
logger37.default("EVENT Retrieving Item in Populate", { key: event.by });
|
|
8615
9235
|
const newItem = await cacheConfig.cache.operations.retrieve(event.by);
|
|
8616
9236
|
if (newItem) {
|
|
8617
9237
|
event.agg = newItem;
|
|
@@ -8619,13 +9239,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8619
9239
|
}
|
|
8620
9240
|
};
|
|
8621
9241
|
const all2 = async (query = {}, locations = []) => {
|
|
8622
|
-
|
|
9242
|
+
logger37.default("all", { query, locations });
|
|
8623
9243
|
const result = await cache.operations.all(query, locations);
|
|
8624
9244
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8625
9245
|
return populatedItems;
|
|
8626
9246
|
};
|
|
8627
9247
|
const one2 = async (query = {}, locations = []) => {
|
|
8628
|
-
|
|
9248
|
+
logger37.default("one", { query, locations });
|
|
8629
9249
|
const item = await cache.operations.one(query, locations);
|
|
8630
9250
|
let populatedItem = null;
|
|
8631
9251
|
if (item) {
|
|
@@ -8634,30 +9254,30 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8634
9254
|
return populatedItem;
|
|
8635
9255
|
};
|
|
8636
9256
|
const action2 = async (key, action3, body = {}) => {
|
|
8637
|
-
|
|
9257
|
+
logger37.default("action", { key, action: action3, body });
|
|
8638
9258
|
const [item, affectedItems] = await cache.operations.action(key, action3, body);
|
|
8639
9259
|
const populatedItem = await populate(item);
|
|
8640
9260
|
return [populatedItem, affectedItems];
|
|
8641
9261
|
};
|
|
8642
9262
|
const allAction2 = async (action3, body = {}, locations = []) => {
|
|
8643
|
-
|
|
9263
|
+
logger37.default("action", { action: action3, body, locations });
|
|
8644
9264
|
const [items, affectedItems] = await cache.operations.allAction(action3, body, locations);
|
|
8645
9265
|
const populatedItems = await Promise.all(items.map(async (item) => populate(item)));
|
|
8646
9266
|
return [populatedItems, affectedItems];
|
|
8647
9267
|
};
|
|
8648
9268
|
const allFacet2 = async (facet3, params = {}, locations = []) => {
|
|
8649
|
-
|
|
9269
|
+
logger37.default("allFacet", { facet: facet3, params, locations });
|
|
8650
9270
|
const response = await cache.operations.allFacet(facet3, params, locations);
|
|
8651
9271
|
return response;
|
|
8652
9272
|
};
|
|
8653
9273
|
const create2 = async (v, locations = []) => {
|
|
8654
|
-
|
|
9274
|
+
logger37.default("create", { v, locations });
|
|
8655
9275
|
const item = locations.length === 0 ? await cache.operations.create(v) : await cache.operations.create(v, { locations });
|
|
8656
9276
|
const populatedItem = await populate(item);
|
|
8657
9277
|
return populatedItem;
|
|
8658
9278
|
};
|
|
8659
9279
|
const get2 = async (key) => {
|
|
8660
|
-
|
|
9280
|
+
logger37.default("get", { key });
|
|
8661
9281
|
const item = await cache.operations.get(key);
|
|
8662
9282
|
let populatedItem = null;
|
|
8663
9283
|
if (item) {
|
|
@@ -8666,7 +9286,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8666
9286
|
return populatedItem;
|
|
8667
9287
|
};
|
|
8668
9288
|
const retrieve2 = async (key) => {
|
|
8669
|
-
|
|
9289
|
+
logger37.default("retrieve", { key });
|
|
8670
9290
|
const item = await cache.operations.retrieve(key);
|
|
8671
9291
|
let populatedItem = null;
|
|
8672
9292
|
if (item) {
|
|
@@ -8675,22 +9295,22 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8675
9295
|
return populatedItem;
|
|
8676
9296
|
};
|
|
8677
9297
|
const remove2 = async (key) => {
|
|
8678
|
-
|
|
9298
|
+
logger37.default("remove", { key });
|
|
8679
9299
|
await cache.operations.remove(key);
|
|
8680
9300
|
};
|
|
8681
9301
|
const update2 = async (key, v) => {
|
|
8682
|
-
|
|
9302
|
+
logger37.default("update", { key, v });
|
|
8683
9303
|
const item = await cache.operations.update(key, v);
|
|
8684
9304
|
const populatedItem = await populate(item);
|
|
8685
9305
|
return populatedItem;
|
|
8686
9306
|
};
|
|
8687
9307
|
const facet2 = async (key, facet3) => {
|
|
8688
|
-
|
|
9308
|
+
logger37.default("facet", { key, facet: facet3 });
|
|
8689
9309
|
const response = await cache.operations.facet(key, facet3);
|
|
8690
9310
|
return response;
|
|
8691
9311
|
};
|
|
8692
9312
|
const find2 = async (finder, finderParams = {}, locations = [], findOptions) => {
|
|
8693
|
-
|
|
9313
|
+
logger37.default("find", { finder, finderParams, locations, findOptions });
|
|
8694
9314
|
const result = await cache.operations.find(finder, finderParams, locations, findOptions);
|
|
8695
9315
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8696
9316
|
return {
|
|
@@ -8699,7 +9319,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8699
9319
|
};
|
|
8700
9320
|
};
|
|
8701
9321
|
const findOne2 = async (finder, finderParams = {}, locations = []) => {
|
|
8702
|
-
|
|
9322
|
+
logger37.default("find", { finder, finderParams, locations });
|
|
8703
9323
|
const item = await cache.operations.findOne(finder, finderParams, locations);
|
|
8704
9324
|
if (!item) {
|
|
8705
9325
|
return null;
|
|
@@ -8708,7 +9328,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8708
9328
|
return populatedItem;
|
|
8709
9329
|
};
|
|
8710
9330
|
const set2 = async (key, v) => {
|
|
8711
|
-
|
|
9331
|
+
logger37.default("set", { key, v });
|
|
8712
9332
|
const item = await cache.operations.set(key, v);
|
|
8713
9333
|
const populatedItem = await populate(item);
|
|
8714
9334
|
return populatedItem;
|
|
@@ -8760,13 +9380,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8760
9380
|
import {
|
|
8761
9381
|
createRegistry as createBaseRegistry
|
|
8762
9382
|
} from "@fjell/registry";
|
|
8763
|
-
var
|
|
9383
|
+
var logger38 = logger_default.get("Registry");
|
|
8764
9384
|
var createRegistryFactory = () => {
|
|
8765
9385
|
return (type, registryHub) => {
|
|
8766
9386
|
if (type !== "cache") {
|
|
8767
9387
|
throw new Error(`Cache registry factory can only create 'cache' type registries, got: ${type}`);
|
|
8768
9388
|
}
|
|
8769
|
-
|
|
9389
|
+
logger38.debug("Creating cache registry", { type, registryHub });
|
|
8770
9390
|
const baseRegistry = createBaseRegistry(type, registryHub);
|
|
8771
9391
|
return baseRegistry;
|
|
8772
9392
|
};
|