ipc-main-internal-utils.ts 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import { ipcMainInternal } from '@electron/internal/browser/ipc-main-internal'
  2. import * as errorUtils from '@electron/internal/common/error-utils'
  3. type IPCHandler = (event: ElectronInternal.IpcMainInternalEvent, ...args: any[]) => any
  4. const callHandler = async function (handler: IPCHandler, event: ElectronInternal.IpcMainInternalEvent, args: any[], reply: (args: any[]) => void) {
  5. try {
  6. const result = await handler(event, ...args)
  7. reply([null, result])
  8. } catch (error) {
  9. reply([errorUtils.serialize(error)])
  10. }
  11. }
  12. export const handle = function <T extends IPCHandler> (channel: string, handler: T) {
  13. ipcMainInternal.on(channel, (event, requestId, ...args) => {
  14. callHandler(handler, event, args, responseArgs => {
  15. if (requestId) {
  16. event._replyInternal(`${channel}_RESPONSE_${requestId}`, ...responseArgs)
  17. } else {
  18. event.returnValue = responseArgs
  19. }
  20. })
  21. })
  22. }
  23. let nextId = 0
  24. export function invokeInWebContents<T> (sender: Electron.WebContentsInternal, sendToAll: boolean, command: string, ...args: any[]) {
  25. return new Promise<T>((resolve, reject) => {
  26. const requestId = ++nextId
  27. const channel = `${command}_RESPONSE_${requestId}`
  28. ipcMainInternal.on(channel, function handler (
  29. event, error: Electron.SerializedError, result: any
  30. ) {
  31. if (event.sender !== sender) {
  32. console.error(`Reply to ${command} sent by unexpected WebContents (${event.sender.id})`)
  33. return
  34. }
  35. ipcMainInternal.removeListener(channel, handler)
  36. if (error) {
  37. reject(errorUtils.deserialize(error))
  38. } else {
  39. resolve(result)
  40. }
  41. })
  42. if (sendToAll) {
  43. sender._sendInternalToAll(command, requestId, ...args)
  44. } else {
  45. sender._sendInternal(command, requestId, ...args)
  46. }
  47. })
  48. }