Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Queue Event Listeners for Queue Persistence + Operation Type Filtering #39

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

robnewton
Copy link

@robnewton robnewton commented Apr 26, 2021

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,
});

@helfer
Copy link
Owner

helfer commented Apr 28, 2021

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?

@robnewton
Copy link
Author

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.

@robnewton
Copy link
Author

robnewton commented Apr 30, 2021

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');
    }
  }
});

@robnewton
Copy link
Author

@helfer did you ever give this anymore consideration to merge in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants