refactor: use node:path, remove experimental strategies
This commit is contained in:
parent
0c8d5edd77
commit
50c675b4e1
6 changed files with 7 additions and 175 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import { readFile, writeFile, readdir, unlink } from 'node:fs/promises';
|
import { readFile, writeFile, readdir, unlink } from 'node:fs/promises';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
import path from 'pathe';
|
import { resolve, dirname, join } from 'node:path';
|
||||||
import { build } from 'esbuild';
|
import { build } from 'esbuild';
|
||||||
|
|
||||||
const ASTROSW = '@ayco/astro-sw';
|
const ASTROSW = '@ayco/astro-sw';
|
||||||
|
@ -96,7 +96,7 @@ export default function serviceWorker(options) {
|
||||||
registerSW();`
|
registerSW();`
|
||||||
|
|
||||||
let output = 'static';
|
let output = 'static';
|
||||||
const __dirname = path.resolve(path.dirname('.'));
|
const __dirname = resolve(dirname('.'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': ASTROSW,
|
'name': ASTROSW,
|
||||||
|
@ -132,7 +132,7 @@ declare const __prefix: string;`
|
||||||
'astro:build:done': async ({ dir, routes, pages, logger }) => {
|
'astro:build:done': async ({ dir, routes, pages, logger }) => {
|
||||||
const outfile = fileURLToPath(new URL('./sw.js', dir));
|
const outfile = fileURLToPath(new URL('./sw.js', dir));
|
||||||
const swPath = (serviceWorkerPath && serviceWorkerPath !== '')
|
const swPath = (serviceWorkerPath && serviceWorkerPath !== '')
|
||||||
? path.join(__dirname, serviceWorkerPath)
|
? join(__dirname, serviceWorkerPath)
|
||||||
: undefined;
|
: undefined;
|
||||||
let originalScript;
|
let originalScript;
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import node from "@astrojs/node";
|
import node from "@astrojs/node";
|
||||||
import serviceWorker from "./packages/index.js";
|
import serviceWorker from "./astro-sw.js";
|
||||||
import { Strategies } from "./packages/strategies/index.js";
|
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
output: "hybrid",
|
output: "hybrid",
|
||||||
|
@ -34,9 +33,6 @@ export default defineConfig({
|
||||||
console.log('>>> registrered', sw)
|
console.log('>>> registrered', sw)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
experimental: {
|
|
||||||
strategy: Strategies.CacheRevalidatePreloadFallback,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./packages/index.js"
|
"import": "./astro-sw.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"main": "./packages/index.js",
|
"main": "./astro-sw.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
|
@ -38,7 +38,6 @@
|
||||||
"fastify": "^4.28.1"
|
"fastify": "^4.28.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.23.1",
|
"esbuild": "^0.23.1"
|
||||||
"pathe": "^1.1.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
/**
|
|
||||||
* Note: @ayco/astro-sw integration injects variables `__prefix`, `__version`, & `__assets`
|
|
||||||
* -- find usage in `astro.config.mjs` integrations
|
|
||||||
* @see https://ayco.io/n/@ayco/astro-sw
|
|
||||||
*/
|
|
||||||
const cacheName = `${__prefix ?? 'app'}-v${__version ?? '000'}`
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: respect a log config property for logInfo
|
|
||||||
*/
|
|
||||||
|
|
||||||
const cleanOldCaches = async () => {
|
|
||||||
const allowCacheNames = ['cozy-reader', cacheName];
|
|
||||||
const allCaches = await caches.keys();
|
|
||||||
allCaches.forEach(key => {
|
|
||||||
if (!allowCacheNames.includes(key)) {
|
|
||||||
// logInfo('Deleting old cache', {force: !!forceLogging, data: key, context: 'cozy-sw'});
|
|
||||||
caches.delete(key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const addResourcesToCache = async (resources) => {
|
|
||||||
const cache = await caches.open(cacheName);
|
|
||||||
// logInfo('adding resources to cache...', { force: !!forceLogging, context: 'cozy-sw', data: resources })
|
|
||||||
await cache.addAll(resources);
|
|
||||||
};
|
|
||||||
|
|
||||||
const putInCache = async (request, response) => {
|
|
||||||
const cache = await caches.open(cacheName);
|
|
||||||
// logInfo('adding one response to cache...', { force: forceLogging, context: 'cozy-sw', data: request.url })
|
|
||||||
// if exists, replace
|
|
||||||
|
|
||||||
const keys = await cache.keys();
|
|
||||||
if (keys.includes(request)) {
|
|
||||||
cache.delete(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
await cache.put(request, response);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const cacheAndRevalidate = async ({ request, preloadResponsePromise, fallbackUrl }) => {
|
|
||||||
|
|
||||||
const cache = await caches.open(cacheName);
|
|
||||||
|
|
||||||
// Try get the resource from the cache
|
|
||||||
const responseFromCache = await cache.match(request);
|
|
||||||
if (responseFromCache) {
|
|
||||||
// logInfo('using cached response...', { force: forceLogging, context: 'cozy-sw', data: responseFromCache.url })
|
|
||||||
// get network response for revalidation of cached assets
|
|
||||||
fetch(request.clone()).then((responseFromNetwork) => {
|
|
||||||
if (responseFromNetwork) {
|
|
||||||
// logInfo('fetched updated resource...', { force: forceLogging, context: 'cozy-sw', data: responseFromNetwork.url })
|
|
||||||
putInCache(request, responseFromNetwork.clone());
|
|
||||||
}
|
|
||||||
}).catch((error) => {
|
|
||||||
logError('failed to fetch updated resource', { force: forceLogging, context: 'cozy-sw', data: error })
|
|
||||||
});
|
|
||||||
|
|
||||||
return responseFromCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Try to use the preloaded response, if it's there
|
|
||||||
// NOTE: Chrome throws errors regarding preloadResponse, see:
|
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1420515
|
|
||||||
// https://github.com/mdn/dom-examples/issues/145
|
|
||||||
// To avoid those errors, remove or comment out this block of preloadResponse
|
|
||||||
// code along with enableNavigationPreload() and the "activate" listener.
|
|
||||||
const preloadResponse = await preloadResponsePromise;
|
|
||||||
if (preloadResponse) {
|
|
||||||
putInCache(request, preloadResponse.clone());
|
|
||||||
// logInfo('using preload response', { force: forceLogging, context: 'cozy-sw', data: preloadResponse.url })
|
|
||||||
return preloadResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Try to get the resource from the network for 5 seconds
|
|
||||||
const responseFromNetwork = await fetch(request.clone());
|
|
||||||
// response may be used only once
|
|
||||||
// we need to save clone to put one copy in cache
|
|
||||||
// and serve second one
|
|
||||||
putInCache(request, responseFromNetwork.clone());
|
|
||||||
// logInfo('using network response', { force: forceLogging, context: 'cozy-sw', data: responseFromNetwork.url })
|
|
||||||
return responseFromNetwork;
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
|
|
||||||
// Try the fallback
|
|
||||||
const fallbackResponse = await cache.match(fallbackUrl);
|
|
||||||
if (fallbackResponse) {
|
|
||||||
// logInfo('using fallback cached response...', { force: forceLogging, context: 'cozy-sw', data: fallbackResponse.url })
|
|
||||||
return fallbackResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// when even the fallback response is not available,
|
|
||||||
// there is nothing we can do, but we must always
|
|
||||||
// return a Response object
|
|
||||||
return new Response('Network error happened', {
|
|
||||||
status: 408,
|
|
||||||
headers: { 'Content-Type': 'text/plain' },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const enableNavigationPreload = async () => {
|
|
||||||
if (self.registration.navigationPreload) {
|
|
||||||
// Enable navigation preloads!
|
|
||||||
await self.registration.navigationPreload.enable();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const activateFn = (event) => {
|
|
||||||
// logInfo('activating service worker...', { force: forceLogging, context: 'cozy-sw' })
|
|
||||||
cleanOldCaches();
|
|
||||||
event.waitUntil(enableNavigationPreload());
|
|
||||||
};
|
|
||||||
|
|
||||||
const installFn = (event) => {
|
|
||||||
|
|
||||||
// logInfo('installing service worker...', { force: forceLogging, context: 'cozy-sw' })
|
|
||||||
self.skipWaiting(); // go straight to activate
|
|
||||||
|
|
||||||
event.waitUntil(
|
|
||||||
addResourcesToCache(__assets ?? [])
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchFn = (event) => {
|
|
||||||
// logInfo('fetch happened', {data: event});
|
|
||||||
|
|
||||||
event.respondWith(
|
|
||||||
cacheAndRevalidate({
|
|
||||||
request: event.request,
|
|
||||||
preloadResponsePromise: event.preloadResponse,
|
|
||||||
fallbackUrl: './',
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const waitFn = (event) => {}
|
|
||||||
|
|
||||||
export const CacheRevalidatePreloadFallback = {
|
|
||||||
fetchFn,
|
|
||||||
installFn,
|
|
||||||
activateFn,
|
|
||||||
waitFn
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
import { CacheRevalidatePreloadFallback } from "./CacheRevalidatePreloadFallback.js";
|
|
||||||
|
|
||||||
export const Strategies = {
|
|
||||||
CacheRevalidatePreloadFallback
|
|
||||||
}
|
|
|
@ -11,9 +11,6 @@ importers:
|
||||||
esbuild:
|
esbuild:
|
||||||
specifier: ^0.23.1
|
specifier: ^0.23.1
|
||||||
version: 0.23.1
|
version: 0.23.1
|
||||||
pathe:
|
|
||||||
specifier: ^1.1.2
|
|
||||||
version: 1.1.2
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@astrojs/node':
|
'@astrojs/node':
|
||||||
specifier: ^8.3.3
|
specifier: ^8.3.3
|
||||||
|
@ -1667,9 +1664,6 @@ packages:
|
||||||
path-to-regexp@6.2.2:
|
path-to-regexp@6.2.2:
|
||||||
resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
|
resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
|
||||||
|
|
||||||
pathe@1.1.2:
|
|
||||||
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
|
|
||||||
|
|
||||||
picocolors@1.0.1:
|
picocolors@1.0.1:
|
||||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||||
|
|
||||||
|
@ -3932,8 +3926,6 @@ snapshots:
|
||||||
|
|
||||||
path-to-regexp@6.2.2: {}
|
path-to-regexp@6.2.2: {}
|
||||||
|
|
||||||
pathe@1.1.2: {}
|
|
||||||
|
|
||||||
picocolors@1.0.1: {}
|
picocolors@1.0.1: {}
|
||||||
|
|
||||||
picomatch@2.3.1: {}
|
picomatch@2.3.1: {}
|
||||||
|
|
Loading…
Reference in a new issue