diff --git a/src/client/dom/cookie.ts b/src/client/dom/cookie.ts index fd66875..f8eae03 100644 --- a/src/client/dom/cookie.ts +++ b/src/client/dom/cookie.ts @@ -1,13 +1,22 @@ +import type { MessageC2W, MessageW2C } from "../../worker"; import { ScramjetClient } from "../client"; export default function (client: ScramjetClient, self: typeof window) { - client.serviceWorker.addEventListener("message", ({ data }) => { - if (!("scramjet$type" in data)) return; + client.serviceWorker.addEventListener( + "message", + ({ data }: { data: MessageW2C }) => { + if (!("scramjet$type" in data)) return; - if (data.scramjet$type === "cookie") { - client.cookieStore.setCookies([data.cookie], new URL(data.url)); + if (data.scramjet$type === "cookie") { + client.cookieStore.setCookies([data.cookie], new URL(data.url)); + let msg = { + scramjet$token: data.scramjet$token, + scramjet$type: "cookie", + }; + client.serviceWorker.controller.postMessage(msg); + } } - }); + ); client.Trap("Document.prototype.cookie", { get() { diff --git a/src/worker/fetch.ts b/src/worker/fetch.ts index 4c6f09e..c94b1e9 100644 --- a/src/worker/fetch.ts +++ b/src/worker/fetch.ts @@ -237,12 +237,16 @@ async function handleResponse( const maybeHeaders = responseHeaders["set-cookie"] || []; for (const cookie in maybeHeaders) { - if (client) - client.postMessage({ + if (client) { + let promise = swtarget.dispatch(client, { scramjet$type: "cookie", cookie, url: url.href, - } as MessageW2C); + }); + if (destination != "document" && destination != "iframe") { + await promise; + } + } } await cookieStore.setCookies( diff --git a/src/worker/index.ts b/src/worker/index.ts index 5d1f37b..5fe17ad 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -38,6 +38,14 @@ export class ScramjetServiceWorker extends EventTarget { addEventListener("message", async ({ data }: { data: MessageC2W }) => { if (!("scramjet$type" in data)) return; + if ("scramjet$token" in data) { + // (ack message) + const cb = this.syncPool[data.scramjet$token]; + delete this.syncPool[data.scramjet$token]; + cb(data); + return; + } + if (data.scramjet$type === "registerServiceWorker") { this.serviceWorkers.push(new FakeServiceWorker(data.port, data.origin)); @@ -58,6 +66,17 @@ export class ScramjetServiceWorker extends EventTarget { }); } + async dispatch(client: Client, data: MessageW2C): Promise { + let token = this.synctoken++; + let cb: (val: MessageC2W) => void; + let promise: Promise = new Promise((r) => (cb = r)); + this.syncPool[token] = cb; + data.scramjet$token = token; + + client.postMessage(data); + return await promise; + } + async loadConfig() { if (this.config) return; @@ -124,7 +143,7 @@ type ConfigMessage = { type MessageCommon = { scramjet$type: string; - scramjet$token: number; + scramjet$token?: number; }; type MessageTypeC2W =