@fjell/cache 4.7.44 → 4.7.46
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/index.js +66 -32
- package/dist/ops/all.d.ts +1 -0
- package/dist/ops/all.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -791,6 +791,18 @@ var CacheEventFactory = class {
|
|
|
791
791
|
|
|
792
792
|
// src/ops/all.ts
|
|
793
793
|
var logger2 = logger_default.get("all");
|
|
794
|
+
var inFlightRequests = /* @__PURE__ */ new Map();
|
|
795
|
+
var CLEANUP_INTERVAL = 3e4;
|
|
796
|
+
var REQUEST_TIMEOUT = 25e3;
|
|
797
|
+
setInterval(() => {
|
|
798
|
+
const now = Date.now();
|
|
799
|
+
inFlightRequests.forEach((request, key) => {
|
|
800
|
+
if (now - request.timestamp > REQUEST_TIMEOUT) {
|
|
801
|
+
logger2.debug("Cleaning up stale in-flight all() request", { key });
|
|
802
|
+
inFlightRequests.delete(key);
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}, CLEANUP_INTERVAL);
|
|
794
806
|
var all = async (query = {}, locations = [], context) => {
|
|
795
807
|
const { api, cacheMap, pkType, ttlManager, coordinate } = context;
|
|
796
808
|
logger2.default("all", { query, locations });
|
|
@@ -870,34 +882,42 @@ async function executeAllLogic(query, locations, context) {
|
|
|
870
882
|
} else {
|
|
871
883
|
logger2.debug("QUERY_CACHE: Cache MISS - No cached query result found", { queryHash });
|
|
872
884
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
885
|
+
const isEmptyQuery = Object.keys(query).length === 0 || (Object.keys(query).length === 1 && "limit" in query || "offset" in query);
|
|
886
|
+
if (!isEmptyQuery) {
|
|
887
|
+
logger2.debug("QUERY_CACHE: Attempting direct cache query using queryIn() for filtered query", {
|
|
888
|
+
queryHash,
|
|
889
|
+
query: JSON.stringify(query),
|
|
890
|
+
locations: JSON.stringify(locations)
|
|
891
|
+
});
|
|
892
|
+
try {
|
|
893
|
+
const directCachedItems = await cacheMap.queryIn(query, locations);
|
|
894
|
+
if (directCachedItems && directCachedItems.length > 0) {
|
|
895
|
+
logger2.debug("QUERY_CACHE: Direct cache query SUCCESS - Found items in item cache", {
|
|
896
|
+
queryHash,
|
|
897
|
+
itemCount: directCachedItems.length,
|
|
898
|
+
itemKeys: directCachedItems.map((item) => JSON.stringify(item.key))
|
|
899
|
+
});
|
|
900
|
+
const itemKeys = directCachedItems.map((item) => item.key);
|
|
901
|
+
await cacheMap.setQueryResult(queryHash, itemKeys);
|
|
902
|
+
logger2.debug("QUERY_CACHE: Stored query result from direct cache hit", {
|
|
903
|
+
queryHash,
|
|
904
|
+
itemKeyCount: itemKeys.length,
|
|
905
|
+
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
906
|
+
});
|
|
907
|
+
return directCachedItems;
|
|
908
|
+
} else {
|
|
909
|
+
logger2.debug("QUERY_CACHE: Direct cache query returned no items", { queryHash });
|
|
910
|
+
}
|
|
911
|
+
} catch (error) {
|
|
912
|
+
logger2.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
|
|
889
913
|
queryHash,
|
|
890
|
-
|
|
891
|
-
itemKeys: itemKeys.map((k) => JSON.stringify(k))
|
|
914
|
+
error: error instanceof Error ? error.message : String(error)
|
|
892
915
|
});
|
|
893
|
-
return directCachedItems;
|
|
894
|
-
} else {
|
|
895
|
-
logger2.debug("QUERY_CACHE: Direct cache query returned no items", { queryHash });
|
|
896
916
|
}
|
|
897
|
-
}
|
|
898
|
-
logger2.debug("QUERY_CACHE:
|
|
917
|
+
} else {
|
|
918
|
+
logger2.debug("QUERY_CACHE: Skipping direct cache query for empty/all query - cannot trust completeness", {
|
|
899
919
|
queryHash,
|
|
900
|
-
|
|
920
|
+
query: JSON.stringify(query)
|
|
901
921
|
});
|
|
902
922
|
}
|
|
903
923
|
logger2.debug("QUERY_CACHE: Fetching from API (cache miss or invalid)", {
|
|
@@ -905,9 +925,22 @@ async function executeAllLogic(query, locations, context) {
|
|
|
905
925
|
query: JSON.stringify(query),
|
|
906
926
|
locations: JSON.stringify(locations)
|
|
907
927
|
});
|
|
928
|
+
const timestamp = Date.now();
|
|
929
|
+
const existingRequest = inFlightRequests.get(queryHash);
|
|
930
|
+
if (existingRequest && timestamp - existingRequest.timestamp < REQUEST_TIMEOUT) {
|
|
931
|
+
logger2.debug("QUERY_CACHE: Using existing in-flight all() request", {
|
|
932
|
+
queryHash,
|
|
933
|
+
age: timestamp - existingRequest.timestamp
|
|
934
|
+
});
|
|
935
|
+
return await existingRequest.promise;
|
|
936
|
+
}
|
|
908
937
|
let ret = [];
|
|
909
938
|
try {
|
|
910
|
-
|
|
939
|
+
const apiRequest = api.all(query, locations);
|
|
940
|
+
inFlightRequests.set(queryHash, { promise: apiRequest, timestamp });
|
|
941
|
+
const cleanup = () => inFlightRequests.delete(queryHash);
|
|
942
|
+
apiRequest.then(cleanup, cleanup);
|
|
943
|
+
ret = await apiRequest;
|
|
911
944
|
logger2.debug("QUERY_CACHE: API response received", {
|
|
912
945
|
queryHash,
|
|
913
946
|
itemCount: ret.length,
|
|
@@ -946,6 +979,7 @@ async function executeAllLogic(query, locations, context) {
|
|
|
946
979
|
context.eventEmitter.emit(event);
|
|
947
980
|
logger2.debug("QUERY_CACHE: Emitted query event", { queryHash });
|
|
948
981
|
} catch (e) {
|
|
982
|
+
inFlightRequests.delete(queryHash);
|
|
949
983
|
if (e instanceof NotFoundError) {
|
|
950
984
|
logger2.debug("QUERY_CACHE: API returned NotFoundError, caching empty result", { queryHash });
|
|
951
985
|
await cacheMap.setQueryResult(queryHash, []);
|
|
@@ -1353,19 +1387,19 @@ import {
|
|
|
1353
1387
|
isValidItemKey
|
|
1354
1388
|
} from "@fjell/core";
|
|
1355
1389
|
var logger5 = logger_default.get("get");
|
|
1356
|
-
var
|
|
1390
|
+
var inFlightRequests2 = /* @__PURE__ */ new Map();
|
|
1357
1391
|
var CLEANUP_TIMEOUT = 5 * 60 * 1e3;
|
|
1358
1392
|
var cleanupStaleRequests = () => {
|
|
1359
1393
|
const now = Date.now();
|
|
1360
1394
|
const keysToDelete = [];
|
|
1361
|
-
|
|
1395
|
+
inFlightRequests2.forEach((request, key) => {
|
|
1362
1396
|
if (now - request.timestamp > CLEANUP_TIMEOUT) {
|
|
1363
1397
|
keysToDelete.push(key);
|
|
1364
1398
|
}
|
|
1365
1399
|
});
|
|
1366
1400
|
keysToDelete.forEach((key) => {
|
|
1367
1401
|
logger5.debug("Cleaning up stale in-flight request", { key });
|
|
1368
|
-
|
|
1402
|
+
inFlightRequests2.delete(key);
|
|
1369
1403
|
});
|
|
1370
1404
|
};
|
|
1371
1405
|
var cleanupInterval = setInterval(cleanupStaleRequests, 60 * 1e3);
|
|
@@ -1495,7 +1529,7 @@ async function executeGetLogic(key, context) {
|
|
|
1495
1529
|
let ret;
|
|
1496
1530
|
const requestKeyStr = keyToString(key);
|
|
1497
1531
|
try {
|
|
1498
|
-
const requestEntry =
|
|
1532
|
+
const requestEntry = inFlightRequests2.get(requestKeyStr);
|
|
1499
1533
|
let apiRequest;
|
|
1500
1534
|
const apiStartTime = Date.now();
|
|
1501
1535
|
if (!requestEntry) {
|
|
@@ -1503,8 +1537,8 @@ async function executeGetLogic(key, context) {
|
|
|
1503
1537
|
apiRequest = api.get(key);
|
|
1504
1538
|
if (apiRequest && typeof apiRequest.then === "function") {
|
|
1505
1539
|
const timestamp = Date.now();
|
|
1506
|
-
|
|
1507
|
-
const cleanup = () =>
|
|
1540
|
+
inFlightRequests2.set(requestKeyStr, { promise: apiRequest, timestamp });
|
|
1541
|
+
const cleanup = () => inFlightRequests2.delete(requestKeyStr);
|
|
1508
1542
|
if (typeof apiRequest.finally === "function") {
|
|
1509
1543
|
apiRequest.finally(cleanup);
|
|
1510
1544
|
} else {
|
|
@@ -1588,7 +1622,7 @@ async function executeGetLogic(key, context) {
|
|
|
1588
1622
|
});
|
|
1589
1623
|
}
|
|
1590
1624
|
} catch (e) {
|
|
1591
|
-
|
|
1625
|
+
inFlightRequests2.delete(requestKeyStr);
|
|
1592
1626
|
const duration = Date.now() - startTime;
|
|
1593
1627
|
logger5.error("CACHE_OP: Error in get() operation", {
|
|
1594
1628
|
key: keyStr,
|
package/dist/ops/all.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Item, ItemQuery, LocKeyArray } from "@fjell/core";
|
|
2
2
|
import { CacheContext } from "../CacheContext";
|
|
3
|
+
export declare const clearInFlightRequests: () => void;
|
|
3
4
|
export declare const all: <V extends Item<S, L1, L2, L3, L4, L5>, S extends string, L1 extends string = never, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(query: ItemQuery | undefined, locations: (LocKeyArray<L1, L2, L3, L4, L5> | []) | undefined, context: CacheContext<V, S, L1, L2, L3, L4, L5>) => Promise<[CacheContext<V, S, L1, L2, L3, L4, L5>, V[]]>;
|
|
4
5
|
//# sourceMappingURL=all.d.ts.map
|
package/dist/ops/all.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../src/ops/all.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EACJ,SAAS,EACT,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"all.d.ts","sourceRoot":"","sources":["../../src/ops/all.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EACJ,SAAS,EACT,WAAW,EACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAyB/C,eAAO,MAAM,qBAAqB,YAEjC,CAAC;AAEF,eAAO,MAAM,GAAG,GACd,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACrC,CAAC,SAAS,MAAM,EAChB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EACzB,EAAE,SAAS,MAAM,GAAG,KAAK,EAEzB,OAAO,SAAS,YAAK,EACrB,YAAW,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,aAAK,EACpD,SAAS,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAC9C,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAcvD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjell/cache",
|
|
3
3
|
"description": "Cache for Fjell",
|
|
4
|
-
"version": "4.7.
|
|
4
|
+
"version": "4.7.46",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cache",
|
|
7
7
|
"fjell"
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"docs:test": "cd docs && npm run test"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@fjell/client-api": "^4.4.
|
|
40
|
+
"@fjell/client-api": "^4.4.55",
|
|
41
41
|
"@fjell/core": "^4.4.61",
|
|
42
42
|
"@fjell/http-api": "^4.4.51",
|
|
43
43
|
"@fjell/logging": "^4.4.58",
|
|
44
|
-
"@fjell/registry": "^4.4.
|
|
44
|
+
"@fjell/registry": "^4.4.67",
|
|
45
45
|
"fast-safe-stringify": "^2.1.1",
|
|
46
46
|
"flatted": "^3.3.3",
|
|
47
47
|
"yocto-queue": "^1.2.1"
|