return fake serviceworkerregistration

This commit is contained in:
velzie 2024-07-21 16:20:52 -04:00
parent 91dc2f96cd
commit f2fe8c1d5e
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F
5 changed files with 87 additions and 2 deletions

21
src/client/swruntime.ts Normal file
View file

@ -0,0 +1,21 @@
import { encodeUrl } from "../shared/rewriters/url";
class ScramjetServiceWorkerRuntime {
constructor() {
addEventListener("message", (event) => {
if ("scramjet$type" in event.data) {
event.stopImmediatePropagation();
return;
}
});
}
}
declare global {
interface Window {
ScramjetServiceWorkerRuntime: typeof ScramjetServiceWorkerRuntime;
}
}
self.ScramjetServiceWorkerRuntime = ScramjetServiceWorkerRuntime;

View file

@ -45,6 +45,14 @@ export const windowProxy = new Proxy(self, {
return Reflect.set(target, prop, newValue);
},
defineProperty(target, property, attributes) {
if (!attributes.get && !attributes.set) {
attributes.writable = true;
}
attributes.configurable = true;
return Reflect.defineProperty(target, property, attributes);
},
});
export const documentProxy = new Proxy(self.document || {}, {

View file

@ -25,8 +25,50 @@ if ("window" in self) {
return Reflect.apply(target, thisArg, argArray);
},
});
//@ts-expect-error temporary until nested sw support
delete window.Navigator.prototype.serviceWorker;
client.Proxy("navigator.serviceWorker.register", {
apply(ctx) {
if (ctx.args[0] instanceof URL) ctx.args[0] = ctx.args[0].href;
let url = encodeUrl(ctx.args[0]) + "?dest=serviceworker";
if (ctx.args[1] && ctx.args[1].type === "module") {
url += "&type=module";
}
let worker = new SharedWorker(url);
let handle = worker.port;
navigator.serviceWorker.controller.postMessage({
scramjet$type: "registerServiceWorker",
port: handle,
});
const fakeRegistration = new Proxy(
{
__proto__: ServiceWorkerRegistration.prototype,
},
{
get(target, prop) {
if (prop === "installing") {
return null;
}
if (prop === "waiting") {
return null;
}
if (prop === "active") {
return handle;
}
if (prop === "scope") {
return ctx.args[0];
}
return Reflect.get(target, prop);
},
}
);
ctx.return(new Promise((resolve) => resolve(fakeRegistration)));
},
});
}
client.Proxy("importScripts", {

3
src/worker/fakesw.ts Normal file
View file

@ -0,0 +1,3 @@
export class FakeServiceWorker {
constructor(public handle: MessagePort) {}
}

View file

@ -1,3 +1,4 @@
import { FakeServiceWorker } from "./fakesw";
import { swfetch } from "./fetch";
import { ScramjetThreadpool } from "./threadpool";
@ -15,6 +16,8 @@ export class ScramjetServiceWorker {
syncPool: Record<number, (val?: any) => void> = {};
synctoken = 0;
serviceWorkers: FakeServiceWorker[] = [];
constructor(config = self.$scramjet.config) {
this.client = new self.$scramjet.shared.util.BareClient();
if (!config.prefix) config.prefix = "/scramjet/";
@ -23,6 +26,14 @@ export class ScramjetServiceWorker {
this.threadpool = new ScramjetThreadpool();
addEventListener("message", ({ data }) => {
if (!("scramjet$type" in data)) return;
if (data.scramjet$type === "registerServiceWorker") {
this.serviceWorkers.push(new FakeServiceWorker(data.port));
return;
}
if (!("scramjet$token" in data)) return;
const resolve = this.syncPool[data.scramjet$token];