mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-15 23:30:00 -04:00
swruntime: implement fetch event
This commit is contained in:
parent
14a0305bdb
commit
15bc9598c9
9 changed files with 273 additions and 31 deletions
|
@ -1,21 +1,121 @@
|
|||
import { ScramjetClient } from "./client";
|
||||
import { encodeUrl } from "./shared";
|
||||
|
||||
class ScramjetServiceWorkerRuntime {
|
||||
constructor() {
|
||||
addEventListener("message", (event) => {
|
||||
if ("scramjet$type" in event.data) {
|
||||
event.stopImmediatePropagation();
|
||||
export class ScramjetServiceWorkerRuntime {
|
||||
constructor(public client: ScramjetClient) {
|
||||
addEventListener("connect", (cevent: MessageEvent) => {
|
||||
const port = cevent.ports[0];
|
||||
|
||||
return;
|
||||
}
|
||||
port.addEventListener("message", (event) => {
|
||||
if ("scramjet$type" in event.data) {
|
||||
handleMessage(client, event.data, port);
|
||||
}
|
||||
});
|
||||
|
||||
port.start();
|
||||
});
|
||||
}
|
||||
|
||||
hook() {}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
ScramjetServiceWorkerRuntime: typeof ScramjetServiceWorkerRuntime;
|
||||
function handleMessage(
|
||||
client: ScramjetClient,
|
||||
data: MessageW2R,
|
||||
port: MessagePort
|
||||
) {
|
||||
const type = data.scramjet$type;
|
||||
const token = data.scramjet$token;
|
||||
|
||||
if (type === "fetch") {
|
||||
const fetchhandlers = client.eventcallbacks.get("fetch");
|
||||
if (!fetchhandlers) return;
|
||||
|
||||
for (const handler of fetchhandlers) {
|
||||
const request = data.scramjet$request;
|
||||
const fakeRequest = new Request(request.url, {
|
||||
body: request.body,
|
||||
headers: new Headers(request.headers),
|
||||
method: request.method,
|
||||
mode: request.mode,
|
||||
});
|
||||
|
||||
Object.defineProperty(fakeRequest, "destination", {
|
||||
value: request.destinitation,
|
||||
});
|
||||
|
||||
const fakeFetchEvent = new FetchEvent("fetch", {
|
||||
request: fakeRequest,
|
||||
});
|
||||
|
||||
fakeFetchEvent.respondWith = async (
|
||||
response: Response | Promise<Response>
|
||||
) => {
|
||||
response = await response;
|
||||
|
||||
response.body;
|
||||
port.postMessage({
|
||||
scramjet$type: "fetch",
|
||||
scramjet$token: token,
|
||||
scramjet$response: {
|
||||
body: response.body,
|
||||
headers: Array.from(response.headers.entries()),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
},
|
||||
} as MessageR2W);
|
||||
};
|
||||
|
||||
handler.proxiedCallback(trustEvent(fakeFetchEvent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.ScramjetServiceWorkerRuntime = ScramjetServiceWorkerRuntime;
|
||||
function trustEvent(event: Event): Event {
|
||||
return new Proxy(event, {
|
||||
get(target, prop, reciever) {
|
||||
if (prop === "isTrusted") return true;
|
||||
|
||||
return Reflect.get(target, prop, reciever);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export type TransferrableResponse = {
|
||||
body: ReadableStream;
|
||||
headers: [string, string][];
|
||||
status: number;
|
||||
statusText: string;
|
||||
};
|
||||
|
||||
export type TransferrableRequest = {
|
||||
body: ReadableStream;
|
||||
headers: [string, string][];
|
||||
destinitation: RequestDestination;
|
||||
method: Request["method"];
|
||||
mode: Request["mode"];
|
||||
url: string;
|
||||
};
|
||||
|
||||
type FetchResponseMessage = {
|
||||
scramjet$type: "fetch";
|
||||
scramjet$response: TransferrableResponse;
|
||||
};
|
||||
|
||||
type FetchRequestMessage = {
|
||||
scramjet$type: "fetch";
|
||||
scramjet$request: TransferrableRequest;
|
||||
};
|
||||
|
||||
// r2w = runtime to (service) worker
|
||||
|
||||
type MessageTypeR2W = FetchResponseMessage;
|
||||
type MessageTypeW2R = FetchRequestMessage;
|
||||
|
||||
type MessageCommon = {
|
||||
scramjet$type: string;
|
||||
scramjet$token: number;
|
||||
};
|
||||
|
||||
export type MessageR2W = MessageCommon & MessageTypeR2W;
|
||||
export type MessageW2R = MessageCommon & MessageTypeW2R;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue