UNPKG

@zubridge/electron

Version:

A streamlined state management library for Electron applications using Zustand.

96 lines (91 loc) 4.09 kB
'use strict'; var electron = require('electron'); /** * Constants used for IPC communication between main and renderer processes. * These are internal to the Zubridge electron implementation. */ var IpcChannel; (function (IpcChannel) { /** Channel for subscribing to state updates */ IpcChannel["SUBSCRIBE"] = "__zubridge_state_update"; /** Channel for getting the current state */ IpcChannel["GET_STATE"] = "__zubridge_get_initial_state"; /** Channel for dispatching actions */ IpcChannel["DISPATCH"] = "__zubridge_dispatch_action"; /** Channel for acknowledging action dispatches */ IpcChannel["DISPATCH_ACK"] = "__zubridge_dispatch_ack"; })(IpcChannel || (IpcChannel = {})); /** * Modern preload bridge that implements the new backend contract */ const preloadBridge = () => { const handlers = { subscribe(callback) { const listener = (_, state) => callback(state); electron.ipcRenderer.on(IpcChannel.SUBSCRIBE, listener); return () => { electron.ipcRenderer.removeListener(IpcChannel.SUBSCRIBE, listener); }; }, async getState() { return electron.ipcRenderer.invoke(IpcChannel.GET_STATE); }, dispatch(action, payload) { if (typeof action === 'function') { // For thunks, we don't do anything in the preload // The renderer implementation will handle executing them // This just prevents an error from being thrown return; } else if (typeof action === 'string') { // Create an action object const actionObj = { type: action, payload: payload, // Generate a unique ID for this action to track acknowledgment id: `${Date.now()}_${Math.random().toString(36).slice(2)}`, }; // Return a promise that resolves when the action is acknowledged return new Promise((resolve) => { // Set up one-time listener for acknowledgment with this action ID const ackListener = (_, ackId) => { if (ackId === actionObj.id) { electron.ipcRenderer.removeListener(IpcChannel.DISPATCH_ACK, ackListener); resolve(); } }; electron.ipcRenderer.on(IpcChannel.DISPATCH_ACK, ackListener); electron.ipcRenderer.send(IpcChannel.DISPATCH, actionObj); }); } else { // For regular action objects, add a unique ID if not already present const actionWithId = { ...action, id: action.id || `${Date.now()}_${Math.random().toString(36).slice(2)}`, }; // Return a promise that resolves when the action is acknowledged return new Promise((resolve) => { // Set up one-time listener for acknowledgment with this action ID const ackListener = (_, ackId) => { if (ackId === actionWithId.id) { electron.ipcRenderer.removeListener(IpcChannel.DISPATCH_ACK, ackListener); resolve(); } }; electron.ipcRenderer.on(IpcChannel.DISPATCH_ACK, ackListener); electron.ipcRenderer.send(IpcChannel.DISPATCH, actionWithId); }); } }, }; return { handlers }; }; /** * Legacy preload bridge for backward compatibility * @deprecated This is now an alias for preloadBridge and uses the new IPC channels. * Please update your code to use preloadBridge directly in the future. */ const preloadZustandBridge = preloadBridge; exports.preloadBridge = preloadBridge; exports.preloadZustandBridge = preloadZustandBridge;