Files
TrueGrowth/vendor/aigcpanel/electron/mapi/event/main.ts
Jammy 52636c91ae
Some checks failed
CI / main (push) Has been cancelled
CI / release-e2e (push) Has been cancelled
Track bundled vendor runtime sources
2026-07-07 10:05:50 +08:00

220 lines
5.3 KiB
TypeScript

import { AppRuntime } from "../env";
import { ipcMain, WebContents } from "electron";
import { StrUtil } from "../../lib/util";
const init = async () => {};
type NameType = "main" | string | WebContents;
type EventType = "APP_READY" | "CALL_PAGE" | "CHANNEL" | "BROADCAST";
type BroadcastType =
| "ConfigChange"
| "ConfigEnvChange"
| "UserChange"
| "DarkModeChange"
| "HotkeyWatch"
| "Notice"
| "MonitorEvent";
const broadcast = (
type: BroadcastType,
data: any,
option?: {
limit?: boolean;
scopes?: string[];
pages?: string[];
},
) => {
data = data || {};
option = Object.assign(
{
limit: false,
scopes: [],
pages: [],
},
option,
);
if (option.pages.length > 0) {
for (const p of option.pages) {
send(p, "BROADCAST", { type, data });
}
} else {
if (!option.limit || option.scopes.includes("main")) {
send("main", "BROADCAST", { type, data });
}
if (!option.limit || option.scopes.includes("pages")) {
for (let name in AppRuntime.windows) {
send(name, "BROADCAST", { type, data });
}
}
}
};
const sendRaw = (
webContents: any,
type: EventType,
data: any = {},
id?: string,
): boolean => {
id = id || StrUtil.randomString(32);
const payload = { id, type, data };
webContents.send("MAIN_PROCESS_MESSAGE", payload);
return true;
};
const send = (
name: NameType,
type: EventType,
data: any = {},
id?: string,
): boolean => {
id = id || StrUtil.randomString(32);
const payload = { id, type, data };
if (typeof name !== "string") {
(name as WebContents).send("MAIN_PROCESS_MESSAGE", payload);
return true;
}
if (name === "main") {
if (!AppRuntime.mainWindow) {
return false;
}
// console.log('send', payload)
AppRuntime.mainWindow?.webContents.send(
"MAIN_PROCESS_MESSAGE",
payload,
);
} else {
if (!AppRuntime.windows[name]) {
return false;
}
AppRuntime.windows[name]?.webContents.send(
"MAIN_PROCESS_MESSAGE",
payload,
);
}
return true;
};
ipcMain.handle(
"event:send",
async (_, name: NameType, type: EventType, data: any) => {
send(name, type, data);
},
);
const callPage = async (
name: NameType,
type: string,
data: any,
option?: {
waitReadyTimeout?: number;
timeout?: number;
},
): Promise<{
code: number;
msg: string;
data?: any;
}> => {
option = Object.assign(
{
waitReadyTimeout: 10 * 1000,
timeout: 60 * 1000,
},
option,
);
return new Promise((resolve, reject) => {
const id = StrUtil.randomString(32);
const timer = setTimeout(() => {
ipcMain.removeListener(listenerKey, listener);
resolve({ code: -1, msg: "timeout" });
}, option.timeout);
const listener = (_, result) => {
clearTimeout(timer);
resolve(result);
return true;
};
const listenerKey = "event:callPage:" + id;
ipcMain.once(listenerKey, listener);
const payload = {
type,
data,
option: {
waitReadyTimeout: option.waitReadyTimeout,
},
};
if (!send(name, "CALL_PAGE", payload, id)) {
clearTimeout(timer);
ipcMain.removeListener(listenerKey, listener);
resolve({ code: -1, msg: "send failed" });
}
});
};
ipcMain.handle(
"event:callPage",
async (
_,
name: string,
type: string,
data: any,
option?: {
timeout?: number;
},
) => {
return callPage(name, type, data, option);
},
);
let onChannelIsListen = false;
let channelOnCallback = {};
const sendChannel = (channel: string, data: any) => {
send("main", "CHANNEL", { channel, data });
};
const onChannel = (channel: string, callback: (data: any) => void) => {
if (!channelOnCallback[channel]) {
channelOnCallback[channel] = [];
}
channelOnCallback[channel].push(callback);
if (!onChannelIsListen) {
onChannelIsListen = true;
ipcMain.handle("event:channelSend", (event, channel_, data) => {
if (channelOnCallback[channel_]) {
channelOnCallback[channel_].forEach(
(callback: (data: any) => void) => {
callback(data);
},
);
}
});
}
};
const offChannel = (channel: string, callback: (data: any) => void) => {
if (channelOnCallback[channel]) {
channelOnCallback[channel] = channelOnCallback[channel].filter(
(item: (data: any) => void) => {
return item !== callback;
},
);
}
if (channelOnCallback[channel].length === 0) {
delete channelOnCallback[channel];
}
};
export default {
init,
send,
};
export const Events = {
broadcast,
send,
sendRaw,
sendChannel,
callPage,
onChannel,
offChannel,
};