reactjrx 1.34.0 → 1.40.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.
Files changed (54) hide show
  1. package/dist/index.cjs +1047 -248
  2. package/dist/index.d.ts +6 -4
  3. package/dist/index.js +1049 -250
  4. package/dist/lib/binding/useObserve.d.ts +2 -2
  5. package/dist/lib/logger.d.ts +48 -0
  6. package/dist/lib/queries/client/cache/cacheClient.d.ts +12 -0
  7. package/dist/lib/queries/client/cache/invalidateCache.d.ts +5 -0
  8. package/dist/lib/queries/client/cache/logger.d.ts +24 -0
  9. package/dist/lib/queries/client/cache/registerResultInCache.d.ts +8 -0
  10. package/dist/lib/queries/client/createClient.d.ts +73 -0
  11. package/dist/lib/queries/client/deduplication/deduplicate.d.ts +3 -0
  12. package/dist/lib/queries/client/fetch/mapWithComplete.d.ts +4 -0
  13. package/dist/lib/queries/client/fetch/notifyQueryResult.d.ts +3 -0
  14. package/dist/lib/queries/client/fetch/queryFetch.d.ts +12 -0
  15. package/dist/lib/queries/client/invalidation/invalidationClient.d.ts +12 -0
  16. package/dist/lib/queries/client/invalidation/logger.d.ts +24 -0
  17. package/dist/lib/queries/client/invalidation/markAsStale.d.ts +8 -0
  18. package/dist/lib/queries/client/keys/compareKeys.d.ts +4 -0
  19. package/dist/lib/queries/client/keys/serializeKey.d.ts +3 -0
  20. package/dist/lib/queries/client/keys/types.d.ts +10 -0
  21. package/dist/lib/queries/client/operators.d.ts +4 -0
  22. package/dist/lib/queries/client/refetch/client.d.ts +18 -0
  23. package/dist/lib/queries/client/store/createQueryStore.d.ts +55 -0
  24. package/dist/lib/queries/client/store/debugger.d.ts +3 -0
  25. package/dist/lib/queries/client/store/garbageCache.d.ts +5 -0
  26. package/dist/lib/queries/client/store/initializeQueryInStore.d.ts +8 -0
  27. package/dist/lib/queries/client/store/mapStoreQueryToRunnerOptions.d.ts +4 -0
  28. package/dist/lib/queries/client/store/queryListener.d.ts +3 -0
  29. package/dist/lib/queries/client/store/updateStoreWithQuery.d.ts +14 -0
  30. package/dist/lib/queries/client/triggers.d.ts +17 -0
  31. package/dist/lib/queries/client/types.d.ts +48 -0
  32. package/dist/lib/queries/react/Provider.d.ts +12 -0
  33. package/dist/lib/queries/react/helpers.d.ts +27 -0
  34. package/dist/lib/queries/react/triggers/activityTrigger.d.ts +9 -0
  35. package/dist/lib/queries/react/triggers/networkTrigger.d.ts +7 -0
  36. package/dist/lib/queries/react/types.d.ts +13 -0
  37. package/dist/lib/queries/react/useQuery.d.ts +6 -0
  38. package/dist/lib/state/useSignal.d.ts +1 -1
  39. package/dist/lib/state/useSignalValue.d.ts +1 -1
  40. package/dist/lib/utils/difference.d.ts +1 -0
  41. package/package.json +1 -1
  42. package/dist/lib/queries/Provider.d.ts +0 -23
  43. package/dist/lib/queries/cache/useCreateCacheStore.d.ts +0 -9
  44. package/dist/lib/queries/deduplication/deduplicate.d.ts +0 -3
  45. package/dist/lib/queries/deduplication/useQueryStore.d.ts +0 -3
  46. package/dist/lib/queries/invalidation/autoRefetch.d.ts +0 -4
  47. package/dist/lib/queries/keys/serializeKey.d.ts +0 -1
  48. package/dist/lib/queries/keys/withKeyComparison.d.ts +0 -16
  49. package/dist/lib/queries/operators.d.ts +0 -2
  50. package/dist/lib/queries/querx.d.ts +0 -3
  51. package/dist/lib/queries/types.d.ts +0 -10
  52. package/dist/lib/queries/useQuery.d.ts +0 -12
  53. /package/dist/lib/queries/{useAsyncQuery.d.ts → react/useAsyncQuery.d.ts} +0 -0
  54. /package/dist/lib/queries/{useSubscribeEffect.d.ts → react/useSubscribeEffect.d.ts} +0 -0
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);
@@ -411,15 +411,6 @@ function retryBackoff(config) {
411
411
  );
412
412
  });
413
413
  }
414
- const retryFromOptions = (options) => retryBackoff({
415
- initialInterval: 100,
416
- ...typeof options.retry === "function" ? {
417
- shouldRetry: options.retry
418
- } : {
419
- maxRetries: options.retry === false ? 0 : options.retry ?? 3
420
- }
421
- });
422
- const querx = (options) => (source) => source.pipe(retryFromOptions(options));
423
414
  const useBehaviorSubject = (state) => {
424
415
  const subject = useConstant(() => new rxjs.BehaviorSubject(state));
425
416
  const completed = react.useRef(false);
@@ -459,6 +450,31 @@ function shallowEqual(objA, objB) {
459
450
  }
460
451
  return true;
461
452
  }
453
+ const retryOnError = (options) => retryBackoff({
454
+ initialInterval: 100,
455
+ ...typeof options.retry === "function" ? {
456
+ shouldRetry: options.retry
457
+ } : {
458
+ maxRetries: options.retry === false ? 0 : options.retry ?? 3
459
+ }
460
+ });
461
+ const mergeResults = (stream$) => stream$.pipe(
462
+ rxjs.scan(
463
+ (acc, current) => {
464
+ return {
465
+ ...acc,
466
+ ...current
467
+ };
468
+ },
469
+ {
470
+ data: void 0,
471
+ error: void 0,
472
+ fetchStatus: "idle",
473
+ status: "loading"
474
+ }
475
+ ),
476
+ rxjs.distinctUntilChanged(shallowEqual)
477
+ );
462
478
  function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
463
479
  const queryRef = useLiveRef(query);
464
480
  const triggerSubject = useSubject();
@@ -505,7 +521,7 @@ function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
505
521
  }),
