import { join } from 'node:path' import { type PluginBuild, build } from 'esbuild' import type { ServiceWorkerBuild } from './dank.ts' export type ServiceWorkerCaching = { cacheKey: string bypassCache?: { hosts?: Array paths?: Array<`/${string}`> } files: Array<`/${string}`> } export async function createServiceWorker( caching: ServiceWorkerCaching, ): Promise { return { outputs: [ { content: await buildServiceWorkerBackend(caching), url: '/sw.js', }, ], } } async function buildServiceWorkerBackend( caching: ServiceWorkerCaching, ): Promise { const result = await build({ logLevel: 'silent', absWorkingDir: join(import.meta.dirname, '../client'), entryPoints: ['ServiceWorker.ts'], treeShaking: true, target: 'ES2022', bundle: true, minify: true, format: 'iife', platform: 'browser', write: false, metafile: true, plugins: [ { name: 'DANK:sw', setup(build: PluginBuild) { build.onResolve({ filter: /DANK:sw/ }, () => { return { path: join(import.meta.dirname, 'DANK.sw.json'), } }) build.onLoad( { filter: /DANK\.sw\.json$/, namespace: 'file' }, async () => ({ contents: JSON.stringify(caching), loader: 'json', }), ) }, }, ], }) return new TextDecoder().decode(result.outputFiles[0].contents) }