diff --git a/public/assets/boot/warmup.js b/public/assets/boot/warmup.js new file mode 100644 index 00000000..ab5c80a2 --- /dev/null +++ b/public/assets/boot/warmup.js @@ -0,0 +1,48 @@ +if (!HTMLScriptElement.supports?.("importmap")) throw new Error("fastboot is not supported on this platform"); +window.bundler = (function(origin) { + const esModules = {}; + return { + register: (path, code) => { + if (path.endsWith(".js")) { + code = code.replace(/from\s?"([^"]+)"/g, (_, spec) => + `from "${new URL(spec, origin + path).href}"`, + ); + code = code.replace(/\bimport\s+"([^"]+)"/g, (_, spec) => + `import "${new URL(spec, origin + path).href}"`, + ); + code = code.replace(/(? { + const $style = document.head.querySelector(`style[id="${new URL(rel, origin + path).href}"]`); + if (!$style) throw new DOMException( + `Missing CSS dependency: ${rel} (referenced from ${path})`, + "NotFoundError", + ); + return `/* ${m} */`; + }); + code += `\n/*# sourceURL=${path} */`; + document.head.appendChild(Object.assign(document.createElement("style"), { + innerHTML: code, + id: origin + path, + })); + } + }, + esModules, + }; +})(new URL(import.meta.url).origin); +await new Promise((resolve, reject) => { + document.head.appendChild(Object.assign(document.createElement("script"), { + type: "module", + src: `./assets/bundle.js?version=${window.VERSION}`, + onload: resolve, + onerror: reject, + })); +}); +document.head.appendChild(Object.assign(document.createElement("script"), { + type: "importmap", + textContent: JSON.stringify({ + imports: window.bundler.esModules, + }, null, 4), +})); diff --git a/public/assets/helpers/loader.js b/public/assets/helpers/loader.js index ffb2599f..ad52da5b 100644 --- a/public/assets/helpers/loader.js +++ b/public/assets/helpers/loader.js @@ -21,6 +21,7 @@ export async function loadCSS(baseURL, path) { $style.setAttribute("href", link.toString()); $style.setAttribute("rel", "stylesheet"); if (document.head.querySelector(`[href="${link.toString()}"]`)) return Promise.resolve(); + else if (document.head.querySelector(`style[id="${link.toString()}"]`)) return Promise.resolve(); document.head.appendChild($style); return new Promise((done) => { $style.onload = done; diff --git a/public/assets/lib/skeleton/index.js b/public/assets/lib/skeleton/index.js index e772981f..5c66a15e 100644 --- a/public/assets/lib/skeleton/index.js +++ b/public/assets/lib/skeleton/index.js @@ -42,7 +42,7 @@ async function load(route, opts) { } const module = window.env === "test" ? require("../.." + route) - : await import("../.." + route); + : await import(new URL("../.." + route, import.meta.url)); if (typeof module.init === "function") await module.init(); diff --git a/public/global.d.ts b/public/global.d.ts index 9a1da04e..15d36327 100644 --- a/public/global.d.ts +++ b/public/global.d.ts @@ -5,5 +5,7 @@ interface Window { [key: string]: any; "xdg-open"?: (mime: string) => void; }; + VERSION: string; + bundler: any; BEARER_TOKEN?: string; } \ No newline at end of file diff --git a/public/index.frontoffice.html b/public/index.frontoffice.html index 375fd079..f432fb0c 100644 --- a/public/index.frontoffice.html +++ b/public/index.frontoffice.html @@ -17,22 +17,19 @@