reactjrx 1.41.0 → 1.44.1

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.cjs CHANGED
@@ -472,7 +472,9 @@ const mergeResults = (stream$) => stream$.pipe(
472
472
  status: "loading"
473
473
  }
474
474
  ),
475
- rxjs.distinctUntilChanged(shallowEqual)
475
+ rxjs.distinctUntilChanged(
476
+ ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
477
+ )
476
478
  );
477
479
  function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
478
480
  const queryRef = useLiveRef(query);
@@ -638,10 +640,16 @@ const createActivityTrigger = (params$) => {
638
640
  return shouldRunTrigger !== false ? rxjs.merge(
639
641
  rxjs.fromEvent(document, "visibilitychange").pipe(
640
642
  rxjs.filter(() => !document.hidden),
641
- rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
643
+ rxjs.map(() => ({
644
+ type: "refetch",
645
+ ignoreStale: shouldRunTrigger === "always"
646
+ }))
642
647
  ),
643
648
  rxjs.fromEvent(window, "focus").pipe(
644
- rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
649
+ rxjs.map(() => ({
650
+ type: "refetch",
651
+ ignoreStale: shouldRunTrigger === "always"
652
+ }))
645
653
  )
646
654
  ) : rxjs.EMPTY;
647
655
  })
@@ -652,7 +660,10 @@ const createNetworkTrigger = (params$) => {
652
660
  rxjs.switchMap(({ options: { refetchOnReconnect = true } }) => {
653
661
  const shouldRunTrigger = typeof refetchOnReconnect === "function" ? refetchOnReconnect({}) : refetchOnReconnect;
654
662
  return shouldRunTrigger !== false ? rxjs.fromEvent(window, "online").pipe(
655
- rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
663
+ rxjs.map(() => ({
664
+ type: "refetch",
665
+ ignoreStale: shouldRunTrigger === "always"
666
+ }))
656
667
  ) : rxjs.EMPTY;
657
668
  })
658
669
  );
