reactjrx 1.55.0 → 1.57.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 +281 -175
- package/dist/index.js +283 -177
- package/dist/lib/queries/client/createClient.d.ts +9 -13
- package/dist/lib/queries/client/mutations/MutationClient.d.ts +51 -5
- package/dist/lib/queries/client/mutations/createMutationRunner.d.ts +13 -0
- package/dist/lib/queries/client/mutations/types.d.ts +10 -3
- package/dist/lib/queries/react/Provider.d.ts +7 -12
- package/dist/lib/queries/react/keys/nanoid.d.ts +1 -0
- package/dist/lib/queries/{client → react}/keys/serializeKey.d.ts +1 -1
- package/dist/lib/queries/react/mutations/useMutation.d.ts +6 -34
- package/dist/lib/queries/react/mutations/useMutation.keys.test.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -428,67 +428,69 @@ const useQueryClient = () => {
|
|
|
428
428
|
}
|
|
429
429
|
return context.client;
|
|
430
430
|
};
|
|
431
|
+
const serializeObject = (object) => {
|
|
432
|
+
if (Array.isArray(object)) {
|
|
433
|
+
return object.reduce((acc, value, index) => {
|
|
434
|
+
if (index === object.length - 1)
|
|
435
|
+
return `${acc}${serializeObject(value)}]`;
|
|
436
|
+
return `${acc}${serializeObject(value)},`;
|
|
437
|
+
}, "[");
|
|
438
|
+
}
|
|
439
|
+
if (object === void 0)
|
|
440
|
+
return "";
|
|
441
|
+
return JSON.stringify(object, Object.keys(object).sort());
|
|
442
|
+
};
|
|
443
|
+
const serializeKey = (key) => {
|
|
444
|
+
if (key.length === 0)
|
|
445
|
+
return "[]";
|
|
446
|
+
return serializeObject(key);
|
|
447
|
+
};
|
|
448
|
+
const nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
|
|
449
|
+
byte &= 63;
|
|
450
|
+
if (byte < 36) {
|
|
451
|
+
id += byte.toString(36);
|
|
452
|
+
} else if (byte < 62) {
|
|
453
|
+
id += (byte - 26).toString(36).toUpperCase();
|
|
454
|
+
} else if (byte > 62) {
|
|
455
|
+
id += "-";
|
|
456
|
+
} else {
|
|
457
|
+
id += "_";
|
|
458
|
+
}
|
|
459
|
+
return id;
|
|
460
|
+
}, "");
|
|
431
461
|
function useMutation(options) {
|
|
432
462
|
const client = useQueryClient();
|
|
433
463
|
const optionsRef = useLiveRef(options);
|
|
434
|
-
const
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
() => client.
|
|
438
|
-
|
|
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$]
|
|
464
|
+
const defaultKey = useConstant(() => [nanoid()]);
|
|
465
|
+
const key = serializeKey(options.mutationKey ?? defaultKey.current);
|
|
466
|
+
const observedMutation = react.useMemo(
|
|
467
|
+
() => client.mutationClient.observe({ key }),
|
|
468
|
+
[key]
|
|
472
469
|
);
|
|
470
|
+
const result = useObserve(observedMutation.result$) ?? observedMutation.lastValue;
|
|
473
471
|
const mutate = react.useCallback(
|
|
474
472
|
(mutationArgs) => {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
473
|
+
client.mutationClient.mutate({
|
|
474
|
+
options: { ...optionsRef.current, mutationKey: key },
|
|
475
|
+
args: mutationArgs
|
|
476
|
+
});
|
|
479
477
|
},
|
|
480
|
-
[
|
|
478
|
+
[client, key]
|
|
481
479
|
);
|
|
482
|
-
react.useEffect(() => {
|
|
483
|
-
if (mutation && !mutation.getClosed()) {
|
|
484
|
-
bufferTriggers.forEach((args) => {
|
|
485
|
-
mutation.trigger$.next(args);
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}, [bufferTriggers, mutation]);
|
|
489
480
|
const reset = react.useCallback(() => {
|
|
490
|
-
reset
|
|
491
|
-
|
|
481
|
+
client.mutationClient.reset({
|
|
482
|
+
key: optionsRef.current.mutationKey ?? defaultKey.current
|
|
483
|
+
});
|
|
484
|
+
}, [client]);
|
|
485
|
+
react.useEffect(() => {
|
|
486
|
+
return () => {
|
|
487
|
+
if (optionsRef.current.cancelOnUnMount) {
|
|
488
|
+
client.mutationClient.reset({
|
|
489
|
+
key: optionsRef.current.mutationKey ?? defaultKey.current
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
}, []);
|
|
492
494
|
return { mutate, reset, ...result };
|
|
493
495
|
}
|
|
494
496
|
const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
@@ -681,23 +683,6 @@ function useSubscribeEffect(source, unsafeOptions, deps = []) {
|
|
|
681
683
|
);
|
|
682
684
|
useSubscribe(enhancerMakeObservable, deps);
|
|
683
685
|
}
|
|
684
|
-
const serializeObject = (object) => {
|
|
685
|
-
if (Array.isArray(object)) {
|
|
686
|
-
return object.reduce((acc, value, index) => {
|
|
687
|
-
if (index === object.length - 1)
|
|
688
|
-
return `${acc}${serializeObject(value)}]`;
|
|
689
|
-
return `${acc}${serializeObject(value)},`;
|
|
690
|
-
}, "[");
|
|
691
|
-
}
|
|
692
|
-
if (object === void 0)
|
|
693
|
-
return "";
|
|
694
|
-
return JSON.stringify(object, Object.keys(object).sort());
|
|
695
|
-
};
|
|
696
|
-
const serializeKey = (key) => {
|
|
697
|
-
if (key.length === 0)
|
|
698
|
-
return "[]";
|
|
699
|
-
return serializeObject(key);
|
|
700
|
-
};
|
|
701
686
|
const retryOnError = (options) => retryBackoff({
|
|
702
687
|
initialInterval: 100,
|
|
703
688
|
...typeof options.retry === "function" ? {
|
|
@@ -1490,120 +1475,237 @@ const mergeResults = (stream$) => stream$.pipe(
|
|
|
1490
1475
|
{
|
|
1491
1476
|
data: void 0,
|
|
1492
1477
|
error: void 0,
|
|
1493
|
-
|
|
1494
|
-
status: "loading"
|
|
1478
|
+
status: "pending"
|
|
1495
1479
|
}
|
|
1496
1480
|
),
|
|
1497
1481
|
rxjs.distinctUntilChanged(
|
|
1498
1482
|
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1499
1483
|
)
|
|
1500
1484
|
);
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1485
|
+
const createMutationRunner = ({
|
|
1486
|
+
__queryFinalizeHook,
|
|
1487
|
+
__queryInitHook,
|
|
1488
|
+
__queryTriggerHook
|
|
1489
|
+
}) => {
|
|
1490
|
+
const trigger$ = new rxjs.Subject();
|
|
1491
|
+
const reset$ = new rxjs.Subject();
|
|
1492
|
+
let closed = false;
|
|
1493
|
+
const mapOperator$ = new rxjs.BehaviorSubject("merge");
|
|
1494
|
+
const mutationsRunning$ = new rxjs.BehaviorSubject(0);
|
|
1495
|
+
const destroy = () => {
|
|
1496
|
+
if (closed) {
|
|
1497
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1498
|
+
}
|
|
1499
|
+
closed = true;
|
|
1500
|
+
mapOperator$.complete();
|
|
1501
|
+
mutationsRunning$.complete();
|
|
1502
|
+
trigger$.complete();
|
|
1503
|
+
reset$.complete();
|
|
1504
|
+
};
|
|
1505
|
+
const stableMapOperator$ = mapOperator$.pipe(
|
|
1506
|
+
rxjs.filter(isDefined),
|
|
1507
|
+
rxjs.distinctUntilChanged()
|
|
1508
|
+
);
|
|
1509
|
+
const mutation$ = stableMapOperator$.pipe(
|
|
1510
|
+
__queryInitHook ?? rxjs.identity,
|
|
1511
|
+
rxjs.mergeMap((mapOperator) => {
|
|
1512
|
+
const switchOperator = mapOperator === "concat" ? rxjs.concatMap : mapOperator === "switch" ? rxjs.switchMap : rxjs.mergeMap;
|
|
1513
|
+
return trigger$.pipe(
|
|
1514
|
+
rxjs.takeUntil(stableMapOperator$.pipe(rxjs.skip(1))),
|
|
1515
|
+
rxjs.tap(() => {
|
|
1516
|
+
mutationsRunning$.next(mutationsRunning$.getValue() + 1);
|
|
1519
1517
|
}),
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
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);
|
|
1518
|
+
switchOperator(({ args, options }) => {
|
|
1519
|
+
const queryRunner$ = rxjs.defer(() => rxjs.from(options.mutationFn(args))).pipe(
|
|
1520
|
+
retryOnError(options),
|
|
1521
|
+
rxjs.take(1),
|
|
1522
|
+
rxjs.map((data) => ({ data, isError: false })),
|
|
1523
|
+
rxjs.catchError((error) => {
|
|
1524
|
+
console.error(error);
|
|
1525
|
+
if (options.onError != null) {
|
|
1526
|
+
options.onError(error, args);
|
|
1527
|
+
}
|
|
1528
|
+
return rxjs.of({ data: error, isError: true });
|
|
1588
1529
|
}),
|
|
1589
|
-
|
|
1590
|
-
|
|
1530
|
+
rxjs.share()
|
|
1531
|
+
);
|
|
1532
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1533
|
+
rxjs.map(({ data, isError }) => isError || data)
|
|
1534
|
+
);
|
|
1535
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1536
|
+
rxjs.take(1),
|
|
1537
|
+
rxjs.map(() => mapOperator === "concat"),
|
|
1538
|
+
rxjs.startWith(true),
|
|
1539
|
+
rxjs.takeUntil(queryIsOver$)
|
|
1540
|
+
);
|
|
1541
|
+
const loading$ = rxjs.of({
|
|
1542
|
+
status: "pending"
|
|
1543
|
+
});
|
|
1544
|
+
return rxjs.merge(
|
|
1545
|
+
loading$,
|
|
1546
|
+
rxjs.combineLatest([
|
|
1547
|
+
queryRunner$,
|
|
1548
|
+
isThisCurrentFunctionLastOneCalled
|
|
1549
|
+
]).pipe(
|
|
1550
|
+
rxjs.map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1551
|
+
if (!isError) {
|
|
1552
|
+
if (options.onSuccess != null)
|
|
1553
|
+
options.onSuccess(data, args);
|
|
1554
|
+
}
|
|
1555
|
+
if (isLastMutationCalled) {
|
|
1556
|
+
return isError ? {
|
|
1557
|
+
status: "error",
|
|
1558
|
+
error: data,
|
|
1559
|
+
data: void 0
|
|
1560
|
+
} : {
|
|
1561
|
+
status: "success",
|
|
1562
|
+
error: void 0,
|
|
1563
|
+
data
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
return {};
|
|
1567
|
+
}),
|
|
1568
|
+
rxjs.takeUntil(reset$)
|
|
1569
|
+
)
|
|
1570
|
+
).pipe(
|
|
1571
|
+
options.__queryRunnerHook ?? rxjs.identity,
|
|
1572
|
+
rxjs.finalize(() => {
|
|
1573
|
+
mutationsRunning$.next(mutationsRunning$.getValue() - 1);
|
|
1574
|
+
})
|
|
1591
1575
|
);
|
|
1592
1576
|
}),
|
|
1593
|
-
rxjs.
|
|
1594
|
-
|
|
1595
|
-
destroy();
|
|
1596
|
-
}
|
|
1597
|
-
})
|
|
1577
|
+
__queryTriggerHook ?? rxjs.identity,
|
|
1578
|
+
mergeResults
|
|
1598
1579
|
);
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1580
|
+
}),
|
|
1581
|
+
__queryFinalizeHook ?? rxjs.identity
|
|
1582
|
+
);
|
|
1583
|
+
return {
|
|
1584
|
+
mutation$,
|
|
1585
|
+
trigger: ({
|
|
1586
|
+
args,
|
|
1587
|
+
options
|
|
1588
|
+
}) => {
|
|
1589
|
+
mapOperator$.next(options.mapOperator);
|
|
1590
|
+
trigger$.next({ args, options });
|
|
1591
|
+
},
|
|
1592
|
+
reset$,
|
|
1593
|
+
destroy,
|
|
1594
|
+
mutationsRunning$,
|
|
1595
|
+
getClosed: () => closed
|
|
1596
|
+
};
|
|
1597
|
+
};
|
|
1598
|
+
class MutationClient {
|
|
1599
|
+
constructor() {
|
|
1600
|
+
/**
|
|
1601
|
+
* Contain all active mutation for a given key.
|
|
1602
|
+
* A mutation ca have several triggers running (it is not necessarily one function running)
|
|
1603
|
+
*
|
|
1604
|
+
* @important
|
|
1605
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1606
|
+
*/
|
|
1607
|
+
__publicField(this, "mutationRunners$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1608
|
+
/**
|
|
1609
|
+
* Mutation result subject. It can be used whether there is a mutation
|
|
1610
|
+
* running or not and can be directly observed.
|
|
1611
|
+
*
|
|
1612
|
+
* @important
|
|
1613
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1614
|
+
*/
|
|
1615
|
+
__publicField(this, "mutationResults$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1616
|
+
__publicField(this, "mutate$", new rxjs.Subject());
|
|
1617
|
+
__publicField(this, "reset$", new rxjs.Subject());
|
|
1618
|
+
this.mutate$.pipe(
|
|
1619
|
+
rxjs.tap(({ options, args }) => {
|
|
1620
|
+
const { mutationKey } = options;
|
|
1621
|
+
let mutationForKey = this.mutationRunners$.getValue().get(mutationKey);
|
|
1622
|
+
if (!mutationForKey) {
|
|
1623
|
+
mutationForKey = createMutationRunner(options);
|
|
1624
|
+
this.mutationRunners$.getValue().set(mutationKey, mutationForKey);
|
|
1625
|
+
mutationForKey.mutation$.subscribe((result) => {
|
|
1626
|
+
let resultForKeySubject = this.mutationResults$.getValue().get(mutationKey);
|
|
1627
|
+
if (!resultForKeySubject) {
|
|
1628
|
+
resultForKeySubject = new rxjs.BehaviorSubject(result);
|
|
1629
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1630
|
+
resultMap.set(mutationKey, resultForKeySubject);
|
|
1631
|
+
this.mutationResults$.next(resultMap);
|
|
1632
|
+
} else {
|
|
1633
|
+
resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
|
|
1634
|
+
}
|
|
1635
|
+
});
|
|
1636
|
+
mutationForKey.mutationsRunning$.pipe(
|
|
1637
|
+
rxjs.skip(1),
|
|
1638
|
+
rxjs.filter((number) => number === 0)
|
|
1639
|
+
).subscribe(() => {
|
|
1640
|
+
mutationForKey == null ? void 0 : mutationForKey.destroy();
|
|
1641
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1642
|
+
resultMap.delete(mutationKey);
|
|
1643
|
+
this.mutationResults$.next(resultMap);
|
|
1644
|
+
const mutationsMap = this.mutationRunners$.getValue();
|
|
1645
|
+
mutationsMap.delete(mutationKey);
|
|
1646
|
+
this.mutationRunners$.next(mutationsMap);
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
mutationForKey.trigger({ args, options });
|
|
1650
|
+
})
|
|
1651
|
+
).subscribe();
|
|
1652
|
+
this.reset$.pipe(
|
|
1653
|
+
rxjs.tap(({ key }) => {
|
|
1654
|
+
var _a;
|
|
1655
|
+
const serializedKey = serializeKey(key);
|
|
1656
|
+
(_a = this.mutationRunners$.getValue().get(serializedKey)) == null ? void 0 : _a.reset$.next();
|
|
1657
|
+
})
|
|
1658
|
+
).subscribe();
|
|
1659
|
+
}
|
|
1660
|
+
observe({ key }) {
|
|
1661
|
+
var _a;
|
|
1662
|
+
const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
|
|
1663
|
+
const mapResultToObservedResult = (value) => ({
|
|
1664
|
+
...value,
|
|
1665
|
+
isIdle: value.status === "idle",
|
|
1666
|
+
isPaused: false,
|
|
1667
|
+
isError: value.error !== void 0,
|
|
1668
|
+
isPending: false,
|
|
1669
|
+
isSuccess: value.status === "success"
|
|
1606
1670
|
});
|
|
1671
|
+
const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
|
|
1672
|
+
data: void 0,
|
|
1673
|
+
error: void 0,
|
|
1674
|
+
status: "idle"
|
|
1675
|
+
});
|
|
1676
|
+
const result$ = this.mutationResults$.pipe(
|
|
1677
|
+
rxjs.switchMap((resultMap) => {
|
|
1678
|
+
const subject = resultMap.get(key);
|
|
1679
|
+
return subject ?? rxjs.EMPTY;
|
|
1680
|
+
})
|
|
1681
|
+
).pipe(
|
|
1682
|
+
rxjs.filter(isDefined),
|
|
1683
|
+
rxjs.map((value) => ({
|
|
1684
|
+
...value,
|
|
1685
|
+
isIdle: value.status === "idle",
|
|
1686
|
+
isPaused: false,
|
|
1687
|
+
isError: value.error !== void 0,
|
|
1688
|
+
isPending: false,
|
|
1689
|
+
isSuccess: value.status === "success"
|
|
1690
|
+
}))
|
|
1691
|
+
);
|
|
1692
|
+
return { result$, lastValue };
|
|
1693
|
+
}
|
|
1694
|
+
mutate(params) {
|
|
1695
|
+
this.mutate$.next(params);
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* This will reset any current mutation runnings.
|
|
1699
|
+
* No discrimination process
|
|
1700
|
+
*/
|
|
1701
|
+
reset(params) {
|
|
1702
|
+
this.reset$.next(params);
|
|
1703
|
+
}
|
|
1704
|
+
destroy() {
|
|
1705
|
+
this.reset$.complete();
|
|
1706
|
+
this.mutate$.complete();
|
|
1707
|
+
this.mutationResults$.complete();
|
|
1708
|
+
this.mutationRunners$.complete();
|
|
1607
1709
|
}
|
|
1608
1710
|
}
|
|
1609
1711
|
const createClient = () => {
|
|
@@ -1727,20 +1829,24 @@ const createClient = () => {
|
|
|
1727
1829
|
const queryListenerSub = queryListener$.subscribe();
|
|
1728
1830
|
const started = [queryStore.start()];
|
|
1729
1831
|
return () => {
|
|
1730
|
-
started.forEach((
|
|
1731
|
-
|
|
1832
|
+
started.forEach((destroy2) => {
|
|
1833
|
+
destroy2();
|
|
1732
1834
|
});
|
|
1733
1835
|
queryListenerSub.unsubscribe();
|
|
1734
1836
|
};
|
|
1735
1837
|
};
|
|
1838
|
+
const destroy = () => {
|
|
1839
|
+
mutationClient.destroy();
|
|
1840
|
+
};
|
|
1736
1841
|
return {
|
|
1737
1842
|
start,
|
|
1738
1843
|
query,
|
|
1739
1844
|
queryStore,
|
|
1740
|
-
|
|
1845
|
+
mutationClient,
|
|
1741
1846
|
...invalidationClient,
|
|
1742
1847
|
...cacheClient,
|
|
1743
|
-
...refetchClient
|
|
1848
|
+
...refetchClient,
|
|
1849
|
+
destroy
|
|
1744
1850
|
};
|
|
1745
1851
|
};
|
|
1746
1852
|
class QueryClient {
|
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
|
|
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 } from "react";
|
|
8
|
+
import { distinctUntilChanged, tap, finalize, catchError, EMPTY, Subject, identity, BehaviorSubject, map, of, zip, merge, throttleTime, asyncScheduler, switchMap, from, defer, iif, timer, throwError, fromEvent, filter, skip, withLatestFrom, scan, retry, shareReplay, endWith, delay, take, takeUntil, share, startWith, pairwise, mergeMap, NEVER, 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) => {
|
|
@@ -426,67 +426,69 @@ const useQueryClient = () => {
|
|
|
426
426
|
}
|
|
427
427
|
return context.client;
|
|
428
428
|
};
|
|
429
|
+
const serializeObject = (object) => {
|
|
430
|
+
if (Array.isArray(object)) {
|
|
431
|
+
return object.reduce((acc, value, index) => {
|
|
432
|
+
if (index === object.length - 1)
|
|
433
|
+
return `${acc}${serializeObject(value)}]`;
|
|
434
|
+
return `${acc}${serializeObject(value)},`;
|
|
435
|
+
}, "[");
|
|
436
|
+
}
|
|
437
|
+
if (object === void 0)
|
|
438
|
+
return "";
|
|
439
|
+
return JSON.stringify(object, Object.keys(object).sort());
|
|
440
|
+
};
|
|
441
|
+
const serializeKey = (key) => {
|
|
442
|
+
if (key.length === 0)
|
|
443
|
+
return "[]";
|
|
444
|
+
return serializeObject(key);
|
|
445
|
+
};
|
|
446
|
+
const nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
|
|
447
|
+
byte &= 63;
|
|
448
|
+
if (byte < 36) {
|
|
449
|
+
id += byte.toString(36);
|
|
450
|
+
} else if (byte < 62) {
|
|
451
|
+
id += (byte - 26).toString(36).toUpperCase();
|
|
452
|
+
} else if (byte > 62) {
|
|
453
|
+
id += "-";
|
|
454
|
+
} else {
|
|
455
|
+
id += "_";
|
|
456
|
+
}
|
|
457
|
+
return id;
|
|
458
|
+
}, "");
|
|
429
459
|
function useMutation(options) {
|
|
430
460
|
const client = useQueryClient();
|
|
431
461
|
const optionsRef = useLiveRef(options);
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
const
|
|
435
|
-
() => client.
|
|
436
|
-
|
|
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$]
|
|
462
|
+
const defaultKey = useConstant(() => [nanoid()]);
|
|
463
|
+
const key = serializeKey(options.mutationKey ?? defaultKey.current);
|
|
464
|
+
const observedMutation = useMemo(
|
|
465
|
+
() => client.mutationClient.observe({ key }),
|
|
466
|
+
[key]
|
|
470
467
|
);
|
|
468
|
+
const result = useObserve(observedMutation.result$) ?? observedMutation.lastValue;
|
|
471
469
|
const mutate = useCallback(
|
|
472
470
|
(mutationArgs) => {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
471
|
+
client.mutationClient.mutate({
|
|
472
|
+
options: { ...optionsRef.current, mutationKey: key },
|
|
473
|
+
args: mutationArgs
|
|
474
|
+
});
|
|
477
475
|
},
|
|
478
|
-
[
|
|
476
|
+
[client, key]
|
|
479
477
|
);
|
|
480
|
-
useEffect(() => {
|
|
481
|
-
if (mutation && !mutation.getClosed()) {
|
|
482
|
-
bufferTriggers.forEach((args) => {
|
|
483
|
-
mutation.trigger$.next(args);
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
}, [bufferTriggers, mutation]);
|
|
487
478
|
const reset = useCallback(() => {
|
|
488
|
-
reset
|
|
489
|
-
|
|
479
|
+
client.mutationClient.reset({
|
|
480
|
+
key: optionsRef.current.mutationKey ?? defaultKey.current
|
|
481
|
+
});
|
|
482
|
+
}, [client]);
|
|
483
|
+
useEffect(() => {
|
|
484
|
+
return () => {
|
|
485
|
+
if (optionsRef.current.cancelOnUnMount) {
|
|
486
|
+
client.mutationClient.reset({
|
|
487
|
+
key: optionsRef.current.mutationKey ?? defaultKey.current
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
}, []);
|
|
490
492
|
return { mutate, reset, ...result };
|
|
491
493
|
}
|
|
492
494
|
const arrayEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);
|
|
@@ -679,23 +681,6 @@ function useSubscribeEffect(source, unsafeOptions, deps = []) {
|
|
|
679
681
|
);
|
|
680
682
|
useSubscribe(enhancerMakeObservable, deps);
|
|
681
683
|
}
|
|
682
|
-
const serializeObject = (object) => {
|
|
683
|
-
if (Array.isArray(object)) {
|
|
684
|
-
return object.reduce((acc, value, index) => {
|
|
685
|
-
if (index === object.length - 1)
|
|
686
|
-
return `${acc}${serializeObject(value)}]`;
|
|
687
|
-
return `${acc}${serializeObject(value)},`;
|
|
688
|
-
}, "[");
|
|
689
|
-
}
|
|
690
|
-
if (object === void 0)
|
|
691
|
-
return "";
|
|
692
|
-
return JSON.stringify(object, Object.keys(object).sort());
|
|
693
|
-
};
|
|
694
|
-
const serializeKey = (key) => {
|
|
695
|
-
if (key.length === 0)
|
|
696
|
-
return "[]";
|
|
697
|
-
return serializeObject(key);
|
|
698
|
-
};
|
|
699
684
|
const retryOnError = (options) => retryBackoff({
|
|
700
685
|
initialInterval: 100,
|
|
701
686
|
...typeof options.retry === "function" ? {
|
|
@@ -1488,120 +1473,237 @@ const mergeResults = (stream$) => stream$.pipe(
|
|
|
1488
1473
|
{
|
|
1489
1474
|
data: void 0,
|
|
1490
1475
|
error: void 0,
|
|
1491
|
-
|
|
1492
|
-
status: "loading"
|
|
1476
|
+
status: "pending"
|
|
1493
1477
|
}
|
|
1494
1478
|
),
|
|
1495
1479
|
distinctUntilChanged(
|
|
1496
1480
|
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1497
1481
|
)
|
|
1498
1482
|
);
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1483
|
+
const createMutationRunner = ({
|
|
1484
|
+
__queryFinalizeHook,
|
|
1485
|
+
__queryInitHook,
|
|
1486
|
+
__queryTriggerHook
|
|
1487
|
+
}) => {
|
|
1488
|
+
const trigger$ = new Subject();
|
|
1489
|
+
const reset$ = new Subject();
|
|
1490
|
+
let closed = false;
|
|
1491
|
+
const mapOperator$ = new BehaviorSubject("merge");
|
|
1492
|
+
const mutationsRunning$ = new BehaviorSubject(0);
|
|
1493
|
+
const destroy = () => {
|
|
1494
|
+
if (closed) {
|
|
1495
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1496
|
+
}
|
|
1497
|
+
closed = true;
|
|
1498
|
+
mapOperator$.complete();
|
|
1499
|
+
mutationsRunning$.complete();
|
|
1500
|
+
trigger$.complete();
|
|
1501
|
+
reset$.complete();
|
|
1502
|
+
};
|
|
1503
|
+
const stableMapOperator$ = mapOperator$.pipe(
|
|
1504
|
+
filter(isDefined),
|
|
1505
|
+
distinctUntilChanged()
|
|
1506
|
+
);
|
|
1507
|
+
const mutation$ = stableMapOperator$.pipe(
|
|
1508
|
+
__queryInitHook ?? identity,
|
|
1509
|
+
mergeMap((mapOperator) => {
|
|
1510
|
+
const switchOperator = mapOperator === "concat" ? concatMap$1 : mapOperator === "switch" ? switchMap : mergeMap;
|
|
1511
|
+
return trigger$.pipe(
|
|
1512
|
+
takeUntil(stableMapOperator$.pipe(skip(1))),
|
|
1513
|
+
tap(() => {
|
|
1514
|
+
mutationsRunning$.next(mutationsRunning$.getValue() + 1);
|
|
1517
1515
|
}),
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
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);
|
|
1516
|
+
switchOperator(({ args, options }) => {
|
|
1517
|
+
const queryRunner$ = defer(() => from(options.mutationFn(args))).pipe(
|
|
1518
|
+
retryOnError(options),
|
|
1519
|
+
take(1),
|
|
1520
|
+
map((data) => ({ data, isError: false })),
|
|
1521
|
+
catchError((error) => {
|
|
1522
|
+
console.error(error);
|
|
1523
|
+
if (options.onError != null) {
|
|
1524
|
+
options.onError(error, args);
|
|
1525
|
+
}
|
|
1526
|
+
return of({ data: error, isError: true });
|
|
1586
1527
|
}),
|
|
1587
|
-
|
|
1588
|
-
|
|
1528
|
+
share()
|
|
1529
|
+
);
|
|
1530
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1531
|
+
map(({ data, isError }) => isError || data)
|
|
1532
|
+
);
|
|
1533
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1534
|
+
take(1),
|
|
1535
|
+
map(() => mapOperator === "concat"),
|
|
1536
|
+
startWith(true),
|
|
1537
|
+
takeUntil(queryIsOver$)
|
|
1538
|
+
);
|
|
1539
|
+
const loading$ = of({
|
|
1540
|
+
status: "pending"
|
|
1541
|
+
});
|
|
1542
|
+
return merge(
|
|
1543
|
+
loading$,
|
|
1544
|
+
combineLatest([
|
|
1545
|
+
queryRunner$,
|
|
1546
|
+
isThisCurrentFunctionLastOneCalled
|
|
1547
|
+
]).pipe(
|
|
1548
|
+
map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1549
|
+
if (!isError) {
|
|
1550
|
+
if (options.onSuccess != null)
|
|
1551
|
+
options.onSuccess(data, args);
|
|
1552
|
+
}
|
|
1553
|
+
if (isLastMutationCalled) {
|
|
1554
|
+
return isError ? {
|
|
1555
|
+
status: "error",
|
|
1556
|
+
error: data,
|
|
1557
|
+
data: void 0
|
|
1558
|
+
} : {
|
|
1559
|
+
status: "success",
|
|
1560
|
+
error: void 0,
|
|
1561
|
+
data
|
|
1562
|
+
};
|
|
1563
|
+
}
|
|
1564
|
+
return {};
|
|
1565
|
+
}),
|
|
1566
|
+
takeUntil(reset$)
|
|
1567
|
+
)
|
|
1568
|
+
).pipe(
|
|
1569
|
+
options.__queryRunnerHook ?? identity,
|
|
1570
|
+
finalize(() => {
|
|
1571
|
+
mutationsRunning$.next(mutationsRunning$.getValue() - 1);
|
|
1572
|
+
})
|
|
1589
1573
|
);
|
|
1590
1574
|
}),
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
destroy();
|
|
1594
|
-
}
|
|
1595
|
-
})
|
|
1575
|
+
__queryTriggerHook ?? identity,
|
|
1576
|
+
mergeResults
|
|
1596
1577
|
);
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1578
|
+
}),
|
|
1579
|
+
__queryFinalizeHook ?? identity
|
|
1580
|
+
);
|
|
1581
|
+
return {
|
|
1582
|
+
mutation$,
|
|
1583
|
+
trigger: ({
|
|
1584
|
+
args,
|
|
1585
|
+
options
|
|
1586
|
+
}) => {
|
|
1587
|
+
mapOperator$.next(options.mapOperator);
|
|
1588
|
+
trigger$.next({ args, options });
|
|
1589
|
+
},
|
|
1590
|
+
reset$,
|
|
1591
|
+
destroy,
|
|
1592
|
+
mutationsRunning$,
|
|
1593
|
+
getClosed: () => closed
|
|
1594
|
+
};
|
|
1595
|
+
};
|
|
1596
|
+
class MutationClient {
|
|
1597
|
+
constructor() {
|
|
1598
|
+
/**
|
|
1599
|
+
* Contain all active mutation for a given key.
|
|
1600
|
+
* A mutation ca have several triggers running (it is not necessarily one function running)
|
|
1601
|
+
*
|
|
1602
|
+
* @important
|
|
1603
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1604
|
+
*/
|
|
1605
|
+
__publicField(this, "mutationRunners$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1606
|
+
/**
|
|
1607
|
+
* Mutation result subject. It can be used whether there is a mutation
|
|
1608
|
+
* running or not and can be directly observed.
|
|
1609
|
+
*
|
|
1610
|
+
* @important
|
|
1611
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1612
|
+
*/
|
|
1613
|
+
__publicField(this, "mutationResults$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1614
|
+
__publicField(this, "mutate$", new Subject());
|
|
1615
|
+
__publicField(this, "reset$", new Subject());
|
|
1616
|
+
this.mutate$.pipe(
|
|
1617
|
+
tap(({ options, args }) => {
|
|
1618
|
+
const { mutationKey } = options;
|
|
1619
|
+
let mutationForKey = this.mutationRunners$.getValue().get(mutationKey);
|
|
1620
|
+
if (!mutationForKey) {
|
|
1621
|
+
mutationForKey = createMutationRunner(options);
|
|
1622
|
+
this.mutationRunners$.getValue().set(mutationKey, mutationForKey);
|
|
1623
|
+
mutationForKey.mutation$.subscribe((result) => {
|
|
1624
|
+
let resultForKeySubject = this.mutationResults$.getValue().get(mutationKey);
|
|
1625
|
+
if (!resultForKeySubject) {
|
|
1626
|
+
resultForKeySubject = new BehaviorSubject(result);
|
|
1627
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1628
|
+
resultMap.set(mutationKey, resultForKeySubject);
|
|
1629
|
+
this.mutationResults$.next(resultMap);
|
|
1630
|
+
} else {
|
|
1631
|
+
resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
mutationForKey.mutationsRunning$.pipe(
|
|
1635
|
+
skip(1),
|
|
1636
|
+
filter((number) => number === 0)
|
|
1637
|
+
).subscribe(() => {
|
|
1638
|
+
mutationForKey == null ? void 0 : mutationForKey.destroy();
|
|
1639
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1640
|
+
resultMap.delete(mutationKey);
|
|
1641
|
+
this.mutationResults$.next(resultMap);
|
|
1642
|
+
const mutationsMap = this.mutationRunners$.getValue();
|
|
1643
|
+
mutationsMap.delete(mutationKey);
|
|
1644
|
+
this.mutationRunners$.next(mutationsMap);
|
|
1645
|
+
});
|
|
1646
|
+
}
|
|
1647
|
+
mutationForKey.trigger({ args, options });
|
|
1648
|
+
})
|
|
1649
|
+
).subscribe();
|
|
1650
|
+
this.reset$.pipe(
|
|
1651
|
+
tap(({ key }) => {
|
|
1652
|
+
var _a;
|
|
1653
|
+
const serializedKey = serializeKey(key);
|
|
1654
|
+
(_a = this.mutationRunners$.getValue().get(serializedKey)) == null ? void 0 : _a.reset$.next();
|
|
1655
|
+
})
|
|
1656
|
+
).subscribe();
|
|
1657
|
+
}
|
|
1658
|
+
observe({ key }) {
|
|
1659
|
+
var _a;
|
|
1660
|
+
const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
|
|
1661
|
+
const mapResultToObservedResult = (value) => ({
|
|
1662
|
+
...value,
|
|
1663
|
+
isIdle: value.status === "idle",
|
|
1664
|
+
isPaused: false,
|
|
1665
|
+
isError: value.error !== void 0,
|
|
1666
|
+
isPending: false,
|
|
1667
|
+
isSuccess: value.status === "success"
|
|
1604
1668
|
});
|
|
1669
|
+
const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
|
|
1670
|
+
data: void 0,
|
|
1671
|
+
error: void 0,
|
|
1672
|
+
status: "idle"
|
|
1673
|
+
});
|
|
1674
|
+
const result$ = this.mutationResults$.pipe(
|
|
1675
|
+
switchMap((resultMap) => {
|
|
1676
|
+
const subject = resultMap.get(key);
|
|
1677
|
+
return subject ?? EMPTY;
|
|
1678
|
+
})
|
|
1679
|
+
).pipe(
|
|
1680
|
+
filter(isDefined),
|
|
1681
|
+
map((value) => ({
|
|
1682
|
+
...value,
|
|
1683
|
+
isIdle: value.status === "idle",
|
|
1684
|
+
isPaused: false,
|
|
1685
|
+
isError: value.error !== void 0,
|
|
1686
|
+
isPending: false,
|
|
1687
|
+
isSuccess: value.status === "success"
|
|
1688
|
+
}))
|
|
1689
|
+
);
|
|
1690
|
+
return { result$, lastValue };
|
|
1691
|
+
}
|
|
1692
|
+
mutate(params) {
|
|
1693
|
+
this.mutate$.next(params);
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* This will reset any current mutation runnings.
|
|
1697
|
+
* No discrimination process
|
|
1698
|
+
*/
|
|
1699
|
+
reset(params) {
|
|
1700
|
+
this.reset$.next(params);
|
|
1701
|
+
}
|
|
1702
|
+
destroy() {
|
|
1703
|
+
this.reset$.complete();
|
|
1704
|
+
this.mutate$.complete();
|
|
1705
|
+
this.mutationResults$.complete();
|
|
1706
|
+
this.mutationRunners$.complete();
|
|
1605
1707
|
}
|
|
1606
1708
|
}
|
|
1607
1709
|
const createClient = () => {
|
|
@@ -1725,20 +1827,24 @@ const createClient = () => {
|
|
|
1725
1827
|
const queryListenerSub = queryListener$.subscribe();
|
|
1726
1828
|
const started = [queryStore.start()];
|
|
1727
1829
|
return () => {
|
|
1728
|
-
started.forEach((
|
|
1729
|
-
|
|
1830
|
+
started.forEach((destroy2) => {
|
|
1831
|
+
destroy2();
|
|
1730
1832
|
});
|
|
1731
1833
|
queryListenerSub.unsubscribe();
|
|
1732
1834
|
};
|
|
1733
1835
|
};
|
|
1836
|
+
const destroy = () => {
|
|
1837
|
+
mutationClient.destroy();
|
|
1838
|
+
};
|
|
1734
1839
|
return {
|
|
1735
1840
|
start,
|
|
1736
1841
|
query,
|
|
1737
1842
|
queryStore,
|
|
1738
|
-
|
|
1843
|
+
mutationClient,
|
|
1739
1844
|
...invalidationClient,
|
|
1740
1845
|
...cacheClient,
|
|
1741
|
-
...refetchClient
|
|
1846
|
+
...refetchClient,
|
|
1847
|
+
destroy
|
|
1742
1848
|
};
|
|
1743
1849
|
};
|
|
1744
1850
|
class QueryClient {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { type Observable,
|
|
1
|
+
import { type Observable, 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
|
+
import { MutationClient } from "./mutations/MutationClient";
|
|
4
5
|
export declare const createClient: () => {
|
|
6
|
+
destroy: () => void;
|
|
5
7
|
pipeQueryResult: <R extends Partial<QueryResult<T>>, T>({ options$ }: {
|
|
6
8
|
key: string;
|
|
7
9
|
queryStore: {
|
|
@@ -38,22 +40,15 @@ export declare const createClient: () => {
|
|
|
38
40
|
exact?: boolean | undefined;
|
|
39
41
|
predicate?: ((storeObject: import("./store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
|
|
40
42
|
}) => 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
|
-
};
|
|
48
43
|
start: () => () => void;
|
|
49
|
-
query: <
|
|
44
|
+
query: <T_4>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
|
|
50
45
|
key: QueryKey;
|
|
51
|
-
fn?: QueryFn<
|
|
52
|
-
fn$?: Observable<QueryFn<
|
|
46
|
+
fn?: QueryFn<T_4> | undefined;
|
|
47
|
+
fn$?: Observable<QueryFn<T_4>> | undefined;
|
|
53
48
|
trigger$?: Observable<QueryTrigger> | undefined;
|
|
54
|
-
options$?: Observable<QueryOptions<
|
|
49
|
+
options$?: Observable<QueryOptions<T_4>> | undefined;
|
|
55
50
|
}) => {
|
|
56
|
-
result$: Observable<QueryResult<
|
|
51
|
+
result$: Observable<QueryResult<T_4>>;
|
|
57
52
|
};
|
|
58
53
|
queryStore: {
|
|
59
54
|
set: (key: string, value: import("./store/createQueryStore").StoreObject<unknown>) => void;
|
|
@@ -74,6 +69,7 @@ export declare const createClient: () => {
|
|
|
74
69
|
size: () => number;
|
|
75
70
|
start: () => () => void;
|
|
76
71
|
};
|
|
72
|
+
mutationClient: MutationClient;
|
|
77
73
|
};
|
|
78
74
|
export declare class QueryClient {
|
|
79
75
|
client: ReturnType<typeof createClient>;
|
|
@@ -1,11 +1,57 @@
|
|
|
1
|
-
import { type Observable
|
|
2
|
-
import { type MutationResult, type MutationOptions } from "./types";
|
|
1
|
+
import { Subject, BehaviorSubject, type Observable } from "rxjs";
|
|
2
|
+
import { type MutationResult, type MutationOptions, type MutationObservedResult } from "./types";
|
|
3
|
+
import { type QueryKey } from "../keys/types";
|
|
3
4
|
export declare class MutationClient {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Contain all active mutation for a given key.
|
|
7
|
+
* A mutation ca have several triggers running (it is not necessarily one function running)
|
|
8
|
+
*
|
|
9
|
+
* @important
|
|
10
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
11
|
+
*/
|
|
12
|
+
mutationRunners$: BehaviorSubject<Map<string, {
|
|
13
|
+
mutation$: Observable<MutationResult<unknown>>;
|
|
14
|
+
trigger: ({ args, options }: {
|
|
15
|
+
args: unknown;
|
|
16
|
+
options: MutationOptions<unknown, unknown>;
|
|
17
|
+
}) => void;
|
|
7
18
|
reset$: Subject<void>;
|
|
8
19
|
destroy: () => void;
|
|
20
|
+
mutationsRunning$: BehaviorSubject<number>;
|
|
9
21
|
getClosed: () => boolean;
|
|
22
|
+
}>>;
|
|
23
|
+
/**
|
|
24
|
+
* Mutation result subject. It can be used whether there is a mutation
|
|
25
|
+
* running or not and can be directly observed.
|
|
26
|
+
*
|
|
27
|
+
* @important
|
|
28
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
29
|
+
*/
|
|
30
|
+
mutationResults$: BehaviorSubject<Map<string, BehaviorSubject<MutationResult<any>>>>;
|
|
31
|
+
mutate$: Subject<{
|
|
32
|
+
options: MutationOptions<any, any>;
|
|
33
|
+
args: any;
|
|
34
|
+
}>;
|
|
35
|
+
reset$: Subject<{
|
|
36
|
+
key: QueryKey;
|
|
37
|
+
}>;
|
|
38
|
+
constructor();
|
|
39
|
+
observe<Result>({ key }: {
|
|
40
|
+
key: string;
|
|
41
|
+
}): {
|
|
42
|
+
result$: Observable<MutationObservedResult<Result>>;
|
|
43
|
+
lastValue: MutationObservedResult<Result>;
|
|
10
44
|
};
|
|
45
|
+
mutate<Result, MutationArgs>(params: {
|
|
46
|
+
options: MutationOptions<Result, MutationArgs>;
|
|
47
|
+
args: MutationArgs;
|
|
48
|
+
}): void;
|
|
49
|
+
/**
|
|
50
|
+
* This will reset any current mutation runnings.
|
|
51
|
+
* No discrimination process
|
|
52
|
+
*/
|
|
53
|
+
reset(params: {
|
|
54
|
+
key: QueryKey;
|
|
55
|
+
}): void;
|
|
56
|
+
destroy(): void;
|
|
11
57
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BehaviorSubject, Subject } from "rxjs";
|
|
2
|
+
import { type MutationOptions, type MutationResult } from "./types";
|
|
3
|
+
export declare const createMutationRunner: <T, MutationArg>({ __queryFinalizeHook, __queryInitHook, __queryTriggerHook }: Pick<MutationOptions<any, any>, "__queryInitHook" | "__queryTriggerHook" | "__queryFinalizeHook">) => {
|
|
4
|
+
mutation$: import("rxjs").Observable<MutationResult<T>>;
|
|
5
|
+
trigger: ({ args, options }: {
|
|
6
|
+
args: MutationArg;
|
|
7
|
+
options: MutationOptions<T, MutationArg>;
|
|
8
|
+
}) => void;
|
|
9
|
+
reset$: Subject<void>;
|
|
10
|
+
destroy: () => void;
|
|
11
|
+
mutationsRunning$: BehaviorSubject<number>;
|
|
12
|
+
getClosed: () => boolean;
|
|
13
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type MonoTypeOperatorFunction, type Observable } from "rxjs";
|
|
2
2
|
import { type Query, type QueryResult } from "../types";
|
|
3
|
-
import { type QueryKey } from "../keys/types";
|
|
4
3
|
/**
|
|
5
4
|
* The default value `merge` is suitable for most use case.
|
|
6
5
|
* You should not have to worry too much about it and only consider changing
|
|
@@ -23,9 +22,16 @@ import { type QueryKey } from "../keys/types";
|
|
|
23
22
|
export type MapOperator = "switch" | "concat" | "merge";
|
|
24
23
|
export interface MutationResult<R> {
|
|
25
24
|
data: R | undefined;
|
|
26
|
-
status: "idle" | "
|
|
25
|
+
status: "idle" | "pending" | "error" | "success";
|
|
27
26
|
error: unknown;
|
|
28
27
|
}
|
|
28
|
+
export interface MutationObservedResult<R> extends MutationResult<R> {
|
|
29
|
+
isError: boolean;
|
|
30
|
+
isIdle: boolean;
|
|
31
|
+
isSuccess: boolean;
|
|
32
|
+
isPending: boolean;
|
|
33
|
+
isPaused: boolean;
|
|
34
|
+
}
|
|
29
35
|
export type MutationFn<T, MutationArg> = ((arg: MutationArg) => Promise<T>) | ((arg: MutationArg) => Observable<T>);
|
|
30
36
|
export interface MutationOptions<Result, MutationArg> {
|
|
31
37
|
enabled?: boolean;
|
|
@@ -50,9 +56,10 @@ export interface MutationOptions<Result, MutationArg> {
|
|
|
50
56
|
onError?: (error: unknown, arg: MutationArg) => void;
|
|
51
57
|
onSuccess?: (data: Result, arg: MutationArg) => void;
|
|
52
58
|
mutationFn: MutationFn<Result, MutationArg>;
|
|
53
|
-
mutationKey:
|
|
59
|
+
mutationKey: string;
|
|
54
60
|
mapOperator?: MapOperator;
|
|
55
61
|
__queryInitHook?: MonoTypeOperatorFunction<any>;
|
|
56
62
|
__queryRunnerHook?: MonoTypeOperatorFunction<any>;
|
|
57
63
|
__queryTriggerHook?: MonoTypeOperatorFunction<Partial<Result>>;
|
|
64
|
+
__queryFinalizeHook?: MonoTypeOperatorFunction<Partial<Result>>;
|
|
58
65
|
}
|
|
@@ -8,6 +8,7 @@ export declare const QueryClientProvider: import("react").MemoExoticComponent<({
|
|
|
8
8
|
client: QueryClient;
|
|
9
9
|
}) => import("react/jsx-runtime").JSX.Element>;
|
|
10
10
|
export declare const useQueryClient: () => {
|
|
11
|
+
destroy: () => void;
|
|
11
12
|
pipeQueryResult: <R extends Partial<import("../client/types").QueryResult<T>>, T>({ options$ }: {
|
|
12
13
|
key: string;
|
|
13
14
|
queryStore: {
|
|
@@ -44,22 +45,15 @@ export declare const useQueryClient: () => {
|
|
|
44
45
|
exact?: boolean | undefined;
|
|
45
46
|
predicate?: ((storeObject: import("../client/store/createQueryStore").StoreObject<unknown>) => boolean) | undefined;
|
|
46
47
|
}) => 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
|
-
};
|
|
54
48
|
start: () => () => void;
|
|
55
|
-
query: <
|
|
49
|
+
query: <T_4>({ key, fn$: maybeFn$, fn: maybeFn, trigger$: externalTrigger$, options$ }: {
|
|
56
50
|
key: import("../client/keys/types").QueryKey;
|
|
57
|
-
fn?: import("../client/types").QueryFn<
|
|
58
|
-
fn$?: import("rxjs").Observable<import("../client/types").QueryFn<
|
|
51
|
+
fn?: import("../client/types").QueryFn<T_4> | undefined;
|
|
52
|
+
fn$?: import("rxjs").Observable<import("../client/types").QueryFn<T_4>> | undefined;
|
|
59
53
|
trigger$?: import("rxjs").Observable<import("../client/types").QueryTrigger> | undefined;
|
|
60
|
-
options$?: import("rxjs").Observable<import("../client/types").QueryOptions<
|
|
54
|
+
options$?: import("rxjs").Observable<import("../client/types").QueryOptions<T_4>> | undefined;
|
|
61
55
|
}) => {
|
|
62
|
-
result$: import("rxjs").Observable<import("../client/types").QueryResult<
|
|
56
|
+
result$: import("rxjs").Observable<import("../client/types").QueryResult<T_4>>;
|
|
63
57
|
};
|
|
64
58
|
queryStore: {
|
|
65
59
|
set: (key: string, value: import("../client/store/createQueryStore").StoreObject<unknown>) => void;
|
|
@@ -80,4 +74,5 @@ export declare const useQueryClient: () => {
|
|
|
80
74
|
size: () => number;
|
|
81
75
|
start: () => () => void;
|
|
82
76
|
};
|
|
77
|
+
mutationClient: import("../client/mutations/MutationClient").MutationClient;
|
|
83
78
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const nanoid: (size?: number) => string;
|
|
@@ -1,45 +1,17 @@
|
|
|
1
|
-
import { type MonoTypeOperatorFunction } from "rxjs";
|
|
2
1
|
import { type MutationOptions } from "../../client/mutations/types";
|
|
3
2
|
import { type QueryKey } from "../../client/keys/types";
|
|
4
3
|
export type AsyncQueryOptions<Result, Params> = Omit<MutationOptions<Result, Params>, "mutationKey"> & {
|
|
5
4
|
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
5
|
cancelOnUnMount?: boolean;
|
|
17
|
-
__triggerHook?: MonoTypeOperatorFunction<unknown>;
|
|
18
6
|
};
|
|
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
7
|
export declare function useMutation<Args = void, R = undefined>(options: AsyncQueryOptions<R, Args>): {
|
|
8
|
+
isError: boolean;
|
|
9
|
+
isIdle: boolean;
|
|
10
|
+
isSuccess: boolean;
|
|
11
|
+
isPending: boolean;
|
|
12
|
+
isPaused: boolean;
|
|
41
13
|
data: R | undefined;
|
|
42
|
-
status: "error" | "idle" | "
|
|
14
|
+
status: "error" | "idle" | "success" | "pending";
|
|
43
15
|
error: unknown;
|
|
44
16
|
mutate: (mutationArgs: Args) => void;
|
|
45
17
|
reset: () => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|