reactjrx 1.55.0 → 1.56.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 +280 -173
- package/dist/index.js +282 -175
- 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 +9 -2
- 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 +5 -33
- 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" ? {
|
|
@@ -1498,112 +1483,230 @@ const mergeResults = (stream$) => stream$.pipe(
|
|
|
1498
1483
|
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1499
1484
|
)
|
|
1500
1485
|
);
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1486
|
+
const createMutationRunner = ({
|
|
1487
|
+
__queryFinalizeHook,
|
|
1488
|
+
__queryInitHook,
|
|
1489
|
+
__queryTriggerHook
|
|
1490
|
+
}) => {
|
|
1491
|
+
const trigger$ = new rxjs.Subject();
|
|
1492
|
+
const reset$ = new rxjs.Subject();
|
|
1493
|
+
let closed = false;
|
|
1494
|
+
const mapOperator$ = new rxjs.BehaviorSubject("merge");
|
|
1495
|
+
const mutationsRunning$ = new rxjs.BehaviorSubject(0);
|
|
1496
|
+
const destroy = () => {
|
|
1497
|
+
if (closed) {
|
|
1498
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1499
|
+
}
|
|
1500
|
+
closed = true;
|
|
1501
|
+
mapOperator$.complete();
|
|
1502
|
+
mutationsRunning$.complete();
|
|
1503
|
+
trigger$.complete();
|
|
1504
|
+
reset$.complete();
|
|
1505
|
+
};
|
|
1506
|
+
const stableMapOperator$ = mapOperator$.pipe(
|
|
1507
|
+
rxjs.filter(isDefined),
|
|
1508
|
+
rxjs.distinctUntilChanged()
|
|
1509
|
+
);
|
|
1510
|
+
const mutation$ = stableMapOperator$.pipe(
|
|
1511
|
+
__queryInitHook ?? rxjs.identity,
|
|
1512
|
+
rxjs.mergeMap((mapOperator) => {
|
|
1513
|
+
const switchOperator = mapOperator === "concat" ? rxjs.concatMap : mapOperator === "switch" ? rxjs.switchMap : rxjs.mergeMap;
|
|
1514
|
+
return trigger$.pipe(
|
|
1515
|
+
rxjs.takeUntil(stableMapOperator$.pipe(rxjs.skip(1))),
|
|
1516
|
+
rxjs.tap(() => {
|
|
1517
|
+
mutationsRunning$.next(mutationsRunning$.getValue() + 1);
|
|
1519
1518
|
}),
|
|
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);
|
|
1519
|
+
switchOperator(({ args, options }) => {
|
|
1520
|
+
const queryRunner$ = rxjs.defer(() => rxjs.from(options.mutationFn(args))).pipe(
|
|
1521
|
+
retryOnError(options),
|
|
1522
|
+
rxjs.take(1),
|
|
1523
|
+
rxjs.map((data) => ({ data, isError: false })),
|
|
1524
|
+
rxjs.catchError((error) => {
|
|
1525
|
+
console.error(error);
|
|
1526
|
+
if (options.onError != null) {
|
|
1527
|
+
options.onError(error, args);
|
|
1528
|
+
}
|
|
1529
|
+
return rxjs.of({ data: error, isError: true });
|
|
1588
1530
|
}),
|
|
1589
|
-
|
|
1590
|
-
|
|
1531
|
+
rxjs.share()
|
|
1532
|
+
);
|
|
1533
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1534
|
+
rxjs.map(({ data, isError }) => isError || data)
|
|
1535
|
+
);
|
|
1536
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1537
|
+
rxjs.take(1),
|
|
1538
|
+
rxjs.map(() => mapOperator === "concat"),
|
|
1539
|
+
rxjs.startWith(true),
|
|
1540
|
+
rxjs.takeUntil(queryIsOver$)
|
|
1541
|
+
);
|
|
1542
|
+
const loading$ = rxjs.of({
|
|
1543
|
+
status: "loading"
|
|
1544
|
+
});
|
|
1545
|
+
return rxjs.merge(
|
|
1546
|
+
loading$,
|
|
1547
|
+
rxjs.combineLatest([
|
|
1548
|
+
queryRunner$,
|
|
1549
|
+
isThisCurrentFunctionLastOneCalled
|
|
1550
|
+
]).pipe(
|
|
1551
|
+
rxjs.map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1552
|
+
if (!isError) {
|
|
1553
|
+
if (options.onSuccess != null)
|
|
1554
|
+
options.onSuccess(data, args);
|
|
1555
|
+
}
|
|
1556
|
+
if (isLastMutationCalled) {
|
|
1557
|
+
return isError ? {
|
|
1558
|
+
status: "error",
|
|
1559
|
+
error: data,
|
|
1560
|
+
data: void 0
|
|
1561
|
+
} : {
|
|
1562
|
+
status: "success",
|
|
1563
|
+
error: void 0,
|
|
1564
|
+
data
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1567
|
+
return {};
|
|
1568
|
+
}),
|
|
1569
|
+
rxjs.takeUntil(reset$)
|
|
1570
|
+
)
|
|
1571
|
+
).pipe(
|
|
1572
|
+
options.__queryRunnerHook ?? rxjs.identity,
|
|
1573
|
+
rxjs.finalize(() => {
|
|
1574
|
+
mutationsRunning$.next(mutationsRunning$.getValue() - 1);
|
|
1575
|
+
})
|
|
1591
1576
|
);
|
|
1592
1577
|
}),
|
|
1593
|
-
rxjs.
|
|
1594
|
-
|
|
1595
|
-
destroy();
|
|
1596
|
-
}
|
|
1597
|
-
})
|
|
1578
|
+
__queryTriggerHook ?? rxjs.identity,
|
|
1579
|
+
mergeResults
|
|
1598
1580
|
);
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1581
|
+
}),
|
|
1582
|
+
__queryFinalizeHook ?? rxjs.identity
|
|
1583
|
+
);
|
|
1584
|
+
return {
|
|
1585
|
+
mutation$,
|
|
1586
|
+
trigger: ({
|
|
1587
|
+
args,
|
|
1588
|
+
options
|
|
1589
|
+
}) => {
|
|
1590
|
+
mapOperator$.next(options.mapOperator);
|
|
1591
|
+
trigger$.next({ args, options });
|
|
1592
|
+
},
|
|
1593
|
+
reset$,
|
|
1594
|
+
destroy,
|
|
1595
|
+
mutationsRunning$,
|
|
1596
|
+
getClosed: () => closed
|
|
1597
|
+
};
|
|
1598
|
+
};
|
|
1599
|
+
class MutationClient {
|
|
1600
|
+
constructor() {
|
|
1601
|
+
/**
|
|
1602
|
+
* Contain all active mutation for a given key.
|
|
1603
|
+
* A mutation ca have several triggers running (it is not necessarily one function running)
|
|
1604
|
+
*
|
|
1605
|
+
* @important
|
|
1606
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1607
|
+
*/
|
|
1608
|
+
__publicField(this, "mutationRunners$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1609
|
+
/**
|
|
1610
|
+
* Mutation result subject. It can be used whether there is a mutation
|
|
1611
|
+
* running or not and can be directly observed.
|
|
1612
|
+
*
|
|
1613
|
+
* @important
|
|
1614
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1615
|
+
*/
|
|
1616
|
+
__publicField(this, "mutationResults$", new rxjs.BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1617
|
+
__publicField(this, "mutate$", new rxjs.Subject());
|
|
1618
|
+
__publicField(this, "reset$", new rxjs.Subject());
|
|
1619
|
+
this.mutate$.pipe(
|
|
1620
|
+
rxjs.tap(({ options, args }) => {
|
|
1621
|
+
const { mutationKey } = options;
|
|
1622
|
+
let mutationForKey = this.mutationRunners$.getValue().get(mutationKey);
|
|
1623
|
+
if (!mutationForKey) {
|
|
1624
|
+
mutationForKey = createMutationRunner(options);
|
|
1625
|
+
this.mutationRunners$.getValue().set(mutationKey, mutationForKey);
|
|
1626
|
+
mutationForKey.mutation$.subscribe((result) => {
|
|
1627
|
+
let resultForKeySubject = this.mutationResults$.getValue().get(mutationKey);
|
|
1628
|
+
if (!resultForKeySubject) {
|
|
1629
|
+
resultForKeySubject = new rxjs.BehaviorSubject(result);
|
|
1630
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1631
|
+
resultMap.set(mutationKey, resultForKeySubject);
|
|
1632
|
+
this.mutationResults$.next(resultMap);
|
|
1633
|
+
} else {
|
|
1634
|
+
resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
|
|
1635
|
+
}
|
|
1636
|
+
});
|
|
1637
|
+
mutationForKey.mutationsRunning$.pipe(
|
|
1638
|
+
rxjs.skip(1),
|
|
1639
|
+
rxjs.filter((number) => number === 0)
|
|
1640
|
+
).subscribe(() => {
|
|
1641
|
+
mutationForKey == null ? void 0 : mutationForKey.destroy();
|
|
1642
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1643
|
+
resultMap.delete(mutationKey);
|
|
1644
|
+
this.mutationResults$.next(resultMap);
|
|
1645
|
+
const mutationsMap = this.mutationRunners$.getValue();
|
|
1646
|
+
mutationsMap.delete(mutationKey);
|
|
1647
|
+
this.mutationRunners$.next(mutationsMap);
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
mutationForKey.trigger({ args, options });
|
|
1651
|
+
})
|
|
1652
|
+
).subscribe();
|
|
1653
|
+
this.reset$.pipe(
|
|
1654
|
+
rxjs.tap(({ key }) => {
|
|
1655
|
+
var _a;
|
|
1656
|
+
const serializedKey = serializeKey(key);
|
|
1657
|
+
(_a = this.mutationRunners$.getValue().get(serializedKey)) == null ? void 0 : _a.reset$.next();
|
|
1658
|
+
})
|
|
1659
|
+
).subscribe();
|
|
1660
|
+
}
|
|
1661
|
+
observe({ key }) {
|
|
1662
|
+
var _a;
|
|
1663
|
+
const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
|
|
1664
|
+
const mapResultToObservedResult = (value) => ({
|
|
1665
|
+
...value,
|
|
1666
|
+
isIdle: value.status === "idle",
|
|
1667
|
+
isPaused: false,
|
|
1668
|
+
isError: value.error !== void 0,
|
|
1669
|
+
isPending: false,
|
|
1670
|
+
isSuccess: value.status === "success"
|
|
1606
1671
|
});
|
|
1672
|
+
const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
|
|
1673
|
+
data: void 0,
|
|
1674
|
+
error: void 0,
|
|
1675
|
+
status: "idle"
|
|
1676
|
+
});
|
|
1677
|
+
const result$ = this.mutationResults$.pipe(
|
|
1678
|
+
rxjs.switchMap((resultMap) => {
|
|
1679
|
+
const subject = resultMap.get(key);
|
|
1680
|
+
return subject ?? rxjs.EMPTY;
|
|
1681
|
+
})
|
|
1682
|
+
).pipe(
|
|
1683
|
+
rxjs.filter(isDefined),
|
|
1684
|
+
rxjs.map((value) => ({
|
|
1685
|
+
...value,
|
|
1686
|
+
isIdle: value.status === "idle",
|
|
1687
|
+
isPaused: false,
|
|
1688
|
+
isError: value.error !== void 0,
|
|
1689
|
+
isPending: false,
|
|
1690
|
+
isSuccess: value.status === "success"
|
|
1691
|
+
}))
|
|
1692
|
+
);
|
|
1693
|
+
return { result$, lastValue };
|
|
1694
|
+
}
|
|
1695
|
+
mutate(params) {
|
|
1696
|
+
this.mutate$.next(params);
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* This will reset any current mutation runnings.
|
|
1700
|
+
* No discrimination process
|
|
1701
|
+
*/
|
|
1702
|
+
reset(params) {
|
|
1703
|
+
this.reset$.next(params);
|
|
1704
|
+
}
|
|
1705
|
+
destroy() {
|
|
1706
|
+
this.reset$.complete();
|
|
1707
|
+
this.mutate$.complete();
|
|
1708
|
+
this.mutationResults$.complete();
|
|
1709
|
+
this.mutationRunners$.complete();
|
|
1607
1710
|
}
|
|
1608
1711
|
}
|
|
1609
1712
|
const createClient = () => {
|
|
@@ -1727,20 +1830,24 @@ const createClient = () => {
|
|
|
1727
1830
|
const queryListenerSub = queryListener$.subscribe();
|
|
1728
1831
|
const started = [queryStore.start()];
|
|
1729
1832
|
return () => {
|
|
1730
|
-
started.forEach((
|
|
1731
|
-
|
|
1833
|
+
started.forEach((destroy2) => {
|
|
1834
|
+
destroy2();
|
|
1732
1835
|
});
|
|
1733
1836
|
queryListenerSub.unsubscribe();
|
|
1734
1837
|
};
|
|
1735
1838
|
};
|
|
1839
|
+
const destroy = () => {
|
|
1840
|
+
mutationClient.destroy();
|
|
1841
|
+
};
|
|
1736
1842
|
return {
|
|
1737
1843
|
start,
|
|
1738
1844
|
query,
|
|
1739
1845
|
queryStore,
|
|
1740
|
-
|
|
1846
|
+
mutationClient,
|
|
1741
1847
|
...invalidationClient,
|
|
1742
1848
|
...cacheClient,
|
|
1743
|
-
...refetchClient
|
|
1849
|
+
...refetchClient,
|
|
1850
|
+
destroy
|
|
1744
1851
|
};
|
|
1745
1852
|
};
|
|
1746
1853
|
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" ? {
|
|
@@ -1496,112 +1481,230 @@ const mergeResults = (stream$) => stream$.pipe(
|
|
|
1496
1481
|
({ data: prevData, ...prev }, { data: currData, ...curr }) => shallowEqual(prev, curr) && shallowEqual(prevData, currData)
|
|
1497
1482
|
)
|
|
1498
1483
|
);
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1484
|
+
const createMutationRunner = ({
|
|
1485
|
+
__queryFinalizeHook,
|
|
1486
|
+
__queryInitHook,
|
|
1487
|
+
__queryTriggerHook
|
|
1488
|
+
}) => {
|
|
1489
|
+
const trigger$ = new Subject();
|
|
1490
|
+
const reset$ = new Subject();
|
|
1491
|
+
let closed = false;
|
|
1492
|
+
const mapOperator$ = new BehaviorSubject("merge");
|
|
1493
|
+
const mutationsRunning$ = new BehaviorSubject(0);
|
|
1494
|
+
const destroy = () => {
|
|
1495
|
+
if (closed) {
|
|
1496
|
+
throw new Error("Trying to close an already closed mutation");
|
|
1497
|
+
}
|
|
1498
|
+
closed = true;
|
|
1499
|
+
mapOperator$.complete();
|
|
1500
|
+
mutationsRunning$.complete();
|
|
1501
|
+
trigger$.complete();
|
|
1502
|
+
reset$.complete();
|
|
1503
|
+
};
|
|
1504
|
+
const stableMapOperator$ = mapOperator$.pipe(
|
|
1505
|
+
filter(isDefined),
|
|
1506
|
+
distinctUntilChanged()
|
|
1507
|
+
);
|
|
1508
|
+
const mutation$ = stableMapOperator$.pipe(
|
|
1509
|
+
__queryInitHook ?? identity,
|
|
1510
|
+
mergeMap((mapOperator) => {
|
|
1511
|
+
const switchOperator = mapOperator === "concat" ? concatMap$1 : mapOperator === "switch" ? switchMap : mergeMap;
|
|
1512
|
+
return trigger$.pipe(
|
|
1513
|
+
takeUntil(stableMapOperator$.pipe(skip(1))),
|
|
1514
|
+
tap(() => {
|
|
1515
|
+
mutationsRunning$.next(mutationsRunning$.getValue() + 1);
|
|
1517
1516
|
}),
|
|
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);
|
|
1517
|
+
switchOperator(({ args, options }) => {
|
|
1518
|
+
const queryRunner$ = defer(() => from(options.mutationFn(args))).pipe(
|
|
1519
|
+
retryOnError(options),
|
|
1520
|
+
take(1),
|
|
1521
|
+
map((data) => ({ data, isError: false })),
|
|
1522
|
+
catchError((error) => {
|
|
1523
|
+
console.error(error);
|
|
1524
|
+
if (options.onError != null) {
|
|
1525
|
+
options.onError(error, args);
|
|
1526
|
+
}
|
|
1527
|
+
return of({ data: error, isError: true });
|
|
1586
1528
|
}),
|
|
1587
|
-
|
|
1588
|
-
|
|
1529
|
+
share()
|
|
1530
|
+
);
|
|
1531
|
+
const queryIsOver$ = queryRunner$.pipe(
|
|
1532
|
+
map(({ data, isError }) => isError || data)
|
|
1533
|
+
);
|
|
1534
|
+
const isThisCurrentFunctionLastOneCalled = trigger$.pipe(
|
|
1535
|
+
take(1),
|
|
1536
|
+
map(() => mapOperator === "concat"),
|
|
1537
|
+
startWith(true),
|
|
1538
|
+
takeUntil(queryIsOver$)
|
|
1539
|
+
);
|
|
1540
|
+
const loading$ = of({
|
|
1541
|
+
status: "loading"
|
|
1542
|
+
});
|
|
1543
|
+
return merge(
|
|
1544
|
+
loading$,
|
|
1545
|
+
combineLatest([
|
|
1546
|
+
queryRunner$,
|
|
1547
|
+
isThisCurrentFunctionLastOneCalled
|
|
1548
|
+
]).pipe(
|
|
1549
|
+
map(([{ data, isError }, isLastMutationCalled]) => {
|
|
1550
|
+
if (!isError) {
|
|
1551
|
+
if (options.onSuccess != null)
|
|
1552
|
+
options.onSuccess(data, args);
|
|
1553
|
+
}
|
|
1554
|
+
if (isLastMutationCalled) {
|
|
1555
|
+
return isError ? {
|
|
1556
|
+
status: "error",
|
|
1557
|
+
error: data,
|
|
1558
|
+
data: void 0
|
|
1559
|
+
} : {
|
|
1560
|
+
status: "success",
|
|
1561
|
+
error: void 0,
|
|
1562
|
+
data
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
return {};
|
|
1566
|
+
}),
|
|
1567
|
+
takeUntil(reset$)
|
|
1568
|
+
)
|
|
1569
|
+
).pipe(
|
|
1570
|
+
options.__queryRunnerHook ?? identity,
|
|
1571
|
+
finalize(() => {
|
|
1572
|
+
mutationsRunning$.next(mutationsRunning$.getValue() - 1);
|
|
1573
|
+
})
|
|
1589
1574
|
);
|
|
1590
1575
|
}),
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
destroy();
|
|
1594
|
-
}
|
|
1595
|
-
})
|
|
1576
|
+
__queryTriggerHook ?? identity,
|
|
1577
|
+
mergeResults
|
|
1596
1578
|
);
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1579
|
+
}),
|
|
1580
|
+
__queryFinalizeHook ?? identity
|
|
1581
|
+
);
|
|
1582
|
+
return {
|
|
1583
|
+
mutation$,
|
|
1584
|
+
trigger: ({
|
|
1585
|
+
args,
|
|
1586
|
+
options
|
|
1587
|
+
}) => {
|
|
1588
|
+
mapOperator$.next(options.mapOperator);
|
|
1589
|
+
trigger$.next({ args, options });
|
|
1590
|
+
},
|
|
1591
|
+
reset$,
|
|
1592
|
+
destroy,
|
|
1593
|
+
mutationsRunning$,
|
|
1594
|
+
getClosed: () => closed
|
|
1595
|
+
};
|
|
1596
|
+
};
|
|
1597
|
+
class MutationClient {
|
|
1598
|
+
constructor() {
|
|
1599
|
+
/**
|
|
1600
|
+
* Contain all active mutation for a given key.
|
|
1601
|
+
* A mutation ca have several triggers running (it is not necessarily one function running)
|
|
1602
|
+
*
|
|
1603
|
+
* @important
|
|
1604
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1605
|
+
*/
|
|
1606
|
+
__publicField(this, "mutationRunners$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1607
|
+
/**
|
|
1608
|
+
* Mutation result subject. It can be used whether there is a mutation
|
|
1609
|
+
* running or not and can be directly observed.
|
|
1610
|
+
*
|
|
1611
|
+
* @important
|
|
1612
|
+
* - automatically cleaned as soon as the last mutation is done for a given key
|
|
1613
|
+
*/
|
|
1614
|
+
__publicField(this, "mutationResults$", new BehaviorSubject(/* @__PURE__ */ new Map()));
|
|
1615
|
+
__publicField(this, "mutate$", new Subject());
|
|
1616
|
+
__publicField(this, "reset$", new Subject());
|
|
1617
|
+
this.mutate$.pipe(
|
|
1618
|
+
tap(({ options, args }) => {
|
|
1619
|
+
const { mutationKey } = options;
|
|
1620
|
+
let mutationForKey = this.mutationRunners$.getValue().get(mutationKey);
|
|
1621
|
+
if (!mutationForKey) {
|
|
1622
|
+
mutationForKey = createMutationRunner(options);
|
|
1623
|
+
this.mutationRunners$.getValue().set(mutationKey, mutationForKey);
|
|
1624
|
+
mutationForKey.mutation$.subscribe((result) => {
|
|
1625
|
+
let resultForKeySubject = this.mutationResults$.getValue().get(mutationKey);
|
|
1626
|
+
if (!resultForKeySubject) {
|
|
1627
|
+
resultForKeySubject = new BehaviorSubject(result);
|
|
1628
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1629
|
+
resultMap.set(mutationKey, resultForKeySubject);
|
|
1630
|
+
this.mutationResults$.next(resultMap);
|
|
1631
|
+
} else {
|
|
1632
|
+
resultForKeySubject == null ? void 0 : resultForKeySubject.next(result);
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
mutationForKey.mutationsRunning$.pipe(
|
|
1636
|
+
skip(1),
|
|
1637
|
+
filter((number) => number === 0)
|
|
1638
|
+
).subscribe(() => {
|
|
1639
|
+
mutationForKey == null ? void 0 : mutationForKey.destroy();
|
|
1640
|
+
const resultMap = this.mutationResults$.getValue();
|
|
1641
|
+
resultMap.delete(mutationKey);
|
|
1642
|
+
this.mutationResults$.next(resultMap);
|
|
1643
|
+
const mutationsMap = this.mutationRunners$.getValue();
|
|
1644
|
+
mutationsMap.delete(mutationKey);
|
|
1645
|
+
this.mutationRunners$.next(mutationsMap);
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
mutationForKey.trigger({ args, options });
|
|
1649
|
+
})
|
|
1650
|
+
).subscribe();
|
|
1651
|
+
this.reset$.pipe(
|
|
1652
|
+
tap(({ key }) => {
|
|
1653
|
+
var _a;
|
|
1654
|
+
const serializedKey = serializeKey(key);
|
|
1655
|
+
(_a = this.mutationRunners$.getValue().get(serializedKey)) == null ? void 0 : _a.reset$.next();
|
|
1656
|
+
})
|
|
1657
|
+
).subscribe();
|
|
1658
|
+
}
|
|
1659
|
+
observe({ key }) {
|
|
1660
|
+
var _a;
|
|
1661
|
+
const currentResultValue = (_a = this.mutationResults$.getValue().get(key)) == null ? void 0 : _a.getValue();
|
|
1662
|
+
const mapResultToObservedResult = (value) => ({
|
|
1663
|
+
...value,
|
|
1664
|
+
isIdle: value.status === "idle",
|
|
1665
|
+
isPaused: false,
|
|
1666
|
+
isError: value.error !== void 0,
|
|
1667
|
+
isPending: false,
|
|
1668
|
+
isSuccess: value.status === "success"
|
|
1604
1669
|
});
|
|
1670
|
+
const lastValue = currentResultValue ? mapResultToObservedResult(currentResultValue) : mapResultToObservedResult({
|
|
1671
|
+
data: void 0,
|
|
1672
|
+
error: void 0,
|
|
1673
|
+
status: "idle"
|
|
1674
|
+
});
|
|
1675
|
+
const result$ = this.mutationResults$.pipe(
|
|
1676
|
+
switchMap((resultMap) => {
|
|
1677
|
+
const subject = resultMap.get(key);
|
|
1678
|
+
return subject ?? EMPTY;
|
|
1679
|
+
})
|
|
1680
|
+
).pipe(
|
|
1681
|
+
filter(isDefined),
|
|
1682
|
+
map((value) => ({
|
|
1683
|
+
...value,
|
|
1684
|
+
isIdle: value.status === "idle",
|
|
1685
|
+
isPaused: false,
|
|
1686
|
+
isError: value.error !== void 0,
|
|
1687
|
+
isPending: false,
|
|
1688
|
+
isSuccess: value.status === "success"
|
|
1689
|
+
}))
|
|
1690
|
+
);
|
|
1691
|
+
return { result$, lastValue };
|
|
1692
|
+
}
|
|
1693
|
+
mutate(params) {
|
|
1694
|
+
this.mutate$.next(params);
|
|
1695
|
+
}
|
|
1696
|
+
/**
|
|
1697
|
+
* This will reset any current mutation runnings.
|
|
1698
|
+
* No discrimination process
|
|
1699
|
+
*/
|
|
1700
|
+
reset(params) {
|
|
1701
|
+
this.reset$.next(params);
|
|
1702
|
+
}
|
|
1703
|
+
destroy() {
|
|
1704
|
+
this.reset$.complete();
|
|
1705
|
+
this.mutate$.complete();
|
|
1706
|
+
this.mutationResults$.complete();
|
|
1707
|
+
this.mutationRunners$.complete();
|
|
1605
1708
|
}
|
|
1606
1709
|
}
|
|
1607
1710
|
const createClient = () => {
|
|
@@ -1725,20 +1828,24 @@ const createClient = () => {
|
|
|
1725
1828
|
const queryListenerSub = queryListener$.subscribe();
|
|
1726
1829
|
const started = [queryStore.start()];
|
|
1727
1830
|
return () => {
|
|
1728
|
-
started.forEach((
|
|
1729
|
-
|
|
1831
|
+
started.forEach((destroy2) => {
|
|
1832
|
+
destroy2();
|
|
1730
1833
|
});
|
|
1731
1834
|
queryListenerSub.unsubscribe();
|
|
1732
1835
|
};
|
|
1733
1836
|
};
|
|
1837
|
+
const destroy = () => {
|
|
1838
|
+
mutationClient.destroy();
|
|
1839
|
+
};
|
|
1734
1840
|
return {
|
|
1735
1841
|
start,
|
|
1736
1842
|
query,
|
|
1737
1843
|
queryStore,
|
|
1738
|
-
|
|
1844
|
+
mutationClient,
|
|
1739
1845
|
...invalidationClient,
|
|
1740
1846
|
...cacheClient,
|
|
1741
|
-
...refetchClient
|
|
1847
|
+
...refetchClient,
|
|
1848
|
+
destroy
|
|
1742
1849
|
};
|
|
1743
1850
|
};
|
|
1744
1851
|
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
|
|
@@ -26,6 +25,13 @@ export interface MutationResult<R> {
|
|
|
26
25
|
status: "idle" | "loading" | "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,43 +1,15 @@
|
|
|
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
14
|
status: "error" | "idle" | "loading" | "success";
|
|
43
15
|
error: unknown;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|