diff --git a/src/worker/index.ts b/src/worker/index.ts index 4c6b92a..9218f8a 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -12,12 +12,74 @@ export class ScramjetServiceWorker { config: typeof self.$scramjet.config; threadpool: ScramjetThreadpool; + syncPool: Record void> = {}; + synctoken = 0; + constructor(config = self.$scramjet.config) { this.client = new self.$scramjet.shared.util.BareClient(); if (!config.prefix) config.prefix = "/scramjet/"; this.config = config; this.threadpool = new ScramjetThreadpool(); + + addEventListener("message", ({ data }) => { + if (!("scramjet$token" in data)) return; + + const resolve = this.syncPool[data.scramjet$token]; + delete this.syncPool[data.scramjet$token]; + if (data.scramjet$type === "getLocalStorage") { + resolve(data.data); + } else if (data.scramjet$type === "setLocalStorage") { + resolve(); + } + }); + } + + async getLocalStorage(): Promise> { + let clients = await self.clients.matchAll(); + clients = clients.filter( + (client) => + client.type === "window" && + !new URL(client.url).pathname.startsWith(this.config.prefix) + ); + + if (clients.length === 0) throw new Error("No clients found"); + + const token = this.synctoken++; + for (const client of clients) { + client.postMessage({ + scramjet$type: "getLocalStorage", + scramjet$token: token, + }); + } + + return new Promise((resolve) => { + this.syncPool[token] = resolve; + }); + } + + async setLocalStorage(data: Record): Promise { + let clients = await self.clients.matchAll(); + clients = clients.filter( + (client) => + client.type === "window" && + !new URL(client.url).pathname.startsWith(this.config.prefix) + ); + + if (clients.length === 0) throw new Error("No clients found"); + + const token = this.synctoken++; + for (const client of clients) { + client.postMessage({ + scramjet$type: "setLocalStorage", + scramjet$token: token, + data, + }); + } + + return new Promise((resolve) => { + this.syncPool[token] = resolve; + }); } route({ request }: FetchEvent) { diff --git a/static/ui.js b/static/ui.js index a4e84ce..a3b6d98 100644 --- a/static/ui.js +++ b/static/ui.js @@ -18,6 +18,25 @@ navigator.serviceWorker.ready.then((reg) => { } }); +navigator.serviceWorker.onmessage = ({ data }) => { + if (data.scramjet$type === "getLocalStorage") { + const pairs = Object.entries(localStorage); + navigator.serviceWorker.controller.postMessage({ + scramjet$type: "getLocalStorage", + scramjet$token: data.scramjet$token, + data: pairs, + }); + } else if (data.scramjet$type === "setLocalStorage") { + for (const [key, value] of data.data) { + localStorage.setItem(key, value); + } + navigator.serviceWorker.controller.postMessage({ + scramjet$type: "setLocalStorage", + scramjet$token: data.scramjet$token, + }); + } +}; + const connection = new BareMux.BareMuxConnection("/baremux/worker.js"); const flex = css` display: flex;