diff --git a/packages/engine-chronocat-api/src/globalVars.ts b/packages/engine-chronocat-api/src/globalVars.ts new file mode 100644 index 0000000..8de4865 --- /dev/null +++ b/packages/engine-chronocat-api/src/globalVars.ts @@ -0,0 +1,12 @@ +import type { Group, Profile, RedIpcData, RedIpcEvent } from '@chronocat/red' + +export const requestMethodMap: Record = {} +export const requestCallbackMap: Record< + string, + (this: RedIpcEvent, detail: RedIpcData) => void +> = {} + +export const groupMap: Record = {} +export const roleMap: Record> = {} +export const friendMap: Record = {} +export const richMediaDownloadMap: Record void> = {} diff --git a/packages/engine-chronocat-api/src/invoke.ts b/packages/engine-chronocat-api/src/invoke.ts new file mode 100644 index 0000000..05ff90e --- /dev/null +++ b/packages/engine-chronocat-api/src/invoke.ts @@ -0,0 +1,61 @@ +// https://github.com/import-js/eslint-plugin-import/issues/2802 +// eslint-disable-next-line import/no-unresolved +import { ipcMain } from 'electron' +import { requestCallbackMap } from './globalVars' +import type { NtApi } from './types' + +export const invoke = async ( + channel: string, + eventName: unknown, + ...args: unknown[] +) => { + const uuid = generateUUID() + const result = await Promise.race([ + new Promise((_, reject) => setTimeout(() => reject(), 10000)), + new Promise((resolve) => { + requestCallbackMap[uuid] = resolve + ipcMain.emit( + channel, + { + sender: { + send: (...args: unknown[]) => { + resolve(args) + }, + }, + }, + { + type: 'request', + callbackId: uuid, + eventName, + }, + args, + ) + }), + ]) + + delete requestCallbackMap[uuid] + + return result +} + +export type Invoke = typeof invoke + +export function define( + eventName: string, + method: string, +): NtApi { + return (...args: A) => + invoke('IPC_UP_2', eventName, method, ...args) as Promise +} + +const generateUUID = () => { + let d = new Date().getTime() + d += performance.now() + + const uuid = 'xxxxxxxx-xxxx-4xxx-8xxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = (d + Math.random() * 16) % 16 | 0 + d = Math.floor(d / 16) + return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16) + }) + return uuid +}