@@ -714,18 +725,18 @@ function useQuery({
714
725
  newKeyTrigger$,
715
726
  newObservableObjectQuery$
716
727
  );
717
- const refetch$ = rxjs.merge(
718
- internalRefresh$.current.pipe(rxjs.map(() => ({ ignoreStale: true }))),
728
+ const trigger$ = rxjs.merge(
729
+ internalRefresh$.current,
719
730
  rxjs.merge(activityRefetch$, networkRefetch$).pipe(rxjs.throttleTime(500))
720
731
  );
721
732
  return newQueryTrigger$.pipe(
722
733
  rxjs.withLatestFrom(key$),
723
734
  rxjs.switchMap(([, key]) => {
724
- const { result$ } = client.query$({
735
+ const { result$ } = client.query({
725
736
  key,
726
737
  fn$,
727
738
  options$,
728
- refetch$
739
+ trigger$
729
740
  });
730
741
  return result$.pipe(
731
742
  rxjs.scan(
@@ -762,7 +773,7 @@ function useQuery({
762
773
  [client]
763
774
  );
764
775
  const refetch = react.useCallback(() => {
765
- internalRefresh$.current.next();
776
+ internalRefresh$.current.next({ type: "refetch", ignoreStale: true });
766
777
  }, [client]);
767
778
  return { ...result, refetch };
768
779
  }
@@ -973,7 +984,6 @@ const createQueryStore = () => {
973
984
  };
974
985
  };
975
986
  const createQueryTrigger = ({
976
- refetch$,
977
987
  options$,
978
988
  queryStore,
979
989
  key
@@ -991,12 +1001,6 @@ const createQueryTrigger = ({
991
1001
  rxjs.filter((event) => key === event.key),
992
1002
  rxjs.map(({ trigger: trigger2 }) => trigger2)
993
1003
  ),
994
- refetch$.pipe(
995
- rxjs.map((event) => ({
996
- ...event,
997
- type: "refetch"
998
- }))
999
- ),
1000
1004
  enabledTrigger$.pipe(
1001
1005
  rxjs.map(() => ({
1002
1006
  type: "enabled",
@@ -1011,12 +1015,18 @@ const deduplicate = (key, queryStore) => (source) => {
1011
1015
  return rxjs.defer(() => {
1012
1016
  var _a;
1013
1017
  const sourceFromStore = (_a = queryStore.get(key)) == null ? void 0 : _a.deduplication_fn;
1018
+ if (sourceFromStore)
1019
+ return sourceFromStore;
1020
+ let sourceToDeduplicate;
1014
1021
  const deleteFromStore = () => {
1015
- queryStore.update(key, {
1016
- deduplication_fn: void 0
1017
- });
1022
+ var _a2;
1023
+ if (((_a2 = queryStore.get(key)) == null ? void 0 : _a2.deduplication_fn) === sourceToDeduplicate) {
1024
+ queryStore.update(key, {
1025
+ deduplication_fn: void 0
1026
+ });
1027
+ }
1018
1028
  };
1019
- const finalSource = sourceFromStore ?? source.pipe(
1029
+ sourceToDeduplicate = source.pipe(
1020
1030
  /**
1021
1031
  * Ideally we would want to remove the query from the store only on finalize,
1022
1032
  * which means whenever the query complete or error. Unfortunately finalize is
@@ -1036,12 +1046,10 @@ const deduplicate = (key, queryStore) => (source) => {
1036
1046
  bufferSize: 1
1037
1047
  })
1038
1048
  );
1039
- if (!sourceFromStore) {
1040
- queryStore.update(key, {
1041
- deduplication_fn: finalSource
1042
- });
1043
- }
1044
- return finalSource;
1049
+ queryStore.update(key, {
1050
+ deduplication_fn: sourceToDeduplicate
1051
+ });
1052
+ return sourceToDeduplicate;
1045
1053
  });
1046
1054
  };
1047
1055
  const notifyQueryResult = (options$) => (stream$) => stream$.pipe(
@@ -1165,8 +1173,9 @@ const createQueryFetch = ({
1165
1173
  const query = queryStore.get(serializedKey);
1166
1174
  const cacheResult = query == null ? void 0 : query.cache_fnResult;
1167
1175
  const hasCache = !!cacheResult;
1176
+ const ignoreStale = trigger2.type === "refetch" && trigger2.ignoreStale;
1168
1177
  if (hasCache) {
1169
- if (!(query == null ? void 0 : query.isStale) && !trigger2.ignoreStale) {
1178
+ if (!(query == null ? void 0 : query.isStale) && !ignoreStale) {
1170
1179
  return rxjs.of({
1171
1180
  fetchStatus: "idle",
1172
1181
  status: "success",
@@ -1236,6 +1245,9 @@ const createInvalidationClient = ({
1236
1245
  keysToRefetch = Array.from(queryStore.keys());
1237
1246
  }
1238
1247
  keysToRefetch.forEach((key) => {
1248
+ queryStore.update(key, {
1249
+ deduplication_fn: void 0
1250
+ });
1239
1251
  queryStore.dispatchQueryTrigger({
1240
1252
  key,
1241
1253
  trigger: { ignoreStale: true, type: "refetch" }
@@ -1246,10 +1258,7 @@ const createInvalidationClient = ({
1246
1258
  invalidateQueries
1247
1259
  };
1248
1260
  };
1249
- const logger$1 = Logger.namespace("refetch");
1250
- const createRefetchClient = ({
1251
- queryStore
1252
- }) => {
1261
+ const createRefetchClient = (_) => {
1253
1262
  const pipeQueryResult = ({
1254
1263
  options$
1255
1264
  }) => (stream) => {
@@ -1279,26 +1288,11 @@ const createRefetchClient = ({
1279
1288
  )
1280
1289
  );
1281
1290
  };
1282
- const pipeQueryTrigger = ({
1283
- key
1284
- }) => (stream) => {
1285
- return rxjs.merge(
1286
- stream.pipe(
1287
- rxjs.tap(({ ignoreStale }) => {
1288
- const query = queryStore.get(key);
1289
- if (query && ignoreStale && !query.isStale) {
1290
- logger$1.log(key, "marked stale by trigger!");
1291
- queryStore.update(key, {
1292
- isStale: true
1293
- });
1294
- }
1295
- })
1296
- )
1297
- );
1291
+ const refetchQueries = (_2) => {
1298
1292
  };
1299
1293
  return {
1300
1294
  pipeQueryResult,
1301
- pipeQueryTrigger
1295
+ refetchQueries
1302
1296
  };
1303
1297
  };
1304
1298
  const difference = (a, b) => a.filter((element) => !b.includes(element));
@@ -1472,10 +1466,11 @@ const updateStoreWithNewQuery = ({
1472
1466
  key
1473
1467
  }) => (stream) => stream.pipe(
1474
1468
  rxjs.withLatestFrom(options$),
1475
- rxjs.map(([value, options]) => {
1469
+ rxjs.map(([trigger2, options]) => {
1476
1470
  if (key.length === 0)
1477
- return [value, () => {
1478
- }];
1471
+ return [trigger2, void 0];
1472
+ if (trigger2.type !== "initial")
1473
+ return [trigger2, void 0];
1479
1474
  if (!queryStore.get(serializedKey)) {
1480
1475
  queryStore.set(serializedKey, getInitialQueryEntity({ key }));
1481
1476
  } else {
@@ -1486,10 +1481,10 @@ const updateStoreWithNewQuery = ({
1486
1481
  }
1487
1482
  });
1488
1483
  }
1489
- return [value, queryStore.addRunner(serializedKey, runner$)];
1484
+ return [trigger2, queryStore.addRunner(serializedKey, runner$)];
1490
1485
  })
1491
1486
  );
1492
- const logger = Logger.namespace("cache");
1487
+ const logger$1 = Logger.namespace("cache");
1493
1488
  const createCacheClient = ({
1494
1489
  queryStore
1495
1490
  }) => {
@@ -1500,7 +1495,7 @@ const createCacheClient = ({
1500
1495
  const serializedKey = serializeKey(queryKey);
1501
1496
  if (queryKey.length === 0)
1502
1497
  return;
1503
- logger.log("set cache for query", serializeKey);
1498
+ logger$1.log("set cache for query", serializeKey);
1504
1499
  if (!queryStore.get(serializedKey)) {
1505
1500
  queryStore.set(serializedKey, getInitialQueryEntity({ key: queryKey }));
1506
1501
  }
@@ -1533,55 +1528,107 @@ const createCacheClient = ({
1533
1528
  setQueryData
1534
1529
  };
1535
1530
  };
1531
+ const logger = Logger.namespace("refetch");
1532
+ const markQueryAsStaleIfRefetch = ({
1533
+ key,
1534
+ serializedKey,
1535
+ queryStore
1536
+ }) => (stream) => {
1537
+ return stream.pipe(
1538
+ rxjs.tap((trigger2) => {
1539
+ if (trigger2.type !== "refetch")
1540
+ return;
1541
+ const query = queryStore.get(serializedKey);
1542
+ if (query && trigger2.ignoreStale && !query.isStale) {
1543
+ logger.log(key, "marked stale by trigger!");
1544
+ queryStore.update(serializedKey, {
1545
+ isStale: true
1546
+ });
1547
+ }
1548
+ })
1549
+ );
1550
+ };
1551
+ const dispatchExternalRefetchToAllQueries = ({
1552
+ queryStore,
1553
+ serializedKey
1554
+ }) => (stream) => stream.pipe(
1555
+ rxjs.tap((trigger2) => {
1556
+ if (trigger2.type === "refetch") {
1557
+ queryStore.update(serializedKey, {
1558
+ deduplication_fn: void 0
1559
+ });
1560
+ queryStore.dispatchQueryTrigger({
1561
+ key: serializedKey,
1562
+ trigger: trigger2
1563
+ });
1564
+ }
1565
+ }),
1566
+ rxjs.filter((trigger2) => trigger2.type !== "refetch")
1567
+ );
1536
1568
  const createClient = () => {
1537
1569
  const queryStore = createQueryStore();
1538
1570
  const invalidationClient = createInvalidationClient({ queryStore });
1539
1571
  const cacheClient = createCacheClient({ queryStore });
1540
- const refetchClient = createRefetchClient({ queryStore });
1541
- const query$ = ({
1572
+ const refetchClient = createRefetchClient();
1573
+ let hasCalledStart = false;
1574
+ const query = ({
1542
1575
  key,
1543
1576
  fn$: maybeFn$,
1544
1577
  fn: maybeFn,
1545
- refetch$ = new rxjs.Subject(),
1578
+ trigger$: externalTrigger$ = new rxjs.Subject(),
1546
1579
  options$ = new rxjs.BehaviorSubject({})
1547
1580
  }) => {
1581
+ if (!hasCalledStart) {
1582
+ throw new Error("You forgot to start client");
1583
+ }
1548
1584
  const serializedKey = serializeKey(key);
1549
- const internalRefetch$ = new rxjs.Subject();
1550
1585
  const fn$ = maybeFn$ ?? (maybeFn ? rxjs.of(maybeFn) : rxjs.NEVER);
1551
- Logger.log("query$()", serializedKey);
1586
+ Logger.log("query$)", serializedKey);
1552
1587
  const runner$ = options$.pipe(rxjs.map((options) => ({ options })));
1553
1588
  let deleteRunner = () => {
1554
1589
  };
1555
- const initialTrigger$ = rxjs.of({
1556
- type: "initial",
1557
- ignoreStale: false
1558
- });
1559
- const trigger$ = createQueryTrigger({
1560
- options$,
1561
- refetch$: rxjs.merge(refetch$, internalRefetch$),
1562
- key: serializedKey,
1563
- queryStore
1564
- }).pipe(refetchClient.pipeQueryTrigger({ options$, key: serializedKey }));
1565
- const result$ = rxjs.merge(
1566
- initialTrigger$.pipe(
1567
- updateStoreWithNewQuery({
1568
- key,
1590
+ const trigger$ = rxjs.merge(
1591
+ externalTrigger$.pipe(
1592
+ dispatchExternalRefetchToAllQueries({
1569
1593
  queryStore,
1570
- runner$,
1571
- serializedKey,
1572
- options$
1573
- }),
1574
- rxjs.map(([value, deleteRunnerFn]) => {
1575
- deleteRunner = deleteRunnerFn;
1576
- return value;
1594
+ serializedKey
1577
1595
  })
1578
1596
  ),
1597
+ createQueryTrigger({
1598
+ options$,
1599
+ key: serializedKey,
1600
+ queryStore
1601
+ })
1602
+ ).pipe(rxjs.share());
1603
+ const result$ = rxjs.merge(
1604
+ rxjs.of({
1605
+ type: "initial"
1606
+ }),
1579
1607
  trigger$
1580
1608
  ).pipe(
1609
+ updateStoreWithNewQuery({
1610
+ key,
1611
+ queryStore,
1612
+ runner$,
1613
+ serializedKey,
1614
+ options$
1615
+ }),
1616
+ rxjs.map(([value, deleteRunnerFn]) => {
1617
+ if (deleteRunnerFn) {
1618
+ deleteRunner = deleteRunnerFn;
1619
+ }
1620
+ return value;
1621
+ }),
1622
+ markQueryAsStaleIfRefetch({
1623
+ key,
1624
+ options$,
1625
+ queryStore,
1626
+ serializedKey
1627
+ }),
1581
1628
  rxjs.withLatestFrom(fn$, options$),
1582
1629
  rxjs.map(([trigger2, fn, options]) => ({ trigger: trigger2, fn, options })),
1583
1630
  rxjs.map((value) => {
1584
- Logger.log("reactjrx", serializedKey, "query trigger", {
1631
+ Logger.log(serializedKey, "query trigger", {
1585
1632
  trigger: value.trigger,
1586
1633
  options: value.options
1587
1634
  });
@@ -1599,19 +1646,6 @@ const createClient = () => {
1599
1646
  trigger$
1600
1647
  })
1601
1648
  ),
1602
- // hooks
1603
- rxjs.switchMap(
1604
- (result) => rxjs.merge(
1605
- rxjs.of(result).pipe(
1606
- refetchClient.pipeQueryResult({
1607
- key: serializedKey,
1608
- queryStore,
1609
- options$,
1610
- refetch$: internalRefetch$
1611
- })
1612
- )
1613
- )
1614
- ),
1615
1649
  mergeResults,
1616
1650
  rxjs.withLatestFrom(options$),
1617
1651
  rxjs.takeWhile(([result, options]) => {
@@ -1647,6 +1681,7 @@ const createClient = () => {
1647
1681
  )
1648
1682
  );
1649
1683
  const start = () => {
1684
+ hasCalledStart = true;
1650
1685
  const queryListenerSub = queryListener$.subscribe();
1651
1686
  const started = [queryStore.start()];
1652
1687
  return () => {
@@ -1658,7 +1693,7 @@ const createClient = () => {
1658
1693
  };
1659
1694
  return {
1660
1695
  start,
1661
- query$,
1696
+ query,
1662
1697
  queryStore,
1663
1698
  ...invalidationClient,
1664
1699
  ...cacheClient,
package/dist/index.js CHANGED
@@ -470,7 +470,9 @@ const mergeResults = (stream$) => stream$.pipe(
470
470
  status: "loading"
471
471
  }
472
472
  ),
473
- distinctUntilChanged(shallowEqual)
473
+ distinctUntilChanged(
474
+ ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
475
+ )
474
476
  );
475
477
  function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
476
478
  const queryRef = useLiveRef(query);
@@ -636,10 +638,16 @@ const createActivityTrigger = (params$) => {
636
638
  return shouldRunTrigger !== false ? merge(
637
639
  fromEvent(document, "visibilitychange").pipe(
638
640
  filter(() => !document.hidden),
639
- map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
641
+ map(() => ({
642
+ type: "refetch",
643
+ ignoreStale: shouldRunTrigger === "always"
644
+ }))
640
645
  ),
641
646
  fromEvent(window, "focus").pipe(
642
- map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
647
+ map(() => ({
648
+ type: "refetch",
649
+ ignoreStale: shouldRunTrigger === "always"
650
+ }))
643
651
  )
644
652
  ) : EMPTY;
645
653
  })
@@ -650,7 +658,10 @@ const createNetworkTrigger = (params$) => {
650
658
  switchMap(({ options: { refetchOnReconnect = true } }) => {
651
659
  const shouldRunTrigger = typeof refetchOnReconnect === "function" ? refetchOnReconnect({}) : refetchOnReconnect;
652
660
  return shouldRunTrigger !== false ? fromEvent(window, "online").pipe(
653
- map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
661
+ map(() => ({
662
+ type: "refetch",
663
+ ignoreStale: shouldRunTrigger === "always"
664
+ }))
654
665
  ) : EMPTY;
655
666
  })
656
667
  );
@@ -712,18 +723,18 @@ function useQuery({
712
723
  newKeyTrigger$,
713
724
  newObservableObjectQuery$
714
725
  );
715
- const refetch$ = merge(
716
- internalRefresh$.current.pipe(map(() => ({ ignoreStale: true }))),
726
+ const trigger$ = merge(
727
+ internalRefresh$.current,
717
728
  merge(activityRefetch$, networkRefetch$).pipe(throttleTime(500))
718
729
  );
719
730
  return newQueryTrigger$.pipe(
720
731
  withLatestFrom(key$),
721
732
  switchMap(([, key]) => {
722
- const { result$ } = client.query$({
733
+ const { result$ } = client.query({
723
734
  key,
724
735
  fn$,
725
736
  options$,
726
- refetch$
737
+ trigger$
727
738
  });
728
739
  return result$.pipe(
729
740
  scan(
@@ -760,7 +771,7 @@ function useQuery({
760
771
  [client]
761
772
  );
762
773
  const refetch = useCallback(() => {
763
- internalRefresh$.current.next();
774
+ internalRefresh$.current.next({ type: "refetch", ignoreStale: true });
764
775
  }, [client]);
765
776
  return { ...result, refetch };
766
777
  }
@@ -971,7 +982,6 @@ const createQueryStore = () => {
971
982
  };
972
983
  };
973
984
  const createQueryTrigger = ({
974
- refetch$,
975
985
  options$,
976
986
  queryStore,
977
987
  key
@@ -989,12 +999,6 @@ const createQueryTrigger = ({
989
999
  filter((event) => key === event.key),
990
1000
  map(({ trigger: trigger2 }) => trigger2)
991
1001
  ),
992
- refetch$.pipe(
993
- map((event) => ({
994
- ...event,
995
- type: "refetch"
996
- }))
997
- ),
998
1002
  enabledTrigger$.pipe(
999
1003
  map(() => ({
1000
1004
  type: "enabled",
@@ -1009,12 +1013,18 @@ const deduplicate = (key, queryStore) => (source) => {
1009
1013
  return defer(() => {
1010
1014
  var _a;
1011
1015
  const sourceFromStore = (_a = queryStore.get(key)) == null ? void 0 : _a.deduplication_fn;
1016
+ if (sourceFromStore)
1017
+ return sourceFromStore;
1018
+ let sourceToDeduplicate;
1012
1019
  const deleteFromStore = () => {
1013
- queryStore.update(key, {
1014
- deduplication_fn: void 0
1015
- });
1020
+ var _a2;
1021
+ if (((_a2 = queryStore.get(key)) == null ? void 0 : _a2.deduplication_fn) === sourceToDeduplicate) {
1022
+ queryStore.update(key, {
1023
+ deduplication_fn: void 0
1024
+ });
1025
+ }
1016
1026
  };
1017
- const finalSource = sourceFromStore ?? source.pipe(
1027
+ sourceToDeduplicate = source.pipe(
1018
1028
  /**
1019
1029
  * Ideally we would want to remove the query from the store only on finalize,
1020
1030
  * which means whenever the query complete or error. Unfortunately finalize is
@@ -1034,12 +1044,10 @@ const deduplicate = (key, queryStore) => (source) => {
1034
1044
  bufferSize: 1
1035
1045
  })
1036
1046
  );
1037
- if (!sourceFromStore) {
1038
- queryStore.update(key, {
1039
- deduplication_fn: finalSource
1040
- });
1041
- }
1042
- return finalSource;
1047
+ queryStore.update(key, {
1048
+ deduplication_fn: sourceToDeduplicate
1049
+ });
1050
+ return sourceToDeduplicate;
1043
1051
  });
1044
1052
  };
1045
1053
  const notifyQueryResult = (options$) => (stream$) => stream$.pipe(
@@ -1163,8 +1171,9 @@ const createQueryFetch = ({
1163
1171
  const query = queryStore.get(serializedKey);
1164
1172
  const cacheResult = query == null ? void 0 : query.cache_fnResult;
1165
1173
  const hasCache = !!cacheResult;
1174
+ const ignoreStale = trigger2.type === "refetch" && trigger2.ignoreStale;
1166
1175
  if (hasCache) {
1167
- if (!(query == null ? void 0 : query.isStale) && !trigger2.ignoreStale) {
1176
+ if (!(query == null ? void 0 : query.isStale) && !ignoreStale) {
1168
1177
  return of({
1169
1178
  fetchStatus: "idle",
1170
1179
  status: "success",
@@ -1234,6 +1243,9 @@ const createInvalidationClient = ({
1234
1243
  keysToRefetch = Array.from(queryStore.keys());
1235
1244
  }
1236
1245
  keysToRefetch.forEach((key) => {
1246
+ queryStore.update(key, {
1247
+ deduplication_fn: void 0
1248
+ });
1237
1249
  queryStore.dispatchQueryTrigger({
1238
1250
  key,
1239
1251
  trigger: { ignoreStale: true, type: "refetch" }
@@ -1244,10 +1256,7 @@ const createInvalidationClient = ({
1244
1256
  invalidateQueries
1245
1257
  };
1246
1258
  };
1247
- const logger$1 = Logger.namespace("refetch");
1248
- const createRefetchClient = ({
1249
- queryStore
1250
- }) => {
1259
+ const createRefetchClient = (_) => {
1251
1260
  const pipeQueryResult = ({
1252
1261
  options$
1253
1262
  }) => (stream) => {
@@ -1277,26 +1286,11 @@ const createRefetchClient = ({
1277
1286
  )
1278
1287
  );
1279
1288
  };
1280
- const pipeQueryTrigger = ({
1281
- key
1282
- }) => (stream) => {
1283
- return merge(
1284
- stream.pipe(
1285
- tap(({ ignoreStale }) => {
1286
- const query = queryStore.get(key);
1287
- if (query && ignoreStale && !query.isStale) {
1288
- logger$1.log(key, "marked stale by trigger!");
1289
- queryStore.update(key, {
1290
- isStale: true
1291
- });
1292
- }
1293
- })
1294
- )
1295
- );
1289
+ const refetchQueries = (_2) => {
1296
1290
  };
1297
1291
  return {
1298
1292
  pipeQueryResult,
1299
- pipeQueryTrigger
1293
+ refetchQueries
1300
1294
  };
1301
1295
  };
1302
1296
  const difference = (a, b) => a.filter((element) => !b.includes(element));
@@ -1470,10 +1464,11 @@ const updateStoreWithNewQuery = ({
1470
1464
  key
1471
1465
  }) => (stream) => stream.pipe(
1472
1466
  withLatestFrom(options$),
1473
- map(([value, options]) => {
1467
+ map(([trigger2, options]) => {
1474
1468
  if (key.length === 0)
1475
- return [value, () => {
1476
- }];
1469
+ return [trigger2, void 0];
1470
+ if (trigger2.type !== "initial")
1471
+ return [trigger2, void 0];
1477
1472
  if (!queryStore.get(serializedKey)) {
1478
1473
  queryStore.set(serializedKey, getInitialQueryEntity({ key }));
1479
1474
  } else {
@@ -1484,10 +1479,10 @@ const updateStoreWithNewQuery = ({
1484
1479
  }
1485
1480
  });
1486
1481
  }
1487
- return [value, queryStore.addRunner(serializedKey, runner$)];
1482
+ return [trigger2, queryStore.addRunner(serializedKey, runner$)];
1488
1483
  })
1489
1484
  );
1490
- const logger = Logger.namespace("cache");
1485
+ const logger$1 = Logger.namespace("cache");
1491
1486
  const createCacheClient = ({
1492
1487
  queryStore
1493
1488
  }) => {
@@ -1498,7 +1493,7 @@ const createCacheClient = ({
1498
1493
  const serializedKey = serializeKey(queryKey);
1499
1494
  if (queryKey.length === 0)
1500
1495
  return;
1501
- logger.log("set cache for query", serializeKey);
1496
+ logger$1.log("set cache for query", serializeKey);
1502
1497
  if (!queryStore.get(serializedKey)) {
1503
1498
  queryStore.set(serializedKey, getInitialQueryEntity({ key: queryKey }));
1504
1499
  }
@@ -1531,55 +1526,107 @@ const createCacheClient = ({
1531
1526
  setQueryData
1532
1527
  };
1533
1528
  };
1529
+ const logger = Logger.namespace("refetch");
1530
+ const markQueryAsStaleIfRefetch = ({
1531
+ key,
1532
+ serializedKey,
1533
+ queryStore
1534
+ }) => (stream) => {
1535
+ return stream.pipe(
1536
+ tap((trigger2) => {
1537
+ if (trigger2.type !== "refetch")
1538
+ return;
1539
+ const query = queryStore.get(serializedKey);
1540
+ if (query && trigger2.ignoreStale && !query.isStale) {
1541
+ logger.log(key, "marked stale by trigger!");
1542
+ queryStore.update(serializedKey, {
1543
+ isStale: true
1544
+ });
1545
+ }
1546
+ })
1547
+ );
1548
+ };
1549
+ const dispatchExternalRefetchToAllQueries = ({
1550
+ queryStore,
1551
+ serializedKey
1552
+ }) => (stream) => stream.pipe(
1553
+ tap((trigger2) => {
1554
+ if (trigger2.type === "refetch") {
1555
+ queryStore.update(serializedKey, {
1556
+ deduplication_fn: void 0
1557
+ });
1558
+ queryStore.dispatchQueryTrigger({
1559
+ key: serializedKey,
1560
+ trigger: trigger2
1561
+ });
1562
+ }
1563
+ }),
1564
+ filter((trigger2) => trigger2.type !== "refetch")
1565
+ );
1534
1566
  const createClient = () => {
1535
1567
  const queryStore = createQueryStore();
1536
1568
  const invalidationClient = createInvalidationClient({ queryStore });
1537
1569
  const cacheClient = createCacheClient({ queryStore });
1538
- const refetchClient = createRefetchClient({ queryStore });
1539
- const query$ = ({
1570
+ const refetchClient = createRefetchClient();
1571
+ let hasCalledStart = false;
1572
+ const query = ({
1540
1573
  key,
1541
1574
  fn$: maybeFn$,
1542
1575
  fn: maybeFn,
1543
- refetch$ = new Subject(),
1576
+ trigger$: externalTrigger$ = new Subject(),
1544
1577
  options$ = new BehaviorSubject({})
1545
1578
  }) => {
1579
+ if (!hasCalledStart) {
1580
+ throw new Error("You forgot to start client");
1581
+ }
1546
1582
  const serializedKey = serializeKey(key);
1547
- const internalRefetch$ = new Subject();
1548
1583
  const fn$ = maybeFn$ ?? (maybeFn ? of(maybeFn) : NEVER);
1549
- Logger.log("query$()", serializedKey);
1584
+ Logger.log("query$)", serializedKey);
1550
1585
  const runner$ = options$.pipe(map((options) => ({ options })));
1551
1586
  let deleteRunner = () => {
1552
1587
  };
1553
- const initialTrigger$ = of({
1554
- type: "initial",
1555
- ignoreStale: false
1556
- });
1557
- const trigger$ = createQueryTrigger({
1558
- options$,
1559
- refetch$: merge(refetch$, internalRefetch$),
1560
- key: serializedKey,
1561
- queryStore
1562
- }).pipe(refetchClient.pipeQueryTrigger({ options$, key: serializedKey }));
1563
- const result$ = merge(
1564
- initialTrigger$.pipe(
1565
- updateStoreWithNewQuery({
1566
- key,
1588
+ const trigger$ = merge(
1589
+ externalTrigger$.pipe(
1590
+ dispatchExternalRefetchToAllQueries({
1567
1591
  queryStore,
1568
- runner$,
1569
- serializedKey,
1570
- options$
1571
- }),
1572
- map(([value, deleteRunnerFn]) => {
1573
- deleteRunner = deleteRunnerFn;
1574
- return value;
1592
+ serializedKey
1575
1593
  })
1576
1594
  ),
1595
+ createQueryTrigger({
1596
+ options$,
1597
+ key: serializedKey,
1598
+ queryStore
1599
+ })
1600
+ ).pipe(share());
1601
+ const result$ = merge(
1602
+ of({
1603
+ type: "initial"
1604
+ }),
1577
1605
  trigger$
1578
1606
  ).pipe(
1607
+ updateStoreWithNewQuery({
1608
+ key,
1609
+ queryStore,
1610
+ runner$,
1611
+ serializedKey,
1612
+ options$
1613
+ }),
1614
+ map(([value, deleteRunnerFn]) => {
1615
+ if (deleteRunnerFn) {
1616
+ deleteRunner = deleteRunnerFn;
1617
+ }
1618
+ return value;
1619
+ }),
1620
+ markQueryAsStaleIfRefetch({
1621
+ key,
1622
+ options$,
1623
+ queryStore,
1624
+ serializedKey
1625
+ }),
1579
1626
  withLatestFrom(fn$, options$),
1580
1627
  map(([trigger2, fn, options]) => ({ trigger: trigger2, fn, options })),
1581
1628
  map((value) => {
1582
- Logger.log("reactjrx", serializedKey, "query trigger", {
1629
+ Logger.log(serializedKey, "query trigger", {
1583
1630
  trigger: value.trigger,
1584
1631
  options: value.options
1585
1632
  });
@@ -1597,19 +1644,6 @@ const createClient = () => {
1597
1644
  trigger$
1598
1645
  })
1599
1646
  ),
1600
- // hooks
1601
- switchMap(
1602
- (result) => merge(
1603
- of(result).pipe(
1604
- refetchClient.pipeQueryResult({
1605
- key: serializedKey,
1606
- queryStore,
1607
- options$,
1608
- refetch$: internalRefetch$
1609
- })
1610
- )
1611
- )
1612
- ),
1613
1647
  mergeResults,
1614
1648
  withLatestFrom(options$),
1615
1649
  takeWhile(([result, options]) => {
@@ -1645,6 +1679,7 @@ const createClient = () => {
1645
1679
  )
1646
1680
  );
1647
1681
  const start = () => {
1682
+ hasCalledStart = true;
1648
1683
  const queryListenerSub = queryListener$.subscribe();
1649
1684
  const started = [queryStore.start()];
1650
1685
  return () => {
@@ -1656,7 +1691,7 @@ const createClient = () => {
1656
1691
  };
1657
1692
  return {
1658
1693
  start,
1659
- query$,
1694
+ query,
1660
1695
  queryStore,
1661
1696
  ...invalidationClient,
1662
1697
  ...cacheClient,
@@ -26,10 +26,9 @@ export declare const createClient: () => {
26
26
  options$: Observable<QueryOptions<T>>;
27
27
  refetch$: Observable<QueryTrigger>;
28
28
  }) => import("rxjs").MonoTypeOperatorFunction<R>;
29
- pipeQueryTrigger: <T_4>({ key }: {
30
- key: string;
31
- options$: Observable<QueryOptions<T_4>>;
32
- }) => import("rxjs").MonoTypeOperatorFunction<QueryTrigger>;
29
+ refetchQueries: (_: {
30
+ queryKey: QueryKey;
31
+ }) => void;
33
32
  setQueryData: ({ queryKey, updater }: {
34
33
  queryKey: QueryKey;
35
34
  updater: unknown;
@@ -40,16 +39,14 @@ export declare const createClient: () => {
40
39
  predicate?: ((storeObject: import("./store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
41
40
  }) => void;
42
41
  start: () => () => void;
43
- query$: <T_5>({ key, fn$: maybeFn$, fn: maybeFn, refetch$, options$ }: {
42
+ query: <T_4>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
44
43
  key: QueryKey;
45
- fn?: QueryFn<T_5> | undefined;
46
- fn$?: Observable<QueryFn<T_5>> | undefined;
47
- refetch$?: Observable<{
48
- ignoreStale: boolean;
49
- }> | undefined;
50
- options$?: Observable<QueryOptions<T_5>> | undefined;
44
+ fn?: QueryFn<T_4> | undefined;
45
+ fn$?: Observable<QueryFn<T_4>> | undefined;
46
+ trigger$?: Observable<QueryTrigger> | undefined;
47
+ options$?: Observable<QueryOptions<T_4>> | undefined;
51
48
  }) => {
52
- result$: Observable<QueryResult<T_5>>;
49
+ result$: Observable<QueryResult<T_4>>;
53
50
  };
54
51
  queryStore: {
55
52
  set: (key: string, value: import("./store/createQueryStore").StoreObject<unknown>) => void;
@@ -1,7 +1,8 @@
1
1
  import { type MonoTypeOperatorFunction, type Observable } from "rxjs";
2
2
  import { type createQueryStore } from "../store/createQueryStore";
3
3
  import { type QueryTrigger, type QueryOptions, type QueryResult } from "../types";
4
- export declare const createRefetchClient: ({ queryStore }: {
4
+ import { type QueryKey } from "../keys/types";
5
+ export declare const createRefetchClient: (_: {
5
6
  queryStore: ReturnType<typeof createQueryStore>;
6
7
  }) => {
7
8
  pipeQueryResult: <R extends Partial<QueryResult<T>>, T>({ options$ }: {
@@ -10,8 +11,7 @@ export declare const createRefetchClient: ({ queryStore }: {
10
11
  options$: Observable<QueryOptions<T>>;
11
12
  refetch$: Observable<QueryTrigger>;
12
13
  }) => MonoTypeOperatorFunction<R>;
13
- pipeQueryTrigger: <T_1>({ key }: {
14
- key: string;
15
- options$: Observable<QueryOptions<T_1>>;
16
- }) => MonoTypeOperatorFunction<QueryTrigger>;
14
+ refetchQueries: (_: {
15
+ queryKey: QueryKey;
16
+ }) => void;
17
17
  };
@@ -0,0 +1,3 @@
1
+ import { type MonoTypeOperatorFunction } from "rxjs";
2
+ import { type QueryPipelineParams, type QueryTrigger } from "../types";
3
+ export declare const dispatchExternalRefetchToAllQueries: <R>({ queryStore, serializedKey }: Pick<QueryPipelineParams<R>, "queryStore" | "serializedKey">) => MonoTypeOperatorFunction<QueryTrigger>;
@@ -0,0 +1,24 @@
1
+ export declare const logger: {
2
+ namespaces: {
3
+ name: string;
4
+ style: {
5
+ backgroundColor: string;
6
+ color: string;
7
+ };
8
+ }[];
9
+ namespace(name: string, style?: {
10
+ backgroundColor: string;
11
+ color: string;
12
+ } | undefined): any;
13
+ printNamespaces(): {
14
+ namespaces: string;
15
+ styles: string[];
16
+ };
17
+ print(method: "log" | "warn" | "error" | "group", ...message: any[]): any;
18
+ printWithoutNamespace(method: "log" | "warn" | "error" | "group", ...message: any[]): any;
19
+ log(...message: any): any;
20
+ warn(...message: any): any;
21
+ error(...message: any): any;
22
+ group(...message: any): any;
23
+ groupEnd(): any;
24
+ };
@@ -0,0 +1,3 @@
1
+ import { type MonoTypeOperatorFunction } from "rxjs";
2
+ import { type QueryPipelineParams, type QueryTrigger } from "../types";
3
+ export declare const markQueryAsStaleIfRefetch: <T>({ key, serializedKey, queryStore }: QueryPipelineParams<T>) => MonoTypeOperatorFunction<QueryTrigger>;
@@ -1,7 +1,10 @@
1
1
  import { type OperatorFunction, type Observable } from "rxjs";
2
- import { type QueryPipelineParams, type QueryOptions } from "../types";
3
- export declare const updateStoreWithNewQuery: <T, R>({ queryStore, serializedKey, runner$, options$, key }: QueryPipelineParams<R> & {
2
+ import { type QueryPipelineParams, type QueryOptions, type QueryTrigger } from "../types";
3
+ export declare const updateStoreWithNewQuery: <R>({ queryStore, serializedKey, runner$, options$, key }: QueryPipelineParams<R> & {
4
4
  runner$: Observable<{
5
5
  options: QueryOptions<R>;
6
6
  }>;
7
- }) => OperatorFunction<T, [T, () => void]>;
7
+ }) => OperatorFunction<QueryTrigger, [
8
+ QueryTrigger,
9
+ (() => void) | undefined
10
+ ]>;
@@ -1,17 +1,8 @@
1
1
  import { type Observable } from "rxjs";
2
- import { type QueryOptions } from "./types";
2
+ import { type QueryTrigger, type QueryOptions } from "./types";
3
3
  import { type QueryStore } from "./store/createQueryStore";
4
- export declare const createQueryTrigger: <T>({ refetch$, options$, queryStore, key }: {
5
- refetch$: Observable<{
6
- ignoreStale: boolean;
7
- }>;
4
+ export declare const createQueryTrigger: <T>({ options$, queryStore, key }: {
8
5
  options$: Observable<QueryOptions<T>>;
9
6
  queryStore: QueryStore;
10
7
  key: string;
11
- }) => Observable<import("./types").QueryTrigger | {
12
- type: string;
13
- ignoreStale: boolean;
14
- } | {
15
- type: string;
16
- ignoreStale: boolean;
17
- }>;
8
+ }) => Observable<QueryTrigger>;
@@ -26,10 +26,20 @@ export interface QueryPipelineParams<R> {
26
26
  key: QueryKey;
27
27
  options$: Observable<QueryOptions<R>>;
28
28
  }
29
- export interface QueryTrigger {
30
- type: string;
29
+ /**
30
+ * Events that trigger stream chain of query.
31
+ * What will happens then depends of what event is triggered
32
+ * and subsequent variables. This is just standardized way
33
+ * of what trigger a query.
34
+ */
35
+ export type QueryTrigger = {
36
+ type: "initial";
37
+ } | {
38
+ type: "refetch";
31
39
  ignoreStale: boolean;
32
- }
40
+ } | {
41
+ type: "enabled";
42
+ };
33
43
  export interface QueryOptions<T = unknown> {
34
44
  enabled?: boolean;
35
45
  retry?: false | number | ((attempt: number, error: unknown) => boolean);
@@ -32,10 +32,9 @@ export declare const useQueryClient: () => {
32
32
  options$: import("rxjs").Observable<import("../client/types").QueryOptions<T>>;
33
33
  refetch$: import("rxjs").Observable<import("../client/types").QueryTrigger>;
34
34
  }) => import("rxjs").MonoTypeOperatorFunction<R>;
35
- pipeQueryTrigger: <T_4>({ key }: {
36
- key: string;
37
- options$: import("rxjs").Observable<import("../client/types").QueryOptions<T_4>>;
38
- }) => import("rxjs").MonoTypeOperatorFunction<import("../client/types").QueryTrigger>;
35
+ refetchQueries: (_: {
36
+ queryKey: import("../client/keys/types").QueryKey;
37
+ }) => void;
39
38
  setQueryData: ({ queryKey, updater }: {
40
39
  queryKey: import("../client/keys/types").QueryKey;
41
40
  updater: unknown;
@@ -46,16 +45,14 @@ export declare const useQueryClient: () => {
46
45
  predicate?: ((storeObject: import("../client/store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
47
46
  }) => void;
48
47
  start: () => () => void;
49
- query$: <T_5>({ key, fn$: maybeFn$, fn: maybeFn, refetch$, options$ }: {
48
+ query: <T_4>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
50
49
  key: import("../client/keys/types").QueryKey;
51
- fn?: import("../client/types").QueryFn<T_5> | undefined;
52
- fn$?: import("rxjs").Observable<import("../client/types").QueryFn<T_5>> | undefined;
53
- refetch$?: import("rxjs").Observable<{
54
- ignoreStale: boolean;
55
- }> | undefined;
56
- options$?: import("rxjs").Observable<import("../client/types").QueryOptions<T_5>> | undefined;
50
+ fn?: import("../client/types").QueryFn<T_4> | undefined;
51
+ fn$?: import("rxjs").Observable<import("../client/types").QueryFn<T_4>> | undefined;
52
+ trigger$?: import("rxjs").Observable<import("../client/types").QueryTrigger> | undefined;
53
+ options$?: import("rxjs").Observable<import("../client/types").QueryOptions<T_4>> | undefined;
57
54
  }) => {
58
- result$: import("rxjs").Observable<import("../client/types").QueryResult<T_5>>;
55
+ result$: import("rxjs").Observable<import("../client/types").QueryResult<T_4>>;
59
56
  };
60
57
  queryStore: {
61
58
  set: (key: string, value: import("../client/store/createQueryStore").StoreObject<unknown>) => void;
@@ -3,7 +3,9 @@ import { type UseQueryOptions } from "../types";
3
3
  export declare const createActivityTrigger: <T>(params$: Observable<{
4
4
  options: UseQueryOptions<T>;
5
5
  }>) => Observable<{
6
+ type: "refetch";
6
7
  ignoreStale: boolean;
7
8
  } | {
9
+ type: "refetch";
8
10
  ignoreStale: boolean;
9
11
  }>;
@@ -3,5 +3,6 @@ import { type UseQueryOptions } from "../types";
3
3
  export declare const createNetworkTrigger: <T>(params$: Observable<{
4
4
  options: UseQueryOptions<T>;
5
5
  }>) => Observable<{
6
+ type: "refetch";
6
7
  ignoreStale: boolean;
7
8
  }>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.41.0",
4
+ "version": "1.44.1",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"