reactjrx 1.29.2 → 1.31.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
@@ -101,17 +101,23 @@ const useConstant = (fn) => {
101
101
  return ref;
102
102
  };
103
103
  const useSubject = ({
104
- onBeforeComplete
104
+ onBeforeComplete,
105
+ completeOnUnmount = true
105
106
  } = {}) => {
106
107
  const subject = useConstant(() => new rxjs.Subject());
107
108
  const completed = react.useRef(false);
108
109
  const onBeforeCompleteRef = useLiveRef(onBeforeComplete);
110
+ const completeOnUnmountRef = useLiveRef(completeOnUnmount);
109
111
  react.useEffect(() => {
110
112
  if (completed.current) {
111
113
  subject.current = new rxjs.Subject();
112
114
  completed.current = false;
113
115
  }
114
116
  return () => {
117
+ if (!completeOnUnmountRef.current) {
118
+ completed.current = true;
119
+ return;
120
+ }
115
121
  if (!completed.current) {
116
122
  if (onBeforeCompleteRef.current != null)
117
123
  onBeforeCompleteRef.current();
@@ -141,10 +147,8 @@ function trigger(mapper = rxjs.identity) {
141
147
  }
142
148
  const SIGNAL_RESET = Symbol("SIGNAL_RESET");
143
149
  function signal(options) {
144
- const { default: defaultValue, key } = options ?? {};
150
+ const { default: defaultValue } = options ?? {};
145
151
  const subject = new rxjs.BehaviorSubject(defaultValue);
146
- const subject$ = subject.asObservable();
147
- const useValue = () => useObserve(subject$, { defaultValue: subject.getValue(), key });
148
152
  const setValue = (arg) => {
149
153
  if (arg === subject.getValue())
150
154
  return;
@@ -162,26 +166,24 @@ function signal(options) {
162
166
  subject.next(arg);
163
167
  };
164
168
  const getValue = () => subject.getValue();
165
- return [
166
- useValue,
167
- setValue,
169
+ return {
170
+ setState: setValue,
168
171
  getValue,
172
+ options,
169
173
  /**
170
174
  * @important
171
175
  * We return the original behavior subject for two reasons:
172
176
  * - useObserve may return the default value directly instead of undefined
173
177
  * - the scope exist for react binding, this observable is a direct access outside of it
174
178
  */
175
- subject,
176
- options,
177
- { setState: setValue, useState: useValue }
178
- ];
179
+ subject
180
+ };
179
181
  }
180
182
  const useSetSignal = (signal2) => {
181
183
  return signal2.setState;
182
184
  };
183
- const useSignalValue = (signal2) => {
184
- return signal2.useState();
185
+ const useSignalValue = (signal2, key) => {
186
+ return useObserve(signal2.subject, { defaultValue: signal2.getValue(), key });
185
187
  };
186
188
  const useSignal = (signal2) => {
187
189
  return [useSignalValue(signal2), useSetSignal(signal2)];
@@ -281,15 +283,14 @@ const getNormalizedPersistanceValue = (unknownValue) => {
281
283
  return void 0;
282
284
  };
283
285
  function withPersistance(_signal, { version = 0 } = {}) {
284
- const [hook, setValue, getState, $, options, ...rest] = _signal;
285
- if (!options.key) {
286
+ if (!_signal.options.key) {
286
287
  console.error(
287
288
  "You need to specify a key to use persistance with this signal"
288
289
  );
289
290
  }
290
291
  const hydrateValue = async ({
291
292
  adapter,
292
- key = options.key
293
+ key = _signal.options.key
293
294
  }) => {
294
295
  if (!key)
295
296
  return;
@@ -300,15 +301,15 @@ function withPersistance(_signal, { version = 0 } = {}) {
300
301
  if (normalizedValue.migrationVersion && version > normalizedValue.migrationVersion) {
301
302
  return;
302
303
  }
303
- setValue(value.value);
304
+ _signal.setState(value.value);
304
305
  };
305
306
  const persistValue = async ({
306
307
  adapter,
307
- key = options.key
308
+ key = _signal.options.key
308
309
  }) => {
309
310
  if (!key)
310
311
  return;
311
- const state = getState();
312
+ const state = _signal.getValue();
312
313
  const value = {
313
314
  value: state,
314
315
  __key: "reactjrx_persistance",
@@ -317,13 +318,14 @@ function withPersistance(_signal, { version = 0 } = {}) {
317
318
  await adapter.setItem(key, value);
318
319
  };
319
320
  return [
320
- { hydrateValue, persistValue, setValue, $, options },
321
- hook,
322
- setValue,
323
- getState,
324
- $,
325
- options,
326
- ...rest
321
+ {
322
+ hydrateValue,
323
+ persistValue,
324
+ setValue: _signal.setState,
325
+ $: _signal.subject,
326
+ options: _signal.options
327
+ },
328
+ _signal
327
329
  ];
328
330
  }
329
331
  const normalizeStore = (store) => {
@@ -435,9 +437,40 @@ const useBehaviorSubject = (state) => {
435
437
  }, []);
436
438
  return subject;
437
439
  };
440
+ function shallowEqual(objA, objB) {
441
+ if (objA === null || objA === void 0 || objB === null || objB === void 0) {
442
+ return objA === objB;
443
+ }
444
+ if (typeof objA !== "object" || typeof objB !== "object") {
445
+ return objA === objB;
446
+ }
447
+ if (objA.constructor !== objB.constructor) {
448
+ return false;
449
+ }
450
+ const keysA = Object.keys(objA);
451
+ const keysB = Object.keys(objB);
452
+ if (keysA.length !== keysB.length) {
453
+ return false;
454
+ }
455
+ for (const key of keysA) {
456
+ if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
457
+ return false;
458
+ }
459
+ }
460
+ return true;
461
+ }
438
462
  function useMutation(query, mapOperatorOrOptions, options = {}) {
439
463
  const queryRef = useLiveRef(query);
440
464
  const triggerSubject = useSubject();
465
+ const resetSubject = useSubject({
466
+ /**
467
+ * @important
468
+ * Because mutation can still run after unmount, the user might
469
+ * want to use reset for whatever reason. We will only manually complete
470
+ * this subject whenever the main query hook finalize.
471
+ */
472
+ completeOnUnmount: false
473
+ });
441
474
  const optionsRef = useLiveRef(
442
475
  typeof mapOperatorOrOptions === "object" ? mapOperatorOrOptions : options
443
476
  );
@@ -449,55 +482,81 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
449
482
  const mapOperator = typeof mapOperatorOrOptions === "string" ? mapOperatorOrOptions : "merge";
450
483
  react.useEffect(() => {
451
484
  const switchOperator = mapOperator === "concat" ? rxjs.concatMap : mapOperator === "switch" ? rxjs.switchMap : rxjs.mergeMap;
452
- const subscription = triggerSubject.current.pipe(
453
- switchOperator((args) => {
454
- const isLastMutationCalled = triggerSubject.current.pipe(
455
- rxjs.take(1),
456
- rxjs.map(() => mapOperator === "concat"),
457
- rxjs.startWith(true)
458
- );
459
- data$.current.next({
460
- ...data$.current.getValue(),
461
- status: "loading"
462
- });
463
- return rxjs.combineLatest([
464
- rxjs.defer(() => rxjs.from(queryRef.current(args))).pipe(
465
- querx(optionsRef.current),
466
- rxjs.first(),
467
- rxjs.map((data) => ({ data, isError: false })),
468
- rxjs.catchError((error) => {
469
- if (optionsRef.current.onError != null) {
470
- optionsRef.current.onError(error);
471
- }
472
- return rxjs.of({ data: error, isError: true });
473
- })
474
- ),
475
- isLastMutationCalled
476
- ]).pipe(
477
- rxjs.tap(([{ data, isError }, isLastMutationCalled2]) => {
478
- if (!isError) {
479
- if (optionsRef.current.onSuccess != null)
480
- optionsRef.current.onSuccess(data);
481
- }
482
- if (isLastMutationCalled2) {
483
- data$.current.next({
484
- ...data$.current.getValue(),
485
- ...isError ? {
486
- status: "error",
487
- error: data,
488
- data: void 0
489
- } : {
490
- status: "success",
491
- error: void 0,
492
- data
493
- }
494
- });
495
- }
485
+ const subscription = rxjs.merge(
486
+ resetSubject.current.pipe(
487
+ rxjs.map(
488
+ () => ({
489
+ status: "idle",
490
+ data: void 0,
491
+ error: void 0
496
492
  })
497
- );
498
- }),
499
- optionsRef.current.hooks ?? rxjs.identity
500
- ).subscribe();
493
+ )
494
+ ),
495
+ triggerSubject.current.pipe(
496
+ switchOperator((args) => {
497
+ const isLastMutationCalled = triggerSubject.current.pipe(
498
+ rxjs.take(1),
499
+ rxjs.map(() => mapOperator === "concat"),
500
+ rxjs.startWith(true)
501
+ );
502
+ return rxjs.merge(
503
+ rxjs.of({
504
+ status: "loading"
505
+ }),
506
+ rxjs.combineLatest([
507
+ rxjs.defer(() => rxjs.from(queryRef.current(args))).pipe(
508
+ querx(optionsRef.current),
509
+ rxjs.first(),
510
+ rxjs.map((data) => ({ data, isError: false })),
511
+ rxjs.catchError((error) => {
512
+ if (optionsRef.current.onError != null) {
513
+ optionsRef.current.onError(error);
514
+ }
515
+ return rxjs.of({ data: error, isError: true });
516
+ })
517
+ ),
518
+ isLastMutationCalled
519
+ ]).pipe(
520
+ rxjs.map(([{ data, isError }, isLastMutationCalled2]) => {
521
+ if (!isError) {
522
+ if (optionsRef.current.onSuccess != null)
523
+ optionsRef.current.onSuccess(data);
524
+ }
525
+ if (isLastMutationCalled2) {
526
+ return isError ? {
527
+ status: "error",
528
+ error: data,
529
+ data: void 0
530
+ } : {
531
+ status: "success",
532
+ error: void 0,
533
+ data
534
+ };
535
+ }
536
+ return void 0;
537
+ }),
538
+ rxjs.takeUntil(resetSubject.current)
539
+ )
540
+ );
541
+ }),
542
+ optionsRef.current.triggerHook ?? rxjs.identity,
543
+ rxjs.finalize(() => {
544
+ resetSubject.current.complete();
545
+ })
546
+ )
547
+ ).pipe(
548
+ /**
549
+ * @important
550
+ * state update optimization
551
+ */
552
+ rxjs.distinctUntilChanged(shallowEqual),
553
+ rxjs.filter((state) => !!state && !!Object.keys(state).length)
554
+ ).subscribe((state) => {
555
+ data$.current.next({
556
+ ...data$.current.getValue(),
557
+ ...state
558
+ });
559
+ });
501
560
  return () => {
502
561
  if (optionsRef.current.cancelOnUnMount) {
503
562
  subscription.unsubscribe();
@@ -514,31 +573,12 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
514
573
  const mutate = react.useCallback((arg) => {
515
574
  triggerSubject.current.next(arg);
516
575
  }, []);
517
- return { ...result, isLoading: result.status === "loading", mutate };
576
+ const reset = react.useCallback(() => {
577
+ resetSubject.current.next();
578
+ }, []);
579
+ return { ...result, isLoading: result.status === "loading", mutate, reset };
518
580
  }
519
581
  const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
520
- function shallowEqual(objA, objB) {
521
- if (objA === null || objA === void 0 || objB === null || objB === void 0) {
522
- return objA === objB;
523
- }
524
- if (typeof objA !== "object" || typeof objB !== "object") {
525
- return objA === objB;
526
- }
527
- if (objA.constructor !== objB.constructor) {
528
- return false;
529
- }
530
- const keysA = Object.keys(objA);
531
- const keysB = Object.keys(objB);
532
- if (keysA.length !== keysB.length) {
533
- return false;
534
- }
535
- for (const key of keysA) {
536
- if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
537
- return false;
538
- }
539
- }
540
- return true;
541
- }
542
582
  const useCreateCacheStore = () => {
543
583
  const cacheStore = useBehaviorSubject({});
544
584
  useSubscribe(
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, concatMap as concatMap$1, mergeMap, skip, interval, withLatestFrom, shareReplay, repeat, filter, share, takeUntil, retry } from "rxjs";
2
+ import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, of, zip, from, map, merge, throttleTime, switchMap, defer, iif, timer, throwError, take, startWith, combineLatest, first, takeUntil, filter, concatMap as concatMap$1, mergeMap, skip, interval, withLatestFrom, shareReplay, repeat, share, retry } from "rxjs";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { retryWhen, concatMap, tap as tap$1 } from "rxjs/operators";
5
5
  const useLiveRef = (value) => {
@@ -99,17 +99,23 @@ const useConstant = (fn) => {
99
99
  return ref;
100
100
  };
101
101
  const useSubject = ({
102
- onBeforeComplete
102
+ onBeforeComplete,
103
+ completeOnUnmount = true
103
104
  } = {}) => {
104
105
  const subject = useConstant(() => new Subject());
105
106
  const completed = useRef(false);
106
107
  const onBeforeCompleteRef = useLiveRef(onBeforeComplete);
108
+ const completeOnUnmountRef = useLiveRef(completeOnUnmount);
107
109
  useEffect(() => {
108
110
  if (completed.current) {
109
111
  subject.current = new Subject();
110
112
  completed.current = false;
111
113
  }
112
114
  return () => {
115
+ if (!completeOnUnmountRef.current) {
116
+ completed.current = true;
117
+ return;
118
+ }
113
119
  if (!completed.current) {
114
120
  if (onBeforeCompleteRef.current != null)
115
121
  onBeforeCompleteRef.current();
@@ -139,10 +145,8 @@ function trigger(mapper = identity) {
139
145
  }
140
146
  const SIGNAL_RESET = Symbol("SIGNAL_RESET");
141
147
  function signal(options) {
142
- const { default: defaultValue, key } = options ?? {};
148
+ const { default: defaultValue } = options ?? {};
143
149
  const subject = new BehaviorSubject(defaultValue);
144
- const subject$ = subject.asObservable();
145
- const useValue = () => useObserve(subject$, { defaultValue: subject.getValue(), key });
146
150
  const setValue = (arg) => {
147
151
  if (arg === subject.getValue())
148
152
  return;
@@ -160,26 +164,24 @@ function signal(options) {
160
164
  subject.next(arg);
161
165
  };
162
166
  const getValue = () => subject.getValue();
163
- return [
164
- useValue,
165
- setValue,
167
+ return {
168
+ setState: setValue,
166
169
  getValue,
170
+ options,
167
171
  /**
168
172
  * @important
169
173
  * We return the original behavior subject for two reasons:
170
174
  * - useObserve may return the default value directly instead of undefined
171
175
  * - the scope exist for react binding, this observable is a direct access outside of it
172
176
  */
173
- subject,
174
- options,
175
- { setState: setValue, useState: useValue }
176
- ];
177
+ subject
178
+ };
177
179
  }
178
180
  const useSetSignal = (signal2) => {
179
181
  return signal2.setState;
180
182
  };
181
- const useSignalValue = (signal2) => {
182
- return signal2.useState();
183
+ const useSignalValue = (signal2, key) => {
184
+ return useObserve(signal2.subject, { defaultValue: signal2.getValue(), key });
183
185
  };
184
186
  const useSignal = (signal2) => {
185
187
  return [useSignalValue(signal2), useSetSignal(signal2)];
@@ -279,15 +281,14 @@ const getNormalizedPersistanceValue = (unknownValue) => {
279
281
  return void 0;
280
282
  };
281
283
  function withPersistance(_signal, { version = 0 } = {}) {
282
- const [hook, setValue, getState, $, options, ...rest] = _signal;
283
- if (!options.key) {
284
+ if (!_signal.options.key) {
284
285
  console.error(
285
286
  "You need to specify a key to use persistance with this signal"
286
287
  );
287
288
  }
288
289
  const hydrateValue = async ({
289
290
  adapter,
290
- key = options.key
291
+ key = _signal.options.key
291
292
  }) => {
292
293
  if (!key)
293
294
  return;
@@ -298,15 +299,15 @@ function withPersistance(_signal, { version = 0 } = {}) {
298
299
  if (normalizedValue.migrationVersion && version > normalizedValue.migrationVersion) {
299
300
  return;
300
301
  }
301
- setValue(value.value);
302
+ _signal.setState(value.value);
302
303
  };
303
304
  const persistValue = async ({
304
305
  adapter,
305
- key = options.key
306
+ key = _signal.options.key
306
307
  }) => {
307
308
  if (!key)
308
309
  return;
309
- const state = getState();
310
+ const state = _signal.getValue();
310
311
  const value = {
311
312
  value: state,
312
313
  __key: "reactjrx_persistance",
@@ -315,13 +316,14 @@ function withPersistance(_signal, { version = 0 } = {}) {
315
316
  await adapter.setItem(key, value);
316
317
  };
317
318
  return [
318
- { hydrateValue, persistValue, setValue, $, options },
319
- hook,
320
- setValue,
321
- getState,
322
- $,
323
- options,
324
- ...rest
319
+ {
320
+ hydrateValue,
321
+ persistValue,
322
+ setValue: _signal.setState,
323
+ $: _signal.subject,
324
+ options: _signal.options
325
+ },
326
+ _signal
325
327
  ];
326
328
  }
327
329
  const normalizeStore = (store) => {
@@ -433,9 +435,40 @@ const useBehaviorSubject = (state) => {
433
435
  }, []);
434
436
  return subject;
435
437
  };
438
+ function shallowEqual(objA, objB) {
439
+ if (objA === null || objA === void 0 || objB === null || objB === void 0) {
440
+ return objA === objB;
441
+ }
442
+ if (typeof objA !== "object" || typeof objB !== "object") {
443
+ return objA === objB;
444
+ }
445
+ if (objA.constructor !== objB.constructor) {
446
+ return false;
447
+ }
448
+ const keysA = Object.keys(objA);
449
+ const keysB = Object.keys(objB);
450
+ if (keysA.length !== keysB.length) {
451
+ return false;
452
+ }
453
+ for (const key of keysA) {
454
+ if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
455
+ return false;
456
+ }
457
+ }
458
+ return true;
459
+ }
436
460
  function useMutation(query, mapOperatorOrOptions, options = {}) {
437
461
  const queryRef = useLiveRef(query);
438
462
  const triggerSubject = useSubject();
463
+ const resetSubject = useSubject({
464
+ /**
465
+ * @important
466
+ * Because mutation can still run after unmount, the user might
467
+ * want to use reset for whatever reason. We will only manually complete
468
+ * this subject whenever the main query hook finalize.
469
+ */
470
+ completeOnUnmount: false
471
+ });
439
472
  const optionsRef = useLiveRef(
440
473
  typeof mapOperatorOrOptions === "object" ? mapOperatorOrOptions : options
441
474
  );
@@ -447,55 +480,81 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
447
480
  const mapOperator = typeof mapOperatorOrOptions === "string" ? mapOperatorOrOptions : "merge";
448
481
  useEffect(() => {
449
482
  const switchOperator = mapOperator === "concat" ? concatMap$1 : mapOperator === "switch" ? switchMap : mergeMap;
450
- const subscription = triggerSubject.current.pipe(
451
- switchOperator((args) => {
452
- const isLastMutationCalled = triggerSubject.current.pipe(
453
- take(1),
454
- map(() => mapOperator === "concat"),
455
- startWith(true)
456
- );
457
- data$.current.next({
458
- ...data$.current.getValue(),
459
- status: "loading"
460
- });
461
- return combineLatest([
462
- defer(() => from(queryRef.current(args))).pipe(
463
- querx(optionsRef.current),
464
- first(),
465
- map((data) => ({ data, isError: false })),
466
- catchError((error) => {
467
- if (optionsRef.current.onError != null) {
468
- optionsRef.current.onError(error);
469
- }
470
- return of({ data: error, isError: true });
471
- })
472
- ),
473
- isLastMutationCalled
474
- ]).pipe(
475
- tap(([{ data, isError }, isLastMutationCalled2]) => {
476
- if (!isError) {
477
- if (optionsRef.current.onSuccess != null)
478
- optionsRef.current.onSuccess(data);
479
- }
480
- if (isLastMutationCalled2) {
481
- data$.current.next({
482
- ...data$.current.getValue(),
483
- ...isError ? {
484
- status: "error",
485
- error: data,
486
- data: void 0
487
- } : {
488
- status: "success",
489
- error: void 0,
490
- data
491
- }
492
- });
493
- }
483
+ const subscription = merge(
484
+ resetSubject.current.pipe(
485
+ map(
486
+ () => ({
487
+ status: "idle",
488
+ data: void 0,
489
+ error: void 0
494
490
  })
495
- );
496
- }),
497
- optionsRef.current.hooks ?? identity
498
- ).subscribe();
491
+ )
492
+ ),
493
+ triggerSubject.current.pipe(
494
+ switchOperator((args) => {
495
+ const isLastMutationCalled = triggerSubject.current.pipe(
496
+ take(1),
497
+ map(() => mapOperator === "concat"),
498
+ startWith(true)
499
+ );
500
+ return merge(
501
+ of({
502
+ status: "loading"
503
+ }),
504
+ combineLatest([
505
+ defer(() => from(queryRef.current(args))).pipe(
506
+ querx(optionsRef.current),
507
+ first(),
508
+ map((data) => ({ data, isError: false })),
509
+ catchError((error) => {
510
+ if (optionsRef.current.onError != null) {
511
+ optionsRef.current.onError(error);
512
+ }
513
+ return of({ data: error, isError: true });
514
+ })
515
+ ),
516
+ isLastMutationCalled
517
+ ]).pipe(
518
+ map(([{ data, isError }, isLastMutationCalled2]) => {
519
+ if (!isError) {
520
+ if (optionsRef.current.onSuccess != null)
521
+ optionsRef.current.onSuccess(data);
522
+ }
523
+ if (isLastMutationCalled2) {
524
+ return isError ? {
525
+ status: "error",
526
+ error: data,
527
+ data: void 0
528
+ } : {
529
+ status: "success",
530
+ error: void 0,
531
+ data
532
+ };
533
+ }
534
+ return void 0;
535
+ }),
536
+ takeUntil(resetSubject.current)
537
+ )
538
+ );
539
+ }),
540
+ optionsRef.current.triggerHook ?? identity,
541
+ finalize(() => {
542
+ resetSubject.current.complete();
543
+ })
544
+ )
545
+ ).pipe(
546
+ /**
547
+ * @important
548
+ * state update optimization
549
+ */
550
+ distinctUntilChanged(shallowEqual),
551
+ filter((state) => !!state && !!Object.keys(state).length)
552
+ ).subscribe((state) => {
553
+ data$.current.next({
554
+ ...data$.current.getValue(),
555
+ ...state
556
+ });
557
+ });
499
558
  return () => {
500
559
  if (optionsRef.current.cancelOnUnMount) {
501
560
  subscription.unsubscribe();
@@ -512,31 +571,12 @@ function useMutation(query, mapOperatorOrOptions, options = {}) {
512
571
  const mutate = useCallback((arg) => {
513
572
  triggerSubject.current.next(arg);
514
573
  }, []);
515
- return { ...result, isLoading: result.status === "loading", mutate };
574
+ const reset = useCallback(() => {
575
+ resetSubject.current.next();
576
+ }, []);
577
+ return { ...result, isLoading: result.status === "loading", mutate, reset };
516
578
  }
517
579
  const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
518
- function shallowEqual(objA, objB) {
519
- if (objA === null || objA === void 0 || objB === null || objB === void 0) {
520
- return objA === objB;
521
- }
522
- if (typeof objA !== "object" || typeof objB !== "object") {
523
- return objA === objB;
524
- }
525
- if (objA.constructor !== objB.constructor) {
526
- return false;
527
- }
528
- const keysA = Object.keys(objA);
529
- const keysB = Object.keys(objB);
530
- if (keysA.length !== keysB.length) {
531
- return false;
532
- }
533
- for (const key of keysA) {
534
- if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
535
- return false;
536
- }
537
- }
538
- return true;
539
- }
540
580
  const useCreateCacheStore = () => {
541
581
  const cacheStore = useBehaviorSubject({});
542
582
  useSubscribe(
@@ -3,8 +3,9 @@ import { Subject } from "rxjs";
3
3
  * @see
4
4
  * useBehaviorSubject
5
5
  */
6
- export declare const useSubject: <S>({ onBeforeComplete }?: {
6
+ export declare const useSubject: <S>({ onBeforeComplete, completeOnUnmount }?: {
7
7
  onBeforeComplete?: (() => void) | undefined;
8
+ completeOnUnmount?: boolean | undefined;
8
9
  }) => {
9
10
  current: Subject<S>;
10
11
  };
@@ -1,4 +1,9 @@
1
1
  import { type MonoTypeOperatorFunction, type Observable } from "rxjs";
2
+ interface QueryState<R> {
3
+ data: R | undefined;
4
+ status: "idle" | "loading" | "error" | "success";
5
+ error: unknown;
6
+ }
2
7
  export interface MutationOptions<R> {
3
8
  retry?: false | number | ((attempt: number, error: unknown) => boolean);
4
9
  /**
@@ -25,9 +30,10 @@ export interface MutationOptions<R> {
25
30
  */
26
31
  cancelOnUnMount?: boolean;
27
32
  /**
28
- * Only use for debugging
33
+ * Only use for debugging.
34
+ * It is not the main subscription hook, only the one following the trigger.
29
35
  */
30
- hooks?: MonoTypeOperatorFunction<any>;
36
+ triggerHook?: MonoTypeOperatorFunction<Partial<QueryState<R>> | undefined>;
31
37
  }
32
38
  interface Result<A, R> {
33
39
  status: "idle" | "loading" | "error" | "success";
@@ -49,6 +55,7 @@ interface Result<A, R> {
49
55
  */
50
56
  error: unknown | undefined;
51
57
  mutate: (args: A) => void;
58
+ reset: () => void;
52
59
  }
53
60
  /**
54
61
  * The default value `merge` is suitable for most use case.
@@ -1,5 +1,4 @@
1
- import { type Observable } from "rxjs";
2
- import { type signal } from "../signal";
1
+ import type { Signal } from "../signal";
3
2
  import { type Adapter } from "./types";
4
3
  export interface WithPersistanceReturn<T> {
5
4
  hydrateValue: (params: {
@@ -8,12 +7,12 @@ export interface WithPersistanceReturn<T> {
8
7
  persistValue: (params: {
9
8
  adapter: Adapter;
10
9
  }) => Promise<void>;
11
- setValue: ReturnType<typeof signal<T>>[1];
12
- $: Observable<T>;
10
+ setValue: Signal<T, T>['setState'];
11
+ $: Signal<T, T>['subject'];
13
12
  options: {
14
13
  key?: string;
15
14
  };
16
15
  }
17
- export declare function withPersistance<T>(_signal: ReturnType<typeof signal<T>>, { version }?: {
16
+ export declare function withPersistance<T>(_signal: Signal<T, T>, { version }?: {
18
17
  version?: number;
19
- }): [WithPersistanceReturn<T>, ...ReturnType<typeof signal<T>>];
18
+ }): [WithPersistanceReturn<T>, Signal<T, T>];
@@ -1,4 +1,4 @@
1
- import { type Observable } from "rxjs";
1
+ import type { Observable } from "rxjs";
2
2
  import { SIGNAL_RESET } from "./constants";
3
3
  type Option<R = undefined> = {
4
4
  key?: string;
@@ -10,15 +10,9 @@ type Option<R = undefined> = {
10
10
  type SetState<S> = (stateOrUpdater: typeof SIGNAL_RESET | S | ((prev: S) => S)) => void;
11
11
  export interface Signal<S, R> {
12
12
  setState: SetState<S>;
13
- useState: () => R;
13
+ getValue: () => R;
14
+ options: Option<S>;
15
+ subject: Observable<S>;
14
16
  }
15
- type Return<S, R> = [
16
- () => R,
17
- SetState<S>,
18
- () => R,
19
- Observable<R>,
20
- Option<S>,
21
- Signal<S, R>
22
- ];
23
- export declare function signal<T = undefined>(options: Option<T>): Return<T, T>;
17
+ export declare function signal<T = undefined>(options: Option<T>): Signal<T, T>;
24
18
  export {};
@@ -1,2 +1,2 @@
1
1
  import { type Signal } from "./signal";
2
- export declare const useSignal: <S, R>(signal: Signal<S, R>) => readonly [R, (stateOrUpdater: typeof import("./constants").SIGNAL_RESET | S | ((prev: S) => S)) => void];
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];
@@ -1,2 +1,2 @@
1
1
  import { type Signal } from "./signal";
2
- export declare const useSignalValue: <S, R>(signal: Signal<S, R>) => R;
2
+ export declare const useSignalValue: <S, R>(signal: Signal<S, R>, key?: string) => S | R;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reactjrx",
3
3
  "private": false,
4
- "version": "1.29.2",
4
+ "version": "1.31.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -57,9 +57,7 @@
57
57
  "typescript": "^5.0.4",
58
58
  "vite": "^4.2.1",
59
59
  "vite-plugin-dts": "^2.2.0",
60
- "vitest": "^0.31.0"
61
- },
62
- "dependencies": {
60
+ "vitest": "^0.31.0",
63
61
  "@testing-library/react": "^14.0.0",
64
62
  "@types/node": "^18.15.11"
65
63
  },