postmessage plumbing

This commit is contained in:
velzie 2024-07-20 13:31:24 -04:00
parent 38130176bb
commit 0a81ae042b
No known key found for this signature in database
GPG key ID: 048413F95F0DDE1F
2 changed files with 81 additions and 0 deletions

View file

@ -12,12 +12,74 @@ export class ScramjetServiceWorker {
config: typeof self.$scramjet.config; config: typeof self.$scramjet.config;
threadpool: ScramjetThreadpool; threadpool: ScramjetThreadpool;
syncPool: Record<number, (val?: any) => void> = {};
synctoken = 0;
constructor(config = self.$scramjet.config) { constructor(config = self.$scramjet.config) {
this.client = new self.$scramjet.shared.util.BareClient(); this.client = new self.$scramjet.shared.util.BareClient();
if (!config.prefix) config.prefix = "/scramjet/"; if (!config.prefix) config.prefix = "/scramjet/";
this.config = config; this.config = config;
this.threadpool = new ScramjetThreadpool(); 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<Record<string, string>> {
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<string, string>): Promise<void> {
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) { route({ request }: FetchEvent) {

View file

@ -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 connection = new BareMux.BareMuxConnection("/baremux/worker.js");
const flex = css` const flex = css`
display: flex; display: flex;