reactjrx 1.32.0 → 1.34.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
@@ -459,13 +459,13 @@ function shallowEqual(objA, objB) {
459
459
  }
460
460
  return true;
461
461
  }
462
- function useMutation(query, mapOperatorOrOptions, options = {}) {
462
+ function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
463
463
  const queryRef = useLiveRef(query);
464
464
  const triggerSubject = useSubject();
465
465
  const resetSubject = useSubject({
466
466
  /**
467
467
  * @important
468
- * Because mutation can still run after unmount, the user might
468
+ * Because async query can still run after unmount, the user might
469
469
  * want to use reset for whatever reason. We will only manually complete
470
470
  * this subject whenever the main query hook finalize.
471
471
  */
@@ -684,6 +684,33 @@ const autoRefetch = (options = {}) => (source) => {
684
684
  })
685
685
  );
686
686
  };
687
+ function isDefined(arg) {
688
+ return arg !== null && arg !== void 0;
689
+ }
690
+ const withKeyComparison = (stream) => stream.pipe(
691
+ rxjs.startWith(void 0),
692
+ rxjs.pairwise(),
693
+ rxjs.map(([previous, current]) => {
694
+ if (current) {
695
+ if (!previous) {
696
+ return {
697
+ ...current,
698
+ previousKey: void 0,
699
+ isUsingDifferentKey: true
700
+ };
701
+ }
702
+ const serializedKey = serializeKey(current.key);
703
+ const serializedPreviousKey = serializeKey(previous.key);
704
+ return {
705
+ ...current,
706
+ previousKey: (previous == null ? void 0 : previous.key) ?? current.key,
707
+ isUsingDifferentKey: serializedPreviousKey !== serializedKey
708
+ };
709
+ }
710
+ return void 0;
711
+ }),
712
+ rxjs.filter(isDefined)
713
+ );
687
714
  function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
688
715
  const query = Array.isArray(keyOrQuery) ? queryOrOptionOrNothing : keyOrQuery;
689
716
  const options = optionsOrNothing ?? (queryOrOptionOrNothing !== query ? queryOrOptionOrNothing : void 0) ?? {};
@@ -747,13 +774,15 @@ function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
747
774
  options: options2,
748
775
  query: query2
749
776
  })),
777
+ withKeyComparison,
750
778
  rxjs.filter(({ enabled }) => enabled),
