electron-event-flux
Version:
Redux store which synchronizes between instances in multiple process
190 lines (189 loc) • 9.04 kB
JavaScript
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var constants_1 = require("./constants");
var electron_1 = require("electron");
var findIndex_1 = require("./utils/findIndex");
;
var ElectronMainClient = /** @class */ (function () {
function ElectronMainClient(callbacks, log) {
var _this = this;
this.clientInfos = [];
this.clientMap = {};
// Renderer process register self, Then the main process will send the store the initial state to the renderer process
this.handleRegister = function (_a, _b) {
var sender = _a.sender;
var clientId = _b.clientId;
var existIndex = findIndex_1.default(_this.clientInfos, function (item) { return item.clientId === clientId; });
if (existIndex !== -1) {
_this.handleUnregisterRenderer(clientId);
}
var clientInfo = {
webContents: sender,
clientId: clientId,
window: electron_1.BrowserWindow.fromWebContents(sender),
};
// Add window first, then get window info, The window info should has prepared
_this.mainClientCallbacks.addWin(clientId);
_this.clientInfos.push(clientInfo);
_this.clientMap[clientId] = clientInfo;
var browserWindow = electron_1.BrowserWindow.fromWebContents(sender);
// Webcontents aren't automatically destroyed on window close
browserWindow.on('closed', function () { return _this.handleUnregisterRenderer(clientId); });
_this.log(function (logger) { return logger("ElectronMainClient", "main init"); });
_this._sendForWebContents(sender, constants_1.mainInitName, _this.mainClientCallbacks.getStores(clientId), _this.mainClientCallbacks.getInitStates(clientId));
};
// When renderer process dispatch an action to main process, the handleRendererDispatch will invoke
// The main process will invoke handleRendererMessage to handle the message and send the result back to renderer process
this.handleRendererDispatch = function (event, clientId, invokeId, stringifiedAction) {
if (!_this.clientMap[clientId])
return;
var webContents = _this.clientMap[clientId].webContents;
_this.mainClientCallbacks.handleRendererMessage(stringifiedAction).then(function (result) {
_this._sendForWebContents(webContents, constants_1.mainReturnName, invokeId, undefined, result);
}, function (err) {
var errObj = null;
if (err) {
errObj = { name: err.name, message: err.message };
if (errObj) {
Object.keys(err).forEach(function (key) { return errObj[key] = err[key]; });
}
}
_this._sendForWebContents(webContents, constants_1.mainReturnName, invokeId, errObj, undefined);
});
};
this.handleWinMessage = function (event, clientId, data) {
if (!_this.clientMap[clientId])
return;
var webContents = _this.clientMap[clientId].webContents;
var existIndex = findIndex_1.default(_this.clientInfos, function (item) { return item.webContents === event.sender; });
if (existIndex !== -1) {
_this._sendForWebContents(webContents, constants_1.winMessageName, _this.clientInfos[existIndex].clientId, data);
}
};
this.log = log;
this.mainClientCallbacks = callbacks;
// Need to keep track of windows, as when a window refreshes it creates a new
// webContents, and the old one must be unregistered
// Cannot delete data, as events could still be sent after close
// events when a BrowserWindow is created using remote
electron_1.ipcMain.on(constants_1.renderRegisterName, this.handleRegister);
electron_1.ipcMain.on(constants_1.renderDispatchName, this.handleRendererDispatch);
electron_1.ipcMain.on(constants_1.winMessageName, this.handleWinMessage);
return this;
}
ElectronMainClient.prototype.handleUnregisterRenderer = function (clientId) {
var existIndex = findIndex_1.default(this.clientInfos, function (item) { return item.clientId === clientId; });
if (existIndex !== -1) {
this.clientInfos.splice(existIndex, 1);
delete this.clientMap[clientId];
this.mainClientCallbacks.deleteWin(clientId);
}
};
;
ElectronMainClient.prototype.checkWebContents = function (webContents) {
return !webContents.isDestroyed() && !webContents.isCrashed();
};
ElectronMainClient.prototype._sendForWebContents = function (webContents, channel) {
var args = [];
for (var _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
if (this.checkWebContents(webContents)) {
webContents.send.apply(webContents, __spread([channel], args));
}
};
ElectronMainClient.prototype.getForwardClients = function () {
return this.clientInfos;
};
ElectronMainClient.prototype.dispatchToRenderer = function (client, payload) {
var webContents = client.webContents;
// if (webContents.isDestroyed() || webContents.isCrashed()) {
// return this.unregisterRenderer(client.clientId);
// }
if (this.checkWebContents(webContents)) {
webContents.send(constants_1.mainDispatchName, payload);
}
};
ElectronMainClient.prototype.sendWinMsg = function (clientId, message) {
if (!this.clientMap[clientId])
return;
var webContents = this.clientMap[clientId].webContents;
if (this.checkWebContents(webContents)) {
webContents.send(constants_1.messageName, message);
}
};
// 通过clientId获取BrowserWindow
ElectronMainClient.prototype.getWindow = function (clientId) {
if (!this.clientMap[clientId])
return undefined;
return this.clientMap[clientId].window;
};
// 通过clientId获取WebContents
ElectronMainClient.prototype.getWebContents = function (clientId) {
if (!this.clientMap[clientId])
return undefined;
return this.clientMap[clientId].webContents;
};
ElectronMainClient.prototype.changeClientAction = function (clientId, params) {
var _this = this;
if (this.clientMap[clientId]) {
var webContents = this.clientMap[clientId].webContents;
// this.sendMessage(win, { action: 'change-props', url });
// win.webContents.send("__INIT_WINDOW__", params);
this._sendForWebContents(webContents, "__INIT_WINDOW__", params);
this.log(function (logger) { return logger("ElectronMainClient", "init Window", params); });
}
else {
var onRegister_1 = function (event, _a) {
var nowClientId = _a.clientId;
if (nowClientId === clientId) {
_this.changeClientAction(clientId, params);
electron_1.ipcMain.removeListener(constants_1.renderRegisterName, onRegister_1);
}
};
// 还没有初始化,则监听注册事件,当初始化之后 开始初始化
electron_1.ipcMain.on(constants_1.renderRegisterName, onRegister_1);
}
};
ElectronMainClient.prototype.isRegister = function (clientId) {
return !!this.clientMap[clientId];
};
ElectronMainClient.prototype.whenRegister = function (clientId, callback) {
if (this.isRegister(clientId)) {
return callback();
}
var onRegister = function (event, _a) {
var nowClientId = _a.clientId;
if (nowClientId === clientId) {
callback();
electron_1.ipcMain.removeListener(constants_1.renderRegisterName, onRegister);
}
};
electron_1.ipcMain.on(constants_1.renderRegisterName, onRegister);
};
ElectronMainClient.prototype.isClose = function (clientId) {
return !this.clientMap[clientId];
};
return ElectronMainClient;
}());
exports.default = ElectronMainClient;