File size: 2,663 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
// i am a cat. i like to be petted. i like to be fed. i like to be
import { initSync, Rewriter } from "../../../rewriter/wasm/out/wasm.js";
import type { JsRewriterOutput } from "../../../rewriter/wasm/out/wasm.js";
import { codecDecode, codecEncode, config, flagEnabled } from "..";
export type { JsRewriterOutput, Rewriter };
import { rewriteUrl, URLMeta } from "./url";
import { htmlRules } from "../htmlRules";
import { rewriteCss, unrewriteCss } from "./css";
import { rewriteJs } from "./js";
import { getInjectScripts } from "./html";
import { CookieStore } from "../cookie";
let wasm_u8: Uint8Array;
if (self.WASM)
wasm_u8 = Uint8Array.from(atob(self.WASM), (c) => c.charCodeAt(0));
// only use in sw
export async function asyncSetWasm() {
const buf = await fetch(config.files.wasm).then((r) => r.arrayBuffer());
wasm_u8 = new Uint8Array(buf);
}
export const textDecoder = new TextDecoder();
let MAGIC = "\0asm".split("").map((x) => x.charCodeAt(0));
function initWasm() {
if (!(wasm_u8 instanceof Uint8Array))
throw new Error("rewriter wasm not found (was it fetched correctly?)");
if (![...wasm_u8.slice(0, 4)].every((x, i) => x === MAGIC[i]))
throw new Error(
"rewriter wasm does not have wasm magic (was it fetched correctly?)\nrewriter wasm contents: " +
textDecoder.decode(wasm_u8)
);
initSync({
module: new WebAssembly.Module(wasm_u8),
});
}
let rewriters = [];
export function getRewriter(meta: URLMeta): [Rewriter, () => void] {
initWasm();
let obj: { rewriter: Rewriter; inUse: boolean };
let index = rewriters.findIndex((x) => !x.inUse);
let len = rewriters.length;
if (index === -1) {
if (flagEnabled("rewriterLogs", meta.base))
console.log(`creating new rewriter, ${len} rewriters made already`);
let rewriter = new Rewriter({
config,
shared: {
rewrite: {
htmlRules,
rewriteUrl,
rewriteCss,
rewriteJs,
getHtmlInjectCode(cookieStore: CookieStore, foundHead: boolean) {
let inject = getInjectScripts(
cookieStore,
(src) => `<script src="${src}"></script>`
).join("");
return foundHead ? `<head>${inject}</head>` : inject;
},
},
},
flagEnabled,
codec: {
encode: codecEncode,
decode: codecDecode,
},
});
obj = { rewriter, inUse: false };
rewriters.push(obj);
} else {
if (flagEnabled("rewriterLogs", meta.base))
console.log(
`using cached rewriter ${index} from list of ${len} rewriters`
);
obj = rewriters[index];
}
obj.inUse = true;
return [obj.rewriter, () => (obj.inUse = false)];
}
|