Skip to content

Commit

Permalink
feat: move arrpc server into a worker thread
Browse files Browse the repository at this point in the history
  • Loading branch information
pendo324 committed Jan 16, 2025
1 parent 5a72491 commit bec9764
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 14 deletions.
6 changes: 6 additions & 0 deletions scripts/build/build.mts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ await Promise.all([
outfile: "dist/js/main.js",
footer: { js: "//# sourceURL=VCDMain" }
}),
createContext({
...NodeCommonOpts,
entryPoints: ["src/main/arrpcWorker.ts"],
outfile: "dist/js/arrpcWorker.js",
footer: { js: "//# sourceURL=VCDArrpcWorker" }
}),
createContext({
...NodeCommonOpts,
entryPoints: ["src/preload/index.ts"],
Expand Down
62 changes: 48 additions & 14 deletions src/main/arrpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,65 @@
* Copyright (c) 2023 Vendicated and Vencord contributors
*/

import Server from "arrpc";
import { IpcEvents } from "shared/IpcEvents";
import { MessageChannel, Worker } from "worker_threads";
const { port1: hostPort, port2: workerPort } = new MessageChannel();

// @ts-ignore: ts error looking for type defintions
// import arrpcWorkerScript from "inline:./arrpcWorker.ts";
import { resolve } from "path";

import { mainWin } from "./mainWindow";
import { Settings } from "./settings";
import { ArrpcEvent, ArrpcHostEvent } from "./utils/arrpcWorkerTypes";

let server: any;
let worker: any;

const inviteCodeRegex = /^(\w|-)+$/;

export async function initArRPC() {
if (server || !Settings.store.arRPC) return;
if (worker || !Settings.store.arRPC) return;

try {
server = await new Server();
server.on("activity", (data: any) => mainWin.webContents.send(IpcEvents.ARRPC_ACTIVITY, JSON.stringify(data)));
server.on("invite", (invite: string, callback: (valid: boolean) => void) => {
invite = String(invite);
if (!inviteCodeRegex.test(invite)) return callback(false);

mainWin.webContents
// Safety: Result of JSON.stringify should always be safe to equal
// Also, just to be super super safe, invite is regex validated above
.executeJavaScript(`Vesktop.openInviteModal(${JSON.stringify(invite)})`)
.then(callback);
worker = new Worker(resolve(__dirname, "./arrpcWorker.js"), {
workerData: {
workerPort
},
transferList: [workerPort]
});
hostPort.on("message", (e: ArrpcEvent) => {
switch (e.eventType) {
case IpcEvents.ARRPC_ACTIVITY: {
mainWin.webContents.send(IpcEvents.ARRPC_ACTIVITY, e.data);
break;
}
case "invite": {
const invite = String(e.data);

if (!inviteCodeRegex.test(invite)) {
const hostEvent: ArrpcHostEvent = {
eventType: "ack-invite",
data: false,
inviteId: e.inviteId
};
return hostPort.postMessage(hostEvent);
}

mainWin.webContents
// Safety: Result of JSON.stringify should always be safe to equal
// Also, just to be super super safe, invite is regex validated above
.executeJavaScript(`Vesktop.openInviteModal(${JSON.stringify(invite)})`)
.then(() => {
const hostEvent: ArrpcHostEvent = {
eventType: "ack-invite",
data: true,
inviteId: e.inviteId
};
hostPort.postMessage(hostEvent);
});
break;
}
}
});
} catch (e) {
console.error("Failed to start arRPC server", e);
Expand Down
42 changes: 42 additions & 0 deletions src/main/arrpcWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* SPDX-License-Identifier: GPL-3.0
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
* Copyright (c) 2023 Vendicated and Vencord contributors
*/

import Server from "arrpc";
import { IpcEvents } from "shared/IpcEvents";
import { MessagePort, workerData } from "worker_threads";

import { ArrpcEvent, ArrpcHostEvent } from "./utils/arrpcWorkerTypes";

let server: any;

type InviteCallback = (valid: boolean) => void;

let inviteCallbacks: Array<InviteCallback> = [];

(async function () {
const { workerPort }: { workerPort: MessagePort } = workerData;
server = await new Server();
server.on("activity", (data: any) => {
const event: ArrpcEvent = {
eventType: IpcEvents.ARRPC_ACTIVITY,
data: JSON.stringify(data)
};
workerPort.postMessage(event);
});
server.on("invite", (invite: string, callback: InviteCallback) => {
const event: ArrpcEvent = {
eventType: "invite",
data: invite,
inviteId: inviteCallbacks.push(callback) - 1
};
workerPort.postMessage(event);
});

workerPort.on("message", (e: ArrpcHostEvent) => {
inviteCallbacks[e.inviteId](e.data);
inviteCallbacks = [...inviteCallbacks.slice(0, e.inviteId), ...inviteCallbacks.slice(e.inviteId + 1)];
});
})();
26 changes: 26 additions & 0 deletions src/main/utils/arrpcWorkerTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: GPL-3.0
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
* Copyright (c) 2023 Vendicated and Vencord contributors
*/

import { IpcEvents } from "shared/IpcEvents";

export type ArrpcEvent = ArrpcActivityEvent | ArrpcInviteEvent;

export interface ArrpcActivityEvent {
eventType: IpcEvents.ARRPC_ACTIVITY;
data: string;
}

export interface ArrpcInviteEvent {
eventType: "invite";
data: string;
inviteId: number;
}

export interface ArrpcHostEvent {
eventType: "ack-invite";
inviteId: number;
data: boolean;
}

0 comments on commit bec9764

Please sign in to comment.