From d0c282dffff24bb74a81cfa523f2f72f949bf8f9 Mon Sep 17 00:00:00 2001 From: Draculabo Date: Sun, 12 Apr 2026 15:18:22 +0800 Subject: [PATCH] refactor(ipc): migrate renderer IPC client to official oRPC client --- src/ipc/manager.ts | 117 +++++---------------------------------------- 1 file changed, 11 insertions(+), 106 deletions(-) diff --git a/src/ipc/manager.ts b/src/ipc/manager.ts index 16d1e49..37ef7d9 100644 --- a/src/ipc/manager.ts +++ b/src/ipc/manager.ts @@ -1,115 +1,16 @@ import { IPC_CHANNELS } from '@/constants'; -import { isString } from 'lodash-es'; +import { createORPCClient } from '@orpc/client'; +import { RPCLink } from '@orpc/client/message-port'; +import type { RouterClient } from '@orpc/server'; +import type { router } from './router'; -// Custom IPC Client that correctly builds method paths -function createIPCClient(port: MessagePort) { - let requestId = 0; - const pendingRequests = new Map< - string, - { resolve: (v: any) => void; reject: (e: any) => void } - >(); - - port.onmessage = (event) => { - try { - const data = isString(event.data) ? JSON.parse(event.data) : event.data; - - const id = data.i || data.id; - const pending = pendingRequests.get(id); - if (pending) { - pendingRequests.delete(id); - if (data.e || data.error) { - const errorMsg = data.e?.m || data.error?.message || JSON.stringify(data.e || data.error); - console.error('[IPCClient] Error response:', errorMsg); - pending.reject(new Error(errorMsg)); - } else { - // ORPC response format: { i, p: { b: { json: value }, s?: statusCode } } - // Or error: { i, p: { s: 500, b: { json: { code, message } } } } - let result; - const payload = data.p; - - // Check for error status - if (payload?.s && payload.s >= 400) { - const errorData = payload.b?.json; - const errorMsg = errorData?.message || errorData?.code || 'Server error'; - console.error('[IPCClient] Server error:', errorData); - pending.reject(new Error(errorMsg)); - return; - } - - // Extract successful result - if (payload?.b?.json !== undefined) { - result = payload.b.json; - } else if (data.r !== undefined) { - // Fallback to 'r' field if present - result = data.r?.b?.json ?? data.r; - } else if ('result' in data) { - result = data.result; - } - - pending.resolve(result); - } - } else { - console.warn('[IPCClient] No pending request for id:', id); - } - } catch (e) { - console.error('[IPCClient] Error parsing response:', e, event.data); - } - }; - - async function callMethod(path: string[], input?: unknown): Promise { - const id = String(++requestId); - const methodPath = path.join('/'); - - return new Promise((resolve, reject) => { - pendingRequests.set(id, { resolve, reject }); - - // ORPC MessagePort protocol format - const payload = { - i: id, - p: { - u: `orpc://localhost/${methodPath}`, - b: { json: input ?? null }, - }, - }; - - port.postMessage(JSON.stringify(payload)); - - setTimeout(() => { - if (pendingRequests.has(id)) { - pendingRequests.delete(id); - reject(new Error(`Request /${methodPath} timed out`)); - } - }, 60000); - }); - } - - // Create a Proxy that builds the path chain - function createProxyChain(pathSoFar: string[] = []): any { - return new Proxy(() => {}, { - get(_target, prop: string) { - if (prop === 'then' || prop === 'catch' || prop === 'finally') { - // Don't intercept promise methods - return undefined; - } - // Build deeper path - return createProxyChain([...pathSoFar, prop]); - }, - apply(_target, _thisArg, args) { - // Called as function - execute RPC - const input = args[0]; - return callMethod(pathSoFar, input); - }, - }); - } - - return createProxyChain(); -} +type IPCClient = RouterClient; class IPCManager { private readonly clientPort: MessagePort; private readonly serverPort: MessagePort; - public readonly client: any; // Will be typed via usage + public readonly client: IPCClient; private initialized: boolean = false; @@ -118,7 +19,11 @@ class IPCManager { this.clientPort = port1; this.serverPort = port2; - this.client = createIPCClient(this.clientPort); + this.client = createORPCClient( + new RPCLink({ + port: this.clientPort, + }), + ); } public initialize() {