@arslaan/pwa
Version:
A simple CLI tool to scaffold and generate service worker and manifest files for PWAs using customizable route-based caching strategies.
97 lines (85 loc) • 2.96 kB
JavaScript
// src/generateServiceWorkerFile.ts
/**
* Generates a complete Service Worker file string based on provided caching strategy routes.
* @param config - Object containing arrays of routes for each strategy.
* @returns A string representing the content of the sw.js file.
*/
export function generateServiceWorkerFile(config) {
const { cacheFirstRoutes, networkFirstRoutes, staleWhileRevalidateRoutes } = config;
// Helper to stringify route conditions
const formatRouteConditions = (routes, strategyFn) => {
return routes
.map((route) => ` if (url.pathname.startsWith('${route}')) return ${strategyFn}(event);`)
.join("\n");
};
return `
// ---- Service Worker (Auto-Generated) ----
/**
* Service Worker Install Event - activates immediately.
*/
self.addEventListener('install', (event) => {
self.skipWaiting();
});
/**
* Service Worker Activate Event - takes control of uncontrolled clients.
*/
self.addEventListener('activate', (event) => {
self.clients.claim();
});
/**
* Fetch Event Handler
* Applies caching strategies based on route pattern matching.
*/
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
${formatRouteConditions(cacheFirstRoutes, "cacheFirst")}
${formatRouteConditions(networkFirstRoutes, "networkFirst")}
${formatRouteConditions(staleWhileRevalidateRoutes, "staleWhileRevalidate")}
});
/**
* ---- Caching Strategy Implementations ----
*/
/**
* Cache First Strategy
* Serves from cache if available, otherwise fetches from network and caches it.
*/
async function cacheFirst(event) {
const cache = await caches.open('app-cache');
const cachedResponse = await cache.match(event.request);
if (cachedResponse) return cachedResponse;
const networkResponse = await fetch(event.request);
cache.put(event.request, networkResponse.clone());
return networkResponse;
}
/**
* Network First Strategy
* Tries to fetch from network first; if fails, returns cached version if available.
*/
async function networkFirst(event) {
const cache = await caches.open('app-cache');
try {
const networkResponse = await fetch(event.request);
cache.put(event.request, networkResponse.clone());
return networkResponse;
} catch (error) {
const cachedResponse = await cache.match(event.request);
return cachedResponse || new Response('Network error and no cache.', { status: 503 });
}
}
/**
* Stale While Revalidate Strategy
* Returns cached version immediately while revalidating cache in the background.
*/
async function staleWhileRevalidate(event) {
const cache = await caches.open('app-cache');
const cachedResponse = await cache.match(event.request);
const fetchPromise = fetch(event.request)
.then((networkResponse) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
})
.catch(() => {});
return cachedResponse || fetchPromise;
}
`;
}