Skip to content

Commit 4f62972

Browse files
committed
refactor fetch handler to a class and implement structures for abstract ipc
1 parent 40014de commit 4f62972

File tree

7 files changed

+178
-115
lines changed

7 files changed

+178
-115
lines changed

packages/chrome/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"@mercuryworkshop/bare-mux-custom": "workspace:*",
1919
"@mercuryworkshop/epoxy-transport": "workspace:*",
2020
"@mercuryworkshop/libcurl-transport": "workspace:*",
21-
"@mercuryworkshop/scramjet": "workspace:scramjet",
21+
"@mercuryworkshop/scramjet": "workspace:*",
2222
"devtools-protocol": "^0.0.1339468",
2323
"domhandler": "^5.0.3",
2424
"dreamland": "workspace:dreamland",

packages/chrome/src/IsolatedFrame.tsx

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import {
33
type ScramjetFetchContext,
44
type ScramjetFetchResponse,
55
CookieJar,
6-
handleFetch,
6+
ScramjetFetchHandler,
77
rewriteUrl,
88
setConfig,
99
unrewriteUrl,
1010
type URLMeta,
11-
ScramjetServiceWorker,
11+
setInterface,
1212
} from "@mercuryworkshop/scramjet/bundled";
13+
1314
import { BareClient } from "@mercuryworkshop/bare-mux-custom";
1415
import { ElementType, type Handler, Parser } from "htmlparser2";
1516
import { type ChildNode, DomHandler, Element, Comment, Node } from "domhandler";
@@ -86,6 +87,12 @@ const cfg = {
8687
};
8788

