reactjrx 1.53.0 → 1.55.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 +253 -174
- package/dist/index.d.ts +2 -2
- package/dist/index.js +255 -176
- package/dist/lib/binding/useObserve.d.ts +1 -0
- package/dist/lib/queries/client/createClient.d.ts +13 -6
- package/dist/lib/queries/client/mutations/MutationClient.d.ts +11 -0
- package/dist/lib/queries/client/mutations/operators.d.ts +3 -0
- package/dist/lib/queries/client/mutations/types.d.ts +58 -0
- package/dist/lib/queries/react/Provider.d.ts +13 -6
- package/dist/lib/queries/react/mutations/useMutation.d.ts +46 -0
- package/package.json +7 -4
- package/dist/lib/queries/react/mutations/useAsyncQuery.d.ts +0 -82
- /package/dist/lib/queries/react/mutations/{useAsyncQuery.test.d.ts → useMutation.test.d.ts} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -35,12 +35,17 @@ function primitiveEqual(objA, objB) {
|
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
37
|
function useObserve(source$, unsafeOptions, unsafeDeps) {
|
|
38
|
-
const options = unsafeOptions != null && !Array.isArray(unsafeOptions) ? unsafeOptions : {
|
|
38
|
+
const options = unsafeOptions != null && !Array.isArray(unsafeOptions) ? unsafeOptions : {
|
|
39
|
+
defaultValue: void 0,
|
|
40
|
+
key: "",
|
|
41
|
+
unsubscribeOnUnmount: true
|
|
42
|
+
};
|
|
39
43
|
const deps = unsafeDeps == null && Array.isArray(unsafeOptions) ? unsafeOptions : typeof source$ === "function" ? unsafeDeps ?? [] : [source$];
|
|
40
44
|
const valueRef = react.useRef(
|
|
41
45
|
"getValue" in source$ && typeof source$.getValue === "function" ? source$.getValue() : options.defaultValue
|
|
42
46
|
);
|
|
43
47
|
const sourceRef = useLiveRef(source$);
|
|
48
|
+
const optionsRef = useLiveRef(options);
|
|
44
49
|
const subscribe = react.useCallback(
|
|
45
50
|
(next) => {
|
|
46
51
|
const source = sourceRef.current;
|
|
@@ -64,6 +69,8 @@ function useObserve(source$, unsafeOptions, unsafeDeps) {
|
|
|
64
69
|
})
|
|
65
70
|
).subscribe(next);
|
|
66
71
|
return () => {
|
|
72
|
+
if (optionsRef.current.unsubscribeOnUnmount === false)
|
|
73
|
+
return;
|
|
67
74
|
sub.unsubscribe();
|
|
68
75
|
};
|
|
69
76
|
},
|
|
@@ -391,175 +398,6 @@ function retryBackoff(config) {
|
|
|
391
398
|
);
|
|
392
399
|
});
|
|
393
400
|
}
|
|
394
|
-
function shallowEqual(objA, objB) {
|
|
395
|
-
if (objA === null || objA === void 0 || objB === void 0) {
|
|
396
|
-
return objA === objB;
|
|
397
|
-
}
|
|
398
|
-
if (typeof objA !== "object" || typeof objB !== "object") {
|
|
399
|
-
return objA === objB;
|
|
400
|
-
}
|
|
401
|
-
if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
|
|
402
|
-
return false;
|
|
403
|
-
}
|
|
404
|
-
const keysA = Object.keys(objA);
|
|
405
|
-
const keysB = Object.keys(objB);
|
|
406
|
-
if (keysA.length !== keysB.length) {
|
|
407
|
-
return false;
|
|
408
|
-
}
|
|
409
|
-
for (const key of keysA) {
|
|
410
|
-
if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
|
|
411
|
-
return false;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return true;
|
|
415
|
-
}
|
|
416
|
-
const retryOnError = (options) => retryBackoff({
|
|
417
|
-
initialInterval: 100,
|
|
418
|
-
...typeof options.retry === "function" ? {
|
|
419
|
-
shouldRetry: options.retry
|
|
420
|
-
} : {
|
|
421
|
-
maxRetries: options.retry === false ? 0 : options.retry ?? 3
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
const mergeResults = (stream$) => stream$.pipe(
|
|
425
|
-
rxjs.scan(
|
|
426
|
-
(acc, current) => {
|
|
427
|
-
return {
|
|
428
|
-
...acc,
|
|
429
|
-
...current
|
|
430
|
-
};
|
|
431
|
-
},
|
|
432
|
-
{
|
|
433
|
-
data: void 0,
|
|
434
|
-
error: void 0,
|
|
435
|
-
fetchStatus: "idle",
|
|
436
|
-
status: "loading"
|
|
437
|
-
}
|
|
438
|
-
),
|
|
439
|
-
rxjs.distinctUntilChanged(
|
|
440
|
-
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
441
|
-
)
|
|
442
|
-
);
|
|
443
|
-
function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
|
|
444
|
-
const queryRef = useLiveRef(query);
|
|
445
|
-
const triggerSubject = useSubject();
|
|
446
|
-
const resetSubject = useSubject({
|
|
447
|
-
/**
|
|
448
|
-
* @important
|
|
449
|
-
* Because async query can still run after unmount, the user might
|
|
450
|
-
* want to use reset for whatever reason. We will only manually complete
|
|
451
|
-
* this subject whenever the main query hook finalize.
|
|
452
|
-
*/
|
|
453
|
-
completeOnUnmount: false
|
|
454
|
-
});
|
|
455
|
-
const optionsRef = useLiveRef(
|
|
456
|
-
typeof mapOperatorOrOptions === "object" ? mapOperatorOrOptions : options
|
|
457
|
-
);
|
|
458
|
-
const data$ = useBehaviorSubject({
|
|
459
|
-
data: void 0,
|
|
460
|
-
error: void 0,
|
|
461
|
-
status: "idle"
|
|
462
|
-
});
|
|
463
|
-
const mapOperator = typeof mapOperatorOrOptions === "string" ? mapOperatorOrOptions : "merge";
|
|
464
|
-
react.useEffect(() => {
|
|
465
|
-
const switchOperator = mapOperator === "concat" ? rxjs.concatMap : mapOperator === "switch" ? rxjs.switchMap : rxjs.mergeMap;
|
|
466
|
-
const subscription = rxjs.merge(
|
|
467
|
-
resetSubject.current.pipe(
|
|
468
|
-
rxjs.map(
|
|
469
|
-
() => ({
|
|
470
|
-
status: "idle",
|
|
471
|
-
data: void 0,
|
|
472
|
-
error: void 0
|
|
473
|
-
})
|
|
474
|
-
)
|
|
475
|
-
),
|
|
476
|
-
triggerSubject.current.pipe(
|
|
477
|
-
switchOperator((args) => {
|
|
478
|
-
const isLastMutationCalled = triggerSubject.current.pipe(
|
|
479
|
-
rxjs.take(1),
|
|
480
|
-
rxjs.map(() => mapOperator === "concat"),
|
|
481
|
-
rxjs.startWith(true)
|
|
482
|
-
);
|
|
483
|
-
return rxjs.merge(
|
|
484
|
-
rxjs.of({
|
|
485
|
-
status: "loading"
|
|
486
|
-
}),
|
|
487
|
-
rxjs.combineLatest([
|
|
488
|
-
rxjs.defer(() => rxjs.from(queryRef.current(args))).pipe(
|
|
489
|
-
retryOnError(optionsRef.current),
|
|
490
|
-
rxjs.first(),
|
|
491
|
-
rxjs.map((data) => ({ data, isError: false })),
|
|
492
|
-
rxjs.catchError((error) => {
|
|
493
|
-
console.error(error);
|
|
494
|
-
if (optionsRef.current.onError != null) {
|
|
495
|
-
optionsRef.current.onError(error, args);
|
|
496
|
-
}
|
|
497
|
-
return rxjs.of({ data: error, isError: true });
|
|
498
|
-
})
|
|
499
|
-
),
|
|
500
|
-
isLastMutationCalled
|
|
501
|
-
]).pipe(
|
|
502
|
-
rxjs.map(([{ data, isError }, isLastMutationCalled2]) => {
|
|
503
|
-
if (!isError) {
|
|
504
|
-
if (optionsRef.current.onSuccess != null)
|
|
505
|
-
optionsRef.current.onSuccess(data, args);
|
|
506
|
-
}
|
|
507
|
-
if (isLastMutationCalled2) {
|
|
508
|
-
return isError ? {
|
|
509
|
-
status: "error",
|
|
510
|
-
error: data,
|
|
511
|
-
data: void 0
|
|
512
|
-
} : {
|
|
513
|
-
status: "success",
|
|
514
|
-
error: void 0,
|
|
515
|
-
data
|
|
516
|
-
};
|
|
517
|
-
}
|
|
518
|
-
return void 0;
|
|
519
|
-
}),
|
|
520
|
-
rxjs.takeUntil(resetSubject.current)
|
|
521
|
-
)
|
|
522
|
-
);
|
|
523
|
-
}),
|
|
524
|
-
optionsRef.current.triggerHook ?? rxjs.identity,
|
|
525
|
-
rxjs.finalize(() => {
|
|
526
|
-
resetSubject.current.complete();
|
|
527
|
-
})
|
|
528
|
-
)
|
|
529
|
-
).pipe(
|
|
530
|
-
rxjs.filter((state) => !!state && !!Object.keys(state).length),
|
|
531
|
-
/**
|
|
532
|
-
* @important
|
|
533
|
-
* state update optimization
|
|
534
|
-
*/
|
|
535
|
-
rxjs.distinctUntilChanged(shallowEqual)
|
|
536
|
-
).subscribe((state) => {
|
|
537
|
-
data$.current.next({
|
|
538
|
-
...data$.current.getValue(),
|
|
539
|
-
...state
|
|
540
|
-
});
|
|
541
|
-
});
|
|
542
|
-
return () => {
|
|
543
|
-
if (optionsRef.current.cancelOnUnMount) {
|
|
544
|
-
subscription.unsubscribe();
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
}, [mapOperator]);
|
|
548
|
-
const result = useObserve(
|
|
549
|
-
() => data$.current,
|
|
550
|
-
{
|
|
551
|
-
defaultValue: data$.current.getValue()
|
|
552
|
-
},
|
|
553
|
-
[]
|
|
554
|
-
);
|
|
555
|
-
const mutate = react.useCallback((arg) => {
|
|
556
|
-
triggerSubject.current.next(arg);
|
|
557
|
-
}, []);
|
|
558
|
-
const reset = react.useCallback(() => {
|
|
559
|
-
resetSubject.current.next();
|
|
560
|
-
}, []);
|
|
561
|
-
return { ...result, isLoading: result.status === "loading", mutate, reset };
|
|
562
|
-
}
|
|
563
401
|
const Context = react.createContext({
|
|
564
402
|
client: null
|
|
565
403
|
});
|
|
@@ -574,7 +412,7 @@ const ClientEffect = ({
|
|
|
574
412
|
}, [client]);
|
|
575
413
|
return null;
|
|
576
414
|
};
|
|
577
|
-
const
|
|
415
|
+
const QueryClientProvider = react.memo(
|
|
578
416
|
({ children, client }) => {
|
|
579
417
|
const value = react.useMemo(() => ({ client: client.client }), [client]);
|
|
580
418
|
return /* @__PURE__ */ jsxRuntime.jsxs(Context.Provider, { value, children: [
|
|
@@ -590,7 +428,92 @@ const useQueryClient = () => {
|
|
|
590
428
|
}
|
|
591
429
|
return context.client;
|
|
592
430
|
};
|
|
431
|
+
function useMutation(options) {
|
|
432
|
+
const client = useQueryClient();
|
|
433
|
+
const optionsRef = useLiveRef(options);
|
|
434
|
+
const optionsSubject = useBehaviorSubject(options);
|
|
435
|
+
const [bufferTriggers, setBufferTriggers] = react.useState([]);
|
|
436
|
+
const createMutation = react.useCallback(
|
|
437
|
+
() => client.createMutation(
|
|
438
|
+
optionsSubject.current.pipe(
|
|
439
|
+
rxjs.map((options2) => ({
|
|
440
|
+
mutationKey: ["none"],
|
|
441
|
+
...options2
|
|
442
|
+
}))
|
|
443
|
+
)
|
|
444
|
+
),
|
|
445
|
+
[]
|
|
446
|
+
);
|
|
447
|
+
const [mutation, setMutation] = react.useState(void 0);
|
|
448
|
+
const { mutation$, trigger$, reset$ } = mutation ?? {};
|
|
449
|
+
react.useEffect(() => {
|
|
450
|
+
const mutation2 = createMutation();
|
|
451
|
+
setMutation(mutation2);
|
|
452
|
+
return () => {
|
|
453
|
+
mutation2.destroy();
|
|
454
|
+
};
|
|
455
|
+
}, []);
|
|
456
|
+
const result = useObserve(
|
|
457
|
+
() => !mutation$ ? rxjs.NEVER : mutation$.pipe(
|
|
458
|
+
optionsRef.current.__triggerHook ?? rxjs.identity,
|
|
459
|
+
rxjs.finalize(() => {
|
|
460
|
+
console.log("finalize");
|
|
461
|
+
})
|
|
462
|
+
),
|
|
463
|
+
{
|
|
464
|
+
defaultValue: {
|
|
465
|
+
data: void 0,
|
|
466
|
+
error: void 0,
|
|
467
|
+
status: "idle"
|
|
468
|
+
},
|
|
469
|
+
unsubscribeOnUnmount: optionsRef.current.cancelOnUnMount ?? false
|
|
470
|
+
},
|
|
471
|
+
[mutation$]
|
|
472
|
+
);
|
|
473
|
+
const mutate = react.useCallback(
|
|
474
|
+
(mutationArgs) => {
|
|
475
|
+
if (!trigger$) {
|
|
476
|
+
setBufferTriggers((value) => [...value, mutationArgs]);
|
|
477
|
+
}
|
|
478
|
+
trigger$ == null ? void 0 : trigger$.next(mutationArgs);
|
|
479
|
+
},
|
|
480
|
+
[trigger$]
|
|
481
|
+
);
|
|
482
|
+
react.useEffect(() => {
|
|
483
|
+
if (mutation && !mutation.getClosed()) {
|
|
484
|
+
bufferTriggers.forEach((args) => {
|
|
485
|
+
mutation.trigger$.next(args);
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}, [bufferTriggers, mutation]);
|
|
489
|
+
const reset = react.useCallback(() => {
|
|
490
|
+
reset$ == null ? void 0 : reset$.next();
|
|
491
|
+
}, [reset$]);
|
|
492
|
+
return { mutate, reset, ...result };
|
|
493
|
+
}
|
|
593
494
|
const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
495
|
+
function shallowEqual(objA, objB) {
|
|
496
|
+
if (objA === null || objA === void 0 || objB === void 0) {
|
|
497
|
+
return objA === objB;
|
|
498
|
+
}
|
|
499
|
+
if (typeof objA !== "object" || typeof objB !== "object") {
|
|
500
|
+
return objA === objB;
|
|
501
|
+
}
|
|
502
|
+
if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
|
|
503
|
+
return false;
|
|
504
|
+
}
|
|
505
|
+
const keysA = Object.keys(objA);
|
|
506
|
+
const keysB = Object.keys(objB);
|
|
507
|
+
if (keysA.length !== keysB.length) {
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
510
|
+
for (const key of keysA) {
|
|
511
|
+
if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
594
517
|
function isDefined(arg) {
|
|
595
518
|
return arg !== null && arg !== void 0;
|
|
596
519
|
}
|
|
@@ -775,6 +698,33 @@ const serializeKey = (key) => {
|
|
|
775
698
|
return "[]";
|
|
776
699
|
return serializeObject(key);
|
|
777
700
|
};
|
|
701
|
+
const retryOnError = (options) => retryBackoff({
|
|
702
|
+
initialInterval: 100,
|
|
703
|
+
...typeof options.retry === "function" ? {
|
|
704
|
+
shouldRetry: options.retry
|
|
705
|
+
} : {
|
|
706
|
+
maxRetries: options.retry === false ? 0 : options.retry ?? 3
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
const mergeResults$1 = (stream$) => stream$.pipe(
|
|
710
|
+
rxjs.scan(
|
|
711
|
+
(acc, current) => {
|
|
712
|
+
return {
|
|
713
|
+
...acc,
|
|
714
|
+
...current
|
|
715
|
+
};
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
data: void 0,
|
|
719
|
+
error: void 0,
|
|
720
|
+
fetchStatus: "idle",
|
|
721
|
+
status: "loading"
|
|
722
|
+
}
|
|
723
|
+
),
|
|
724
|
+
rxjs.distinctUntilChanged(
|
|
725
|
+
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
726
|
+
)
|
|
727
|
+
);
|
|
778
728
|
const resetStyle = { backgroundColor: "transparent", color: "inherit" };
|
|
779
729
|
function createLogger(env) {
|
|
780
730
|
const _logger = {
|
|
@@ -1529,11 +1479,139 @@ const dispatchExternalRefetchToAllQueries = ({
|
|
|
1529
1479
|
}),
|
|
1530
1480
|
rxjs.filter((trigger2) => trigger2.type !== "refetch")
|
|
1531
1481
|
);
|
|
1482
|
+
const mergeResults = (stream$) => stream$.pipe(
|
|
1483
|
+
rxjs.scan(
|
|
1484
|
+
(acc, current) => {
|
|
1485
|
+
return {
|
|
1486
|
+
...acc,
|
|
1487
|
+
...current
|
|
1488
|
+
};
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
data: void 0,
|
|
1492
|
+
error: void 0,
|
|
1493
|
+
// fetchStatus: "idle",
|
|
1494
|
+
status: "loading"
|
|
1495
|
+
}
|
|
1496
|
+
),
|
|
1497
|
+
rxjs.distinctUntilChanged(
|
|
1498
|
+
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1499
|
+
)
|
|
1500
|
+
);
|
|
1501
|
+
class MutationClient {
|
|
1502
|
+
constructor() {
|
|
1503
|
+
__publicField(this, "createMutation", (options$) => {
|
|
1504
|
+
const trigger$ = new rxjs.Subject();
|
|
1505
|
+
const reset$ = new rxjs.Subject();
|
|
1506
|
+
let closed = false;
|
|
1507
|
+
const destroy = () => {
|
|
1508
|
+
if (closed) {
|
|
1509
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1510
|
+
}
|
|
1511
|
+
closed = true;
|
|
1512
|
+
trigger$.complete();
|
|
1513
|
+
reset$.complete();
|
|
1514
|
+
};
|
|
1515
|
+
const initOptions = options$.pipe(
|
|
1516
|
+
rxjs.tap(({ mutationKey }) => {
|
|
1517
|
+
const serializedKey = serializeKey(mutationKey);
|
|
1518
|
+
Logger.log("query$", serializedKey);
|
|
1519
|
+
}),
|
|
1520
|
+
rxjs.take(1)
|
|
1521
|
+
);
|
|
1522
|
+
const mutation$ = initOptions.pipe(
|
|
1523
|
+
rxjs.mergeMap(
|
|
1524
|
+
(options) => rxjs.of(options).pipe(
|
|
1525
|
+
options.__queryInitHook ?? rxjs.identity
|
|
1526
|
+
)
|
|
1527
|
+
),
|
|
1528
|
+
rxjs.mergeMap((options) => {
|
|
1529
|
+
const { mapOperator } = options;
|
|
1530
|
+
const switchOperator = mapOperator === "concat" ? rxjs.concatMap : mapOperator === "switch" ? rxjs.switchMap : rxjs.mergeMap;
|
|
1531
|
+
return trigger$.pipe(
|
|
1532
|
+
rxjs.withLatestFrom(options$),
|
|
1533
|
+
switchOperator(([mutationArg, { mutationFn }]) => {
|
|
1534
|
+
const queryRunner$ = rxjs.defer(
|
|
1535
|
+
() => rxjs.from(mutationFn(mutationArg))
|
|
1536
|
+
).pipe(
|
|
1537
|
+
retryOnError(options),
|
|
1538
|
+
rxjs.take(1),
|
|
1539
|
+
rxjs.map((data) => ({ data, isError: false })),
|
|
1540
|
+
rxjs.catchError((error) => {
|
|
1541
|
+
console.error(error);
|
|
1542
|
+
if (options.onError != null) {
|
|
1543
|
+
options.onError(error, mutationArg);
|
|
1544
|
+
}
|
|
1545
|
+
return rxjs.of({ data: error, isError: true });
|
|
1546
|
+
}),
|
|
1547
|
+
rxjs.share()
|
|
1548
|
+
);
|
|
1549
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1550
|
+
rxjs.map(({ data, isError }) => isError || data)
|
|
1551
|
+
);
|
|
1552
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1553
|
+
rxjs.take(1),
|
|
1554
|
+
rxjs.map(() => mapOperator === "concat"),
|
|
1555
|
+
rxjs.startWith(true),
|
|
1556
|
+
rxjs.takeUntil(queryIsOver$)
|
|
1557
|
+
);
|
|
1558
|
+
const loading$ = rxjs.of({
|
|
1559
|
+
status: "loading"
|
|
1560
|
+
});
|
|
1561
|
+
return rxjs.merge(
|
|
1562
|
+
loading$,
|
|
1563
|
+
rxjs.combineLatest([
|
|
1564
|
+
queryRunner$,
|
|
1565
|
+
isThisCurrentFunctionLastOneCalled
|
|
1566
|
+
]).pipe(
|
|
1567
|
+
rxjs.map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1568
|
+
if (!isError) {
|
|
1569
|
+
if (options.onSuccess != null)
|
|
1570
|
+
options.onSuccess(data, mutationArg);
|
|
1571
|
+
}
|
|
1572
|
+
if (isLastMutationCalled) {
|
|
1573
|
+
return isError ? {
|
|
1574
|
+
status: "error",
|
|
1575
|
+
error: data,
|
|
1576
|
+
data: void 0
|
|
1577
|
+
} : {
|
|
1578
|
+
status: "success",
|
|
1579
|
+
error: void 0,
|
|
1580
|
+
data
|
|
1581
|
+
};
|
|
1582
|
+
}
|
|
1583
|
+
return {};
|
|
1584
|
+
}),
|
|
1585
|
+
rxjs.takeUntil(reset$)
|
|
1586
|
+
)
|
|
1587
|
+
).pipe(options.__queryRunnerHook ?? rxjs.identity);
|
|
1588
|
+
}),
|
|
1589
|
+
options.__queryTriggerHook ?? rxjs.identity,
|
|
1590
|
+
mergeResults
|
|
1591
|
+
);
|
|
1592
|
+
}),
|
|
1593
|
+
rxjs.finalize(() => {
|
|
1594
|
+
if (!closed) {
|
|
1595
|
+
destroy();
|
|
1596
|
+
}
|
|
1597
|
+
})
|
|
1598
|
+
);
|
|
1599
|
+
return {
|
|
1600
|
+
mutation$,
|
|
1601
|
+
trigger$,
|
|
1602
|
+
reset$,
|
|
1603
|
+
destroy,
|
|
1604
|
+
getClosed: () => closed
|
|
1605
|
+
};
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1532
1609
|
const createClient = () => {
|
|
1533
1610
|
const queryStore = createQueryStore();
|
|
1534
1611
|
const invalidationClient = createInvalidationClient({ queryStore });
|
|
1535
1612
|
const cacheClient = createCacheClient({ queryStore });
|
|
1536
1613
|
const refetchClient = createRefetchClient();
|
|
1614
|
+
const mutationClient = new MutationClient();
|
|
1537
1615
|
let hasCalledStart = false;
|
|
1538
1616
|
const query = ({
|
|
1539
1617
|
key,
|
|
@@ -1610,7 +1688,7 @@ const createClient = () => {
|
|
|
1610
1688
|
trigger$
|
|
1611
1689
|
})
|
|
1612
1690
|
),
|
|
1613
|
-
mergeResults,
|
|
1691
|
+
mergeResults$1,
|
|
1614
1692
|
rxjs.withLatestFrom(options$),
|
|
1615
1693
|
rxjs.takeWhile(([result, options]) => {
|
|
1616
1694
|
const shouldStop = result.data !== void 0 && options.terminateOnFirstResult;
|
|
@@ -1659,6 +1737,7 @@ const createClient = () => {
|
|
|
1659
1737
|
start,
|
|
1660
1738
|
query,
|
|
1661
1739
|
queryStore,
|
|
1740
|
+
...mutationClient,
|
|
1662
1741
|
...invalidationClient,
|
|
1663
1742
|
...cacheClient,
|
|
1664
1743
|
...refetchClient
|
|
@@ -1671,7 +1750,7 @@ class QueryClient {
|
|
|
1671
1750
|
}
|
|
1672
1751
|
}
|
|
1673
1752
|
exports.QueryClient = QueryClient;
|
|
1674
|
-
exports.QueryClientProvider =
|
|
1753
|
+
exports.QueryClientProvider = QueryClientProvider;
|
|
1675
1754
|
exports.SIGNAL_RESET = SIGNAL_RESET;
|
|
1676
1755
|
exports.createClient = createClient;
|
|
1677
1756
|
exports.createLocalforageAdapter = createLocalforageAdapter;
|
|
@@ -1681,9 +1760,9 @@ exports.getDelay = getDelay;
|
|
|
1681
1760
|
exports.retryBackoff = retryBackoff;
|
|
1682
1761
|
exports.signal = signal;
|
|
1683
1762
|
exports.trigger = trigger;
|
|
1684
|
-
exports.useAsyncQuery = useAsyncQuery;
|
|
1685
1763
|
exports.useBehaviorSubject = useBehaviorSubject;
|
|
1686
1764
|
exports.useLiveRef = useLiveRef;
|
|
1765
|
+
exports.useMutation = useMutation;
|
|
1687
1766
|
exports.useObserve = useObserve;
|
|
1688
1767
|
exports.useObserveCallback = useObserveCallback;
|
|
1689
1768
|
exports.usePersistSignals = usePersistSignals;
|
package/dist/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export * from "./lib/state/persistance/usePersistSignals";
|
|
|
13
13
|
export * from "./lib/utils/useUnmountObservable";
|
|
14
14
|
export * from "./lib/utils/retryBackoff";
|
|
15
15
|
export * from "./lib/utils/useLiveRef";
|
|
16
|
-
export * from "./lib/queries/react/mutations/
|
|
16
|
+
export * from "./lib/queries/react/mutations/useMutation";
|
|
17
17
|
export * from "./lib/queries/react/queries/useQuery";
|
|
18
18
|
export * from "./lib/queries/react/useSubscribeEffect";
|
|
19
19
|
export * from "./lib/queries/client/createClient";
|
|
20
|
-
export {
|
|
20
|
+
export { QueryClientProvider, useQueryClient } from "./lib/queries/react/Provider";
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,8 @@ var __publicField = (obj, key, value) => {
|
|
|
4
4
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
return value;
|
|
6
6
|
};
|
|
7
|
-
import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, createContext, memo, useContext } from "react";
|
|
8
|
-
import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, map, of, zip, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError,
|
|
7
|
+
import { useRef, useMemo, useCallback, useSyncExternalStore, useEffect, createContext, memo, useContext, useState } from "react";
|
|
8
|
+
import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, map, of, zip, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError, NEVER, fromEvent, filter, skip, withLatestFrom, scan, retry, shareReplay, endWith, delay, take, takeUntil, share, startWith, pairwise, mergeMap, combineLatest, concatMap as concatMap$1, takeWhile } from "rxjs";
|
|
9
9
|
import { retryWhen, concatMap, tap as tap$1 } from "rxjs/operators";
|
|
10
10
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
11
11
|
const useLiveRef = (value) => {
|
|
@@ -33,12 +33,17 @@ function primitiveEqual(objA, objB) {
|
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
function useObserve(source$, unsafeOptions, unsafeDeps) {
|
|
36
|
-
const options = unsafeOptions != null && !Array.isArray(unsafeOptions) ? unsafeOptions : {
|
|
36
|
+
const options = unsafeOptions != null && !Array.isArray(unsafeOptions) ? unsafeOptions : {
|
|
37
|
+
defaultValue: void 0,
|
|
38
|
+
key: "",
|
|
39
|
+
unsubscribeOnUnmount: true
|
|
40
|
+
};
|
|
37
41
|
const deps = unsafeDeps == null && Array.isArray(unsafeOptions) ? unsafeOptions : typeof source$ === "function" ? unsafeDeps ?? [] : [source$];
|
|
38
42
|
const valueRef = useRef(
|
|
39
43
|
"getValue" in source$ && typeof source$.getValue === "function" ? source$.getValue() : options.defaultValue
|
|
40
44
|
);
|
|
41
45
|
const sourceRef = useLiveRef(source$);
|
|
46
|
+
const optionsRef = useLiveRef(options);
|
|
42
47
|
const subscribe = useCallback(
|
|
43
48
|
(next) => {
|
|
44
49
|
const source = sourceRef.current;
|
|
@@ -62,6 +67,8 @@ function useObserve(source$, unsafeOptions, unsafeDeps) {
|
|
|
62
67
|
})
|
|
63
68
|
).subscribe(next);
|
|
64
69
|
return () => {
|
|
70
|
+
if (optionsRef.current.unsubscribeOnUnmount === false)
|
|
71
|
+
return;
|
|
65
72
|
sub.unsubscribe();
|
|
66
73
|
};
|
|
67
74
|
},
|
|
@@ -389,175 +396,6 @@ function retryBackoff(config) {
|
|
|
389
396
|
);
|
|
390
397
|
});
|
|
391
398
|
}
|
|
392
|
-
function shallowEqual(objA, objB) {
|
|
393
|
-
if (objA === null || objA === void 0 || objB === void 0) {
|
|
394
|
-
return objA === objB;
|
|
395
|
-
}
|
|
396
|
-
if (typeof objA !== "object" || typeof objB !== "object") {
|
|
397
|
-
return objA === objB;
|
|
398
|
-
}
|
|
399
|
-
if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
|
|
400
|
-
return false;
|
|
401
|
-
}
|
|
402
|
-
const keysA = Object.keys(objA);
|
|
403
|
-
const keysB = Object.keys(objB);
|
|
404
|
-
if (keysA.length !== keysB.length) {
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
407
|
-
for (const key of keysA) {
|
|
408
|
-
if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
|
|
409
|
-
return false;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
return true;
|
|
413
|
-
}
|
|
414
|
-
const retryOnError = (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 mergeResults = (stream$) => stream$.pipe(
|
|
423
|
-
scan(
|
|
424
|
-
(acc, current) => {
|
|
425
|
-
return {
|
|
426
|
-
...acc,
|
|
427
|
-
...current
|
|
428
|
-
};
|
|
429
|
-
},
|
|
430
|
-
{
|
|
431
|
-
data: void 0,
|
|
432
|
-
error: void 0,
|
|
433
|
-
fetchStatus: "idle",
|
|
434
|
-
status: "loading"
|
|
435
|
-
}
|
|
436
|
-
),
|
|
437
|
-
distinctUntilChanged(
|
|
438
|
-
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
439
|
-
)
|
|
440
|
-
);
|
|
441
|
-
function useAsyncQuery(query, mapOperatorOrOptions, options = {}) {
|
|
442
|
-
const queryRef = useLiveRef(query);
|
|
443
|
-
const triggerSubject = useSubject();
|
|
444
|
-
const resetSubject = useSubject({
|
|
445
|
-
/**
|
|
446
|
-
* @important
|
|
447
|
-
* Because async query can still run after unmount, the user might
|
|
448
|
-
* want to use reset for whatever reason. We will only manually complete
|
|
449
|
-
* this subject whenever the main query hook finalize.
|
|
450
|
-
*/
|
|
451
|
-
completeOnUnmount: false
|
|
452
|
-
});
|
|
453
|
-
const optionsRef = useLiveRef(
|
|
454
|
-
typeof mapOperatorOrOptions === "object" ? mapOperatorOrOptions : options
|
|
455
|
-
);
|
|
456
|
-
const data$ = useBehaviorSubject({
|
|
457
|
-
data: void 0,
|
|
458
|
-
error: void 0,
|
|
459
|
-
status: "idle"
|
|
460
|
-
});
|
|
461
|
-
const mapOperator = typeof mapOperatorOrOptions === "string" ? mapOperatorOrOptions : "merge";
|
|
462
|
-
useEffect(() => {
|
|
463
|
-
const switchOperator = mapOperator === "concat" ? concatMap$1 : mapOperator === "switch" ? switchMap : mergeMap;
|
|
464
|
-
const subscription = merge(
|
|
465
|
-
resetSubject.current.pipe(
|
|
466
|
-
map(
|
|
467
|
-
() => ({
|
|
468
|
-
status: "idle",
|
|
469
|
-
data: void 0,
|
|
470
|
-
error: void 0
|
|
471
|
-
})
|
|
472
|
-
)
|
|
473
|
-
),
|
|
474
|
-
triggerSubject.current.pipe(
|
|
475
|
-
switchOperator((args) => {
|
|
476
|
-
const isLastMutationCalled = triggerSubject.current.pipe(
|
|
477
|
-
take(1),
|
|
478
|
-
map(() => mapOperator === "concat"),
|
|
479
|
-
startWith(true)
|
|
480
|
-
);
|
|
481
|
-
return merge(
|
|
482
|
-
of({
|
|
483
|
-
status: "loading"
|
|
484
|
-
}),
|
|
485
|
-
combineLatest([
|
|
486
|
-
defer(() => from(queryRef.current(args))).pipe(
|
|
487
|
-
retryOnError(optionsRef.current),
|
|
488
|
-
first(),
|
|
489
|
-
map((data) => ({ data, isError: false })),
|
|
490
|
-
catchError((error) => {
|
|
491
|
-
console.error(error);
|
|
492
|
-
if (optionsRef.current.onError != null) {
|
|
493
|
-
optionsRef.current.onError(error, args);
|
|
494
|
-
}
|
|
495
|
-
return of({ data: error, isError: true });
|
|
496
|
-
})
|
|
497
|
-
),
|
|
498
|
-
isLastMutationCalled
|
|
499
|
-
]).pipe(
|
|
500
|
-
map(([{ data, isError }, isLastMutationCalled2]) => {
|
|
501
|
-
if (!isError) {
|
|
502
|
-
if (optionsRef.current.onSuccess != null)
|
|
503
|
-
optionsRef.current.onSuccess(data, args);
|
|
504
|
-
}
|
|
505
|
-
if (isLastMutationCalled2) {
|
|
506
|
-
return isError ? {
|
|
507
|
-
status: "error",
|
|
508
|
-
error: data,
|
|
509
|
-
data: void 0
|
|
510
|
-
} : {
|
|
511
|
-
status: "success",
|
|
512
|
-
error: void 0,
|
|
513
|
-
data
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
return void 0;
|
|
517
|
-
}),
|
|
518
|
-
takeUntil(resetSubject.current)
|
|
519
|
-
)
|
|
520
|
-
);
|
|
521
|
-
}),
|
|
522
|
-
optionsRef.current.triggerHook ?? identity,
|
|
523
|
-
finalize(() => {
|
|
524
|
-
resetSubject.current.complete();
|
|
525
|
-
})
|
|
526
|
-
)
|
|
527
|
-
).pipe(
|
|
528
|
-
filter((state) => !!state && !!Object.keys(state).length),
|
|
529
|
-
/**
|
|
530
|
-
* @important
|
|
531
|
-
* state update optimization
|
|
532
|
-
*/
|
|
533
|
-
distinctUntilChanged(shallowEqual)
|
|
534
|
-
).subscribe((state) => {
|
|
535
|
-
data$.current.next({
|
|
536
|
-
...data$.current.getValue(),
|
|
537
|
-
...state
|
|
538
|
-
});
|
|
539
|
-
});
|
|
540
|
-
return () => {
|
|
541
|
-
if (optionsRef.current.cancelOnUnMount) {
|
|
542
|
-
subscription.unsubscribe();
|
|
543
|
-
}
|
|
544
|
-
};
|
|
545
|
-
}, [mapOperator]);
|
|
546
|
-
const result = useObserve(
|
|
547
|
-
() => data$.current,
|
|
548
|
-
{
|
|
549
|
-
defaultValue: data$.current.getValue()
|
|
550
|
-
},
|
|
551
|
-
[]
|
|
552
|
-
);
|
|
553
|
-
const mutate = useCallback((arg) => {
|
|
554
|
-
triggerSubject.current.next(arg);
|
|
555
|
-
}, []);
|
|
556
|
-
const reset = useCallback(() => {
|
|
557
|
-
resetSubject.current.next();
|
|
558
|
-
}, []);
|
|
559
|
-
return { ...result, isLoading: result.status === "loading", mutate, reset };
|
|
560
|
-
}
|
|
561
399
|
const Context = createContext({
|
|
562
400
|
client: null
|
|
563
401
|
});
|
|
@@ -572,7 +410,7 @@ const ClientEffect = ({
|
|
|
572
410
|
}, [client]);
|
|
573
411
|
return null;
|
|
574
412
|
};
|
|
575
|
-
const
|
|
413
|
+
const QueryClientProvider = memo(
|
|
576
414
|
({ children, client }) => {
|
|
577
415
|
const value = useMemo(() => ({ client: client.client }), [client]);
|
|
578
416
|
return /* @__PURE__ */ jsxs(Context.Provider, { value, children: [
|
|
@@ -588,7 +426,92 @@ const useQueryClient = () => {
|
|
|
588
426
|
}
|
|
589
427
|
return context.client;
|
|
590
428
|
};
|
|
429
|
+
function useMutation(options) {
|
|
430
|
+
const client = useQueryClient();
|
|
431
|
+
const optionsRef = useLiveRef(options);
|
|
432
|
+
const optionsSubject = useBehaviorSubject(options);
|
|
433
|
+
const [bufferTriggers, setBufferTriggers] = useState([]);
|
|
434
|
+
const createMutation = useCallback(
|
|
435
|
+
() => client.createMutation(
|
|
436
|
+
optionsSubject.current.pipe(
|
|
437
|
+
map((options2) => ({
|
|
438
|
+
mutationKey: ["none"],
|
|
439
|
+
...options2
|
|
440
|
+
}))
|
|
441
|
+
)
|
|
442
|
+
),
|
|
443
|
+
[]
|
|
444
|
+
);
|
|
445
|
+
const [mutation, setMutation] = useState(void 0);
|
|
446
|
+
const { mutation$, trigger$, reset$ } = mutation ?? {};
|
|
447
|
+
useEffect(() => {
|
|
448
|
+
const mutation2 = createMutation();
|
|
449
|
+
setMutation(mutation2);
|
|
450
|
+
return () => {
|
|
451
|
+
mutation2.destroy();
|
|
452
|
+
};
|
|
453
|
+
}, []);
|
|
454
|
+
const result = useObserve(
|
|
455
|
+
() => !mutation$ ? NEVER : mutation$.pipe(
|
|
456
|
+
optionsRef.current.__triggerHook ?? identity,
|
|
457
|
+
finalize(() => {
|
|
458
|
+
console.log("finalize");
|
|
459
|
+
})
|
|
460
|
+
),
|
|
461
|
+
{
|
|
462
|
+
defaultValue: {
|
|
463
|
+
data: void 0,
|
|
464
|
+
error: void 0,
|
|
465
|
+
status: "idle"
|
|
466
|
+
},
|
|
467
|
+
unsubscribeOnUnmount: optionsRef.current.cancelOnUnMount ?? false
|
|
468
|
+
},
|
|
469
|
+
[mutation$]
|
|
470
|
+
);
|
|
471
|
+
const mutate = useCallback(
|
|
472
|
+
(mutationArgs) => {
|
|
473
|
+
if (!trigger$) {
|
|
474
|
+
setBufferTriggers((value) => [...value, mutationArgs]);
|
|
475
|
+
}
|
|
476
|
+
trigger$ == null ? void 0 : trigger$.next(mutationArgs);
|
|
477
|
+
},
|
|
478
|
+
[trigger$]
|
|
479
|
+
);
|
|
480
|
+
useEffect(() => {
|
|
481
|
+
if (mutation && !mutation.getClosed()) {
|
|
482
|
+
bufferTriggers.forEach((args) => {
|
|
483
|
+
mutation.trigger$.next(args);
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
}, [bufferTriggers, mutation]);
|
|
487
|
+
const reset = useCallback(() => {
|
|
488
|
+
reset$ == null ? void 0 : reset$.next();
|
|
489
|
+
}, [reset$]);
|
|
490
|
+
return { mutate, reset, ...result };
|
|
491
|
+
}
|
|
591
492
|
const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
493
|
+
function shallowEqual(objA, objB) {
|
|
494
|
+
if (objA === null || objA === void 0 || objB === void 0) {
|
|
495
|
+
return objA === objB;
|
|
496
|
+
}
|
|
497
|
+
if (typeof objA !== "object" || typeof objB !== "object") {
|
|
498
|
+
return objA === objB;
|
|
499
|
+
}
|
|
500
|
+
if (objA.constructor !== (objB == null ? void 0 : objB.constructor)) {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
const keysA = Object.keys(objA);
|
|
504
|
+
const keysB = Object.keys(objB);
|
|
505
|
+
if (keysA.length !== keysB.length) {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
for (const key of keysA) {
|
|
509
|
+
if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
|
|
510
|
+
return false;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
592
515
|
function isDefined(arg) {
|
|
593
516
|
return arg !== null && arg !== void 0;
|
|
594
517
|
}
|
|
@@ -773,6 +696,33 @@ const serializeKey = (key) => {
|
|
|
773
696
|
return "[]";
|
|
774
697
|
return serializeObject(key);
|
|
775
698
|
};
|
|
699
|
+
const retryOnError = (options) => retryBackoff({
|
|
700
|
+
initialInterval: 100,
|
|
701
|
+
...typeof options.retry === "function" ? {
|
|
702
|
+
shouldRetry: options.retry
|
|
703
|
+
} : {
|
|
704
|
+
maxRetries: options.retry === false ? 0 : options.retry ?? 3
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
const mergeResults$1 = (stream$) => stream$.pipe(
|
|
708
|
+
scan(
|
|
709
|
+
(acc, current) => {
|
|
710
|
+
return {
|
|
711
|
+
...acc,
|
|
712
|
+
...current
|
|
713
|
+
};
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
data: void 0,
|
|
717
|
+
error: void 0,
|
|
718
|
+
fetchStatus: "idle",
|
|
719
|
+
status: "loading"
|
|
720
|
+
}
|
|
721
|
+
),
|
|
722
|
+
distinctUntilChanged(
|
|
723
|
+
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
724
|
+
)
|
|
725
|
+
);
|
|
776
726
|
const resetStyle = { backgroundColor: "transparent", color: "inherit" };
|
|
777
727
|
function createLogger(env) {
|
|
778
728
|
const _logger = {
|
|
@@ -1527,11 +1477,139 @@ const dispatchExternalRefetchToAllQueries = ({
|
|
|
1527
1477
|
}),
|
|
1528
1478
|
filter((trigger2) => trigger2.type !== "refetch")
|
|
1529
1479
|
);
|
|
1480
|
+
const mergeResults = (stream$) => stream$.pipe(
|
|
1481
|
+
scan(
|
|
1482
|
+
(acc, current) => {
|
|
1483
|
+
return {
|
|
1484
|
+
...acc,
|
|
1485
|
+
...current
|
|
1486
|
+
};
|
|
1487
|
+
},
|
|
1488
|
+
{
|
|
1489
|
+
data: void 0,
|
|
1490
|
+
error: void 0,
|
|
1491
|
+
// fetchStatus: "idle",
|
|
1492
|
+
status: "loading"
|
|
1493
|
+
}
|
|
1494
|
+
),
|
|
1495
|
+
distinctUntilChanged(
|
|
1496
|
+
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1497
|
+
)
|
|
1498
|
+
);
|
|
1499
|
+
class MutationClient {
|
|
1500
|
+
constructor() {
|
|
1501
|
+
__publicField(this, "createMutation", (options$) => {
|
|
1502
|
+
const trigger$ = new Subject();
|
|
1503
|
+
const reset$ = new Subject();
|
|
1504
|
+
let closed = false;
|
|
1505
|
+
const destroy = () => {
|
|
1506
|
+
if (closed) {
|
|
1507
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1508
|
+
}
|
|
1509
|
+
closed = true;
|
|
1510
|
+
trigger$.complete();
|
|
1511
|
+
reset$.complete();
|
|
1512
|
+
};
|
|
1513
|
+
const initOptions = options$.pipe(
|
|
1514
|
+
tap(({ mutationKey }) => {
|
|
1515
|
+
const serializedKey = serializeKey(mutationKey);
|
|
1516
|
+
Logger.log("query$", serializedKey);
|
|
1517
|
+
}),
|
|
1518
|
+
take(1)
|
|
1519
|
+
);
|
|
1520
|
+
const mutation$ = initOptions.pipe(
|
|
1521
|
+
mergeMap(
|
|
1522
|
+
(options) => of(options).pipe(
|
|
1523
|
+
options.__queryInitHook ?? identity
|
|
1524
|
+
)
|
|
1525
|
+
),
|
|
1526
|
+
mergeMap((options) => {
|
|
1527
|
+
const { mapOperator } = options;
|
|
1528
|
+
const switchOperator = mapOperator === "concat" ? concatMap$1 : mapOperator === "switch" ? switchMap : mergeMap;
|
|
1529
|
+
return trigger$.pipe(
|
|
1530
|
+
withLatestFrom(options$),
|
|
1531
|
+
switchOperator(([mutationArg, { mutationFn }]) => {
|
|
1532
|
+
const queryRunner$ = defer(
|
|
1533
|
+
() => from(mutationFn(mutationArg))
|
|
1534
|
+
).pipe(
|
|
1535
|
+
retryOnError(options),
|
|
1536
|
+
take(1),
|
|
1537
|
+
map((data) => ({ data, isError: false })),
|
|
1538
|
+
catchError((error) => {
|
|
1539
|
+
console.error(error);
|
|
1540
|
+
if (options.onError != null) {
|
|
1541
|
+
options.onError(error, mutationArg);
|
|
1542
|
+
}
|
|
1543
|
+
return of({ data: error, isError: true });
|
|
1544
|
+
}),
|
|
1545
|
+
share()
|
|
1546
|
+
);
|
|
1547
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1548
|
+
map(({ data, isError }) => isError || data)
|
|
1549
|
+
);
|
|
1550
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1551
|
+
take(1),
|
|
1552
|
+
map(() => mapOperator === "concat"),
|
|
1553
|
+
startWith(true),
|
|
1554
|
+
takeUntil(queryIsOver$)
|
|
1555
|
+
);
|
|
1556
|
+
const loading$ = of({
|
|
1557
|
+
status: "loading"
|
|
1558
|
+
});
|
|
1559
|
+
return merge(
|
|
1560
|
+
loading$,
|
|
1561
|
+
combineLatest([
|
|
1562
|
+
queryRunner$,
|
|
1563
|
+
isThisCurrentFunctionLastOneCalled
|
|
1564
|
+
]).pipe(
|
|
1565
|
+
map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1566
|
+
if (!isError) {
|
|
1567
|
+
if (options.onSuccess != null)
|
|
1568
|
+
options.onSuccess(data, mutationArg);
|
|
1569
|
+
}
|
|
1570
|
+
if (isLastMutationCalled) {
|
|
1571
|
+
return isError ? {
|
|
1572
|
+
status: "error",
|
|
1573
|
+
error: data,
|
|
1574
|
+
data: void 0
|
|
1575
|
+
} : {
|
|
1576
|
+
status: "success",
|
|
1577
|
+
error: void 0,
|
|
1578
|
+
data
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
return {};
|
|
1582
|
+
}),
|
|
1583
|
+
takeUntil(reset$)
|
|
1584
|
+
)
|
|
1585
|
+
).pipe(options.__queryRunnerHook ?? identity);
|
|
1586
|
+
}),
|
|
1587
|
+
options.__queryTriggerHook ?? identity,
|
|
1588
|
+
mergeResults
|
|
1589
|
+
);
|
|
1590
|
+
}),
|
|
1591
|
+
finalize(() => {
|
|
1592
|
+
if (!closed) {
|
|
1593
|
+
destroy();
|
|
1594
|
+
}
|
|
1595
|
+
})
|
|
1596
|
+
);
|
|
1597
|
+
return {
|
|
1598
|
+
mutation$,
|
|
1599
|
+
trigger$,
|
|
1600
|
+
reset$,
|
|
1601
|
+
destroy,
|
|
1602
|
+
getClosed: () => closed
|
|
1603
|
+
};
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1530
1607
|
const createClient = () => {
|
|
1531
1608
|
const queryStore = createQueryStore();
|
|
1532
1609
|
const invalidationClient = createInvalidationClient({ queryStore });
|
|
1533
1610
|
const cacheClient = createCacheClient({ queryStore });
|
|
1534
1611
|
const refetchClient = createRefetchClient();
|
|
1612
|
+
const mutationClient = new MutationClient();
|
|
1535
1613
|
let hasCalledStart = false;
|
|
1536
1614
|
const query = ({
|
|
1537
1615
|
key,
|
|
@@ -1608,7 +1686,7 @@ const createClient = () => {
|
|
|
1608
1686
|
trigger$
|
|
1609
1687
|
})
|
|
1610
1688
|
),
|
|
1611
|
-
mergeResults,
|
|
1689
|
+
mergeResults$1,
|
|
1612
1690
|
withLatestFrom(options$),
|
|
1613
1691
|
takeWhile(([result, options]) => {
|
|
1614
1692
|
const shouldStop = result.data !== void 0 && options.terminateOnFirstResult;
|
|
@@ -1657,6 +1735,7 @@ const createClient = () => {
|
|
|
1657
1735
|
start,
|
|
1658
1736
|
query,
|
|
1659
1737
|
queryStore,
|
|
1738
|
+
...mutationClient,
|
|
1660
1739
|
...invalidationClient,
|
|
1661
1740
|
...cacheClient,
|
|
1662
1741
|
...refetchClient
|
|
@@ -1670,7 +1749,7 @@ class QueryClient {
|
|
|
1670
1749
|
}
|
|
1671
1750
|
export {
|
|
1672
1751
|
QueryClient,
|
|
1673
|
-
|
|
1752
|
+
QueryClientProvider,
|
|
1674
1753
|
SIGNAL_RESET,
|
|
1675
1754
|
createClient,
|
|
1676
1755
|
createLocalforageAdapter,
|
|
@@ -1680,9 +1759,9 @@ export {
|
|
|
1680
1759
|
retryBackoff,
|
|
1681
1760
|
signal,
|
|
1682
1761
|
trigger,
|
|
1683
|
-
useAsyncQuery,
|
|
1684
1762
|
useBehaviorSubject,
|
|
1685
1763
|
useLiveRef,
|
|
1764
|
+
useMutation,
|
|
1686
1765
|
useObserve,
|
|
1687
1766
|
useObserveCallback,
|
|
1688
1767
|
usePersistSignals,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Observable, BehaviorSubject } from "rxjs";
|
|
1
|
+
import { type Observable, Subject, BehaviorSubject } from "rxjs";
|
|
2
2
|
import { type QueryOptions, type QueryFn, type QueryTrigger, type QueryResult } from "./types";
|
|
3
3
|
import { type QueryKey } from "./keys/types";
|
|
4
4
|
export declare const createClient: () => {
|
|
@@ -38,15 +38,22 @@ export declare const createClient: () => {
|
|
|
38
38
|
exact?: boolean | undefined;
|
|
39
39
|
predicate?: ((storeObject: import("./store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
|
|
40
40
|
}) => void;
|
|
41
|
+
createMutation: <T_4, MutationArg>(options$: Observable<import("./mutations/types").MutationOptions<T_4, MutationArg>>) => {
|
|
42
|
+
mutation$: Observable<import("./mutations/types").MutationResult<T_4>>;
|
|
43
|
+
trigger$: Subject<MutationArg>;
|
|
44
|
+
reset$: Subject<void>;
|
|
45
|
+
destroy: () => void;
|
|
46
|
+
getClosed: () => boolean;
|
|
47
|
+
};
|
|
41
48
|
start: () => () => void;
|
|
42
|
-
query: <
|
|
49
|
+
query: <T_5>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
|
|
43
50
|
key: QueryKey;
|
|
44
|
-
fn?: QueryFn<
|
|
45
|
-
fn$?: Observable<QueryFn<
|
|
51
|
+
fn?: QueryFn<T_5> | undefined;
|
|
52
|
+
fn$?: Observable<QueryFn<T_5>> | undefined;
|
|
46
53
|
trigger$?: Observable<QueryTrigger> | undefined;
|
|
47
|
-
options$?: Observable<QueryOptions<
|
|
54
|
+
options$?: Observable<QueryOptions<T_5>> | undefined;
|
|
48
55
|
}) => {
|
|
49
|
-
result$: Observable<QueryResult<
|
|
56
|
+
result$: Observable<QueryResult<T_5>>;
|
|
50
57
|
};
|
|
51
58
|
queryStore: {
|
|
52
59
|
set: (key: string, value: import("./store/createQueryStore").StoreObject<unknown>) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Observable, Subject } from "rxjs";
|
|
2
|
+
import { type MutationResult, type MutationOptions } from "./types";
|
|
3
|
+
export declare class MutationClient {
|
|
4
|
+
createMutation: <T, MutationArg>(options$: Observable<MutationOptions<T, MutationArg>>) => {
|
|
5
|
+
mutation$: Observable<MutationResult<T>>;
|
|
6
|
+
trigger$: Subject<MutationArg>;
|
|
7
|
+
reset$: Subject<void>;
|
|
8
|
+
destroy: () => void;
|
|
9
|
+
getClosed: () => boolean;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type MonoTypeOperatorFunction, type Observable } from "rxjs";
|
|
2
|
+
import { type Query, type QueryResult } from "../types";
|
|
3
|
+
import { type QueryKey } from "../keys/types";
|
|
4
|
+
/**
|
|
5
|
+
* The default value `merge` is suitable for most use case.
|
|
6
|
+
* You should not have to worry too much about it and only consider changing
|
|
7
|
+
* it when specific need arise.
|
|
8
|
+
*
|
|
9
|
+
* `merge`:
|
|
10
|
+
* Run each async query as they are triggered without any cancellation or queue system.
|
|
11
|
+
* The result is always from the latest async query triggered, not necessarily
|
|
12
|
+
* the latest one running.
|
|
13
|
+
*
|
|
14
|
+
* `concat`:
|
|
15
|
+
* Unlike merge, it will trigger each async query sequentially following
|
|
16
|
+
* a queue system. The result is not necessarily the last triggered async query
|
|
17
|
+
* but the current running async query.
|
|
18
|
+
*
|
|
19
|
+
* `switch`:
|
|
20
|
+
* Only run the latest async query triggered and cancel any previously running one.
|
|
21
|
+
* Result correspond to the current running async query.
|
|
22
|
+
*/
|
|
23
|
+
export type MapOperator = "switch" | "concat" | "merge";
|
|
24
|
+
export interface MutationResult<R> {
|
|
25
|
+
data: R | undefined;
|
|
26
|
+
status: "idle" | "loading" | "error" | "success";
|
|
27
|
+
error: unknown;
|
|
28
|
+
}
|
|
29
|
+
export type MutationFn<T, MutationArg> = ((arg: MutationArg) => Promise<T>) | ((arg: MutationArg) => Observable<T>);
|
|
30
|
+
export interface MutationOptions<Result, MutationArg> {
|
|
31
|
+
enabled?: boolean;
|
|
32
|
+
retry?: false | number | ((attempt: number, error: unknown) => boolean);
|
|
33
|
+
/**
|
|
34
|
+
* @important
|
|
35
|
+
* The hook with the lowest value will be taken into account
|
|
36
|
+
*/
|
|
37
|
+
staleTime?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Force the new query to be marked as stale. Only on first trigger
|
|
40
|
+
*/
|
|
41
|
+
markStale?: boolean;
|
|
42
|
+
cacheTime?: number;
|
|
43
|
+
/**
|
|
44
|
+
* @important
|
|
45
|
+
* interval is paused until the query finish fetching. This avoid infinite
|
|
46
|
+
* loop of refetch
|
|
47
|
+
*/
|
|
48
|
+
refetchInterval?: number | false | ((data: QueryResult<Result>["data"] | undefined, query: Query) => number | false);
|
|
49
|
+
terminateOnFirstResult?: boolean;
|
|
50
|
+
onError?: (error: unknown, arg: MutationArg) => void;
|
|
51
|
+
onSuccess?: (data: Result, arg: MutationArg) => void;
|
|
52
|
+
mutationFn: MutationFn<Result, MutationArg>;
|
|
53
|
+
mutationKey: QueryKey;
|
|
54
|
+
mapOperator?: MapOperator;
|
|
55
|
+
__queryInitHook?: MonoTypeOperatorFunction<any>;
|
|
56
|
+
__queryRunnerHook?: MonoTypeOperatorFunction<any>;
|
|
57
|
+
__queryTriggerHook?: MonoTypeOperatorFunction<Partial<Result>>;
|
|
58
|
+
}
|
|
@@ -3,7 +3,7 @@ import { type QueryClient, type createClient } from "../client/createClient";
|
|
|
3
3
|
export declare const Context: import("react").Context<{
|
|
4
4
|
client: ReturnType<typeof createClient>;
|
|
5
5
|
}>;
|
|
6
|
-
export declare const
|
|
6
|
+
export declare const QueryClientProvider: import("react").MemoExoticComponent<({ children, client }: {
|
|
7
7
|
children: ReactNode;
|
|
8
8
|
client: QueryClient;
|
|
9
9
|
}) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -44,15 +44,22 @@ export declare const useQueryClient: () => {
|
|
|
44
44
|
exact?: boolean | undefined;
|
|
45
45
|
predicate?: ((storeObject: import("../client/store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
|
|
46
46
|
}) => void;
|
|
47
|
+
createMutation: <T_4, MutationArg>(options$: import("rxjs").Observable<import("../client/mutations/types").MutationOptions<T_4, MutationArg>>) => {
|
|
48
|
+
mutation$: import("rxjs").Observable<import("../client/mutations/types").MutationResult<T_4>>;
|
|
49
|
+
trigger$: import("rxjs").Subject<MutationArg>;
|
|
50
|
+
reset$: import("rxjs").Subject<void>;
|
|
51
|
+
destroy: () => void;
|
|
52
|
+
getClosed: () => boolean;
|
|
53
|
+
};
|
|
47
54
|
start: () => () => void;
|
|
48
|
-
query: <
|
|
55
|
+
query: <T_5>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
|
|
49
56
|
key: import("../client/keys/types").QueryKey;
|
|
50
|
-
fn?: import("../client/types").QueryFn<
|
|
51
|
-
fn$?: import("rxjs").Observable<import("../client/types").QueryFn<
|
|
57
|
+
fn?: import("../client/types").QueryFn<T_5> | undefined;
|
|
58
|
+
fn$?: import("rxjs").Observable<import("../client/types").QueryFn<T_5>> | undefined;
|
|
52
59
|
trigger$?: import("rxjs").Observable<import("../client/types").QueryTrigger> | undefined;
|
|
53
|
-
options$?: import("rxjs").Observable<import("../client/types").QueryOptions<
|
|
60
|
+
options$?: import("rxjs").Observable<import("../client/types").QueryOptions<T_5>> | undefined;
|
|
54
61
|
}) => {
|
|
55
|
-
result$: import("rxjs").Observable<import("../client/types").QueryResult<
|
|
62
|
+
result$: import("rxjs").Observable<import("../client/types").QueryResult<T_5>>;
|
|
56
63
|
};
|
|
57
64
|
queryStore: {
|
|
58
65
|
set: (key: string, value: import("../client/store/createQueryStore").StoreObject<unknown>) => void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type MonoTypeOperatorFunction } from "rxjs";
|
|
2
|
+
import { type MutationOptions } from "../../client/mutations/types";
|
|
3
|
+
import { type QueryKey } from "../../client/keys/types";
|
|
4
|
+
export type AsyncQueryOptions<Result, Params> = Omit<MutationOptions<Result, Params>, "mutationKey"> & {
|
|
5
|
+
mutationKey?: QueryKey;
|
|
6
|
+
/**
|
|
7
|
+
* When true, any running async query will be cancelled (when possible) on unmount.
|
|
8
|
+
* You need to handle it yourself for promises if needed.
|
|
9
|
+
* Callbacks will not be called as a result.
|
|
10
|
+
*
|
|
11
|
+
* This is unlikely to be needed but in some situation you may want to cancel
|
|
12
|
+
* any ongoing process if the user navigate away for example.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
cancelOnUnMount?: boolean;
|
|
17
|
+
__triggerHook?: MonoTypeOperatorFunction<unknown>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* @important
|
|
21
|
+
* Your async query function is cancelled whenever you call a new mutate or
|
|
22
|
+
* when the component is unmounted. Same behavior will happens with your
|
|
23
|
+
* callback functions regarding unmounting. None of them will be called.
|
|
24
|
+
*
|
|
25
|
+
* If you provide an observable as a return it will be automatically cancelled
|
|
26
|
+
* as well during unmount or if called again. If you provide anything else you
|
|
27
|
+
* are in charge of controlling the flow.
|
|
28
|
+
*
|
|
29
|
+
* If you need to execute async query independently of the component lifecycle or
|
|
30
|
+
* execute functions in parallel you should not use this hook.
|
|
31
|
+
*
|
|
32
|
+
* @important
|
|
33
|
+
* If you return an observable, the stream will be unsubscribed after receiving
|
|
34
|
+
* the first value. This hook is not meant to be running long running effects.
|
|
35
|
+
*
|
|
36
|
+
* @todo keep async query running on unmount
|
|
37
|
+
* callback should return unmount$ variables
|
|
38
|
+
* options.cancelOnUnmount should be false by default
|
|
39
|
+
*/
|
|
40
|
+
export declare function useMutation<Args = void, R = undefined>(options: AsyncQueryOptions<R, Args>): {
|
|
41
|
+
data: R | undefined;
|
|
42
|
+
status: "error" | "idle" | "loading" | "success";
|
|
43
|
+
error: unknown;
|
|
44
|
+
mutate: (mutationArgs: Args) => void;
|
|
45
|
+
reset: () => void;
|
|
46
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactjrx",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.55.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"rxjs": "*"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
+
"@testing-library/react": "^14.0.0",
|
|
41
|
+
"@types/node": "^18.15.11",
|
|
40
42
|
"@types/react": "^18.0.28",
|
|
41
43
|
"@types/react-dom": "^18.0.11",
|
|
42
44
|
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
|
@@ -57,12 +59,13 @@
|
|
|
57
59
|
"typescript": "^5.0.4",
|
|
58
60
|
"vite": "^4.2.1",
|
|
59
61
|
"vite-plugin-dts": "^3.6.3",
|
|
60
|
-
"vitest": "^0.34.6"
|
|
61
|
-
"@testing-library/react": "^14.0.0",
|
|
62
|
-
"@types/node": "^18.15.11"
|
|
62
|
+
"vitest": "^0.34.6"
|
|
63
63
|
},
|
|
64
64
|
"repository": {
|
|
65
65
|
"type": "git",
|
|
66
66
|
"url": "https://github.com/mbret/reactjrx.git"
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"@tanstack/react-query": "^5.8.4"
|
|
67
70
|
}
|
|
68
71
|
}
|
|
@@ -1,82 +0,0 @@
|
|
|
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
|
-
}
|
|
7
|
-
export interface AsyncQueryOptions<Result, Params> {
|
|
8
|
-
retry?: false | number | ((attempt: number, error: unknown) => boolean);
|
|
9
|
-
/**
|
|
10
|
-
* Called for every async query on error.
|
|
11
|
-
* `merge` mapping will run callback as they happen.
|
|
12
|
-
* Use `concat` if you need to run callbacks in order of calling.
|
|
13
|
-
*/
|
|
14
|
-
onError?: (error: unknown, params: Params) => void;
|
|
15
|
-
/**
|
|
16
|
-
* Called for every async query on success.
|
|
17
|
-
* `merge` mapping will run callback as they happen.
|
|
18
|
-
* Use `concat` if you need to run callbacks in order of calling.
|
|
19
|
-
*/
|
|
20
|
-
onSuccess?: (data: Result, params: Params) => void;
|
|
21
|
-
/**
|
|
22
|
-
* When true, any running async query will be cancelled (when possible) on unmount.
|
|
23
|
-
* You need to handle it yourself for promises if needed.
|
|
24
|
-
* Callbacks will not be called as a result.
|
|
25
|
-
*
|
|
26
|
-
* This is unlikely to be needed but in some situation you may want to cancel
|
|
27
|
-
* any ongoing process if the user navigate away for example.
|
|
28
|
-
*
|
|
29
|
-
* @default false
|
|
30
|
-
*/
|
|
31
|
-
cancelOnUnMount?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Only use for debugging.
|
|
34
|
-
* It is not the main subscription hook, only the one following the trigger.
|
|
35
|
-
*/
|
|
36
|
-
triggerHook?: MonoTypeOperatorFunction<Partial<QueryState<Result>> | undefined>;
|
|
37
|
-
}
|
|
38
|
-
interface Result<A, R> {
|
|
39
|
-
status: "idle" | "loading" | "error" | "success";
|
|
40
|
-
isLoading: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* If the latest async query is in a success state, data contains its result.
|
|
43
|
-
*
|
|
44
|
-
* @important
|
|
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
|
-
*/
|
|
48
|
-
data: R | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* If the latest async query is in a error state, error contains its error.
|
|
51
|
-
*
|
|
52
|
-
* @important
|
|
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
|
-
*/
|
|
56
|
-
error: unknown | undefined;
|
|
57
|
-
mutate: (args: A) => void;
|
|
58
|
-
reset: () => void;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* The default value `merge` is suitable for most use case.
|
|
62
|
-
* You should not have to worry too much about it and only consider changing
|
|
63
|
-
* it when specific need arise.
|
|
64
|
-
*
|
|
65
|
-
* `merge`:
|
|
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
|
-
* the latest one running.
|
|
69
|
-
*
|
|
70
|
-
* `concat`:
|
|
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
|
-
*
|
|
75
|
-
* `switch`:
|
|
76
|
-
* Only run the latest async query triggered and cancel any previously running one.
|
|
77
|
-
* Result correspond to the current running async query.
|
|
78
|
-
*/
|
|
79
|
-
type MapOperator = "switch" | "concat" | "merge";
|
|
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
|
-
export {};
|
|
File without changes
|