751
- rxjs.switchMap(({ key: key2, options: options2, query: query2 }) => {
779
+ rxjs.switchMap(({ key: key2, options: options2, isUsingDifferentKey, query: query2 }) => {
752
780
  const serializedKey = serializeKey(key2);
753
781
  return rxjs.of(null).pipe(
754
782
  rxjs.tap(() => {
755
783
  data$.current.next({
756
784
  ...data$.current.getValue(),
785
+ data: isUsingDifferentKey ? void 0 : data$.current.getValue().data,
757
786
  error: void 0,
758
787
  isLoading: true
759
788
  });
@@ -831,8 +860,8 @@ exports.getDelay = getDelay;
831
860
  exports.retryBackoff = retryBackoff;
832
861
  exports.signal = signal;
833
862
  exports.trigger = trigger;
863
+ exports.useAsyncQuery = useAsyncQuery;
834
864
  exports.useLiveRef = useLiveRef;
835
- exports.useMutation = useMutation;
836
865
  exports.useObserve = useObserve;
837
866
  exports.useObserveCallback = useObserveCallback;
838
867
  exports.usePersistSignalsContext = usePersistSignalsContext;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export * from "./lib/state/persistance/createLocalforageAdapter";
15
15
  export * from "./lib/utils/useUnmountObservable";
16
16
  export * from "./lib/utils/retryBackoff";
17
17
  export * from "./lib/utils/useLiveRef";
18
- export * from "./lib/queries/useMutation";
18
+ export * from "./lib/queries/useAsyncQuery";
19
19
  export * from "./lib/queries/useQuery";
20
20
  export * from "./lib/queries/useSubscribeEffect";
21
21
  export { Provider as ReactjrxQueryProvider } from "./lib/queries/Provider";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, createContext, memo, useContext, useState } from "react";
2
- import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, of, zip, from, map, merge, throttleTime, switchMap, defer, iif, timer, throwError, take, startWith, combineLatest, first, takeUntil, filter, concatMap as concatMap$1, mergeMap, skip, interval, withLatestFrom, shareReplay, repeat, share, retry } from "rxjs";
2
+ import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, of, zip, from, map, merge, throttleTime, switchMap, defer, iif, timer, throwError, take, startWith, combineLatest, first, takeUntil, filter, concatMap as concatMap$1, mergeMap, skip, interval, withLatestFrom, shareReplay, repeat, pairwise, share, retry } from "rxjs";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { retryWhen, concatMap, tap as tap$1 } from "rxjs/operators";
5
5
  const useLiveRef = (value) => {
@@ -457,13 +457,13 @@ function shallowEqual(objA, objB) {
457
457
  }
458
458
  return true;
459
459
  }
460
- function useMutation(query, mapOperatorOrOptions, options = {}) {
460
+ function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
461
461
  const queryRef = useLiveRef(query);
462
462
  const triggerSubject = useSubject();
463
463
  const resetSubject = useSubject({
464
464
  /**
465
465
  * @important
466
- * Because mutation can still run after unmount, the user might
466
+ * Because async query can still run after unmount, the user might
467
467
  * want to use reset for whatever reason. We will only manually complete
468
468
  * this subject whenever the main query hook finalize.
469
469
  */
@@ -682,6 +682,33 @@ const autoRefetch = (options = {}) => (source) => {
682
682
  })
683
683
  );
684
684
  };
685
+ function isDefined(arg) {
686
+ return arg !== null && arg !== void 0;
687
+ }
688
+ const withKeyComparison = (stream) => stream.pipe(
689
+ startWith(void 0),
690
+ pairwise(),
691
+ map(([previous, current]) => {
692
+ if (current) {
693
+ if (!previous) {
694
+ return {
695
+ ...current,
696
+ previousKey: void 0,
697
+ isUsingDifferentKey: true
698
+ };
699
+ }
700
+ const serializedKey = serializeKey(current.key);
701
+ const serializedPreviousKey = serializeKey(previous.key);
702
+ return {
703
+ ...current,
704
+ previousKey: (previous == null ? void 0 : previous.key) ?? current.key,
705
+ isUsingDifferentKey: serializedPreviousKey !== serializedKey
706
+ };
707
+ }
708
+ return void 0;
709
+ }),
710
+ filter(isDefined)
711
+ );
685
712
  function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
686
713
  const query = Array.isArray(keyOrQuery) ? queryOrOptionOrNothing : keyOrQuery;
687
714
  const options = optionsOrNothing ?? (queryOrOptionOrNothing !== query ? queryOrOptionOrNothing : void 0) ?? {};
@@ -745,13 +772,15 @@ function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
745
772
  options: options2,
746
773
  query: query2
747
774
  })),
775
+ withKeyComparison,
748
776
  filter(({ enabled }) => enabled),
749
- switchMap(({ key: key2, options: options2, query: query2 }) => {
777
+ switchMap(({ key: key2, options: options2, isUsingDifferentKey, query: query2 }) => {
750
778
  const serializedKey = serializeKey(key2);
751
779
  return of(null).pipe(
752
780
  tap(() => {
753
781
  data$.current.next({
754
782
  ...data$.current.getValue(),
783
+ data: isUsingDifferentKey ? void 0 : data$.current.getValue().data,
755
784
  error: void 0,
756
785
  isLoading: true
757
786
  });
@@ -830,8 +859,8 @@ export {
830
859
  retryBackoff,
831
860
  signal,
832
861
  trigger,
862
+ useAsyncQuery,
833
863
  useLiveRef,
834
- useMutation,
835
864
  useObserve,
836
865
  useObserveCallback,
837
866
  usePersistSignalsContext,
@@ -0,0 +1,16 @@
1
+ import type { Observable } from "rxjs";
2
+ export declare const withKeyComparison: <T extends {
3
+ key: any[];
4
+ }>(stream: Observable<T>) => Observable<(T & {
5
+ previousKey: undefined;
6
+ isUsingDifferentKey: boolean;
7
+ } extends infer T_1 ? T_1 extends T & {
8
+ previousKey: undefined;
9
+ isUsingDifferentKey: boolean;
10
+ } ? T_1 extends null | undefined ? never : T_1 : never : never) | (T & {
11
+ previousKey: any[];
12
+ isUsingDifferentKey: boolean;
13
+ } extends infer T_2 ? T_2 extends T & {
14
+ previousKey: any[];
15
+ isUsingDifferentKey: boolean;
16
+ } ? T_2 extends null | undefined ? never : T_2 : never : never)>;
@@ -4,22 +4,22 @@ interface QueryState<R> {
4
4
  status: "idle" | "loading" | "error" | "success";
5
5
  error: unknown;
6
6
  }
7
- export interface MutationOptions<Result, Params> {
7
+ export interface AsyncQueryOptions<Result, Params> {
8
8
  retry?: false | number | ((attempt: number, error: unknown) => boolean);
9
9
  /**
10
- * Called for every mutation on error.
10
+ * Called for every async query on error.
11
11
  * `merge` mapping will run callback as they happen.
12
12
  * Use `concat` if you need to run callbacks in order of calling.
13
13
  */
14
14
  onError?: (error: unknown, params: Params) => void;
15
15
  /**
16
- * Called for every mutation on success.
16
+ * Called for every async query on success.
17
17
  * `merge` mapping will run callback as they happen.
18
18
  * Use `concat` if you need to run callbacks in order of calling.
19
19
  */
20
20
  onSuccess?: (data: Result, params: Params) => void;
21
21
  /**
22
- * When true, any running mutation will be cancelled (when possible) on unmount.
22
+ * When true, any running async query will be cancelled (when possible) on unmount.
23
23
  * You need to handle it yourself for promises if needed.
24
24
  * Callbacks will not be called as a result.
25
25
  *
@@ -39,19 +39,19 @@ interface Result<A, R> {
39
39
  status: "idle" | "loading" | "error" | "success";
40
40
  isLoading: boolean;
41
41
  /**
42
- * If the latest mutation is in a success state, data contains its result.
42
+ * If the latest async query is in a success state, data contains its result.
43
43
  *
44
44
  * @important
45
- * The value does not automatically reset when a new mutation run. It will be updated
46
- * when a new mutation success or error.
45
+ * The value does not automatically reset when a new async query run. It will be updated
46
+ * when a new async query success or error.
47
47
  */
48
48
  data: R | undefined;
49
49
  /**
50
- * If the latest mutation is in a error state, error contains its error.
50
+ * If the latest async query is in a error state, error contains its error.
51
51
  *
52
52
  * @important
53
- * The value does not automatically reset when a new mutation run. It will be updated
54
- * when a new mutation success or error.
53
+ * The value does not automatically reset when a new async query run. It will be updated
54
+ * when a new async query success or error.
55
55
  */
56
56
  error: unknown | undefined;
57
57
  mutate: (args: A) => void;
@@ -63,20 +63,20 @@ interface Result<A, R> {
63
63
  * it when specific need arise.
64
64
  *
65
65
  * `merge`:
66
- * Run each mutation as they are triggered without any cancellation or queue system.
67
- * The result is always from the latest mutation triggered, not necessarily
66
+ * Run each async query as they are triggered without any cancellation or queue system.
67
+ * The result is always from the latest async query triggered, not necessarily
68
68
  * the latest one running.
69
69
  *
70
70
  * `concat`:
71
- * Unlike merge, it will trigger each mutation sequentially following
72
- * a queue system. The result is not necessarily the last triggered mutation
73
- * but the current running mutation.
71
+ * Unlike merge, it will trigger each async query sequentially following
72
+ * a queue system. The result is not necessarily the last triggered async query
73
+ * but the current running async query.
74
74
  *
75
75
  * `switch`:
76
- * Only run the latest mutation triggered and cancel any previously running one.
77
- * Result correspond to the current running mutation.
76
+ * Only run the latest async query triggered and cancel any previously running one.
77
+ * Result correspond to the current running async query.
78
78
  */
79
79
  type MapOperator = "switch" | "concat" | "merge";
80
- export declare function useMutation<A = void, R = undefined>(query: (args: A) => Promise<R> | Observable<R>, mapOperatorOrOptions?: MapOperator, options?: MutationOptions<R, A>): Result<A, R>;
81
- export declare function useMutation<A = void, R = undefined>(query: (args: A) => Promise<R> | Observable<R>, mapOperatorOrOptions?: MutationOptions<R, A>): Result<A, R>;
80
+ export declare function useAsyncQuery<A = void, R = undefined>(query: (args: A) => Promise<R> | Observable<R>, mapOperatorOrOptions?: MapOperator, options?: AsyncQueryOptions<R, A>): Result<A, R>;
81
+ export declare function useAsyncQuery<A = void, R = undefined>(query: (args: A) => Promise<R> | Observable<R>, mapOperatorOrOptions?: AsyncQueryOptions<R, A>): Result<A, R>;
82
82
  export {};
@@ -0,0 +1 @@
1
+ export declare function isDefined<T>(arg: T | null | undefined): arg is T extends null | undefined ? never : T;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.32.0",
4
+ "version": "1.34.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"