Event Service (IPC)
The Event Service in Trufos facilitates Inter-Process Communication (IPC) between the main process and the renderer process. It’s implemented as two distinct but related services: MainEventService
for the backend and RendererEventService
for the frontend.
MainEventService
- Location:
src/main/event/main-event-service.ts
- Purpose: To expose main process functionalities to the renderer process securely and handle requests originating from the UI.
- Mechanism:
- It implements the
IEventService
interface (defined insrc/shim/event-service.ts
). - During its construction, it iterates over its own methods and dynamically registers IPC handlers for each using
ipcMain.handle(channelName, handler)
. ThechannelName
is typically the method name itself. - Each handler is wrapped with
wrapWithErrorHandler
, which catches errors from the underlying service calls, logs them, and returns them as standardError
objects over IPC.
- It implements the
- Responsibilities:
- Delegates calls to other main process services (e.g.,
PersistenceService
,HttpService
,EnvironmentService
). - Acts as the single point of entry for most renderer-to-main communication.
- Handles specialized IPC events like those for data streaming (
stream-events.ts
) and log forwarding.
- Delegates calls to other main process services (e.g.,
RendererEventService
- Location:
src/renderer/services/event/renderer-event-service.ts
- Purpose: To provide a clean, Promise-based API for renderer-side code to interact with the main process functionalities exposed by
MainEventService
. - Mechanism:
- It also conceptually implements the
IEventService
interface. - For each method in
IEventService
, it uses acreateEventMethod
helper. This helper function:- Calls
window.electron.ipcRenderer.invoke(channelName, ...args)
, wherechannelName
matches the method name. - Awaits the Promise returned by
invoke
. - If the result from the main process is an
Error
object, it throws a newMainProcessError
(fromsrc/renderer/error/MainProcessError.ts
) to distinguish it from renderer-side errors. - Otherwise, it returns the successful result.
- Calls
- It also provides methods for listening to (
on
) and emitting (emit
) general IPC events that are not part of the request/response pattern (e.g.,before-close
,ready-to-close
for application shutdown).
- It also conceptually implements the
- Responsibilities:
- Abstracts away the raw
ipcRenderer
calls. - Provides type safety for IPC calls based on
IEventService
. - Handles error wrapping for responses from the main process.
- Abstracts away the raw
IEventService
Interface
- Location:
src/shim/event-service.ts
- Purpose: Defines the contract for methods that are exposed via IPC. This shared interface ensures that both
MainEventService
andRendererEventService
are synchronized in terms of method signatures and channel names. - Key Methods Defined:
loadCollection
,listCollections
sendRequest
saveRequest
,saveChanges
,discardChanges
deleteObject
getAppVersion
getActiveEnvironmentVariables
,getVariable
,setCollectionVariables
selectEnvironment
saveFolder
openCollection
,createCollection
,closeCollection
showOpenDialog
Overall Flow
- Renderer component/service needs to perform a main process task (e.g., save a file).
- It calls a method on
RendererEventService.instance
(e.g.,RendererEventService.instance.saveRequest(requestData)
). RendererEventService
useswindow.electron.ipcRenderer.invoke('saveRequest', requestData)
to send the request to the main process.MainEventService
(which has a handler registered for'saveRequest'
) receives the call.- The handler in
MainEventService
calls the actual implementation (e.g.,PersistenceService.instance.saveRequest(requestData)
). - The result (or an error) from
PersistenceService
is returned by theMainEventService
handler. RendererEventService
receives the result. If it’s an error, it throwsMainProcessError
; otherwise, it returns the data.- The original caller in the renderer process receives the data or catches the error.
This structured approach to IPC ensures maintainability, type safety, and proper error handling between the main and renderer processes. For more details on the underlying IPC mechanisms, see IPC Communication.