8889
setConfig(cfg);
90+
setInterface({
91+
onServerbound: (type, fn) => {},
92+
onClientbound: (type, fn) => {},
93+
sendClientbound: (type, message) => {},
94+
sendServerbound: (type, message) => {},
95+
});
8996
export const bare = new BareClient(
9097
new LibcurlClient({
9198
wisp: cfg.wisp,
@@ -94,7 +101,8 @@ export const bare = new BareClient(
94101

95102
type Controller = {
96103
controllerframe: HTMLIFrameElement;
97-
cookiestore: CookieJar;
104+
cookieJar: CookieJar;
105+
fetchHandler: ScramjetFetchHandler;
98106
rootdomain: string;
99107
baseurl: URL;
100108
prefix: URL;
@@ -139,7 +147,33 @@ function makeController(url: URL): Controller {
139147
});
140148

141149
const prefix = new URL(baseurl.protocol + baseurl.host + cfg.prefix);
142-
const cookiestore = new CookieJar();
150+
const cookieJar = new CookieJar();
151+
152+
const fetchHandler = new ScramjetFetchHandler({
153+
client: bare,
154+
cookieJar,
155+
prefix: prefix,
156+
});
157+
fetchHandler.addEventListener("htmlPostRewrite", (e: any) => {
158+
const handler = e.handler as DomHandler;
159+
function findhead(node: Element): Element | null {
160+
if (node.type === ElementType.Tag && node.name === "head") {
161+
return node as Element;
162+
} else if (node.childNodes) {
163+
for (const child of node.childNodes) {
164+
const head = findhead(child as Element);
165+
if (head) return head;
166+
}
167+
}
168+
169+
return null;
170+
}
171+
172+
const head = findhead(handler.root as Node as Element)!;
173+
174+
// inject after the scramjet scripts and before the rest of the page
175+
head.children.splice(3, 0, new Element("script", { src: inject_script }));
176+
});
143177

144178
const controller = {
145179
controllerframe: frame,
@@ -149,7 +183,8 @@ function makeController(url: URL): Controller {
149183
prefix,
150184
ready,
151185
readyResolve: readyResolve!,
152-
cookiestore,
186+
cookieJar,
187+
fetchHandler,
153188
};
154189
controllers.push(controller);
155190

@@ -190,7 +225,7 @@ const methods = {
190225
controller: Controller
191226
): Promise<[ScramjetFetchResponse, Transferable[] | undefined]> {
192227
// repopulate fetchcontext fields with the items that weren't cloned over postMessage
193-
data.cookieStore = controller.cookiestore;
228+
data.cookieStore = controller.cookieJar;
194229
data.rawUrl = new URL(data.rawUrl);
195230
if (data.rawClientUrl) data.rawClientUrl = new URL(data.rawClientUrl);
196231
let headers = new ScramjetHeaders();
@@ -257,36 +292,7 @@ const methods = {
257292
}
258293
}
259294

260-
// TODO fix eventtarget jank
261-
const tgt = new EventTarget();
262-
tgt.addEventListener("htmlPostRewrite", (e: any) => {
263-
const handler = e.handler as DomHandler;
264-
function findhead(node: Element): Element | null {
265-
if (node.type === ElementType.Tag && node.name === "head") {
266-
return node as Element;
267-
} else if (node.childNodes) {
268-
for (const child of node.childNodes) {
269-
const head = findhead(child as Element);
270-
if (head) return head;
271-
}
272-
}
273-
274-
return null;
275-
}
276-
277-
const head = findhead(handler.root as Node as Element)!;
278-
279-
// inject after the scramjet scripts and before the rest of the page
280-
head.children.splice(3, 0, new Element("script", { src: inject_script }));
281-
});
282-
283-
const fetchresponse = await handleFetch.call(
284-
tgt as any,
285-
data,
286-
cfg,
287-
bare,
288-
controller.prefix
289-
);
295+
const fetchresponse = await controller.fetchHandler.handleFetch(data);
290296

291297
let transfer: any[] | undefined = undefined;
292298
if (

packages/chrome/src/Tab.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,12 @@ import { browser } from "./Browser";
44
import { History, type SerializedHistory } from "./History";
55
import { NewTabPage } from "./pages/NewTabPage";
66
import { PlaygroundPage } from "./pages/PlaygroundPage";
7-
import { createMenu } from "./components/Menu";
87
import { AboutPage } from "./pages/AboutPage";
98
import { HistoryPage } from "./pages/HistoryPage";
109
import { SettingsPage } from "./pages/SettingsPage";
1110
import { serviceWorkerReady } from "./main";
1211
import { DownloadsPage } from "./pages/DownloadsPage";
1312
import {
14-
ScramjetHeaders,
15-
ScramjetServiceWorker,
16-
type ScramjetInitConfig,
17-
type ScramjetFetchContext,
18-
ScramjetController,
19-
type ScramjetFetchResponse,
20-
handleFetch,
21-
rewriteUrl,
22-
config,
2313
ScramjetClient,
2414
ScramjetFrame,
2515
} from "@mercuryworkshop/scramjet/bundled";

packages/scramjet/src/client/dom/cookie.ts

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,22 @@
1+
import { iface } from "@/shared";
12
import type { MessageC2W, MessageW2C } from "@/worker";
23
import { ScramjetClient } from "@client/index";
34

45
export default function (client: ScramjetClient, self: typeof window) {
5-
client.serviceWorker.addEventListener(
6-
"message",
7-
({ data }: { data: MessageW2C }) => {
8-
if (!("scramjet$type" in data)) return;
9-
10-
if (data.scramjet$type === "cookie") {
11-
client.cookieStore.setCookies([data.cookie], new URL(data.url));
12-
const msg = {
13-
scramjet$token: data.scramjet$token,
14-
scramjet$type: "cookie",
15-
};
16-
client.serviceWorker.controller.postMessage(msg);
17-
}
18-
}
19-
);
6+
iface.onClientbound("setCookie", ({ cookie, url }) => {
7+
client.cookieStore.setCookies([cookie], new URL(url));
8+
return undefined;
9+
});
2010

2111
client.Trap("Document.prototype.cookie", {
2212
get() {
2313
return client.cookieStore.getCookies(client.url, true);
2414
},
2515
set(ctx, value: string) {
26-
client.cookieStore.setCookies([value], client.url);
27-
const controller = client.descriptors.get(
28-
"ServiceWorkerContainer.prototype.controller",
29-
client.serviceWorker
30-
);
31-
if (controller) {
32-
client.natives.call("ServiceWorker.prototype.postMessage", controller, {
33-
scramjet$type: "cookie",
34-
cookie: value,
35-
url: client.url.href,
36-
});
37-
}
16+
iface.sendServerbound("setCookie", {
17+
cookie: value,
18+
url: client.url.href,
19+
});
3820
},
3921
});
4022

packages/scramjet/src/shared/index.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,51 @@ export let bareTransport: BareTransport | null = null;
3838
export function setBareTransport(transport: BareTransport) {
3939
bareTransport = transport;
4040
}
41+
42+
export type Clientbound = {
43+
setCookie: [
44+
{
45+
cookie: string;
46+
url: string;
47+
},
48+
];
49+
};
50+
51+
export type Serverbound = {
52+
setCookie: [
53+
{
54+
cookie: string;
55+
url: string;
56+
},
57+
];
58+
blobData: [
59+
{
60+
id: string;
61+
data: Blob;
62+
},
63+
];
64+
};
65+
66+
export type ScramjetInterface = {
67+
sendServerbound<K extends keyof Serverbound>(
68+
type: K,
69+
msg: Serverbound[K][0]
70+
): Promise<Serverbound[K][1]>;
71+
onClientbound<K extends keyof Clientbound>(
72+
type: K,
73+
listener: (msg: Clientbound[K][0]) => Promise<Clientbound[K][1]>
74+
): () => void;
75+
sendClientbound<K extends keyof Clientbound>(
76+
type: K,
77+
msg: Clientbound[K][0]
78+
): Promise<Clientbound[K][1]>;
79+
onServerbound<K extends keyof Serverbound>(
80+
type: K,
81+
listener: (msg: Serverbound[K][0]) => Promise<Serverbound[K][1]>
82+
): () => void;
83+
};
84+
85+
export let iface: ScramjetInterface = null!;
86+
export function setInterface(newIface: ScramjetInterface) {
87+
iface = newIface;
88+
}

0 commit comments

Comments
 (0)