Changeset View
Changeset View
Standalone View
Standalone View
web/cashtab/src/serviceWorker.js
import { clientsClaim } from 'workbox-core'; | import { clientsClaim } from 'workbox-core'; | ||||
import { setCacheNameDetails } from 'workbox-core'; | import { setCacheNameDetails } from 'workbox-core'; | ||||
import { precacheAndRoute } from 'workbox-precaching'; | import { precacheAndRoute } from 'workbox-precaching'; | ||||
import { registerRoute } from 'workbox-routing'; | import { registerRoute } from 'workbox-routing'; | ||||
import { CacheFirst } from 'workbox-strategies'; | import { CacheFirst } from 'workbox-strategies'; | ||||
import { CacheableResponsePlugin } from 'workbox-cacheable-response'; | |||||
import { ExpirationPlugin } from 'workbox-expiration'; | import { ExpirationPlugin } from 'workbox-expiration'; | ||||
clientsClaim(); | clientsClaim(); | ||||
self.skipWaiting(); | self.skipWaiting(); | ||||
// cofingure prefix, suffix, and cacheNames | // cofingure prefix, suffix, and cacheNames | ||||
const prefix = 'cashtab'; | const prefix = 'cashtab'; | ||||
const suffix = 'v1.0.0'; | const suffix = 'v1.0.1'; | ||||
const staticAssetsCache = `static-assets`; | const staticAssetsCache = `static-assets`; | ||||
// configure prefix and suffix for default cache names | // configure prefix and suffix for default cache names | ||||
setCacheNameDetails({ | setCacheNameDetails({ | ||||
prefix: prefix, | prefix: prefix, | ||||
suffix: suffix, | suffix: suffix, | ||||
precache: staticAssetsCache, | precache: staticAssetsCache, | ||||
}); | }); | ||||
// injection point for static assets caching | // injection point for static assets caching | ||||
precacheAndRoute(self.__WB_MANIFEST); | precacheAndRoute(self.__WB_MANIFEST); | ||||
// A response is only cacheable if | |||||
// - status code is 200 | |||||
// - it has a blockhash - meaning it has been confirmed | |||||
const isResponseCacheable = async ( | |||||
response, | |||||
checkResponseDataForCacheableConditons, | |||||
) => { | |||||
// TODO: add error checking | |||||
// response must be of type Response | |||||
// checkResponseDataForCacheableConditons() must be a function | |||||
let cachable = false; | |||||
if (response && response.status === 200) { | |||||
const clonedResponse = response.clone(); | |||||
const clonedResponseData = await clonedResponse.json(); | |||||
if (checkResponseDataForCacheableConditons(clonedResponseData)) { | |||||
cachable = true; | |||||
} | |||||
} | |||||
return cachable; | |||||
}; | |||||
const createCustomPlugin = checkResponseDataForCacheableConditons => { | |||||
return { | |||||
cacheWillUpdate: async ({ response }) => { | |||||
const cacheable = await isResponseCacheable( | |||||
response, | |||||
checkResponseDataForCacheableConditons, | |||||
); | |||||
if (cacheable) { | |||||
return response; | |||||
} | |||||
return null; | |||||
}, | |||||
}; | |||||
}; | |||||
const blockhashExistsInTxResponse = responseBodyJson => { | |||||
return responseBodyJson && responseBodyJson.blockhash; | |||||
}; | |||||
const blockhashExistsInSlpTxResponse = responseBodyJson => { | |||||
return ( | |||||
responseBodyJson && | |||||
responseBodyJson.retData && | |||||
responseBodyJson.retData.blockhash | |||||
); | |||||
}; | |||||
// Caching TX and Token Details using CacheFirst Strategy | // Caching TX and Token Details using CacheFirst Strategy | ||||
const txDetailsCaches = [ | const txDetailsCaches = [ | ||||
{ | { | ||||
// ecash tx | // ecash tx | ||||
path: '/rawtransactions/getRawTransaction/', | path: '/rawtransactions/getRawTransaction/', | ||||
name: `${prefix}-tx-data-${suffix}`, | name: `${prefix}-tx-data-${suffix}`, | ||||
customPlugin: createCustomPlugin(blockhashExistsInTxResponse), | |||||
}, | }, | ||||
{ | { | ||||
// slp tx | // slp tx | ||||
path: '/slp/txDetails/', | path: '/slp/txDetails/', | ||||
name: `${prefix}-slp-tx-data-${suffix}`, | name: `${prefix}-slp-tx-data-${suffix}`, | ||||
}, | customPlugin: createCustomPlugin(blockhashExistsInSlpTxResponse), | ||||
{ | |||||
// slp token | |||||
path: '/slp/tokenStats/', | |||||
name: `${prefix}-slp-token-stats-${suffix}`, | |||||
}, | }, | ||||
]; | ]; | ||||
txDetailsCaches.forEach(cache => { | txDetailsCaches.forEach(cache => { | ||||
registerRoute( | registerRoute( | ||||
({ url }) => url.pathname.includes(cache.path), | ({ url }) => url.pathname.includes(cache.path), | ||||
new CacheFirst({ | new CacheFirst({ | ||||
cacheName: cache.name, | cacheName: cache.name, | ||||
plugins: [ | plugins: [ | ||||
new CacheableResponsePlugin({ | cache.customPlugin, | ||||
statuses: [200], | |||||
}), | |||||
new ExpirationPlugin({ | new ExpirationPlugin({ | ||||
maxEntries: 1000, | maxEntries: 1000, | ||||
maxAgeSeconds: 365 * 24 * 60 * 60, | maxAgeSeconds: 365 * 24 * 60 * 60, | ||||
}), | }), | ||||
], | ], | ||||
}), | }), | ||||
); | ); | ||||
}); | }); |