File size: 1,767 Bytes
bee6636 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
import { type MessageW2R, type MessageR2W } from "../client/swruntime";
export class FakeServiceWorker {
syncToken = 0;
promises: Record<number, (val?: MessageR2W) => void> = {};
messageChannel = new MessageChannel();
connected = false;
constructor(
public handle: MessagePort,
public origin: string
) {
this.messageChannel.port1.addEventListener("message", (event) => {
if ("scramjet$type" in event.data) {
if (event.data.scramjet$type === "init") {
this.connected = true;
} else {
this.handleMessage(event.data);
}
}
});
this.messageChannel.port1.start();
this.handle.postMessage(
{
scramjet$type: "init",
scramjet$port: this.messageChannel.port2,
},
[this.messageChannel.port2]
);
}
handleMessage(data: MessageR2W) {
const cb = this.promises[data.scramjet$token];
if (cb) {
cb(data);
delete this.promises[data.scramjet$token];
}
}
async fetch(request: Request): Promise<Response | false> {
const token = this.syncToken++;
const message: MessageW2R = {
scramjet$type: "fetch",
scramjet$token: token,
scramjet$request: {
url: request.url,
body: request.body,
headers: Array.from(request.headers.entries()),
method: request.method,
mode: request.mode,
destinitation: request.destination,
},
};
const transfer = request.body ? [request.body] : [];
this.handle.postMessage(message, transfer);
const { scramjet$response: r } = (await new Promise((resolve) => {
this.promises[token] = resolve;
})) as MessageR2W;
if (!r) return false;
return new Response(r.body, {
headers: r.headers,
status: r.status,
statusText: r.statusText,
});
}
}
|