-
-
Save noeljackson/c6bbab569ab774299d7937b19c838dbb to your computer and use it in GitHub Desktop.
Sketch of an implementation for a possible apollo-link-offline module with similar behavior to apollo-offline.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ApolloLink } from 'apollo-link' | |
import QueueLink from 'apollo-link-queue' | |
import { RetryLink } from 'apollo-link-retry' | |
import { NetInfo } from 'react-native' | |
import Observable from 'zen-observable' | |
export function createOfflineLink({ cache }) { | |
const retryLink = new RetryLink({ | |
attempts: { | |
max: Infinity, | |
retryIf(error, operation) { | |
const cachedResponse = cache.readQuery({ | |
query: operation.query, | |
variables: operation.variables, | |
}) | |
return !!error && cachedResponse == null | |
}, | |
}, | |
}) | |
const queueLink = new QueueLink() | |
NetInfo.addEventListener('connectionChange', event => { | |
if (isOnline(event.type)) { | |
queueLink.open() | |
} else { | |
queueLink.close() | |
} | |
}) | |
function isOnline(connectionType) { | |
return connectionType !== 'none' && connectionType !== 'unknown' | |
} | |
const optimisticFetchLink = new ApolloLink((operation, forward) => { | |
return new Observable(observer => { | |
forward(operation).subscribe({ | |
// Don't do anything with normal responses. | |
next: response => observer.next(response), | |
error: error => { | |
if (error.message === 'Network request failed') { | |
// The response may already be persisted in the cache - if so, there | |
// is no need to throw. Instead, just resolve with the cached data. | |
const cachedResponse = cache.readQuery({ | |
query: operation.query, | |
variables: operation.variables, | |
}) | |
if (cachedResponse != null) { | |
observer.next({ data: cachedResponse }) | |
} else { | |
observer.error(error) | |
} | |
} else { | |
// Don't do anything with any other error. | |
observer.error(error) | |
} | |
}, | |
}) | |
}) | |
}) | |
return ApolloLink.from([optimisticFetchLink, retryLink, queueLink]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment