mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-14 15:00:01 -04:00
122 lines
3 KiB
TypeScript
122 lines
3 KiB
TypeScript
import { FakeServiceWorker } from "./fakesw";
|
|
import { swfetch } from "./fetch";
|
|
import type BareClient from "@mercuryworkshop/bare-mux";
|
|
import { ScramjetConfig } from "../types";
|
|
import { $scramjet, loadCodecs } from "../scramjet";
|
|
|
|
export class ScramjetServiceWorker extends EventTarget {
|
|
client: BareClient;
|
|
config: ScramjetConfig;
|
|
|
|
syncPool: Record<number, (val?: any) => void> = {};
|
|
synctoken = 0;
|
|
|
|
cookieStore = new $scramjet.shared.CookieStore();
|
|
|
|
serviceWorkers: FakeServiceWorker[] = [];
|
|
|
|
constructor() {
|
|
super();
|
|
this.client = new $scramjet.shared.util.BareClient();
|
|
|
|
const db = indexedDB.open("$scramjet", 1);
|
|
|
|
db.onsuccess = () => {
|
|
const res = db.result;
|
|
const tx = res.transaction("cookies", "readonly");
|
|
const store = tx.objectStore("cookies");
|
|
const cookies = store.get("cookies");
|
|
|
|
cookies.onsuccess = () => {
|
|
if (cookies.result) {
|
|
this.cookieStore.load(cookies.result);
|
|
dbg.log("Loaded cookies from IDB!");
|
|
}
|
|
};
|
|
};
|
|
|
|
addEventListener("message", async ({ data }: { data: MessageC2W }) => {
|
|
if (!("scramjet$type" in data)) return;
|
|
|
|
if (data.scramjet$type === "registerServiceWorker") {
|
|
this.serviceWorkers.push(new FakeServiceWorker(data.port, data.origin));
|
|
|
|
return;
|
|
}
|
|
|
|
if (data.scramjet$type === "cookie") {
|
|
this.cookieStore.setCookies([data.cookie], new URL(data.url));
|
|
const res = db.result;
|
|
const tx = res.transaction("cookies", "readwrite");
|
|
const store = tx.objectStore("cookies");
|
|
store.put(JSON.parse(this.cookieStore.dump()), "cookies");
|
|
}
|
|
});
|
|
}
|
|
|
|
async loadConfig() {
|
|
if (this.config) return;
|
|
|
|
const request = indexedDB.open("$scramjet", 1);
|
|
|
|
return new Promise<void>((resolve, reject) => {
|
|
request.onsuccess = async () => {
|
|
const db = request.result;
|
|
const tx = db.transaction("config", "readonly");
|
|
const store = tx.objectStore("config");
|
|
const config = store.get("config");
|
|
|
|
config.onsuccess = () => {
|
|
this.config = config.result;
|
|
$scramjet.config = config.result;
|
|
|
|
loadCodecs();
|
|
|
|
resolve();
|
|
};
|
|
config.onerror = () => reject(config.error);
|
|
};
|
|
|
|
request.onerror = () => reject(request.error);
|
|
});
|
|
}
|
|
|
|
route({ request }: FetchEvent) {
|
|
if (request.url.startsWith(location.origin + this.config.prefix))
|
|
return true;
|
|
else return false;
|
|
}
|
|
|
|
async fetch({ request, clientId }: FetchEvent) {
|
|
const client = await self.clients.get(clientId);
|
|
|
|
return swfetch.call(this, request, client);
|
|
}
|
|
}
|
|
|
|
// @ts-ignore
|
|
self.ScramjetServiceWorker = ScramjetServiceWorker;
|
|
|
|
type RegisterServiceWorkerMessage = {
|
|
scramjet$type: "registerServiceWorker";
|
|
port: MessagePort;
|
|
origin: string;
|
|
};
|
|
|
|
type CookieMessage = {
|
|
scramjet$type: "cookie";
|
|
cookie: string;
|
|
url: string;
|
|
};
|
|
|
|
type MessageCommon = {
|
|
scramjet$type: string;
|
|
scramjet$token: number;
|
|
};
|
|
|
|
type MessageTypeC2W = RegisterServiceWorkerMessage | CookieMessage;
|
|
type MessageTypeW2C = CookieMessage;
|
|
|
|
// c2w: client to (service) worker
|
|
export type MessageC2W = MessageCommon & MessageTypeC2W;
|
|
export type MessageW2C = MessageCommon & MessageTypeW2C;
|