@chenpeiyuan/electron-message 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -30,9 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
32
  Main: () => Main,
33
- Preload: () => Preload
33
+ Preload: () => Preload,
34
+ expose: () => expose
34
35
  });
35
36
  module.exports = __toCommonJS(index_exports);
37
+ var import_electron3 = require("electron");
36
38
 
37
39
  // main/Preload.ts
38
40
  var import_electron = require("electron");
@@ -286,9 +288,22 @@ var Main = class extends Base {
286
288
  });
287
289
  }
288
290
  };
291
+
292
+ // main/index.ts
293
+ function expose(key = "service", config) {
294
+ const preload = new Preload(config);
295
+ preload.init();
296
+ import_electron3.contextBridge.exposeInMainWorld(key, {
297
+ invoke: preload.invoke.bind(preload),
298
+ getService: preload.getService.bind(preload),
299
+ addService: preload.addService.bind(preload),
300
+ addServices: preload.addServices.bind(preload)
301
+ });
302
+ }
289
303
  // Annotate the CommonJS export names for ESM import in node:
290
304
  0 && (module.exports = {
291
305
  Main,
292
- Preload
306
+ Preload,
307
+ expose
293
308
  });
294
309
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../main/index.ts","../main/Preload.ts","../main/Base.ts","../main/reqEvent.ts","../main/resEvent.ts","../main/Main.ts"],"sourcesContent":["import {\r\n type ServiceReqEvent,\r\n} from './reqEvent'\r\nimport {\r\n type Service,\r\n} from './Base'\r\n\r\nexport {\r\n Preload\r\n} from './Preload'\r\nexport {\r\n Main\r\n} from './Main'\r\n\r\n/**\r\n * 暴露接口类型\r\n */\r\nexport type ExposeApi = {\r\n /**\r\n * 调用服务\r\n * @param reqEvent \r\n * @returns \r\n */\r\n invoke: (reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) => Promise<any>\r\n \r\n /**\r\n * 添加服务\r\n * @param api \r\n * @param service \r\n * @returns \r\n */\r\n addService: (api: string, service: Service) => void\r\n\r\n /**\r\n * 添加服务\r\n * @param services \r\n * @returns \r\n */\r\n addServices: (services: Record<string, Service>) => void\r\n}\r\n","import { ipcRenderer } from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n checkReqEvent, \r\n createReqEvent,\r\n type ServiceReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n createResEvent,\r\n} from './resEvent'\r\n\r\n/**\r\n * 预加载脚本\r\n */\r\nexport class Preload extends Base {\r\n\r\n async invoke(reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) {\r\n const {\r\n log,\r\n reqChannel,\r\n resChannel,\r\n } = this.config\r\n\r\n reqEvent = createReqEvent(reqEvent)\r\n log.debug(reqChannel, reqEvent)\r\n\r\n const resEvent = await ipcRenderer.invoke(reqChannel, reqEvent)\r\n log.debug(resChannel, resEvent, {endAt: Date.now()})\r\n\r\n return resEvent.error || resEvent.result\r\n }\r\n\r\n override doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 处理请求\r\n ipcRenderer.addListener(reqChannel, async (\r\n event: Electron.IpcRendererEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n const resEvent = createResEvent(reqEvent, {})\r\n try {\r\n const service = this.getService(reqEvent.api)\r\n if (service == null) {\r\n throw new Error(`客户端服务无法找到: ${reqEvent.api}`)\r\n }\r\n \r\n resEvent.result = await service(...reqEvent.params)\r\n }\r\n catch(error) {\r\n resEvent.error = toErrorObject(error)\r\n }\r\n \r\n ipcRenderer.send(resChannel, resEvent)\r\n log.debug(resChannel, resEvent)\r\n })\r\n }\r\n}","/**\r\n * 服务函数类型\r\n */\r\nexport type Service = (...params: Array<any>) => Promise<any>\r\n\r\n/**\r\n * 错误转对象方法\r\n */\r\ntype ToErrorObjectFn = (obj: any) => any\r\n\r\n/**\r\n * 打印日志方法\r\n */\r\ntype LogFn = (...args: Array<any>) => void\r\n\r\n/**\r\n * 默认错误转对象方法\r\n * @param obj \r\n * @returns \r\n */\r\nexport const toErrorObject = (obj: any): any => {\r\n if (obj instanceof Error) {\r\n const result: any = {\r\n error: obj.name,\r\n stack: obj.stack,\r\n cause: obj.cause,\r\n message: obj.message,\r\n }\r\n if ('extras' in obj) {\r\n result.extras = obj['extras']\r\n }\r\n return result\r\n }\r\n return obj\r\n}\r\n\r\n/**\r\n * 默认日志方法\r\n * @param args \r\n */\r\nconst log = function(...args: Array<any>) {\r\n console.log(...args)\r\n}\r\n\r\n/**\r\n * 配置类型\r\n */\r\nexport type Config = {\r\n reqChannel: string\r\n resChannel: string\r\n toErrorObject: ToErrorObjectFn\r\n log: {\r\n trace: LogFn,\r\n debug: LogFn,\r\n info: LogFn,\r\n warn: LogFn,\r\n error: LogFn,\r\n }\r\n}\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst reqChannel = 'runService:req'\r\nconst resChannel = 'runService:res'\r\nconst defaultConfig = {\r\n reqChannel,\r\n resChannel,\r\n toErrorObject,\r\n log: {\r\n trace: log,\r\n debug: log,\r\n info: log,\r\n warn: log,\r\n error: log,\r\n }\r\n}\r\n\r\nexport class Base {\r\n private inited = false\r\n private readonly services = new Map<string, Service>()\r\n protected readonly config: Config\r\n\r\n constructor(config?: Partial<Config>) {\r\n this.config = Object.assign({}, defaultConfig, config)\r\n }\r\n\r\n /**\r\n * 获取服务\r\n * @param key \r\n * @returns \r\n */\r\n getService(key: string): Service | undefined {\r\n return this.services.get(key)\r\n }\r\n\r\n /**\r\n * 添加服务\r\n * @param key \r\n * @param service \r\n */\r\n addService(key: string, service: Service): void {\r\n this.services.set(key, service)\r\n }\r\n\r\n /**\r\n * 添加多个服务\r\n * @param services \r\n */\r\n addServices(services: Record<string, Service>): void {\r\n Object.entries(services)\r\n .forEach(([key, service]) => {\r\n this.addService(key, service)\r\n })\r\n }\r\n\r\n /**\r\n * 删除服务\r\n * @param key \r\n */\r\n delService(key: string): void {\r\n this.services.delete(key)\r\n }\r\n\r\n /**\r\n * 初始化\r\n * @returns \r\n */\r\n init(): void {\r\n if (this.inited) {\r\n return\r\n }\r\n this.inited = true\r\n\r\n // 安装基础设施\r\n this.doInit()\r\n }\r\n\r\n protected doInit(): void {\r\n return\r\n }\r\n\r\n}","import z from 'zod'\r\n\r\n/**\r\n * 服务请求定义\r\n */\r\nconst ServiceReqEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n params: z.array(z.any()),\r\n reqAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务请求类型\r\n */\r\nexport type ServiceReqEvent = z.infer<typeof ServiceReqEventSchema>\r\n\r\n/**\r\n * 创建标识\r\n * @returns \r\n */\r\nexport function generateId(): string {\r\n const prefix = Date.now().toString(36)\r\n const suffix = Math.random().toString(36).substring(2, 6)\r\n return `${prefix}:${suffix}`\r\n}\r\n\r\n/**\r\n * 创建服务请求\r\n * @param event \r\n * @returns \r\n */\r\nexport function createReqEvent(\r\n event: Omit<ServiceReqEvent, 'id' | 'reqAt'>\r\n): ServiceReqEvent {\r\n const id = generateId()\r\n return {\r\n ...event,\r\n id, \r\n reqAt: Date.now()\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务请求\r\n * @param event \r\n */\r\nexport function checkReqEvent(event: any): void {\r\n ServiceReqEventSchema.parse(event)\r\n}","import z from 'zod'\r\nimport type { ServiceReqEvent } from './reqEvent'\r\n\r\n/**\r\n * 服务响应定义\r\n */\r\nconst ServiceResEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n error: z.object({\r\n error: z.string(),\r\n message: z.string(),\r\n stack: z.string().optional(),\r\n extras: z.any().optional()\r\n }).optional(),\r\n result: z.any().optional(),\r\n reqAt: z.number(),\r\n resAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务响应类型\r\n */\r\nexport type ServiceResEvent = z.infer<typeof ServiceResEventSchema>\r\n\r\n/**\r\n * 创建服务响应\r\n * @param reqEvent \r\n * @param resEvent \r\n * @returns \r\n */\r\nexport function createResEvent(\r\n reqEvent: ServiceReqEvent, \r\n resEvent: Pick<ServiceResEvent, 'error' | 'result'>\r\n): ServiceResEvent {\r\n const { \r\n id, \r\n api, \r\n dst: src, \r\n src: dst, \r\n reqAt \r\n } = reqEvent\r\n return {\r\n ...resEvent,\r\n id,\r\n api,\r\n dst,\r\n src,\r\n reqAt,\r\n resAt: Date.now(),\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务响应\r\n * @param event \r\n */\r\nexport function checkResEvent(event: object): void {\r\n ServiceResEventSchema.parse(event)\r\n}","import { \r\n type WebContents, \r\n ipcMain, \r\n} from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n type ServiceReqEvent, \r\n checkReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n type ServiceResEvent,\r\n checkResEvent,\r\n createResEvent\r\n} from './resEvent'\r\n\r\n/**\r\n * 主线程脚本\r\n */\r\nexport abstract class Main extends Base {\r\n private readonly resolvers = new Map<string, PromiseWithResolvers<any>>()\r\n\r\n /**\r\n * 获取网页对象\r\n * @param reqEvent \r\n */\r\n protected abstract getWebContents(reqEvent: ServiceReqEvent): WebContents\r\n\r\n doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 转发请求\r\n ipcMain.handle(reqChannel, async (\r\n event: Electron.IpcMainInvokeEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n try {\r\n // 主线程\r\n if (!reqEvent.dst) {\r\n log.debug('调用主线程服务')\r\n \r\n const { api, params } = reqEvent\r\n const service = this.getService(api)\r\n if (service == null) {\r\n throw new Error(`主线程服务无法找到: ${api}`)\r\n }\r\n \r\n const result = await service(...params)\r\n const resEvent = createResEvent(reqEvent, {\r\n result,\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n \r\n // 渲染线程\r\n log.debug('调用渲染线程服务')\r\n \r\n // 转发请求\r\n const webContents = this.getWebContents(reqEvent)\r\n webContents.send(reqChannel, reqEvent)\r\n \r\n const resolver = Promise.withResolvers<any>()\r\n this.resolvers.set(reqEvent.id, resolver)\r\n return resolver.promise\r\n }\r\n catch(error) {\r\n const resEvent = createResEvent(reqEvent, {\r\n error: toErrorObject(error),\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n })\r\n \r\n // 转发响应\r\n ipcMain.addListener(resChannel, (\r\n event: Electron.IpcMainEvent, \r\n resEvent: ServiceResEvent\r\n ) => {\r\n log.debug(resChannel, resEvent)\r\n checkResEvent(resEvent)\r\n\r\n const resolver = this.resolvers.get(resEvent.id)\r\n if (resolver == null) {\r\n throw new Error(`请求无法找到: ${resEvent.id}`)\r\n }\r\n\r\n this.resolvers.delete(resEvent.id)\r\n resolver.resolve(resEvent)\r\n })\r\n }\r\n}"],"mappings":"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","names":["z","import_zod","z","log","reqChannel","resChannel","toErrorObject","import_electron","log","reqChannel","resChannel","toErrorObject"]}
1
+ {"version":3,"sources":["../main/index.ts","../main/Preload.ts","../main/Base.ts","../main/reqEvent.ts","../main/resEvent.ts","../main/Main.ts"],"sourcesContent":["import {\n type ServiceReqEvent,\n} from './reqEvent'\nimport {\n type Config,\n type Service,\n} from './Base'\nimport { contextBridge } from 'electron'\nimport { Preload } from './Preload'\n\nexport {\n Preload\n} from './Preload'\nexport {\n Main\n} from './Main'\nexport {\n type Config,\n type Service\n} from './Base'\n\n/**\n * 暴露接口类型\n */\nexport type ExposeApi = {\n /**\n * 调用服务\n * @param reqEvent \n * @returns \n */\n invoke: (reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) => Promise<any>\n\n /**\n * 获取服务\n * @param key \n */\n getService(key: string): Service | undefined\n \n /**\n * 添加服务\n * @param api \n * @param service \n * @returns \n */\n addService: (api: string, service: Service) => void\n\n /**\n * 添加服务\n * @param services \n * @returns \n */\n addServices: (services: Record<string, Service>) => void\n}\n\n/**\n * 暴露方法到渲染线程\n * \n * @param key \n * @param config \n */\nexport function expose(key = 'service', config?: Partial<Config>) {\n const preload = new Preload(config)\n preload.init()\n\n contextBridge.exposeInMainWorld(key, {\n invoke: preload.invoke.bind(preload),\n getService: preload.getService.bind(preload),\n addService: preload.addService.bind(preload),\n addServices: preload.addServices.bind(preload),\n })\n}","import { ipcRenderer } from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n checkReqEvent, \r\n createReqEvent,\r\n type ServiceReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n createResEvent,\r\n} from './resEvent'\r\n\r\n/**\r\n * 预加载脚本\r\n */\r\nexport class Preload extends Base {\r\n\r\n async invoke(reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) {\r\n const {\r\n log,\r\n reqChannel,\r\n resChannel,\r\n } = this.config\r\n\r\n reqEvent = createReqEvent(reqEvent)\r\n log.debug(reqChannel, reqEvent)\r\n\r\n const resEvent = await ipcRenderer.invoke(reqChannel, reqEvent)\r\n log.debug(resChannel, resEvent, {endAt: Date.now()})\r\n\r\n return resEvent.error || resEvent.result\r\n }\r\n\r\n override doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 处理请求\r\n ipcRenderer.addListener(reqChannel, async (\r\n event: Electron.IpcRendererEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n const resEvent = createResEvent(reqEvent, {})\r\n try {\r\n const service = this.getService(reqEvent.api)\r\n if (service == null) {\r\n throw new Error(`客户端服务无法找到: ${reqEvent.api}`)\r\n }\r\n \r\n resEvent.result = await service(...reqEvent.params)\r\n }\r\n catch(error) {\r\n resEvent.error = toErrorObject(error)\r\n }\r\n \r\n ipcRenderer.send(resChannel, resEvent)\r\n log.debug(resChannel, resEvent)\r\n })\r\n }\r\n}","/**\r\n * 服务函数类型\r\n */\r\nexport type Service = (...params: Array<any>) => Promise<any>\r\n\r\n/**\r\n * 错误转对象方法\r\n */\r\ntype ToErrorObjectFn = (obj: any) => any\r\n\r\n/**\r\n * 打印日志方法\r\n */\r\ntype LogFn = (...args: Array<any>) => void\r\n\r\n/**\r\n * 默认错误转对象方法\r\n * @param obj \r\n * @returns \r\n */\r\nexport const toErrorObject = (obj: any): any => {\r\n if (obj instanceof Error) {\r\n const result: any = {\r\n error: obj.name,\r\n stack: obj.stack,\r\n cause: obj.cause,\r\n message: obj.message,\r\n }\r\n if ('extras' in obj) {\r\n result.extras = obj['extras']\r\n }\r\n return result\r\n }\r\n return obj\r\n}\r\n\r\n/**\r\n * 默认日志方法\r\n * @param args \r\n */\r\nconst log = function(...args: Array<any>) {\r\n console.log(...args)\r\n}\r\n\r\n/**\r\n * 配置类型\r\n */\r\nexport type Config = {\r\n reqChannel: string\r\n resChannel: string\r\n toErrorObject: ToErrorObjectFn\r\n log: {\r\n trace: LogFn,\r\n debug: LogFn,\r\n info: LogFn,\r\n warn: LogFn,\r\n error: LogFn,\r\n }\r\n}\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst reqChannel = 'runService:req'\r\nconst resChannel = 'runService:res'\r\nconst defaultConfig = {\r\n reqChannel,\r\n resChannel,\r\n toErrorObject,\r\n log: {\r\n trace: log,\r\n debug: log,\r\n info: log,\r\n warn: log,\r\n error: log,\r\n }\r\n}\r\n\r\nexport class Base {\r\n private inited = false\r\n private readonly services = new Map<string, Service>()\r\n protected readonly config: Config\r\n\r\n constructor(config?: Partial<Config>) {\r\n this.config = Object.assign({}, defaultConfig, config)\r\n }\r\n\r\n /**\r\n * 获取服务\r\n * @param key \r\n * @returns \r\n */\r\n getService(key: string): Service | undefined {\r\n return this.services.get(key)\r\n }\r\n\r\n /**\r\n * 添加服务\r\n * @param key \r\n * @param service \r\n */\r\n addService(key: string, service: Service): void {\r\n this.services.set(key, service)\r\n }\r\n\r\n /**\r\n * 添加多个服务\r\n * @param services \r\n */\r\n addServices(services: Record<string, Service>): void {\r\n Object.entries(services)\r\n .forEach(([key, service]) => {\r\n this.addService(key, service)\r\n })\r\n }\r\n\r\n /**\r\n * 删除服务\r\n * @param key \r\n */\r\n delService(key: string): void {\r\n this.services.delete(key)\r\n }\r\n\r\n /**\r\n * 初始化\r\n * @returns \r\n */\r\n init(): void {\r\n if (this.inited) {\r\n return\r\n }\r\n this.inited = true\r\n\r\n // 安装基础设施\r\n this.doInit()\r\n }\r\n\r\n protected doInit(): void {\r\n return\r\n }\r\n\r\n}","import z from 'zod'\r\n\r\n/**\r\n * 服务请求定义\r\n */\r\nconst ServiceReqEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n params: z.array(z.any()),\r\n reqAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务请求类型\r\n */\r\nexport type ServiceReqEvent = z.infer<typeof ServiceReqEventSchema>\r\n\r\n/**\n * 创建标识\n * @returns \n */\nexport function generateId(): string {\n const prefix = Date.now().toString(36)\n const suffix = Math.random().toString(36).substring(2, 6)\n return `${prefix}:${suffix}`\n}\r\n\r\n/**\r\n * 创建服务请求\r\n * @param event \r\n * @returns \r\n */\r\nexport function createReqEvent(\r\n event: Omit<ServiceReqEvent, 'id' | 'reqAt'>\r\n): ServiceReqEvent {\r\n const id = generateId()\r\n return {\r\n ...event,\r\n id, \r\n reqAt: Date.now()\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务请求\r\n * @param event \r\n */\r\nexport function checkReqEvent(event: any): void {\r\n ServiceReqEventSchema.parse(event)\r\n}","import z from 'zod'\r\nimport type { ServiceReqEvent } from './reqEvent'\r\n\r\n/**\r\n * 服务响应定义\r\n */\r\nconst ServiceResEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n error: z.object({\r\n error: z.string(),\r\n message: z.string(),\r\n stack: z.string().optional(),\r\n extras: z.any().optional()\r\n }).optional(),\r\n result: z.any().optional(),\r\n reqAt: z.number(),\r\n resAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务响应类型\r\n */\r\nexport type ServiceResEvent = z.infer<typeof ServiceResEventSchema>\r\n\r\n/**\r\n * 创建服务响应\r\n * @param reqEvent \r\n * @param resEvent \r\n * @returns \r\n */\r\nexport function createResEvent(\r\n reqEvent: ServiceReqEvent, \r\n resEvent: Pick<ServiceResEvent, 'error' | 'result'>\r\n): ServiceResEvent {\r\n const { \r\n id, \r\n api, \r\n dst: src, \r\n src: dst, \r\n reqAt \r\n } = reqEvent\r\n return {\r\n ...resEvent,\r\n id,\r\n api,\r\n dst,\r\n src,\r\n reqAt,\r\n resAt: Date.now(),\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务响应\r\n * @param event \r\n */\r\nexport function checkResEvent(event: object): void {\r\n ServiceResEventSchema.parse(event)\r\n}","import { \r\n type WebContents, \r\n ipcMain, \r\n} from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n type ServiceReqEvent, \r\n checkReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n type ServiceResEvent,\r\n checkResEvent,\r\n createResEvent\r\n} from './resEvent'\r\n\r\n/**\r\n * 主线程脚本\r\n */\r\nexport abstract class Main extends Base {\r\n private readonly resolvers = new Map<string, PromiseWithResolvers<any>>()\r\n\r\n /**\r\n * 获取网页对象\r\n * @param reqEvent \r\n */\r\n protected abstract getWebContents(reqEvent: ServiceReqEvent): WebContents\r\n\r\n doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 转发请求\r\n ipcMain.handle(reqChannel, async (\r\n event: Electron.IpcMainInvokeEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n try {\r\n // 主线程\r\n if (!reqEvent.dst) {\r\n log.debug('调用主线程服务')\r\n \r\n const { api, params } = reqEvent\r\n const service = this.getService(api)\r\n if (service == null) {\r\n throw new Error(`主线程服务无法找到: ${api}`)\r\n }\r\n \r\n const result = await service(...params)\r\n const resEvent = createResEvent(reqEvent, {\r\n result,\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n \r\n // 渲染线程\r\n log.debug('调用渲染线程服务')\r\n \r\n // 转发请求\r\n const webContents = this.getWebContents(reqEvent)\r\n webContents.send(reqChannel, reqEvent)\r\n \r\n const resolver = Promise.withResolvers<any>()\r\n this.resolvers.set(reqEvent.id, resolver)\r\n return resolver.promise\r\n }\r\n catch(error) {\r\n const resEvent = createResEvent(reqEvent, {\r\n error: toErrorObject(error),\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n })\r\n \r\n // 转发响应\r\n ipcMain.addListener(resChannel, (\r\n event: Electron.IpcMainEvent, \r\n resEvent: ServiceResEvent\r\n ) => {\r\n log.debug(resChannel, resEvent)\r\n checkResEvent(resEvent)\r\n\r\n const resolver = this.resolvers.get(resEvent.id)\r\n if (resolver == null) {\r\n throw new Error(`请求无法找到: ${resEvent.id}`)\r\n }\r\n\r\n this.resolvers.delete(resEvent.id)\r\n resolver.resolve(resEvent)\r\n })\r\n }\r\n}"],"mappings":"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","names":["import_electron","z","import_zod","z","log","reqChannel","resChannel","toErrorObject","import_electron","log","reqChannel","resChannel","toErrorObject"]}
package/dist/index.d.cts CHANGED
@@ -110,6 +110,11 @@ type ExposeApi = {
110
110
  * @returns
111
111
  */
112
112
  invoke: (reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) => Promise<any>;
113
+ /**
114
+ * 获取服务
115
+ * @param key
116
+ */
117
+ getService(key: string): Service | undefined;
113
118
  /**
114
119
  * 添加服务
115
120
  * @param api
@@ -124,5 +129,12 @@ type ExposeApi = {
124
129
  */
125
130
  addServices: (services: Record<string, Service>) => void;
126
131
  };
132
+ /**
133
+ * 暴露方法到渲染线程
134
+ *
135
+ * @param key
136
+ * @param config
137
+ */
138
+ declare function expose(key?: string, config?: Partial<Config>): void;
127
139
 
128
- export { type ExposeApi, Main, Preload };
140
+ export { type Config, type ExposeApi, Main, Preload, type Service, expose };
package/dist/index.d.ts CHANGED
@@ -110,6 +110,11 @@ type ExposeApi = {
110
110
  * @returns
111
111
  */
112
112
  invoke: (reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) => Promise<any>;
113
+ /**
114
+ * 获取服务
115
+ * @param key
116
+ */
117
+ getService(key: string): Service | undefined;
113
118
  /**
114
119
  * 添加服务
115
120
  * @param api
@@ -124,5 +129,12 @@ type ExposeApi = {
124
129
  */
125
130
  addServices: (services: Record<string, Service>) => void;
126
131
  };
132
+ /**
133
+ * 暴露方法到渲染线程
134
+ *
135
+ * @param key
136
+ * @param config
137
+ */
138
+ declare function expose(key?: string, config?: Partial<Config>): void;
127
139
 
128
- export { type ExposeApi, Main, Preload };
140
+ export { type Config, type ExposeApi, Main, Preload, type Service, expose };
package/dist/index.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ // main/index.ts
2
+ import { contextBridge } from "electron";
3
+
1
4
  // main/Preload.ts
2
5
  import { ipcRenderer } from "electron";
3
6
 
@@ -252,8 +255,21 @@ var Main = class extends Base {
252
255
  });
253
256
  }
