Files
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

270 lines
8.2 KiB
TypeScript

import ServerApi from "./api";
import { ipcMain } from "electron";
import { Log } from "../log/main";
import { mapError } from "./error";
import { AigcServer } from "../../aigcserver";
import { SendType, ServerContext, ServerInfo } from "./type";
import { Files } from "../file/main";
import { getGpuInfo } from "../../lib/env-main";
import { EnumServerType } from "../../../src/types/Server";
ipcMain.handle("server:listGpus", async (event) => {
return await getGpuInfo();
});
let runningServerCount = 0;
ipcMain.handle(
"server:runningServerCount",
async (event, count: number | null) => {
if (count === null) {
return runningServerCount;
}
// console.log('runningServerCount', count)
runningServerCount = count;
return runningServerCount;
},
);
const getRunningServerCount = () => {
return runningServerCount;
};
const serverModule: {
[key: string]: ServerContext;
} = {};
const init = () => {};
const getModule = async (
serverInfo: ServerInfo,
option?: {
throwException: boolean;
},
): Promise<ServerContext> => {
option = Object.assign(
{
throwException: true,
},
option,
);
// console.log('getModule', serverInfo)
if (!serverModule[serverInfo.localPath]) {
try {
if (serverInfo.name.startsWith("Cloud")) {
const server = new AigcServer["Cloud"]();
server.type = "buildIn";
server.ServerApi = ServerApi;
await server.init();
serverModule[serverInfo.localPath] = server;
} else if (serverInfo.name in AigcServer) {
const server = AigcServer[serverInfo.name] as ServerContext;
server.type = "buildIn";
server.ServerApi = ServerApi;
await server.init();
serverModule[serverInfo.localPath] = server;
} else if (serverInfo.type === EnumServerType.REMOTE) {
const server = new AigcServer["RemoteServer"](serverInfo);
server.type = "buildIn";
server.ServerApi = ServerApi;
await server.init();
serverModule[serverInfo.localPath] = server;
} else {
const serverPath = `${serverInfo.localPath}/server.js`;
const configPath = `${serverInfo.localPath}/config.json`;
let server = null;
if (
await Files.exists(serverPath, {
isDataPath: false,
})
) {
const module = await import(`file://${serverPath}`);
server = module.default;
}
if (
!server &&
(await Files.exists(configPath, {
isDataPath: false,
}))
) {
const configContent = await Files.read(configPath, {
isDataPath: false,
});
try {
const config = JSON.parse(configContent);
if (config.entry === "__EasyServer__") {
server = new AigcServer["EasyServer"](config);
} else {
throw `ServerEntryNotFound : ${config.entry}`;
}
} catch (e) {
throw `ConfigParseError : ${configPath}`;
}
}
if (!server) {
throw `ServerFileNotFound : ${serverPath}`;
}
server.type = "custom";
server.ServerApi = ServerApi;
if (server.init) {
await server.init();
}
server.send = (type: SendType, data: any) => {
server.ServerApi.event.sendChannel(
server.ServerInfo.eventChannelName,
{ type, data },
);
};
server.sendLog = (data: any) => {
server.ServerApi.file.appendText(
server.ServerInfo.logFile,
data,
{ isDataPath: true },
);
};
serverModule[serverInfo.localPath] = server;
}
} catch (e) {
if (!option.throwException) {
return null;
}
const error = mapError(e);
Log.error("mapi.server.getModule.error", error);
throw error;
}
}
// console.log('getModule', serverInfo, serverModule[serverInfo.localPath])
serverModule[serverInfo.localPath].ServerInfo = serverInfo;
return serverModule[serverInfo.localPath];
};
ipcMain.handle("server:isSupport", async (event, serverInfo: ServerInfo) => {
try {
const module = await getModule(serverInfo, {
throwException: false,
});
return !!module;
} catch (e) {
return false;
}
});
ipcMain.handle("server:start", async (event, serverInfo: ServerInfo) => {
const module = await getModule(serverInfo);
try {
return await module.start();
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.start.error", error);
throw error;
}
});
ipcMain.handle("server:ping", async (event, serverInfo: ServerInfo) => {
const module = await getModule(serverInfo);
try {
return await module.ping();
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.ping.error", error);
throw error;
}
return false;
});
ipcMain.handle("server:stop", async (event, serverInfo: ServerInfo) => {
const module = await getModule(serverInfo);
try {
return await module.stop();
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.stop.error", error);
throw error;
}
});
ipcMain.handle("server:cancel", async (event, serverInfo: ServerInfo) => {
const module = await getModule(serverInfo);
try {
return await module.cancel();
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.cancel.error", error);
throw error;
}
});
ipcMain.handle("server:deletes", async (event, serverInfo: ServerInfo) => {
if (serverModule[serverInfo.localPath]) {
delete serverModule[serverInfo.localPath];
}
return true;
});
ipcMain.handle("server:config", async (event, serverInfo: ServerInfo) => {
const module = await getModule(serverInfo);
try {
return await module.config();
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.config.error", error);
throw error;
}
});
ipcMain.handle(
"server:callFunction",
async (
event,
serverInfo: ServerInfo,
method: string,
data: any,
option: any,
) => {
// console.log('getModule.before', serverInfo, method)
const module = await getModule(serverInfo);
// console.log('getModule.end', serverInfo, method, module)
const func = module[method];
if (!func) {
throw new Error(`MethodNotFound : ${method}`);
}
try {
return await func.bind(module)(data, option || {});
} catch (e) {
const error = mapError(e);
Log.error("mapi.server.callFunction.error", {
type: typeof e,
error,
serverInfo,
method,
data,
option,
});
return {
code: -1,
msg: error,
};
}
},
);
export default {
init,
};
export const ServerMain = {
getRunningServerCount,
callFunction: async (
serverInfo: ServerInfo,
method: string,
data: any,
option?: any,
) => {
const module = await getModule(serverInfo);
const func = module[method];
if (!func) {
throw new Error(`MethodNotFound: ${method}`);
}
return await func.bind(module)(data, option || {});
},
};