new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Electron · all subjects

ipc patterns

25 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Use napi_create_threadsafe_function for cross-thread callbacks to JavaScript

When calling JavaScript callbacks from native C++ threads, use napi_create_threadsafe_function to create a threadsafe function that marshals the call from the native thread to the Node.js event loop. This allows safe asynchronous communication between native code running on different threads and JavaScript.

Use Napi::ObjectWrap to wrap C++ classes for JavaScript

Use Napi::ObjectWrap<ClassName> to create a wrapper class that exposes C++ functionality to JavaScript. Implement DefineClass to register methods, set up a constructor, and export to JavaScript via exports.Set().

napi_release_threadsafe_function with napi_tsfn_release on shutdown

Call napi_release_threadsafe_function(tsfn_, napi_tsfn_release) in the destructor to properly clean up the threadsafe function. Use napi_tsfn_abort only when aborting without waiting for pending work.

napi_tsfn_blocking mode waits for threadsafe function to become available

When calling napi_call_threadsafe_function, pass napi_tsfn_blocking as the mode to wait for the function to become available if the queue is full. This is safer than non-blocking modes for critical callbacks.

Persistent references keep objects alive across event loop cycles

Use Napi::ObjectReference with Napi::Persistent to create persistent references to JavaScript objects and functions that need to survive beyond the current native function call. These must be manually reset when no longer needed.

Use EventEmitter pattern in JavaScript wrapper for native addon callbacks

Wrap native addon callback events in a JavaScript EventEmitter class. Listen to native addon events and re-emit them as EventEmitter events. This provides a familiar Node.js interface for consuming native callbacks.

Check process.platform before loading platform-specific native addons

In the JavaScript wrapper for platform-specific native addons, check process.platform to ensure the addon is only loaded on supported platforms. Throw an error if loaded on an unsupported platform.

Thread-safe function pattern for Swift callbacks to JavaScript

Use napi_create_threadsafe_function to safely bridge callbacks from Swift running on native threads to the Node.js event loop. The pattern involves: creating a CallbackData struct to pass event type and payload between threads, using a lambda-generated Objective-C block as the Swift callback, and calling napi_call_threadsafe_function with napi_tsfn_blocking mode. In the callback handler, retrieve the registered JavaScript function from a stored callbacks object and call it with the payload. Always release the threadsafe function in the destructor using napi_release_threadsafe_function with napi_tsfn_release (or napi_tsfn_abort in the destroy method).

ipcRenderer.send method signature and behavior

ipcRenderer.send(channel, ...args) sends an asynchronous message to the main process via channel along with arguments. Arguments are serialized with the Structured Clone Algorithm like window.postMessage, so prototype chains are not included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception. Non-standard JavaScript types such as DOM objects or special Electron objects will throw an exception. DOM objects such as ImageBitmap, File, DOMMatrix cannot be sent over Electron's IPC. The main process handles it by listening for channel with the ipcMain module.

ipcRenderer.send vs ipcRenderer.invoke

If you want to receive a single response from the main process, like the result of a method call, consider using ipcRenderer.invoke instead of ipcRenderer.send.

ipcRenderer.invoke method signature and return value

ipcRenderer.invoke(channel, ...args) sends a message to the main process via channel and expects a result asynchronously. Returns Promise<any> that resolves with the response from the main process. Arguments are serialized with the Structured Clone Algorithm like window.postMessage, so prototype chains are not included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.

ipcRenderer.invoke requires ipcMain.handle on main process

The main process should listen for the channel in ipcRenderer.invoke using ipcMain.handle().

ipcRenderer.invoke example

// Renderer process ipcRenderer.invoke('some-name', someArgument).then((result) => { // ... }) // Main process ipcMain.handle('some-name', async (event, someArgument) => { const result = await doSomeWork(someArgument) return result }) This example shows how to use ipcRenderer.invoke to send a message from the renderer and receive a response from the main process.

ipcRenderer.invoke with MessagePort

If you need to transfer a MessagePort to the main process, use ipcRenderer.postMessage instead of ipcRenderer.invoke.

ipcRenderer.invoke non-standard type restrictions

Non-standard JavaScript types such as DOM objects or special Electron objects cannot be sent via ipcRenderer.invoke and will throw an exception. DOM objects such as ImageBitmap, File, DOMMatrix cannot be sent over Electron's IPC.

ipcRenderer.invoke error handling

If the handler in the main process throws an error, the promise returned by invoke will reject. However, the Error object in the renderer process will not be the same as the one thrown in the main process.

ipcRenderer.sendSync method signature and return value

ipcRenderer.sendSync(channel, ...args) sends a message to the main process via channel and expects a result synchronously. Returns any - the value sent back by the ipcMain handler. Arguments are serialized with the Structured Clone Algorithm like window.postMessage, so prototype chains are not included. Sending Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.

ipcRenderer.sendSync main process handling

The main process handles ipcRenderer.sendSync by listening for channel with ipcMain module and replying by setting event.returnValue.

Avoid synchronous IPC - sendSync blocks renderer process

Sending a synchronous message with ipcRenderer.sendSync will block the whole renderer process until the reply is received. Use this method only as a last resort. It is much better to use the asynchronous version, invoke().

ipcRenderer.postMessage method signature

ipcRenderer.postMessage(channel, message, [transfer]) sends a message to the main process, optionally transferring ownership of zero or more MessagePort objects. Channel is a string, message is any type, and transfer is an optional array of MessagePort objects.

ipcRenderer.postMessage MessagePort handling

The transferred MessagePort objects will be available in the main process as MessagePortMain objects by accessing the ports property of the emitted event.

ipcRenderer.postMessage example

// Renderer process const { port1, port2 } = new MessageChannel() ipcRenderer.postMessage('port', { message: 'hello' }, [port1]) // Main process ipcMain.on('port', (e, msg) => { const [port] = e.ports // ... }) This example shows how to transfer a MessagePort from the renderer to the main process using ipcRenderer.postMessage.

IpcRendererEvent object structure

IpcRendererEvent extends Event and has two properties: sender (an IpcRenderer instance that emitted the event originally) and ports (a list of MessagePorts that were transferred with the message).

IpcRendererEvent sender property

The sender property of IpcRendererEvent is an IpcRenderer instance that emitted the event originally.

IpcRendererEvent ports property

The ports property of IpcRendererEvent is a list of MessagePorts that were transferred with the message.

Give your agent this brain