506
522
  rxjs.combineLatest([
507
523
  rxjs.defer(() => rxjs.from(queryRef.current(args))).pipe(
508
- querx(optionsRef.current),
524
+ retryOnError(optionsRef.current),
509
525
  rxjs.first(),
510
526
  rxjs.map((data) => ({ data, isError: false })),
511
527
  rxjs.catchError((error) => {
@@ -546,12 +562,12 @@ function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
546
562
  })
547
563
  )
548
564
  ).pipe(
565
+ rxjs.filter((state) => !!state && !!Object.keys(state).length),
549
566
  /**
550
567
  * @important
551
568
  * state update optimization
552
569
  */
553
- rxjs.distinctUntilChanged(shallowEqual),
554
- rxjs.filter((state) => !!state && !!Object.keys(state).length)
570
+ rxjs.distinctUntilChanged(shallowEqual)
555
571
  ).subscribe((state) => {
556
572
  data$.current.next({
557
573
  ...data$.current.getValue(),
@@ -579,255 +595,168 @@ function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
579
595
  }, []);
580
596
  return { ...result, isLoading: result.status === "loading", mutate, reset };
581
597
  }
582
- const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
583
- const useCreateCacheStore = () => {
584
- const cacheStore = useBehaviorSubject({});
585
- useSubscribe(
586
- () => cacheStore.current.pipe(
587
- rxjs.skip(1),
588
- rxjs.tap(() => {
589
- const store = cacheStore.current.getValue();
590
- console.log(
591
- "[cache] update",
592
- Object.keys(store).reduce((acc, key) => {
593
- const entry = store[key];
594
- if (entry != null) {
595
- acc[key] = entry;
596
- }
597
- acc[key]._debug = {
598
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
599
- // @ts-expect-error
600
- eol: new Date(store[key].date + store[key].ttl)
601
- };
602
- return acc;
603
- }, {})
604
- );
605
- })
606
- ),
607
- [cacheStore]
608
- );
609
- useSubscribe(
610
- () => rxjs.interval(1e3).pipe(
611
- rxjs.withLatestFrom(cacheStore.current),
612
- rxjs.tap(() => {
613
- const now = (/* @__PURE__ */ new Date()).getTime();
614
- const store = cacheStore.current.getValue();
615
- const keys = Object.keys(store);
616
- const validKeys = keys.filter((key) => {
617
- const value = store[key];
618
- if (value != null && value.date + value.ttl > now) {
619
- return true;
620
- }
621
- return false;
622
- });
623
- if (validKeys.length === keys.length) {
624
- return;
625
- }
626
- const newStore = validKeys.reduce((acc, key) => {
627
- const entry = store[key];
628
- if (entry != null) {
629
- acc[key] = entry;
630
- }
631
- return acc;
632
- }, {});
633
- cacheStore.current.next(newStore);
634
- })
635
- ),
636
- [cacheStore]
637
- );
638
- return cacheStore;
639
- };
640
- const useQueryStore = () => {
641
- const [store] = react.useState(/* @__PURE__ */ new Map());
642
- return store;
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 });
598
+ const Context = react.createContext({
599
+ client: null
650
600
  });
651
- const useProvider = () => {
601
+ const Provider = react.memo(
602
+ ({
603
+ children,
604
+ client
605
+ }) => {
606
+ const value = react.useMemo(() => ({ client }), [client]);
607
+ react.useEffect(
608
+ () => () => {
609
+ client.destroy();
610
+ },
611
+ [client]
612
+ );
613
+ return /* @__PURE__ */ jsxRuntime.jsx(Context.Provider, { value, children });
614
+ }
615
+ );
616
+ const useReactJrxProvider = () => {
652
617
  const context = react.useContext(Context);
618
+ if (context === null) {
619
+ throw new Error("You forgot to register the provider");
620
+ }
653
621
  return { ...context };
654
622
  };
655
- const serializeKey = (key) => {
656
- if (key.length === 0)
657
- return "";
658
- return JSON.stringify(key);
659
- };
660
- const deduplicate = (key, queryStore) => (source) => {
661
- if (!key)
662
- return source;
663
- const sourceFromStore = queryStore == null ? void 0 : queryStore.get(key);
664
- const finalSource = sourceFromStore ?? source.pipe(
665
- rxjs.finalize(() => {
666
- queryStore == null ? void 0 : queryStore.delete(key);
667
- }),
668
- rxjs.shareReplay({
669
- refCount: true,
670
- bufferSize: 1
623
+ const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
624
+ function isDefined(arg) {
625
+ return arg !== null && arg !== void 0;
626
+ }
627
+ const createActivityTrigger = (params$) => {
628
+ return params$.pipe(
629
+ rxjs.switchMap(({ options: { refetchOnWindowFocus = true } }) => {
630
+ const shouldRunTrigger = typeof refetchOnWindowFocus === "function" ? refetchOnWindowFocus({}) : refetchOnWindowFocus;
631
+ return shouldRunTrigger !== false ? rxjs.merge(
632
+ rxjs.fromEvent(document, "visibilitychange").pipe(
633
+ rxjs.filter(() => !document.hidden),
634
+ rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
635
+ ),
636
+ rxjs.fromEvent(window, "focus").pipe(
637
+ rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
638
+ )
639
+ ) : rxjs.EMPTY;
671
640
  })
672
641
  );
673
- if (sourceFromStore == null) {
674
- queryStore == null ? void 0 : queryStore.set(key, finalSource);
675
- }
676
- return finalSource;
677
642
  };
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
643
+ const createNetworkTrigger = (params$) => {
644
+ return params$.pipe(
645
+ rxjs.switchMap(({ options: { refetchOnReconnect = true } }) => {
646
+ const shouldRunTrigger = typeof refetchOnReconnect === "function" ? refetchOnReconnect({}) : refetchOnReconnect;
647
+ return shouldRunTrigger !== false ? rxjs.fromEvent(window, "online").pipe(
648
+ rxjs.map(() => ({ ignoreStale: shouldRunTrigger === "always" }))
649
+ ) : rxjs.EMPTY;
684
650
  })
685
651
  );
686
652
  };
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
- );
714
- function useQuery(keyOrQuery, queryOrOptionOrNothing, optionsOrNothing) {
715
- const query = Array.isArray(keyOrQuery) ? queryOrOptionOrNothing : keyOrQuery;
716
- const options = optionsOrNothing ?? (queryOrOptionOrNothing !== query ? queryOrOptionOrNothing : void 0) ?? {};
717
- const key = Array.isArray(keyOrQuery) ? keyOrQuery : void 0;
718
- 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();
653
+ const useQueryParams = ({
654
+ queryKey,
655
+ queryFn,
656
+ ...options
657
+ }) => {
658
+ const params$ = useBehaviorSubject({ queryKey, options, queryFn });
726
659
  react.useEffect(() => {
727
660
  params$.current.next({
728
- key,
661
+ queryKey,
729
662
  options,
730
- query
663
+ queryFn
731
664
  });
732
- }, [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
- }, []);
665
+ }, [queryKey, options, queryFn]);
666
+ return params$;
667
+ };
668
+ const defaultValue = {
669
+ data: void 0,
670
+ isLoading: true,
671
+ error: void 0,
672
+ status: "loading",
673
+ fetchStatus: "idle"
674
+ };
675
+ function useQuery({
676
+ queryKey,
677
+ queryFn,
678
+ ...options
679
+ }) {
680
+ const internalRefresh$ = useSubject();
681
+ const { client } = useReactJrxProvider();
682
+ const params$ = useQueryParams({ queryFn, queryKey, ...options });
823
683
  const result = useObserve(
824
- () => data$.current,
825
- { defaultValue: data$.current.getValue() },
826
- []
684
+ () => {
685
+ const key$ = params$.current.pipe(rxjs.map(({ queryKey: queryKey2 }) => queryKey2 ?? []));
686
+ const initialTrigger$ = rxjs.of(null);
687
+ const newKeyTrigger$ = key$.pipe(
688
+ rxjs.distinctUntilChanged(arrayEqual),
689
+ rxjs.skip(1)
690
+ );
691
+ const isQueryObject = (query) => !!query && typeof query !== "function";
692
+ const newObservableObjectQuery$ = params$.current.pipe(
693
+ rxjs.map(({ queryFn: queryFn2 }) => queryFn2),
694
+ rxjs.filter(isQueryObject),
695
+ rxjs.distinctUntilChanged(shallowEqual),
696
+ isQueryObject(params$.current.getValue().queryFn) ? rxjs.skip(1) : rxjs.identity
697
+ );
698
+ const fn$ = params$.current.pipe(
699
+ rxjs.map(({ queryFn: queryFn2 }) => queryFn2),
700
+ rxjs.filter(isDefined)
701
+ );
702
+ const options$ = params$.current.pipe(rxjs.map(({ options: options2 }) => options2));
703
+ const activityRefetch$ = createActivityTrigger(params$.current);
704
+ const networkRefetch$ = createNetworkTrigger(params$.current);
705
+ const newQueryTrigger$ = rxjs.merge(
706
+ initialTrigger$,
707
+ newKeyTrigger$,
708
+ newObservableObjectQuery$
709
+ );
710
+ const refetch$ = rxjs.merge(
711
+ internalRefresh$.current.pipe(rxjs.map(() => ({ ignoreStale: true }))),
712
+ rxjs.merge(activityRefetch$, networkRefetch$).pipe(rxjs.throttleTime(500))
713
+ );
714
+ return newQueryTrigger$.pipe(
715
+ rxjs.withLatestFrom(key$),
716
+ rxjs.switchMap(([, key]) => {
717
+ const { result$ } = client.query$({
718
+ key,
719
+ fn$,
720
+ options$,
721
+ refetch$
722
+ });
723
+ return result$.pipe(
724
+ rxjs.scan(
725
+ (previousValue, { data: currentData, ...currentValue }) => ({
726
+ data: void 0,
727
+ ...previousValue,
728
+ ...currentValue,
729
+ isLoading: currentValue.status === "loading",
730
+ ...currentData && {
731
+ data: currentData.result
732
+ }
733
+ }),
734
+ {}
735
+ )
736
+ );
737
+ })
738
+ /**
739
+ * @important
740
+ * We skip the first result as it is comparable to default passed value.
741
+ * This is assuming all query are async and does not return a result right away.
742
+ * This is a design choice.
743
+ */
744
+ // params$.current.getValue().options.enabled !== false
745
+ // ? skip(1)
746
+ // : identity
747
+ );
748
+ },
749
+ {
750
+ defaultValue: {
751
+ ...defaultValue,
752
+ isLoading: params$.current.getValue().options.enabled !== false
753
+ }
754
+ },
755
+ [client]
827
756
  );
828
- const refetch = react.useCallback((arg) => {
829
- refetch$.current.next(arg);
830
- }, []);
757
+ const refetch = react.useCallback(() => {
758
+ internalRefresh$.current.next();
759
+ }, [client]);
831
760
  return { ...result, refetch };
832
761
  }
833
762
  function useSubscribeEffect(source, unsafeOptions, deps = []) {
@@ -850,9 +779,877 @@ function useSubscribeEffect(source, unsafeOptions, deps = []) {
850
779
  );
851
780
  useSubscribe(enhancerMakeObservable, deps);
852
781
  }
782
+ const serializeObject = (object) => {
783
+ if (Array.isArray(object)) {
784
+ return object.reduce((acc, value, index) => {
785
+ if (index === object.length - 1)
786
+ return `${acc}${serializeObject(value)}]`;
787
+ return `${acc}${serializeObject(value)},`;
788
+ }, "[");
789
+ }
790
+ if (object === void 0)
791
+ return "";
792
+ return JSON.stringify(object, Object.keys(object).sort());
793
+ };
794
+ const serializeKey = (key) => {
795
+ if (key.length === 0)
796
+ return "[]";
797
+ return serializeObject(key);
798
+ };
799
+ const resetStyle = { backgroundColor: "transparent", color: "inherit" };
800
+ function createLogger(env) {
801
+ const _logger = {
802
+ namespaces: [
803
+ { name: "@reactjrx", style: { backgroundColor: "#d02f4e", color: "white" } }
804
+ ],
805
+ namespace(name, style) {
806
+ const logger2 = createLogger(env);
807
+ logger2.namespaces.push({
808
+ name,
809
+ style: style ?? resetStyle
810
+ });
811
+ return logger2;
812
+ },
813
+ printNamespaces() {
814
+ return {
815
+ namespaces: _logger.namespaces.map(({ name }) => `%c ${name} %c`).join(" "),
816
+ styles: _logger.namespaces.reduce((acc, { style }) => {
817
+ acc.push(
818
+ `background-color: ${style.backgroundColor}; color: ${style.color};`
819
+ );
820
+ acc.push("background-color: transparent; color: inherit;");
821
+ return acc;
822
+ }, [])
823
+ };
824
+ },
825
+ print(method, ...message) {
826
+ if (env === "development") {
827
+ const { namespaces, styles } = _logger.printNamespaces();
828
+ console[method](namespaces, ...styles, ...message);
829
+ }
830
+ return _logger;
831
+ },
832
+ printWithoutNamespace(method, ...message) {
833
+ if (env === "development") {
834
+ console[method](...message);
835
+ }
836
+ return _logger;
837
+ },
838
+ log(...message) {
839
+ return _logger.print("log", ...message);
840
+ },
841
+ warn(...message) {
842
+ return _logger.print("warn", ...message);
843
+ },
844
+ error(...message) {
845
+ return _logger.print("error", ...message);
846
+ },
847
+ group(...message) {
848
+ return _logger.print("group", ...message);
849
+ },
850
+ groupEnd() {
851
+ if (env === "development") {
852
+ console.groupEnd();
853
+ }
854
+ return _logger;
855
+ }
856
+ };
857
+ return _logger;
858
+ }
859
+ const Logger = createLogger("development");
860
+ const logger$3 = Logger.namespace("store");
861
+ const createDebugger = (store$) => {
862
+ return store$.pipe(
863
+ rxjs.map(
864
+ (value) => [...value.keys()].reduce((acc, key) => {
865
+ var _a;
866
+ acc[key] = (_a = value.get(key)) == null ? void 0 : _a.getValue();
867
+ return acc;
868
+ }, {})
869
+ ),
870
+ rxjs.distinctUntilChanged(shallowEqual)
871
+ ).subscribe((value) => {
872
+ logger$3.log("store", "update", value);
873
+ });
874
+ };
875
+ const createQueryStore = () => {
876
+ const store = /* @__PURE__ */ new Map();
877
+ const store$ = new rxjs.BehaviorSubject(store);
878
+ const queryEventSubject = new rxjs.Subject();
879
+ const queryTriggerSubject = new rxjs.Subject();
880
+ const notify = () => {
881
+ store$.next(store);
882
+ };
883
+ const setValue = (key, value) => {
884
+ store.set(key, new rxjs.BehaviorSubject(value));
885
+ notify();
886
+ };
887
+ const getValue = (serializedKey) => {
888
+ var _a;
889
+ return (_a = store.get(serializedKey)) == null ? void 0 : _a.getValue();
890
+ };
891
+ const getValue$ = (key) => {
892
+ return store$.pipe(
893
+ rxjs.map(() => store.get(key)),
894
+ rxjs.filter(isDefined),
895
+ rxjs.map((entry) => entry.getValue()),
896
+ rxjs.distinctUntilChanged(shallowEqual)
897
+ );
898
+ };
899
+ const updateValue = (key, value) => {
900
+ const existingObject = store.get(key);
901
+ if (!existingObject)
902
+ return;
903
+ if (typeof value === "function") {
904
+ existingObject.next({
905
+ ...existingObject.getValue(),
906
+ ...value(existingObject.getValue())
907
+ });
908
+ } else {
909
+ existingObject.next({ ...existingObject.getValue(), ...value });
910
+ }
911
+ store$.next(store);
912
+ };
913
+ const updateMany = (value, predicate = () => true) => {
914
+ store.forEach((oldValue$) => {
915
+ const oldValue = oldValue$.getValue();
916
+ if (predicate(oldValue)) {
917
+ oldValue$.next({ ...oldValue, ...value });
918
+ }
919
+ });
920
+ store$.next(store);
921
+ };
922
+ const deleteValue = (key) => {
923
+ store.delete(key);
924
+ store$.next(store);
925
+ };
926
+ const addRunner = (key, stream) => {
927
+ updateValue(key, (old) => ({
928
+ ...old,
929
+ runners: [...old.runners, stream]
930
+ }));
931
+ return () => {
932
+ var _a;
933
+ const newListeners = ((_a = store.get(key)) == null ? void 0 : _a.getValue().runners.filter((reference) => reference !== stream)) ?? [];
934
+ updateValue(key, (old) => ({
935
+ ...old,
936
+ runners: newListeners
937
+ }));
938
+ };
939
+ };
940
+ const debugger$ = createDebugger(store$);
941
+ return {
942
+ set: setValue,
943
+ get: getValue,
944
+ get$: getValue$,
945
+ delete: deleteValue,
946
+ update: updateValue,
947
+ keys: () => store.keys(),
948
+ updateMany,
949
+ addRunner,
950
+ store$,
951
+ queryEvent$: queryEventSubject.asObservable(),
952
+ dispatchQueryEvent: (event) => {
953
+ queryEventSubject.next(event);
954
+ },
955
+ queryTrigger$: queryTriggerSubject.asObservable(),
956
+ dispatchQueryTrigger: (event) => {
957
+ queryTriggerSubject.next(event);
958
+ },
959
+ size: () => store.size,
960
+ destroy: () => {
961
+ debugger$.unsubscribe();
962
+ queryEventSubject.complete();
963
+ queryTriggerSubject.complete();
964
+ }
965
+ };
966
+ };
967
+ const createQueryTrigger = ({
968
+ refetch$,
969
+ options$,
970
+ queryStore,
971
+ key
972
+ }) => {
973
+ const enabledOption$ = options$.pipe(
974
+ rxjs.map(({ enabled = true }) => enabled),
975
+ rxjs.distinctUntilChanged()
976
+ );
977
+ const enabledTrigger$ = enabledOption$.pipe(
978
+ rxjs.skip(1),
979
+ rxjs.filter((enabled) => enabled)
980
+ );
981
+ return rxjs.merge(
982
+ queryStore.queryTrigger$.pipe(
983
+ rxjs.filter((event) => key === event.key),
984
+ rxjs.map(({ trigger: trigger2 }) => trigger2)
985
+ ),
986
+ refetch$.pipe(
987
+ rxjs.map((event) => ({
988
+ ...event,
989
+ type: "refetch"
990
+ }))
991
+ ),
992
+ enabledTrigger$.pipe(
993
+ rxjs.map(() => ({
994
+ type: "enabled",
995
+ ignoreStale: false
996
+ }))
997
+ )
998
+ );
999
+ };
1000
+ const deduplicate = (key, queryStore) => (source) => {
1001
+ if (key === serializeKey([]))
1002
+ return source;
1003
+ return rxjs.defer(() => {
1004
+ var _a;
1005
+ const sourceFromStore = (_a = queryStore.get(key)) == null ? void 0 : _a.deduplication_fn;
1006
+ const deleteFromStore = () => {
1007
+ queryStore.update(key, {
1008
+ deduplication_fn: void 0
1009
+ });
1010
+ };
1011
+ const finalSource = sourceFromStore ?? source.pipe(
1012
+ /**
1013
+ * Ideally we would want to remove the query from the store only on finalize,
1014
+ * which means whenever the query complete or error. Unfortunately finalize is
1015
+ * triggered after a new stream arrive which create a concurrency issue.
1016
+ * tap is triggered correctly synchronously and before a new query arrive.
1017
+ */
1018
+ rxjs.tap({
1019
+ error: deleteFromStore,
1020
+ complete: deleteFromStore
1021
+ }),
1022
+ /**
1023
+ * Because tap is not called on unsubscription we still need to handle the case.
1024
+ */
1025
+ rxjs.finalize(deleteFromStore),
1026
+ rxjs.shareReplay({
1027
+ refCount: true,
1028
+ bufferSize: 1
1029
+ })
1030
+ );
1031
+ if (!sourceFromStore) {
1032
+ queryStore.update(key, {
1033
+ deduplication_fn: finalSource
1034
+ });
1035
+ }
1036
+ return finalSource;
1037
+ });
1038
+ };
1039
+ const notifyQueryResult = (options$) => (stream$) => stream$.pipe(
1040
+ rxjs.withLatestFrom(options$),
1041
+ rxjs.map(([result, options]) => {
1042
+ var _a, _b;
1043
+ if (result.error) {
1044
+ (_a = options.onError) == null ? void 0 : _a.call(options, result.error);
1045
+ } else {
1046
+ (_b = options.onSuccess) == null ? void 0 : _b.call(options, result);
1047
+ }
1048
+ return result;
1049
+ })
1050
+ );
1051
+ const registerResultInCache = ({
1052
+ queryStore,
1053
+ serializedKey,
1054
+ options
1055
+ }) => (stream) => stream.pipe(
1056
+ rxjs.tap((result) => {
1057
+ queryStore.update(serializedKey, {
1058
+ ...options.cacheTime !== 0 && {
1059
+ cache_fnResult: { result }
1060
+ }
1061
+ });
1062
+ })
1063
+ );
1064
+ const mapWithComplete = (mapFn) => (stream) => {
1065
+ return stream.pipe(rxjs.map(mapFn({ isComplete: false })));
1066
+ };
1067
+ const createQueryFetch = ({
1068
+ options$,
1069
+ options,
1070
+ fn,
1071
+ queryStore,
1072
+ serializedKey,
1073
+ trigger: trigger2,
1074
+ trigger$
1075
+ }) => {
1076
+ const enabledOption$ = options$.pipe(
1077
+ rxjs.map(({ enabled = true }) => enabled),
1078
+ rxjs.distinctUntilChanged()
1079
+ );
1080
+ const disabled$ = enabledOption$.pipe(
1081
+ rxjs.distinctUntilChanged(),
1082
+ rxjs.filter((enabled) => !enabled)
1083
+ );
1084
+ const deferredQuery = rxjs.defer(() => {
1085
+ const queryOrResponse = typeof fn === "function" ? fn() : fn;
1086
+ return rxjs.from(queryOrResponse);
1087
+ });
1088
+ const fnExecution$ = deferredQuery.pipe(
1089
+ retryOnError(options),
1090
+ deduplicate(serializedKey, queryStore),
1091
+ rxjs.tap(() => {
1092
+ queryStore.dispatchQueryEvent({
1093
+ key: serializedKey,
1094
+ type: "fetchSuccess"
1095
+ });
1096
+ queryStore.update(serializedKey, {
1097
+ lastFetchedAt: (/* @__PURE__ */ new Date()).getTime()
1098
+ });
1099
+ }),
1100
+ registerResultInCache({ serializedKey, options, queryStore }),
1101
+ mapWithComplete(({ isComplete }) => (result) => ({
1102
+ status: "success",
1103
+ ...isComplete && {
1104
+ fetchStatus: "idle"
1105
+ },
1106
+ data: { result },
1107
+ error: void 0
1108
+ })),
1109
+ rxjs.endWith({
1110
+ fetchStatus: "idle"
1111
+ }),
1112
+ rxjs.catchError((error) => {
1113
+ queryStore.dispatchQueryEvent({
1114
+ key: serializedKey,
1115
+ type: "fetchError"
1116
+ });
1117
+ return rxjs.of({
1118
+ fetchStatus: "idle",
1119
+ status: "error",
1120
+ data: void 0,
1121
+ error
1122
+ });
1123
+ }),
1124
+ notifyQueryResult(options$)
1125
+ );
1126
+ const newCache$ = queryStore.queryEvent$.pipe(
1127
+ rxjs.filter(
1128
+ (event) => event.key === serializedKey && event.type === "queryDataSet"
1129
+ ),
1130
+ rxjs.map(() => {
1131
+ var _a, _b;
1132
+ return (_b = (_a = queryStore.get(serializedKey)) == null ? void 0 : _a.cache_fnResult) == null ? void 0 : _b.result;
1133
+ }),
1134
+ rxjs.filter(isDefined),
1135
+ rxjs.map((result) => ({
1136
+ status: "success",
1137
+ data: { result }
1138
+ })),
1139
+ /**
1140
+ * @important
1141
+ * To avoid cache update being returned being the first result is returned.
1142
+ * For example if user set query data inside onSuccess callback, we simulate
1143
+ * a small delay to ensure it happens after.
1144
+ */
1145
+ rxjs.delay(1)
1146
+ );
1147
+ const execution$ = rxjs.merge(
1148
+ disabled$.pipe(
1149
+ rxjs.take(1),
1150
+ rxjs.map(() => ({
1151
+ fetchStatus: "idle"
1152
+ }))
1153
+ ),
1154
+ rxjs.merge(
1155
+ rxjs.of({ fetchStatus: "fetching", error: void 0 }),
1156
+ fnExecution$
1157
+ ).pipe(rxjs.takeUntil(disabled$)),
1158
+ newCache$
1159
+ ).pipe(rxjs.takeUntil(trigger$));
1160
+ const query = queryStore.get(serializedKey);
1161
+ const cacheResult = query == null ? void 0 : query.cache_fnResult;
1162
+ const hasCache = !!cacheResult;
1163
+ if (hasCache) {
1164
+ if (!(query == null ? void 0 : query.isStale) && !trigger2.ignoreStale) {
1165
+ return rxjs.of({
1166
+ fetchStatus: "idle",
1167
+ status: "success",
1168
+ data: { result: cacheResult.result },
1169
+ error: void 0
1170
+ });
1171
+ } else {
1172
+ return rxjs.merge(
1173
+ rxjs.of({
1174
+ fetchStatus: "fetching",
1175
+ status: "success",
1176
+ data: { result: cacheResult.result },
1177
+ error: void 0
1178
+ }),
1179
+ execution$
1180
+ );
1181
+ }
1182
+ }
1183
+ return execution$;
1184
+ };
1185
+ const compareKeys = (keyA, keyB, { exact = false } = {}) => {
1186
+ if (exact) {
1187
+ return serializeKey(keyA) === serializeKey(keyB);
1188
+ }
1189
+ return keyA.reduce((acc, value, index) => {
1190
+ if (!acc)
1191
+ return false;
1192
+ return serializeObject(value) === serializeObject(keyB[index]);
1193
+ }, true);
1194
+ };
1195
+ const logger$2 = Logger.namespace("invalidation");
1196
+ const createInvalidationClient = ({
1197
+ queryStore
1198
+ }) => {
1199
+ const invalidateQueries = ({
1200
+ queryKey,
1201
+ exact = false,
1202
+ predicate
1203
+ } = {}) => {
1204
+ let keysToRefetch = [];
1205
+ if (queryKey) {
1206
+ logger$2.log(`invalidation requested for`, queryKey);
1207
+ queryStore.updateMany({ isStale: true }, (entry) => {
1208
+ const isValid = compareKeys(queryKey, entry.queryKey, { exact });
1209
+ if (isValid) {
1210
+ keysToRefetch.push(serializeKey(entry.queryKey));
1211
+ }
1212
+ return isValid;
1213
+ });
1214
+ } else if (predicate) {
1215
+ queryStore.updateMany({ isStale: true }, (entry) => {
1216
+ const isValid = predicate(entry);
1217
+ if (isValid) {
1218
+ keysToRefetch.push(serializeKey(entry.queryKey));
1219
+ }
1220
+ return isValid;
1221
+ });
1222
+ } else {
1223
+ logger$2.log(`Invalidation requested for all queries`);
1224
+ queryStore.updateMany({ isStale: true });
1225
+ keysToRefetch = Array.from(queryStore.keys());
1226
+ }
1227
+ keysToRefetch.forEach((key) => {
1228
+ queryStore.dispatchQueryTrigger({
1229
+ key,
1230
+ trigger: { ignoreStale: true, type: "refetch" }
1231
+ });
1232
+ });
1233
+ };
1234
+ return {
1235
+ invalidateQueries,
1236
+ destroy: () => {
1237
+ }
1238
+ };
1239
+ };
1240
+ const logger$1 = Logger.namespace("refetch");
1241
+ const createRefetchClient = ({
1242
+ queryStore
1243
+ }) => {
1244
+ const pipeQueryResult = ({
1245
+ options$
1246
+ }) => (stream) => {
1247
+ const sharedStream = stream.pipe(rxjs.share());
1248
+ return rxjs.merge(
1249
+ sharedStream,
1250
+ sharedStream.pipe(
1251
+ rxjs.filter(
1252
+ (result) => !!result.data && result.fetchStatus !== "fetching"
1253
+ ),
1254
+ rxjs.distinctUntilChanged((prev, curr) => prev.data === curr.data),
1255
+ rxjs.withLatestFrom(options$),
1256
+ rxjs.map(([, { refetchInterval }]) => refetchInterval),
1257
+ rxjs.filter(isDefined),
1258
+ rxjs.switchMap((refetchInterval) => {
1259
+ if (typeof refetchInterval === "number") {
1260
+ return rxjs.timer(refetchInterval).pipe(
1261
+ rxjs.map(() => ({
1262
+ type: "refetch",
1263
+ ignoreStale: true
1264
+ })),
1265
+ rxjs.switchMap(() => rxjs.EMPTY)
1266
+ );
1267
+ }
1268
+ return rxjs.EMPTY;
1269
+ })
1270
+ )
1271
+ );
1272
+ };
1273
+ const pipeQueryTrigger = ({
1274
+ key
1275
+ }) => (stream) => {
1276
+ return rxjs.merge(
1277
+ stream.pipe(
1278
+ rxjs.tap(({ ignoreStale }) => {
1279
+ const query = queryStore.get(key);
1280
+ if (query && ignoreStale && !query.isStale) {
1281
+ logger$1.log(key, "marked stale by trigger!");
1282
+ queryStore.update(key, {
1283
+ isStale: true
1284
+ });
1285
+ }
1286
+ })
1287
+ )
1288
+ );
1289
+ };
1290
+ return {
1291
+ pipeQueryResult,
1292
+ pipeQueryTrigger,
1293
+ destroy: () => {
1294
+ }
1295
+ };
1296
+ };
1297
+ const difference = (a, b) => a.filter((element) => !b.includes(element));
1298
+ const createQueryListener = (store, onQuery) => store.store$.pipe(
1299
+ rxjs.map((store2) => [...store2.keys()]),
1300
+ rxjs.startWith([]),
1301
+ rxjs.pairwise(),
1302
+ rxjs.mergeMap(([previousKeys, currentKeys]) => {
1303
+ const newKeys = difference(currentKeys, previousKeys);
1304
+ return rxjs.merge(
1305
+ ...newKeys.map((key) => {
1306
+ const deleted$ = store.store$.pipe(
1307
+ rxjs.map(() => store.get(key)),
1308
+ rxjs.filter((item) => item === void 0)
1309
+ );
1310
+ return rxjs.merge(rxjs.NEVER, rxjs.of(key)).pipe(
1311
+ rxjs.tap(() => {
1312
+ console.log("QUERY", key, "in");
1313
+ }),
1314
+ onQuery,
1315
+ rxjs.finalize(() => {
1316
+ console.log("QUERY", key, "complete");
1317
+ }),
1318
+ rxjs.takeUntil(deleted$)
1319
+ );
1320
+ })
1321
+ );
1322
+ })
1323
+ );
1324
+ const mapStoreQueryToRunnerOptions = (stream) => stream.pipe(
1325
+ rxjs.switchMap((entry) => rxjs.combineLatest(entry.runners)),
1326
+ rxjs.map((runnerValues) => runnerValues.map(({ options }) => options))
1327
+ );
1328
+ const mapOptionsToOption$1 = (stream) => stream.pipe(
1329
+ rxjs.map(
1330
+ (options) => options.reduce(
1331
+ (acc, value) => {
1332
+ return {
1333
+ ...acc,
1334
+ lowestStaleTime: value.staleTime === void 0 ? acc.lowestStaleTime : Math.min(
1335
+ value.staleTime ?? Infinity,
1336
+ acc.lowestStaleTime ?? Infinity
1337
+ )
1338
+ };
1339
+ },
1340
+ { lowestStaleTime: void 0 }
1341
+ )
1342
+ ),
1343
+ rxjs.distinctUntilChanged(shallowEqual)
1344
+ );
1345
+ const onlyFetchEventDone = (key) => (stream) => stream.pipe(
1346
+ rxjs.filter(
1347
+ (event) => event.key === key && (event.type === "fetchError" || event.type === "fetchSuccess")
1348
+ )
1349
+ );
1350
+ const markAsStale = ({
1351
+ queryStore
1352
+ }) => (stream) => stream.pipe(
1353
+ rxjs.switchMap((key) => {
1354
+ const query$ = queryStore.get$(key);
1355
+ return queryStore.queryEvent$.pipe(
1356
+ onlyFetchEventDone(key),
1357
+ rxjs.switchMap(
1358
+ () => query$.pipe(
1359
+ mapStoreQueryToRunnerOptions,
1360
+ mapOptionsToOption$1,
1361
+ rxjs.tap(({ lowestStaleTime = 0 }) => {
1362
+ var _a;
1363
+ if (lowestStaleTime === 0) {
1364
+ logger$2.log(key, "marked as stale!", {
1365
+ staleTime: lowestStaleTime
1366
+ });
1367
+ queryStore.update(key, { isStale: true });
1368
+ } else if ((_a = queryStore.get(key)) == null ? void 0 : _a.isStale) {
1369
+ logger$2.log(key, "marked non stale", {
1370
+ staleTime: lowestStaleTime
1371
+ });
1372
+ queryStore.update(key, { isStale: false });
1373
+ }
1374
+ }),
1375
+ rxjs.filter(
1376
+ ({ lowestStaleTime }) => lowestStaleTime !== Infinity && lowestStaleTime !== 0
1377
+ ),
1378
+ rxjs.switchMap(({ lowestStaleTime = 0 }) => rxjs.timer(lowestStaleTime)),
1379
+ rxjs.tap(() => {
1380
+ var _a;
1381
+ if (!((_a = queryStore.get(key)) == null ? void 0 : _a.isStale)) {
1382
+ logger$2.log(key, "marked as stale!");
1383
+ queryStore.update(key, { isStale: true });
1384
+ }
1385
+ })
1386
+ )
1387
+ ),
1388
+ rxjs.map(() => key)
1389
+ );
1390
+ })
1391
+ );
1392
+ const mapOptionsToOption = (stream) => stream.pipe(
1393
+ rxjs.map(
1394
+ (options) => options.reduce(
1395
+ (acc, value) => {
1396
+ return {
1397
+ ...acc,
1398
+ lowestCacheTime: value.cacheTime === void 0 ? acc.lowestCacheTime : Math.min(
1399
+ value.cacheTime ?? Infinity,
1400
+ acc.lowestCacheTime ?? Infinity
1401
+ )
1402
+ };
1403
+ },
1404
+ { lowestCacheTime: void 0 }
1405
+ )
1406
+ ),
1407
+ rxjs.distinctUntilChanged(shallowEqual)
1408
+ );
1409
+ const onCacheUpdate = (stream) => stream.pipe(
1410
+ rxjs.map((item) => item.cache_fnResult),
1411
+ rxjs.distinctUntilChanged(shallowEqual)
1412
+ );
1413
+ const invalidateCache = ({
1414
+ queryStore
1415
+ }) => (stream) => stream.pipe(
1416
+ rxjs.switchMap((key) => {
1417
+ const query$ = queryStore.get$(key);
1418
+ const invalidateCache$ = query$.pipe(
1419
+ onCacheUpdate,
1420
+ rxjs.switchMap(
1421
+ () => query$.pipe(
1422
+ mapStoreQueryToRunnerOptions,
1423
+ mapOptionsToOption,
1424
+ rxjs.switchMap(
1425
+ ({
1426
+ lowestCacheTime = 5 * 60 * 1e3
1427
+ /* 5mn */
1428
+ }) => rxjs.timer(lowestCacheTime).pipe(
1429
+ rxjs.tap(() => {
1430
+ queryStore.update(key, { cache_fnResult: void 0 });
1431
+ })
1432
+ )
1433
+ )
1434
+ )
1435
+ )
1436
+ );
1437
+ return invalidateCache$.pipe(rxjs.map(() => key));
1438
+ })
1439
+ );
1440
+ const garbageCache = ({
1441
+ queryStore
1442
+ }) => (stream) => stream.pipe(
1443
+ rxjs.switchMap((key) => {
1444
+ const query$ = queryStore.get$(key);
1445
+ return query$.pipe(
1446
+ rxjs.filter((entry) => !entry.cache_fnResult),
1447
+ rxjs.map((entry) => entry.runners.length > 0),
1448
+ rxjs.pairwise(),
1449
+ rxjs.filter(([hadRunners, hasRunners]) => hadRunners && !hasRunners),
1450
+ rxjs.tap(() => {
1451
+ queryStore.delete(key);
1452
+ }),
1453
+ rxjs.map(() => key)
1454
+ );
1455
+ })
1456
+ );
1457
+ const getInitialQueryEntity = ({ key }) => ({
1458
+ isStale: true,
1459
+ queryKey: key,
1460
+ runners: []
1461
+ });
1462
+ const updateStoreWithQuery = ({
1463
+ queryStore,
1464
+ serializedKey,
1465
+ runner$,
1466
+ key
1467
+ }) => (stream) => stream.pipe(
1468
+ rxjs.map((value) => {
1469
+ if (key.length === 0)
1470
+ return [value, () => {
1471
+ }];
1472
+ if (!queryStore.get(serializedKey)) {
1473
+ queryStore.set(serializedKey, getInitialQueryEntity({ key }));
1474
+ } else {
1475
+ queryStore.update(serializedKey, {
1476
+ queryKey: key,
1477
+ ...value.options.markStale && {
1478
+ isStale: true
1479
+ }
1480
+ });
1481
+ }
1482
+ return [value, queryStore.addRunner(serializedKey, runner$)];
1483
+ })
1484
+ );
1485
+ const logger = Logger.namespace("cache");
1486
+ const createCacheClient = ({
1487
+ queryStore
1488
+ }) => {
1489
+ const setQueryData = ({
1490
+ queryKey,
1491
+ updater
1492
+ }) => {
1493
+ const serializedKey = serializeKey(queryKey);
1494
+ if (queryKey.length === 0)
1495
+ return;
1496
+ logger.log("set cache for query", serializeKey);
1497
+ if (!queryStore.get(serializedKey)) {
1498
+ queryStore.set(serializedKey, getInitialQueryEntity({ key: queryKey }));
1499
+ }
1500
+ queryStore.update(serializedKey, (entity) => {
1501
+ var _a;
1502
+ if (typeof updater === "function") {
1503
+ const callableUpdater = updater;
1504
+ return {
1505
+ ...entity,
1506
+ cache_fnResult: {
1507
+ result: callableUpdater(
1508
+ (_a = entity.cache_fnResult) == null ? void 0 : _a.result
1509
+ )
1510
+ }
1511
+ };
1512
+ }
1513
+ return {
1514
+ ...entity,
1515
+ cache_fnResult: {
1516
+ result: updater
1517
+ }
1518
+ };
1519
+ });
1520
+ queryStore.dispatchQueryEvent({
1521
+ key: serializedKey,
1522
+ type: "queryDataSet"
1523
+ });
1524
+ };
1525
+ return {
1526
+ setQueryData
1527
+ };
1528
+ };
1529
+ const createClient = () => {
1530
+ const queryStore = createQueryStore();
1531
+ const invalidationClient = createInvalidationClient({ queryStore });
1532
+ const cacheClient = createCacheClient({ queryStore });
1533
+ const refetchClient = createRefetchClient({ queryStore });
1534
+ const query$ = ({
1535
+ key,
1536
+ fn$: maybeFn$,
1537
+ fn: maybeFn,
1538
+ refetch$ = new rxjs.Subject(),
1539
+ options$ = new rxjs.BehaviorSubject({})
1540
+ }) => {
1541
+ const serializedKey = serializeKey(key);
1542
+ const internalRefetch$ = new rxjs.Subject();
1543
+ const fn$ = maybeFn$ ?? (maybeFn ? rxjs.of(maybeFn) : rxjs.NEVER);
1544
+ console.log("query$()", serializedKey);
1545
+ const runner$ = options$.pipe(rxjs.map((options) => ({ options })));
1546
+ let deleteRunner = () => {
1547
+ };
1548
+ const initialTrigger$ = rxjs.of({
1549
+ type: "initial",
1550
+ ignoreStale: false
1551
+ });
1552
+ const trigger$ = createQueryTrigger({
1553
+ options$,
1554
+ refetch$: rxjs.merge(refetch$, internalRefetch$),
1555
+ key: serializedKey,
1556
+ queryStore
1557
+ }).pipe(refetchClient.pipeQueryTrigger({ options$, key: serializedKey }));
1558
+ const result$ = rxjs.merge(initialTrigger$, trigger$).pipe(
1559
+ rxjs.withLatestFrom(fn$, options$),
1560
+ rxjs.map(([trigger2, fn, options]) => ({ trigger: trigger2, fn, options })),
1561
+ updateStoreWithQuery({
1562
+ key,
1563
+ queryStore,
1564
+ runner$,
1565
+ serializedKey
1566
+ }),
1567
+ rxjs.map(([value, deleteRunnerFn]) => {
1568
+ deleteRunner = deleteRunnerFn;
1569
+ console.log("reactjrx", serializedKey, "query trigger", {
1570
+ trigger: value.trigger,
1571
+ options: value.options
1572
+ });
1573
+ return value;
1574
+ }),
1575
+ rxjs.filter(({ options }) => options.enabled !== false),
1576
+ rxjs.mergeMap(
1577
+ ({ fn, options, trigger: trigger2 }) => createQueryFetch({
1578
+ options$,
1579
+ options,
1580
+ fn,
1581
+ queryStore,
1582
+ serializedKey,
1583
+ trigger: trigger2,
1584
+ trigger$
1585
+ })
1586
+ ),
1587
+ // hooks
1588
+ rxjs.switchMap(
1589
+ (result) => rxjs.merge(
1590
+ rxjs.of(result).pipe(
1591
+ refetchClient.pipeQueryResult({
1592
+ key: serializedKey,
1593
+ queryStore,
1594
+ options$,
1595
+ refetch$: internalRefetch$
1596
+ })
1597
+ )
1598
+ )
1599
+ ),
1600
+ mergeResults,
1601
+ rxjs.withLatestFrom(options$),
1602
+ rxjs.takeWhile(([result, options]) => {
1603
+ const shouldStop = result.data !== void 0 && options.terminateOnFirstResult;
1604
+ return !shouldStop;
1605
+ }, true),
1606
+ rxjs.map(([result]) => result),
1607
+ rxjs.tap((result) => {
1608
+ console.log("result", result);
1609
+ }),
1610
+ rxjs.finalize(() => {
1611
+ deleteRunner();
1612
+ })
1613
+ );
1614
+ return {
1615
+ result$
1616
+ };
1617
+ };
1618
+ const queryListenerSub = createQueryListener(
1619
+ queryStore,
1620
+ (stream) => stream.pipe(
1621
+ rxjs.switchMap((key) => {
1622
+ const key$ = rxjs.of(key);
1623
+ return rxjs.merge(
1624
+ invalidateCache({
1625
+ queryStore
1626
+ })(key$),
1627
+ markAsStale({
1628
+ queryStore
1629
+ })(key$),
1630
+ garbageCache({
1631
+ queryStore
1632
+ })(key$)
1633
+ );
1634
+ })
1635
+ )
1636
+ ).subscribe();
1637
+ return {
1638
+ query$,
1639
+ queryStore,
1640
+ ...invalidationClient,
1641
+ ...cacheClient,
1642
+ ...refetchClient,
1643
+ destroy: () => {
1644
+ queryStore.destroy();
1645
+ queryListenerSub.unsubscribe();
1646
+ }
1647
+ };
1648
+ };
853
1649
  exports.PersistSignals = PersistSignals;
854
1650
  exports.ReactjrxQueryProvider = Provider;
855
1651
  exports.SIGNAL_RESET = SIGNAL_RESET;
1652
+ exports.createClient = createClient;
856
1653
  exports.createLocalforageAdapter = createLocalforageAdapter;
857
1654
  exports.createSharedStoreAdapter = createSharedStoreAdapter;
858
1655
  exports.exponentialBackoffDelay = exponentialBackoffDelay;
@@ -866,10 +1663,12 @@ exports.useObserve = useObserve;
866
1663
  exports.useObserveCallback = useObserveCallback;
867
1664
  exports.usePersistSignalsContext = usePersistSignalsContext;
868
1665
  exports.useQuery = useQuery;
1666
+ exports.useReactJrxProvider = useReactJrxProvider;
869
1667
  exports.useScopeSignals = useScopeSignals;
870
1668
  exports.useSetSignal = useSetSignal;
871
1669
  exports.useSignal = useSignal;
872
1670
  exports.useSignalValue = useSignalValue;
1671
+ exports.useSubject = useSubject;
873
1672
  exports.useSubscribe = useSubscribe;
874
1673
  exports.useSubscribeEffect = useSubscribeEffect;
875
1674
  exports.useUnmountObservable = useUnmountObservable;