forked from johannesjo/parallel-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathipc.ts
More file actions
59 lines (51 loc) · 1.7 KB
/
ipc.ts
File metadata and controls
59 lines (51 loc) · 1.7 KB
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
// Core IPC — wraps Electron's ipcRenderer for frontend-backend communication.
import { IPC } from '../../electron/ipc/channels';
declare global {
interface Window {
electron: {
ipcRenderer: {
invoke: (channel: string, ...args: unknown[]) => Promise<unknown>;
send: (channel: string, ...args: unknown[]) => void;
on: (channel: string, listener: (...args: unknown[]) => void) => () => void;
removeAllListeners: (channel: string) => void;
};
};
}
}
export class Channel<T> {
private _id = crypto.randomUUID();
cleanup: (() => void) | null = null;
onmessage: ((msg: T) => void) | null = null;
constructor() {
this.cleanup = window.electron.ipcRenderer.on(`channel:${this._id}`, (msg: unknown) => {
this.onmessage?.(msg as T);
});
}
get id() {
return this._id;
}
toJSON() {
return { __CHANNEL_ID__: this._id };
}
}
export async function invoke<T>(cmd: IPC, args?: Record<string, unknown>): Promise<T> {
// JSON round-trip ensures all args are structured-clone-safe.
// Triggers Channel.toJSON() to replace Channel instances with
// plain { __CHANNEL_ID__: id } objects.
const safeArgs = args ? (JSON.parse(JSON.stringify(args)) as Record<string, unknown>) : undefined;
return window.electron.ipcRenderer.invoke(cmd, safeArgs) as Promise<T>;
}
/**
* Invoke an IPC command without awaiting the result.
* Logs errors to console and optionally calls onError for user-visible feedback.
*/
export function fireAndForget(
cmd: IPC,
args?: Record<string, unknown>,
onError?: (err: unknown) => void,
): void {
invoke(cmd, args).catch((err: unknown) => {
console.error(`[IPC] ${cmd} failed:`, err);
onError?.(err);
});
}