diff --git a/lib/client-bundle-plugin.js b/lib/client-bundle-plugin.js index 06b69615..679b5e43 100644 --- a/lib/client-bundle-plugin.js +++ b/lib/client-bundle-plugin.js @@ -20,6 +20,7 @@ const allSrcPlaceholder = 'CLIENT_BUNDLE_PLUGIN_ALL_SRC'; export function getDependencies(clientOutput, item) { const crawlDependencies = new Set([item.fileName]); + const referencedFiles = new Set(); for (const fileName of crawlDependencies) { const chunk = clientOutput.find((v) => v.fileName === fileName); @@ -27,11 +28,23 @@ export function getDependencies(clientOutput, item) { for (const dep of chunk.imports) { crawlDependencies.add(dep); } + + for (const dep of chunk.referencedFiles) { + referencedFiles.add(dep); + } } // Don't add self as dependency crawlDependencies.delete(item.fileName); + // Merge referencedFiles as regular deps. + // + // Didn't do this as part of the main loop since their `chunk` can't have + // nested deps and sometimes might be missing altogether, depending on type. + for (const dep of referencedFiles) { + crawlDependencies.add(dep); + } + return [...crawlDependencies]; } @@ -139,9 +152,9 @@ export default function (inputOptions, outputOptions, resolveFileUrl) { if (property.startsWith(allSrcPlaceholder)) { const allModules = [ clientEntry, - ...dependencies.map((name) => - clientOutput.find((item) => item.fileName === name), - ), + ...dependencies + .map((name) => clientOutput.find((item) => item.fileName === name)) + .filter((item) => item.code), ]; const inlineDefines = [ diff --git a/lib/entry-data-plugin.js b/lib/entry-data-plugin.js index 5316438e..91d96595 100644 --- a/lib/entry-data-plugin.js +++ b/lib/entry-data-plugin.js @@ -17,10 +17,14 @@ const prefix = 'entry-data:'; const mainNamePlaceholder = 'ENTRY_DATA_PLUGIN_MAIN_NAME'; const dependenciesPlaceholder = 'ENTRY_DATA_PLUGIN_DEPS'; const placeholderRe = /(ENTRY_DATA_PLUGIN_(?:MAIN_NAME|DEPS))(\d+)/g; -const filenamePrefix = 'static/'; + +/** @param {string} fileName */ +export function fileNameToURL(fileName) { + return fileName.replace(/^static\//, '/'); +} export default function entryDataPlugin() { - /** @type {string} */ + /** @type {number} */ let exportCounter; /** @type {Map} */ let counterToIdMap; @@ -69,15 +73,11 @@ export default function entryDataPlugin() { if (!chunk) throw Error(`Cannot find ${id}`); if (placeholder === mainNamePlaceholder) { - return JSON.stringify( - chunk.fileName.slice(filenamePrefix.length), - ); + return JSON.stringify(fileNameToURL(chunk.fileName)); } return JSON.stringify( - getDependencies(chunks, chunk).map((item) => - item.slice(filenamePrefix.length), - ), + getDependencies(chunks, chunk).map(fileNameToURL), ); }, ); diff --git a/missing-types.d.ts b/missing-types.d.ts index 0444a321..2adaaa15 100644 --- a/missing-types.d.ts +++ b/missing-types.d.ts @@ -44,6 +44,11 @@ declare module 'data-url:*' { export default url; } +declare module 'service-worker:*' { + const url: string; + export default url; +} + declare var ga: { (...args: any[]): void; q: any[]; diff --git a/package-lock.json b/package-lock.json index b1f2f78f..1200eb72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -179,9 +179,9 @@ } }, "@surma/rollup-plugin-off-main-thread": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.1.tgz", - "integrity": "sha512-7OU8wfyv18YPWVmecg2/0Jh+pm3lQbvPhIWHd1YQpoxPKPW/vsDNGBaCnMKsZbz29RjgCoXKugAjyagPncgdEw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.2.tgz", + "integrity": "sha512-dOD6nGZ79RmWKDRQuC7SOGXMvDkkLwBogu+epfVFMKiy2kOUtLZkb8wV/ettuMt37YJAJKYCKUmxSbZL2LkUQg==", "dev": true, "requires": { "ejs": "^3.1.6", @@ -7183,9 +7183,9 @@ "dev": true }, "wasm-feature-detect": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.9.tgz", - "integrity": "sha512-2E9/gtLVLpv2wnZDyYv8WY2dR9gHbmyv5uhZsnOcMSzqc78aGZpKQORPNcnrPwAU23nFUo7GAwKuoTAWRgsJ7Q==" + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.2.11.tgz", + "integrity": "sha512-HUqwaodrQGaZgz1lZaNioIkog9tkeEJjrM3eq4aUL04whXOVDRc/o2EGb/8kV0QX411iAYWEqq7fMBmJ6dKS6w==" }, "which": { "version": "2.0.2", diff --git a/package.json b/package.json index 4e20b856..5ed11038 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-node-resolve": "^11.1.0", "@rollup/plugin-replace": "^2.3.4", - "@surma/rollup-plugin-off-main-thread": "^2.2.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.2", "@types/dedent": "^0.7.0", "@types/mime-types": "^2.1.0", "@types/node": "^14.14.7", @@ -58,6 +58,6 @@ "*.rs": "rustfmt" }, "dependencies": { - "wasm-feature-detect": "^1.2.9" + "wasm-feature-detect": "^1.2.11" } } diff --git a/rollup.config.js b/rollup.config.js index 37d3865b..815c65ad 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -18,6 +18,7 @@ import commonjs from '@rollup/plugin-commonjs'; import { terser } from 'rollup-plugin-terser'; import OMT from '@surma/rollup-plugin-off-main-thread'; import replace from '@rollup/plugin-replace'; +import { importMetaAssets } from '@web/rollup-plugin-import-meta-assets'; import simpleTS from './lib/simple-ts'; import clientBundlePlugin from './lib/client-bundle-plugin'; @@ -31,10 +32,10 @@ import featurePlugin from './lib/feature-plugin'; import initialCssPlugin from './lib/initial-css-plugin'; import serviceWorkerPlugin from './lib/sw-plugin'; import dataURLPlugin from './lib/data-url-plugin'; -import entryDataPlugin from './lib/entry-data-plugin'; +import entryDataPlugin, { fileNameToURL } from './lib/entry-data-plugin'; function resolveFileUrl({ fileName }) { - return JSON.stringify(fileName.replace(/^static\//, '/')); + return JSON.stringify(fileNameToURL(fileName)); } const dir = '.tmp/build'; @@ -106,6 +107,7 @@ export default async function ({ watch }) { plugins: [ { resolveFileUrl }, OMT({ loader: await omtLoaderPromise }), + importMetaAssets(), serviceWorkerPlugin({ output: 'static/serviceworker.js', }), diff --git a/src/client/missing-types.d.ts b/src/client/missing-types.d.ts index d25cdf43..bad86b28 100644 --- a/src/client/missing-types.d.ts +++ b/src/client/missing-types.d.ts @@ -19,9 +19,4 @@ interface Navigator { declare module 'add-css:*' {} -declare module 'service-worker:*' { - const url: string; - export default url; -} - declare module 'preact/debug' {} diff --git a/src/features/decoders/avif/worker/avifDecode.ts b/src/features/decoders/avif/worker/avifDecode.ts index acb6a252..5e70be21 100644 --- a/src/features/decoders/avif/worker/avifDecode.ts +++ b/src/features/decoders/avif/worker/avifDecode.ts @@ -11,7 +11,6 @@ * limitations under the License. */ import type { AVIFModule } from 'codecs/avif/dec/avif_dec'; -import wasmUrl from 'url:codecs/avif/dec/avif_dec.wasm'; import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils'; let emscriptenModule: Promise; @@ -19,7 +18,7 @@ let emscriptenModule: Promise; export default async function decode(blob: Blob): Promise { if (!emscriptenModule) { const decoder = await import('codecs/avif/dec/avif_dec'); - emscriptenModule = initEmscriptenModule(decoder.default, wasmUrl); + emscriptenModule = initEmscriptenModule(decoder.default); } const [module, data] = await Promise.all([ diff --git a/src/features/decoders/jxl/worker/jxlDecode.ts b/src/features/decoders/jxl/worker/jxlDecode.ts index 1df498b9..6a8f96e7 100644 --- a/src/features/decoders/jxl/worker/jxlDecode.ts +++ b/src/features/decoders/jxl/worker/jxlDecode.ts @@ -11,14 +11,13 @@ * limitations under the License. */ import jxlDecoder, { JXLModule } from 'codecs/jxl/dec/jxl_dec'; -import wasmUrl from 'url:codecs/jxl/dec/jxl_dec.wasm'; import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils'; let emscriptenModule: Promise; export default async function decode(blob: Blob): Promise { if (!emscriptenModule) { - emscriptenModule = initEmscriptenModule(jxlDecoder, wasmUrl); + emscriptenModule = initEmscriptenModule(jxlDecoder); } const [module, data] = await Promise.all([ diff --git a/src/features/decoders/webp/worker/webpDecode.ts b/src/features/decoders/webp/worker/webpDecode.ts index 3026be51..29bd4e43 100644 --- a/src/features/decoders/webp/worker/webpDecode.ts +++ b/src/features/decoders/webp/worker/webpDecode.ts @@ -11,7 +11,6 @@ * limitations under the License. */ import type { WebPModule } from 'codecs/webp/dec/webp_dec'; -import wasmUrl from 'url:codecs/webp/dec/webp_dec.wasm'; import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils'; let emscriptenModule: Promise; @@ -19,7 +18,7 @@ let emscriptenModule: Promise; export default async function decode(blob: Blob): Promise { if (!emscriptenModule) { const decoder = await import('codecs/webp/dec/webp_dec'); - emscriptenModule = initEmscriptenModule(decoder.default, wasmUrl); + emscriptenModule = initEmscriptenModule(decoder.default); } const [module, data] = await Promise.all([ diff --git a/src/features/decoders/wp2/worker/wp2Decode.ts b/src/features/decoders/wp2/worker/wp2Decode.ts index a8ed56b2..7a37f449 100644 --- a/src/features/decoders/wp2/worker/wp2Decode.ts +++ b/src/features/decoders/wp2/worker/wp2Decode.ts @@ -11,14 +11,13 @@ * limitations under the License. */ import wp2Decoder, { WP2Module } from 'codecs/wp2/dec/wp2_dec'; -import wasmUrl from 'url:codecs/wp2/dec/wp2_dec.wasm'; import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils'; let emscriptenModule: Promise; export default async function decode(blob: Blob): Promise { if (!emscriptenModule) { - emscriptenModule = initEmscriptenModule(wp2Decoder, wasmUrl); + emscriptenModule = initEmscriptenModule(wp2Decoder); } const [module, data] = await Promise.all([ diff --git a/src/features/encoders/avif/worker/avifEncode.ts b/src/features/encoders/avif/worker/avifEncode.ts index c5103c2b..94f828b7 100644 --- a/src/features/encoders/avif/worker/avifEncode.ts +++ b/src/features/encoders/avif/worker/avifEncode.ts @@ -12,9 +12,6 @@ */ import type { AVIFModule } from 'codecs/avif/enc/avif_enc'; import type { EncodeOptions } from '../shared/meta'; -import wasmUrlWithoutMT from 'url:codecs/avif/enc/avif_enc.wasm'; -import wasmUrlWithMT from 'url:codecs/avif/enc/avif_enc_mt.wasm'; -import workerUrl from 'omt:codecs/avif/enc/avif_enc_mt.worker.js'; import { initEmscriptenModule } from 'features/worker-utils'; import { threads } from 'wasm-feature-detect'; @@ -23,14 +20,10 @@ let emscriptenModule: Promise; async function init() { if (await threads()) { const avifEncoder = await import('codecs/avif/enc/avif_enc_mt'); - return initEmscriptenModule( - avifEncoder.default, - wasmUrlWithMT, - workerUrl, - ); + return initEmscriptenModule(avifEncoder.default); } const avifEncoder = await import('codecs/avif/enc/avif_enc.js'); - return initEmscriptenModule(avifEncoder.default, wasmUrlWithoutMT); + return initEmscriptenModule(avifEncoder.default); } export default async function encode( diff --git a/src/features/encoders/jxl/worker/jxlEncode.ts b/src/features/encoders/jxl/worker/jxlEncode.ts index 0378c2a7..02a0f19c 100644 --- a/src/features/encoders/jxl/worker/jxlEncode.ts +++ b/src/features/encoders/jxl/worker/jxlEncode.ts @@ -16,31 +16,19 @@ import type { EncodeOptions } from '../shared/meta'; import { initEmscriptenModule } from 'features/worker-utils'; import { threads, simd } from 'wasm-feature-detect'; -import wasmUrl from 'url:codecs/jxl/enc/jxl_enc.wasm'; - -import wasmUrlWithMT from 'url:codecs/jxl/enc/jxl_enc_mt.wasm'; -import workerUrl from 'omt:codecs/jxl/enc/jxl_enc_mt.worker.js'; - -import wasmUrlWithMTAndSIMD from 'url:codecs/jxl/enc/jxl_enc_mt_simd.wasm'; -import workerUrlWithSIMD from 'omt:codecs/jxl/enc/jxl_enc_mt_simd.worker.js'; - let emscriptenModule: Promise; async function init() { if (await threads()) { if (await simd()) { const jxlEncoder = await import('codecs/jxl/enc/jxl_enc_mt_simd'); - return initEmscriptenModule( - jxlEncoder.default, - wasmUrlWithMTAndSIMD, - workerUrlWithSIMD, - ); + return initEmscriptenModule(jxlEncoder.default); } const jxlEncoder = await import('codecs/jxl/enc/jxl_enc_mt'); - return initEmscriptenModule(jxlEncoder.default, wasmUrlWithMT, workerUrl); + return initEmscriptenModule(jxlEncoder.default); } const jxlEncoder = await import('codecs/jxl/enc/jxl_enc'); - return initEmscriptenModule(jxlEncoder.default, wasmUrl); + return initEmscriptenModule(jxlEncoder.default); } export default async function encode( diff --git a/src/features/encoders/mozJPEG/worker/mozjpegEncode.ts b/src/features/encoders/mozJPEG/worker/mozjpegEncode.ts index 4cc8b699..949999a9 100644 --- a/src/features/encoders/mozJPEG/worker/mozjpegEncode.ts +++ b/src/features/encoders/mozJPEG/worker/mozjpegEncode.ts @@ -12,7 +12,6 @@ */ import mozjpeg_enc, { MozJPEGModule } from 'codecs/mozjpeg/enc/mozjpeg_enc'; import { EncodeOptions } from '../shared/meta'; -import wasmUrl from 'url:codecs/mozjpeg/enc/mozjpeg_enc.wasm'; import { initEmscriptenModule } from 'features/worker-utils'; let emscriptenModule: Promise; @@ -22,7 +21,7 @@ export default async function encode( options: EncodeOptions, ): Promise { if (!emscriptenModule) { - emscriptenModule = initEmscriptenModule(mozjpeg_enc, wasmUrl); + emscriptenModule = initEmscriptenModule(mozjpeg_enc); } const module = await emscriptenModule; diff --git a/src/features/encoders/oxiPNG/worker/oxipngEncode.ts b/src/features/encoders/oxiPNG/worker/oxipngEncode.ts index 558f5498..c71525ea 100644 --- a/src/features/encoders/oxiPNG/worker/oxipngEncode.ts +++ b/src/features/encoders/oxiPNG/worker/oxipngEncode.ts @@ -10,30 +10,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import initOxiWasmST, { - optimise as optimiseST, -} from 'codecs/oxipng/pkg/squoosh_oxipng'; -import initOxiWasmMT, { - initThreadPool, - optimise as optimiseMT, -} from 'codecs/oxipng/pkg-parallel/squoosh_oxipng'; -import oxiWasmUrlST from 'url:codecs/oxipng/pkg/squoosh_oxipng_bg.wasm'; -import oxiWasmUrlMT from 'url:codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm'; import { EncodeOptions } from '../shared/meta'; import { threads } from 'wasm-feature-detect'; async function initMT() { - await initOxiWasmMT(oxiWasmUrlMT); + const { default: init, initThreadPool, optimise } = await import( + 'codecs/oxipng/pkg-parallel/squoosh_oxipng' + ); + await init(); await initThreadPool(navigator.hardwareConcurrency); - return optimiseMT; + return optimise; } async function initST() { - await initOxiWasmST(oxiWasmUrlST); - return optimiseST; + const { default: init, optimise } = await import( + 'codecs/oxipng/pkg/squoosh_oxipng' + ); + await init(); + return optimise; } -let wasmReady: Promise; +let wasmReady: ReturnType; export default async function encode( data: ArrayBuffer, diff --git a/src/features/encoders/webP/worker/webpEncode.ts b/src/features/encoders/webP/worker/webpEncode.ts index 035c166d..14d6f755 100644 --- a/src/features/encoders/webP/worker/webpEncode.ts +++ b/src/features/encoders/webP/worker/webpEncode.ts @@ -16,18 +16,15 @@ import type { EncodeOptions } from '../shared/meta'; import { initEmscriptenModule } from 'features/worker-utils'; import { simd } from 'wasm-feature-detect'; -import wasmUrl from 'url:codecs/webp/enc/webp_enc.wasm'; -import wasmUrlWithSIMD from 'url:codecs/webp/enc/webp_enc_simd.wasm'; - let emscriptenModule: Promise; async function init() { if (await simd()) { const webpEncoder = await import('codecs/webp/enc/webp_enc_simd'); - return initEmscriptenModule(webpEncoder.default, wasmUrlWithSIMD); + return initEmscriptenModule(webpEncoder.default); } const webpEncoder = await import('codecs/webp/enc/webp_enc'); - return initEmscriptenModule(webpEncoder.default, wasmUrl); + return initEmscriptenModule(webpEncoder.default); } export default async function encode( diff --git a/src/features/encoders/wp2/worker/wp2Encode.ts b/src/features/encoders/wp2/worker/wp2Encode.ts index 1c12573b..f6d9c0fd 100644 --- a/src/features/encoders/wp2/worker/wp2Encode.ts +++ b/src/features/encoders/wp2/worker/wp2Encode.ts @@ -16,31 +16,19 @@ import type { EncodeOptions } from '../shared/meta'; import { initEmscriptenModule } from 'features/worker-utils'; import { threads, simd } from 'wasm-feature-detect'; -import wasmUrl from 'url:codecs/wp2/enc/wp2_enc.wasm'; - -import wasmUrlWithMT from 'url:codecs/wp2/enc/wp2_enc_mt.wasm'; -import workerUrl from 'omt:codecs/wp2/enc/wp2_enc_mt.worker.js'; - -import wasmUrlWithMTAndSIMD from 'url:codecs/wp2/enc/wp2_enc_mt_simd.wasm'; -import workerUrlWithSIMD from 'omt:codecs/wp2/enc/wp2_enc_mt_simd.worker.js'; - let emscriptenModule: Promise; async function init() { if (await threads()) { if (await simd()) { const wp2Encoder = await import('codecs/wp2/enc/wp2_enc_mt_simd'); - return initEmscriptenModule( - wp2Encoder.default, - wasmUrlWithMTAndSIMD, - workerUrlWithSIMD, - ); + return initEmscriptenModule(wp2Encoder.default); } const wp2Encoder = await import('codecs/wp2/enc/wp2_enc_mt'); - return initEmscriptenModule(wp2Encoder.default, wasmUrlWithMT, workerUrl); + return initEmscriptenModule(wp2Encoder.default); } const wp2Encoder = await import('codecs/wp2/enc/wp2_enc'); - return initEmscriptenModule(wp2Encoder.default, wasmUrl); + return initEmscriptenModule(wp2Encoder.default); } export default async function encode( diff --git a/src/features/processors/quantize/worker/quantize.ts b/src/features/processors/quantize/worker/quantize.ts index c62c02ee..009e360e 100644 --- a/src/features/processors/quantize/worker/quantize.ts +++ b/src/features/processors/quantize/worker/quantize.ts @@ -11,7 +11,6 @@ * limitations under the License. */ import imagequant, { QuantizerModule } from 'codecs/imagequant/imagequant'; -import wasmUrl from 'url:codecs/imagequant/imagequant.wasm'; import { initEmscriptenModule } from 'features/worker-utils'; import { Options } from '../shared/meta'; @@ -22,7 +21,7 @@ export default async function process( opts: Options, ): Promise { if (!emscriptenModule) { - emscriptenModule = initEmscriptenModule(imagequant, wasmUrl); + emscriptenModule = initEmscriptenModule(imagequant); } const module = await emscriptenModule; diff --git a/src/features/processors/resize/worker/resize.ts b/src/features/processors/resize/worker/resize.ts index 72fc8ab8..dc6c8338 100644 --- a/src/features/processors/resize/worker/resize.ts +++ b/src/features/processors/resize/worker/resize.ts @@ -1,8 +1,6 @@ import type { WorkerResizeOptions } from '../shared/meta'; import { getContainOffsets } from '../shared/util'; import initResizeWasm, { resize as wasmResize } from 'codecs/resize/pkg'; -import resizeWasmUrl from 'url:codecs/resize/pkg/squoosh_resize_bg.wasm'; -import hqxWasmUrl from 'url:codecs/hqx/pkg/squooshhqx_bg.wasm'; import initHqxWasm, { resize as wasmHqx } from 'codecs/hqx/pkg'; interface HqxResizeOptions extends WorkerResizeOptions { @@ -63,7 +61,7 @@ async function hqx( opts: HqxResizeOptions, ): Promise { if (!hqxWasmReady) { - hqxWasmReady = initHqxWasm(hqxWasmUrl); + hqxWasmReady = initHqxWasm(); } await hqxWasmReady; @@ -96,7 +94,7 @@ export default async function resize( let input = data; if (!resizeWasmReady) { - resizeWasmReady = initResizeWasm(resizeWasmUrl); + resizeWasmReady = initResizeWasm(); } if (optsIsHqxOpts(opts)) { diff --git a/src/features/worker-utils/index.ts b/src/features/worker-utils/index.ts index f1fea6df..72113d95 100644 --- a/src/features/worker-utils/index.ts +++ b/src/features/worker-utils/index.ts @@ -12,17 +12,10 @@ */ export function initEmscriptenModule( moduleFactory: EmscriptenWasm.ModuleFactory, - wasmUrl: string, - workerUrl?: string, ): Promise { return moduleFactory({ // Just to be safe, don't automatically invoke any wasm functions noInitialRun: true, - locateFile: (url: string) => { - if (url.endsWith('.wasm')) return wasmUrl; - if (url.endsWith('.worker.js')) return workerUrl!; - throw Error('Unknown url in locateFile ' + url); - }, }); } diff --git a/src/sw/index.ts b/src/sw/index.ts index 66ca403a..266f2c55 100644 --- a/src/sw/index.ts +++ b/src/sw/index.ts @@ -7,6 +7,7 @@ import { serveShareTarget, } from './util'; import { get } from 'idb-keyval'; +import { shouldCacheDynamically } from './to-cache'; // Give TypeScript the correct global. declare var self: ServiceWorkerGlobalScope; @@ -70,7 +71,7 @@ self.addEventListener('fetch', (event) => { // We only care about GET from here on in. if (event.request.method !== 'GET') return; - if (url.pathname.startsWith('/c/demo-')) { + if (shouldCacheDynamically(url.pathname)) { cacheOrNetworkAndCache(event, dynamicCache); cleanupCache(event, dynamicCache, ASSETS); return; diff --git a/src/sw/to-cache.ts b/src/sw/to-cache.ts index cbc922f5..bad10ef0 100644 --- a/src/sw/to-cache.ts +++ b/src/sw/to-cache.ts @@ -13,18 +13,46 @@ function subtractSets(set1: Set, set2: Set): Set { // Initial app stuff import * as initialApp from 'entry-data:client/initial-app'; +import swUrl from 'service-worker:sw'; import * as compress from 'entry-data:client/lazy-app/Compress'; import * as swBridge from 'entry-data:client/lazy-app/sw-bridge'; import * as blobAnim from 'entry-data:shared/prerendered-app/Intro/blob-anim'; -import logo from 'url:shared/prerendered-app/Intro/imgs/logo.svg'; -import githubLogo from 'url:shared/prerendered-app/Intro/imgs/github-logo.svg'; -import largePhotoIcon from 'url:shared/prerendered-app/Intro/imgs/demos/icon-demo-large-photo.jpg'; -import artworkIcon from 'url:shared/prerendered-app/Intro/imgs/demos/icon-demo-artwork.jpg'; -import deviceScreenIcon from 'url:shared/prerendered-app/Intro/imgs/demos/icon-demo-device-screen.jpg'; -import logoIcon from 'url:shared/prerendered-app/Intro/imgs/demos/icon-demo-logo.png'; -import logoWithText from 'url:shared/prerendered-app/Intro/imgs/logo-with-text.svg'; -let initalJs = new Set([ +// The processors and codecs +// Simple stuff everyone gets: +import * as featuresWorker from 'entry-data:../features-worker'; + +// Decoders (some are feature detected) +import * as avifDec from 'entry-data:codecs/avif/dec/avif_dec'; +import * as webpDec from 'entry-data:codecs/webp/dec/webp_dec'; + +// AVIF +import * as avifEncMt from 'entry-data:codecs/avif/enc/avif_enc_mt'; +import * as avifEnc from 'entry-data:codecs/avif/enc/avif_enc'; + +// JXL +import * as jxlEncMtSimd from 'entry-data:codecs/jxl/enc/jxl_enc_mt_simd'; +import * as jxlEncMt from 'entry-data:codecs/jxl/enc/jxl_enc_mt'; +import * as jxlEnc from 'entry-data:codecs/jxl/enc/jxl_enc'; + +// OXI +import * as oxiMt from 'entry-data:codecs/oxipng/pkg-parallel/squoosh_oxipng'; +import * as oxi from 'entry-data:codecs/oxipng/pkg/squoosh_oxipng'; + +// WebP +import * as webpEncSimd from 'entry-data:codecs/webp/enc/webp_enc_simd'; +import * as webpEnc from 'entry-data:codecs/webp/enc/webp_enc'; + +// WP2 +import * as wp2EncMtSimd from 'entry-data:codecs/wp2/enc/wp2_enc_mt_simd'; +import * as wp2EncMt from 'entry-data:codecs/wp2/enc/wp2_enc_mt'; +import * as wp2Enc from 'entry-data:codecs/wp2/enc/wp2_enc'; + +export function shouldCacheDynamically(url: string) { + return url.startsWith('/c/demo-'); +} + +let initialJs = new Set([ compress.main, ...compress.deps, swBridge.main, @@ -32,77 +60,26 @@ let initalJs = new Set([ blobAnim.main, ...blobAnim.deps, ]); -// But initial app and any deps have already been inlined, so we don't need them: -initalJs = subtractSets( - initalJs, - new Set([initialApp.main, ...initialApp.deps]), +initialJs = subtractSets( + initialJs, + new Set([ + initialApp.main, + ...initialApp.deps.filter( + (item) => + // Exclude JS deps that have been inlined: + item.endsWith('.js') || + // As well as large image deps we want to keep dynamic: + shouldCacheDynamically(item), + ), + // Exclude features Worker itself - it's referenced from the main app, + // but is meant to be cached lazily. + featuresWorker.main, + // Also exclude Service Worker itself (we're inside right now). + swUrl, + ]), ); -export const initial = [ - '/', - ...initalJs, - logo, - githubLogo, - largePhotoIcon, - artworkIcon, - deviceScreenIcon, - logoIcon, - logoWithText, -]; - -// The processors and codecs -// Simple stuff everyone gets: -import * as featuresWorker from 'entry-data:../features-worker'; -import rotateWasm from 'url:codecs/rotate/rotate.wasm'; -import quantWasm from 'url:codecs/imagequant/imagequant.wasm'; -import resizeWasm from 'url:codecs/resize/pkg/squoosh_resize_bg.wasm'; -import hqxWasm from 'url:codecs/hqx/pkg/squooshhqx_bg.wasm'; -import mozjpegWasm from 'url:codecs/mozjpeg/enc/mozjpeg_enc.wasm'; - -// Decoders (some are feature detected) -import * as avifDec from 'entry-data:codecs/avif/dec/avif_dec'; -import avifDecWasm from 'url:codecs/avif/dec/avif_dec.wasm'; -import jxlDecWasm from 'url:codecs/jxl/dec/jxl_dec.wasm'; -import * as webpDec from 'entry-data:codecs/webp/dec/webp_dec'; -import webpDecWasm from 'url:codecs/webp/dec/webp_dec.wasm'; -import wp2DecWasm from 'url:codecs/wp2/dec/wp2_dec.wasm'; - -// AVIF -import * as avifEncMtWorker from 'entry-data:codecs/avif/enc/avif_enc_mt.worker.js'; -import * as avifEncMt from 'entry-data:codecs/avif/enc/avif_enc_mt'; -import avifEncMtWasm from 'url:codecs/avif/enc/avif_enc_mt.wasm'; -import avifEncWasm from 'url:codecs/avif/enc/avif_enc.wasm'; -import * as avifEnc from 'entry-data:codecs/avif/enc/avif_enc.js'; - -// JXL -import * as jxlEncMtSimdWorker from 'entry-data:codecs/jxl/enc/jxl_enc_mt_simd.worker.js'; -import * as jxlEncMtSimd from 'entry-data:codecs/jxl/enc/jxl_enc_mt_simd'; -import jxlEncMtSimdWasm from 'url:codecs/jxl/enc/jxl_enc_mt_simd.wasm'; -import * as jxlEncMtWorker from 'entry-data:codecs/jxl/enc/jxl_enc_mt.worker.js'; -import * as jxlEncMt from 'entry-data:codecs/jxl/enc/jxl_enc_mt'; -import jxlEncMtWasm from 'url:codecs/jxl/enc/jxl_enc_mt.wasm'; -import jxlEncWasm from 'url:codecs/jxl/enc/jxl_enc.wasm'; -import * as jxlEnc from 'entry-data:codecs/jxl/enc/jxl_enc'; - -// OXI -import oxiMtWasm from 'url:codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm'; -import oxiWasm from 'url:codecs/oxipng/pkg/squoosh_oxipng_bg.wasm'; - -// WebP -import * as webpEncSimd from 'entry-data:codecs/webp/enc/webp_enc_simd'; -import webpEncSimdWasm from 'url:codecs/webp/enc/webp_enc_simd.wasm'; -import * as webpEnc from 'entry-data:codecs/webp/enc/webp_enc'; -import webpEncWasm from 'url:codecs/webp/enc/webp_enc.wasm'; - -// WP2 -import * as wp2EncMtSimdWorker from 'entry-data:codecs/wp2/enc/wp2_enc_mt_simd.worker.js'; -import * as wp2EncMtSimd from 'entry-data:codecs/wp2/enc/wp2_enc_mt_simd'; -import wp2EncMtSimdWasm from 'url:codecs/wp2/enc/wp2_enc_mt_simd.wasm'; -import * as wp2EncMtWorker from 'entry-data:codecs/wp2/enc/wp2_enc_mt.worker.js'; -import * as wp2EncMt from 'entry-data:codecs/wp2/enc/wp2_enc_mt'; -import wp2EncMtWasm from 'url:codecs/wp2/enc/wp2_enc_mt.wasm'; -import * as wp2Enc from 'entry-data:codecs/wp2/enc/wp2_enc'; -import wp2EncWasm from 'url:codecs/wp2/enc/wp2_enc.wasm'; +export const initial = ['/', ...initialJs]; export const theRest = (async () => { const [ @@ -124,88 +101,54 @@ export const theRest = (async () => { }), ]); - const items = [ - featuresWorker.main, - ...featuresWorker.deps, - rotateWasm, - quantWasm, - resizeWasm, - hqxWasm, - mozjpegWasm, - jxlDecWasm, - wp2DecWasm, - ]; + const items: string[] = []; - if (!supportsAvif) items.push(avifDec.main, ...avifDec.deps, avifDecWasm); - if (!supportsWebP) items.push(webpDec.main, ...webpDec.deps, webpDecWasm); + function addWithDeps(entry: typeof import('entry-data:*')) { + items.push(entry.main, ...entry.deps); + } + + addWithDeps(featuresWorker); + + if (!supportsAvif) addWithDeps(avifDec); + if (!supportsWebP) addWithDeps(webpDec); // AVIF if (supportsThreads) { - items.push( - avifEncMtWorker.main, - ...avifEncMtWorker.deps, - avifEncMt.main, - ...avifEncMt.deps, - avifEncMtWasm, - ); + addWithDeps(avifEncMt); } else { - items.push(avifEnc.main, ...avifEnc.deps, avifEncWasm); + addWithDeps(avifEnc); } // JXL if (supportsThreads && supportsSimd) { - items.push( - jxlEncMtSimdWorker.main, - ...jxlEncMtSimdWorker.deps, - jxlEncMtSimd.main, - ...jxlEncMtSimd.deps, - jxlEncMtSimdWasm, - ); + addWithDeps(jxlEncMtSimd); } else if (supportsThreads) { - items.push( - jxlEncMtWorker.main, - ...jxlEncMtWorker.deps, - jxlEncMt.main, - ...jxlEncMt.deps, - jxlEncMtWasm, - ); + addWithDeps(jxlEncMt); } else { - items.push(jxlEnc.main, ...jxlEnc.deps, jxlEncWasm); + addWithDeps(jxlEnc); } // OXI if (supportsThreads) { - items.push(oxiMtWasm); + addWithDeps(oxiMt); } else { - items.push(oxiWasm); + addWithDeps(oxi); } // WebP if (supportsSimd) { - items.push(webpEncSimd.main, ...webpEncSimd.deps, webpEncSimdWasm); + addWithDeps(webpEncSimd); } else { - items.push(webpEnc.main, ...webpEnc.deps, webpEncWasm); + addWithDeps(webpEnc); } // WP2 if (supportsThreads && supportsSimd) { - items.push( - wp2EncMtSimdWorker.main, - ...wp2EncMtSimdWorker.deps, - wp2EncMtSimd.main, - ...wp2EncMtSimd.deps, - wp2EncMtSimdWasm, - ); + addWithDeps(wp2EncMtSimd); } else if (supportsThreads) { - items.push( - wp2EncMtWorker.main, - ...wp2EncMtWorker.deps, - wp2EncMt.main, - ...wp2EncMt.deps, - wp2EncMtWasm, - ); + addWithDeps(wp2EncMt); } else { - items.push(wp2Enc.main, ...wp2Enc.deps, wp2EncWasm); + addWithDeps(wp2Enc); } return [...new Set(items)];