reactjrx 1.61.0 → 1.62.0

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
@@ -465,7 +465,9 @@ function useMutation(options, queryClient) {
465
465
  const defaultKey = useConstant(() => [nanoid()]);
466
466
  const key = serializeKey(options.mutationKey ?? defaultKey.current);
467
467
  const observedMutation = react.useMemo(
468
- () => finalQueryClient.mutationClient.observe({ key }),
468
+ () => finalQueryClient.mutationClient.mutationResultObserver.observe({
469
+ key
470
+ }),
469
471
  [key]
470
472
  );
471
473
  const result = useObserve(observedMutation.result$) ?? observedMutation.lastValue;
@@ -1468,47 +1470,38 @@ const dispatchExternalRefetchToAllQueries = ({
1468
1470
  }),
1469
1471
  rxjs.filter((trigger2) => trigger2.type !== "refetch")
1470
1472
  );
1471
- const mergeResults = (stream$) => stream$.pipe(
1472
- rxjs.scan(
1473
- (acc, current) => {
1474
- return {
1475
- ...acc,
1476
- ...current,
1477
- data: current.data ?? acc.data,
1478
- error: current.error ?? acc.error
1479
- };
1480
- },
1481
- {
1482
- data: void 0,
1483
- error: void 0,
1484
- status: "pending"
1485
- }
1486
- ),
1487
- rxjs.distinctUntilChanged(
1488
- ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
1489
- )
1490
- );
1491
1473
  const getDefaultMutationState = () => ({
1492
- context: {},
1474
+ context: void 0,
1493
1475
  data: void 0,
1494
1476
  error: null,
1495
1477
  status: "idle",
1496
1478
  submittedAt: 0,
1497
1479
  variables: void 0
1498
1480
  });
1481
+ const mergeResults = (stream$) => stream$.pipe(
1482
+ rxjs.scan((acc, current) => {
1483
+ return {
1484
+ ...acc,
1485
+ ...current,
1486
+ data: current.data ?? acc.data,
1487
+ error: current.error ?? acc.error
1488
+ };
1489
+ }, getDefaultMutationState()),
1490
+ rxjs.distinctUntilChanged(
1491
+ ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
1492
+ )
1493
+ );
1499
1494
  class Mutation {
1500
1495
  constructor({
1501
1496
  args,
1502
1497
  ...options
1503
1498
  }) {
1504
- __publicField(this, "stateSubject", new rxjs.BehaviorSubject(
1505
- getDefaultMutationState()
1506
- ));
1499
+ __publicField(this, "stateSubject", new rxjs.ReplaySubject(1));
1507
1500
  /**
1508
1501
  * @important
1509
- * proxy for rect-query, not really useful
1502
+ * convenience over usage of stateSubject for sync access
1510
1503
  */
1511
- __publicField(this, "state", this.stateSubject.getValue());
1504
+ __publicField(this, "state", getDefaultMutationState());
1512
1505
  __publicField(this, "options");
1513
1506
  __publicField(this, "mutation$");
1514
1507
  this.options = options;
@@ -1528,11 +1521,13 @@ class Mutation {
1528
1521
  return rxjs.of({ data: error, isError: true });
1529
1522
  })
1530
1523
  );
