Add dedicated injector

This commit is contained in:
2025-02-13 17:34:28 +01:00
parent f2e59cfda3
commit cdc69bd932
15 changed files with 77384 additions and 1070 deletions
+13 -88
View File
@@ -1,99 +1,15 @@
// Creating artificial API between two worlds
export type InterceptBefore = (requestInfo: string, init?: RequestInit) => Promise<void> | void;
export type InterceptAfter = (requestInfo: string, response: Response, init?: RequestInit) => Promise<void> | void;
export class Interceptor {
private static fetch = window.fetch;
private static overwritten = false;
private static before = new Map<string, InterceptBefore[]>();
private static after = new Map<string, InterceptAfter[]>();
private constructor() {}
private static overrideFetch() {
if (this.overwritten) {
return;
}
this.overwritten = true;
(window as any).fetch = async (...args: any) => {
const url = ((args[0] as RequestInfo | URL) || "").toString();
const init = args[1];
const befores = [...(this.before.get(url) || []), ...(this.before.get("*") || [])];
if (befores) {
for (const before of befores) {
await before(url, init);
}
}
const response = (this.fetch as any)(...args);
const afters = [...(this.after.get(url) || []), ...(this.after.get("*") || [])];
if (afters) {
const result = await response;
for (const after of afters) {
try {
await after(url, result, init);
} catch (_) {}
}
return response;
} else {
return response;
}
};
}
static onAfter(url: string, cb: InterceptAfter) {
Interceptor.overrideFetch();
const arr = Interceptor.after.get(url) || [];
if (!arr.includes(cb)) {
arr.push(cb);
}
Interceptor.after.set(url, arr);
}
static offAfter(url: string, cb: InterceptAfter) {
const arr = Interceptor.after.get(url) || [];
const index = arr.indexOf(cb);
if (index !== -1) {
arr.splice(index, 1);
}
if (arr.length) {
Interceptor.after.set(url, arr);
} else {
Interceptor.after.delete(url);
}
}
static onBefore(url: string, cb: InterceptBefore) {
Interceptor.overrideFetch();
const arr = Interceptor.before.get(url) || [];
if (!arr.includes(cb)) {
arr.push(cb);
}
Interceptor.before.set(url, arr);
}
static offBefore(url: string, cb: InterceptBefore) {
const arr = Interceptor.before.get(url) || [];
const index = arr.indexOf(cb);
if (index !== -1) {
arr.splice(index, 1);
}
if (arr.length) {
Interceptor.before.set(url, arr);
} else {
Interceptor.before.delete(url);
}
}
}
import { EVENT_CROSS_WORLD_INJECTED, EVENT_CROSS_WORLD_PIXEL_PLACED, EVENT_CROSS_WORLD_URL_UPDATE } from "./constants";
import { Interceptor } from "./lib/interceptor";
import { HistoryPushStateSpy } from "./lib/urlHistorySpy.ts";
Interceptor.onAfter("/api/pixel", async (_, response, init) => {
try {
if (response.status === 200 && init && "body" in init) {
const body = JSON.parse(init.body as any);
if ("x" in body && "y" in body && "color" in body) {
const pixelsPlaced = new CustomEvent("__pixelsPlaced", {
const pixelsPlaced = new CustomEvent(EVENT_CROSS_WORLD_PIXEL_PLACED, {
detail: { color: body.color, x: body.x, y: body.y },
});
document.dispatchEvent(pixelsPlaced);
@@ -103,3 +19,12 @@ Interceptor.onAfter("/api/pixel", async (_, response, init) => {
console.error(error);
}
});
HistoryPushStateSpy.onPushState((_, __, url) => {
const pixelsPlaced = new CustomEvent(EVENT_CROSS_WORLD_URL_UPDATE, {
detail: url,
});
document.dispatchEvent(pixelsPlaced);
});
document.dispatchEvent(new CustomEvent(EVENT_CROSS_WORLD_INJECTED));