apollo-link-queue
apollo-link-queue copied to clipboard
Queue Event Listeners for Queue Persistence + Operation Type Filtering
I've pulled from a couple of other projects to develop a queue persistence package that is working for us in React Native. Here's the changes I made to this package for it to work. Per feedback @helfer gave to others about persistence not belonging in this package I took the approach of using the listeners from another PR and extended it a bit. Then I developed the other package https://github.com/SocialAutoTransport/apollo-link-queue-persist to make use of these changes.
Optional filtering
import QueueLink from 'apollo-link-queue';
const queueLink = new QueueLink();
// Optionally only queue mutations
QueueLink.setFilter(['mutation']);
// To start queueing requests
queueLink.close();
// To let requests pass (and execute all queued requests)
queueLink.open();
Link Queue Event Listeners
Listeners allow for a system outside to be notified when an enqueue or dequeue event occurrs. You can register a listener for a specific operation name or pass the keyword "any" to listen to all operations using the static method QueueLink.addLinkQueueEventListener()
.
QueueLink.addLinkQueueEventListener()
takes the following parameters:
- Operation name to listen to. Valid values are any
or an actual operation name string from the mutation or query you want to be alerted on.
- The enqueue
or dequeue
string to specify which event to listen to,
- A callback function that takes a single parameter which will be the operation from the queue that is being acted upon.
QueueLink.addLinkQueueEventListener("insert_myObject", "enqueue", (item: any) => {
console.log('QueueLink listener (insert_myObject, enqueued) fired with item: ', item);
});
QueueLink.addLinkQueueEventListener("insert_myObject", "dequeue", (item: any) => {
console.log('QueueLink listener (insert_myObject, dequeue) fired with item: ', item);
});
QueueLink.addLinkQueueEventListener("any", "enqueue", (item: any) => {
console.log('QueueLink listener (any, enqueued) fired with item: ', item);
});
QueueLink.addLinkQueueEventListener("any", "dequeue", (item: any) => {
console.log('QueueLink listener (any, dequeue) fired with item: ', item);
});
Usage
import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistQueue, AsyncStorageWrapper } from 'apollo-link-queue-persist';
import QueueLink from 'apollo-link-queue';
import {ApolloClient, InMemoryCache, ApolloProvider, HttpLink, ApolloLink} from '@apollo/client';
const queueLink = new QueueLink();
const client = new ApolloClient({
link: ApolloLink.from([queueLink, httpLink]);,
cache: new InMemoryCache(),
});
await persistQueue({
queueLink,
storage: AsyncStorage,
client,
});
Hi @robnewton, thanks for posting here. If I read your intentions correctly, you're not actually expecting to get this merged, right? Maybe the best thing to do would be to update README.md and link to your package if you think it's ready to be used by others?
I was hoping to have it merged so that I do not need to maintain a separate fork ongoing. Once it’s merged I can update the apollo-link-queue-persist package deps to reference this instead.
The setFilter() doesn't appear to be working correctly as implemented in our fork so I am using the following in the meantime. When I get it fixed in our fork I will follow up, or might just remove it, haven't decided.
// Determine if an operation is a mutation
const isMutationOperation = operation => {
return operation.query.definitions.filter(e => e.operation === 'mutation').length > 0;
};
// Only allow mutations to be queued
const onlyQueueMutationsLink = new ApolloLink((operation, forward) =>
isMutationOperation(operation) ? queueLink.request(operation, forward) : forward(operation),
);
Also as info I've added a couple new features to the queue persist library we are using along side our fork to do queue persistence to Async Storage in React Native. Below is an example showing the new onCompleted and onError functions.
await persistQueue({
queueLink,
storage: AsyncStorage,
client: apolloClient,
onCompleted: (request, response) => {
console.log('Called onCompleted()', request, response);
//Optional request specific handling
if (request.context.customProperty === 'some specific value') {
console.log('Do something specific based on that query or mutation running successfully');
}
},
onError: (request, error) => {
console.error('Called onError()', request, error);
//Optional request specific handling
if (request.context.customProperty === 'some specific value') {
console.error('Do something specific based on that query or mutation failing');
}
}
});
@helfer did you ever give this anymore consideration to merge in?