reactjrx 1.33.0 → 1.35.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
@@ -147,8 +147,8 @@ function trigger(mapper = rxjs.identity) {
147
147
  }
148
148
  const SIGNAL_RESET = Symbol("SIGNAL_RESET");
149
149
  function signal(options) {
150
- const { default: defaultValue } = options ?? {};
151
- const subject = new rxjs.BehaviorSubject(defaultValue);
150
+ const { default: defaultValue2 } = options ?? {};
151
+ const subject = new rxjs.BehaviorSubject(defaultValue2);
152
152
  const setValue = (arg) => {
153
153
  if (arg === subject.getValue())
154
154
  return;
@@ -160,7 +160,7 @@ function signal(options) {
160
160
  return;
161
161
  }
162
162
  if (arg === SIGNAL_RESET) {
163
- subject.next(defaultValue ?? void 0);
163
+ subject.next(defaultValue2 ?? void 0);
164
164
  return;
165
165
  }
166
166
  subject.next(arg);
@@ -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
  */
@@ -519,6 +519,7 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
519
519
  isLastMutationCalled
520
520
  ]).pipe(
521
521
  rxjs.map(([{ data, isError }, isLastMutationCalled2]) => {
522
+ console.log("success", { data, isLastMutationCalled: isLastMutationCalled2 });
522
523
  if (!isError) {
523
524
  if (optionsRef.current.onSuccess != null)
524
525
  optionsRef.current.onSuccess(data, args);
@@ -546,12 +547,12 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
546
547
  })
547
548
  )
548
549
  ).pipe(
550
+ rxjs.filter((state) => !!state && !!Object.keys(state).length),
549
551
  /**
550
552
  * @important
551
553
  * state update optimization
552
554
  */
553
- rxjs.distinctUntilChanged(shallowEqual),
554
- rxjs.filter((state) => !!state && !!Object.keys(state).length)
555
+ rxjs.distinctUntilChanged(shallowEqual)
555
556
  ).subscribe((state) => {
556
557
  data$.current.next({
557
558
  ...data$.current.getValue(),
@@ -579,7 +580,6 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
579
580
  }, []);
580
581
  return { ...result, isLoading: result.status === "loading", mutate, reset };
581
582
  }
582
- const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
583
583
  const useCreateCacheStore = () => {
584
584
  const cacheStore = useBehaviorSubject({});
585
585
  useSubscribe(
@@ -641,21 +641,17 @@ const useQueryStore = () => {
641
641
  const [store] = react.useState(/* @__PURE__ */ new Map());
642
642
  return store;
643
643
  };
644
- const Context = react.createContext(void 0);
645
- const Provider = react.memo(({ children }) => {
646
- const cacheStore = useCreateCacheStore();
647
- const queryStore = useQueryStore();
648
- const value = react.useMemo(() => ({ cacheStore, queryStore }), []);
649
- return /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
650
- });
651
- const useProvider = () => {
652
- const context = react.useContext(Context);
653
- return { ...context };
654
- };
655
- const serializeKey = (key) => {
656
- if (key.length === 0)
657
- return "";
658
- return JSON.stringify(key);
644
+ const DEFAULT_STALE = 9999;
645
+ const autoRefetch = (options$ = rxjs.of({})) => (source) => {
646
+ return source.pipe(
647
+ rxjs.repeat({
648
+ delay: () => options$.pipe(
649
+ rxjs.switchMap(
650
+ (options) => options.staleTime === Infinity ? rxjs.EMPTY : rxjs.timer(options.staleTime ?? DEFAULT_STALE)
651
+ )
652
+ )
653
+ })
654
+ );
659
655
  };
660
656
  const deduplicate = (key, queryStore) => (source) => {
661
657
  if (!key)
@@ -675,54 +671,151 @@ const deduplicate = (key, queryStore) => (source) => {
675
671
  }
676
672
  return finalSource;
677
673
  };
678
- const autoRefetch = (options = {}) => (source) => {
679
- if (options.staleTime === Infinity)
680
- return source;
681
- return source.pipe(
682
- rxjs.repeat({
683
- delay: options.staleTime ?? 999999
684
- })
685
- );
674
+ const serializeKey = (key) => {
675
+ if (key.length === 0)
676
+ return "";
677
+ return JSON.stringify(key);
686
678
  };
687
- function isDefined(arg) {
688
- return arg !== null && arg !== void 0;
689
- }
690
- const withKeyComparison = (stream) => stream.pipe(
691
- rxjs.startWith(void 0),
679
+ const notifyQueryResult = (options$) => (stream$) => stream$.pipe(
680
+ rxjs.withLatestFrom(options$),
681
+ rxjs.map(([result, options]) => {
682
+ var _a, _b;
683
+ if (result.error) {
684
+ (_a = options.onError) == null ? void 0 : _a.call(options, result.error);
685
+ } else {
686
+ (_b = options.onSuccess) == null ? void 0 : _b.call(options, result);
687
+ }
688
+ return result;
689
+ })
690
+ );
691
+ const mergeResults = (stream$) => stream$.pipe(
692
+ rxjs.startWith({ isLoading: false, data: void 0, error: void 0 }),
692
693
  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
- };
694
+ rxjs.map(([previous, current]) => ({
695
+ isLoading: false,
696
+ data: void 0,
697
+ error: void 0,
698
+ ...previous,
699
+ ...current
700
+ })),
701
+ rxjs.distinctUntilChanged(shallowEqual)
702
+ );
703
+ const createClient = () => {
704
+ const queryStore = /* @__PURE__ */ new Map();
705
+ const refetch$ = new rxjs.Subject();
706
+ const query$ = ({
707
+ key,
708
+ fn$,
709
+ options$
710
+ }) => {
711
+ const refetch$2 = new rxjs.Subject();
712
+ const enabled$ = options$.pipe(rxjs.map(({ enabled = true }) => enabled));
713
+ const disabled$ = enabled$.pipe(
714
+ rxjs.distinctUntilChanged(),
715
+ rxjs.filter((enabled) => !enabled)
716
+ );
717
+ const triggers = [
718
+ refetch$2.pipe(rxjs.startWith(null)),
719
+ enabled$.pipe(
720
+ rxjs.distinctUntilChanged(),
721
+ rxjs.filter((enabled) => enabled)
722
+ )
723
+ ];
724
+ const serializedKey = serializeKey(key);
725
+ const query$2 = rxjs.combineLatest(triggers).pipe(
726
+ rxjs.tap((params) => {
727
+ console.log("query$ trigger", { key, params });
728
+ }),
729
+ rxjs.withLatestFrom(fn$),
730
+ rxjs.switchMap(([, query]) => {
731
+ const deferredQuery = rxjs.defer(() => {
732
+ const queryOrResponse = typeof query === "function" ? query() : query;
733
+ return rxjs.from(queryOrResponse);
734
+ });
735
+ return rxjs.merge(
736
+ disabled$.pipe(
737
+ rxjs.take(1),
738
+ rxjs.map(() => ({
739
+ isLoading: false
740
+ }))
741
+ ),
742
+ rxjs.merge(
743
+ rxjs.of({ isLoading: true, error: void 0 }),
744
+ deferredQuery.pipe(
745
+ deduplicate(serializedKey, queryStore),
746
+ rxjs.map((result) => ({
747
+ isLoading: false,
748
+ data: { result },
749
+ error: void 0
750
+ })),
751
+ rxjs.catchError(
752
+ (error) => rxjs.of({
753
+ isLoading: false,
754
+ data: void 0,
755
+ error
756
+ })
757
+ ),
758
+ notifyQueryResult(options$)
759
+ )
760
+ ).pipe(autoRefetch(options$), rxjs.takeUntil(disabled$))
761
+ );
762
+ }),
763
+ mergeResults,
764
+ rxjs.tap((data) => {
765
+ console.log("query$ return", data);
766
+ })
767
+ );
768
+ return {
769
+ query$: query$2,
770
+ refetch$: refetch$2,
771
+ enabled$
772
+ };
773
+ };
774
+ return {
775
+ query$,
776
+ refetch$,
777
+ queryStore,
778
+ destroy: () => {
709
779
  }
710
- return void 0;
711
- }),
712
- rxjs.filter(isDefined)
780
+ };
781
+ };
782
+ const Context = react.createContext({
783
+ cacheStore: {},
784
+ client: createClient()
785
+ });
786
+ const Provider = react.memo(
787
+ ({
788
+ children,
789
+ client
790
+ }) => {
791
+ const cacheStore = useCreateCacheStore();
792
+ const queryStore = useQueryStore();
793
+ const value = react.useMemo(() => ({ cacheStore, queryStore, client }), [client]);
794
+ react.useEffect(
795
+ () => () => {
796
+ client.destroy();
797
+ },
798
+ [client]
799
+ );
800
+ return /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
801
+ }
713
802
  );
803
+ const useProvider = () => {
804
+ const context = react.useContext(Context);
805
+ return { ...context };
806
+ };
807
+ const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
808
+ function isDefined(arg) {
809
+ return arg !== null && arg !== void 0;
810
+ }
811
+ const defaultValue = { data: void 0, isLoading: true, error: void 0 };
714
812
  function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
715
813
  const query = Array.isArray(keyOrQuery) ? queryOrOptionOrNothing : keyOrQuery;
716
814
  const options = optionsOrNothing ?? (queryOrOptionOrNothing !== query ? queryOrOptionOrNothing : void 0) ?? {};
815
+ const internalRefresh$ = useSubject();
816
+ const { client } = useProvider();
717
817
  const key = Array.isArray(keyOrQuery) ? keyOrQuery : void 0;
718
818
  const params$ = useBehaviorSubject({ key, options, query });
719
- const refetch$ = useSubject();
720
- const data$ = useBehaviorSubject({
721
- data: void 0,
722
- error: void 0,
723
- isLoading: true
724
- });
725
- const { queryStore } = useProvider();
726
819
  react.useEffect(() => {
727
820
  params$.current.next({
728
821
  key,
@@ -730,104 +823,81 @@ function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
730
823
  query
731
824
  });
732
825
  }, [key, options, query]);
733
- useSubscribe(() => {
734
- const options$ = params$.current.pipe(
735
- rxjs.map(({ options: options2 }) => options2),
736
- rxjs.distinctUntilChanged(shallowEqual)
737
- );
738
- const newKeyReceived$ = params$.current.pipe(
739
- rxjs.map(({ key: key2 }) => key2 ?? []),
740
- rxjs.distinctUntilChanged(arrayEqual)
741
- );
742
- const newQuery$ = params$.current.pipe(
743
- rxjs.map(({ query: query2 }) => query2 ?? (() => rxjs.of(void 0)))
744
- );
745
- const queryAsObservableObjectChanged$ = newQuery$.pipe(
746
- rxjs.filter((query2) => typeof query2 !== "function"),
747
- rxjs.distinctUntilChanged(shallowEqual)
748
- );
749
- const enabledOptionChanged$ = options$.pipe(
750
- rxjs.map(({ enabled = true }) => enabled),
751
- rxjs.distinctUntilChanged(),
752
- rxjs.share()
753
- );
754
- const queryTrigger$ = rxjs.combineLatest([
755
- newKeyReceived$,
756
- enabledOptionChanged$,
757
- queryAsObservableObjectChanged$.pipe(rxjs.startWith(void 0)),
758
- refetch$.current.pipe(rxjs.startWith(void 0))
759
- ]);
760
- const disabled$ = enabledOptionChanged$.pipe(
761
- rxjs.filter((enabled) => !enabled),
762
- rxjs.tap(() => {
763
- data$.current.next({
764
- ...data$.current.getValue(),
765
- isLoading: false
766
- });
767
- })
768
- );
769
- return queryTrigger$.pipe(
770
- rxjs.withLatestFrom(options$, newQuery$),
771
- rxjs.map(([[key2, enabled], options2, query2]) => ({
772
- key: key2,
773
- enabled,
774
- options: options2,
775
- query: query2
776
- })),
777
- withKeyComparison,
778
- rxjs.filter(({ enabled }) => enabled),
779
- rxjs.switchMap(({ key: key2, options: options2, isUsingDifferentKey, query: query2 }) => {
780
- const serializedKey = serializeKey(key2);
781
- return rxjs.of(null).pipe(
782
- rxjs.tap(() => {
783
- data$.current.next({
784
- ...data$.current.getValue(),
785
- data: isUsingDifferentKey ? void 0 : data$.current.getValue().data,
786
- error: void 0,
787
- isLoading: true
788
- });
789
- }),
790
- rxjs.switchMap(() => {
791
- const query$ = rxjs.defer(() => {
792
- const queryOrResponse = typeof query2 === "function" ? query2() : query2;
793
- return rxjs.from(queryOrResponse);
794
- });
795
- return query$.pipe(
796
- querx(options2),
797
- deduplicate(serializedKey, queryStore),
798
- // key.length > 0 ? withCache(key) : identity,
799
- rxjs.map((response) => [response]),
800
- rxjs.catchError((error) => {
801
- return rxjs.of([void 0, error]);
802
- }),
803
- rxjs.tap(([response, error]) => {
804
- if (response) {
805
- if (options2.onSuccess != null)
806
- options2.onSuccess(response);
807
- }
808
- data$.current.next({
809
- ...data$.current.getValue(),
810
- isLoading: false,
811
- error,
812
- data: response
813
- });
814
- })
815
- );
816
- }),
817
- autoRefetch(options2),
818
- rxjs.takeUntil(disabled$)
819
- );
820
- })
821
- );
822
- }, []);
823
826
  const result = useObserve(
824
- () => data$.current,
825
- { defaultValue: data$.current.getValue() },
826
- []
827
+ () => {
828
+ const computedDefaultValue = {
829
+ ...defaultValue,
830
+ isLoading: params$.current.getValue().options.enabled !== false
831
+ };
832
+ const newKeyReceived$ = params$.current.pipe(
833
+ rxjs.map(({ key: key2 }) => key2 ?? []),
834
+ rxjs.distinctUntilChanged(arrayEqual)
835
+ );
836
+ const newObservableObjectQuery$ = params$.current.pipe(
837
+ rxjs.map(({ query: query2 }) => query2),
838
+ rxjs.distinctUntilChanged(shallowEqual),
839
+ rxjs.skip(1),
840
+ rxjs.filter((query2) => !!query2 && typeof query2 !== "function"),
841
+ rxjs.startWith(params$.current.getValue().query),
842
+ rxjs.filter(isDefined)
843
+ );
844
+ const fn$ = params$.current.pipe(
845
+ rxjs.map(({ query: query2 }) => query2),
846
+ rxjs.filter(isDefined)
847
+ );
848
+ const options$ = params$.current.pipe(rxjs.map(({ options: options2 }) => options2));
849
+ const triggers$ = rxjs.combineLatest([
850
+ newKeyReceived$,
851
+ newObservableObjectQuery$
852
+ ]);
853
+ return triggers$.pipe(
854
+ rxjs.switchMap(([key2]) => {
855
+ const { query$, refetch$ } = client.query$({
856
+ key: key2,
857
+ fn$,
858
+ options$
859
+ });
860
+ const subscriptions = [internalRefresh$.current.subscribe(refetch$)];
861
+ return query$.pipe(
862
+ rxjs.finalize(() => {
863
+ subscriptions.forEach((sub) => {
864
+ sub.unsubscribe();
865
+ });
866
+ }),
867
+ rxjs.startWith(computedDefaultValue),
868
+ rxjs.pairwise(),
869
+ rxjs.map(
870
+ ([
871
+ { data: previousData, ...restPrevious },
872
+ { data: currentData, ...restCurrent }
873
+ ]) => ({
874
+ ...restPrevious,
875
+ ...restCurrent,
876
+ data: currentData && "result" in currentData ? currentData.result : previousData == null ? void 0 : previousData.result
877
+ })
878
+ )
879
+ );
880
+ }),
881
+ /**
882
+ * @important
883
+ * We skip the first result as it is comparable to default passed value.
884
+ * This is assuming all query are async and does not return a result right away.
885
+ * This is a design choice.
886
+ */
887
+ params$.current.getValue().options.enabled !== false ? rxjs.skip(1) : rxjs.identity
888
+ );
889
+ },
890
+ {
891
+ defaultValue: {
892
+ ...defaultValue,
893
+ isLoading: params$.current.getValue().options.enabled !== false
894
+ }
895
+ },
896
+ [client]
827
897
  );
828
- const refetch = react.useCallback((arg) => {
829
- refetch$.current.next(arg);
830
- }, []);
898
+ const refetch = react.useCallback(() => {
899
+ internalRefresh$.current.next();
900
+ }, [client]);
831
901
  return { ...result, refetch };
832
902
  }
833
903
  function useSubscribeEffect(source, unsafeOptions, deps = []) {
@@ -853,6 +923,7 @@ function useSubscribeEffect(source, unsafeOptions, deps = []) {
853
923
  exports.PersistSignals = PersistSignals;
854
924
  exports.ReactjrxQueryProvider = Provider;
855
925
  exports.SIGNAL_RESET = SIGNAL_RESET;
926
+ exports.createClient = createClient;
856
927
  exports.createLocalforageAdapter = createLocalforageAdapter;
857
928
  exports.createSharedStoreAdapter = createSharedStoreAdapter;
858
929
  exports.exponentialBackoffDelay = exponentialBackoffDelay;
@@ -860,8 +931,8 @@ exports.getDelay = getDelay;
860
931
  exports.retryBackoff = retryBackoff;
861
932
  exports.signal = signal;
862
933
  exports.trigger = trigger;
934
+ exports.useAsyncQuery = useAsyncQuery;
863
935
  exports.useLiveRef = useLiveRef;
864
- exports.useMutation = useMutation;
865
936
  exports.useObserve = useObserve;
866
937
  exports.useObserveCallback = useObserveCallback;
867
938
  exports.usePersistSignalsContext = usePersistSignalsContext;
@@ -870,6 +941,7 @@ exports.useScopeSignals = useScopeSignals;
870
941
  exports.useSetSignal = useSetSignal;
871
942
  exports.useSignal = useSignal;
872
943
  exports.useSignalValue = useSignalValue;
944
+ exports.useSubject = useSubject;
873
945
  exports.useSubscribe = useSubscribe;
874
946
  exports.useSubscribeEffect = useSubscribeEffect;
875
947
  exports.useUnmountObservable = useUnmountObservable;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from "./lib/binding/useObserve";
2
2
  export * from "./lib/binding/useSubscribe";
3
3
  export * from "./lib/binding/useObserveCallback";
4
4
  export * from "./lib/binding/trigger";
5
+ export * from "./lib/binding/useSubject";
5
6
  export * from "./lib/state/signal";
6
7
  export * from "./lib/state/useSignal";
7
8
  export * from "./lib/state/useSetSignal";
@@ -15,7 +16,8 @@ export * from "./lib/state/persistance/createLocalforageAdapter";
15
16
  export * from "./lib/utils/useUnmountObservable";
16
17
  export * from "./lib/utils/retryBackoff";
17
18
  export * from "./lib/utils/useLiveRef";
18
- export * from "./lib/queries/useMutation";
19
+ export * from "./lib/queries/useAsyncQuery";
19
20
  export * from "./lib/queries/useQuery";
20
21
  export * from "./lib/queries/useSubscribeEffect";
22
+ export * from "./lib/queries/client/createClient";
21
23
  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, pairwise, 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, repeat, shareReplay, pairwise, 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) => {
@@ -145,8 +145,8 @@ function trigger(mapper = identity) {
145
145
  }
146
146
  const SIGNAL_RESET = Symbol("SIGNAL_RESET");
147
147
  function signal(options) {
148
- const { default: defaultValue } = options ?? {};
149
- const subject = new BehaviorSubject(defaultValue);
148
+ const { default: defaultValue2 } = options ?? {};
149
+ const subject = new BehaviorSubject(defaultValue2);
150
150
  const setValue = (arg) => {
151
151
  if (arg === subject.getValue())
152
152
  return;
@@ -158,7 +158,7 @@ function signal(options) {
158
158
  return;
159
159
  }
160
160
  if (arg === SIGNAL_RESET) {
161
- subject.next(defaultValue ?? void 0);
161
+ subject.next(defaultValue2 ?? void 0);
162
162
  return;
163
163
  }
164
164
  subject.next(arg);
@@ -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
  */
@@ -517,6 +517,7 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
517
517
  isLastMutationCalled
518
518
  ]).pipe(
519
519
  map(([{ data, isError }, isLastMutationCalled2]) => {
520
+ console.log("success", { data, isLastMutationCalled: isLastMutationCalled2 });
520
521
  if (!isError) {
521
522
  if (optionsRef.current.onSuccess != null)
522
523
  optionsRef.current.onSuccess(data, args);
@@ -544,12 +545,12 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
544
545
  })
545
546
  )
546
547
  ).pipe(
548
+ filter((state) => !!state && !!Object.keys(state).length),
547
549
  /**
548
550
  * @important
549
551
  * state update optimization
550
552
  */
551
- distinctUntilChanged(shallowEqual),
552
- filter((state) => !!state && !!Object.keys(state).length)
553
+ distinctUntilChanged(shallowEqual)
553
554
  ).subscribe((state) => {
554
555
  data$.current.next({
555
556
  ...data$.current.getValue(),
@@ -577,7 +578,6 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
577
578
  }, []);
578
579
  return { ...result, isLoading: result.status === "loading", mutate, reset };
579
580
  }
580
- const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
581
581
  const useCreateCacheStore = () => {
582
582
  const cacheStore = useBehaviorSubject({});
583
583
  useSubscribe(
@@ -639,21 +639,17 @@ const useQueryStore = () => {
639
639
  const [store] = useState(/* @__PURE__ */ new Map());
640
640
  return store;
641
641
  };
642
- const Context = createContext(void 0);
643
- const Provider = memo(({ children }) => {
644
- const cacheStore = useCreateCacheStore();
645
- const queryStore = useQueryStore();
646
- const value = useMemo(() => ({ cacheStore, queryStore }), []);
647
- return /* @__PURE__ */ jsx(Context.Provider, { value, children });
648
- });
649
- const useProvider = () => {
650
- const context = useContext(Context);
651
- return { ...context };
652
- };
653
- const serializeKey = (key) => {
654
- if (key.length === 0)
655
- return "";
656
- return JSON.stringify(key);
642
+ const DEFAULT_STALE = 9999;
643
+ const autoRefetch = (options$ = of({})) => (source) => {
644
+ return source.pipe(
645
+ repeat({
646
+ delay: () => options$.pipe(
647
+ switchMap(
648
+ (options) => options.staleTime === Infinity ? EMPTY : timer(options.staleTime ?? DEFAULT_STALE)
649
+ )
650
+ )
651
+ })
652
+ );
657
653
  };
658
654
  const deduplicate = (key, queryStore) => (source) => {
659
655
  if (!key)
@@ -673,54 +669,151 @@ const deduplicate = (key, queryStore) => (source) => {
673
669
  }
674
670
  return finalSource;
675
671
  };
676
- const autoRefetch = (options = {}) => (source) => {
677
- if (options.staleTime === Infinity)
678
- return source;
679
- return source.pipe(
680
- repeat({
681
- delay: options.staleTime ?? 999999
682
- })
683
- );
672
+ const serializeKey = (key) => {
673
+ if (key.length === 0)
674
+ return "";
675
+ return JSON.stringify(key);
684
676
  };
685
- function isDefined(arg) {
686
- return arg !== null && arg !== void 0;
687
- }
688
- const withKeyComparison = (stream) => stream.pipe(
689
- startWith(void 0),
677
+ const notifyQueryResult = (options$) => (stream$) => stream$.pipe(
678
+ withLatestFrom(options$),
679
+ map(([result, options]) => {
680
+ var _a, _b;
681
+ if (result.error) {
682
+ (_a = options.onError) == null ? void 0 : _a.call(options, result.error);
683
+ } else {
684
+ (_b = options.onSuccess) == null ? void 0 : _b.call(options, result);
685
+ }
686
+ return result;
687
+ })
688
+ );
689
+ const mergeResults = (stream$) => stream$.pipe(
690
+ startWith({ isLoading: false, data: void 0, error: void 0 }),
690
691
  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
- };
692
+ map(([previous, current]) => ({
693
+ isLoading: false,
694
+ data: void 0,
695
+ error: void 0,
696
+ ...previous,
697
+ ...current
698
+ })),
699
+ distinctUntilChanged(shallowEqual)
700
+ );
701
+ const createClient = () => {
702
+ const queryStore = /* @__PURE__ */ new Map();
703
+ const refetch$ = new Subject();
704
+ const query$ = ({
705
+ key,
706
+ fn$,
707
+ options$
708
+ }) => {
709
+ const refetch$2 = new Subject();
710
+ const enabled$ = options$.pipe(map(({ enabled = true }) => enabled));
711
+ const disabled$ = enabled$.pipe(
712
+ distinctUntilChanged(),
713
+ filter((enabled) => !enabled)
714
+ );
715
+ const triggers = [
716
+ refetch$2.pipe(startWith(null)),
717
+ enabled$.pipe(
718
+ distinctUntilChanged(),
719
+ filter((enabled) => enabled)
720
+ )
721
+ ];
722
+ const serializedKey = serializeKey(key);
723
+ const query$2 = combineLatest(triggers).pipe(
724
+ tap((params) => {
725
+ console.log("query$ trigger", { key, params });
726
+ }),
727
+ withLatestFrom(fn$),
728
+ switchMap(([, query]) => {
729
+ const deferredQuery = defer(() => {
730
+ const queryOrResponse = typeof query === "function" ? query() : query;
731
+ return from(queryOrResponse);
732
+ });
733
+ return merge(
734
+ disabled$.pipe(
735
+ take(1),
736
+ map(() => ({
737
+ isLoading: false
738
+ }))
739
+ ),
740
+ merge(
741
+ of({ isLoading: true, error: void 0 }),
742
+ deferredQuery.pipe(
743
+ deduplicate(serializedKey, queryStore),
744
+ map((result) => ({
745
+ isLoading: false,
746
+ data: { result },
747
+ error: void 0
748
+ })),
749
+ catchError(
750
+ (error) => of({
751
+ isLoading: false,
752
+ data: void 0,
753
+ error
754
+ })
755
+ ),
756
+ notifyQueryResult(options$)
757
+ )
758
+ ).pipe(autoRefetch(options$), takeUntil(disabled$))
759
+ );
760
+ }),
761
+ mergeResults,
762
+ tap((data) => {
763
+ console.log("query$ return", data);
764
+ })
765
+ );
766
+ return {
767
+ query$: query$2,
768
+ refetch$: refetch$2,
769
+ enabled$
770
+ };
771
+ };
772
+ return {
773
+ query$,
774
+ refetch$,
775
+ queryStore,
776
+ destroy: () => {
707
777
  }
708
- return void 0;
709
- }),
710
- filter(isDefined)
778
+ };
779
+ };
780
+ const Context = createContext({
781
+ cacheStore: {},
782
+ client: createClient()
783
+ });
784
+ const Provider = memo(
785
+ ({
786
+ children,
787
+ client
788
+ }) => {
789
+ const cacheStore = useCreateCacheStore();
790
+ const queryStore = useQueryStore();
791
+ const value = useMemo(() => ({ cacheStore, queryStore, client }), [client]);
792
+ useEffect(
793
+ () => () => {
794
+ client.destroy();
795
+ },
796
+ [client]
797
+ );
798
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
799
+ }
711
800
  );
801
+ const useProvider = () => {
802
+ const context = useContext(Context);
803
+ return { ...context };
804
+ };
805
+ const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
806
+ function isDefined(arg) {
807
+ return arg !== null && arg !== void 0;
808
+ }
809
+ const defaultValue = { data: void 0, isLoading: true, error: void 0 };
712
810
  function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
713
811
  const query = Array.isArray(keyOrQuery) ? queryOrOptionOrNothing : keyOrQuery;
714
812
  const options = optionsOrNothing ?? (queryOrOptionOrNothing !== query ? queryOrOptionOrNothing : void 0) ?? {};
813
+ const internalRefresh$ = useSubject();
814
+ const { client } = useProvider();
715
815
  const key = Array.isArray(keyOrQuery) ? keyOrQuery : void 0;
716
816
  const params$ = useBehaviorSubject({ key, options, query });
717
- const refetch$ = useSubject();
718
- const data$ = useBehaviorSubject({
719
- data: void 0,
720
- error: void 0,
721
- isLoading: true
722
- });
723
- const { queryStore } = useProvider();
724
817
  useEffect(() => {
725
818
  params$.current.next({
726
819
  key,
@@ -728,104 +821,81 @@ function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
728
821
  query
729
822
  });
730
823
  }, [key, options, query]);
731
- useSubscribe(() => {
732
- const options$ = params$.current.pipe(
733
- map(({ options: options2 }) => options2),
734
- distinctUntilChanged(shallowEqual)
735
- );
736
- const newKeyReceived$ = params$.current.pipe(
737
- map(({ key: key2 }) => key2 ?? []),
738
- distinctUntilChanged(arrayEqual)
739
- );
740
- const newQuery$ = params$.current.pipe(
741
- map(({ query: query2 }) => query2 ?? (() => of(void 0)))
742
- );
743
- const queryAsObservableObjectChanged$ = newQuery$.pipe(
744
- filter((query2) => typeof query2 !== "function"),
745
- distinctUntilChanged(shallowEqual)
746
- );
747
- const enabledOptionChanged$ = options$.pipe(
748
- map(({ enabled = true }) => enabled),
749
- distinctUntilChanged(),
750
- share()
751
- );
752
- const queryTrigger$ = combineLatest([
753
- newKeyReceived$,
754
- enabledOptionChanged$,
755
- queryAsObservableObjectChanged$.pipe(startWith(void 0)),
756
- refetch$.current.pipe(startWith(void 0))
757
- ]);
758
- const disabled$ = enabledOptionChanged$.pipe(
759
- filter((enabled) => !enabled),
760
- tap(() => {
761
- data$.current.next({
762
- ...data$.current.getValue(),
763
- isLoading: false
764
- });
765
- })
766
- );
767
- return queryTrigger$.pipe(
768
- withLatestFrom(options$, newQuery$),
769
- map(([[key2, enabled], options2, query2]) => ({
770
- key: key2,
771
- enabled,
772
- options: options2,
773
- query: query2
774
- })),
775
- withKeyComparison,
776
- filter(({ enabled }) => enabled),
777
- switchMap(({ key: key2, options: options2, isUsingDifferentKey, query: query2 }) => {
778
- const serializedKey = serializeKey(key2);
779
- return of(null).pipe(
780
- tap(() => {
781
- data$.current.next({
782
- ...data$.current.getValue(),
783
- data: isUsingDifferentKey ? void 0 : data$.current.getValue().data,
784
- error: void 0,
785
- isLoading: true
786
- });
787
- }),
788
- switchMap(() => {
789
- const query$ = defer(() => {
790
- const queryOrResponse = typeof query2 === "function" ? query2() : query2;
791
- return from(queryOrResponse);
792
- });
793
- return query$.pipe(
794
- querx(options2),
795
- deduplicate(serializedKey, queryStore),
796
- // key.length > 0 ? withCache(key) : identity,
797
- map((response) => [response]),
798
- catchError((error) => {
799
- return of([void 0, error]);
800
- }),
801
- tap(([response, error]) => {
802
- if (response) {
803
- if (options2.onSuccess != null)
804
- options2.onSuccess(response);
805
- }
806
- data$.current.next({
807
- ...data$.current.getValue(),
808
- isLoading: false,
809
- error,
810
- data: response
811
- });
812
- })
813
- );
814
- }),
815
- autoRefetch(options2),
816
- takeUntil(disabled$)
817
- );
818
- })
819
- );
820
- }, []);
821
824
  const result = useObserve(
822
- () => data$.current,
823
- { defaultValue: data$.current.getValue() },
824
- []
825
+ () => {
826
+ const computedDefaultValue = {
827
+ ...defaultValue,
828
+ isLoading: params$.current.getValue().options.enabled !== false
829
+ };
830
+ const newKeyReceived$ = params$.current.pipe(
831
+ map(({ key: key2 }) => key2 ?? []),
832
+ distinctUntilChanged(arrayEqual)
833
+ );
834
+ const newObservableObjectQuery$ = params$.current.pipe(
835
+ map(({ query: query2 }) => query2),
836
+ distinctUntilChanged(shallowEqual),
837
+ skip(1),
838
+ filter((query2) => !!query2 && typeof query2 !== "function"),
839
+ startWith(params$.current.getValue().query),
840
+ filter(isDefined)
841
+ );
842
+ const fn$ = params$.current.pipe(
843
+ map(({ query: query2 }) => query2),
844
+ filter(isDefined)
845
+ );
846
+ const options$ = params$.current.pipe(map(({ options: options2 }) => options2));
847
+ const triggers$ = combineLatest([
848
+ newKeyReceived$,
849
+ newObservableObjectQuery$
850
+ ]);
851
+ return triggers$.pipe(
852
+ switchMap(([key2]) => {
853
+ const { query$, refetch$ } = client.query$({
854
+ key: key2,
855
+ fn$,
856
+ options$
857
+ });
858
+ const subscriptions = [internalRefresh$.current.subscribe(refetch$)];
859
+ return query$.pipe(
860
+ finalize(() => {
861
+ subscriptions.forEach((sub) => {
862
+ sub.unsubscribe();
863
+ });
864
+ }),
865
+ startWith(computedDefaultValue),
866
+ pairwise(),
867
+ map(
868
+ ([
869
+ { data: previousData, ...restPrevious },
870
+ { data: currentData, ...restCurrent }
871
+ ]) => ({
872
+ ...restPrevious,
873
+ ...restCurrent,
874
+ data: currentData && "result" in currentData ? currentData.result : previousData == null ? void 0 : previousData.result
875
+ })
876
+ )
877
+ );
878
+ }),
879
+ /**
880
+ * @important
881
+ * We skip the first result as it is comparable to default passed value.
882
+ * This is assuming all query are async and does not return a result right away.
883
+ * This is a design choice.
884
+ */
885
+ params$.current.getValue().options.enabled !== false ? skip(1) : identity
886
+ );
887
+ },
888
+ {
889
+ defaultValue: {
890
+ ...defaultValue,
891
+ isLoading: params$.current.getValue().options.enabled !== false
892
+ }
893
+ },
894
+ [client]
825
895
  );
826
- const refetch = useCallback((arg) => {
827
- refetch$.current.next(arg);
828
- }, []);
896
+ const refetch = useCallback(() => {
897
+ internalRefresh$.current.next();
898
+ }, [client]);
829
899
  return { ...result, refetch };
830
900
  }
831
901
  function useSubscribeEffect(source, unsafeOptions, deps = []) {
@@ -852,6 +922,7 @@ export {
852
922
  PersistSignals,
853
923
  Provider as ReactjrxQueryProvider,
854
924
  SIGNAL_RESET,
925
+ createClient,
855
926
  createLocalforageAdapter,
856
927
  createSharedStoreAdapter,
857
928
  exponentialBackoffDelay,
@@ -859,8 +930,8 @@ export {
859
930
  retryBackoff,
860
931
  signal,
861
932
  trigger,
933
+ useAsyncQuery,
862
934
  useLiveRef,
863
- useMutation,
864
935
  useObserve,
865
936
  useObserveCallback,
866
937
  usePersistSignalsContext,
@@ -869,6 +940,7 @@ export {
869
940
  useSetSignal,
870
941
  useSignal,
871
942
  useSignalValue,
943
+ useSubject,
872
944
  useSubscribe,
873
945
  useSubscribeEffect,
874
946
  useUnmountObservable,
@@ -10,6 +10,6 @@ interface Option<R = undefined> {
10
10
  export declare function useObserve<T>(source: BehaviorSubject<T>): T;
11
11
  export declare function useObserve<T>(source: Observable<T>): T | undefined;
12
12
  export declare function useObserve<T>(source: () => Observable<T>, deps: DependencyList): T | undefined;
13
- export declare function useObserve<T, R = undefined>(source: Observable<T>, options: Option<R>): T | R;
14
- export declare function useObserve<T, R = undefined>(source: () => Observable<T>, options: Option<R>, deps: DependencyList): T | R;
13
+ export declare function useObserve<T>(source: Observable<T>, options: Option<T>): T;
14
+ export declare function useObserve<T>(source: () => Observable<T>, options: Option<T>, deps: DependencyList): T;
15
15
  export {};
@@ -1,5 +1,6 @@
1
1
  import { type ReactNode } from "react";
2
2
  import { type BehaviorSubject } from "rxjs";
3
+ import { createClient } from "./client/createClient";
3
4
  type CacheStore = Record<string, {
4
5
  value: any;
5
6
  date: number;
@@ -9,15 +10,16 @@ export declare const Context: import("react").Context<{
9
10
  cacheStore: {
10
11
  current: BehaviorSubject<CacheStore>;
11
12
  };
12
- queryStore: import("./deduplication/useQueryStore").QueryStore;
13
- } | undefined>;
14
- export declare const Provider: import("react").MemoExoticComponent<({ children }: {
13
+ client: ReturnType<typeof createClient>;
14
+ }>;
15
+ export declare const Provider: import("react").MemoExoticComponent<({ children, client }: {
15
16
  children: ReactNode;
17
+ client: ReturnType<typeof createClient>;
16
18
  }) => import("react/jsx-runtime").JSX.Element>;
17
19
  export declare const useProvider: () => {
18
- cacheStore?: {
20
+ cacheStore: {
19
21
  current: BehaviorSubject<CacheStore>;
20
- } | undefined;
21
- queryStore?: import("./deduplication/useQueryStore").QueryStore | undefined;
22
+ };
23
+ client: ReturnType<typeof createClient>;
22
24
  };
23
25
  export {};
@@ -0,0 +1,21 @@
1
+ import { type Observable, Subject } from "rxjs";
2
+ import { type QuerxOptions } from "../types";
3
+ import { type QueryResult } from "./types";
4
+ type Query<T> = (() => Promise<T>) | (() => Observable<T>) | Observable<T>;
5
+ export declare const createClient: () => {
6
+ query$: <T>({ key, fn$, options$ }: {
7
+ key: any[];
8
+ fn$: Observable<Query<T>>;
9
+ options$: Observable<QuerxOptions<T>>;
10
+ }) => {
11
+ query$: Observable<QueryResult<T>>;
12
+ refetch$: Subject<void>;
13
+ enabled$: Observable<boolean>;
14
+ };
15
+ refetch$: Subject<{
16
+ key: any[];
17
+ }>;
18
+ queryStore: Map<any, any>;
19
+ destroy: () => void;
20
+ };
21
+ export {};
@@ -0,0 +1,5 @@
1
+ import { type Observable } from "rxjs";
2
+ import { type QuerxOptions } from "../types";
3
+ import { type QueryResult } from "./types";
4
+ export declare const notifyQueryResult: <T>(options$: Observable<QuerxOptions<T>>) => (stream$: Observable<Partial<QueryResult<T>>>) => Observable<Partial<QueryResult<T>>>;
5
+ export declare const mergeResults: <T>(stream$: Observable<Partial<QueryResult<T>>>) => Observable<QueryResult<T>>;
@@ -0,0 +1,7 @@
1
+ export interface QueryResult<T> {
2
+ data: {
3
+ result: T;
4
+ } | undefined;
5
+ isLoading: boolean;
6
+ error: unknown;
7
+ }
@@ -1,4 +1,4 @@
1
1
  import { type Observable } from "rxjs";
2
- export declare const autoRefetch: <T>(options?: {
2
+ export declare const autoRefetch: <T>(options$?: Observable<{
3
3
  staleTime?: number;
4
- }) => (source: Observable<T>) => Observable<T>;
4
+ }>) => (source: Observable<T>) => Observable<T>;
@@ -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 {};
@@ -1,2 +1,2 @@
1
1
  import { type Signal } from "./signal";
2
- export declare const useSignal: <S, R>(signal: Signal<S, R>) => readonly [S | R, (stateOrUpdater: typeof import("./constants").SIGNAL_RESET | S | ((prev: S) => S)) => void];
2
+ export declare const useSignal: <S>(signal: Signal<S, S>) => readonly [S, (stateOrUpdater: typeof import("./constants").SIGNAL_RESET | S | ((prev: S) => S)) => void];
@@ -1,2 +1,2 @@
1
1
  import { type Signal } from "./signal";
2
- export declare const useSignalValue: <S, R>(signal: Signal<S, R>, key?: string) => S | R;
2
+ export declare const useSignalValue: <S>(signal: Signal<S, S>, key?: string) => S;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.33.0",
4
+ "version": "1.35.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -1,16 +0,0 @@
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)>;