mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 14:30:02 -04:00
threads 🚀🚀🚀
This commit is contained in:
parent
b06605dc52
commit
d433f67d67
8 changed files with 179 additions and 26 deletions
|
@ -7,10 +7,11 @@ const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|||
|
||||
export default defineConfig({
|
||||
// change to production when needed
|
||||
mode: "production",
|
||||
mode: "development",
|
||||
entry: {
|
||||
shared: join(__dirname, "src/shared/index.ts"),
|
||||
worker: join(__dirname, "src/worker/index.ts"),
|
||||
thread: join(__dirname, "src/thread/thread.ts"),
|
||||
client: join(__dirname, "src/client/index.ts"),
|
||||
config: join(__dirname, "src/scramjet.config.ts"),
|
||||
codecs: join(__dirname, "src/codecs/index.ts"),
|
||||
|
|
|
@ -8,6 +8,7 @@ self.$scramjet.config = {
|
|||
config: "/scram/scramjet.config.js",
|
||||
shared: "/scram/scramjet.shared.js",
|
||||
worker: "/scram/scramjet.worker.js",
|
||||
thread: "/scram/scramjet.thread.js",
|
||||
client: "/scram/scramjet.client.js",
|
||||
codecs: "/scram/scramjet.codecs.js",
|
||||
};
|
||||
|
|
46
src/thread/thread.ts
Normal file
46
src/thread/thread.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { rewriteJs } from "../shared/rewriters/js";
|
||||
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
onconnect = (e) => {
|
||||
const port = e.ports[0];
|
||||
|
||||
|
||||
console.log("thread: connected to port", port)
|
||||
port.postMessage("ready");
|
||||
|
||||
let syncToken = 0;
|
||||
port.onmessage = ({ data }) => {
|
||||
console.log("thread: received message", data)
|
||||
const [task, ...args] = data;
|
||||
let token = syncToken++;
|
||||
|
||||
try {
|
||||
let res = tasks[task](...args);
|
||||
console.log("thread: task", task, "completed with token", token)
|
||||
port.postMessage({
|
||||
token,
|
||||
result: res
|
||||
})
|
||||
} catch (e) {
|
||||
port.postMessage({
|
||||
token,
|
||||
error: e.message
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
port.postMessage("idle");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const tasks = {
|
||||
"rewriteJs": taskRewriteJs,
|
||||
}
|
||||
|
||||
|
||||
function taskRewriteJs(js: ArrayBuffer, origin: string): string {
|
||||
return rewriteJs(js, new URL(origin));
|
||||
}
|
1
src/types.d.ts
vendored
1
src/types.d.ts
vendored
|
@ -37,6 +37,7 @@ declare global {
|
|||
config: string;
|
||||
shared: string;
|
||||
worker: string;
|
||||
thread: string;
|
||||
client: string;
|
||||
codecs: string;
|
||||
};
|
||||
|
|
|
@ -115,8 +115,7 @@ export async function swfetch(this: ScramjetServiceWorker, { request }: FetchEve
|
|||
}
|
||||
break;
|
||||
case "script":
|
||||
// responseBody = rewriteJs(await response.text(), url);
|
||||
responseBody = rewriteJs(await response.text());
|
||||
responseBody = await this.threadpool.rewriteJs(await response.arrayBuffer(), url.toString());
|
||||
break;
|
||||
case "style":
|
||||
responseBody = rewriteCss(await response.text(), url);
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
import { swfetch } from "./fetch";
|
||||
import { ScramjetThreadpool } from "./threadpool";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
ScramjetServiceWorker;
|
||||
ScramjetThread;
|
||||
}
|
||||
}
|
||||
|
||||
export class ScramjetServiceWorker {
|
||||
client: typeof self.$scramjet.shared.util.BareClient.prototype;
|
||||
config: typeof self.$scramjet.config;
|
||||
threadpool: ScramjetThreadpool;
|
||||
|
||||
constructor(config = self.$scramjet.config) {
|
||||
this.client = new self.$scramjet.shared.util.BareClient();
|
||||
if (!config.prefix) config.prefix = "/scramjet/";
|
||||
this.config = config;
|
||||
|
||||
this.threadpool = new ScramjetThreadpool();
|
||||
|
||||
}
|
||||
|
||||
route({ request }: FetchEvent) {
|
||||
|
@ -27,6 +31,4 @@ export class ScramjetServiceWorker {
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
self.ScramjetServiceWorker = ScramjetServiceWorker;
|
||||
|
|
92
src/worker/threadpool.ts
Normal file
92
src/worker/threadpool.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
|
||||
type Thread = {
|
||||
handle: MessagePort;
|
||||
ready: boolean;
|
||||
busy: boolean;
|
||||
syncToken: number;
|
||||
promises: Map<number, { resolve, reject }>;
|
||||
}
|
||||
|
||||
export class ScramjetThreadpool {
|
||||
threads: Thread[] = [];
|
||||
constructor() {
|
||||
self.addEventListener("message", ({ data }) => {
|
||||
if (data.scramjet$type == "add") {
|
||||
this.spawn(data.handle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
spawn(handle) {
|
||||
const thread = {
|
||||
handle,
|
||||
ready: false,
|
||||
busy: false,
|
||||
syncToken: 0,
|
||||
promises: new Map()
|
||||
}
|
||||
|
||||
this.threads.push(thread);
|
||||
|
||||
thread.handle.onmessage = (e) => {
|
||||
if (e.data === "ready") {
|
||||
thread.ready = true;
|
||||
return;
|
||||
}
|
||||
if (e.data === "idle") {
|
||||
thread.busy = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const { token, result, error } = e.data;
|
||||
const { resolve, reject } = thread.promises.get(token);
|
||||
thread.promises.delete(token);
|
||||
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
}
|
||||
|
||||
thread.handle.start();
|
||||
}
|
||||
|
||||
pick(): Thread | undefined {
|
||||
const alive = this.threads.filter(t => t.ready);
|
||||
const idle = alive.filter(t => !t.busy);
|
||||
|
||||
// no threads
|
||||
if (!alive.length) return;
|
||||
|
||||
// there is a thread, but it's busy
|
||||
if (!idle.length) return alive[Math.floor(Math.random() * alive.length)];
|
||||
|
||||
// there's an open thread
|
||||
return idle[Math.floor(Math.random() * idle.length)];
|
||||
}
|
||||
|
||||
run(task: string, args: any[], transferrable: any[]): Promise<any> {
|
||||
const thread = this.pick();
|
||||
if (!thread) throw new Error("No threads available");
|
||||
thread.busy = true;
|
||||
|
||||
|
||||
let token = thread.syncToken++;
|
||||
|
||||
// console.log("runthread: dispatching task", task, "to thread", thread, "of token", token)
|
||||
return new Promise((resolve, reject) => {
|
||||
thread.promises.set(token, { resolve, reject });
|
||||
|
||||
thread.handle.postMessage([
|
||||
task,
|
||||
...args
|
||||
], transferrable);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async rewriteJs(js: ArrayBuffer, origin: string): Promise<string> {
|
||||
return await this.run("rewriteJs", [js, origin], [js]);
|
||||
}
|
||||
}
|
51
static/ui.js
51
static/ui.js
|
@ -1,10 +1,21 @@
|
|||
navigator.serviceWorker
|
||||
.register("./sw.js", {
|
||||
scope: $scramjet.config.prefix,
|
||||
})
|
||||
.then((reg) => {
|
||||
reg.update();
|
||||
});
|
||||
.register("./sw.js")
|
||||
.then((reg) => {
|
||||
reg.update();
|
||||
});
|
||||
|
||||
navigator.serviceWorker.ready.then((reg) => {
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const thread = new SharedWorker($scramjet.config.thread, { name: "thread" + i });
|
||||
|
||||
reg.active.postMessage({
|
||||
scramjet$type: "add",
|
||||
handle: thread.port
|
||||
}, [thread.port]);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
const connection = new BareMux.BareMuxConnection("/baremux/worker.js");
|
||||
const flex = css`
|
||||
display: flex;
|
||||
|
@ -13,21 +24,21 @@ const col = css`
|
|||
flex-direction: column;
|
||||
`;
|
||||
const store = $store(
|
||||
{
|
||||
url: "https://google.com",
|
||||
wispurl: "wss://wisp.mercurywork.shop/",
|
||||
bareurl:
|
||||
(location.protocol === "https:" ? "https" : "http") +
|
||||
"://" +
|
||||
location.host +
|
||||
"/bare/",
|
||||
},
|
||||
{ ident: "settings", backing: "localstorage", autosave: "auto" }
|
||||
{
|
||||
url: "https://google.com",
|
||||
wispurl: "wss://wisp.mercurywork.shop/",
|
||||
bareurl:
|
||||
(location.protocol === "https:" ? "https" : "http") +
|
||||
"://" +
|
||||
location.host +
|
||||
"/bare/",
|
||||
},
|
||||
{ ident: "settings", backing: "localstorage", autosave: "auto" }
|
||||
);
|
||||
connection.setTransport("/baremod/index.mjs", [store.bareurl]);
|
||||
function App() {
|
||||
this.urlencoded = "";
|
||||
this.css = `
|
||||
this.urlencoded = "";
|
||||
this.css = `
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #e0def4;
|
||||
|
@ -86,7 +97,7 @@ function App() {
|
|||
}
|
||||
`;
|
||||
|
||||
return html`
|
||||
return html`
|
||||
<div>
|
||||
<h1>Percury Unblocker</h1>
|
||||
<p>surf the unblocked and mostly buggy web</p>
|
||||
|
@ -110,5 +121,5 @@ function App() {
|
|||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
document.body.appendChild(h(App));
|
||||
document.body.appendChild(h(App));
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue