diff --git a/src/serviceworker/src/strategy.ts b/src/serviceworker/src/strategy.ts index d052e5a..949f2cf 100644 --- a/src/serviceworker/src/strategy.ts +++ b/src/serviceworker/src/strategy.ts @@ -1,15 +1,21 @@ export class Strategy { - #cache: Cache - - constructor(cache: Cache) { - this.#cache = cache + private constructor() { + throw new Error( + 'fetch Strategy is not instantiable and only expose static methods', + ) } - cacheFirst({ request, preloadResponse }: Pick) { + static cacheFirst( + cache: Cache, + { request, preloadResponse }: Pick< + FetchEvent, + 'request' | 'preloadResponse' + >, + ) { const fetchRequest = async () => { const response = await fetch(request) if (response.ok) { - this.#cache.put(request, response) + cache.put(request, response) } } @@ -17,22 +23,26 @@ export class Strategy { preloadResponse .then((preload: Response | undefined) => { if (preload?.ok) { - return this.#cache.put(request, preload) + return cache.put(request, preload) } throw new Error() }) // Else fetch request .catch(fetchRequest) - return this.#cache.match(request) + return cache.match(request) } - fastestAndCacheRefresh( - { request, preloadResponse }: Pick, - ac: AbortController = new AbortController() + static fastestAndCacheRefresh( + cache: Cache, + { request, preloadResponse }: Pick< + FetchEvent, + 'request' | 'preloadResponse' + >, + ac: AbortController = new AbortController(), ) { // Get cache or throw - const cachedOrError = this.#cache.match(request) + const cachedOrError = cache.match(request) .then((response) => { if (response) { // Abort network request @@ -43,12 +53,12 @@ export class Strategy { }) // Fetch and cache - const fetchedAndCached = this.networkOnly({ request, preloadResponse}, ac) + const fetchedAndCached = this.networkOnly({ request, preloadResponse }, ac) .then((response) => { // Abort cache request ac.abort() // Update cache - this.#cache.put(request, response.clone()) + cache.put(request, response.clone()) return response }) @@ -56,8 +66,12 @@ export class Strategy { return Promise.race([cachedOrError, fetchedAndCached]) } - async networkFirst( - { request, preloadResponse }: Pick, + static async networkFirst( + cache: Cache, + { request, preloadResponse }: Pick< + FetchEvent, + 'request' | 'preloadResponse' + >, { fallbackUrl, timeout }: { fallbackUrl?: string; timeout?: number }, ) { const signal = timeout ? AbortSignal.timeout(timeout) : undefined @@ -66,7 +80,7 @@ export class Strategy { // Get navigator preload (see: https://developer.mozilla.org/en-US/docs/Web/API/Pick/preloadResponse) const preload = await getPreload(preloadResponse) if (preload?.ok) { - this.#cache.put(request, preload.clone()) + cache.put(request, preload.clone()) return preload } } catch { @@ -74,23 +88,26 @@ export class Strategy { // Else fetch request const response = await fetch(request, { signal }) if (response.ok) { - this.#cache.put(request, response.clone()) + cache.put(request, response.clone()) return response } } catch { // Else return fallback or cached response - return this.#cache.match(fallbackUrl ?? request) + return cache.match(fallbackUrl ?? request) } } } - networkOnly( - { request, preloadResponse }: Pick, - ac: AbortController = new AbortController() + static networkOnly( + { request, preloadResponse }: Pick< + FetchEvent, + 'request' | 'preloadResponse' + >, + ac: AbortController = new AbortController(), ): Promise { // Browser preload const preload = getPreload(preloadResponse, ac) - .then(response => { + .then((response) => { if (response === undefined) { throw new Error(`no preload response for ${request.url}`) } @@ -101,13 +118,13 @@ export class Strategy { // Client fetch const fetched = fetch(request, { signal: ac.signal }) - .then(response => { + .then((response) => { // Cancel preload event ac.abort() return response }) - - return Promise.race([preload, fetched]) + + return Promise.race([preload, fetched]) } }