@zubridge/electron
Version:
A streamlined state management library for Electron applications using Zustand.
75 lines (74 loc) • 3.29 kB
JavaScript
import { ipcRenderer } from 'electron';
import { IpcChannel } from './constants';
/**
* Modern preload bridge that implements the new backend contract
*/
export const preloadBridge = () => {
const handlers = {
subscribe(callback) {
const listener = (_, state) => callback(state);
ipcRenderer.on(IpcChannel.SUBSCRIBE, listener);
return () => {
ipcRenderer.removeListener(IpcChannel.SUBSCRIBE, listener);
};
},
async getState() {
return 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) {
ipcRenderer.removeListener(IpcChannel.DISPATCH_ACK, ackListener);
resolve();
}
};
ipcRenderer.on(IpcChannel.DISPATCH_ACK, ackListener);
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) {
ipcRenderer.removeListener(IpcChannel.DISPATCH_ACK, ackListener);
resolve();
}
};
ipcRenderer.on(IpcChannel.DISPATCH_ACK, ackListener);
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.
*/
export const preloadZustandBridge = preloadBridge;