refactor: delete codecs/ & self.$scramjet

This commit is contained in:
velzie 2024-10-13 10:20:19 -04:00
parent f8d33a207e
commit 337134bcdc
No known key found for this signature in database
GPG key ID: AA51AEFB0A1F3820
22 changed files with 148 additions and 206 deletions

View file

@ -49,17 +49,18 @@ fn get_config(scramjet: &Object) -> Config {
let codec = &get_obj(scramjet, "codec"); let codec = &get_obj(scramjet, "codec");
let config = &get_obj(scramjet, "config"); let config = &get_obj(scramjet, "config");
let flags = &get_obj(config, "flags"); let flags = &get_obj(config, "flags");
let globals = &get_obj(config, "globals");
Config { Config {
prefix: get_str(config, "prefix"), prefix: get_str(config, "prefix"),
encode: create_encode_function(get_obj(codec, "encode")), encode: create_encode_function(get_obj(codec, "encode")),
wrapfn: get_str(config, "wrapfn"), wrapfn: get_str(globals, "wrapfn"),
importfn: get_str(config, "importfn"), importfn: get_str(globals, "importfn"),
rewritefn: get_str(config, "rewritefn"), rewritefn: get_str(globals, "rewritefn"),
metafn: get_str(config, "metafn"), metafn: get_str(globals, "metafn"),
setrealmfn: get_str(config, "setrealmfn"), setrealmfn: get_str(globals, "setrealmfn"),
pushsourcemapfn: get_str(config, "pushsourcemapfn"), pushsourcemapfn: get_str(globals, "pushsourcemapfn"),
do_sourcemaps: get_bool(flags, "sourcemaps"), do_sourcemaps: get_bool(flags, "sourcemaps"),
capture_errors: get_bool(flags, "captureErrors"), capture_errors: get_bool(flags, "captureErrors"),

View file

@ -419,7 +419,7 @@ fn expression_span(e: &Expression) -> Span {
} }
// js MUST not be able to get a reference to any of these because sbx // js MUST not be able to get a reference to any of these because sbx
const UNSAFE_GLOBALS: [&str; 9] = [ const UNSAFE_GLOBALS: [&str; 10] = [
"window", "window",
"self", "self",
"globalThis", "globalThis",

View file

@ -15,9 +15,7 @@ export default defineConfig({
entry: { entry: {
shared: join(__dirname, "src/shared/index.ts"), shared: join(__dirname, "src/shared/index.ts"),
worker: join(__dirname, "src/worker/index.ts"), worker: join(__dirname, "src/worker/index.ts"),
thread: join(__dirname, "src/thread/thread.ts"),
client: join(__dirname, "src/client/index.ts"), client: join(__dirname, "src/client/index.ts"),
codecs: join(__dirname, "src/codecs/index.ts"),
controller: join(__dirname, "src/controller/index.ts"), controller: join(__dirname, "src/controller/index.ts"),
sync: join(__dirname, "src/sync.ts"), sync: join(__dirname, "src/sync.ts"),
}, },

View file

@ -1,5 +1,6 @@
// entrypoint for scramjet.client.js // entrypoint for scramjet.client.js
import { loadCodecs } from "../scramjet";
import { SCRAMJETCLIENT } from "../symbols"; import { SCRAMJETCLIENT } from "../symbols";
import { ScramjetClient } from "./client"; import { ScramjetClient } from "./client";
import { ScramjetServiceWorkerRuntime } from "./swruntime"; import { ScramjetServiceWorkerRuntime } from "./swruntime";
@ -19,6 +20,8 @@ export class ScramjetContextInit extends Event {
dbg.log("scrammin"); dbg.log("scrammin");
// if it already exists, that means the handlers have probably already been setup by the parent document // if it already exists, that means the handlers have probably already been setup by the parent document
if (!(SCRAMJETCLIENT in <Partial<typeof self>>self)) { if (!(SCRAMJETCLIENT in <Partial<typeof self>>self)) {
loadCodecs();
const client = new ScramjetClient(self); const client = new ScramjetClient(self);
if (self.COOKIE) client.loadcookies(self.COOKIE); if (self.COOKIE) client.loadcookies(self.COOKIE);

View file

@ -4,7 +4,7 @@ import { config, rewriteJs } from "../../shared";
export default function (client: ScramjetClient, self: Self) { export default function (client: ScramjetClient, self: Self) {
// used for proxying *direct eval* // used for proxying *direct eval*
// eval("...") -> eval($scramjet$rewrite("...")) // eval("...") -> eval($scramjet$rewrite("..."))
Object.defineProperty(self, config.rewritefn, { Object.defineProperty(self, config.globals.rewritefn, {
value: function (js: any) { value: function (js: any) {
if (typeof js !== "string") return js; if (typeof js !== "string") return js;

View file

@ -5,7 +5,7 @@ import { rewriteUrl } from "../../shared/rewriters/url";
export default function (client: ScramjetClient, self: Self) { export default function (client: ScramjetClient, self: Self) {
const Function = client.natives.Function; const Function = client.natives.Function;
self[config.importfn] = function (base: string) { self[config.globals.importfn] = function (base: string) {
return function (url: string) { return function (url: string) {
const resolved = new URL(url, base).href; const resolved = new URL(url, base).href;
@ -15,7 +15,7 @@ export default function (client: ScramjetClient, self: Self) {
}; };
}; };
self[config.metafn] = function (base: string) { self[config.globals.metafn] = function (base: string) {
return { return {
url: base, url: base,
resolve: function (url: string) { resolve: function (url: string) {

View file

@ -60,7 +60,7 @@ export default function (client: ScramjetClient, self: typeof globalThis) {
// the main magic of the proxy. all attempts to access any "banned objects" will be redirected here, and instead served a proxy object // the main magic of the proxy. all attempts to access any "banned objects" will be redirected here, and instead served a proxy object
// this contrasts from how other proxies will leave the root object alone and instead attempt to catch every member access // this contrasts from how other proxies will leave the root object alone and instead attempt to catch every member access
// this presents some issues (see element.ts), but makes us a good bit faster at runtime! // this presents some issues (see element.ts), but makes us a good bit faster at runtime!
Object.defineProperty(self, config.wrapfn, { Object.defineProperty(self, config.globals.wrapfn, {
value: client.wrapfn, value: client.wrapfn,
writable: false, writable: false,
configurable: false, configurable: false,
@ -81,7 +81,7 @@ export default function (client: ScramjetClient, self: typeof globalThis) {
// ((t)=>$scramjet$tryset(location,"+=",t)||location+=t)(...); // ((t)=>$scramjet$tryset(location,"+=",t)||location+=t)(...);
// it has to be a discrete function because there's always the possibility that "location" is a local variable // it has to be a discrete function because there's always the possibility that "location" is a local variable
// we have to use an IIFE to avoid duplicating side-effects in the getter // we have to use an IIFE to avoid duplicating side-effects in the getter
Object.defineProperty(self, config.trysetfn, { Object.defineProperty(self, config.globals.trysetfn, {
value: function (lhs: any, op: string, rhs: any) { value: function (lhs: any, op: string, rhs: any) {
if (lhs instanceof Location) { if (lhs instanceof Location) {
// @ts-ignore // @ts-ignore

View file

@ -1,79 +0,0 @@
// for some reason eslint was parsing the type inside of the function params as a variable
export interface Codec {
// eslint-disable-next-line
encode: (str: string | undefined) => string;
// eslint-disable-next-line
decode: (str: string | undefined) => string;
}
const none = {
encode: (str: string | undefined) => str,
decode: (str: string | undefined) => str,
};
const plain = {
encode: (str: string | undefined) => {
if (!str) return str;
return encodeURIComponent(str);
},
decode: (str: string | undefined) => {
if (!str) return str;
return decodeURIComponent(str);
},
};
const xor = {
encode: (str: string | undefined, key: number = 2) => {
if (!str) return str;
let result = "";
for (let i = 0; i < str.length; i++) {
result += i % key ? String.fromCharCode(str.charCodeAt(i) ^ key) : str[i];
}
return encodeURIComponent(result);
},
decode: (str: string | undefined, key: number = 2) => {
if (!str) return str;
const [input, ...search] = str.split("?");
let result = "";
const decoded = decodeURIComponent(input);
for (let i = 0; i < decoded.length; i++) {
result +=
i % key ? String.fromCharCode(decoded.charCodeAt(i) ^ key) : decoded[i];
}
return result + (search.length ? "?" + search.join("?") : "");
},
};
const base64 = {
encode: (str: string | undefined) => {
if (!str) return str;
return decodeURIComponent(btoa(str));
},
decode: (str: string | undefined) => {
if (!str) return str;
return atob(str);
},
};
if (typeof self.$scramjet === "undefined") {
//@ts-expect-error really dumb workaround
self.$scramjet = {};
}
self.$scramjet.codecs = {
none,
plain,
xor,
base64,
};
if ("document" in self && document.currentScript) {
document.currentScript.remove();
}

View file

@ -1,30 +1,32 @@
import { ScramjetConfig } from "../types"; import { ScramjetConfig } from "../types";
import { Codec } from "../codecs"; import { Codec } from "../codecs";
import { ScramjetFrame } from "./frame"; import { ScramjetFrame } from "./frame";
import { $scramjet, loadCodecs } from "../scramjet";
export class ScramjetController { export class ScramjetController {
config: ScramjetConfig;
private store: IDBDatabase; private store: IDBDatabase;
codec: Codec;
constructor(config: ScramjetConfig) { constructor(config: Partial<ScramjetConfig>) {
// sane ish defaults
const defaultConfig: Partial<ScramjetConfig> = { const defaultConfig: Partial<ScramjetConfig> = {
prefix: "/scramjet/", prefix: "/scramjet/",
codec: "plain",
wrapfn: "$scramjet$wrap", globals: {
trysetfn: "$scramjet$tryset", wrapfn: "$scramjet$wrap",
importfn: "$scramjet$import", trysetfn: "$scramjet$tryset",
rewritefn: "$scramjet$rewrite", importfn: "$scramjet$import",
metafn: "$scramjet$meta", rewritefn: "$scramjet$rewrite",
setrealmfn: "$scramjet$setrealm", metafn: "$scramjet$meta",
pushsourcemapfn: "$scramjet$pushsourcemap", setrealmfn: "$scramjet$setrealm",
wasm: "/scramjet.wasm.js", pushsourcemapfn: "$scramjet$pushsourcemap",
shared: "/scramjet.shared.js", },
worker: "/scramjet.worker.js", files: {
thread: "/scramjet.thread.js", wasm: "/scramjet.wasm.js",
client: "/scramjet.client.js", shared: "/scramjet.shared.js",
codecs: "/scramjet.codecs.js", worker: "/scramjet.worker.js",
sync: "/scramjet.sync.js", client: "/scramjet.client.js",
sync: "/scramjet.sync.js",
},
flags: { flags: {
serviceworkers: false, serviceworkers: false,
naiiveRewriter: false, naiiveRewriter: false,
@ -34,6 +36,12 @@ export class ScramjetController {
scramitize: false, scramitize: false,
sourcemaps: false, sourcemaps: false,
}, },
codec: {
encode: `if (!url) return url;
return encodeURIComponent(url);`,
decode: `if (!url) return url;
return decodeURIComponent(url);`,
},
}; };
const deepMerge = (target: any, source: any): any => { const deepMerge = (target: any, source: any): any => {
@ -46,12 +54,11 @@ export class ScramjetController {
return Object.assign(target || {}, source); return Object.assign(target || {}, source);
}; };
this.config = deepMerge(defaultConfig, config); $scramjet.config = deepMerge(defaultConfig, config);
} }
async init(serviceWorkerPath: string): Promise<ServiceWorkerRegistration> { async init(serviceWorkerPath: string): Promise<ServiceWorkerRegistration> {
await import(/* webpackIgnore: true */ this.config.codecs); loadCodecs();
this.codec = self.$scramjet.codecs[this.config.codec];
await this.openIDB(); await this.openIDB();
@ -72,7 +79,7 @@ export class ScramjetController {
encodeUrl(url: string | URL): string { encodeUrl(url: string | URL): string {
if (url instanceof URL) url = url.toString(); if (url instanceof URL) url = url.toString();
return this.config.prefix + this.codec.encode(url); return $scramjet.config.prefix + $scramjet.codec.encode(url);
} }
async openIDB(): Promise<IDBDatabase> { async openIDB(): Promise<IDBDatabase> {
@ -102,7 +109,7 @@ export class ScramjetController {
} }
const tx = this.store.transaction("config", "readwrite"); const tx = this.store.transaction("config", "readwrite");
const store = tx.objectStore("config"); const store = tx.objectStore("config");
const req = store.put(this.config, "config"); const req = store.put($scramjet.config, "config");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
req.onsuccess = resolve; req.onsuccess = resolve;
@ -111,8 +118,8 @@ export class ScramjetController {
} }
async modifyConfig(config: ScramjetConfig) { async modifyConfig(config: ScramjetConfig) {
this.config = Object.assign({}, this.config, config); $scramjet.config = Object.assign({}, $scramjet.config, config);
this.codec = self.$scramjet.codecs[this.config.codec]; loadCodecs();
await this.#saveConfig(); await this.#saveConfig();
} }

3
src/global.d.ts vendored
View file

@ -5,4 +5,7 @@ declare const dbg: {
debug: (message: string, ...args: any[]) => void; debug: (message: string, ...args: any[]) => void;
}; };
declare const COMMITHASH: string;
declare const VERSION: string;
declare type Self = Window & typeof globalThis; declare type Self = Window & typeof globalThis;

26
src/scramjet.ts Normal file
View file

@ -0,0 +1,26 @@
import { ScramjetConfig } from "./types";
if (!("$scramjet" in self)) {
// @ts-expect-error ts stuff
self.$scramjet = {
version: {
build: COMMITHASH,
version: VERSION,
},
codec: {},
};
}
export const $scramjet = self.$scramjet;
const nativeFunction = Function;
export function loadCodecs() {
$scramjet.codec.encode = nativeFunction(
"url",
$scramjet.config.codec.encode
) as any;
$scramjet.codec.decode = nativeFunction(
"url",
$scramjet.config.codec.decode
) as any;
}

View file

@ -1,3 +1,5 @@
import { $scramjet } from "./scramjet";
export const { export const {
util: { BareClient, ScramjetHeaders, BareMuxConnection }, util: { BareClient, ScramjetHeaders, BareMuxConnection },
url: { rewriteUrl, unrewriteUrl, rewriteBlob, unrewriteBlob }, url: { rewriteUrl, unrewriteUrl, rewriteBlob, unrewriteBlob },
@ -13,6 +15,6 @@ export const {
htmlRules, htmlRules,
}, },
CookieStore, CookieStore,
} = self.$scramjet.shared; } = $scramjet.shared;
export const config = self.$scramjet.config; export const config = $scramjet.config;

View file

@ -14,8 +14,9 @@ import { parseDomain } from "parse-domain";
import { ScramjetHeaders } from "./headers"; import { ScramjetHeaders } from "./headers";
import { CookieStore } from "./cookie"; import { CookieStore } from "./cookie";
import { htmlRules, unrewriteHtml } from "./rewriters/html"; import { htmlRules, unrewriteHtml } from "./rewriters/html";
import { $scramjet } from "../scramjet";
self.$scramjet.shared = { $scramjet.shared = {
util: { util: {
parseDomain, parseDomain,
BareClient, BareClient,

View file

@ -6,6 +6,7 @@ import { rewriteCss } from "./css";
import { rewriteJs } from "./js"; import { rewriteJs } from "./js";
import { CookieStore } from "../cookie"; import { CookieStore } from "../cookie";
import { unrewriteBlob } from "../../shared/rewriters/url"; import { unrewriteBlob } from "../../shared/rewriters/url";
import { $scramjet } from "../../scramjet";
export function rewriteHtml( export function rewriteHtml(
html: string, html: string,
@ -43,8 +44,7 @@ export function rewriteHtml(
const dump = JSON.stringify(cookieStore.dump()); const dump = JSON.stringify(cookieStore.dump());
const injected = ` const injected = `
self.COOKIE = ${dump}; self.COOKIE = ${dump};
self.$scramjet.config = ${JSON.stringify(self.$scramjet.config)}; self.$scramjet.config = ${JSON.stringify($scramjet.config)};
self.$scramjet.codec = self.$scramjet.codecs[self.$scramjet.config.codec];
if ("document" in self && document.currentScript) { if ("document" in self && document.currentScript) {
document.currentScript.remove(); document.currentScript.remove();
} }
@ -53,11 +53,10 @@ export function rewriteHtml(
const script = (src) => new Element("script", { src }); const script = (src) => new Element("script", { src });
head.children.unshift( head.children.unshift(
script(self.$scramjet.config["wasm"]), script($scramjet.config.files.wasm),
script(self.$scramjet.config["codecs"]), script($scramjet.config.files.shared),
script("data:application/javascript;base64," + btoa(injected)), script("data:application/javascript;base64," + btoa(injected)),
script(self.$scramjet.config["shared"]), script($scramjet.config.files.client)
script(self.$scramjet.config["client"])
); );
} }

View file

@ -7,6 +7,7 @@ import {
rewrite_js, rewrite_js,
rewrite_js_from_arraybuffer, rewrite_js_from_arraybuffer,
} from "../../../rewriter/out/rewriter.js"; } from "../../../rewriter/out/rewriter.js";
import { $scramjet } from "../../scramjet";
initSync({ initSync({
module: new WebAssembly.Module( module: new WebAssembly.Module(
@ -19,7 +20,7 @@ init();
Error.stackTraceLimit = 50; Error.stackTraceLimit = 50;
export function rewriteJs(js: string | ArrayBuffer, meta: URLMeta) { export function rewriteJs(js: string | ArrayBuffer, meta: URLMeta) {
if (self.$scramjet.config.flags.naiiveRewriter) { if ($scramjet.config.flags.naiiveRewriter) {
const text = typeof js === "string" ? js : new TextDecoder().decode(js); const text = typeof js === "string" ? js : new TextDecoder().decode(js);
return rewriteJsNaiive(text); return rewriteJsNaiive(text);
@ -27,14 +28,12 @@ export function rewriteJs(js: string | ArrayBuffer, meta: URLMeta) {
const before = performance.now(); const before = performance.now();
if (typeof js === "string") { if (typeof js === "string") {
js = new TextDecoder().decode( js = new TextDecoder().decode(rewrite_js(js, meta.base.href, $scramjet));
rewrite_js(js, meta.base.href, self.$scramjet)
);
} else { } else {
js = rewrite_js_from_arraybuffer( js = rewrite_js_from_arraybuffer(
new Uint8Array(js), new Uint8Array(js),
meta.base.href, meta.base.href,
self.$scramjet $scramjet
); );
} }
const after = performance.now(); const after = performance.now();
@ -56,7 +55,7 @@ export function rewriteJsNaiive(js: string | ArrayBuffer) {
} }
return ` return `
with (${self.$scramjet.config.wrapfn}(globalThis)) { with (${$scramjet.config.globals.wrapfn}(globalThis)) {
${js} ${js}

View file

@ -1,3 +1,4 @@
import { $scramjet } from "../../scramjet";
import { rewriteJs } from "./js"; import { rewriteJs } from "./js";
export type URLMeta = { export type URLMeta = {
@ -31,9 +32,9 @@ export function rewriteUrl(url: string | URL, meta: URLMeta) {
if (url.startsWith("javascript:")) { if (url.startsWith("javascript:")) {
return "javascript:" + rewriteJs(url.slice("javascript:".length), meta); return "javascript:" + rewriteJs(url.slice("javascript:".length), meta);
} else if (url.startsWith("blob:")) { } else if (url.startsWith("blob:")) {
return location.origin + self.$scramjet.config.prefix + url; return location.origin + $scramjet.config.prefix + url;
} else if (url.startsWith("data:")) { } else if (url.startsWith("data:")) {
return location.origin + self.$scramjet.config.prefix + url; return location.origin + $scramjet.config.prefix + url;
} else if (url.startsWith("mailto:") || url.startsWith("about:")) { } else if (url.startsWith("mailto:") || url.startsWith("about:")) {
return url; return url;
} else { } else {
@ -43,8 +44,8 @@ export function rewriteUrl(url: string | URL, meta: URLMeta) {
return ( return (
location.origin + location.origin +
self.$scramjet.config.prefix + $scramjet.config.prefix +
self.$scramjet.codec.encode(new URL(url, base).href) $scramjet.codec.encode(new URL(url, base).href)
); );
} }
} }
@ -54,7 +55,7 @@ export function unrewriteUrl(url: string | URL) {
url = url.href; url = url.href;
} }
const prefixed = location.origin + self.$scramjet.config.prefix; const prefixed = location.origin + $scramjet.config.prefix;
if (url.startsWith("javascript:")) { if (url.startsWith("javascript:")) {
//TODO //TODO
@ -69,8 +70,8 @@ export function unrewriteUrl(url: string | URL) {
} else if (url.startsWith("mailto:") || url.startsWith("about:")) { } else if (url.startsWith("mailto:") || url.startsWith("about:")) {
return url; return url;
} else if (tryCanParseURL(url)) { } else if (tryCanParseURL(url)) {
return self.$scramjet.codec.decode( return $scramjet.codec.decode(
url.slice((location.origin + self.$scramjet.config.prefix).length) url.slice((location.origin + $scramjet.config.prefix).length)
); );
} else { } else {
return url; return url;

View file

@ -1,3 +1,4 @@
import { $scramjet } from "../../scramjet";
import { rewriteJs } from "./js"; import { rewriteJs } from "./js";
import { URLMeta } from "./url"; import { URLMeta } from "./url";
@ -9,22 +10,11 @@ export function rewriteWorkers(
) { ) {
let str = ""; let str = "";
str += `self.$scramjet = {}; self.$scramjet.config = ${JSON.stringify(self.$scramjet.config)}; for (const script of clientscripts) {
`; if (type === "module") {
str += ""; str += `import "${$scramjet.config.files[script]}"\n`;
if (type === "module") { } else {
str += `import "${self.$scramjet.config["codecs"]}" str += `importScripts("${$scramjet.config.files[script]}");\n`;
self.$scramjet.codec = self.$scramjet.codecs[self.$scramjet.config.codec];
`;
for (const script of clientscripts) {
str += `import "${self.$scramjet.config[script]}"\n`;
}
} else {
str += `importScripts("${self.$scramjet.config["codecs"]}");
self.$scramjet.codec = self.$scramjet.codecs[self.$scramjet.config.codec];
`;
for (const script of clientscripts) {
str += `importScripts("${self.$scramjet.config[script]}");\n`;
} }
} }

46
src/types.d.ts vendored
View file

@ -36,23 +36,28 @@ type ScramjetFlags = {
interface ScramjetConfig { interface ScramjetConfig {
prefix: string; prefix: string;
codec: string; globals: {
wrapfn: string; wrapfn: string;
trysetfn: string; trysetfn: string;
importfn: string; importfn: string;
rewritefn: string; rewritefn: string;
metafn: string; metafn: string;
setrealmfn: string; setrealmfn: string;
pushsourcemapfn: string; pushsourcemapfn: string;
wasm: string; };
shared: string; files: {
worker: string; wasm: string;
thread: string; shared: string;
client: string; worker: string;
codecs: string; client: string;
sync: string; sync: string;
};
flags: ScramjetFlags; flags: ScramjetFlags;
siteflags?: Record<string, ScramjetFlags>; siteflags: Record<string, ScramjetFlags>;
codec: {
encode: string;
decode: string;
};
} }
declare global { declare global {
@ -85,13 +90,10 @@ declare global {
CookieStore: typeof CookieStore; CookieStore: typeof CookieStore;
}; };
config: ScramjetConfig; config: ScramjetConfig;
codecs: { codec: {
none: Codec; encode: (url: string) => string;
plain: Codec; decode: (url: string) => string;
base64: Codec;
xor: Codec;
}; };
codec: Codec;
}; };
COOKIE: string; COOKIE: string;
WASM: string; WASM: string;

View file

@ -16,6 +16,7 @@ import {
} from "../shared"; } from "../shared";
import type { URLMeta } from "../shared/rewriters/url"; import type { URLMeta } from "../shared/rewriters/url";
import { $scramjet } from "../scramjet";
function newmeta(url: URL): URLMeta { function newmeta(url: URL): URLMeta {
return { return {
@ -115,7 +116,7 @@ export async function swfetch(
if ( if (
client && client &&
new URL(client.url).pathname.startsWith(self.$scramjet.config.prefix) new URL(client.url).pathname.startsWith($scramjet.config.prefix)
) { ) {
// TODO: i was against cors emulation but we might actually break stuff if we send full origin/referrer always // TODO: i was against cors emulation but we might actually break stuff if we send full origin/referrer always
const clientURL = new URL(unrewriteUrl(client.url)); const clientURL = new URL(unrewriteUrl(client.url));

View file

@ -3,22 +3,23 @@ import { swfetch } from "./fetch";
import { ScramjetThreadpool } from "./threadpool"; import { ScramjetThreadpool } from "./threadpool";
import type BareClient from "@mercuryworkshop/bare-mux"; import type BareClient from "@mercuryworkshop/bare-mux";
import { ScramjetConfig } from "../types"; import { ScramjetConfig } from "../types";
import { $scramjet, loadCodecs } from "../scramjet";
export class ScramjetServiceWorker extends EventTarget { export class ScramjetServiceWorker extends EventTarget {
client: BareClient; client: BareClient;
config: typeof self.$scramjet.config; config: ScramjetConfig;
threadpool: ScramjetThreadpool; threadpool: ScramjetThreadpool;
syncPool: Record<number, (val?: any) => void> = {}; syncPool: Record<number, (val?: any) => void> = {};
synctoken = 0; synctoken = 0;
cookieStore = new self.$scramjet.shared.CookieStore(); cookieStore = new $scramjet.shared.CookieStore();
serviceWorkers: FakeServiceWorker[] = []; serviceWorkers: FakeServiceWorker[] = [];
constructor() { constructor() {
super(); super();
this.client = new self.$scramjet.shared.util.BareClient(); this.client = new $scramjet.shared.util.BareClient();
this.threadpool = new ScramjetThreadpool(); this.threadpool = new ScramjetThreadpool();
@ -40,19 +41,6 @@ export class ScramjetServiceWorker extends EventTarget {
async loadConfig() { async loadConfig() {
if (this.config) return; if (this.config) return;
// const store = new IDBMap("config", {
// prefix: "scramjet",
// });
// if (store.has("config")) {
// const config = await store.get("config");
// this.config = config;
// self.$scramjet.config = config;
// self.$scramjet.codec = self.$scramjet.codecs[config.codec];
// }
// Recreate the above code using the stock IDB API
const request = indexedDB.open("$scramjet", 1); const request = indexedDB.open("$scramjet", 1);
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
@ -64,8 +52,9 @@ export class ScramjetServiceWorker extends EventTarget {
config.onsuccess = () => { config.onsuccess = () => {
this.config = config.result; this.config = config.result;
self.$scramjet.config = config.result; $scramjet.config = config.result;
self.$scramjet.codec = self.$scramjet.codecs[config.result.codec];
loadCodecs();
resolve(); resolve();
}; };

View file

@ -1,6 +1,5 @@
importScripts( importScripts(
"/scram/scramjet.wasm.js", "/scram/scramjet.wasm.js",
"/scram/scramjet.codecs.js",
"/scram/scramjet.shared.js", "/scram/scramjet.shared.js",
"/scram/scramjet.worker.js" "/scram/scramjet.worker.js"
); );

View file

@ -1,11 +1,11 @@
const scramjet = new ScramjetController({ const scramjet = new ScramjetController({
wasm: "/scram/scramjet.wasm.js", files: {
codecs: "/scram/scramjet.codecs.js", wasm: "/scram/scramjet.wasm.js",
worker: "/scram/scramjet.worker.js", worker: "/scram/scramjet.worker.js",
thread: "/scram/scramjet.thread.js", client: "/scram/scramjet.client.js",
client: "/scram/scramjet.client.js", shared: "/scram/scramjet.shared.js",
shared: "/scram/scramjet.shared.js", sync: "/scram/scramjet.sync.js",
sync: "/scram/scramjet.sync.js", },
}); });
scramjet.init("./sw.js"); scramjet.init("./sw.js");
@ -148,7 +148,7 @@ function App() {
return html` return html`
<div> <div>
<h1>Percury Unblocker</h1> <h1>scramjet</h1>
<p>surf the unblocked and mostly buggy web</p> <p>surf the unblocked and mostly buggy web</p>
<div class=${[flex, "cfg"]}> <div class=${[flex, "cfg"]}>