Created
November 7, 2024 18:26
-
-
Save bignimbus/ccb1010183447689ac7bc25df022481a to your computer and use it in GitHub Desktop.
Apollo Client TTL example
This file contains hidden or 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
// 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