diff --git a/src/serviceworker/mod.ts b/src/serviceworker/mod.ts index c5768f8..0df7955 100644 --- a/src/serviceworker/mod.ts +++ b/src/serviceworker/mod.ts @@ -8,20 +8,37 @@ import type { JsonValue } from '$std/json/common.ts' // Force load service worker types const self = globalThis as unknown as ServiceWorkerGlobalScope +// global RAM cache +const memory = new Map() + // Pseudo storage API for SW const swStorage = { + __memory: new Map(), async getItem(key: string): Promise { + // RAM cache + if (this.__memory.has(key)) { + return this.__memory.get(key) as T + } + + // FS cache const cache = await caches.open('$SW_STORAGE') const request = new Request(`http://null/${encodeURIComponent(key)}`) const response = await cache.match(request) if (response !== undefined) { - return response.json() + const item = await response.json() + this.__memory.set(key, item) + return item } + this.__memory.set(key, null) return null }, async setItem(key: string, item: T): Promise { + // RAM cache + this.__memory.set(key, item) + + // FS Cache const cache = await caches.open('$SW_STORAGE') const request = new Request(`http://null/${encodeURIComponent(key)}`) const response = Response.json(item) @@ -42,12 +59,22 @@ async function getPreCachedUrls(): Promise { async function getPreCache(): Promise { const version = await swStorage.getItem('$sw.pre-cache.version') + + // Get "cache" from ram + if (memory.has(version)) { + return memory.get(version) as Cache + } + // Get cache from server if (version === null) { await openPreCache() return getPreCache() } - return caches.open(version) + + // Get "cache" from fs + const cache = await caches.open(version) + memory.set(version, cache) + return cache } const IS_SW = 'onpushsubscriptionchange' in self @@ -132,8 +159,17 @@ async function fetchHandler(event: FetchEvent) { // Network only return fetch(event.request) } + async function getDynCache(): Promise { + const lifeTime = 1 * 24 * 3_600 * 1000 //1 day + const now = Date.now() const version = await swStorage.getItem('$sw.dyn-cache.version') + + // Get "cache" from ram + if (memory.has(version)) { + return memory.get(version) + } + // Create cache if (version === null) { await swStorage.setItem('$sw.dyn-cache.version', now + lifeTime) @@ -147,12 +183,22 @@ async function getDynCache(): Promise { return getDynCache() } + // Get "cache" from fs + const cache = await caches.open(version.toString()) + + memory.set(version, cache) return cache } - // Network only - return fetch(event.request) -} +async function updatePreCache(): Promise { + const lifeTime = Date.now() + 1 * 24 * 3_600 * 1000 // 1 day + const now = Date.now() + const memoryKey = 'last-update-pre-cache' + + // Refresh on sw start or 1 times / day + if (memory.get(memoryKey) > now) { + return + } const serverVersion = await getServerPreCacheVersion() const clientVersion = await swStorage.getItem('$sw.pre-cache.version') @@ -164,6 +210,8 @@ async function getDynCache(): Promise { await openPreCache() // Delete old pre-cache caches.delete(clientVersion) + // Update memory + memory.set(memoryKey, lifeTime) } async function getServerPreCacheVersion(): Promise {