···
/* eslint-disable @typescript-eslint/no-use-before-define */
···
const makeResultSource = (operation: Operation) => {
605
+
// Filter by matching key (or _instance if it’s set)
(res: OperationResult) =>
res.operation.kind === operation.kind &&
res.operation.key === operation.key &&
(!res.operation.context._instance ||
res.operation.context._instance === operation.context._instance)
613
+
// End the results stream when an active teardown event is sent
617
+
filter(op => op.kind === 'teardown' && op.key === operation.key)
614
-
// Mask typename properties if the option for it is turned on
615
-
if (opts.maskTypename) {
622
+
if (operation.kind !== 'query') {
623
+
// Interrupt subscriptions and mutations when they have no more results
618
-
map(res => ({ ...res, data: maskTypename(res.data, true) }))
626
+
takeWhile(result => !!result.hasNext, true)
631
+
// Add `stale: true` flag when a new operation is sent for queries
632
+
switchMap(result => {
633
+
const value$ = fromValue(result);
634
+
return result.stale
642
+
op.kind === 'query' &&
643
+
op.key === operation.key &&
644
+
op.context.requestPolicy !== 'cache-only'
647
+
map(() => ({ ...result, stale: true }))
622
-
if (operation.kind !== 'query') {
654
+
if (operation.kind !== 'mutation') {
657
+
// Store replay result
659
+
dispatched.delete(operation.key);
660
+
replays.set(operation.key, result);
662
+
// Cleanup active states on end of source
664
+
// Delete the active operation handle
665
+
dispatched.delete(operation.key);
666
+
replays.delete(operation.key);
667
+
active.delete(operation.key);
668
+
// Interrupt active queue
669
+
isOperationBatchActive = false;
670
+
// Delete all queued up operations of the same key on end
671
+
for (let i = queue.length - 1; i >= 0; i--)
672
+
if (queue[i].key === operation.key) queue.splice(i, 1);
673
+
// Dispatch a teardown signal for the stopped operation
675
+
makeOperation('teardown', operation, operation.context)
682
+
// Send mutation operation on start
nextOperation(operation);
631
-
// A mutation is always limited to just a single result and is never shared
632
-
if (operation.kind === 'mutation') {
633
-
return pipe(result$, take(1));
636
-
if (operation.kind === 'subscription') {
689
+
// Mask typename properties if the option for it is turned on
690
+
if (opts.maskTypename) {
639
-
takeWhile(result => !!result.hasNext)
693
+
map(res => ({ ...res, data: maskTypename(res.data, true) }))
645
-
// End the results stream when an active teardown event is sent
649
-
filter(op => op.kind === 'teardown' && op.key === operation.key)
652
-
switchMap(result => {
653
-
if (operation.kind !== 'query' || result.stale) {
654
-
return fromValue(result);
659
-
// Mark a result as stale when a new operation is sent for it
664
-
op.kind === 'query' &&
665
-
op.key === operation.key &&
666
-
op.context.requestPolicy !== 'cache-only'
669
-
map(() => ({ ...result, stale: true }))
674
-
dispatched.delete(operation.key);
675
-
replays.set(operation.key, result);
678
-
// Delete the active operation handle
679
-
dispatched.delete(operation.key);
680
-
replays.delete(operation.key);
681
-
active.delete(operation.key);
682
-
// Delete all queued up operations of the same key on end
683
-
for (let i = queue.length - 1; i >= 0; i--)
684
-
if (queue[i].key === operation.key) queue.splice(i, 1);
685
-
// Dispatch a teardown signal for the stopped operation
686
-
nextOperation(makeOperation('teardown', operation, operation.context));
697
+
return share(result$);
···
739
-
make<OperationResult>(observer => {
747
+
lazy<OperationResult>(() => {
let source = active.get(operation.key);
active.set(operation.key, (source = makeResultSource(operation)));
748
-
const prevReplay = replays.get(operation.key);
749
-
const isNetworkOperation =
750
-
operation.context.requestPolicy === 'cache-and-network' ||
751
-
operation.context.requestPolicy === 'network-only';
752
-
if (operation.kind !== 'query') {
754
-
} else if (isNetworkOperation) {
755
-
dispatchOperation(operation);
756
-
if (prevReplay && !prevReplay.hasNext) prevReplay.stale = true;
753
+
const isNetworkOperation =
754
+
operation.context.requestPolicy === 'cache-and-network' ||
755
+
operation.context.requestPolicy === 'network-only';
756
+
const replay = replays.get(operation.key);
760
-
prevReplay != null &&
761
-
prevReplay === replays.get(operation.key)
763
-
observer.next(prevReplay);
764
-
} else if (!isNetworkOperation) {
758
+
if (operation.kind !== 'query' || !replay || isNetworkOperation) {
dispatchOperation(operation);
769
-
isOperationBatchActive = false;
770
-
observer.complete();
772
-
subscribe(observer.next)
767
+
if (operation.kind === 'query' && replay) {
773
+
if (replay === replays.get(operation.key)) {
774
+
if (isNetworkOperation && !replay.hasNext)
775
+
replay.stale = true;
778
+
if (!isNetworkOperation) dispatchOperation(operation);