diff --git a/public/assets/helpers/loader.js b/public/assets/helpers/loader.js index 118ded60..e1935683 100644 --- a/public/assets/helpers/loader.js +++ b/public/assets/helpers/loader.js @@ -1,3 +1,5 @@ +import { onDestroy } from "../lib/skeleton/index.js"; + export async function loadJS(baseURL, path, opts = {}) { const $script = document.createElement("script"); const link = new URL(path, baseURL); @@ -26,6 +28,31 @@ export async function loadCSS(baseURL, path) { }); } +export async function loadWorker(baseURL, path, opts = {}) { + const { iframe = true } = opts; + let url = new URL(path, baseURL); + if (iframe) { + // eg: fix issue coming from loading worker through an iframe like this nasty: + // SecurityError: Failed to construct 'Worker': Script at 'xxx.worker.js' cannot be accessed from origin 'null'. + // at Module.default (loader_dbf.js:9:20) + // at application_table.js:58:50 + let code = await fetch(new URL(path, baseURL)).then((res) => res.text()); + const importPathRE = new RegExp("import\\s+(?:[^'\";]*?\\s+from\\s+)?[\"']([^\"']+)[\"']", "gm"); + code = code.replaceAll("import.meta.url", `"${baseURL}"`) + code.matchAll(importPathRE).forEach(([_, path]) => { + code = code.replaceAll(path, new URL(path, baseURL)); + }); + url = URL.createObjectURL(new Blob([code], { type: "application/javascript" })); + onDestroy(() => URL.revokeObjectURL(url)); + } + const worker = new Worker(url, { type: "module" }); + onDestroy(() => worker.terminate()); + await new Promise((resolve) => worker.addEventListener( + "message", resolve, { once: true }, + )); + return worker; +} + export async function loadCSSInline(baseURL, filename) { const res = await fetch(new URL(filename, baseURL).pathname, { cache: "force-cache",