@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 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
- logger2.debug("QUERY_CACHE: Attempting direct cache query using queryIn()", {
874
- queryHash,
875
- query: JSON.stringify(query),
876
- locations: JSON.stringify(locations)
877
- });
878
- try {
879
- const directCachedItems = await cacheMap.queryIn(query, locations);
880
- if (directCachedItems && directCachedItems.length > 0) {
881
- logger2.debug("QUERY_CACHE: Direct cache query SUCCESS - Found items in item cache", {
882
- queryHash,
883
- itemCount: directCachedItems.length,
884
- itemKeys: directCachedItems.map((item) => JSON.stringify(item.key))
885
- });
886
- const itemKeys = directCachedItems.map((item) => item.key);
887
- await cacheMap.setQueryResult(queryHash, itemKeys);
888
- logger2.debug("QUERY_CACHE: Stored query result from direct cache hit", {
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
- itemKeyCount: itemKeys.length,
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
- } catch (error) {
898
- logger2.debug("QUERY_CACHE: Error querying cache directly, proceeding to API", {
917
+ } else {
918
+ logger2.debug("QUERY_CACHE: Skipping direct cache query for empty/all query - cannot trust completeness", {
899
919
  queryHash,
900
- error: error instanceof Error ? error.message : String(error)
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
- ret = await api.all(query, locations);
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 inFlightRequests = /* @__PURE__ */ new Map();
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
- inFlightRequests.forEach((request, key) => {
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
- inFlightRequests.delete(key);
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 = inFlightRequests.get(requestKeyStr);
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
- inFlightRequests.set(requestKeyStr, { promise: apiRequest, timestamp });
1507
- const cleanup = () => inFlightRequests.delete(requestKeyStr);
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
- inFlightRequests.delete(requestKeyStr);
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
@@ -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;AAO/C,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"}
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.44",
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.54",
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.66",
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"