1531
- const loading$ = rxjs.of({
1532
- status: "pending"
1524
+ const initState$ = rxjs.of({
1525
+ ...this.state,
1526
+ status: "pending",
1527
+ submittedAt: (/* @__PURE__ */ new Date()).getTime()
1533
1528
  });
1534
1529
  this.mutation$ = rxjs.merge(
1535
- loading$,
1530
+ initState$,
1536
1531
  queryRunner$.pipe(
1537
1532
  rxjs.map(({ data, isError }) => {
1538
1533
  if (!isError) {
@@ -1648,7 +1643,8 @@ const createMutationRunner = ({
1648
1643
  __queryTriggerHook ?? rxjs.identity
1649
1644
  );
1650
1645
  }),
1651
- __queryFinalizeHook ?? rxjs.identity
1646
+ __queryFinalizeHook ?? rxjs.identity,
1647
+ rxjs.shareReplay(1)
1652
1648
  );
1653
1649
  cancel$.subscribe(() => {
1654
1650
  if (mutationsSubject.getValue().length === 0)
@@ -1680,31 +1676,109 @@ const createPredicateForFilters = ({
1680
1676
  serializeKey(mutation.options.mutationKey) !== serializeKey(mutationKey)) {
1681
1677
  return false;
1682
1678
  }
1683
- if (status && mutation.stateSubject.getValue().status !== status)
1679
+ if (status && mutation.state.status !== status)
1684
1680
  return false;
1685
1681
  return true;
1686
1682
  };
1687
1683
  const finalPredicate = predicate ?? defaultPredicate;
1688
1684
  return finalPredicate;
1689
1685
  };
1690
- class MutationClient {
1691
- constructor() {
1686
+ class MutationResultObserver {
1687
+ constructor(mutationRunnersByKey$) {
1692
1688
  /**
1693
- * Contain all active mutation for a given key.
1694
- * A mutation ca have several triggers running (it is not necessarily one function running)
1689
+ * Mutation result subject. It can be used whether there is a mutation
1690
+ * running or not and can be directly observed.
1695
1691
  *
1696
1692
  * @important
1697
1693
  * - automatically cleaned as soon as the last mutation is done for a given key
1698
1694
  */
1699
- __publicField(this, "mutationRunnersByKey$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
1695
+ __publicField(this, "mutationResults$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
1696
+ mutationRunnersByKey$.pipe(
1697
+ rxjs.switchMap((mapItem) => {
1698
+ const runners = Array.from(mapItem.values()).map((runner) => {
1699
+ const serializedMutationKey = serializeKey(runner.mutationKey);
1700
+ return runner.mutation$.pipe(
1701
+ rxjs.tap((result) => {
1702
+ this.updateResultForKey({
1703
+ serializedMutationKey,
1704
+ result
1705
+ });
1706
+ }),
1707
+ rxjs.finalize(() => {
1708
+ this.deleteResultForKey({ serializedMutationKey });
1709
+ })
1710
+ );
1711
+ });
1712
+ return rxjs.merge(...runners);
1713
+ })
1714
+ ).subscribe();
1715
+ }
1716
+ getDefaultResultValue() {
1717
+ return {
1718
+ ...getDefaultMutationState(),
1719
+ isSuccess: false,
1720
+ isPending: false,
1721
+ isIdle: true,
1722
+ isError: false
1723
+ };
1724
+ }
1725
+ deleteResultForKey({
1726
+ serializedMutationKey
1727
+ }) {
1728
+ const resultMap = this.mutationResults$.getValue();
1729
+ resultMap.delete(serializedMutationKey);
1730
+ this.mutationResults$.next(resultMap);
1731
+ }
1732
+ updateResultForKey({
1733
+ serializedMutationKey,
1734
+ result
1735
+ }) {
1736
+ const resultForKeySubject = this.mutationResults$.getValue().get(serializedMutationKey);
1737
+ const valueForResult = {
1738
+ ...this.getDefaultResultValue(),
1739
+ ...result,
1740
+ isSuccess: result.status === "success",
1741
+ isPending: result.status === "pending",
1742
+ isIdle: result.status === "idle",
1743
+ isError: result.status === "error"
1744
+ };
1745
+ if (!resultForKeySubject) {
1746
+ const resultMap = this.mutationResults$.getValue();
1747
+ resultMap.set(
1748
+ serializedMutationKey,
1749
+ new rxjs.BehaviorSubject(valueForResult)
1750
+ );
1751
+ this.mutationResults$.next(resultMap);
1752
+ } else {
1753
+ resultForKeySubject == null ? void 0 : resultForKeySubject.next(valueForResult);
1754
+ }
1755
+ }
1756
+ observe({ key }) {
1757
+ var _a;
1758
+ const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
1759
+ const lastValue = currentResultValue ?? this.getDefaultResultValue();
1760
+ const result$ = this.mutationResults$.pipe(
1761
+ rxjs.switchMap((resultMap) => {
1762
+ const subject = resultMap.get(key);
1763
+ return subject ?? rxjs.EMPTY;
1764
+ })
1765
+ ).pipe(rxjs.filter(isDefined));
1766
+ return { result$, lastValue };
1767
+ }
1768
+ destroy() {
1769
+ this.mutationResults$.complete();
1770
+ }
1771
+ }
1772
+ class MutationClient {
1773
+ constructor() {
1700
1774
  /**
1701
- * Mutation result subject. It can be used whether there is a mutation
1702
- * running or not and can be directly observed.
1775
+ * Contain all active mutation for a given key.
1776
+ * A mutation ca have several triggers running (it is not necessarily one function running)
1703
1777
  *
1704
1778
  * @important
1705
1779
  * - automatically cleaned as soon as the last mutation is done for a given key
1706
1780
  */
1707
- __publicField(this, "mutationResults$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
1781
+ __publicField(this, "mutationRunnersByKey$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
1708
1782
  __publicField(this, "mutate$", new rxjs.Subject());
1709
1783
  __publicField(this, "cancel$", new rxjs.Subject());
1710
1784
  /**
@@ -1715,6 +1789,9 @@ class MutationClient {
1715
1789
  * List of all mutations running
1716
1790
  */
1717
1791
  __publicField(this, "mutationsSubject", new rxjs.BehaviorSubject([]));
1792
+ __publicField(this, "mutationResultObserver", new MutationResultObserver(
1793
+ this.mutationRunnersByKey$
1794
+ ));
1718
1795
  this.mutate$.pipe(
1719
1796
  rxjs.tap(({ options, args }) => {
1720
1797
  const { mutationKey } = options;
@@ -1728,26 +1805,13 @@ class MutationClient {
1728
1805
  mutationKey
1729
1806
  };
1730
1807
  this.setMutationRunnersByKey(serializedMutationKey, mutationForKey);
1731
- mutationForKey.mutation$.subscribe((result) => {
1732
- let resultForKeySubject = this.mutationResults$.getValue().get(serializedMutationKey);
1733
- if (!resultForKeySubject) {
1734
- resultForKeySubject = new rxjs.BehaviorSubject(result);
1735
- const resultMap = this.mutationResults$.getValue();
1736
- resultMap.set(serializedMutationKey, resultForKeySubject);
1737
- this.mutationResults$.next(resultMap);
1738
- } else {
1739
- resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
1740
- }
1741
- });
1808
+ mutationForKey.mutation$.subscribe();
1742
1809
  mutationForKey.mutationsSubject.pipe(
1743
1810
  rxjs.distinctUntilChanged(shallowEqual),
1744
1811
  rxjs.skip(1),
1745
1812
  rxjs.filter((items) => items.length === 0)
1746
1813
  ).subscribe(() => {
1747
1814
  mutationForKey == null ? void 0 : mutationForKey.destroy();
1748
- const resultMap = this.mutationResults$.getValue();
1749
- resultMap.delete(serializedMutationKey);
1750
- this.mutationResults$.next(resultMap);
1751
1815
  this.deleteMutationRunnersByKey(serializedMutationKey);
1752
1816
  });
1753
1817
  }
@@ -1806,7 +1870,7 @@ class MutationClient {
1806
1870
  useIsMutating(filters = {}) {
1807
1871
  const predicate = createPredicateForFilters(filters);
1808
1872
  const reduceByNumber = (entries) => entries.reduce((acc, mutation) => {
1809
- return predicate(mutation) && mutation.stateSubject.getValue().status === "pending" ? 1 + acc : acc;
1873
+ return predicate(mutation) && mutation.state.status === "pending" ? 1 + acc : acc;
1810
1874
  }, 0);
1811
1875
  const lastValue = reduceByNumber(this.mutationsSubject.getValue());
1812
1876
  const value$ = this.mutationsSubject.pipe(
@@ -1826,7 +1890,7 @@ class MutationClient {
1826
1890
  select
1827
1891
  } = {}) {
1828
1892
  const predicate = createPredicateForFilters(filters);
1829
- const finalSelect = select ?? ((mutation) => mutation.stateSubject.getValue());
1893
+ const finalSelect = select ?? ((mutation) => mutation.state);
1830
1894
  const lastValue = this.mutationsSubject.getValue().reduce((acc, mutation) => {
1831
1895
  const result = [...acc, mutation];
1832
1896
  return result;
@@ -1845,40 +1909,6 @@ class MutationClient {
1845
1909
  );
1846
1910
  return { value$, lastValue };
1847
1911
  }
1848
- observe({ key }) {
1849
- var _a;
1850
- const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
1851
- const mapResultToObservedResult = (value) => ({
1852
- ...value,
1853
- isIdle: value.status === "idle",
1854
- isPaused: false,
1855
- isError: value.error !== void 0,
1856
- isPending: false,
1857
- isSuccess: value.status === "success"
1858
- });
1859
- const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
1860
- data: void 0,
1861
- error: void 0,
1862
- status: "idle"
1863
- });
1864
- const result$ = this.mutationResults$.pipe(
1865
- rxjs.switchMap((resultMap) => {
1866
- const subject = resultMap.get(key);
1867
- return subject ?? rxjs.EMPTY;
1868
- })
1869
- ).pipe(
1870
- rxjs.filter(isDefined),
1871
- rxjs.map((value) => ({
1872
- ...value,
1873
- isIdle: value.status === "idle",
1874
- isPaused: false,
1875
- isError: value.error !== void 0,
1876
- isPending: false,
1877
- isSuccess: value.status === "success"
1878
- }))
1879
- );
1880
- return { result$, lastValue };
1881
- }
1882
1912
  mutate(params) {
1883
1913
  this.mutate$.next(params);
1884
1914
  }
@@ -1892,7 +1922,7 @@ class MutationClient {
1892
1922
  destroy() {
1893
1923
  this.cancel$.complete();
1894
1924
  this.mutate$.complete();
1895
- this.mutationResults$.complete();
1925
+ this.mutationResultObserver.destroy();
1896
1926
  this.mutationRunnersByKey$.complete();
1897
1927
  this.isMutatingSubject.complete();
1898
1928
  this.mutationsSubject.complete();
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => {
5
5
  return value;
6
6
  };
7
7
  import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, createContext, memo, useContext } from "react";
8
- import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, map, of, zip, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError, fromEvent, filter, skip, withLatestFrom, scan, retry, shareReplay, endWith, delay, take, takeUntil, share, startWith, pairwise, mergeMap, NEVER, combineLatest, concatMap as concatMap$1, takeWhile } from "rxjs";
8
+ import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, map, of, zip, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError, fromEvent, filter, skip, withLatestFrom, scan, retry, shareReplay, endWith, delay, take, takeUntil, share, startWith, pairwise, mergeMap, NEVER, combineLatest, ReplaySubject, concatMap as concatMap$1, takeWhile } from "rxjs";
9
9
  import { retryWhen, concatMap, tap as tap$1 } from "rxjs/operators";
10
10
  import { jsxs, jsx } from "react/jsx-runtime";
11
11
  const useLiveRef = (value) => {
@@ -463,7 +463,9 @@ function useMutation(options, queryClient) {
463
463
  const defaultKey = useConstant(() => [nanoid()]);
464
464
  const key = serializeKey(options.mutationKey ?? defaultKey.current);
465
465
  const observedMutation = useMemo(
466
- () => finalQueryClient.mutationClient.observe({ key }),
466
+ () => finalQueryClient.mutationClient.mutationResultObserver.observe({
467
+ key
468
+ }),
467
469
  [key]
468
470
  );
469
471
  const result = useObserve(observedMutation.result$) ?? observedMutation.lastValue;
@@ -1466,47 +1468,38 @@ const dispatchExternalRefetchToAllQueries = ({
1466
1468
  }),
1467
1469
  filter((trigger2) => trigger2.type !== "refetch")
1468
1470
  );
1469
- const mergeResults = (stream$) => stream$.pipe(
1470
- scan(
1471
- (acc, current) => {
1472
- return {
1473
- ...acc,
1474
- ...current,
1475
- data: current.data ?? acc.data,
1476
- error: current.error ?? acc.error
1477
- };
1478
- },
1479
- {
1480
- data: void 0,
1481
- error: void 0,
1482
- status: "pending"
1483
- }
1484
- ),
1485
- distinctUntilChanged(
1486
- ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
1487
- )
1488
- );
1489
1471
  const getDefaultMutationState = () => ({
1490
- context: {},
1472
+ context: void 0,
1491
1473
  data: void 0,
1492
1474
  error: null,
1493
1475
  status: "idle",
1494
1476
  submittedAt: 0,
1495
1477
  variables: void 0
1496
1478
  });
1479
+ const mergeResults = (stream$) => stream$.pipe(
1480
+ scan((acc, current) => {
1481
+ return {
1482
+ ...acc,
1483
+ ...current,
1484
+ data: current.data ?? acc.data,
1485
+ error: current.error ?? acc.error
1486
+ };
1487
+ }, getDefaultMutationState()),
1488
+ distinctUntilChanged(
1489
+ ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
1490
+ )
1491
+ );
1497
1492
  class Mutation {
1498
1493
  constructor({
1499
1494
  args,
1500
1495
  ...options
1501
1496
  }) {
1502
- __publicField(this, "stateSubject", new BehaviorSubject(
1503
- getDefaultMutationState()
1504
- ));
1497
+ __publicField(this, "stateSubject", new ReplaySubject(1));
1505
1498
  /**
1506
1499
  * @important
1507
- * proxy for rect-query, not really useful
1500
+ * convenience over usage of stateSubject for sync access
1508
1501
  */
1509
- __publicField(this, "state", this.stateSubject.getValue());
1502
+ __publicField(this, "state", getDefaultMutationState());
1510
1503
  __publicField(this, "options");
1511
1504
  __publicField(this, "mutation$");
1512
1505
  this.options = options;
@@ -1526,11 +1519,13 @@ class Mutation {
1526
1519
  return of({ data: error, isError: true });
1527
1520
  })
1528
1521
  );
1529
- const loading$ = of({
1530
- status: "pending"
1522
+ const initState$ = of({
1523
+ ...this.state,
1524
+ status: "pending",
1525
+ submittedAt: (/* @__PURE__ */ new Date()).getTime()
1531
1526
  });
1532
1527
  this.mutation$ = merge(
1533
- loading$,
1528
+ initState$,
1534
1529
  queryRunner$.pipe(
1535
1530
  map(({ data, isError }) => {
1536
1531
  if (!isError) {
@@ -1646,7 +1641,8 @@ const createMutationRunner = ({
1646
1641
  __queryTriggerHook ?? identity
1647
1642
  );
1648
1643
  }),
1649
- __queryFinalizeHook ?? identity
1644
+ __queryFinalizeHook ?? identity,
1645
+ shareReplay(1)
1650
1646
  );
1651
1647
  cancel$.subscribe(() => {
1652
1648
  if (mutationsSubject.getValue().length === 0)
@@ -1678,31 +1674,109 @@ const createPredicateForFilters = ({
1678
1674
  serializeKey(mutation.options.mutationKey) !== serializeKey(mutationKey)) {
1679
1675
  return false;
1680
1676
  }
1681
- if (status && mutation.stateSubject.getValue().status !== status)
1677
+ if (status && mutation.state.status !== status)
1682
1678
  return false;
1683
1679
  return true;
1684
1680
  };
1685
1681
  const finalPredicate = predicate ?? defaultPredicate;
1686
1682
  return finalPredicate;
1687
1683
  };
1688
- class MutationClient {
1689
- constructor() {
1684
+ class MutationResultObserver {
1685
+ constructor(mutationRunnersByKey$) {
1690
1686
  /**
1691
- * Contain all active mutation for a given key.
1692
- * A mutation ca have several triggers running (it is not necessarily one function running)
1687
+ * Mutation result subject. It can be used whether there is a mutation
1688
+ * running or not and can be directly observed.
1693
1689
  *
1694
1690
  * @important
1695
1691
  * - automatically cleaned as soon as the last mutation is done for a given key
1696
1692
  */
1697
- __publicField(this, "mutationRunnersByKey$", new BehaviorSubject(/* @__PURE__ */ new Map()));
1693
+ __publicField(this, "mutationResults$", new BehaviorSubject(/* @__PURE__ */ new Map()));
1694
+ mutationRunnersByKey$.pipe(
1695
+ switchMap((mapItem) => {
1696
+ const runners = Array.from(mapItem.values()).map((runner) => {
1697
+ const serializedMutationKey = serializeKey(runner.mutationKey);
1698
+ return runner.mutation$.pipe(
1699
+ tap((result) => {
1700
+ this.updateResultForKey({
1701
+ serializedMutationKey,
1702
+ result
1703
+ });
1704
+ }),
1705
+ finalize(() => {
1706
+ this.deleteResultForKey({ serializedMutationKey });
1707
+ })
1708
+ );
1709
+ });
1710
+ return merge(...runners);
1711
+ })
1712
+ ).subscribe();
1713
+ }
1714
+ getDefaultResultValue() {
1715
+ return {
1716
+ ...getDefaultMutationState(),
1717
+ isSuccess: false,
1718
+ isPending: false,
1719
+ isIdle: true,
1720
+ isError: false
1721
+ };
1722
+ }
1723
+ deleteResultForKey({
1724
+ serializedMutationKey
1725
+ }) {
1726
+ const resultMap = this.mutationResults$.getValue();
1727
+ resultMap.delete(serializedMutationKey);
1728
+ this.mutationResults$.next(resultMap);
1729
+ }
1730
+ updateResultForKey({
1731
+ serializedMutationKey,
1732
+ result
1733
+ }) {
1734
+ const resultForKeySubject = this.mutationResults$.getValue().get(serializedMutationKey);
1735
+ const valueForResult = {
1736
+ ...this.getDefaultResultValue(),
1737
+ ...result,
1738
+ isSuccess: result.status === "success",
1739
+ isPending: result.status === "pending",
1740
+ isIdle: result.status === "idle",
1741
+ isError: result.status === "error"
1742
+ };
1743
+ if (!resultForKeySubject) {
1744
+ const resultMap = this.mutationResults$.getValue();
1745
+ resultMap.set(
1746
+ serializedMutationKey,
1747
+ new BehaviorSubject(valueForResult)
1748
+ );
1749
+ this.mutationResults$.next(resultMap);
1750
+ } else {
1751
+ resultForKeySubject == null ? void 0 : resultForKeySubject.next(valueForResult);
1752
+ }
1753
+ }
1754
+ observe({ key }) {
1755
+ var _a;
1756
+ const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
1757
+ const lastValue = currentResultValue ?? this.getDefaultResultValue();
1758
+ const result$ = this.mutationResults$.pipe(
1759
+ switchMap((resultMap) => {
1760
+ const subject = resultMap.get(key);
1761
+ return subject ?? EMPTY;
1762
+ })
1763
+ ).pipe(filter(isDefined));
1764
+ return { result$, lastValue };
1765
+ }
1766
+ destroy() {
1767
+ this.mutationResults$.complete();
1768
+ }
1769
+ }
1770
+ class MutationClient {
1771
+ constructor() {
1698
1772
  /**
1699
- * Mutation result subject. It can be used whether there is a mutation
1700
- * running or not and can be directly observed.
1773
+ * Contain all active mutation for a given key.
1774
+ * A mutation ca have several triggers running (it is not necessarily one function running)
1701
1775
  *
1702
1776
  * @important
1703
1777
  * - automatically cleaned as soon as the last mutation is done for a given key
1704
1778
  */
1705
- __publicField(this, "mutationResults$", new BehaviorSubject(/* @__PURE__ */ new Map()));
1779
+ __publicField(this, "mutationRunnersByKey$", new BehaviorSubject(/* @__PURE__ */ new Map()));
1706
1780
  __publicField(this, "mutate$", new Subject());
1707
1781
  __publicField(this, "cancel$", new Subject());
1708
1782
  /**
@@ -1713,6 +1787,9 @@ class MutationClient {
1713
1787
  * List of all mutations running
1714
1788
  */
1715
1789
  __publicField(this, "mutationsSubject", new BehaviorSubject([]));
1790
+ __publicField(this, "mutationResultObserver", new MutationResultObserver(
1791
+ this.mutationRunnersByKey$
1792
+ ));
1716
1793
  this.mutate$.pipe(
1717
1794
  tap(({ options, args }) => {
1718
1795
  const { mutationKey } = options;
@@ -1726,26 +1803,13 @@ class MutationClient {
1726
1803
  mutationKey
1727
1804
  };
1728
1805
  this.setMutationRunnersByKey(serializedMutationKey, mutationForKey);
1729
- mutationForKey.mutation$.subscribe((result) => {
1730
- let resultForKeySubject = this.mutationResults$.getValue().get(serializedMutationKey);
1731
- if (!resultForKeySubject) {
1732
- resultForKeySubject = new BehaviorSubject(result);
1733
- const resultMap = this.mutationResults$.getValue();
1734
- resultMap.set(serializedMutationKey, resultForKeySubject);
1735
- this.mutationResults$.next(resultMap);
1736
- } else {
1737
- resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
1738
- }
1739
- });
1806
+ mutationForKey.mutation$.subscribe();
1740
1807
  mutationForKey.mutationsSubject.pipe(
1741
1808
  distinctUntilChanged(shallowEqual),
1742
1809
  skip(1),
1743
1810
  filter((items) => items.length === 0)
1744
1811
  ).subscribe(() => {
1745
1812
  mutationForKey == null ? void 0 : mutationForKey.destroy();
1746
- const resultMap = this.mutationResults$.getValue();
1747
- resultMap.delete(serializedMutationKey);
1748
- this.mutationResults$.next(resultMap);
1749
1813
  this.deleteMutationRunnersByKey(serializedMutationKey);
1750
1814
  });
1751
1815
  }
@@ -1804,7 +1868,7 @@ class MutationClient {
1804
1868
  useIsMutating(filters = {}) {
1805
1869
  const predicate = createPredicateForFilters(filters);
1806
1870
  const reduceByNumber = (entries) => entries.reduce((acc, mutation) => {
1807
- return predicate(mutation) && mutation.stateSubject.getValue().status === "pending" ? 1 + acc : acc;
1871
+ return predicate(mutation) && mutation.state.status === "pending" ? 1 + acc : acc;
1808
1872
  }, 0);
1809
1873
  const lastValue = reduceByNumber(this.mutationsSubject.getValue());
1810
1874
  const value$ = this.mutationsSubject.pipe(
@@ -1824,7 +1888,7 @@ class MutationClient {
1824
1888
  select
1825
1889
  } = {}) {
1826
1890
  const predicate = createPredicateForFilters(filters);
1827
- const finalSelect = select ?? ((mutation) => mutation.stateSubject.getValue());
1891
+ const finalSelect = select ?? ((mutation) => mutation.state);
1828
1892
  const lastValue = this.mutationsSubject.getValue().reduce((acc, mutation) => {
1829
1893
  const result = [...acc, mutation];
1830
1894
  return result;
@@ -1843,40 +1907,6 @@ class MutationClient {
1843
1907
  );
1844
1908
  return { value$, lastValue };
1845
1909
  }
1846
- observe({ key }) {
1847
- var _a;
1848
- const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
1849
- const mapResultToObservedResult = (value) => ({
1850
- ...value,
1851
- isIdle: value.status === "idle",
1852
- isPaused: false,
1853
- isError: value.error !== void 0,
1854
- isPending: false,
1855
- isSuccess: value.status === "success"
1856
- });
1857
- const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
1858
- data: void 0,
1859
- error: void 0,
1860
- status: "idle"
1861
- });
1862
- const result$ = this.mutationResults$.pipe(
1863
- switchMap((resultMap) => {
1864
- const subject = resultMap.get(key);
1865
- return subject ?? EMPTY;
1866
- })
1867
- ).pipe(
1868
- filter(isDefined),
1869
- map((value) => ({
1870
- ...value,
1871
- isIdle: value.status === "idle",
1872
- isPaused: false,
1873
- isError: value.error !== void 0,
1874
- isPending: false,
1875
- isSuccess: value.status === "success"
1876
- }))
1877
- );
1878
- return { result$, lastValue };
1879
- }
1880
1910
  mutate(params) {
1881
1911
  this.mutate$.next(params);
1882
1912
  }
@@ -1890,7 +1920,7 @@ class MutationClient {
1890
1920
  destroy() {
1891
1921
  this.cancel$.complete();
1892
1922
  this.mutate$.complete();
1893
- this.mutationResults$.complete();
1923
+ this.mutationResultObserver.destroy();
1894
1924
  this.mutationRunnersByKey$.complete();
1895
1925
  this.isMutatingSubject.complete();
1896
1926
  this.mutationsSubject.complete();
@@ -1,14 +1,14 @@
1
- import { BehaviorSubject, type Observable } from "rxjs";
2
- import { type MutationState, type MutationOptions, type MutationResult } from "./types";
1
+ import { type Observable, ReplaySubject } from "rxjs";
2
+ import { type MutationState, type MutationOptions } from "./types";
3
3
  export declare class Mutation<Data> {
4
- stateSubject: BehaviorSubject<MutationState<Data, unknown, void, unknown>>;
4
+ stateSubject: ReplaySubject<MutationState<Data, unknown, void, unknown>>;
5
5
  /**
6
6
  * @important
7
- * proxy for rect-query, not really useful
7
+ * convenience over usage of stateSubject for sync access
8
8
  */
9
9
  state: MutationState<Data>;
10
10
  options: MutationOptions<Data, any>;
11
- mutation$: Observable<MutationResult<Data>>;
11
+ mutation$: Observable<MutationState<Data>>;
12
12
  constructor({ args, ...options }: {
13
13
  args: any;
14
14
  } & MutationOptions<Data, any>);
@@ -1,7 +1,8 @@
1
- import { Subject, BehaviorSubject, type Observable } from "rxjs";
2
- import { type MutationResult, type MutationOptions, type MutationObservedResult, type MutationFilters, type MutationKey, type MutationState } from "./types";
1
+ import { Subject, BehaviorSubject } from "rxjs";
2
+ import { type MutationOptions, type MutationFilters, type MutationKey, type MutationState } from "./types";
3
3
  import { type QueryKey } from "../keys/types";
4
4
  import { type Mutation } from "./Mutation";
5
+ import { MutationResultObserver } from "./MutationResultObserver";
5
6
  export declare class MutationClient {
6
7
  /**
7
8
  * Contain all active mutation for a given key.
@@ -11,7 +12,7 @@ export declare class MutationClient {
11
12
  * - automatically cleaned as soon as the last mutation is done for a given key
12
13
  */
13
14
  mutationRunnersByKey$: BehaviorSubject<Map<string, {
14
- mutation$: Observable<MutationResult<unknown>>;
15
+ mutation$: import("rxjs").Observable<MutationState<unknown, unknown, void, unknown>>;
15
16
  trigger: ({ args, options }: {
16
17
  args: unknown;
17
18
  options: MutationOptions<unknown, unknown>;
@@ -23,14 +24,6 @@ export declare class MutationClient {
23
24
  } & {
24
25
  mutationKey: MutationKey;
25
26
  }>>;
26
- /**
27
- * Mutation result subject. It can be used whether there is a mutation
28
- * running or not and can be directly observed.
29
- *
30
- * @important
31
- * - automatically cleaned as soon as the last mutation is done for a given key
32
- */
33
- mutationResults$: BehaviorSubject<Map<string, BehaviorSubject<MutationResult<any>>>>;
34
27
  mutate$: Subject<{
35
28
  options: MutationOptions<any, any>;
36
29
  args: any;
@@ -46,6 +39,7 @@ export declare class MutationClient {
46
39
  * List of all mutations running
47
40
  */
48
41
  mutationsSubject: BehaviorSubject<Mutation<any>[]>;
42
+ mutationResultObserver: MutationResultObserver;
49
43
  constructor();
50
44
  /**
51
45
  * @helper
@@ -59,7 +53,7 @@ export declare class MutationClient {
59
53
  * @helper
60
54
  */
61
55
  getMutationRunnersByKey(key: string): ({
62
- mutation$: Observable<MutationResult<unknown>>;
56
+ mutation$: import("rxjs").Observable<MutationState<unknown, unknown, void, unknown>>;
63
57
  trigger: ({ args, options }: {
64
58
  args: unknown;
65
59
  options: MutationOptions<unknown, unknown>;
@@ -72,22 +66,16 @@ export declare class MutationClient {
72
66
  mutationKey: MutationKey;
73
67
  }) | undefined;
74
68
  useIsMutating<TData>(filters?: MutationFilters<TData>): {
75
- value$: Observable<number>;
69
+ value$: import("rxjs").Observable<number>;
76
70
  lastValue: number;
77
71
  };
78
72
  mutationState<TData, Selected = MutationState<TData>>({ filters, select }?: {
79
73
  filters?: MutationFilters<TData>;
80
74
  select?: (mutation: Mutation<TData>) => Selected;
81
75
  }): {
82
- value$: Observable<Selected[]>;
76
+ value$: import("rxjs").Observable<Selected[]>;
83
77
  lastValue: Selected[];
84
78
  };
85
- observe<Result>({ key }: {
86
- key: string;
87
- }): {
88
- result$: Observable<MutationObservedResult<Result>>;
89
- lastValue: MutationObservedResult<Result>;
90
- };
91
79
  mutate<Result, MutationArgs>(params: {
92
80
  options: MutationOptions<Result, MutationArgs>;
93
81
  args: MutationArgs;
@@ -0,0 +1,32 @@
1
+ import { BehaviorSubject, type Observable } from "rxjs";
2
+ import { type MutationKey, type MutationObserverResult, type MutationState } from "./types";
3
+ import { type DefaultError } from "../types";
4
+ import { type createMutationRunner } from "./createMutationRunner";
5
+ export declare class MutationResultObserver {
6
+ /**
7
+ * Mutation result subject. It can be used whether there is a mutation
8
+ * running or not and can be directly observed.
9
+ *
10
+ * @important
11
+ * - automatically cleaned as soon as the last mutation is done for a given key
12
+ */
13
+ mutationResults$: BehaviorSubject<Map<string, BehaviorSubject<MutationObserverResult>>>;
14
+ constructor(mutationRunnersByKey$: BehaviorSubject<Map<string, ReturnType<typeof createMutationRunner> & {
15
+ mutationKey: MutationKey;
16
+ }>>);
17
+ getDefaultResultValue<TData>(): MutationObserverResult<TData>;
18
+ deleteResultForKey({ serializedMutationKey }: {
19
+ serializedMutationKey: string;
20
+ }): void;
21
+ updateResultForKey<TData, TError = DefaultError>({ serializedMutationKey, result }: {
22
+ serializedMutationKey: string;
23
+ result: MutationState<TData, TError>;
24
+ }): void;
25
+ observe<Result>({ key }: {
26
+ key: string;
27
+ }): {
28
+ result$: Observable<MutationObserverResult<Result>>;
29
+ lastValue: MutationObserverResult<Result>;
30
+ };
31
+ destroy(): void;
32
+ }
@@ -3,7 +3,7 @@ import { type MutationOptions } from "./types";
3
3
  import { Mutation } from "./Mutation";
4
4
  export type MutationRunner = ReturnType<typeof createMutationRunner>;
5
5
  export declare const createMutationRunner: <T, MutationArg>({ __queryFinalizeHook, __queryInitHook, __queryTriggerHook }: Pick<MutationOptions<any, any>, "__queryInitHook" | "__queryTriggerHook" | "__queryFinalizeHook">) => {
6
- mutation$: import("rxjs").Observable<import("./types").MutationResult<unknown>>;
6
+ mutation$: import("rxjs").Observable<import("./types").MutationState<unknown, unknown, void, unknown>>;
7
7
  trigger: ({ args, options }: {
8
8
  args: MutationArg;
9
9
  options: MutationOptions<T, MutationArg>;
@@ -1,3 +1,3 @@
1
1
  import { type Observable } from "rxjs";
2
- import { type MutationResult } from "./types";
3
- export declare const mergeResults: <T>(stream$: Observable<Partial<MutationResult<T>>>) => Observable<MutationResult<T>>;
2
+ import { type MutationState } from "./types";
3
+ export declare const mergeResults: <T>(stream$: Observable<Partial<MutationState<T, unknown, void, unknown>>>) => Observable<MutationState<T, unknown, void, unknown>>;
@@ -1,5 +1,5 @@
1
1
  import { type MonoTypeOperatorFunction, type Observable } from "rxjs";
2
- import { type Query, type QueryResult } from "../types";
2
+ import { type DefaultError, type Query, type QueryResult } from "../types";
3
3
  import { type Mutation } from "./Mutation";
4
4
  /**
5
5
  * The default value `merge` is suitable for most use case.
@@ -43,18 +43,6 @@ export interface MutationFilters<TData> {
43
43
  */
44
44
  status?: MutationStatus;
45
45
  }
46
- export interface MutationResult<R> {
47
- data: R | undefined;
48
- status: MutationStatus;
49
- error: unknown;
50
- }
51
- export interface MutationObservedResult<R> extends MutationResult<R> {
52
- isError: boolean;
53
- isIdle: boolean;
54
- isSuccess: boolean;
55
- isPending: boolean;
56
- isPaused: boolean;
57
- }
58
46
  export type MutationFn<Data, MutationArg> = Observable<Data> | ((arg: MutationArg) => Promise<Data>) | ((arg: MutationArg) => Observable<Data>);
59
47
  export interface MutationOptions<Result, MutationArg> {
60
48
  enabled?: boolean;
@@ -89,8 +77,71 @@ export interface MutationOptions<Result, MutationArg> {
89
77
  export interface MutationState<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> {
90
78
  context: TContext | undefined;
91
79
  data: TData | undefined;
92
- error: TError;
80
+ error: TError | null;
93
81
  status: MutationStatus;
94
82
  variables: TVariables | undefined;
95
83
  submittedAt: number;
96
84
  }
85
+ export interface MutateOptions<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> {
86
+ onSuccess?: (data: TData, variables: TVariables, context: TContext) => void;
87
+ onError?: (error: TError, variables: TVariables, context: TContext | undefined) => void;
88
+ onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => void;
89
+ }
90
+ export type MutateFunction<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> = (variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext>) => Promise<TData>;
91
+ export interface MutationObserverBaseResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationState<TData, TError, TVariables, TContext> {
92
+ isError: boolean;
93
+ isIdle: boolean;
94
+ isPending: boolean;
95
+ isSuccess: boolean;
96
+ }
97
+ export interface MutationObserverIdleResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
98
+ data: undefined;
99
+ variables: undefined;
100
+ error: null;
101
+ isError: false;
102
+ isIdle: true;
103
+ isPending: false;
104
+ isSuccess: false;
105
+ status: "idle";
106
+ }
107
+ export interface MutationObserverLoadingResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
108
+ data: undefined;
109
+ variables: TVariables;
110
+ error: null;
111
+ isError: false;
112
+ isIdle: false;
113
+ isPending: true;
114
+ isSuccess: false;
115
+ status: "pending";
116
+ }
117
+ export interface MutationObserverErrorResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
118
+ data: undefined;
119
+ error: TError;
120
+ variables: TVariables;
121
+ isError: true;
122
+ isIdle: false;
123
+ isPending: false;
124
+ isSuccess: false;
125
+ status: "error";
126
+ }
127
+ export interface MutationObserverSuccessResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
128
+ data: TData;
129
+ error: null;
130
+ variables: TVariables;
131
+ isError: false;
132
+ isIdle: false;
133
+ isPending: false;
134
+ isSuccess: true;
135
+ status: "success";
136
+ }
137
+ export interface MutationObserverAnyResult<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown> extends MutationObserverBaseResult<TData, TError, TVariables, TContext> {
138
+ data: TData | undefined;
139
+ error: TError | null;
140
+ variables: TVariables;
141
+ isError: boolean;
142
+ isIdle: boolean;
143
+ isPending: boolean;
144
+ isSuccess: boolean;
145
+ status: MutationStatus;
146
+ }
147
+ export type MutationObserverResult<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> = MutationObserverAnyResult<TData, TError, TVariables, TContext>;
@@ -5,14 +5,16 @@ export type AsyncQueryOptions<Result, Params> = Omit<MutationOptions<Result, Par
5
5
  cancelOnUnMount?: boolean;
6
6
  };
7
7
  export declare function useMutation<Args = void, R = undefined>(options: AsyncQueryOptions<R, Args>, queryClient?: QueryClient): {
8
+ data: R | undefined;
9
+ error: unknown;
10
+ variables: void;
8
11
  isError: boolean;
9
12
  isIdle: boolean;
10
- isSuccess: boolean;
11
13
  isPending: boolean;
12
- isPaused: boolean;
13
- data: R | undefined;
14
+ isSuccess: boolean;
14
15
  status: import("../../client/mutations/types").MutationStatus;
15
- error: unknown;
16
+ context: unknown;
17
+ submittedAt: number;
16
18
  mutate: (mutationArgs: Args) => void;
17
19
  cancel: () => void;
18
20
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.61.0",
4
+ "version": "1.62.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"