@fjell/cache 4.7.60 → 4.7.61
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.map +1 -1
- package/dist/Cache.d.ts.map +1 -1
- package/dist/CacheStats.d.ts +6 -0
- package/dist/CacheStats.d.ts.map +1 -1
- package/dist/InstanceFactory.d.ts.map +1 -1
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Options.d.ts.map +1 -1
- package/dist/browser/AsyncIndexDBCacheMap.d.ts.map +1 -1
- package/dist/browser/LocalStorageCacheMap.d.ts.map +1 -1
- package/dist/browser/SessionStorageCacheMap.d.ts.map +1 -1
- package/dist/events/CacheEventEmitter.d.ts.map +1 -1
- package/dist/eviction/EvictionStrategyValidation.d.ts.map +1 -1
- package/dist/index.js +796 -186
- package/dist/normalization.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/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -606,7 +606,20 @@ var createQueryHash = (pkType, query, locations) => {
|
|
|
606
606
|
};
|
|
607
607
|
const hash = deterministicStringify(hashInput);
|
|
608
608
|
if (!hash || typeof hash !== "string" || hash.trim() === "") {
|
|
609
|
-
|
|
609
|
+
const errorContext = {
|
|
610
|
+
component: "cache",
|
|
611
|
+
subcomponent: "normalization",
|
|
612
|
+
operation: "createQueryHash",
|
|
613
|
+
pkType,
|
|
614
|
+
query: JSON.stringify(query),
|
|
615
|
+
locations: JSON.stringify(locations),
|
|
616
|
+
hashResult: hash,
|
|
617
|
+
suggestion: "This indicates a bug in query normalization. Check query and location structures."
|
|
618
|
+
};
|
|
619
|
+
console.error("Invalid query hash generated:", JSON.stringify(errorContext, null, 2));
|
|
620
|
+
throw new Error(
|
|
621
|
+
`Invalid query hash generated: hash is empty or invalid. Input: ${JSON.stringify({ pkType, query, locations })}. This indicates a bug in query normalization logic.`
|
|
622
|
+
);
|
|
610
623
|
}
|
|
611
624
|
return hash;
|
|
612
625
|
};
|
|
@@ -866,10 +879,27 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
866
879
|
logger4.debug("Cache bypass enabled, fetching directly from API", { query, locations });
|
|
867
880
|
try {
|
|
868
881
|
const ret = await api.all(query, locations, allOptions);
|
|
869
|
-
logger4.debug("API response received (not cached due to bypass)", {
|
|
882
|
+
logger4.debug("API response received (not cached due to bypass)", {
|
|
883
|
+
operation: "all",
|
|
884
|
+
mode: "bypass",
|
|
885
|
+
query,
|
|
886
|
+
locations,
|
|
887
|
+
itemCount: ret.items.length,
|
|
888
|
+
metadata: ret.metadata
|
|
889
|
+
});
|
|
870
890
|
return ret;
|
|
871
891
|
} catch (error) {
|
|
872
|
-
logger4.error("API request failed
|
|
892
|
+
logger4.error("API request failed in bypass mode", {
|
|
893
|
+
operation: "all",
|
|
894
|
+
mode: "bypass",
|
|
895
|
+
query,
|
|
896
|
+
locations,
|
|
897
|
+
errorType: error.constructor?.name || typeof error,
|
|
898
|
+
errorMessage: error.message,
|
|
899
|
+
errorCode: error.code || error.errorInfo?.code,
|
|
900
|
+
suggestion: "Verify API endpoint is accessible, query syntax is correct, and locations are valid",
|
|
901
|
+
error
|
|
902
|
+
});
|
|
873
903
|
throw error;
|
|
874
904
|
}
|
|
875
905
|
}
|
|
@@ -955,8 +985,15 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
955
985
|
}
|
|
956
986
|
} catch (error) {
|
|
957
987
|
logger4.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
|
|
988
|
+
operation: "all",
|
|
989
|
+
phase: "cache-query",
|
|
958
990
|
queryHash,
|
|
959
|
-
|
|
991
|
+
query: JSON.stringify(query),
|
|
992
|
+
locations: JSON.stringify(locations),
|
|
993
|
+
errorType: error.constructor?.name || typeof error,
|
|
994
|
+
errorMessage: error instanceof Error ? error.message : String(error),
|
|
995
|
+
cacheType: cacheMap.implementationType,
|
|
996
|
+
note: "This is expected behavior - falling back to API when cache query fails"
|
|
960
997
|
});
|
|
961
998
|
}
|
|
962
999
|
} else {
|
|
@@ -1031,9 +1068,19 @@ async function executeAllLogic(query, locations, context, allOptions) {
|
|
|
1031
1068
|
await cacheMap.setQueryResult(queryHash, []);
|
|
1032
1069
|
logger4.debug("QUERY_CACHE: Cached empty query result for not found", { queryHash });
|
|
1033
1070
|
} else {
|
|
1034
|
-
logger4.
|
|
1071
|
+
logger4.error("QUERY_CACHE: API error occurred during all() operation", {
|
|
1072
|
+
operation: "all",
|
|
1073
|
+
phase: "api-fetch",
|
|
1035
1074
|
queryHash,
|
|
1036
|
-
|
|
1075
|
+
query: JSON.stringify(query),
|
|
1076
|
+
locations: JSON.stringify(locations),
|
|
1077
|
+
errorType: e instanceof Error ? e.constructor.name : typeof e,
|
|
1078
|
+
errorMessage: e instanceof Error ? e.message : String(e),
|
|
1079
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1080
|
+
cacheType: cacheMap.implementationType,
|
|
1081
|
+
inFlightRequestsCount: inFlightRequests.size,
|
|
1082
|
+
suggestion: "Check API connectivity, query syntax, location keys, and network connectivity",
|
|
1083
|
+
error: e
|
|
1037
1084
|
});
|
|
1038
1085
|
throw e;
|
|
1039
1086
|
}
|
|
@@ -1405,27 +1452,63 @@ var create = async (v, locations = [], context) => {
|
|
|
1405
1452
|
return [context, result];
|
|
1406
1453
|
};
|
|
1407
1454
|
async function executeCreateLogic(v, locations, context) {
|
|
1455
|
+
const startTime = Date.now();
|
|
1408
1456
|
const { api, cacheMap, pkType, eventEmitter, ttlManager, evictionManager } = context;
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1457
|
+
try {
|
|
1458
|
+
logger6.debug("CACHE_OP: create() started", {
|
|
1459
|
+
operation: "create",
|
|
1460
|
+
itemType: pkType,
|
|
1461
|
+
hasLocations: locations.length > 0,
|
|
1462
|
+
locationCount: locations.length,
|
|
1463
|
+
itemData: JSON.stringify(v)
|
|
1464
|
+
});
|
|
1465
|
+
const created = await api.create(v, locations.length > 0 ? { locations } : void 0);
|
|
1466
|
+
const apiDuration = Date.now() - startTime;
|
|
1467
|
+
cacheMap.set(created.key, created);
|
|
1468
|
+
const keyStr = JSON.stringify(created.key);
|
|
1469
|
+
ttlManager.onItemAdded(keyStr, cacheMap);
|
|
1470
|
+
const evictedKeys = await evictionManager.onItemAdded(keyStr, created, cacheMap);
|
|
1471
|
+
for (const evictedKey of evictedKeys) {
|
|
1472
|
+
const parsedKey = JSON.parse(evictedKey);
|
|
1473
|
+
await cacheMap.delete(parsedKey);
|
|
1474
|
+
}
|
|
1475
|
+
await cacheMap.clearQueryResults();
|
|
1476
|
+
const itemEvent = CacheEventFactory.itemCreated(created.key, created, "api");
|
|
1477
|
+
eventEmitter.emit(itemEvent);
|
|
1478
|
+
const queryInvalidatedEvent = CacheEventFactory.createQueryInvalidatedEvent(
|
|
1479
|
+
[],
|
|
1480
|
+
// We don't track which specific queries were invalidated
|
|
1481
|
+
"item_changed",
|
|
1482
|
+
{ source: "operation", context: { operation: "create" } }
|
|
1483
|
+
);
|
|
1484
|
+
eventEmitter.emit(queryInvalidatedEvent);
|
|
1485
|
+
const totalDuration = Date.now() - startTime;
|
|
1486
|
+
logger6.debug("CACHE_OP: create() completed successfully", {
|
|
1487
|
+
operation: "create",
|
|
1488
|
+
itemType: pkType,
|
|
1489
|
+
key: keyStr,
|
|
1490
|
+
evictedCount: evictedKeys.length,
|
|
1491
|
+
apiDuration,
|
|
1492
|
+
totalDuration
|
|
1493
|
+
});
|
|
1494
|
+
return created;
|
|
1495
|
+
} catch (e) {
|
|
1496
|
+
const duration = Date.now() - startTime;
|
|
1497
|
+
logger6.error("CACHE_OP: create() operation failed", {
|
|
1498
|
+
operation: "create",
|
|
1499
|
+
itemType: pkType,
|
|
1500
|
+
itemData: JSON.stringify(v),
|
|
1501
|
+
locations: JSON.stringify(locations),
|
|
1502
|
+
duration,
|
|
1503
|
+
errorType: e.constructor?.name || typeof e,
|
|
1504
|
+
errorMessage: e.message,
|
|
1505
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1506
|
+
cacheType: cacheMap.implementationType,
|
|
1507
|
+
suggestion: "Check validation errors, duplicate constraints, required fields, and API connectivity",
|
|
1508
|
+
stack: e.stack
|
|
1509
|
+
});
|
|
1510
|
+
throw e;
|
|
1417
1511
|
}
|
|
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
1512
|
}
|
|
1430
1513
|
|
|
1431
1514
|
// src/ops/get.ts
|
|
@@ -1475,8 +1558,15 @@ async function executeGetLogic(key, context) {
|
|
|
1475
1558
|
});
|
|
1476
1559
|
statsManager.incrementRequests();
|
|
1477
1560
|
if (!isValidItemKey(key)) {
|
|
1478
|
-
logger7.error("CACHE_OP: Invalid key for get", {
|
|
1479
|
-
|
|
1561
|
+
logger7.error("CACHE_OP: Invalid key for get operation", {
|
|
1562
|
+
key: keyStr,
|
|
1563
|
+
keyType: typeof key,
|
|
1564
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1565
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }",
|
|
1566
|
+
itemType: pkType,
|
|
1567
|
+
coordinate: JSON.stringify(context.coordinate)
|
|
1568
|
+
});
|
|
1569
|
+
throw new Error(`Invalid key for get operation: ${keyStr}. Expected valid PriKey or ComKey structure.`);
|
|
1480
1570
|
}
|
|
1481
1571
|
if (context.options?.bypassCache) {
|
|
1482
1572
|
logger7.debug("CACHE_OP: Cache bypass enabled, fetching directly from API", { key: keyStr });
|
|
@@ -1501,8 +1591,15 @@ async function executeGetLogic(key, context) {
|
|
|
1501
1591
|
}
|
|
1502
1592
|
} catch (error) {
|
|
1503
1593
|
logger7.error("CACHE_OP: API request failed in bypass mode", {
|
|
1594
|
+
operation: "get",
|
|
1595
|
+
mode: "bypass",
|
|
1504
1596
|
key: keyStr,
|
|
1597
|
+
itemType: pkType,
|
|
1505
1598
|
duration: Date.now() - startTime,
|
|
1599
|
+
errorType: error.constructor?.name || typeof error,
|
|
1600
|
+
errorMessage: error.message,
|
|
1601
|
+
errorCode: error.code || error.errorInfo?.code,
|
|
1602
|
+
suggestion: "Verify API endpoint is accessible and key exists. Cache bypass mode does not retry.",
|
|
1506
1603
|
error
|
|
1507
1604
|
});
|
|
1508
1605
|
throw error;
|
|
@@ -1671,10 +1768,19 @@ async function executeGetLogic(key, context) {
|
|
|
1671
1768
|
} catch (e) {
|
|
1672
1769
|
inFlightRequests2.delete(requestKeyStr);
|
|
1673
1770
|
const duration = Date.now() - startTime;
|
|
1674
|
-
logger7.error("CACHE_OP:
|
|
1771
|
+
logger7.error("CACHE_OP: get() operation failed", {
|
|
1772
|
+
operation: "get",
|
|
1675
1773
|
key: keyStr,
|
|
1774
|
+
itemType: pkType,
|
|
1676
1775
|
duration,
|
|
1677
|
-
|
|
1776
|
+
errorType: e.constructor?.name || typeof e,
|
|
1777
|
+
errorMessage: e.message,
|
|
1778
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1779
|
+
cacheType: cacheMap.implementationType,
|
|
1780
|
+
ttlEnabled: ttlManager.isTTLEnabled(),
|
|
1781
|
+
bypassMode: context.options?.bypassCache || false,
|
|
1782
|
+
inFlightRequestsCount: inFlightRequests2.size,
|
|
1783
|
+
suggestion: "Check API connectivity, key validity, and cache configuration",
|
|
1678
1784
|
stack: e.stack
|
|
1679
1785
|
});
|
|
1680
1786
|
throw e;
|
|
@@ -1798,13 +1904,27 @@ var remove = async (key, context) => {
|
|
|
1798
1904
|
};
|
|
1799
1905
|
async function executeRemoveLogic(key, context) {
|
|
1800
1906
|
const { api, cacheMap } = context;
|
|
1907
|
+
const keyStr = JSON.stringify(key);
|
|
1801
1908
|
if (!isValidItemKey3(key)) {
|
|
1802
|
-
logger9.error("
|
|
1803
|
-
|
|
1909
|
+
logger9.error("CACHE_OP: Invalid key for remove operation", {
|
|
1910
|
+
operation: "remove",
|
|
1911
|
+
key: keyStr,
|
|
1912
|
+
keyType: typeof key,
|
|
1913
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1914
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }"
|
|
1915
|
+
});
|
|
1916
|
+
throw new Error(`Invalid key for remove operation: ${keyStr}. Expected valid PriKey or ComKey structure.`);
|
|
1804
1917
|
}
|
|
1918
|
+
const startTime = Date.now();
|
|
1805
1919
|
try {
|
|
1920
|
+
logger9.debug("CACHE_OP: remove() started", {
|
|
1921
|
+
operation: "remove",
|
|
1922
|
+
key: keyStr,
|
|
1923
|
+
cacheType: cacheMap.implementationType
|
|
1924
|
+
});
|
|
1806
1925
|
const previousItem = await cacheMap.get(key);
|
|
1807
1926
|
await api.remove(key);
|
|
1927
|
+
const apiDuration = Date.now() - startTime;
|
|
1808
1928
|
cacheMap.delete(key);
|
|
1809
1929
|
await cacheMap.clearQueryResults();
|
|
1810
1930
|
if (previousItem) {
|
|
@@ -1817,9 +1937,27 @@ async function executeRemoveLogic(key, context) {
|
|
|
1817
1937
|
{ source: "operation", context: { operation: "remove" } }
|
|
1818
1938
|
);
|
|
1819
1939
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
1820
|
-
|
|
1940
|
+
const totalDuration = Date.now() - startTime;
|
|
1941
|
+
logger9.debug("CACHE_OP: remove() completed successfully", {
|
|
1942
|
+
operation: "remove",
|
|
1943
|
+
key: keyStr,
|
|
1944
|
+
hadCachedItem: !!previousItem,
|
|
1945
|
+
apiDuration,
|
|
1946
|
+
totalDuration
|
|
1947
|
+
});
|
|
1821
1948
|
} catch (e) {
|
|
1822
|
-
|
|
1949
|
+
const duration = Date.now() - startTime;
|
|
1950
|
+
logger9.error("CACHE_OP: remove() operation failed", {
|
|
1951
|
+
operation: "remove",
|
|
1952
|
+
key: keyStr,
|
|
1953
|
+
duration,
|
|
1954
|
+
errorType: e.constructor?.name || typeof e,
|
|
1955
|
+
errorMessage: e.message,
|
|
1956
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
1957
|
+
cacheType: cacheMap.implementationType,
|
|
1958
|
+
suggestion: "Check item exists, delete permissions, referential integrity constraints, and API connectivity",
|
|
1959
|
+
stack: e.stack
|
|
1960
|
+
});
|
|
1823
1961
|
throw e;
|
|
1824
1962
|
}
|
|
1825
1963
|
}
|
|
@@ -1845,33 +1983,52 @@ var update = async (key, v, context) => {
|
|
|
1845
1983
|
async function executeUpdateLogic(key, v, context) {
|
|
1846
1984
|
const { api, cacheMap, pkType } = context;
|
|
1847
1985
|
if (!isValidItemKey4(key)) {
|
|
1848
|
-
logger10.error("
|
|
1849
|
-
|
|
1986
|
+
logger10.error("CACHE_OP: Invalid key for update operation", {
|
|
1987
|
+
operation: "update",
|
|
1988
|
+
key: JSON.stringify(key),
|
|
1989
|
+
keyType: typeof key,
|
|
1990
|
+
itemType: pkType,
|
|
1991
|
+
reason: "Key validation failed - must be a valid PriKey or ComKey",
|
|
1992
|
+
suggestion: "Ensure the key has the correct structure: PriKey { kt, pk } or ComKey { kt, sk, lk }"
|
|
1993
|
+
});
|
|
1994
|
+
throw new Error(`Invalid key for update operation: ${JSON.stringify(key)}. Expected valid PriKey or ComKey structure.`);
|
|
1850
1995
|
}
|
|
1851
1996
|
logger10.debug("Invalidating item key before update", { key });
|
|
1852
1997
|
cacheMap.invalidateItemKeys([key]);
|
|
1853
1998
|
await cacheMap.clearQueryResults();
|
|
1999
|
+
const startTime = Date.now();
|
|
2000
|
+
const keyStr = JSON.stringify(key);
|
|
1854
2001
|
try {
|
|
2002
|
+
logger10.debug("CACHE_OP: update() started", {
|
|
2003
|
+
operation: "update",
|
|
2004
|
+
key: keyStr,
|
|
2005
|
+
itemType: pkType,
|
|
2006
|
+
updateData: JSON.stringify(v)
|
|
2007
|
+
});
|
|
1855
2008
|
const previousItem = await cacheMap.get(key);
|
|
1856
2009
|
const updated = await api.update(key, v);
|
|
1857
|
-
|
|
2010
|
+
const apiDuration = Date.now() - startTime;
|
|
2011
|
+
logger10.debug("CACHE_OP: Caching update result", {
|
|
2012
|
+
operation: "update",
|
|
2013
|
+
updatedKey: JSON.stringify(updated.key)
|
|
2014
|
+
});
|
|
1858
2015
|
await cacheMap.set(updated.key, updated);
|
|
1859
2016
|
const cachedItem = await cacheMap.get(updated.key);
|
|
1860
|
-
const
|
|
1861
|
-
const metadata = await cacheMap.getMetadata(
|
|
2017
|
+
const updatedKeyStr = JSON.stringify(updated.key);
|
|
2018
|
+
const metadata = await cacheMap.getMetadata(updatedKeyStr);
|
|
1862
2019
|
if (!metadata) {
|
|
1863
2020
|
const now = Date.now();
|
|
1864
2021
|
const baseMetadata = {
|
|
1865
|
-
key:
|
|
2022
|
+
key: updatedKeyStr,
|
|
1866
2023
|
addedAt: now,
|
|
1867
2024
|
lastAccessedAt: now,
|
|
1868
2025
|
accessCount: 1,
|
|
1869
2026
|
estimatedSize: estimateValueSize(updated)
|
|
1870
2027
|
};
|
|
1871
|
-
await cacheMap.setMetadata(
|
|
2028
|
+
await cacheMap.setMetadata(updatedKeyStr, baseMetadata);
|
|
1872
2029
|
}
|
|
1873
|
-
await context.ttlManager.onItemAdded(
|
|
1874
|
-
const evictedKeys = await context.evictionManager.onItemAdded(
|
|
2030
|
+
await context.ttlManager.onItemAdded(updatedKeyStr, cacheMap);
|
|
2031
|
+
const evictedKeys = await context.evictionManager.onItemAdded(updatedKeyStr, updated, cacheMap);
|
|
1875
2032
|
for (const evictedKey of evictedKeys) {
|
|
1876
2033
|
const parsedKey = JSON.parse(evictedKey);
|
|
1877
2034
|
await cacheMap.delete(parsedKey);
|
|
@@ -1885,9 +2042,31 @@ async function executeUpdateLogic(key, v, context) {
|
|
|
1885
2042
|
{ source: "operation", context: { operation: "update" } }
|
|
1886
2043
|
);
|
|
1887
2044
|
context.eventEmitter.emit(queryInvalidatedEvent);
|
|
2045
|
+
const totalDuration = Date.now() - startTime;
|
|
2046
|
+
logger10.debug("CACHE_OP: update() completed successfully", {
|
|
2047
|
+
operation: "update",
|
|
2048
|
+
key: updatedKeyStr,
|
|
2049
|
+
itemType: pkType,
|
|
2050
|
+
evictedCount: evictedKeys.length,
|
|
2051
|
+
apiDuration,
|
|
2052
|
+
totalDuration
|
|
2053
|
+
});
|
|
1888
2054
|
return updated;
|
|
1889
2055
|
} catch (e) {
|
|
1890
|
-
|
|
2056
|
+
const duration = Date.now() - startTime;
|
|
2057
|
+
logger10.error("CACHE_OP: update() operation failed", {
|
|
2058
|
+
operation: "update",
|
|
2059
|
+
key: keyStr,
|
|
2060
|
+
itemType: pkType,
|
|
2061
|
+
updateData: JSON.stringify(v),
|
|
2062
|
+
duration,
|
|
2063
|
+
errorType: e.constructor?.name || typeof e,
|
|
2064
|
+
errorMessage: e.message,
|
|
2065
|
+
errorCode: e.code || e.errorInfo?.code,
|
|
2066
|
+
cacheType: cacheMap.implementationType,
|
|
2067
|
+
suggestion: "Check item exists, validation rules, update permissions, and API connectivity",
|
|
2068
|
+
stack: e.stack
|
|
2069
|
+
});
|
|
1891
2070
|
throw e;
|
|
1892
2071
|
}
|
|
1893
2072
|
}
|
|
@@ -3524,7 +3703,17 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3524
3703
|
const useAggressiveCleanup = attempt > 0;
|
|
3525
3704
|
this.tryCleanupOldEntries(useAggressiveCleanup);
|
|
3526
3705
|
if (isLastAttempt) {
|
|
3527
|
-
|
|
3706
|
+
logger21.error("LocalStorage quota exceeded after all cleanup attempts", {
|
|
3707
|
+
component: "cache",
|
|
3708
|
+
subcomponent: "LocalStorageCacheMap",
|
|
3709
|
+
operation: "set",
|
|
3710
|
+
key: JSON.stringify(key),
|
|
3711
|
+
retryAttempts: attempt + 1,
|
|
3712
|
+
suggestion: "Reduce cache size limits, clear more data, or use IndexedDB for larger storage needs"
|
|
3713
|
+
});
|
|
3714
|
+
throw new Error(
|
|
3715
|
+
"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."
|
|
3716
|
+
);
|
|
3528
3717
|
}
|
|
3529
3718
|
continue;
|
|
3530
3719
|
}
|
|
@@ -3665,8 +3854,18 @@ var LocalStorageCacheMap = class _LocalStorageCacheMap extends CacheMap {
|
|
|
3665
3854
|
async setQueryResult(queryHash, itemKeys, metadata) {
|
|
3666
3855
|
logger21.trace("setQueryResult", { queryHash, itemKeys, hasMetadata: !!metadata });
|
|
3667
3856
|
if (!queryHash || typeof queryHash !== "string" || queryHash.trim() === "") {
|
|
3668
|
-
logger21.error("Invalid queryHash provided to setQueryResult", {
|
|
3669
|
-
|
|
3857
|
+
logger21.error("Invalid queryHash provided to setQueryResult", {
|
|
3858
|
+
component: "cache",
|
|
3859
|
+
subcomponent: "LocalStorageCacheMap",
|
|
3860
|
+
operation: "setQueryResult",
|
|
3861
|
+
queryHash,
|
|
3862
|
+
queryHashType: typeof queryHash,
|
|
3863
|
+
itemKeys,
|
|
3864
|
+
suggestion: "Ensure queryHash is a non-empty string generated from query normalization"
|
|
3865
|
+
});
|
|
3866
|
+
throw new Error(
|
|
3867
|
+
`Invalid queryHash provided to setQueryResult: ${JSON.stringify(queryHash)}. Expected non-empty string, got ${typeof queryHash}. This usually indicates a bug in query hash generation.`
|
|
3868
|
+
);
|
|
3670
3869
|
}
|
|
3671
3870
|
const queryKey = `${this.keyPrefix}:query:${queryHash}`;
|
|
3672
3871
|
const entry = {
|
|
@@ -4081,8 +4280,19 @@ var SessionStorageCacheMap = class _SessionStorageCacheMap extends CacheMap {
|
|
|
4081
4280
|
const jsonString = safeStringify2(toStore);
|
|
4082
4281
|
sessionStorage.setItem(storageKey, jsonString);
|
|
4083
4282
|
} catch (error) {
|
|
4084
|
-
|
|
4085
|
-
|
|
4283
|
+
const isQuotaError = error?.name === "QuotaExceededError" || error?.message?.includes("quota") || error?.code === 22;
|
|
4284
|
+
logger22.error("Error storing to sessionStorage", {
|
|
4285
|
+
component: "cache",
|
|
4286
|
+
subcomponent: "SessionStorageCacheMap",
|
|
4287
|
+
operation: "set",
|
|
4288
|
+
key: JSON.stringify(key),
|
|
4289
|
+
errorType: error?.name,
|
|
4290
|
+
errorMessage: error?.message,
|
|
4291
|
+
isQuotaError,
|
|
4292
|
+
suggestion: isQuotaError ? "SessionStorage quota exceeded. Clear old data, reduce cache size, or use IndexedDB instead." : "Check browser sessionStorage support and data serializability."
|
|
4293
|
+
});
|
|
4294
|
+
const errorMsg = isQuotaError ? "SessionStorage quota exceeded. Try clearing old cache data or reducing cache size." : `Failed to store item in sessionStorage: ${error?.message || error}`;
|
|
4295
|
+
throw new Error(errorMsg);
|
|
4086
4296
|
}
|
|
4087
4297
|
}
|
|
4088
4298
|
async includesKey(key) {
|
|
@@ -4667,8 +4877,18 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4667
4877
|
try {
|
|
4668
4878
|
storageKey = this.getStorageKey(key);
|
|
4669
4879
|
} catch (keyError) {
|
|
4670
|
-
logger23.
|
|
4671
|
-
|
|
4880
|
+
logger23.error("Storage key generation failed", {
|
|
4881
|
+
component: "cache",
|
|
4882
|
+
subcomponent: "AsyncIndexDBCacheMap",
|
|
4883
|
+
operation: "set",
|
|
4884
|
+
key: JSON.stringify(key),
|
|
4885
|
+
errorType: keyError?.constructor?.name,
|
|
4886
|
+
errorMessage: keyError?.message,
|
|
4887
|
+
suggestion: "Check key structure and normalization logic"
|
|
4888
|
+
});
|
|
4889
|
+
throw new Error(
|
|
4890
|
+
`Failed to generate storage key for IndexedDB: ${keyError?.message || keyError}. Key: ${JSON.stringify(key)}. This indicates a key normalization issue.`
|
|
4891
|
+
);
|
|
4672
4892
|
}
|
|
4673
4893
|
const storedItem = {
|
|
4674
4894
|
originalKey: key,
|
|
@@ -4692,8 +4912,19 @@ var AsyncIndexDBCacheMap = class _AsyncIndexDBCacheMap {
|
|
|
4692
4912
|
}
|
|
4693
4913
|
});
|
|
4694
4914
|
} catch (error) {
|
|
4695
|
-
|
|
4696
|
-
|
|
4915
|
+
const isQuotaError = error?.name === "QuotaExceededError" || error?.message?.includes("quota");
|
|
4916
|
+
logger23.error("Error in IndexedDB set operation", {
|
|
4917
|
+
component: "cache",
|
|
4918
|
+
subcomponent: "AsyncIndexDBCacheMap",
|
|
4919
|
+
operation: "set",
|
|
4920
|
+
key: JSON.stringify(key),
|
|
4921
|
+
errorType: error?.name,
|
|
4922
|
+
errorMessage: error?.message,
|
|
4923
|
+
isQuotaError,
|
|
4924
|
+
suggestion: isQuotaError ? "IndexedDB quota exceeded. Clear old data, reduce cache size, or request more storage quota." : "Check IndexedDB support, permissions, and data serializability."
|
|
4925
|
+
});
|
|
4926
|
+
const errorMsg = isQuotaError ? "IndexedDB quota exceeded. Try clearing old cache data or reducing cache size." : `Failed to store item in IndexedDB: ${error?.message || error}`;
|
|
4927
|
+
throw new Error(errorMsg);
|
|
4697
4928
|
}
|
|
4698
4929
|
}
|
|
4699
4930
|
/**
|
|
@@ -5573,6 +5804,7 @@ var IndexDBCacheMap = class _IndexDBCacheMap extends CacheMap {
|
|
|
5573
5804
|
};
|
|
5574
5805
|
|
|
5575
5806
|
// src/Options.ts
|
|
5807
|
+
var logger25 = logger_default.get("Options");
|
|
5576
5808
|
var DEFAULT_CACHE_OPTIONS = {
|
|
5577
5809
|
cacheType: "memory",
|
|
5578
5810
|
enableDebugLogging: false,
|
|
@@ -5676,12 +5908,29 @@ var createCacheMap = (kta, options) => {
|
|
|
5676
5908
|
break;
|
|
5677
5909
|
case "custom":
|
|
5678
5910
|
if (!options.customCacheMapFactory) {
|
|
5679
|
-
|
|
5911
|
+
logger25.error("Custom cache map factory missing", {
|
|
5912
|
+
component: "cache",
|
|
5913
|
+
operation: "createCacheMap",
|
|
5914
|
+
cacheType: "custom",
|
|
5915
|
+
suggestion: 'Provide customCacheMapFactory function in cache options when using cacheType: "custom"'
|
|
5916
|
+
});
|
|
5917
|
+
throw new Error(
|
|
5918
|
+
'Custom cache map factory is required when cacheType is "custom". Provide customCacheMapFactory in cache options.'
|
|
5919
|
+
);
|
|
5680
5920
|
}
|
|
5681
5921
|
underlyingCache = options.customCacheMapFactory(kta);
|
|
5682
5922
|
break;
|
|
5683
5923
|
default:
|
|
5684
|
-
|
|
5924
|
+
logger25.error("Unsupported cache type", {
|
|
5925
|
+
component: "cache",
|
|
5926
|
+
operation: "createCacheMap",
|
|
5927
|
+
cacheType: options.cacheType,
|
|
5928
|
+
validTypes: ["memory", "localStorage", "sessionStorage", "indexedDB", "asyncIndexedDB", "custom"],
|
|
5929
|
+
suggestion: "Use one of: memory, localStorage, sessionStorage, indexedDB, asyncIndexedDB, or custom"
|
|
5930
|
+
});
|
|
5931
|
+
throw new Error(
|
|
5932
|
+
`Unsupported cache type: ${options.cacheType}. Valid types: memory, localStorage, sessionStorage, indexedDB, asyncIndexedDB, custom.`
|
|
5933
|
+
);
|
|
5685
5934
|
}
|
|
5686
5935
|
if (options.twoLayer && Object.keys(options.twoLayer).length > 0) {
|
|
5687
5936
|
return new TwoLayerCacheMap(underlyingCache, options.twoLayer);
|
|
@@ -5762,19 +6011,29 @@ Did you mean: ${suggestions.join(", ")}?`;
|
|
|
5762
6011
|
throw new Error(errorMessage);
|
|
5763
6012
|
}
|
|
5764
6013
|
if (options.cacheType === "custom" && !options.customCacheMapFactory) {
|
|
5765
|
-
throw new Error(
|
|
6014
|
+
throw new Error(
|
|
6015
|
+
'customCacheMapFactory is required when cacheType is "custom". Provide a factory function that creates your custom CacheMap implementation.'
|
|
6016
|
+
);
|
|
5766
6017
|
}
|
|
5767
6018
|
if (typeof options.maxRetries === "number" && options.maxRetries < 0) {
|
|
5768
|
-
throw new Error(
|
|
6019
|
+
throw new Error(
|
|
6020
|
+
`maxRetries must be non-negative, got ${options.maxRetries}. Suggestion: Use 0 or positive integer for retry attempts.`
|
|
6021
|
+
);
|
|
5769
6022
|
}
|
|
5770
6023
|
if (typeof options.retryDelay === "number" && options.retryDelay < 0) {
|
|
5771
|
-
throw new Error(
|
|
6024
|
+
throw new Error(
|
|
6025
|
+
`retryDelay must be non-negative, got ${options.retryDelay}ms. Suggestion: Use 0 or positive number for delay in milliseconds.`
|
|
6026
|
+
);
|
|
5772
6027
|
}
|
|
5773
6028
|
if (typeof options.ttl === "number" && options.ttl <= 0) {
|
|
5774
|
-
throw new Error(
|
|
6029
|
+
throw new Error(
|
|
6030
|
+
`ttl must be positive, got ${options.ttl}. Suggestion: Use positive number for TTL in seconds, or 0 to disable TTL.`
|
|
6031
|
+
);
|
|
5775
6032
|
}
|
|
5776
6033
|
if (typeof options.memoryConfig?.maxItems === "number" && options.memoryConfig.maxItems <= 0) {
|
|
5777
|
-
throw new Error(
|
|
6034
|
+
throw new Error(
|
|
6035
|
+
`memoryConfig.maxItems must be positive, got ${options.memoryConfig.maxItems}. Suggestion: Use positive integer for maximum cache items.`
|
|
6036
|
+
);
|
|
5778
6037
|
}
|
|
5779
6038
|
if (options.memoryConfig?.size) {
|
|
5780
6039
|
validateSizeConfig(options.memoryConfig.size);
|
|
@@ -5874,16 +6133,43 @@ Did you mean: ${suggestions.join(", ")}?`);
|
|
|
5874
6133
|
if (["localStorage", "sessionStorage"].includes(options.cacheType)) {
|
|
5875
6134
|
const isRealBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement === "function";
|
|
5876
6135
|
if (!isRealBrowser) {
|
|
5877
|
-
|
|
6136
|
+
logger25.error("Browser cache type used in non-browser environment", {
|
|
6137
|
+
component: "cache",
|
|
6138
|
+
operation: "validateOptions",
|
|
6139
|
+
cacheType: options.cacheType,
|
|
6140
|
+
environment: typeof window === "undefined" ? "node" : "unknown",
|
|
6141
|
+
suggestion: 'Use cacheType: "memory" for Node.js/server environments, or ensure code runs in browser'
|
|
6142
|
+
});
|
|
6143
|
+
throw new Error(
|
|
6144
|
+
`${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.`
|
|
6145
|
+
);
|
|
5878
6146
|
}
|
|
5879
6147
|
}
|
|
5880
6148
|
if (options.cacheType === "indexedDB") {
|
|
5881
6149
|
if (typeof window === "undefined" || !window.indexedDB) {
|
|
5882
|
-
|
|
6150
|
+
logger25.error("IndexedDB not available", {
|
|
6151
|
+
component: "cache",
|
|
6152
|
+
operation: "validateOptions",
|
|
6153
|
+
cacheType: "indexedDB",
|
|
6154
|
+
hasWindow: typeof window !== "undefined",
|
|
6155
|
+
hasIndexedDB: typeof window !== "undefined" && !!window.indexedDB,
|
|
6156
|
+
suggestion: "Use memory cache for Node.js, or check browser IndexedDB support"
|
|
6157
|
+
});
|
|
6158
|
+
throw new Error(
|
|
6159
|
+
`IndexedDB is not available in this environment. Browser support required. Suggestion: Use cacheType: "memory" for server-side or unsupported browsers.`
|
|
6160
|
+
);
|
|
5883
6161
|
}
|
|
5884
6162
|
}
|
|
5885
6163
|
if (options.cacheType === "asyncIndexedDB") {
|
|
5886
|
-
|
|
6164
|
+
logger25.error("AsyncIndexedDB cannot be used with sync factory", {
|
|
6165
|
+
component: "cache",
|
|
6166
|
+
operation: "validateOptions",
|
|
6167
|
+
cacheType: "asyncIndexedDB",
|
|
6168
|
+
suggestion: 'Use AsyncIndexDBCacheMap directly for async operations, or use cacheType: "indexedDB" for sync wrapper'
|
|
6169
|
+
});
|
|
6170
|
+
throw new Error(
|
|
6171
|
+
'asyncIndexedDB cannot be used with synchronous cache factory. Use AsyncIndexDBCacheMap directly for async operations, or use cacheType: "indexedDB" for the sync wrapper.'
|
|
6172
|
+
);
|
|
5887
6173
|
}
|
|
5888
6174
|
};
|
|
5889
6175
|
|
|
@@ -5898,7 +6184,11 @@ var reset = async (coordinate, options) => {
|
|
|
5898
6184
|
}
|
|
5899
6185
|
};
|
|
5900
6186
|
|
|
6187
|
+
// src/ttl/TTLCalculator.ts
|
|
6188
|
+
var logger26 = logger_default.get("TTLCalculator");
|
|
6189
|
+
|
|
5901
6190
|
// src/ttl/TTLConfig.ts
|
|
6191
|
+
var logger27 = logger_default.get("TTLConfig");
|
|
5902
6192
|
var defaultTTLConfig = {
|
|
5903
6193
|
item: {
|
|
5904
6194
|
default: 3600,
|
|
@@ -5997,10 +6287,10 @@ var highTrafficTTLConfig = {
|
|
|
5997
6287
|
};
|
|
5998
6288
|
|
|
5999
6289
|
// src/cache/warming/CacheWarmer.ts
|
|
6000
|
-
var
|
|
6290
|
+
var logger28 = logger_default.get("CacheWarmer");
|
|
6001
6291
|
|
|
6002
6292
|
// src/Operations.ts
|
|
6003
|
-
var
|
|
6293
|
+
var logger29 = logger_default.get("Operations");
|
|
6004
6294
|
var CacheMapOperations = class {
|
|
6005
6295
|
constructor(api, coordinate, cacheMap, pkType, options, eventEmitter, ttlManager, evictionManager, statsManager, registry) {
|
|
6006
6296
|
this.api = api;
|
|
@@ -6014,7 +6304,7 @@ var CacheMapOperations = class {
|
|
|
6014
6304
|
this.statsManager = statsManager;
|
|
6015
6305
|
this.registry = registry;
|
|
6016
6306
|
if (this.options.enableDebugLogging) {
|
|
6017
|
-
|
|
6307
|
+
logger29.debug("CacheMapOperations initialized", {
|
|
6018
6308
|
cacheType: this.cacheMap.implementationType,
|
|
6019
6309
|
isTwoLayer: this.cacheMap instanceof TwoLayerCacheMap
|
|
6020
6310
|
});
|
|
@@ -6107,7 +6397,7 @@ var createOperations = (api, coordinate, cacheMap, pkType, options, eventEmitter
|
|
|
6107
6397
|
};
|
|
6108
6398
|
|
|
6109
6399
|
// src/eviction/EvictionManager.ts
|
|
6110
|
-
var
|
|
6400
|
+
var logger30 = logger_default.get("EvictionManager");
|
|
6111
6401
|
var EvictionManager = class {
|
|
6112
6402
|
evictionStrategy;
|
|
6113
6403
|
constructor(evictionStrategy) {
|
|
@@ -6119,7 +6409,7 @@ var EvictionManager = class {
|
|
|
6119
6409
|
*/
|
|
6120
6410
|
setEvictionStrategy(strategy) {
|
|
6121
6411
|
this.evictionStrategy = strategy;
|
|
6122
|
-
|
|
6412
|
+
logger30.debug("Eviction strategy updated", {
|
|
6123
6413
|
strategy: strategy?.getStrategyName() || "none"
|
|
6124
6414
|
});
|
|
6125
6415
|
}
|
|
@@ -6140,13 +6430,13 @@ var EvictionManager = class {
|
|
|
6140
6430
|
return;
|
|
6141
6431
|
}
|
|
6142
6432
|
try {
|
|
6143
|
-
|
|
6433
|
+
logger30.debug("EVICTION: Item accessed, updating metadata", {
|
|
6144
6434
|
key,
|
|
6145
6435
|
strategy: this.evictionStrategy.getStrategyName()
|
|
6146
6436
|
});
|
|
6147
6437
|
await this.evictionStrategy.onItemAccessed(key, metadataProvider);
|
|
6148
6438
|
} catch (error) {
|
|
6149
|
-
|
|
6439
|
+
logger30.error("EVICTION: Error in eviction strategy onItemAccessed", {
|
|
6150
6440
|
key,
|
|
6151
6441
|
error,
|
|
6152
6442
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -6164,12 +6454,12 @@ var EvictionManager = class {
|
|
|
6164
6454
|
const startTime = Date.now();
|
|
6165
6455
|
const evictedKeys = [];
|
|
6166
6456
|
if (!this.evictionStrategy) {
|
|
6167
|
-
|
|
6457
|
+
logger30.debug("EVICTION: No eviction strategy configured", { key });
|
|
6168
6458
|
return evictedKeys;
|
|
6169
6459
|
}
|
|
6170
6460
|
try {
|
|
6171
6461
|
const estimatedSize = estimateValueSize(value);
|
|
6172
|
-
|
|
6462
|
+
logger30.debug("EVICTION: Item addition started", {
|
|
6173
6463
|
key,
|
|
6174
6464
|
estimatedSize,
|
|
6175
6465
|
strategy: this.evictionStrategy.getStrategyName()
|
|
@@ -6177,7 +6467,7 @@ var EvictionManager = class {
|
|
|
6177
6467
|
const contextStartTime = Date.now();
|
|
6178
6468
|
const context = await this.createEvictionContext(metadataProvider, estimatedSize);
|
|
6179
6469
|
const contextDuration = Date.now() - contextStartTime;
|
|
6180
|
-
|
|
6470
|
+
logger30.debug("EVICTION: Current cache state", {
|
|
6181
6471
|
key,
|
|
6182
6472
|
currentItemCount: context.currentSize.itemCount,
|
|
6183
6473
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
@@ -6190,7 +6480,7 @@ var EvictionManager = class {
|
|
|
6190
6480
|
const keysToEvict = await this.evictionStrategy.selectForEviction(metadataProvider, context);
|
|
6191
6481
|
const selectionDuration = Date.now() - selectionStartTime;
|
|
6192
6482
|
if (keysToEvict.length > 0) {
|
|
6193
|
-
|
|
6483
|
+
logger30.debug("EVICTION: Items selected for eviction", {
|
|
6194
6484
|
key,
|
|
6195
6485
|
evictCount: keysToEvict.length,
|
|
6196
6486
|
keysToEvict,
|
|
@@ -6202,7 +6492,7 @@ var EvictionManager = class {
|
|
|
6202
6492
|
for (const evictKey of keysToEvict) {
|
|
6203
6493
|
await this.evictionStrategy.onItemRemoved(evictKey, metadataProvider);
|
|
6204
6494
|
evictedKeys.push(evictKey);
|
|
6205
|
-
|
|
6495
|
+
logger30.debug("EVICTION: Marked item for eviction", {
|
|
6206
6496
|
evictedKey: evictKey,
|
|
6207
6497
|
newKey: key
|
|
6208
6498
|
});
|
|
@@ -6213,7 +6503,7 @@ var EvictionManager = class {
|
|
|
6213
6503
|
const addMetadataDuration = Date.now() - addMetadataStart;
|
|
6214
6504
|
const totalDuration = Date.now() - startTime;
|
|
6215
6505
|
if (evictedKeys.length > 0) {
|
|
6216
|
-
|
|
6506
|
+
logger30.debug("EVICTION: Eviction completed", {
|
|
6217
6507
|
newKey: key,
|
|
6218
6508
|
evictedCount: evictedKeys.length,
|
|
6219
6509
|
evictedKeys,
|
|
@@ -6224,14 +6514,14 @@ var EvictionManager = class {
|
|
|
6224
6514
|
totalDuration
|
|
6225
6515
|
});
|
|
6226
6516
|
} else {
|
|
6227
|
-
|
|
6517
|
+
logger30.debug("EVICTION: No eviction needed", {
|
|
6228
6518
|
newKey: key,
|
|
6229
6519
|
estimatedSize,
|
|
6230
6520
|
totalDuration
|
|
6231
6521
|
});
|
|
6232
6522
|
}
|
|
6233
6523
|
} catch (error) {
|
|
6234
|
-
|
|
6524
|
+
logger30.error("EVICTION: Error in eviction strategy onItemAdded", {
|
|
6235
6525
|
key,
|
|
6236
6526
|
error,
|
|
6237
6527
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
@@ -6251,7 +6541,7 @@ var EvictionManager = class {
|
|
|
6251
6541
|
try {
|
|
6252
6542
|
this.evictionStrategy.onItemRemoved(key, metadataProvider);
|
|
6253
6543
|
} catch (error) {
|
|
6254
|
-
|
|
6544
|
+
logger30.error("Error in eviction strategy onItemRemoved", { key, error });
|
|
6255
6545
|
}
|
|
6256
6546
|
}
|
|
6257
6547
|
/**
|
|
@@ -6263,15 +6553,15 @@ var EvictionManager = class {
|
|
|
6263
6553
|
const startTime = Date.now();
|
|
6264
6554
|
const evictedKeys = [];
|
|
6265
6555
|
if (!this.evictionStrategy) {
|
|
6266
|
-
|
|
6556
|
+
logger30.debug("EVICTION: No eviction strategy configured for manual eviction");
|
|
6267
6557
|
return evictedKeys;
|
|
6268
6558
|
}
|
|
6269
6559
|
try {
|
|
6270
|
-
|
|
6560
|
+
logger30.debug("EVICTION: Manual eviction started", {
|
|
6271
6561
|
strategy: this.evictionStrategy.getStrategyName()
|
|
6272
6562
|
});
|
|
6273
6563
|
const context = await this.createEvictionContext(metadataProvider);
|
|
6274
|
-
|
|
6564
|
+
logger30.debug("EVICTION: Manual eviction - current cache state", {
|
|
6275
6565
|
currentItemCount: context.currentSize.itemCount,
|
|
6276
6566
|
currentSizeBytes: context.currentSize.sizeBytes,
|
|
6277
6567
|
maxItems: context.limits.maxItems,
|
|
@@ -6284,20 +6574,20 @@ var EvictionManager = class {
|
|
|
6284
6574
|
}
|
|
6285
6575
|
const duration = Date.now() - startTime;
|
|
6286
6576
|
if (evictedKeys.length > 0) {
|
|
6287
|
-
|
|
6577
|
+
logger30.debug("EVICTION: Manual eviction completed", {
|
|
6288
6578
|
evictedCount: evictedKeys.length,
|
|
6289
6579
|
evictedKeys,
|
|
6290
6580
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
6291
6581
|
duration
|
|
6292
6582
|
});
|
|
6293
6583
|
} else {
|
|
6294
|
-
|
|
6584
|
+
logger30.debug("EVICTION: Manual eviction - no items to evict", {
|
|
6295
6585
|
strategy: this.evictionStrategy.getStrategyName(),
|
|
6296
6586
|
duration
|
|
6297
6587
|
});
|
|
6298
6588
|
}
|
|
6299
6589
|
} catch (error) {
|
|
6300
|
-
|
|
6590
|
+
logger30.error("EVICTION: Error in manual eviction", {
|
|
6301
6591
|
error,
|
|
6302
6592
|
strategy: this.evictionStrategy?.getStrategyName()
|
|
6303
6593
|
});
|
|
@@ -6320,7 +6610,7 @@ var EvictionManager = class {
|
|
|
6320
6610
|
this.evictionStrategy.reset();
|
|
6321
6611
|
}
|
|
6322
6612
|
}
|
|
6323
|
-
|
|
6613
|
+
logger30.debug("Eviction manager cleared");
|
|
6324
6614
|
}
|
|
6325
6615
|
/**
|
|
6326
6616
|
* Create eviction context from current cache state
|
|
@@ -6458,61 +6748,149 @@ var LRUEvictionStrategy = class extends EvictionStrategy {
|
|
|
6458
6748
|
// src/eviction/EvictionStrategyValidation.ts
|
|
6459
6749
|
function validateNumberRange(value, min, max, fieldName) {
|
|
6460
6750
|
if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
|
|
6461
|
-
throw new Error(
|
|
6751
|
+
throw new Error(
|
|
6752
|
+
`${fieldName} must be a finite number, got ${typeof value} (${value}). Suggestion: Provide a valid numeric value for ${fieldName}.`
|
|
6753
|
+
);
|
|
6462
6754
|
}
|
|
6463
6755
|
if (value < min || value > max) {
|
|
6464
|
-
throw new Error(
|
|
6756
|
+
throw new Error(
|
|
6757
|
+
`${fieldName} must be between ${min} and ${max}, got ${value}. Suggestion: Adjust ${fieldName} to be within the valid range.`
|
|
6758
|
+
);
|
|
6465
6759
|
}
|
|
6466
6760
|
}
|
|
6467
6761
|
function validatePositiveInteger(value, fieldName) {
|
|
6468
6762
|
if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
|
|
6469
|
-
throw new Error(
|
|
6763
|
+
throw new Error(
|
|
6764
|
+
`${fieldName} must be a finite number, got ${typeof value} (${value}). Suggestion: Provide a valid numeric value for ${fieldName}.`
|
|
6765
|
+
);
|
|
6470
6766
|
}
|
|
6471
6767
|
if (!Number.isInteger(value) || value <= 0) {
|
|
6472
|
-
throw new Error(
|
|
6768
|
+
throw new Error(
|
|
6769
|
+
`${fieldName} must be a positive integer, got ${value}. Suggestion: Use a positive whole number (1, 2, 3, ...) for ${fieldName}.`
|
|
6770
|
+
);
|
|
6473
6771
|
}
|
|
6474
6772
|
}
|
|
6475
6773
|
function sanitizeLFUConfig(config) {
|
|
6476
6774
|
const sanitized = { ...config };
|
|
6477
6775
|
if (typeof sanitized.decayFactor === "number") {
|
|
6478
6776
|
if (sanitized.decayFactor < 0) {
|
|
6479
|
-
|
|
6777
|
+
const warning = {
|
|
6778
|
+
component: "cache",
|
|
6779
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6780
|
+
operation: "sanitizeLFUConfig",
|
|
6781
|
+
field: "decayFactor",
|
|
6782
|
+
invalidValue: sanitized.decayFactor,
|
|
6783
|
+
correctedValue: 0,
|
|
6784
|
+
validRange: "0-1",
|
|
6785
|
+
note: "Auto-correcting invalid configuration value"
|
|
6786
|
+
};
|
|
6787
|
+
console.warn("Invalid decayFactor corrected:", JSON.stringify(warning, null, 2));
|
|
6480
6788
|
sanitized.decayFactor = 0;
|
|
6481
6789
|
} else if (sanitized.decayFactor > 1) {
|
|
6482
|
-
|
|
6790
|
+
const warning = {
|
|
6791
|
+
component: "cache",
|
|
6792
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6793
|
+
operation: "sanitizeLFUConfig",
|
|
6794
|
+
field: "decayFactor",
|
|
6795
|
+
invalidValue: sanitized.decayFactor,
|
|
6796
|
+
correctedValue: 1,
|
|
6797
|
+
validRange: "0-1",
|
|
6798
|
+
note: "Auto-correcting invalid configuration value"
|
|
6799
|
+
};
|
|
6800
|
+
console.warn("Invalid decayFactor corrected:", JSON.stringify(warning, null, 2));
|
|
6483
6801
|
sanitized.decayFactor = 1;
|
|
6484
6802
|
}
|
|
6485
6803
|
}
|
|
6486
6804
|
if (typeof sanitized.decayInterval === "number" && sanitized.decayInterval <= 0) {
|
|
6487
|
-
|
|
6805
|
+
const warning = {
|
|
6806
|
+
component: "cache",
|
|
6807
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6808
|
+
operation: "sanitizeLFUConfig",
|
|
6809
|
+
field: "decayInterval",
|
|
6810
|
+
invalidValue: sanitized.decayInterval,
|
|
6811
|
+
correctedValue: 3e5,
|
|
6812
|
+
minimumValue: 1,
|
|
6813
|
+
note: "Auto-correcting to 5 minutes (300000ms) default"
|
|
6814
|
+
};
|
|
6815
|
+
console.warn("Invalid decayInterval corrected:", JSON.stringify(warning, null, 2));
|
|
6488
6816
|
sanitized.decayInterval = 3e5;
|
|
6489
6817
|
}
|
|
6490
6818
|
if (typeof sanitized.sketchWidth === "number") {
|
|
6491
6819
|
if (sanitized.sketchWidth <= 0) {
|
|
6492
|
-
console.warn(
|
|
6820
|
+
console.warn("Invalid sketchWidth corrected:", JSON.stringify({
|
|
6821
|
+
component: "cache",
|
|
6822
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6823
|
+
field: "sketchWidth",
|
|
6824
|
+
invalidValue: sanitized.sketchWidth,
|
|
6825
|
+
correctedValue: 1024,
|
|
6826
|
+
note: "Auto-correcting invalid configuration"
|
|
6827
|
+
}, null, 2));
|
|
6493
6828
|
sanitized.sketchWidth = 1024;
|
|
6494
6829
|
} else if (sanitized.sketchWidth < 16) {
|
|
6495
|
-
console.warn(
|
|
6830
|
+
console.warn("Suboptimal sketchWidth corrected:", JSON.stringify({
|
|
6831
|
+
component: "cache",
|
|
6832
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6833
|
+
field: "sketchWidth",
|
|
6834
|
+
invalidValue: sanitized.sketchWidth,
|
|
6835
|
+
correctedValue: 16,
|
|
6836
|
+
minimumRecommended: 16,
|
|
6837
|
+
note: "Correcting for optimal performance"
|
|
6838
|
+
}, null, 2));
|
|
6496
6839
|
sanitized.sketchWidth = 16;
|
|
6497
6840
|
} else if (sanitized.sketchWidth > 65536) {
|
|
6498
|
-
console.warn(
|
|
6841
|
+
console.warn("Excessive sketchWidth corrected:", JSON.stringify({
|
|
6842
|
+
component: "cache",
|
|
6843
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6844
|
+
field: "sketchWidth",
|
|
6845
|
+
invalidValue: sanitized.sketchWidth,
|
|
6846
|
+
correctedValue: 65536,
|
|
6847
|
+
maximumRecommended: 65536,
|
|
6848
|
+
note: "Correcting for optimal performance"
|
|
6849
|
+
}, null, 2));
|
|
6499
6850
|
sanitized.sketchWidth = 65536;
|
|
6500
6851
|
}
|
|
6501
6852
|
}
|
|
6502
6853
|
if (typeof sanitized.sketchDepth === "number") {
|
|
6503
6854
|
if (sanitized.sketchDepth <= 0) {
|
|
6504
|
-
console.warn(
|
|
6855
|
+
console.warn("Invalid sketchDepth corrected:", JSON.stringify({
|
|
6856
|
+
component: "cache",
|
|
6857
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6858
|
+
field: "sketchDepth",
|
|
6859
|
+
invalidValue: sanitized.sketchDepth,
|
|
6860
|
+
correctedValue: 4
|
|
6861
|
+
}, null, 2));
|
|
6505
6862
|
sanitized.sketchDepth = 4;
|
|
6506
6863
|
} else if (sanitized.sketchDepth < 1) {
|
|
6507
|
-
console.warn(
|
|
6864
|
+
console.warn("Suboptimal sketchDepth corrected:", JSON.stringify({
|
|
6865
|
+
component: "cache",
|
|
6866
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6867
|
+
field: "sketchDepth",
|
|
6868
|
+
invalidValue: sanitized.sketchDepth,
|
|
6869
|
+
correctedValue: 1,
|
|
6870
|
+
minimumRecommended: 1
|
|
6871
|
+
}, null, 2));
|
|
6508
6872
|
sanitized.sketchDepth = 1;
|
|
6509
6873
|
} else if (sanitized.sketchDepth > 16) {
|
|
6510
|
-
console.warn(
|
|
6874
|
+
console.warn("Excessive sketchDepth corrected:", JSON.stringify({
|
|
6875
|
+
component: "cache",
|
|
6876
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6877
|
+
field: "sketchDepth",
|
|
6878
|
+
invalidValue: sanitized.sketchDepth,
|
|
6879
|
+
correctedValue: 16,
|
|
6880
|
+
maximumRecommended: 16
|
|
6881
|
+
}, null, 2));
|
|
6511
6882
|
sanitized.sketchDepth = 16;
|
|
6512
6883
|
}
|
|
6513
6884
|
}
|
|
6514
6885
|
if (typeof sanitized.minFrequencyThreshold === "number" && sanitized.minFrequencyThreshold <= 0) {
|
|
6515
|
-
console.warn(
|
|
6886
|
+
console.warn("Invalid minFrequencyThreshold corrected:", JSON.stringify({
|
|
6887
|
+
component: "cache",
|
|
6888
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6889
|
+
field: "minFrequencyThreshold",
|
|
6890
|
+
invalidValue: sanitized.minFrequencyThreshold,
|
|
6891
|
+
correctedValue: 1,
|
|
6892
|
+
minimumValue: 1
|
|
6893
|
+
}, null, 2));
|
|
6516
6894
|
sanitized.minFrequencyThreshold = 1;
|
|
6517
6895
|
}
|
|
6518
6896
|
return sanitized;
|
|
@@ -6543,32 +6921,86 @@ function validateLFUConfig(config) {
|
|
|
6543
6921
|
function sanitizeARCConfig(config) {
|
|
6544
6922
|
const sanitized = { ...config };
|
|
6545
6923
|
if (typeof sanitized.maxCacheSize === "number" && sanitized.maxCacheSize <= 0) {
|
|
6546
|
-
console.warn(
|
|
6924
|
+
console.warn("Invalid maxCacheSize corrected:", JSON.stringify({
|
|
6925
|
+
component: "cache",
|
|
6926
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6927
|
+
operation: "sanitizeARCConfig",
|
|
6928
|
+
field: "maxCacheSize",
|
|
6929
|
+
invalidValue: sanitized.maxCacheSize,
|
|
6930
|
+
correctedValue: 1e3
|
|
6931
|
+
}, null, 2));
|
|
6547
6932
|
sanitized.maxCacheSize = 1e3;
|
|
6548
6933
|
}
|
|
6549
6934
|
if (typeof sanitized.frequencyThreshold === "number" && sanitized.frequencyThreshold <= 0) {
|
|
6550
|
-
console.warn(
|
|
6935
|
+
console.warn("Invalid frequencyThreshold corrected:", JSON.stringify({
|
|
6936
|
+
component: "cache",
|
|
6937
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6938
|
+
operation: "sanitizeARCConfig",
|
|
6939
|
+
field: "frequencyThreshold",
|
|
6940
|
+
invalidValue: sanitized.frequencyThreshold,
|
|
6941
|
+
correctedValue: 2
|
|
6942
|
+
}, null, 2));
|
|
6551
6943
|
sanitized.frequencyThreshold = 2;
|
|
6552
6944
|
}
|
|
6553
6945
|
if (typeof sanitized.frequencyDecayFactor === "number") {
|
|
6554
6946
|
if (sanitized.frequencyDecayFactor < 0) {
|
|
6555
|
-
console.warn(
|
|
6947
|
+
console.warn("Invalid frequencyDecayFactor corrected:", JSON.stringify({
|
|
6948
|
+
component: "cache",
|
|
6949
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6950
|
+
operation: "sanitizeARCConfig",
|
|
6951
|
+
field: "frequencyDecayFactor",
|
|
6952
|
+
invalidValue: sanitized.frequencyDecayFactor,
|
|
6953
|
+
correctedValue: 0,
|
|
6954
|
+
validRange: "0-1"
|
|
6955
|
+
}, null, 2));
|
|
6556
6956
|
sanitized.frequencyDecayFactor = 0;
|
|
6557
6957
|
} else if (sanitized.frequencyDecayFactor > 1) {
|
|
6558
|
-
console.warn(
|
|
6958
|
+
console.warn("Invalid frequencyDecayFactor corrected:", JSON.stringify({
|
|
6959
|
+
component: "cache",
|
|
6960
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6961
|
+
operation: "sanitizeARCConfig",
|
|
6962
|
+
field: "frequencyDecayFactor",
|
|
6963
|
+
invalidValue: sanitized.frequencyDecayFactor,
|
|
6964
|
+
correctedValue: 1,
|
|
6965
|
+
validRange: "0-1"
|
|
6966
|
+
}, null, 2));
|
|
6559
6967
|
sanitized.frequencyDecayFactor = 1;
|
|
6560
6968
|
}
|
|
6561
6969
|
}
|
|
6562
6970
|
if (typeof sanitized.frequencyDecayInterval === "number" && sanitized.frequencyDecayInterval <= 0) {
|
|
6563
|
-
console.warn(
|
|
6971
|
+
console.warn("Invalid frequencyDecayInterval corrected:", JSON.stringify({
|
|
6972
|
+
component: "cache",
|
|
6973
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6974
|
+
operation: "sanitizeARCConfig",
|
|
6975
|
+
field: "frequencyDecayInterval",
|
|
6976
|
+
invalidValue: sanitized.frequencyDecayInterval,
|
|
6977
|
+
correctedValue: 6e4,
|
|
6978
|
+
note: "Corrected to 1 minute default"
|
|
6979
|
+
}, null, 2));
|
|
6564
6980
|
sanitized.frequencyDecayInterval = 6e4;
|
|
6565
6981
|
}
|
|
6566
6982
|
if (typeof sanitized.adaptiveLearningRate === "number") {
|
|
6567
6983
|
if (sanitized.adaptiveLearningRate < 0) {
|
|
6568
|
-
console.warn(
|
|
6984
|
+
console.warn("Invalid adaptiveLearningRate corrected:", JSON.stringify({
|
|
6985
|
+
component: "cache",
|
|
6986
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6987
|
+
operation: "sanitizeARCConfig",
|
|
6988
|
+
field: "adaptiveLearningRate",
|
|
6989
|
+
invalidValue: sanitized.adaptiveLearningRate,
|
|
6990
|
+
correctedValue: 0,
|
|
6991
|
+
validRange: "0-10"
|
|
6992
|
+
}, null, 2));
|
|
6569
6993
|
sanitized.adaptiveLearningRate = 0;
|
|
6570
6994
|
} else if (sanitized.adaptiveLearningRate > 10) {
|
|
6571
|
-
console.warn(
|
|
6995
|
+
console.warn("Invalid adaptiveLearningRate corrected:", JSON.stringify({
|
|
6996
|
+
component: "cache",
|
|
6997
|
+
subcomponent: "EvictionStrategyValidation",
|
|
6998
|
+
operation: "sanitizeARCConfig",
|
|
6999
|
+
field: "adaptiveLearningRate",
|
|
7000
|
+
invalidValue: sanitized.adaptiveLearningRate,
|
|
7001
|
+
correctedValue: 10,
|
|
7002
|
+
validRange: "0-10"
|
|
7003
|
+
}, null, 2));
|
|
6572
7004
|
sanitized.adaptiveLearningRate = 10;
|
|
6573
7005
|
}
|
|
6574
7006
|
}
|
|
@@ -6594,24 +7026,62 @@ function validateARCConfig(config) {
|
|
|
6594
7026
|
function sanitizeTwoQueueConfig(config) {
|
|
6595
7027
|
const sanitized = { ...config };
|
|
6596
7028
|
if (typeof sanitized.maxCacheSize === "number" && sanitized.maxCacheSize <= 0) {
|
|
6597
|
-
console.warn(
|
|
7029
|
+
console.warn("Invalid maxCacheSize corrected:", JSON.stringify({
|
|
7030
|
+
component: "cache",
|
|
7031
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7032
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7033
|
+
field: "maxCacheSize",
|
|
7034
|
+
invalidValue: sanitized.maxCacheSize,
|
|
7035
|
+
correctedValue: 1e3
|
|
7036
|
+
}, null, 2));
|
|
6598
7037
|
sanitized.maxCacheSize = 1e3;
|
|
6599
7038
|
}
|
|
6600
7039
|
if (typeof sanitized.promotionThreshold === "number" && sanitized.promotionThreshold <= 0) {
|
|
6601
|
-
console.warn(
|
|
7040
|
+
console.warn("Invalid promotionThreshold corrected:", JSON.stringify({
|
|
7041
|
+
component: "cache",
|
|
7042
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7043
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7044
|
+
field: "promotionThreshold",
|
|
7045
|
+
invalidValue: sanitized.promotionThreshold,
|
|
7046
|
+
correctedValue: 2
|
|
7047
|
+
}, null, 2));
|
|
6602
7048
|
sanitized.promotionThreshold = 2;
|
|
6603
7049
|
}
|
|
6604
7050
|
if (typeof sanitized.hotQueueDecayFactor === "number") {
|
|
6605
7051
|
if (sanitized.hotQueueDecayFactor < 0) {
|
|
6606
|
-
console.warn(
|
|
7052
|
+
console.warn("Invalid hotQueueDecayFactor corrected:", JSON.stringify({
|
|
7053
|
+
component: "cache",
|
|
7054
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7055
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7056
|
+
field: "hotQueueDecayFactor",
|
|
7057
|
+
invalidValue: sanitized.hotQueueDecayFactor,
|
|
7058
|
+
correctedValue: 0,
|
|
7059
|
+
validRange: "0-1"
|
|
7060
|
+
}, null, 2));
|
|
6607
7061
|
sanitized.hotQueueDecayFactor = 0;
|
|
6608
7062
|
} else if (sanitized.hotQueueDecayFactor > 1) {
|
|
6609
|
-
console.warn(
|
|
7063
|
+
console.warn("Invalid hotQueueDecayFactor corrected:", JSON.stringify({
|
|
7064
|
+
component: "cache",
|
|
7065
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7066
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7067
|
+
field: "hotQueueDecayFactor",
|
|
7068
|
+
invalidValue: sanitized.hotQueueDecayFactor,
|
|
7069
|
+
correctedValue: 1,
|
|
7070
|
+
validRange: "0-1"
|
|
7071
|
+
}, null, 2));
|
|
6610
7072
|
sanitized.hotQueueDecayFactor = 1;
|
|
6611
7073
|
}
|
|
6612
7074
|
}
|
|
6613
7075
|
if (typeof sanitized.hotQueueDecayInterval === "number" && sanitized.hotQueueDecayInterval <= 0) {
|
|
6614
|
-
console.warn(
|
|
7076
|
+
console.warn("Invalid hotQueueDecayInterval corrected:", JSON.stringify({
|
|
7077
|
+
component: "cache",
|
|
7078
|
+
subcomponent: "EvictionStrategyValidation",
|
|
7079
|
+
operation: "sanitizeTwoQueueConfig",
|
|
7080
|
+
field: "hotQueueDecayInterval",
|
|
7081
|
+
invalidValue: sanitized.hotQueueDecayInterval,
|
|
7082
|
+
correctedValue: 3e5,
|
|
7083
|
+
note: "Corrected to 5 minutes default"
|
|
7084
|
+
}, null, 2));
|
|
6615
7085
|
sanitized.hotQueueDecayInterval = 3e5;
|
|
6616
7086
|
}
|
|
6617
7087
|
return sanitized;
|
|
@@ -7658,7 +8128,7 @@ function createEvictionStrategy(policy, maxCacheSize, config) {
|
|
|
7658
8128
|
}
|
|
7659
8129
|
|
|
7660
8130
|
// src/ttl/TTLManager.ts
|
|
7661
|
-
var
|
|
8131
|
+
var logger31 = logger_default.get("TTLManager");
|
|
7662
8132
|
var TTLManager = class {
|
|
7663
8133
|
config;
|
|
7664
8134
|
cleanupTimer;
|
|
@@ -7670,7 +8140,7 @@ var TTLManager = class {
|
|
|
7670
8140
|
validateOnAccess: true,
|
|
7671
8141
|
...config
|
|
7672
8142
|
};
|
|
7673
|
-
|
|
8143
|
+
logger31.debug("TTL_DEBUG: TTLManager created", {
|
|
7674
8144
|
config: this.config,
|
|
7675
8145
|
isTTLEnabled: this.isTTLEnabled(),
|
|
7676
8146
|
defaultTTL: this.config.defaultTTL
|
|
@@ -7703,13 +8173,13 @@ var TTLManager = class {
|
|
|
7703
8173
|
this.startAutoCleanup();
|
|
7704
8174
|
}
|
|
7705
8175
|
}
|
|
7706
|
-
|
|
8176
|
+
logger31.debug("TTL configuration updated", { config: this.config });
|
|
7707
8177
|
}
|
|
7708
8178
|
/**
|
|
7709
8179
|
* Set TTL metadata for an item when it's added
|
|
7710
8180
|
*/
|
|
7711
8181
|
async onItemAdded(key, metadataProvider, itemTTL) {
|
|
7712
|
-
|
|
8182
|
+
logger31.debug("TTL_DEBUG: onItemAdded called", {
|
|
7713
8183
|
key,
|
|
7714
8184
|
itemTTL,
|
|
7715
8185
|
isTTLEnabled: this.isTTLEnabled(),
|
|
@@ -7717,19 +8187,19 @@ var TTLManager = class {
|
|
|
7717
8187
|
metadataProviderType: metadataProvider?.constructor?.name
|
|
7718
8188
|
});
|
|
7719
8189
|
if (!this.isTTLEnabled() && !itemTTL) {
|
|
7720
|
-
|
|
8190
|
+
logger31.debug("TTL_DEBUG: No TTL configured for item - returning early", { key });
|
|
7721
8191
|
return;
|
|
7722
8192
|
}
|
|
7723
|
-
|
|
8193
|
+
logger31.debug("TTL_DEBUG: Getting metadata for key", { key });
|
|
7724
8194
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7725
|
-
|
|
8195
|
+
logger31.debug("TTL_DEBUG: Retrieved metadata", {
|
|
7726
8196
|
key,
|
|
7727
8197
|
hasMetadata: !!metadata,
|
|
7728
8198
|
metadataKeys: metadata ? Object.keys(metadata) : null,
|
|
7729
8199
|
metadata
|
|
7730
8200
|
});
|
|
7731
8201
|
if (!metadata) {
|
|
7732
|
-
|
|
8202
|
+
logger31.debug("TTL_DEBUG: No metadata found for item when setting TTL", {
|
|
7733
8203
|
key,
|
|
7734
8204
|
metadataProviderType: metadataProvider?.constructor?.name,
|
|
7735
8205
|
metadataProviderMethods: metadataProvider ? Object.getOwnPropertyNames(Object.getPrototypeOf(metadataProvider)) : null
|
|
@@ -7737,7 +8207,7 @@ var TTLManager = class {
|
|
|
7737
8207
|
return;
|
|
7738
8208
|
}
|
|
7739
8209
|
const ttl = itemTTL || this.config.defaultTTL;
|
|
7740
|
-
|
|
8210
|
+
logger31.debug("TTL_DEBUG: Calculated TTL value", {
|
|
7741
8211
|
key,
|
|
7742
8212
|
itemTTL,
|
|
7743
8213
|
defaultTTL: this.config.defaultTTL,
|
|
@@ -7750,7 +8220,7 @@ var TTLManager = class {
|
|
|
7750
8220
|
expiresAt: metadata.addedAt + ttl,
|
|
7751
8221
|
ttl
|
|
7752
8222
|
};
|
|
7753
|
-
|
|
8223
|
+
logger31.debug("TTL_DEBUG: Setting TTL metadata", {
|
|
7754
8224
|
key,
|
|
7755
8225
|
ttl,
|
|
7756
8226
|
addedAt: metadata.addedAt,
|
|
@@ -7758,9 +8228,9 @@ var TTLManager = class {
|
|
|
7758
8228
|
ttlMetadata
|
|
7759
8229
|
});
|
|
7760
8230
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7761
|
-
|
|
8231
|
+
logger31.trace("TTL_DEBUG: TTL set for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7762
8232
|
} else {
|
|
7763
|
-
|
|
8233
|
+
logger31.debug("TTL_DEBUG: No TTL set - invalid TTL value", { key, ttl });
|
|
7764
8234
|
}
|
|
7765
8235
|
}
|
|
7766
8236
|
/**
|
|
@@ -7769,14 +8239,14 @@ var TTLManager = class {
|
|
|
7769
8239
|
async isExpired(key, metadataProvider) {
|
|
7770
8240
|
const metadata = await metadataProvider.getMetadata(key);
|
|
7771
8241
|
if (!metadata || !metadata.expiresAt) {
|
|
7772
|
-
|
|
8242
|
+
logger31.debug("TTL_CHECK: No TTL set for item", { key, hasMetadata: !!metadata });
|
|
7773
8243
|
return false;
|
|
7774
8244
|
}
|
|
7775
8245
|
const now = Date.now();
|
|
7776
8246
|
const expired = now >= metadata.expiresAt;
|
|
7777
8247
|
const remainingMs = metadata.expiresAt - now;
|
|
7778
8248
|
if (expired) {
|
|
7779
|
-
|
|
8249
|
+
logger31.debug("TTL_CHECK: Item EXPIRED", {
|
|
7780
8250
|
key,
|
|
7781
8251
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7782
8252
|
now: new Date(now).toISOString(),
|
|
@@ -7784,7 +8254,7 @@ var TTLManager = class {
|
|
|
7784
8254
|
ttl: metadata.ttl
|
|
7785
8255
|
});
|
|
7786
8256
|
} else {
|
|
7787
|
-
|
|
8257
|
+
logger31.debug("TTL_CHECK: Item still valid", {
|
|
7788
8258
|
key,
|
|
7789
8259
|
expiresAt: new Date(metadata.expiresAt).toISOString(),
|
|
7790
8260
|
remainingMs,
|
|
@@ -7800,17 +8270,17 @@ var TTLManager = class {
|
|
|
7800
8270
|
*/
|
|
7801
8271
|
async validateItem(key, metadataProvider) {
|
|
7802
8272
|
if (!this.config.validateOnAccess) {
|
|
7803
|
-
|
|
8273
|
+
logger31.debug("TTL_VALIDATE: Validation disabled, skipping check", { key });
|
|
7804
8274
|
return true;
|
|
7805
8275
|
}
|
|
7806
|
-
|
|
8276
|
+
logger31.debug("TTL_VALIDATE: Validating item", {
|
|
7807
8277
|
key,
|
|
7808
8278
|
ttlEnabled: this.isTTLEnabled(),
|
|
7809
8279
|
defaultTTL: this.config.defaultTTL
|
|
7810
8280
|
});
|
|
7811
8281
|
const isExpired = await this.isExpired(key, metadataProvider);
|
|
7812
8282
|
const isValid = !isExpired;
|
|
7813
|
-
|
|
8283
|
+
logger31.debug("TTL_VALIDATE: Validation result", {
|
|
7814
8284
|
key,
|
|
7815
8285
|
isValid,
|
|
7816
8286
|
isExpired
|
|
@@ -7844,7 +8314,7 @@ var TTLManager = class {
|
|
|
7844
8314
|
const expiredKeys = [];
|
|
7845
8315
|
const allMetadata = await metadataProvider.getAllMetadata();
|
|
7846
8316
|
const now = Date.now();
|
|
7847
|
-
|
|
8317
|
+
logger31.debug("TTL_CLEANUP: Scanning for expired items", {
|
|
7848
8318
|
totalItems: allMetadata.size,
|
|
7849
8319
|
now: new Date(now).toISOString()
|
|
7850
8320
|
});
|
|
@@ -7855,7 +8325,7 @@ var TTLManager = class {
|
|
|
7855
8325
|
itemsWithTTL++;
|
|
7856
8326
|
if (now >= ttlMetadata.expiresAt) {
|
|
7857
8327
|
expiredKeys.push(key);
|
|
7858
|
-
|
|
8328
|
+
logger31.debug("TTL_CLEANUP: Found expired item", {
|
|
7859
8329
|
key,
|
|
7860
8330
|
expiresAt: new Date(ttlMetadata.expiresAt).toISOString(),
|
|
7861
8331
|
expiredByMs: now - ttlMetadata.expiresAt
|
|
@@ -7865,7 +8335,7 @@ var TTLManager = class {
|
|
|
7865
8335
|
}
|
|
7866
8336
|
const duration = Date.now() - startTime;
|
|
7867
8337
|
if (expiredKeys.length > 0) {
|
|
7868
|
-
|
|
8338
|
+
logger31.debug("TTL_CLEANUP: Expired items found", {
|
|
7869
8339
|
expiredCount: expiredKeys.length,
|
|
7870
8340
|
totalItems: allMetadata.size,
|
|
7871
8341
|
itemsWithTTL,
|
|
@@ -7873,7 +8343,7 @@ var TTLManager = class {
|
|
|
7873
8343
|
duration
|
|
7874
8344
|
});
|
|
7875
8345
|
} else {
|
|
7876
|
-
|
|
8346
|
+
logger31.debug("TTL_CLEANUP: No expired items found", {
|
|
7877
8347
|
totalItems: allMetadata.size,
|
|
7878
8348
|
itemsWithTTL,
|
|
7879
8349
|
duration
|
|
@@ -7905,7 +8375,7 @@ var TTLManager = class {
|
|
|
7905
8375
|
}
|
|
7906
8376
|
metadata.expiresAt += additionalTTL;
|
|
7907
8377
|
await metadataProvider.setMetadata(key, metadata);
|
|
7908
|
-
|
|
8378
|
+
logger31.trace("TTL extended for item", { key, additionalTTL, newExpiresAt: metadata.expiresAt });
|
|
7909
8379
|
return true;
|
|
7910
8380
|
}
|
|
7911
8381
|
/**
|
|
@@ -7927,7 +8397,7 @@ var TTLManager = class {
|
|
|
7927
8397
|
ttl
|
|
7928
8398
|
};
|
|
7929
8399
|
await metadataProvider.setMetadata(key, ttlMetadata);
|
|
7930
|
-
|
|
8400
|
+
logger31.trace("TTL refreshed for item", { key, ttl, expiresAt: ttlMetadata.expiresAt });
|
|
7931
8401
|
return true;
|
|
7932
8402
|
}
|
|
7933
8403
|
/**
|
|
@@ -7939,9 +8409,9 @@ var TTLManager = class {
|
|
|
7939
8409
|
}
|
|
7940
8410
|
if (this.config.cleanupInterval) {
|
|
7941
8411
|
this.cleanupTimer = setInterval(() => {
|
|
7942
|
-
|
|
8412
|
+
logger31.trace("Auto cleanup timer triggered");
|
|
7943
8413
|
}, this.config.cleanupInterval);
|
|
7944
|
-
|
|
8414
|
+
logger31.debug("Auto cleanup started", { interval: this.config.cleanupInterval });
|
|
7945
8415
|
}
|
|
7946
8416
|
}
|
|
7947
8417
|
/**
|
|
@@ -7951,7 +8421,7 @@ var TTLManager = class {
|
|
|
7951
8421
|
if (this.cleanupTimer) {
|
|
7952
8422
|
clearInterval(this.cleanupTimer);
|
|
7953
8423
|
this.cleanupTimer = null;
|
|
7954
|
-
|
|
8424
|
+
logger31.debug("Auto cleanup stopped");
|
|
7955
8425
|
}
|
|
7956
8426
|
}
|
|
7957
8427
|
/**
|
|
@@ -7959,18 +8429,31 @@ var TTLManager = class {
|
|
|
7959
8429
|
*/
|
|
7960
8430
|
clear() {
|
|
7961
8431
|
this.stopAutoCleanup();
|
|
7962
|
-
|
|
8432
|
+
logger31.debug("TTL manager cleared");
|
|
7963
8433
|
}
|
|
7964
8434
|
/**
|
|
7965
8435
|
* Cleanup resources
|
|
7966
8436
|
*/
|
|
7967
8437
|
destroy() {
|
|
8438
|
+
logger31.debug("TTL manager destroy started", {
|
|
8439
|
+
component: "cache",
|
|
8440
|
+
subcomponent: "TTLManager",
|
|
8441
|
+
operation: "destroy",
|
|
8442
|
+
autoCleanupEnabled: !!this.config.cleanupInterval,
|
|
8443
|
+
note: "Stopping auto-cleanup and clearing TTL data"
|
|
8444
|
+
});
|
|
7968
8445
|
this.stopAutoCleanup();
|
|
7969
|
-
|
|
8446
|
+
logger31.debug("TTL manager destroyed", {
|
|
8447
|
+
component: "cache",
|
|
8448
|
+
subcomponent: "TTLManager",
|
|
8449
|
+
operation: "destroy",
|
|
8450
|
+
note: "All TTL tracking data cleared"
|
|
8451
|
+
});
|
|
7970
8452
|
}
|
|
7971
8453
|
};
|
|
7972
8454
|
|
|
7973
8455
|
// src/events/CacheEventEmitter.ts
|
|
8456
|
+
var logger32 = logger_default.get("CacheEventEmitter");
|
|
7974
8457
|
var CacheEventEmitter = class {
|
|
7975
8458
|
subscriptions = /* @__PURE__ */ new Map();
|
|
7976
8459
|
nextSubscriptionId = 1;
|
|
@@ -8071,9 +8554,17 @@ var CacheEventEmitter = class {
|
|
|
8071
8554
|
*/
|
|
8072
8555
|
emit(event) {
|
|
8073
8556
|
if (this.isDestroyed) {
|
|
8557
|
+
logger32.debug("Event emission skipped - emitter is destroyed", {
|
|
8558
|
+
component: "cache",
|
|
8559
|
+
subcomponent: "CacheEventEmitter",
|
|
8560
|
+
eventType: event.type,
|
|
8561
|
+
suggestion: "This is expected during cleanup. Ensure emitter is not used after destroy()."
|
|
8562
|
+
});
|
|
8074
8563
|
return;
|
|
8075
8564
|
}
|
|
8076
8565
|
let emittedCount = 0;
|
|
8566
|
+
const totalSubscriptions = this.subscriptions.size;
|
|
8567
|
+
const activeSubscriptions = Array.from(this.subscriptions.values()).filter((s) => s.isActive).length;
|
|
8077
8568
|
for (const subscription of this.subscriptions.values()) {
|
|
8078
8569
|
if (!subscription.isActive) {
|
|
8079
8570
|
continue;
|
|
@@ -8083,6 +8574,17 @@ var CacheEventEmitter = class {
|
|
|
8083
8574
|
emittedCount++;
|
|
8084
8575
|
}
|
|
8085
8576
|
}
|
|
8577
|
+
logger32.trace("Event emitted to subscriptions", {
|
|
8578
|
+
component: "cache",
|
|
8579
|
+
subcomponent: "CacheEventEmitter",
|
|
8580
|
+
eventType: event.type,
|
|
8581
|
+
eventSource: event.source,
|
|
8582
|
+
eventKey: "key" in event ? JSON.stringify(event.key) : void 0,
|
|
8583
|
+
totalSubscriptions,
|
|
8584
|
+
activeSubscriptions,
|
|
8585
|
+
emittedCount,
|
|
8586
|
+
note: emittedCount === 0 ? "No subscriptions matched this event" : void 0
|
|
8587
|
+
});
|
|
8086
8588
|
}
|
|
8087
8589
|
/**
|
|
8088
8590
|
* Get count of active subscriptions
|
|
@@ -8287,20 +8789,36 @@ var CacheEventEmitter = class {
|
|
|
8287
8789
|
*/
|
|
8288
8790
|
handleListenerError(error, event, subscription) {
|
|
8289
8791
|
const errorObj = error instanceof Error ? error : new Error(String(error));
|
|
8792
|
+
const errorContext = {
|
|
8793
|
+
component: "CacheEventEmitter",
|
|
8794
|
+
operation: "event-listener",
|
|
8795
|
+
eventType: event.type,
|
|
8796
|
+
eventKey: "key" in event ? JSON.stringify(event.key) : void 0,
|
|
8797
|
+
subscriptionId: subscription.id,
|
|
8798
|
+
errorType: errorObj.constructor.name,
|
|
8799
|
+
errorMessage: errorObj.message,
|
|
8800
|
+
suggestion: "Review event listener implementation for errors. Consider adding error handling in the listener.",
|
|
8801
|
+
stack: errorObj.stack
|
|
8802
|
+
};
|
|
8290
8803
|
if (subscription.options.onError) {
|
|
8291
8804
|
try {
|
|
8292
8805
|
subscription.options.onError(errorObj, event);
|
|
8293
8806
|
} catch (handlerError) {
|
|
8294
|
-
console.error("Error in cache event listener:",
|
|
8807
|
+
console.error("Error in cache event listener:", JSON.stringify(errorContext, null, 2));
|
|
8808
|
+
console.error("Original error:", errorObj);
|
|
8295
8809
|
console.error("Error in error handler:", handlerError);
|
|
8810
|
+
console.error("Critical: Both the event listener and its error handler failed. Review error handling logic.");
|
|
8296
8811
|
}
|
|
8297
8812
|
} else {
|
|
8298
|
-
console.error("Error in cache event listener:",
|
|
8813
|
+
console.error("Error in cache event listener (no error handler configured):", JSON.stringify(errorContext, null, 2));
|
|
8814
|
+
console.error("Original error:", errorObj);
|
|
8815
|
+
console.error("Suggestion: Add an onError handler to your subscription to handle listener errors gracefully.");
|
|
8299
8816
|
}
|
|
8300
8817
|
}
|
|
8301
8818
|
};
|
|
8302
8819
|
|
|
8303
8820
|
// src/CacheStats.ts
|
|
8821
|
+
var logger33 = logger_default.get("CacheStats");
|
|
8304
8822
|
var CacheStatsManager = class {
|
|
8305
8823
|
stats = {
|
|
8306
8824
|
numRequests: 0,
|
|
@@ -8310,11 +8828,22 @@ var CacheStatsManager = class {
|
|
|
8310
8828
|
numUnsubscriptions: 0,
|
|
8311
8829
|
activeSubscriptions: 0
|
|
8312
8830
|
};
|
|
8831
|
+
lastLoggedStats = {
|
|
8832
|
+
numRequests: 0,
|
|
8833
|
+
numMisses: 0,
|
|
8834
|
+
numHits: 0,
|
|
8835
|
+
numSubscriptions: 0,
|
|
8836
|
+
numUnsubscriptions: 0,
|
|
8837
|
+
activeSubscriptions: 0
|
|
8838
|
+
};
|
|
8839
|
+
LOG_THRESHOLD = 100;
|
|
8840
|
+
// Log every 100 requests
|
|
8313
8841
|
/**
|
|
8314
8842
|
* Increment the request counter
|
|
8315
8843
|
*/
|
|
8316
8844
|
incrementRequests() {
|
|
8317
8845
|
this.stats.numRequests++;
|
|
8846
|
+
this.maybeLogStats();
|
|
8318
8847
|
}
|
|
8319
8848
|
/**
|
|
8320
8849
|
* Increment the cache hit counter
|
|
@@ -8328,6 +8857,27 @@ var CacheStatsManager = class {
|
|
|
8328
8857
|
incrementMisses() {
|
|
8329
8858
|
this.stats.numMisses++;
|
|
8330
8859
|
}
|
|
8860
|
+
/**
|
|
8861
|
+
* Log statistics periodically for monitoring
|
|
8862
|
+
*/
|
|
8863
|
+
maybeLogStats() {
|
|
8864
|
+
const requestsSinceLastLog = this.stats.numRequests - this.lastLoggedStats.numRequests;
|
|
8865
|
+
if (requestsSinceLastLog >= this.LOG_THRESHOLD) {
|
|
8866
|
+
const hitRate = this.stats.numRequests > 0 ? (this.stats.numHits / this.stats.numRequests * 100).toFixed(2) : "0.00";
|
|
8867
|
+
logger33.debug("Cache statistics update", {
|
|
8868
|
+
component: "cache",
|
|
8869
|
+
subcomponent: "CacheStatsManager",
|
|
8870
|
+
totalRequests: this.stats.numRequests,
|
|
8871
|
+
hits: this.stats.numHits,
|
|
8872
|
+
misses: this.stats.numMisses,
|
|
8873
|
+
hitRate: `${hitRate}%`,
|
|
8874
|
+
activeSubscriptions: this.stats.activeSubscriptions,
|
|
8875
|
+
requestsSinceLastLog,
|
|
8876
|
+
note: `Statistics logged every ${this.LOG_THRESHOLD} requests for monitoring`
|
|
8877
|
+
});
|
|
8878
|
+
this.lastLoggedStats = { ...this.stats };
|
|
8879
|
+
}
|
|
8880
|
+
}
|
|
8331
8881
|
/**
|
|
8332
8882
|
* Increment the subscription counter
|
|
8333
8883
|
*/
|
|
@@ -8366,9 +8916,17 @@ var CacheStatsManager = class {
|
|
|
8366
8916
|
};
|
|
8367
8917
|
|
|
8368
8918
|
// src/Cache.ts
|
|
8369
|
-
var
|
|
8919
|
+
var logger34 = logger_default.get("Cache");
|
|
8370
8920
|
var createCache = (api, coordinate, registry, options) => {
|
|
8371
|
-
|
|
8921
|
+
logger34.debug("createCache", {
|
|
8922
|
+
component: "cache",
|
|
8923
|
+
operation: "createCache",
|
|
8924
|
+
itemType: coordinate.kta[0],
|
|
8925
|
+
hierarchy: coordinate.kta,
|
|
8926
|
+
cacheType: options?.cacheType,
|
|
8927
|
+
hasRegistry: !!registry,
|
|
8928
|
+
note: "Cache creation started"
|
|
8929
|
+
});
|
|
8372
8930
|
const completeOptions = createOptions(options);
|
|
8373
8931
|
const cacheMap = createCacheMap(coordinate.kta, completeOptions);
|
|
8374
8932
|
const pkType = coordinate.kta[0];
|
|
@@ -8448,18 +9006,24 @@ var isCache2 = (cache) => {
|
|
|
8448
9006
|
};
|
|
8449
9007
|
|
|
8450
9008
|
// src/InstanceFactory.ts
|
|
8451
|
-
var
|
|
9009
|
+
var logger35 = logger_default.get("InstanceFactory");
|
|
8452
9010
|
var createInstanceFactory = (api, options) => {
|
|
8453
9011
|
const templateOptions = createOptions(options);
|
|
8454
9012
|
validateOptions(templateOptions);
|
|
8455
9013
|
return (coordinate, context) => {
|
|
8456
9014
|
const instanceOptions = createOptions(options);
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
9015
|
+
logger35.debug("Creating cache instance", {
|
|
9016
|
+
component: "cache",
|
|
9017
|
+
operation: "createInstance",
|
|
9018
|
+
itemType: coordinate.kta[0],
|
|
9019
|
+
hierarchy: coordinate.kta,
|
|
8461
9020
|
cacheType: instanceOptions.cacheType,
|
|
8462
|
-
|
|
9021
|
+
ttlEnabled: !!instanceOptions.ttl,
|
|
9022
|
+
ttlValue: instanceOptions.ttl,
|
|
9023
|
+
evictionEnabled: !!instanceOptions.evictionConfig,
|
|
9024
|
+
evictionStrategy: instanceOptions.evictionConfig?.type,
|
|
9025
|
+
twoLayerEnabled: !!instanceOptions.twoLayer,
|
|
9026
|
+
note: "Cache instance initialization started"
|
|
8463
9027
|
});
|
|
8464
9028
|
const cacheMap = createCacheMap(coordinate.kta, instanceOptions);
|
|
8465
9029
|
const pkType = coordinate.kta[0];
|
|
@@ -8521,9 +9085,9 @@ var createInstanceFactory = (api, options) => {
|
|
|
8521
9085
|
};
|
|
8522
9086
|
|
|
8523
9087
|
// src/Instance.ts
|
|
8524
|
-
var
|
|
9088
|
+
var logger36 = logger_default.get("Instance");
|
|
8525
9089
|
var createInstance = (registry, coordinate, api, options) => {
|
|
8526
|
-
|
|
9090
|
+
logger36.debug("createInstance", { coordinate, api, registry, options });
|
|
8527
9091
|
return createCache(api, coordinate, registry, options);
|
|
8528
9092
|
};
|
|
8529
9093
|
var isInstance = (instance) => {
|
|
@@ -8531,7 +9095,7 @@ var isInstance = (instance) => {
|
|
|
8531
9095
|
};
|
|
8532
9096
|
|
|
8533
9097
|
// src/Aggregator.ts
|
|
8534
|
-
var
|
|
9098
|
+
var logger37 = logger_default.get("ItemAggregator");
|
|
8535
9099
|
var toCacheConfig = (config) => {
|
|
8536
9100
|
let cacheConfig;
|
|
8537
9101
|
if (config.optional === void 0) {
|
|
@@ -8543,23 +9107,32 @@ var toCacheConfig = (config) => {
|
|
|
8543
9107
|
};
|
|
8544
9108
|
var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
8545
9109
|
const populate = async (item) => {
|
|
8546
|
-
|
|
9110
|
+
logger37.default("populate", { item });
|
|
8547
9111
|
for (const key in aggregates) {
|
|
8548
9112
|
await populateAggregate(key, item);
|
|
8549
9113
|
}
|
|
8550
9114
|
for (const key in events) {
|
|
8551
9115
|
await populateEvent(key, item);
|
|
8552
9116
|
}
|
|
8553
|
-
|
|
9117
|
+
logger37.default("populate done", { item });
|
|
8554
9118
|
return item;
|
|
8555
9119
|
};
|
|
8556
9120
|
const populateAggregate = async (key, item) => {
|
|
8557
|
-
|
|
9121
|
+
logger37.default("populate aggregate key", { key });
|
|
8558
9122
|
const cacheConfig = toCacheConfig(aggregates[key]);
|
|
8559
9123
|
if (item.refs === void 0) {
|
|
8560
9124
|
if (cacheConfig.optional === false) {
|
|
8561
|
-
|
|
8562
|
-
|
|
9125
|
+
logger37.error("Item missing required refs property", {
|
|
9126
|
+
component: "cache",
|
|
9127
|
+
subcomponent: "Aggregator",
|
|
9128
|
+
operation: "populateRef",
|
|
9129
|
+
refKey: key,
|
|
9130
|
+
item: JSON.stringify(item),
|
|
9131
|
+
suggestion: "Ensure the item has a refs property or mark this reference as optional in cache configuration"
|
|
9132
|
+
});
|
|
9133
|
+
throw new Error(
|
|
9134
|
+
`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.`
|
|
9135
|
+
);
|
|
8563
9136
|
} else {
|
|
8564
9137
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
8565
9138
|
delete item.events[key];
|
|
@@ -8567,8 +9140,18 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8567
9140
|
}
|
|
8568
9141
|
} else if (item.refs[key] === void 0) {
|
|
8569
9142
|
if (cacheConfig.optional === false) {
|
|
8570
|
-
|
|
8571
|
-
|
|
9143
|
+
logger37.error("Item missing required reference", {
|
|
9144
|
+
component: "cache",
|
|
9145
|
+
subcomponent: "Aggregator",
|
|
9146
|
+
operation: "populateRef",
|
|
9147
|
+
refKey: key,
|
|
9148
|
+
availableRefs: Object.keys(item.refs || {}),
|
|
9149
|
+
item: JSON.stringify(item),
|
|
9150
|
+
suggestion: `Ensure the item has refs.${key} property or mark this reference as optional in cache configuration`
|
|
9151
|
+
});
|
|
9152
|
+
throw new Error(
|
|
9153
|
+
`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.`
|
|
9154
|
+
);
|
|
8572
9155
|
} else {
|
|
8573
9156
|
if (item.events && Object.prototype.hasOwnProperty.call(item.events, key)) {
|
|
8574
9157
|
delete item.events[key];
|
|
@@ -8576,7 +9159,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8576
9159
|
}
|
|
8577
9160
|
} else {
|
|
8578
9161
|
const ref = item.refs[key];
|
|
8579
|
-
|
|
9162
|
+
logger37.default("AGG Retrieving Item in Populate", { key: ref });
|
|
8580
9163
|
const newItem = await cacheConfig.cache.operations.retrieve(ref);
|
|
8581
9164
|
if (newItem) {
|
|
8582
9165
|
if (item.aggs === void 0) {
|
|
@@ -8593,25 +9176,52 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8593
9176
|
}
|
|
8594
9177
|
};
|
|
8595
9178
|
const populateEvent = async (key, item) => {
|
|
8596
|
-
|
|
9179
|
+
logger37.default("populate event key", { key });
|
|
8597
9180
|
const cacheConfig = toCacheConfig(events[key]);
|
|
8598
9181
|
if (item.events === void 0) {
|
|
8599
|
-
|
|
9182
|
+
logger37.error("Item missing events property", {
|
|
9183
|
+
component: "cache",
|
|
9184
|
+
subcomponent: "Aggregator",
|
|
9185
|
+
operation: "populateEvent",
|
|
9186
|
+
eventKey: key,
|
|
9187
|
+
item: JSON.stringify(item),
|
|
9188
|
+
suggestion: "Ensure the item has an events property with event data"
|
|
9189
|
+
});
|
|
9190
|
+
throw new Error(
|
|
9191
|
+
`Item missing events property for event '${key}'. Item: ${JSON.stringify(item)}. Suggestion: Ensure events are properly tracked on this item type.`
|
|
9192
|
+
);
|
|
8600
9193
|
} else if (item.events[key] === void 0) {
|
|
8601
9194
|
if (cacheConfig.optional === false) {
|
|
8602
|
-
|
|
8603
|
-
|
|
9195
|
+
logger37.error("Item missing required event", {
|
|
9196
|
+
component: "cache",
|
|
9197
|
+
subcomponent: "Aggregator",
|
|
9198
|
+
operation: "populateEvent",
|
|
9199
|
+
eventKey: key,
|
|
9200
|
+
availableEvents: Object.keys(item.events || {}),
|
|
9201
|
+
item: JSON.stringify(item),
|
|
9202
|
+
suggestion: `Ensure the item has events.${key} property or mark this event as optional`
|
|
9203
|
+
});
|
|
9204
|
+
throw new Error(
|
|
9205
|
+
`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.`
|
|
9206
|
+
);
|
|
8604
9207
|
}
|
|
8605
9208
|
} else {
|
|
8606
9209
|
const event = item.events[key];
|
|
8607
9210
|
if (event.by === void 0) {
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
9211
|
+
logger37.error('Event missing required "by" field', {
|
|
9212
|
+
component: "cache",
|
|
9213
|
+
subcomponent: "Aggregator",
|
|
9214
|
+
operation: "populateEvent",
|
|
9215
|
+
eventKey: key,
|
|
9216
|
+
event,
|
|
9217
|
+
itemKey: item.key,
|
|
9218
|
+
suggestion: 'Ensure event has a "by" field with the user/actor who triggered the event'
|
|
9219
|
+
});
|
|
9220
|
+
throw new Error(
|
|
9221
|
+
`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
9222
|
);
|
|
8612
|
-
throw new Error("populateEvent with an Event that does not have by: " + JSON.stringify({ key }));
|
|
8613
9223
|
}
|
|
8614
|
-
|
|
9224
|
+
logger37.default("EVENT Retrieving Item in Populate", { key: event.by });
|
|
8615
9225
|
const newItem = await cacheConfig.cache.operations.retrieve(event.by);
|
|
8616
9226
|
if (newItem) {
|
|
8617
9227
|
event.agg = newItem;
|
|
@@ -8619,13 +9229,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8619
9229
|
}
|
|
8620
9230
|
};
|
|
8621
9231
|
const all2 = async (query = {}, locations = []) => {
|
|
8622
|
-
|
|
9232
|
+
logger37.default("all", { query, locations });
|
|
8623
9233
|
const result = await cache.operations.all(query, locations);
|
|
8624
9234
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8625
9235
|
return populatedItems;
|
|
8626
9236
|
};
|
|
8627
9237
|
const one2 = async (query = {}, locations = []) => {
|
|
8628
|
-
|
|
9238
|
+
logger37.default("one", { query, locations });
|
|
8629
9239
|
const item = await cache.operations.one(query, locations);
|
|
8630
9240
|
let populatedItem = null;
|
|
8631
9241
|
if (item) {
|
|
@@ -8634,30 +9244,30 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8634
9244
|
return populatedItem;
|
|
8635
9245
|
};
|
|
8636
9246
|
const action2 = async (key, action3, body = {}) => {
|
|
8637
|
-
|
|
9247
|
+
logger37.default("action", { key, action: action3, body });
|
|
8638
9248
|
const [item, affectedItems] = await cache.operations.action(key, action3, body);
|
|
8639
9249
|
const populatedItem = await populate(item);
|
|
8640
9250
|
return [populatedItem, affectedItems];
|
|
8641
9251
|
};
|
|
8642
9252
|
const allAction2 = async (action3, body = {}, locations = []) => {
|
|
8643
|
-
|
|
9253
|
+
logger37.default("action", { action: action3, body, locations });
|
|
8644
9254
|
const [items, affectedItems] = await cache.operations.allAction(action3, body, locations);
|
|
8645
9255
|
const populatedItems = await Promise.all(items.map(async (item) => populate(item)));
|
|
8646
9256
|
return [populatedItems, affectedItems];
|
|
8647
9257
|
};
|
|
8648
9258
|
const allFacet2 = async (facet3, params = {}, locations = []) => {
|
|
8649
|
-
|
|
9259
|
+
logger37.default("allFacet", { facet: facet3, params, locations });
|
|
8650
9260
|
const response = await cache.operations.allFacet(facet3, params, locations);
|
|
8651
9261
|
return response;
|
|
8652
9262
|
};
|
|
8653
9263
|
const create2 = async (v, locations = []) => {
|
|
8654
|
-
|
|
9264
|
+
logger37.default("create", { v, locations });
|
|
8655
9265
|
const item = locations.length === 0 ? await cache.operations.create(v) : await cache.operations.create(v, { locations });
|
|
8656
9266
|
const populatedItem = await populate(item);
|
|
8657
9267
|
return populatedItem;
|
|
8658
9268
|
};
|
|
8659
9269
|
const get2 = async (key) => {
|
|
8660
|
-
|
|
9270
|
+
logger37.default("get", { key });
|
|
8661
9271
|
const item = await cache.operations.get(key);
|
|
8662
9272
|
let populatedItem = null;
|
|
8663
9273
|
if (item) {
|
|
@@ -8666,7 +9276,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8666
9276
|
return populatedItem;
|
|
8667
9277
|
};
|
|
8668
9278
|
const retrieve2 = async (key) => {
|
|
8669
|
-
|
|
9279
|
+
logger37.default("retrieve", { key });
|
|
8670
9280
|
const item = await cache.operations.retrieve(key);
|
|
8671
9281
|
let populatedItem = null;
|
|
8672
9282
|
if (item) {
|
|
@@ -8675,22 +9285,22 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8675
9285
|
return populatedItem;
|
|
8676
9286
|
};
|
|
8677
9287
|
const remove2 = async (key) => {
|
|
8678
|
-
|
|
9288
|
+
logger37.default("remove", { key });
|
|
8679
9289
|
await cache.operations.remove(key);
|
|
8680
9290
|
};
|
|
8681
9291
|
const update2 = async (key, v) => {
|
|
8682
|
-
|
|
9292
|
+
logger37.default("update", { key, v });
|
|
8683
9293
|
const item = await cache.operations.update(key, v);
|
|
8684
9294
|
const populatedItem = await populate(item);
|
|
8685
9295
|
return populatedItem;
|
|
8686
9296
|
};
|
|
8687
9297
|
const facet2 = async (key, facet3) => {
|
|
8688
|
-
|
|
9298
|
+
logger37.default("facet", { key, facet: facet3 });
|
|
8689
9299
|
const response = await cache.operations.facet(key, facet3);
|
|
8690
9300
|
return response;
|
|
8691
9301
|
};
|
|
8692
9302
|
const find2 = async (finder, finderParams = {}, locations = [], findOptions) => {
|
|
8693
|
-
|
|
9303
|
+
logger37.default("find", { finder, finderParams, locations, findOptions });
|
|
8694
9304
|
const result = await cache.operations.find(finder, finderParams, locations, findOptions);
|
|
8695
9305
|
const populatedItems = await Promise.all(result.items.map(async (item) => populate(item)));
|
|
8696
9306
|
return {
|
|
@@ -8699,7 +9309,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8699
9309
|
};
|
|
8700
9310
|
};
|
|
8701
9311
|
const findOne2 = async (finder, finderParams = {}, locations = []) => {
|
|
8702
|
-
|
|
9312
|
+
logger37.default("find", { finder, finderParams, locations });
|
|
8703
9313
|
const item = await cache.operations.findOne(finder, finderParams, locations);
|
|
8704
9314
|
if (!item) {
|
|
8705
9315
|
return null;
|
|
@@ -8708,7 +9318,7 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8708
9318
|
return populatedItem;
|
|
8709
9319
|
};
|
|
8710
9320
|
const set2 = async (key, v) => {
|
|
8711
|
-
|
|
9321
|
+
logger37.default("set", { key, v });
|
|
8712
9322
|
const item = await cache.operations.set(key, v);
|
|
8713
9323
|
const populatedItem = await populate(item);
|
|
8714
9324
|
return populatedItem;
|
|
@@ -8760,13 +9370,13 @@ var createAggregator = async (cache, { aggregates = {}, events = {} }) => {
|
|
|
8760
9370
|
import {
|
|
8761
9371
|
createRegistry as createBaseRegistry
|
|
8762
9372
|
} from "@fjell/registry";
|
|
8763
|
-
var
|
|
9373
|
+
var logger38 = logger_default.get("Registry");
|
|
8764
9374
|
var createRegistryFactory = () => {
|
|
8765
9375
|
return (type, registryHub) => {
|
|
8766
9376
|
if (type !== "cache") {
|
|
8767
9377
|
throw new Error(`Cache registry factory can only create 'cache' type registries, got: ${type}`);
|
|
8768
9378
|
}
|
|
8769
|
-
|
|
9379
|
+
logger38.debug("Creating cache registry", { type, registryHub });
|
|
8770
9380
|
const baseRegistry = createBaseRegistry(type, registryHub);
|
|
8771
9381
|
return baseRegistry;
|
|
8772
9382
|
};
|