apollo-link-queue
Version:
A link to queue requests when a certain condition is met (eg. device is offline)
57 lines (49 loc) • 1.48 kB
text/typescript
import {
ApolloLink,
Operation,
FetchResult,
NextLink,
} from '@apollo/client/link/core';
import {
Observable,
Observer,
} from '@apollo/client/utilities';
interface OperationQueueEntry {
operation: Operation;
forward: NextLink;
observer: Observer<FetchResult>;
subscription?: { unsubscribe: () => void };
}
export default class QueueLink extends ApolloLink {
private opQueue: OperationQueueEntry[] = [];
private isOpen = true;
public open() {
this.isOpen = true;
this.opQueue.forEach(({ operation, forward, observer }) => {
forward(operation).subscribe(observer);
});
this.opQueue = [];
}
public close() {
this.isOpen = false;
}
public request(operation: Operation, forward: NextLink) {
if (this.isOpen) {
return forward(operation);
}
if (operation.getContext().skipQueue) {
return forward(operation);
}
return new Observable<FetchResult>((observer: Observer<FetchResult>) => {
const operationEntry = { operation, forward, observer };
this.enqueue(operationEntry);
return () => this.cancelOperation(operationEntry);
});
}
private cancelOperation(entry: OperationQueueEntry) {
this.opQueue = this.opQueue.filter(e => e !== entry);
}
private enqueue(entry: OperationQueueEntry) {
this.opQueue.push(entry);
}
}