Skip to content

Instantly share code, notes, and snippets.

@bignimbus
Created November 7, 2024 18:26
Show Gist options
  • Save bignimbus/ccb1010183447689ac7bc25df022481a to your computer and use it in GitHub Desktop.
Save bignimbus/ccb1010183447689ac7bc25df022481a to your computer and use it in GitHub Desktop.
Apollo Client TTL example
// credit: Ben Newman
// a possible workaround is to store the timestamp info in the field using field policy merge and read functions:
new InMemoryCache({
typePolicies: {
SomeType: {
fields: {
theField: {
read(existing) {
if (existing && existing.storageTime) {
const elapsedMillis = Date.now() - existing.storageTime;
if (elapsedMillis > YOUR_DESIRED_TTL) {
// Returning undefined indicates field is missing
// Here might be a good place to schedule eviction (not automatic)
return;
}
}
// If there's nothing in the cache for this field yet, existing will be undefined,
// so the read function will (correctly) return undefined here:
return existing && existing.value;
},
merge(existing, incoming, { mergeObjects }) {
// Instead of storing incoming as-is, we store a { value, storageTime } object
return {
value: existing ? mergeObjects(existing, incoming) : incoming,
storageTime: Date.now(),
};
},
},
},
},
})
// ideally you could use a helper function to simplify applying this logic to multiple fields:
new InMemoryCache({
typePolicies: {
SomeType: {
fields: {
theField: makeTTLFieldPolicy(YOUR_DESIRED_TTL),
anotherField: makeTTLFieldPolicy(2 * YOUR_DESIRED_TTL),
// ... and so on ...
},
},
},
})
// where makeTTLFieldPolicy is something like
function makeTTLFieldPolicy(maxElapsedMillis) {
return {
read(existing) {
if (existing && existing.storageTime) {
const elapsedMillis = Date.now() - existing.storageTime;
if (elapsedMillis > maxElapsedMillis) {
return;
}
}
return existing && existing.value;
},
merge(existing, incoming, { mergeObjects }) {
return {
value: existing ? mergeObjects(existing, incoming) : incoming,
storageTime: Date.now(),
};
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment