Add cache option to api Vuex action.

It allows the caching and retrieval of requests using Cache API.
This commit is contained in:
D. Berge
2025-07-27 10:47:57 +02:00
parent c2eb82ffe7
commit b80b8ffb52

View File

@@ -1,4 +1,22 @@
/** Make an API request
*
* @a resource {String} is the target URL
* @a init {Object} are the Fetch options
* @a cb {Function} is a callback function: (res, err) => {}
* @a opts {Object} are other optional parameters:
* opts.silent {Boolean} controls whether snack messages are shown on failure
* opts.cache {Object} controls whether Cache API is used
* opts.cache.name {String} is the name of the cache to use. Defaults to "dougal"
*
* If Cache API is used, this function looks for a matching request in the cache
* first, and returns it if found. If not found, it makes the request over the API
* and then stores it in the cache.
*
* `opts.cache` may also be `true` (defaults to using the "dougal" cache),
* a cache name (equivalent to {name: "…"}) or even an empty object (equivalent
* to `true`).
*/
async function api ({state, getters, commit, dispatch}, [resource, init = {}, cb, opts = {}]) {
try {
commit("queueRequest");
@@ -21,14 +39,46 @@ async function api ({state, getters, commit, dispatch}, [resource, init = {}, cb
init.body = JSON.stringify(init.body);
}
const url = /^https?:\/\//i.test(resource) ? resource : (state.apiUrl + resource);
const res = await fetch(url, init);
let res; // The response
let cache; // Potentially, a Cache API cache name
let isCached;
if (opts?.cache === true) {
opts.cache = { name: "dougal" };
} else if (typeof opts?.cache === "string") {
opts.cache = { name: opts.cache };
} else if (opts?.cache) {
if (!(opts.cache instanceof Object)) {
opts.cache = { name: "dougal" }
} else if (!(opts.cache.name)) {
opts.cache.name = "dougal";
}
}
if (opts?.cache) {
cache = await caches.open(opts.cache.name);
res = await cache.match(url);
isCached = !!res;
}
if (!res) {
res = await fetch(url, init);
}
if (cache && !isCached) {
cache.put(url, res.clone());
}
if (typeof cb === 'function') {
await cb(null, res);
}
if (res.ok) {
if (!isCached) {
await dispatch('setCredentials');
}
try {
if (!res.bodyUsed) { // It may have been consumed by a callback