reactjrx 1.101.0 → 1.104.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
@@ -14,6 +14,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
14
14
  const React = require("react");
15
15
  const rxjs = require("rxjs");
16
16
  const operators = require("rxjs/operators");
17
+ const reactQuery = require("@tanstack/react-query");
17
18
  const jsxRuntime = require("react/jsx-runtime");
18
19
  function _interopNamespaceDefault(e) {
19
20
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -61,7 +62,8 @@ function makeObservable(something) {
61
62
  function useObserve(source$, optionsOrDeps, maybeDeps) {
62
63
  const options = optionsOrDeps != null && !Array.isArray(optionsOrDeps) ? optionsOrDeps : {
63
64
  defaultValue: void 0,
64
- unsubscribeOnUnmount: true
65
+ unsubscribeOnUnmount: true,
66
+ compareFn: void 0
65
67
  };
66
68
  const deps = !maybeDeps && Array.isArray(optionsOrDeps) ? optionsOrDeps : typeof source$ === "function" ? maybeDeps ?? [] : [source$];
67
69
  const valueRef = React.useRef(
@@ -73,13 +75,15 @@ function useObserve(source$, optionsOrDeps, maybeDeps) {
73
75
  (next) => {
74
76
  const source = sourceRef.current;
75
77
  const sub = makeObservable(source).pipe(
78
+ optionsRef.current.defaultValue ? rxjs.startWith(optionsRef.current.defaultValue) : rxjs.identity,
76
79
  /**
77
- * @important
78
- * We only check primitives because underlying subscription might
79
- * be using objects and keeping same reference but pushing new
80
- * properties values
80
+ * @important there is already a Object.is comparison in place from react
81
+ * so we only add a custom compareFn if provided
81
82
  */
82
- rxjs.distinctUntilChanged((a, b) => a === b),
83
+ optionsRef.current.compareFn ? rxjs.distinctUntilChanged((a, b) => {
84
+ if (a === void 0 || b === void 0) return false;
85
+ return optionsRef.current.compareFn(a, b);
86
+ }) : rxjs.identity,
83
87
  rxjs.tap((value) => {
84
88
  valueRef.current = value;
85
89
  }),
@@ -205,7 +209,7 @@ function signal(config = {}) {
205
209
  default: config.default,
206
210
  key: config.key
207
211
  };
208
- const { default: defaultValue } = normalizedConfig ?? {};
212
+ const { default: defaultValue } = normalizedConfig;
209
213
  const subject = new rxjs.BehaviorSubject(defaultValue);
210
214
  const setValue = (arg) => {
211
215
  const update = (value) => {
@@ -476,6 +480,28 @@ function persistSignals({
476
480
  )
477
481
  );
478
482
  }
483
+ function shallowEqual(objA, objB) {
484
+ if (objA === null || objA === void 0 || objB === void 0) {
485
+ return objA === objB;
486
+ }
487
+ if (typeof objA !== "object" || typeof objB !== "object") {
488
+ return objA === objB;
489
+ }
490
+ if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
491
+ return false;
492
+ }
493
+ const keysA = Object.keys(objA);
494
+ const keysB = Object.keys(objB);
495
+ if (keysA.length !== keysB.length) {
496
+ return false;
497
+ }
498
+ for (const key of keysA) {
499
+ if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
500
+ return false;
501
+ }
502
+ }
503
+ return true;
504
+ }
479
505
  function usePersistSignals({
480
506
  entries = [],
481
507
  onHydrated,
@@ -487,18 +513,21 @@ function usePersistSignals({
487
513
  return useObserve(
488
514
  () => {
489
515
  const persistence$ = adapterSubject.current.pipe(
490
- rxjs.concatMap((adapter2) => {
491
- if (!adapter2) return rxjs.NEVER;
492
- return entriesSubject.current.pipe(
493
- rxjs.concatMap(
494
- (entries2) => persistSignals({
495
- adapter: adapter2,
496
- entries: entries2,
497
- onHydrated: () => {
498
- var _a;
499
- (_a = onHydratedRef.current) == null ? void 0 : _a.call(onHydratedRef);
500
- }
501
- })
516
+ rxjs.switchMap((adapter2) => {
517
+ if (!adapter2) return rxjs.of({ type: "reset" });
518
+ return rxjs.merge(
519
+ rxjs.of({ type: "reset" }),
520
+ entriesSubject.current.pipe(
521
+ rxjs.concatMap(
522
+ (entries2) => persistSignals({
523
+ adapter: adapter2,
524
+ entries: entries2,
525
+ onHydrated: () => {
526
+ var _a;
527
+ (_a = onHydratedRef.current) == null ? void 0 : _a.call(onHydratedRef);
528
+ }
529
+ })
530
+ )
502
531
  )
503
532
  );
504
533
  })
@@ -506,6 +535,7 @@ function usePersistSignals({
506
535
  return persistence$.pipe(
507
536
  rxjs.scan(
508
537
  (acc, event) => {
538
+ if (event.type === "reset") return { isHydrated: false };
509
539
  if (event.type === "hydrated") return { isHydrated: true };
510
540
  return acc;
511
541
  },
@@ -513,8 +543,8 @@ function usePersistSignals({
513
543
  )
514
544
  );
515
545
  },
516
- { defaultValue: { isHydrated: false } },
517
- [adapterSubject]
546
+ { defaultValue: { isHydrated: false }, compareFn: shallowEqual },
547
+ [adapterSubject, entriesSubject]
518
548
  );
519
549
  }
520
550
  const useUnmountObservable = () => {
@@ -623,6 +653,90 @@ function isDefined(arg) {
623
653
  }
624
654
  const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
625
655
  const isServer = typeof window === "undefined" || "Deno" in window;
656
+ function useQuery$(options, queryClient) {
657
+ const sub = React.useRef();
658
+ const _queryClient = reactQuery.useQueryClient(queryClient);
659
+ const queryFnAsync = (context) => {
660
+ let isResolved = false;
661
+ return new Promise((resolve, reject) => {
662
+ let lastData = void 0;
663
+ if (sub.current) {
664
+ sub.current.unsubscribe();
665
+ sub.current = void 0;
666
+ }
667
+ const unsub = _queryClient.getQueryCache().subscribe((d) => {
668
+ var _a;
669
+ if (d.type === "observerRemoved" && d.query.observers.length === 0) {
670
+ unsub();
671
+ _queryClient.cancelQueries({ queryKey: context.queryKey });
672
+ (_a = sub.current) == null ? void 0 : _a.unsubscribe();
673
+ }
674
+ });
675
+ const source = rxjs.defer(
676
+ () => typeof options.queryFn === "function" ? options.queryFn(context) : options.queryFn
677
+ );
678
+ sub.current = source.pipe(
679
+ rxjs.finalize(() => {
680
+ unsub();
681
+ isResolved = true;
682
+ })
683
+ ).subscribe({
684
+ next: (data) => {
685
+ lastData = data;
686
+ _queryClient == null ? void 0 : _queryClient.setQueryData(context.queryKey, data);
687
+ },
688
+ error: (error) => {
689
+ isResolved = true;
690
+ reject(error);
691
+ },
692
+ complete: () => {
693
+ if (lastData === void 0)
694
+ return reject(new Error("Stream completed without any data"));
695
+ if (isResolved) return;
696
+ isResolved = true;
697
+ resolve(lastData);
698
+ }
699
+ });
700
+ });
701
+ };
702
+ const result = reactQuery.useQuery(
703
+ {
704
+ ...options,
705
+ queryFn: queryFnAsync
706
+ },
707
+ queryClient
708
+ );
709
+ return result;
710
+ }
711
+ function useMutation$(options, queryClient) {
712
+ const mutationFnAsync = (variables) => {
713
+ let lastData;
714
+ return new Promise((resolve, reject) => {
715
+ const source = typeof options.mutationFn === "function" ? options.mutationFn(variables) : options.mutationFn;
716
+ source.pipe(rxjs.take(1)).subscribe({
717
+ next: (data) => {
718
+ lastData = data;
719
+ },
720
+ error: (error) => {
721
+ reject(error);
722
+ },
723
+ complete: () => {
724
+ if (lastData === void 0)
725
+ return reject(new Error("Stream completed without any data"));
726
+ resolve(lastData);
727
+ }
728
+ });
729
+ });
730
+ };
731
+ const result = reactQuery.useMutation(
732
+ {
733
+ ...options,
734
+ mutationFn: mutationFnAsync
735
+ },
736
+ queryClient
737
+ );
738
+ return result;
739
+ }
626
740
  function hasObjectPrototype(o) {
627
741
  return Object.prototype.toString.call(o) === "[object Object]";
628
742
  }
@@ -789,28 +903,6 @@ const matchKey = (keyA, keyB, { exact = false } = {}) => {
789
903
  }
790
904
  return partialMatchKey(keyA, keyB);
791
905
  };
792
- function shallowEqual(objA, objB) {
793
- if (objA === null || objA === void 0 || objB === void 0) {
794
- return objA === objB;
795
- }
796
- if (typeof objA !== "object" || typeof objB !== "object") {
797
- return objA === objB;
798
- }
799
- if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
800
- return false;
801
- }
802
- const keysA = Object.keys(objA);
803
- const keysB = Object.keys(objB);
804
- if (keysA.length !== keysB.length) {
805
- return false;
806
- }
807
- for (const key of keysA) {
808
- if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
809
- return false;
810
- }
811
- }
812
- return true;
813
- }
814
906
  const distinctUntilStateChanged = (stream) => stream.pipe(
815
907
  rxjs.distinctUntilChanged(
816
908
  ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
@@ -1972,12 +2064,17 @@ const executeMutation = ({
1972
2064
  const isPaused = state.isPaused;
1973
2065
  const defaultFn = async () => await Promise.reject(new Error("No mutationFn found"));
1974
2066
  const mutationFn = options.mutationFn ?? defaultFn;
1975
- const contextFromOnMutate$ = makeObservable(
1976
- // eslint-disable-next-line @typescript-eslint/promise-function-async
1977
- () => {
1978
- var _a;
1979
- return ((_a = options.onMutate) == null ? void 0 : _a.call(options, variables)) ?? void 0;
1980
- }
2067
+ const onMutateFactory = () => {
2068
+ var _a;
2069
+ return ((_a = options.onMutate) == null ? void 0 : _a.call(options, variables)) ?? void 0;
2070
+ };
2071
+ const contextFromOnMutate$ = makeObservable(onMutateFactory);
2072
+ contextFromOnMutate$.pipe(
2073
+ rxjs.tap((context) => {
2074
+ if (context === void 0) {
2075
+ throw new Error("onMutate returned undefined");
2076
+ }
2077
+ })
1981
2078
  );
1982
2079
  const rawContext$ = rxjs.of(state.context);
1983
2080
  const context$ = rxjs.iif(() => isPaused, rawContext$, contextFromOnMutate$).pipe(
@@ -2005,10 +2102,7 @@ const executeMutation = ({
2005
2102
  };
2006
2103
  const queryRunner$ = context$.pipe(
2007
2104
  rxjs.switchMap((context) => {
2008
- const fn$ = typeof mutationFn === "function" ? (
2009
- // eslint-disable-next-line @typescript-eslint/promise-function-async
2010
- makeObservable(() => mutationFn(variables))
2011
- ) : mutationFn;
2105
+ const fn$ = typeof mutationFn === "function" ? makeObservable(() => mutationFn(variables)) : mutationFn;
2012
2106
  const sharedFn$ = fn$.pipe(rxjs.share());
2013
2107
  const completeWithoutValue$ = sharedFn$.pipe(
2014
2108
  rxjs.isEmpty(),
@@ -2185,6 +2279,7 @@ class Mutation {
2185
2279
  return (_b = (_a = mutationCache.config).onMutate) == null ? void 0 : _b.call(
2186
2280
  _a,
2187
2281
  variables2,
2282
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2188
2283
  this
2189
2284
  );
2190
2285
  }
@@ -2208,6 +2303,7 @@ class Mutation {
2208
2303
  error,
2209
2304
  variables2,
2210
2305
  context,
2306
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2211
2307
  this
2212
2308
  );
2213
2309
  }
@@ -2230,6 +2326,7 @@ class Mutation {
2230
2326
  error,
2231
2327
  variables2,
2232
2328
  context,
2329
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2233
2330
  this
2234
2331
  );
2235
2332
  }
@@ -2251,6 +2348,7 @@ class Mutation {
2251
2348
  data,
2252
2349
  variables2,
2253
2350
  context,
2351
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2254
2352
  this
2255
2353
  );
2256
2354
  }
@@ -3406,11 +3504,13 @@ exports.useForeverQuery = useForeverQuery;
3406
3504
  exports.useLiveRef = useLiveRef;
3407
3505
  exports.useMount = useMount;
3408
3506
  exports.useMutation = useMutation;
3507
+ exports.useMutation$ = useMutation$;
3409
3508
  exports.useObservableState = useObservableState;
3410
3509
  exports.useObserve = useObserve;
3411
3510
  exports.useObserveCallback = useObserveCallback;
3412
3511
  exports.usePersistSignals = usePersistSignals;
3413
3512
  exports.useQuery = useQuery;
3513
+ exports.useQuery$ = useQuery$;
3414
3514
  exports.useQueryClient = useQueryClient;
3415
3515
  exports.useSignal = useSignal;
3416
3516
  exports.useSignalValue = useSignalValue;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export * from './lib/state/persistance/adapters/createLocalStorageAdapter';
13
13
  export * from './lib/state/react/usePersistSignals';
14
14
  export { type SignalPersistenceConfig } from './lib/state/persistance/types';
15
15
  export * from './lib/utils';
16
+ export * from './lib/tmp/useQuery$';
17
+ export * from './lib/tmp/useMutation$';
16
18
  export * from './lib/queries/react/mutations/useMutation';
17
19
  export * from './lib/queries/react/queries/useQuery';
18
20
  export * from './lib/queries/react/useQueryClient';
package/dist/index.js CHANGED
@@ -11,8 +11,9 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
11
11
  var _trigger$, _mutationRunner, _currentMutationSubject, _visibility$, _focusedSubject, _client, _currentQuery, _fetchSubject, _currentQueryInitialState, _lastResult, _lastQueryWithDefinedData, _observers, _observerCount, _cancelSubject, _executeSubject, _store, _defaultOptions, _initialState, _notifySubject, _store2, _mutationCache, _queryCache, _mutationDefaults, _queryDefaults, _defaultOptions2;
12
12
  import * as React from "react";
13
13
  import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, useState, createContext, memo, useContext } from "react";
14
- import { isObservable, from, of, defer, distinctUntilChanged, tap, catchError, EMPTY, Subject, BehaviorSubject, skip, first, map, switchMap, zip, share, merge, throttleTime, asyncScheduler, concatMap, NEVER, scan, throwError, timer, Observable, takeWhile, filter, last, mergeMap as mergeMap$1, takeUntil, identity, shareReplay, ignoreElements, fromEvent, noop as noop$1, startWith, pairwise, delay, interval, withLatestFrom, retry, iif, isEmpty, concat, toArray, take, combineLatest, endWith, lastValueFrom } from "rxjs";
14
+ import { isObservable, from, of, defer, startWith, identity, distinctUntilChanged, tap, catchError, EMPTY, Subject, BehaviorSubject, skip, first, map, switchMap, zip, share, merge, throttleTime, asyncScheduler, concatMap, scan, throwError, timer, finalize, take, Observable, takeWhile, filter, last, mergeMap as mergeMap$1, takeUntil, shareReplay, ignoreElements, fromEvent, noop as noop$1, pairwise, NEVER, delay, interval, withLatestFrom, retry, iif, isEmpty, concat, toArray, combineLatest, endWith, lastValueFrom } from "rxjs";
15
15
  import { catchError as catchError$1, mergeMap, retryWhen, concatMap as concatMap$1, first as first$1, tap as tap$1 } from "rxjs/operators";
16
+ import { useQueryClient as useQueryClient$1, useQuery as useQuery$1, useMutation as useMutation$1 } from "@tanstack/react-query";
16
17
  import { jsxs, jsx } from "react/jsx-runtime";
17
18
  const useLiveRef = (value) => {
18
19
  const ref = useRef(value);
@@ -43,7 +44,8 @@ function makeObservable(something) {
43
44
  function useObserve(source$, optionsOrDeps, maybeDeps) {
44
45
  const options = optionsOrDeps != null && !Array.isArray(optionsOrDeps) ? optionsOrDeps : {
45
46
  defaultValue: void 0,
46
- unsubscribeOnUnmount: true
47
+ unsubscribeOnUnmount: true,
48
+ compareFn: void 0
47
49
  };
48
50
  const deps = !maybeDeps && Array.isArray(optionsOrDeps) ? optionsOrDeps : typeof source$ === "function" ? maybeDeps ?? [] : [source$];
49
51
  const valueRef = useRef(
@@ -55,13 +57,15 @@ function useObserve(source$, optionsOrDeps, maybeDeps) {
55
57
  (next) => {
56
58
  const source = sourceRef.current;
57
59
  const sub = makeObservable(source).pipe(
60
+ optionsRef.current.defaultValue ? startWith(optionsRef.current.defaultValue) : identity,
58
61
  /**
59
- * @important
60
- * We only check primitives because underlying subscription might
61
- * be using objects and keeping same reference but pushing new
62
- * properties values
62
+ * @important there is already a Object.is comparison in place from react
63
+ * so we only add a custom compareFn if provided
63
64
  */
64
- distinctUntilChanged((a, b) => a === b),
65
+ optionsRef.current.compareFn ? distinctUntilChanged((a, b) => {
66
+ if (a === void 0 || b === void 0) return false;
67
+ return optionsRef.current.compareFn(a, b);
68
+ }) : identity,
65
69
  tap((value) => {
66
70
  valueRef.current = value;
67
71
  }),
@@ -187,7 +191,7 @@ function signal(config = {}) {
187
191
  default: config.default,
188
192
  key: config.key
189
193
  };
190
- const { default: defaultValue } = normalizedConfig ?? {};
194
+ const { default: defaultValue } = normalizedConfig;
191
195
  const subject = new BehaviorSubject(defaultValue);
192
196
  const setValue = (arg) => {
193
197
  const update = (value) => {
@@ -458,6 +462,28 @@ function persistSignals({
458
462
  )
459
463
  );
460
464
  }
465
+ function shallowEqual(objA, objB) {
466
+ if (objA === null || objA === void 0 || objB === void 0) {
467
+ return objA === objB;
468
+ }
469
+ if (typeof objA !== "object" || typeof objB !== "object") {
470
+ return objA === objB;
471
+ }
472
+ if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
473
+ return false;
474
+ }
475
+ const keysA = Object.keys(objA);
476
+ const keysB = Object.keys(objB);
477
+ if (keysA.length !== keysB.length) {
478
+ return false;
479
+ }
480
+ for (const key of keysA) {
481
+ if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
482
+ return false;
483
+ }
484
+ }
485
+ return true;
486
+ }
461
487
  function usePersistSignals({
462
488
  entries = [],
463
489
  onHydrated,
@@ -469,18 +495,21 @@ function usePersistSignals({
469
495
  return useObserve(
470
496
  () => {
471
497
  const persistence$ = adapterSubject.current.pipe(
472
- concatMap((adapter2) => {
473
- if (!adapter2) return NEVER;
474
- return entriesSubject.current.pipe(
475
- concatMap(
476
- (entries2) => persistSignals({
477
- adapter: adapter2,
478
- entries: entries2,
479
- onHydrated: () => {
480
- var _a;
481
- (_a = onHydratedRef.current) == null ? void 0 : _a.call(onHydratedRef);
482
- }
483
- })
498
+ switchMap((adapter2) => {
499
+ if (!adapter2) return of({ type: "reset" });
500
+ return merge(
501
+ of({ type: "reset" }),
502
+ entriesSubject.current.pipe(
503
+ concatMap(
504
+ (entries2) => persistSignals({
505
+ adapter: adapter2,
506
+ entries: entries2,
507
+ onHydrated: () => {
508
+ var _a;
509
+ (_a = onHydratedRef.current) == null ? void 0 : _a.call(onHydratedRef);
510
+ }
511
+ })
512
+ )
484
513
  )
485
514
  );
486
515
  })
@@ -488,6 +517,7 @@ function usePersistSignals({
488
517
  return persistence$.pipe(
489
518
  scan(
490
519
  (acc, event) => {
520
+ if (event.type === "reset") return { isHydrated: false };
491
521
  if (event.type === "hydrated") return { isHydrated: true };
492
522
  return acc;
493
523
  },
@@ -495,8 +525,8 @@ function usePersistSignals({
495
525
  )
496
526
  );
497
527
  },
498
- { defaultValue: { isHydrated: false } },
499
- [adapterSubject]
528
+ { defaultValue: { isHydrated: false }, compareFn: shallowEqual },
529
+ [adapterSubject, entriesSubject]
500
530
  );
501
531
  }
502
532
  const useUnmountObservable = () => {
@@ -605,6 +635,90 @@ function isDefined(arg) {
605
635
  }
606
636
  const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
607
637
  const isServer = typeof window === "undefined" || "Deno" in window;
638
+ function useQuery$(options, queryClient) {
639
+ const sub = useRef();
640
+ const _queryClient = useQueryClient$1(queryClient);
641
+ const queryFnAsync = (context) => {
642
+ let isResolved = false;
643
+ return new Promise((resolve, reject) => {
644
+ let lastData = void 0;
645
+ if (sub.current) {
646
+ sub.current.unsubscribe();
647
+ sub.current = void 0;
648
+ }
649
+ const unsub = _queryClient.getQueryCache().subscribe((d) => {
650
+ var _a;
651
+ if (d.type === "observerRemoved" && d.query.observers.length === 0) {
652
+ unsub();
653
+ _queryClient.cancelQueries({ queryKey: context.queryKey });
654
+ (_a = sub.current) == null ? void 0 : _a.unsubscribe();
655
+ }
656
+ });
657
+ const source = defer(
658
+ () => typeof options.queryFn === "function" ? options.queryFn(context) : options.queryFn
659
+ );
660
+ sub.current = source.pipe(
661
+ finalize(() => {
662
+ unsub();
663
+ isResolved = true;
664
+ })
665
+ ).subscribe({
666
+ next: (data) => {
667
+ lastData = data;
668
+ _queryClient == null ? void 0 : _queryClient.setQueryData(context.queryKey, data);
669
+ },
670
+ error: (error) => {
671
+ isResolved = true;
672
+ reject(error);
673
+ },
674
+ complete: () => {
675
+ if (lastData === void 0)
676
+ return reject(new Error("Stream completed without any data"));
677
+ if (isResolved) return;
678
+ isResolved = true;
679
+ resolve(lastData);
680
+ }
681
+ });
682
+ });
683
+ };
684
+ const result = useQuery$1(
685
+ {
686
+ ...options,
687
+ queryFn: queryFnAsync
688
+ },
689
+ queryClient
690
+ );
691
+ return result;
692
+ }
693
+ function useMutation$(options, queryClient) {
694
+ const mutationFnAsync = (variables) => {
695
+ let lastData;
696
+ return new Promise((resolve, reject) => {
697
+ const source = typeof options.mutationFn === "function" ? options.mutationFn(variables) : options.mutationFn;
698
+ source.pipe(take(1)).subscribe({
699
+ next: (data) => {
700
+ lastData = data;
701
+ },
702
+ error: (error) => {
703
+ reject(error);
704
+ },
705
+ complete: () => {
706
+ if (lastData === void 0)
707
+ return reject(new Error("Stream completed without any data"));
708
+ resolve(lastData);
709
+ }
710
+ });
711
+ });
712
+ };
713
+ const result = useMutation$1(
714
+ {
715
+ ...options,
716
+ mutationFn: mutationFnAsync
717
+ },
718
+ queryClient
719
+ );
720
+ return result;
721
+ }
608
722
  function hasObjectPrototype(o) {
609
723
  return Object.prototype.toString.call(o) === "[object Object]";
610
724
  }
@@ -771,28 +885,6 @@ const matchKey = (keyA, keyB, { exact = false } = {}) => {
771
885
  }
772
886
  return partialMatchKey(keyA, keyB);
773
887
  };
774
- function shallowEqual(objA, objB) {
775
- if (objA === null || objA === void 0 || objB === void 0) {
776
- return objA === objB;
777
- }
778
- if (typeof objA !== "object" || typeof objB !== "object") {
779
- return objA === objB;
780
- }
781
- if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
782
- return false;
783
- }
784
- const keysA = Object.keys(objA);
785
- const keysB = Object.keys(objB);
786
- if (keysA.length !== keysB.length) {
787
- return false;
788
- }
789
- for (const key of keysA) {
790
- if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
791
- return false;
792
- }
793
- }
794
- return true;
795
- }
796
888
  const distinctUntilStateChanged = (stream) => stream.pipe(
797
889
  distinctUntilChanged(
798
890
  ({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
@@ -1954,12 +2046,17 @@ const executeMutation = ({
1954
2046
  const isPaused = state.isPaused;
1955
2047
  const defaultFn = async () => await Promise.reject(new Error("No mutationFn found"));
1956
2048
  const mutationFn = options.mutationFn ?? defaultFn;
1957
- const contextFromOnMutate$ = makeObservable(
1958
- // eslint-disable-next-line @typescript-eslint/promise-function-async
1959
- () => {
1960
- var _a;
1961
- return ((_a = options.onMutate) == null ? void 0 : _a.call(options, variables)) ?? void 0;
1962
- }
2049
+ const onMutateFactory = () => {
2050
+ var _a;
2051
+ return ((_a = options.onMutate) == null ? void 0 : _a.call(options, variables)) ?? void 0;
2052
+ };
2053
+ const contextFromOnMutate$ = makeObservable(onMutateFactory);
2054
+ contextFromOnMutate$.pipe(
2055
+ tap((context) => {
2056
+ if (context === void 0) {
2057
+ throw new Error("onMutate returned undefined");
2058
+ }
2059
+ })
1963
2060
  );
1964
2061
  const rawContext$ = of(state.context);
1965
2062
  const context$ = iif(() => isPaused, rawContext$, contextFromOnMutate$).pipe(
@@ -1987,10 +2084,7 @@ const executeMutation = ({
1987
2084
  };
1988
2085
  const queryRunner$ = context$.pipe(
1989
2086
  switchMap((context) => {
1990
- const fn$ = typeof mutationFn === "function" ? (
1991
- // eslint-disable-next-line @typescript-eslint/promise-function-async
1992
- makeObservable(() => mutationFn(variables))
1993
- ) : mutationFn;
2087
+ const fn$ = typeof mutationFn === "function" ? makeObservable(() => mutationFn(variables)) : mutationFn;
1994
2088
  const sharedFn$ = fn$.pipe(share());
1995
2089
  const completeWithoutValue$ = sharedFn$.pipe(
1996
2090
  isEmpty(),
@@ -2167,6 +2261,7 @@ class Mutation {
2167
2261
  return (_b = (_a = mutationCache.config).onMutate) == null ? void 0 : _b.call(
2168
2262
  _a,
2169
2263
  variables2,
2264
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2170
2265
  this
2171
2266
  );
2172
2267
  }
@@ -2190,6 +2285,7 @@ class Mutation {
2190
2285
  error,
2191
2286
  variables2,
2192
2287
  context,
2288
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2193
2289
  this
2194
2290
  );
2195
2291
  }
@@ -2212,6 +2308,7 @@ class Mutation {
2212
2308
  error,
2213
2309
  variables2,
2214
2310
  context,
2311
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2215
2312
  this
2216
2313
  );
2217
2314
  }
@@ -2233,6 +2330,7 @@ class Mutation {
2233
2330
  data,
2234
2331
  variables2,
2235
2332
  context,
2333
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2236
2334
  this
2237
2335
  );
2238
2336
  }
@@ -3389,11 +3487,13 @@ export {
3389
3487
  useLiveRef,
3390
3488
  useMount,
3391
3489
  useMutation,
3490
+ useMutation$,
3392
3491
  useObservableState,
3393
3492
  useObserve,
3394
3493
  useObserveCallback,
3395
3494
  usePersistSignals,
3396
3495
  useQuery,
3496
+ useQuery$,
3397
3497
  useQueryClient,
3398
3498
  useSignal,
3399
3499
  useSignalValue,
@@ -3,6 +3,7 @@ import { Observable, BehaviorSubject } from 'rxjs';
3
3
  interface Option<R = undefined> {
4
4
  defaultValue: R;
5
5
  unsubscribeOnUnmount?: boolean;
6
+ compareFn?: (a: R, b: R) => boolean;
6
7
  }
7
8
  export declare function useObserve<T>(source: BehaviorSubject<T>): T;
8
9
  export declare function useObserve<T>(source: Observable<T>): T | undefined;
@@ -9,18 +9,18 @@ export declare function createLogger(env: string): {
9
9
  namespace(name: string, style?: {
10
10
  backgroundColor: string;
11
11
  color: string;
12
- }): any;
12
+ }): /*elided*/ any;
13
13
  printNamespaces(): {
14
14
  namespaces: string;
15
15
  styles: string[];
16
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;
17
+ print(method: "log" | "warn" | "error" | "group", ...message: any[]): /*elided*/ any;
18
+ printWithoutNamespace(method: "log" | "warn" | "error" | "group", ...message: any[]): /*elided*/ any;
19
+ log(...message: any): /*elided*/ any;
20
+ warn(...message: any): /*elided*/ any;
21
+ error(...message: any): /*elided*/ any;
22
+ group(...message: any): /*elided*/ any;
23
+ groupEnd(): /*elided*/ any;
24
24
  };
25
25
  export declare const Logger: {
26
26
  namespaces: {
@@ -33,16 +33,16 @@ export declare const Logger: {
33
33
  namespace(name: string, style?: {
34
34
  backgroundColor: string;
35
35
  color: string;
36
- }): any;
36
+ }): /*elided*/ any;
37
37
  printNamespaces(): {
38
38
  namespaces: string;
39
39
  styles: string[];
40
40
  };
41
- print(method: "log" | "warn" | "error" | "group", ...message: any[]): any;
42
- printWithoutNamespace(method: "log" | "warn" | "error" | "group", ...message: any[]): any;
43
- log(...message: any): any;
44
- warn(...message: any): any;
45
- error(...message: any): any;
46
- group(...message: any): any;
47
- groupEnd(): any;
41
+ print(method: "log" | "warn" | "error" | "group", ...message: any[]): /*elided*/ any;
42
+ printWithoutNamespace(method: "log" | "warn" | "error" | "group", ...message: any[]): /*elided*/ any;
43
+ log(...message: any): /*elided*/ any;
44
+ warn(...message: any): /*elided*/ any;
45
+ error(...message: any): /*elided*/ any;
46
+ group(...message: any): /*elided*/ any;
47
+ groupEnd(): /*elided*/ any;
48
48
  };
@@ -1,4 +1,5 @@
1
1
  import { MutationOptions, MutationState } from './types';
2
+ import { DefaultError } from '../../types';
2
3
  export declare const executeMutation: <TData = unknown, TError = Error, TVariables = void, TContext = unknown>({ variables, state, options }: {
3
4
  variables: TVariables;
4
5
  state: MutationState<TData, TError, TVariables, TContext>;
@@ -1,2 +1,3 @@
1
+ import { DefaultError } from '../../types';
1
2
  import { MutationFilters } from '../types';
2
3
  export declare const createPredicateForFilters: <TData = unknown, TError = Error, TVariables = any, TContext = unknown>({ mutationKey, status, predicate, exact }?: MutationFilters<TData, TError, TVariables, TContext>) => (mutation: import('../mutation/Mutation').Mutation<TData, TError, TVariables, TContext>) => boolean;
@@ -1,5 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { QueryKey } from '../../../keys/types';
3
+ import { DefaultError } from '../../../types';
3
4
  import { QueryState } from '../types';
4
5
  import { QueryOptions } from '../../types';
5
6
  export declare const executeQuery: <TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: QueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
@@ -1,3 +1,4 @@
1
+ import { DefaultError } from '../../types';
1
2
  import { Observable } from 'rxjs';
2
3
  import { QueryOptions } from '../types';
3
4
  import { QueryState } from './types';
@@ -1,4 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
+ import { DefaultError } from '../../../types';
2
3
  import { QueryState } from '../types';
3
4
  export declare const whenNewData: <TQueryFnData = unknown, TError = Error, TData = TQueryFnData>(source: Observable<Partial<QueryState<TData, TError>>>) => Observable<{
4
5
  data: TData | undefined;
@@ -1,6 +1,20 @@
1
1
  import { Observable } from 'rxjs';
2
- export declare function makeObservable<Data>(fn: () => Observable<Data> | Data | Promise<Data>): Observable<Data>;
3
- export declare function makeObservable<Data>(fn: () => Data): Data extends Observable<infer ObservedData> ? Observable<ObservedData> : Data extends Promise<infer ThenData> ? Observable<ThenData> : Observable<Data>;
4
- export declare function makeObservable<Data>(fn: Data): Observable<Data>;
5
- export declare function makeObservable<Data>(fn: Promise<Data>): Observable<Data>;
2
+ type FnReturnToObservable<T> = T extends Observable<infer ObservedData> ? ObservedData : T extends Promise<infer ThenData> ? ThenData : T;
6
3
  export declare function makeObservable<Data>(fn: Observable<Data>): Observable<Data>;
4
+ export declare function makeObservable<Data>(fn: Promise<Data>): Observable<Data>;
5
+ export declare function makeObservable<Data>(fn: Promise<Data> | Observable<Data>): Observable<Data>;
6
+ export declare function makeObservable<Data>(fn: () => Promise<Data> | Observable<Data>): Observable<Data>;
7
+ /**
8
+ * Generic factory
9
+ */
10
+ export declare function makeObservable<TContext>(fn: () => Promise<TContext | undefined> | Observable<TContext | undefined> | TContext | undefined): Observable<undefined | TContext>;
11
+ /**
12
+ * Generic factory
13
+ */
14
+ export declare function makeObservable<Return>(fn: () => Return): Observable<FnReturnToObservable<Return>>;
15
+ /**
16
+ * Generic factory OR Observable
17
+ */
18
+ export declare function makeObservable<Data, Return>(fn: Observable<Data> | (() => Return)): Observable<Data | FnReturnToObservable<Return>>;
19
+ export declare function makeObservable<Data>(fn: Data): Observable<Data>;
20
+ export {};
@@ -3,6 +3,9 @@ import { Adapter } from '../persistance/adapters/Adapter';
3
3
  /**
4
4
  * Make sure to pass stable reference of entries and adapter if you don't
5
5
  * intentionally want to start over the process.
6
+ *
7
+ * `isHydrated` will be `true` after the first successful hydration. This value
8
+ * will be reset as soon as the adapter reference changes.
6
9
  */
7
10
  export declare function usePersistSignals({ entries, onHydrated, adapter }: {
8
11
  /**
@@ -0,0 +1,5 @@
1
+ import { DefaultError, QueryClient, UseMutationOptions } from '@tanstack/react-query';
2
+ import { Observable } from 'rxjs';
3
+ export declare function useMutation$<TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown>(options: Omit<UseMutationOptions<TData, TError, TVariables, TContext>, "mutationFn"> & {
4
+ mutationFn: ((variables: TVariables) => Observable<TData>) | Observable<TData>;
5
+ }, queryClient?: QueryClient): import('@tanstack/react-query').UseMutationResult<TData, TError, TVariables, TContext>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import { DefaultError, QueryClient, QueryFunctionContext, QueryKey, UseQueryOptions } from '@tanstack/react-query';
2
+ import { Observable } from 'rxjs';
3
+ export declare function useQuery$<TQueryFnData = unknown, TError = DefaultError, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryFn"> & {
4
+ queryFn: ((context: QueryFunctionContext<TQueryKey>) => Observable<TQueryFnData>) | Observable<TQueryFnData>;
5
+ }, queryClient?: QueryClient): import('@tanstack/react-query').UseQueryResult<TData, TError>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.101.0",
4
+ "version": "1.104.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -14,9 +14,6 @@
14
14
  "require": "./dist/index.umd.cjs"
15
15
  }
16
16
  },
17
- "engines": {
18
- "node": "20"
19
- },
20
17
  "types": "./dist/index.d.ts",
21
18
  "publishConfig": {
22
19
  "access": "public"
@@ -37,10 +34,10 @@
37
34
  "peerDependencies": {
38
35
  "react": "18",
39
36
  "react-dom": "18",
40
- "rxjs": "*"
37
+ "rxjs": "*",
38
+ "@tanstack/react-query": "^5.8.4"
41
39
  },
42
40
  "devDependencies": {
43
- "@tanstack/react-query": "^5.8.4",
44
41
  "@testing-library/jest-dom": "^6.2.0",
45
42
  "@testing-library/react": "^16.0.0",
46
43
  "@types/node": "^20.0.0",
@@ -61,7 +58,7 @@
61
58
  "rollup-plugin-node-externals": "^7.0.1",
62
59
  "rxjs": "^7.8.0",
63
60
  "semantic-release": "^24.1.1",
64
- "typescript": "5.6.2",
61
+ "typescript": "^5.6.2",
65
62
  "vite": "^5.1.3",
66
63
  "vite-plugin-dts": "^4.2.1",
67
64
  "vitest": "^1.3.0"