From a0ef702b54ba85da3a776b70d1d7218255bc2933 Mon Sep 17 00:00:00 2001 From: Avad3 <65318266+Avad3@users.noreply.github.com> Date: Fri, 12 Jul 2024 18:01:34 -0400 Subject: [PATCH] small changes --- esbuild.dev.js | 3 ++- esbuild.js | 3 ++- src/bundle/index.ts | 34 ++++++--------------------------- src/bundle/rewriters/css.ts | 4 ++-- src/bundle/rewriters/html.ts | 37 +++++++++++++++++++++++------------- src/client/beacon.ts | 4 +++- src/client/css.ts | 26 +++++++++++++------------ src/client/element.ts | 33 ++++++++++++++++++-------------- src/client/eval.ts | 10 ++++++---- src/client/fetch.ts | 10 ++++++---- src/client/location.ts | 9 +++++---- src/client/trustedTypes.ts | 9 ++++++--- src/client/xmlhttprequest.ts | 24 ++++++++++++----------- src/worker/index.ts | 19 +++++++++--------- static/sw.js | 9 ++++----- static/ui.js | 3 ++- 16 files changed, 124 insertions(+), 113 deletions(-) diff --git a/esbuild.dev.js b/esbuild.dev.js index 0a338d5..7b18738 100644 --- a/esbuild.dev.js +++ b/esbuild.dev.js @@ -15,7 +15,7 @@ const bare = createBareServer("/bare/", { }); const fastify = Fastify({ - serverFactory: (handler, opts) => { + serverFactory: (handler) => { return createServer() .on("request", (req, res) => { if (bare.shouldRoute(req)) { @@ -59,6 +59,7 @@ const devServer = await context({ bundle: true, sourcemap: true, logLevel: "info", + format: "esm", plugins: [ copy({ resolveFrom: "cwd", diff --git a/esbuild.js b/esbuild.js index a84d92b..61cdc86 100644 --- a/esbuild.js +++ b/esbuild.js @@ -19,7 +19,8 @@ const scramjetBuild = await build({ logLevel: "info", metafile: true, treeShaking: true, - minify: true + minify: true, + format: "esm" }); writeFileSync("./meta.json", JSON.stringify(scramjetBuild.metafile)); diff --git a/src/bundle/index.ts b/src/bundle/index.ts index 7be93f5..394f79a 100644 --- a/src/bundle/index.ts +++ b/src/bundle/index.ts @@ -1,8 +1,8 @@ -import { encodeUrl, decodeUrl } from "./rewriters/url"; -import { rewriteCss } from "./rewriters/css"; -import { rewriteHtml, rewriteSrcset } from "./rewriters/html"; -import { rewriteJs } from "./rewriters/js"; -import { rewriteHeaders } from "./rewriters/headers"; +export { encodeUrl, decodeUrl } from "./rewriters/url"; +export { rewriteCss } from "./rewriters/css"; +export { rewriteHtml, rewriteSrcset } from "./rewriters/html"; +export { rewriteJs } from "./rewriters/js"; +export { rewriteHeaders } from "./rewriters/headers"; export function isScramjetFile(src: string) { let bool = false; @@ -11,26 +11,4 @@ export function isScramjetFile(src: string) { }); return bool; -} - -const bundle = { - rewriters: { - url: { - encodeUrl, decodeUrl - }, - rewriteCss, - rewriteHtml, - rewriteSrcset, - rewriteJs, - rewriteHeaders - }, - isScramjetFile -} - -declare global { - interface Window { - __scramjet$bundle: typeof bundle; - } -} - -self.__scramjet$bundle = bundle; \ No newline at end of file +} \ No newline at end of file diff --git a/src/bundle/rewriters/css.ts b/src/bundle/rewriters/css.ts index 8868b31..c74b882 100644 --- a/src/bundle/rewriters/css.ts +++ b/src/bundle/rewriters/css.ts @@ -3,9 +3,9 @@ import { encodeUrl } from "./url"; export function rewriteCss(css: string, origin?: URL) { css = css.replace(/(?<=url\("?'?)[^"'][\S]*[^"'](?="?'?\);?)/gm, (match) => encodeUrl(match, origin)); //painful regex simulator - css = css.replace(/@import\s+(['"])?([^'"\);]+)\1?\s*(?:;|$)/gm, (match, quote, url) => { + css = css.replace(/@import\s+(['"])?([^'");]+)\1?\s*(?:;|$)/gm, (_, quote, url) => { return `@import ${quote || ""}${encodeUrl(url.trim(), origin)}${quote || ""};`; }); + return css; - } diff --git a/src/bundle/rewriters/html.ts b/src/bundle/rewriters/html.ts index e0deb3b..88de237 100644 --- a/src/bundle/rewriters/html.ts +++ b/src/bundle/rewriters/html.ts @@ -21,21 +21,32 @@ export function rewriteHtml(html: string, origin?: URL) { function traverseParsedHtml(node, origin?: URL) { /* csp attributes */ - if (hasAttrib(node, "nonce")) delete node.attribs.nonce; - if (hasAttrib(node, "integrity")) delete node.attribs.integrity; - if (hasAttrib(node, "csp")) delete node.attribs.csp; + for (const cspAttr of ["nonce", "integrity", "csp"]) { + if (hasAttrib(node, cspAttr)) { + node.attribs[`data-${cspAttr}`] = node.attribs[cspAttr]; + delete node.attribs[cspAttr]; + } + } /* url attributes */ - if (hasAttrib(node, "src") && !isScramjetFile(node.attribs.src)) node.attribs.src = encodeUrl(node.attribs.src, origin); - if (hasAttrib(node, "href")) node.attribs.href = encodeUrl(node.attribs.href, origin); - if (hasAttrib(node, "data")) node.attribs.data = encodeUrl(node.attribs.data, origin); - if (hasAttrib(node, "action")) node.attribs.action = encodeUrl(node.attribs.action, origin); - if (hasAttrib(node, "formaction")) node.attribs.formaction = encodeUrl(node.attribs.formaction, origin); + for (const urlAttr of ["src", "href", "data", "action"]) { + if (hasAttrib(node, urlAttr) && !isScramjetFile(node.attribs[urlAttr])) { + const value = node.attribs[urlAttr]; + node.attribs[`data-${urlAttr}`] = value; + node.attribs[urlAttr] = encodeUrl(value, origin); + } + } /* other */ + for (const srcsetAttr of ["srcset", "imagesrcset"]) { + if (hasAttrib(node, srcsetAttr)) { + const value = node.attribs[srcsetAttr]; + node.attribs[`data-${srcsetAttr}`] = value; + node.attribs[srcsetAttr] = rewriteSrcset(value, origin); + } + } + if (hasAttrib(node, "srcdoc")) node.attribs.srcdoc = rewriteHtml(node.attribs.srcdoc, origin); - if (hasAttrib(node, "srcset")) node.attribs.srcset = rewriteSrcset(node.attribs.srcset, origin); - if (hasAttrib(node, "imagesrcset")) node.attribs.imagesrcset = rewriteSrcset(node.attribs.imagesrcset, origin); if (hasAttrib(node, "style")) node.attribs.style = rewriteCss(node.attribs.style, origin); if (node.name === "style" && node.children[0] !== undefined) node.children[0].data = rewriteCss(node.children[0].data, origin); @@ -54,7 +65,8 @@ function traverseParsedHtml(node, origin?: URL) { const scramjetScripts = []; ["codecs", "config", "bundle", "client"].forEach((script) => { scramjetScripts.push(new Element("script", { - src: self.__scramjet$config[script] + src: self.__scramjet$config[script], + type: "module" })); }); @@ -70,7 +82,6 @@ function traverseParsedHtml(node, origin?: URL) { return node; } -// stole from osana lmao export function rewriteSrcset(srcset: string, origin?: URL) { const urls = srcset.split(/ [0-9]+x,? ?/g); if (!urls) return ""; @@ -83,4 +94,4 @@ export function rewriteSrcset(srcset: string, origin?: URL) { }); return rewrittenUrls.join(""); -} +} \ No newline at end of file diff --git a/src/client/beacon.ts b/src/client/beacon.ts index b42e173..bf377eb 100644 --- a/src/client/beacon.ts +++ b/src/client/beacon.ts @@ -1,6 +1,8 @@ +import { encodeUrl } from "../bundle"; + navigator.sendBeacon = new Proxy(navigator.sendBeacon, { apply(target, thisArg, argArray) { - argArray[0] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[0]); + argArray[0] = encodeUrl(argArray[0]); return Reflect.apply(target, thisArg, argArray); }, diff --git a/src/client/css.ts b/src/client/css.ts index 34ec502..2e5e61b 100644 --- a/src/client/css.ts +++ b/src/client/css.ts @@ -1,21 +1,23 @@ +import { rewriteCss } from "../bundle"; + const cssProperties = ["background", "background-image", "mask", "mask-image", "list-style", "list-style-image", "border-image", "border-image-source", "cursor"]; const jsProperties = ["background", "backgroundImage", "mask", "maskImage", "listStyle", "listStyleImage", "borderImage", "borderImageSource", "cursor"]; - + CSSStyleDeclaration.prototype.setProperty = new Proxy(CSSStyleDeclaration.prototype.setProperty, { - apply(target, thisArg, argArray) { - if (cssProperties.includes(argArray[0])) argArray[1] = self.__scramjet$bundle.rewriters.rewriteCss(argArray[1]); - - return Reflect.apply(target, thisArg, argArray); - }, + apply(target, thisArg, argArray) { + if (cssProperties.includes(argArray[0])) argArray[1] = rewriteCss(argArray[1]); + + return Reflect.apply(target, thisArg, argArray); + }, }); jsProperties.forEach((prop) => { - const propDescriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, prop); + const propDescriptor = Object.getOwnPropertyDescriptor(CSSStyleDeclaration.prototype, prop); - Object.defineProperty(CSSStyleDeclaration.prototype, prop, { - set(v) { - propDescriptor.set.call(this, self.__scramjet$bundle.rewriters.rewriteCss(v)); - }, - }) + Object.defineProperty(CSSStyleDeclaration.prototype, prop, { + set(v) { + propDescriptor.set.call(this, rewriteCss(v)); + }, + }) }); diff --git a/src/client/element.ts b/src/client/element.ts index 616b7c1..594abf6 100644 --- a/src/client/element.ts +++ b/src/client/element.ts @@ -1,3 +1,5 @@ +import { encodeUrl, rewriteCss, rewriteHtml, rewriteJs, rewriteSrcset } from "../bundle"; + // object // iframe // embed @@ -37,25 +39,26 @@ Object.keys(attribs).forEach((attrib: string) => { const descriptor = Object.getOwnPropertyDescriptor(element.prototype, attrib); Object.defineProperty(element.prototype, attrib, { get() { - return descriptor.get.call(this, [this.dataset[`_${attrib}`]]); + return this.dataset[attrib]; }, set(value) { - this.dataset[`_${attrib}`] = value; + this.dataset[attrib] = value; if (/nonce|integrity|csp/.test(attrib)) { this.removeAttribute(attrib); } else if (/src|href|data|action|formaction/.test(attrib)) { + // @ts-expect-error if (value instanceof TrustedScriptURL) { return; } - value = self.__scramjet$bundle.rewriters.url.encodeUrl(value); + value = encodeUrl(value); } else if (attrib === "srcdoc") { - value = self.__scramjet$bundle.rewriters.rewriteHtml(value); + value = rewriteHtml(value); } else if (/(image)?srcset/.test(attrib)) { - value = self.__scramjet$bundle.rewriters.rewriteSrcset(value); + value = rewriteSrcset(value); } else if (attrib === "style") { - value = self.__scramjet$bundle.rewriters.rewriteCss(value); + value = rewriteCss(value); } descriptor.set.call(this, value); @@ -68,7 +71,7 @@ HTMLElement.prototype.getAttribute = new Proxy(Element.prototype.getAttribute, { apply(target, thisArg, argArray) { console.log(thisArg); if (Object.keys(attribs).includes(argArray[0])) { - argArray[0] = `_${argArray[0]}`; + argArray[0] = `data-${argArray[0]}`; } return Reflect.apply(target, thisArg, argArray); @@ -89,13 +92,13 @@ HTMLElement.prototype.setAttribute = new Proxy(Element.prototype.setAttribute, { return; } else if (/src|href|data|action|formaction/.test(argArray[0])) { console.log(thisArg); - argArray[1] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[1]); + argArray[1] = encodeUrl(argArray[1]); } else if (argArray[0] === "srcdoc") { - argArray[1] = self.__scramjet$bundle.rewriters.rewriteHtml(argArray[1]); + argArray[1] = rewriteHtml(argArray[1]); } else if (/(image)?srcset/.test(argArray[0])) { - argArray[1] = self.__scramjet$bundle.rewriters.rewriteSrcset(argArray[1]); + argArray[1] = rewriteSrcset(argArray[1]); } else if (argArray[1] === "style") { - argArray[1] = self.__scramjet$bundle.rewriters.rewriteCss(argArray[1]); + argArray[1] = rewriteCss(argArray[1]); } } @@ -108,14 +111,16 @@ const innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML" Object.defineProperty(HTMLElement.prototype, "innerHTML", { set(value) { if (this instanceof HTMLScriptElement) { + // @ts-expect-error if (!(value instanceof TrustedScript)) { - value = self.__scramjet$bundle.rewriters.rewriteJs(value); + value = rewriteJs(value); } } else if (this instanceof HTMLStyleElement) { - value = self.__scramjet$bundle.rewriters.rewriteCss(value); + value = rewriteCss(value); } else { + // @ts-expect-error if (!(value instanceof TrustedHTML)) { - value = self.__scramjet$bundle.rewriters.rewriteHtml(value); + value = rewriteHtml(value); } } diff --git a/src/client/eval.ts b/src/client/eval.ts index 27dd6b1..c811304 100644 --- a/src/client/eval.ts +++ b/src/client/eval.ts @@ -1,16 +1,18 @@ +import { rewriteJs } from "../bundle"; + const FunctionProxy = new Proxy(Function, { construct(target, argArray) { if (argArray.length === 1) { - return Reflect.construct(target, self.__scramjet$bundle.rewriters.rewriteJs(argArray[0])); + return Reflect.construct(target, rewriteJs(argArray[0])); } else { - return Reflect.construct(target, self.__scramjet$bundle.rewriters.rewriteJs(argArray[argArray.length - 1])) + return Reflect.construct(target, rewriteJs(argArray[argArray.length - 1])) } }, apply(target, thisArg, argArray) { if (argArray.length === 1) { - return Reflect.apply(target, undefined, self.__scramjet$bundle.rewriters.rewriteJs(argArray[0])); + return Reflect.apply(target, undefined, rewriteJs(argArray[0])); } else { - return Reflect.apply(target, undefined, [...argArray.map((x, index) => index === argArray.length - 1), self.__scramjet$bundle.rewriters.rewriteJs(argArray[argArray.length - 1])]) + return Reflect.apply(target, undefined, [...argArray.map((x, index) => index === argArray.length - 1), rewriteJs(argArray[argArray.length - 1])]) } }, }); diff --git a/src/client/fetch.ts b/src/client/fetch.ts index ed40f1c..a40b675 100644 --- a/src/client/fetch.ts +++ b/src/client/fetch.ts @@ -1,8 +1,10 @@ // ts throws an error if you dont do window.fetch +import { encodeUrl, rewriteHeaders } from "../bundle"; + window.fetch = new Proxy(window.fetch, { apply(target, thisArg, argArray) { - argArray[0] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[0]); + argArray[0] = encodeUrl(argArray[0]); return Reflect.apply(target, thisArg, argArray); }, @@ -10,7 +12,7 @@ window.fetch = new Proxy(window.fetch, { Headers = new Proxy(Headers, { construct(target, argArray, newTarget) { - argArray[0] = self.__scramjet$bundle.rewriters.rewriteHeaders(argArray[0]); + argArray[0] = rewriteHeaders(argArray[0]); return Reflect.construct(target, argArray, newTarget); }, @@ -18,7 +20,7 @@ Headers = new Proxy(Headers, { Request = new Proxy(Request, { construct(target, argArray, newTarget) { - if (typeof argArray[0] === "string") argArray[0] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[0]); + if (typeof argArray[0] === "string") argArray[0] = encodeUrl(argArray[0]); return Reflect.construct(target, argArray, newTarget); }, @@ -26,7 +28,7 @@ Request = new Proxy(Request, { Response.redirect = new Proxy(Response.redirect, { apply(target, thisArg, argArray) { - argArray[0] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[0]); + argArray[0] = encodeUrl(argArray[0]); return Reflect.apply(target, thisArg, argArray); }, diff --git a/src/client/location.ts b/src/client/location.ts index 67aac60..85554f6 100644 --- a/src/client/location.ts +++ b/src/client/location.ts @@ -1,10 +1,11 @@ // @ts-nocheck +import { encodeUrl, decodeUrl } from "../bundle"; function urlLocation() { - let loc = new URL(self.__scramjet$bundle.rewriters.url.decodeUrl(location.href)); - loc.assign = (url: string) => location.assign(self.__scramjet$bundle.rewriters.url.encodeUrl(url)); + const loc = new URL(decodeUrl(location.href)); + loc.assign = (url: string) => location.assign(encodeUrl(url)); loc.reload = () => location.reload(); - loc.replace = (url: string) => location.replace(self.__scramjet$bundle.rewriters.url.encodeUrl(url)); + loc.replace = (url: string) => location.replace(encodeUrl(url)); loc.toString = () => loc.href; return loc; @@ -20,7 +21,7 @@ export function LocationProxy() { set(obj, prop, value) { if (prop === "href") { - location.href = self.__scramjet$bundle.rewriters.url.encodeUrl(value); + location.href = encodeUrl(value); } else { loc[prop] = value; } diff --git a/src/client/trustedTypes.ts b/src/client/trustedTypes.ts index 3806a97..339eb3c 100644 --- a/src/client/trustedTypes.ts +++ b/src/client/trustedTypes.ts @@ -1,9 +1,12 @@ +import { rewriteHtml, rewriteJs, encodeUrl } from "../bundle"; + +// @ts-expect-error trustedTypes.createPolicy = new Proxy(trustedTypes.createPolicy, { apply(target, thisArg, argArray) { if (argArray[1].createHTML) { argArray[1].createHTML = new Proxy(argArray[1].createHTML, { apply(target1, thisArg1, argArray1) { - return self.__scramjet$bundle.rewriters.rewriteHtml(target1(...argArray1)); + return rewriteHtml(target1(...argArray1)); }, }); } @@ -11,7 +14,7 @@ trustedTypes.createPolicy = new Proxy(trustedTypes.createPolicy, { if (argArray[1].createScript) { argArray[1].createScript = new Proxy(argArray[1].createScript, { apply(target1, thisArg1, argArray1) { - return self.__scramjet$bundle.rewriters.rewriteJs(target1(...argArray1)); + return rewriteJs(target1(...argArray1)); }, }); } @@ -19,7 +22,7 @@ trustedTypes.createPolicy = new Proxy(trustedTypes.createPolicy, { if (argArray[1].createScriptURL) { argArray[1].createScriptURL = new Proxy(argArray[1].createScriptURL, { apply(target1, thisArg1, argArray1) { - return self.__scramjet$bundle.rewriters.url.encodeUrl(target1(...argArray1)) + return encodeUrl(target1(...argArray1)); }, }) } diff --git a/src/client/xmlhttprequest.ts b/src/client/xmlhttprequest.ts index 8422a08..bee9567 100644 --- a/src/client/xmlhttprequest.ts +++ b/src/client/xmlhttprequest.ts @@ -1,18 +1,20 @@ -XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open, { - apply(target, thisArg, argArray) { - if (argArray[1]) argArray[1] = self.__scramjet$bundle.rewriters.url.encodeUrl(argArray[1]); +import { encodeUrl, rewriteHeaders } from "../bundle"; - return Reflect.apply(target, thisArg, argArray); - }, +XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open, { + apply(target, thisArg, argArray) { + if (argArray[1]) argArray[1] = encodeUrl(argArray[1]); + + return Reflect.apply(target, thisArg, argArray); + }, }); XMLHttpRequest.prototype.setRequestHeader = new Proxy(XMLHttpRequest.prototype.setRequestHeader, { - apply(target, thisArg, argArray) { - let headerObject = Object.fromEntries([argArray]); - headerObject = self.__scramjet$bundle.rewriters.rewriteHeaders(headerObject); + apply(target, thisArg, argArray) { + let headerObject = Object.fromEntries([argArray]); + headerObject = rewriteHeaders(headerObject); - argArray = Object.entries(headerObject)[0]; + argArray = Object.entries(headerObject)[0]; - return Reflect.apply(target, thisArg, argArray); - }, + return Reflect.apply(target, thisArg, argArray); + }, }); diff --git a/src/worker/index.ts b/src/worker/index.ts index e0590fc..d48a04b 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -1,5 +1,6 @@ import { BareClient } from "@mercuryworkshop/bare-mux"; -import { BareResponseFetch } from "@mercuryworkshop/bare-mux" +import { BareResponseFetch } from "@mercuryworkshop/bare-mux"; +import { encodeUrl, decodeUrl, rewriteCss, rewriteHeaders, rewriteHtml, rewriteJs } from "../bundle"; declare global { interface Window { @@ -7,7 +8,7 @@ declare global { } } -self.ScramjetServiceWorker = class ScramjetServiceWorker { +export default class ScramjetServiceWorker { client: typeof BareClient.prototype; config: typeof self.__scramjet$config; constructor(config = self.__scramjet$config) { @@ -25,11 +26,11 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { const urlParam = new URLSearchParams(new URL(request.url).search); if (urlParam.has("url")) { - return Response.redirect(self.__scramjet$bundle.rewriters.url.encodeUrl(urlParam.get("url"), new URL(urlParam.get("url")))) + return Response.redirect(encodeUrl(urlParam.get("url"), new URL(urlParam.get("url")))) } try { - const url = new URL(self.__scramjet$bundle.rewriters.url.decodeUrl(request.url)); + const url = new URL(decodeUrl(request.url)); const response: BareResponseFetch = await this.client.fetch(url, { method: request.method, @@ -42,18 +43,18 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { }); let responseBody; - const responseHeaders = self.__scramjet$bundle.rewriters.rewriteHeaders(response.rawHeaders, url); + const responseHeaders = rewriteHeaders(response.rawHeaders, url); if (response.body) { switch (request.destination) { case "iframe": case "document": - responseBody = self.__scramjet$bundle.rewriters.rewriteHtml(await response.text(), url); + responseBody = rewriteHtml(await response.text(), url); break; case "script": - responseBody = self.__scramjet$bundle.rewriters.rewriteJs(await response.text(), url); + responseBody = rewriteJs(await response.text(), url); break; case "style": - responseBody = self.__scramjet$bundle.rewriters.rewriteCss(await response.text(), url); + responseBody = rewriteCss(await response.text(), url); break; case "sharedworker": break; @@ -104,7 +105,7 @@ self.ScramjetServiceWorker = class ScramjetServiceWorker { console.error(err); - return renderError(err, self.__scramjet$bundle.rewriters.url.decodeUrl(request.url)); + return renderError(err, decodeUrl(request.url)); } } } diff --git a/static/sw.js b/static/sw.js index 655b310..5cdc815 100644 --- a/static/sw.js +++ b/static/sw.js @@ -1,7 +1,6 @@ -importScripts("scramjet.codecs.js"); -importScripts("scramjet.config.js"); -importScripts( __scramjet$config.bundle || "scramjet.bundle.js") -importScripts( __scramjet$config.worker || "scramjet.worker.js"); +import ScramjetServiceWorker from "./scramjet.worker.js"; +import "./scramjet.codecs.js"; +import "./scramjet.config.js"; const scramjet = new ScramjetServiceWorker(); @@ -13,4 +12,4 @@ self.addEventListener("fetch", async (event) => { return await fetch(event.request); } })()) -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/static/ui.js b/static/ui.js index 1e533c4..8cbc298 100644 --- a/static/ui.js +++ b/static/ui.js @@ -1,5 +1,6 @@ navigator.serviceWorker.register("./sw.js", { - scope: __scramjet$config.prefix + scope: __scramjet$config.prefix, + type: "module" }) const connection = new BareMux.BareMuxConnection("/bare-mux-worker.js") const flex = css`display: flex;`;