254
257
  };
258
+
259
+ // main/index.ts
260
+ function expose(key = "service", config) {
261
+ const preload = new Preload(config);
262
+ preload.init();
263
+ contextBridge.exposeInMainWorld(key, {
264
+ invoke: preload.invoke.bind(preload),
265
+ getService: preload.getService.bind(preload),
266
+ addService: preload.addService.bind(preload),
267
+ addServices: preload.addServices.bind(preload)
268
+ });
269
+ }
255
270
  export {
256
271
  Main,
257
- Preload
272
+ Preload,
273
+ expose
258
274
  };
259
275
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../main/Preload.ts","../main/Base.ts","../main/reqEvent.ts","../main/resEvent.ts","../main/Main.ts"],"sourcesContent":["import { ipcRenderer } from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n checkReqEvent, \r\n createReqEvent,\r\n type ServiceReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n createResEvent,\r\n} from './resEvent'\r\n\r\n/**\r\n * 预加载脚本\r\n */\r\nexport class Preload extends Base {\r\n\r\n async invoke(reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) {\r\n const {\r\n log,\r\n reqChannel,\r\n resChannel,\r\n } = this.config\r\n\r\n reqEvent = createReqEvent(reqEvent)\r\n log.debug(reqChannel, reqEvent)\r\n\r\n const resEvent = await ipcRenderer.invoke(reqChannel, reqEvent)\r\n log.debug(resChannel, resEvent, {endAt: Date.now()})\r\n\r\n return resEvent.error || resEvent.result\r\n }\r\n\r\n override doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 处理请求\r\n ipcRenderer.addListener(reqChannel, async (\r\n event: Electron.IpcRendererEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n const resEvent = createResEvent(reqEvent, {})\r\n try {\r\n const service = this.getService(reqEvent.api)\r\n if (service == null) {\r\n throw new Error(`客户端服务无法找到: ${reqEvent.api}`)\r\n }\r\n \r\n resEvent.result = await service(...reqEvent.params)\r\n }\r\n catch(error) {\r\n resEvent.error = toErrorObject(error)\r\n }\r\n \r\n ipcRenderer.send(resChannel, resEvent)\r\n log.debug(resChannel, resEvent)\r\n })\r\n }\r\n}","/**\r\n * 服务函数类型\r\n */\r\nexport type Service = (...params: Array<any>) => Promise<any>\r\n\r\n/**\r\n * 错误转对象方法\r\n */\r\ntype ToErrorObjectFn = (obj: any) => any\r\n\r\n/**\r\n * 打印日志方法\r\n */\r\ntype LogFn = (...args: Array<any>) => void\r\n\r\n/**\r\n * 默认错误转对象方法\r\n * @param obj \r\n * @returns \r\n */\r\nexport const toErrorObject = (obj: any): any => {\r\n if (obj instanceof Error) {\r\n const result: any = {\r\n error: obj.name,\r\n stack: obj.stack,\r\n cause: obj.cause,\r\n message: obj.message,\r\n }\r\n if ('extras' in obj) {\r\n result.extras = obj['extras']\r\n }\r\n return result\r\n }\r\n return obj\r\n}\r\n\r\n/**\r\n * 默认日志方法\r\n * @param args \r\n */\r\nconst log = function(...args: Array<any>) {\r\n console.log(...args)\r\n}\r\n\r\n/**\r\n * 配置类型\r\n */\r\nexport type Config = {\r\n reqChannel: string\r\n resChannel: string\r\n toErrorObject: ToErrorObjectFn\r\n log: {\r\n trace: LogFn,\r\n debug: LogFn,\r\n info: LogFn,\r\n warn: LogFn,\r\n error: LogFn,\r\n }\r\n}\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst reqChannel = 'runService:req'\r\nconst resChannel = 'runService:res'\r\nconst defaultConfig = {\r\n reqChannel,\r\n resChannel,\r\n toErrorObject,\r\n log: {\r\n trace: log,\r\n debug: log,\r\n info: log,\r\n warn: log,\r\n error: log,\r\n }\r\n}\r\n\r\nexport class Base {\r\n private inited = false\r\n private readonly services = new Map<string, Service>()\r\n protected readonly config: Config\r\n\r\n constructor(config?: Partial<Config>) {\r\n this.config = Object.assign({}, defaultConfig, config)\r\n }\r\n\r\n /**\r\n * 获取服务\r\n * @param key \r\n * @returns \r\n */\r\n getService(key: string): Service | undefined {\r\n return this.services.get(key)\r\n }\r\n\r\n /**\r\n * 添加服务\r\n * @param key \r\n * @param service \r\n */\r\n addService(key: string, service: Service): void {\r\n this.services.set(key, service)\r\n }\r\n\r\n /**\r\n * 添加多个服务\r\n * @param services \r\n */\r\n addServices(services: Record<string, Service>): void {\r\n Object.entries(services)\r\n .forEach(([key, service]) => {\r\n this.addService(key, service)\r\n })\r\n }\r\n\r\n /**\r\n * 删除服务\r\n * @param key \r\n */\r\n delService(key: string): void {\r\n this.services.delete(key)\r\n }\r\n\r\n /**\r\n * 初始化\r\n * @returns \r\n */\r\n init(): void {\r\n if (this.inited) {\r\n return\r\n }\r\n this.inited = true\r\n\r\n // 安装基础设施\r\n this.doInit()\r\n }\r\n\r\n protected doInit(): void {\r\n return\r\n }\r\n\r\n}","import z from 'zod'\r\n\r\n/**\r\n * 服务请求定义\r\n */\r\nconst ServiceReqEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n params: z.array(z.any()),\r\n reqAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务请求类型\r\n */\r\nexport type ServiceReqEvent = z.infer<typeof ServiceReqEventSchema>\r\n\r\n/**\r\n * 创建标识\r\n * @returns \r\n */\r\nexport function generateId(): string {\r\n const prefix = Date.now().toString(36)\r\n const suffix = Math.random().toString(36).substring(2, 6)\r\n return `${prefix}:${suffix}`\r\n}\r\n\r\n/**\r\n * 创建服务请求\r\n * @param event \r\n * @returns \r\n */\r\nexport function createReqEvent(\r\n event: Omit<ServiceReqEvent, 'id' | 'reqAt'>\r\n): ServiceReqEvent {\r\n const id = generateId()\r\n return {\r\n ...event,\r\n id, \r\n reqAt: Date.now()\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务请求\r\n * @param event \r\n */\r\nexport function checkReqEvent(event: any): void {\r\n ServiceReqEventSchema.parse(event)\r\n}","import z from 'zod'\r\nimport type { ServiceReqEvent } from './reqEvent'\r\n\r\n/**\r\n * 服务响应定义\r\n */\r\nconst ServiceResEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n error: z.object({\r\n error: z.string(),\r\n message: z.string(),\r\n stack: z.string().optional(),\r\n extras: z.any().optional()\r\n }).optional(),\r\n result: z.any().optional(),\r\n reqAt: z.number(),\r\n resAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务响应类型\r\n */\r\nexport type ServiceResEvent = z.infer<typeof ServiceResEventSchema>\r\n\r\n/**\r\n * 创建服务响应\r\n * @param reqEvent \r\n * @param resEvent \r\n * @returns \r\n */\r\nexport function createResEvent(\r\n reqEvent: ServiceReqEvent, \r\n resEvent: Pick<ServiceResEvent, 'error' | 'result'>\r\n): ServiceResEvent {\r\n const { \r\n id, \r\n api, \r\n dst: src, \r\n src: dst, \r\n reqAt \r\n } = reqEvent\r\n return {\r\n ...resEvent,\r\n id,\r\n api,\r\n dst,\r\n src,\r\n reqAt,\r\n resAt: Date.now(),\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务响应\r\n * @param event \r\n */\r\nexport function checkResEvent(event: object): void {\r\n ServiceResEventSchema.parse(event)\r\n}","import { \r\n type WebContents, \r\n ipcMain, \r\n} from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n type ServiceReqEvent, \r\n checkReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n type ServiceResEvent,\r\n checkResEvent,\r\n createResEvent\r\n} from './resEvent'\r\n\r\n/**\r\n * 主线程脚本\r\n */\r\nexport abstract class Main extends Base {\r\n private readonly resolvers = new Map<string, PromiseWithResolvers<any>>()\r\n\r\n /**\r\n * 获取网页对象\r\n * @param reqEvent \r\n */\r\n protected abstract getWebContents(reqEvent: ServiceReqEvent): WebContents\r\n\r\n doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 转发请求\r\n ipcMain.handle(reqChannel, async (\r\n event: Electron.IpcMainInvokeEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n try {\r\n // 主线程\r\n if (!reqEvent.dst) {\r\n log.debug('调用主线程服务')\r\n \r\n const { api, params } = reqEvent\r\n const service = this.getService(api)\r\n if (service == null) {\r\n throw new Error(`主线程服务无法找到: ${api}`)\r\n }\r\n \r\n const result = await service(...params)\r\n const resEvent = createResEvent(reqEvent, {\r\n result,\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n \r\n // 渲染线程\r\n log.debug('调用渲染线程服务')\r\n \r\n // 转发请求\r\n const webContents = this.getWebContents(reqEvent)\r\n webContents.send(reqChannel, reqEvent)\r\n \r\n const resolver = Promise.withResolvers<any>()\r\n this.resolvers.set(reqEvent.id, resolver)\r\n return resolver.promise\r\n }\r\n catch(error) {\r\n const resEvent = createResEvent(reqEvent, {\r\n error: toErrorObject(error),\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n })\r\n \r\n // 转发响应\r\n ipcMain.addListener(resChannel, (\r\n event: Electron.IpcMainEvent, \r\n resEvent: ServiceResEvent\r\n ) => {\r\n log.debug(resChannel, resEvent)\r\n checkResEvent(resEvent)\r\n\r\n const resolver = this.resolvers.get(resEvent.id)\r\n if (resolver == null) {\r\n throw new Error(`请求无法找到: ${resEvent.id}`)\r\n }\r\n\r\n this.resolvers.delete(resEvent.id)\r\n resolver.resolve(resEvent)\r\n })\r\n }\r\n}"],"mappings":"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","names":["z","log","reqChannel","resChannel","toErrorObject","log","reqChannel","resChannel","toErrorObject"]}
1
+ {"version":3,"sources":["../main/index.ts","../main/Preload.ts","../main/Base.ts","../main/reqEvent.ts","../main/resEvent.ts","../main/Main.ts"],"sourcesContent":["import {\n type ServiceReqEvent,\n} from './reqEvent'\nimport {\n type Config,\n type Service,\n} from './Base'\nimport { contextBridge } from 'electron'\nimport { Preload } from './Preload'\n\nexport {\n Preload\n} from './Preload'\nexport {\n Main\n} from './Main'\nexport {\n type Config,\n type Service\n} from './Base'\n\n/**\n * 暴露接口类型\n */\nexport type ExposeApi = {\n /**\n * 调用服务\n * @param reqEvent \n * @returns \n */\n invoke: (reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) => Promise<any>\n\n /**\n * 获取服务\n * @param key \n */\n getService(key: string): Service | undefined\n \n /**\n * 添加服务\n * @param api \n * @param service \n * @returns \n */\n addService: (api: string, service: Service) => void\n\n /**\n * 添加服务\n * @param services \n * @returns \n */\n addServices: (services: Record<string, Service>) => void\n}\n\n/**\n * 暴露方法到渲染线程\n * \n * @param key \n * @param config \n */\nexport function expose(key = 'service', config?: Partial<Config>) {\n const preload = new Preload(config)\n preload.init()\n\n contextBridge.exposeInMainWorld(key, {\n invoke: preload.invoke.bind(preload),\n getService: preload.getService.bind(preload),\n addService: preload.addService.bind(preload),\n addServices: preload.addServices.bind(preload),\n })\n}","import { ipcRenderer } from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n checkReqEvent, \r\n createReqEvent,\r\n type ServiceReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n createResEvent,\r\n} from './resEvent'\r\n\r\n/**\r\n * 预加载脚本\r\n */\r\nexport class Preload extends Base {\r\n\r\n async invoke(reqEvent: Omit<ServiceReqEvent, 'id' | 'reqAt'>) {\r\n const {\r\n log,\r\n reqChannel,\r\n resChannel,\r\n } = this.config\r\n\r\n reqEvent = createReqEvent(reqEvent)\r\n log.debug(reqChannel, reqEvent)\r\n\r\n const resEvent = await ipcRenderer.invoke(reqChannel, reqEvent)\r\n log.debug(resChannel, resEvent, {endAt: Date.now()})\r\n\r\n return resEvent.error || resEvent.result\r\n }\r\n\r\n override doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 处理请求\r\n ipcRenderer.addListener(reqChannel, async (\r\n event: Electron.IpcRendererEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n const resEvent = createResEvent(reqEvent, {})\r\n try {\r\n const service = this.getService(reqEvent.api)\r\n if (service == null) {\r\n throw new Error(`客户端服务无法找到: ${reqEvent.api}`)\r\n }\r\n \r\n resEvent.result = await service(...reqEvent.params)\r\n }\r\n catch(error) {\r\n resEvent.error = toErrorObject(error)\r\n }\r\n \r\n ipcRenderer.send(resChannel, resEvent)\r\n log.debug(resChannel, resEvent)\r\n })\r\n }\r\n}","/**\r\n * 服务函数类型\r\n */\r\nexport type Service = (...params: Array<any>) => Promise<any>\r\n\r\n/**\r\n * 错误转对象方法\r\n */\r\ntype ToErrorObjectFn = (obj: any) => any\r\n\r\n/**\r\n * 打印日志方法\r\n */\r\ntype LogFn = (...args: Array<any>) => void\r\n\r\n/**\r\n * 默认错误转对象方法\r\n * @param obj \r\n * @returns \r\n */\r\nexport const toErrorObject = (obj: any): any => {\r\n if (obj instanceof Error) {\r\n const result: any = {\r\n error: obj.name,\r\n stack: obj.stack,\r\n cause: obj.cause,\r\n message: obj.message,\r\n }\r\n if ('extras' in obj) {\r\n result.extras = obj['extras']\r\n }\r\n return result\r\n }\r\n return obj\r\n}\r\n\r\n/**\r\n * 默认日志方法\r\n * @param args \r\n */\r\nconst log = function(...args: Array<any>) {\r\n console.log(...args)\r\n}\r\n\r\n/**\r\n * 配置类型\r\n */\r\nexport type Config = {\r\n reqChannel: string\r\n resChannel: string\r\n toErrorObject: ToErrorObjectFn\r\n log: {\r\n trace: LogFn,\r\n debug: LogFn,\r\n info: LogFn,\r\n warn: LogFn,\r\n error: LogFn,\r\n }\r\n}\r\n\r\n/**\r\n * 默认配置\r\n */\r\nconst reqChannel = 'runService:req'\r\nconst resChannel = 'runService:res'\r\nconst defaultConfig = {\r\n reqChannel,\r\n resChannel,\r\n toErrorObject,\r\n log: {\r\n trace: log,\r\n debug: log,\r\n info: log,\r\n warn: log,\r\n error: log,\r\n }\r\n}\r\n\r\nexport class Base {\r\n private inited = false\r\n private readonly services = new Map<string, Service>()\r\n protected readonly config: Config\r\n\r\n constructor(config?: Partial<Config>) {\r\n this.config = Object.assign({}, defaultConfig, config)\r\n }\r\n\r\n /**\r\n * 获取服务\r\n * @param key \r\n * @returns \r\n */\r\n getService(key: string): Service | undefined {\r\n return this.services.get(key)\r\n }\r\n\r\n /**\r\n * 添加服务\r\n * @param key \r\n * @param service \r\n */\r\n addService(key: string, service: Service): void {\r\n this.services.set(key, service)\r\n }\r\n\r\n /**\r\n * 添加多个服务\r\n * @param services \r\n */\r\n addServices(services: Record<string, Service>): void {\r\n Object.entries(services)\r\n .forEach(([key, service]) => {\r\n this.addService(key, service)\r\n })\r\n }\r\n\r\n /**\r\n * 删除服务\r\n * @param key \r\n */\r\n delService(key: string): void {\r\n this.services.delete(key)\r\n }\r\n\r\n /**\r\n * 初始化\r\n * @returns \r\n */\r\n init(): void {\r\n if (this.inited) {\r\n return\r\n }\r\n this.inited = true\r\n\r\n // 安装基础设施\r\n this.doInit()\r\n }\r\n\r\n protected doInit(): void {\r\n return\r\n }\r\n\r\n}","import z from 'zod'\r\n\r\n/**\r\n * 服务请求定义\r\n */\r\nconst ServiceReqEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n params: z.array(z.any()),\r\n reqAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务请求类型\r\n */\r\nexport type ServiceReqEvent = z.infer<typeof ServiceReqEventSchema>\r\n\r\n/**\n * 创建标识\n * @returns \n */\nexport function generateId(): string {\n const prefix = Date.now().toString(36)\n const suffix = Math.random().toString(36).substring(2, 6)\n return `${prefix}:${suffix}`\n}\r\n\r\n/**\r\n * 创建服务请求\r\n * @param event \r\n * @returns \r\n */\r\nexport function createReqEvent(\r\n event: Omit<ServiceReqEvent, 'id' | 'reqAt'>\r\n): ServiceReqEvent {\r\n const id = generateId()\r\n return {\r\n ...event,\r\n id, \r\n reqAt: Date.now()\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务请求\r\n * @param event \r\n */\r\nexport function checkReqEvent(event: any): void {\r\n ServiceReqEventSchema.parse(event)\r\n}","import z from 'zod'\r\nimport type { ServiceReqEvent } from './reqEvent'\r\n\r\n/**\r\n * 服务响应定义\r\n */\r\nconst ServiceResEventSchema = z.object({\r\n id: z.string(),\r\n api: z.string(),\r\n dst: z.string(),\r\n src: z.string(),\r\n error: z.object({\r\n error: z.string(),\r\n message: z.string(),\r\n stack: z.string().optional(),\r\n extras: z.any().optional()\r\n }).optional(),\r\n result: z.any().optional(),\r\n reqAt: z.number(),\r\n resAt: z.number(),\r\n})\r\n\r\n/**\r\n * 服务响应类型\r\n */\r\nexport type ServiceResEvent = z.infer<typeof ServiceResEventSchema>\r\n\r\n/**\r\n * 创建服务响应\r\n * @param reqEvent \r\n * @param resEvent \r\n * @returns \r\n */\r\nexport function createResEvent(\r\n reqEvent: ServiceReqEvent, \r\n resEvent: Pick<ServiceResEvent, 'error' | 'result'>\r\n): ServiceResEvent {\r\n const { \r\n id, \r\n api, \r\n dst: src, \r\n src: dst, \r\n reqAt \r\n } = reqEvent\r\n return {\r\n ...resEvent,\r\n id,\r\n api,\r\n dst,\r\n src,\r\n reqAt,\r\n resAt: Date.now(),\r\n }\r\n}\r\n\r\n/**\r\n * 检查服务响应\r\n * @param event \r\n */\r\nexport function checkResEvent(event: object): void {\r\n ServiceResEventSchema.parse(event)\r\n}","import { \r\n type WebContents, \r\n ipcMain, \r\n} from 'electron'\r\nimport { Base } from './Base'\r\nimport { \r\n type ServiceReqEvent, \r\n checkReqEvent, \r\n} from './reqEvent'\r\nimport {\r\n type ServiceResEvent,\r\n checkResEvent,\r\n createResEvent\r\n} from './resEvent'\r\n\r\n/**\r\n * 主线程脚本\r\n */\r\nexport abstract class Main extends Base {\r\n private readonly resolvers = new Map<string, PromiseWithResolvers<any>>()\r\n\r\n /**\r\n * 获取网页对象\r\n * @param reqEvent \r\n */\r\n protected abstract getWebContents(reqEvent: ServiceReqEvent): WebContents\r\n\r\n doInit(): void {\r\n const {\r\n log,\r\n reqChannel, \r\n resChannel,\r\n toErrorObject\r\n } = this.config\r\n\r\n // 转发请求\r\n ipcMain.handle(reqChannel, async (\r\n event: Electron.IpcMainInvokeEvent, \r\n reqEvent: ServiceReqEvent\r\n ) => {\r\n log.debug(reqChannel, reqEvent)\r\n checkReqEvent(reqEvent)\r\n\r\n try {\r\n // 主线程\r\n if (!reqEvent.dst) {\r\n log.debug('调用主线程服务')\r\n \r\n const { api, params } = reqEvent\r\n const service = this.getService(api)\r\n if (service == null) {\r\n throw new Error(`主线程服务无法找到: ${api}`)\r\n }\r\n \r\n const result = await service(...params)\r\n const resEvent = createResEvent(reqEvent, {\r\n result,\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n \r\n // 渲染线程\r\n log.debug('调用渲染线程服务')\r\n \r\n // 转发请求\r\n const webContents = this.getWebContents(reqEvent)\r\n webContents.send(reqChannel, reqEvent)\r\n \r\n const resolver = Promise.withResolvers<any>()\r\n this.resolvers.set(reqEvent.id, resolver)\r\n return resolver.promise\r\n }\r\n catch(error) {\r\n const resEvent = createResEvent(reqEvent, {\r\n error: toErrorObject(error),\r\n })\r\n log.debug(resChannel, resEvent)\r\n return resEvent\r\n }\r\n })\r\n \r\n // 转发响应\r\n ipcMain.addListener(resChannel, (\r\n event: Electron.IpcMainEvent, \r\n resEvent: ServiceResEvent\r\n ) => {\r\n log.debug(resChannel, resEvent)\r\n checkResEvent(resEvent)\r\n\r\n const resolver = this.resolvers.get(resEvent.id)\r\n if (resolver == null) {\r\n throw new Error(`请求无法找到: ${resEvent.id}`)\r\n }\r\n\r\n this.resolvers.delete(resEvent.id)\r\n resolver.resolve(resEvent)\r\n })\r\n }\r\n}"],"mappings":"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","names":["z","log","reqChannel","resChannel","toErrorObject","log","reqChannel","resChannel","toErrorObject"]}
package/package.json CHANGED
@@ -1,49 +1,49 @@
1
- {
2
- "name": "@chenpeiyuan/electron-message",
3
- "version": "1.0.1",
4
- "type": "module",
5
- "main": "./dist/index.cjs",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.cjs"
13
- }
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "publishConfig": {
19
- "registry": "https://registry.npmjs.org/",
20
- "access": "public"
21
- },
22
- "scripts": {
23
- "prebuild": "rimraf dist .tsbuildinfo",
24
- "build": "tsup",
25
- "test": "vitest run",
26
- "test:watch": "vitest"
27
- },
28
- "keywords": [],
29
- "author": "",
30
- "license": "ISC",
31
- "packageManager": "pnpm@10.12.4",
32
- "dependencies": {
33
- "zod": "^4.3.6"
34
- },
35
- "devDependencies": {
36
- "@types/node": "^24.9.2",
37
- "cross-env": "^10.1.0",
38
- "electron": "^40.4.1",
39
- "rimraf": "^6.0.1",
40
- "tsc-alias": "^1.8.16",
41
- "tsup": "^8.5.0",
42
- "tsx": "^4.20.6",
43
- "typescript": "^5.9.3",
44
- "vitest": "^4.0.4"
45
- },
46
- "peerDependencies": {
47
- "electron": "^40.4.1"
48
- }
49
- }
1
+ {
2
+ "name": "@chenpeiyuan/electron-message",
3
+ "version": "1.0.3",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org/",
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "prebuild": "rimraf dist .tsbuildinfo",
24
+ "build": "tsup",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest"
27
+ },
28
+ "keywords": [],
29
+ "author": "",
30
+ "license": "ISC",
31
+ "packageManager": "pnpm@10.12.4",
32
+ "dependencies": {
33
+ "zod": "^4.3.6"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^24.9.2",
37
+ "cross-env": "^10.1.0",
38
+ "electron": "^40.4.1",
39
+ "rimraf": "^6.0.1",
40
+ "tsc-alias": "^1.8.16",
41
+ "tsup": "^8.5.0",
42
+ "tsx": "^4.20.6",
43
+ "typescript": "^5.9.3",
44
+ "vitest": "^4.0.4"
45
+ },
46
+ "peerDependencies": {
47
+ "electron": "^40.4.1"
48
+ }
49
+ }