Skip to content

Commit

Permalink
CHORE refactor again (#4169)
Browse files Browse the repository at this point in the history
* CHORE refactor again

* REFACTOR the `electron` plugin to improve ipcRenderer communications

* FIX typo
  • Loading branch information
pubkey authored Dec 6, 2022
1 parent 52c3884 commit 6fdf597
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 193 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# RxDB Changelog

<!-- CHANGELOG NEWEST -->
- REFACTOR the `electron` plugin to improve ipcRenderer communications.
- REMOVE `is-electron` dependency.
<!-- ADD new changes here! -->

Expand Down
7 changes: 6 additions & 1 deletion examples/electron/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ const { exposeIpcMainRxStorage } = require('rxdb/plugins/electron');

const { getDatabase } = require('./shared');

/**
* @link https://github.com/electron/electron/issues/19775#issuecomment-834649057
*/
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';

const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

Expand All @@ -32,7 +37,7 @@ function createWindow() {
w.setPosition(x, y);
windows.push(w);

// use this to debug
// use this to debug by automatically opening the devtools.
// w.webContents.openDevTools();
}

Expand Down
66 changes: 28 additions & 38 deletions src/plugins/electron/rx-storage-ipc-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,52 @@
* that is supposed to run inside of the electron main process
*/
import type {
RxStorage,
RxStorageInstanceCreationParams
RxStorage
} from '../../types';
import {
ensureNotFalsy,
getFromMapOrThrow
} from '../../util';
import { Subject } from 'rxjs';
import {
IPC_RENDERER_KEY_PREFIX,
IPC_RENDERER_TO_MAIN
IPC_RENDERER_KEY_PREFIX
} from './electron-helper';
import {
exposeRxStorageMessageChannel,
RxMessageChannelExposeSettings,
RxStorageMessageToRemote
} from '../../rx-storage-message-channel';

export function exposeIpcMainRxStorage<T, D>(
args: {
key: string;
storage: RxStorage<T, D>;
ipcMain: any;
}
) {

const onCreateRemoteStorage$ = new Subject<{
port: MessagePort;
params: RxStorageInstanceCreationParams<any, any>;
}>;
const portByDatabaseInstanceToken = new Map<string, MessagePort>();
const channelId = [
IPC_RENDERER_KEY_PREFIX,
args.key,
].join('|');
const messages$ = new Subject<RxStorageMessageToRemote>();
const openRenderers: Set<any> = new Set();
args.ipcMain.on(
[
IPC_RENDERER_KEY_PREFIX,
'postMessage',
args.key,
'createStorageInstance'
].join('|'),
(event: any, params: RxStorageInstanceCreationParams<any, any>) => {
const [port] = event.ports;
portByDatabaseInstanceToken.set(params.databaseInstanceToken, port);
onCreateRemoteStorage$.next({
params,
port
});
channelId,
(event: any, message: any) => {
openRenderers.add(event.sender);
if (message) {
messages$.next(message);
}
}
);
const send: RxMessageChannelExposeSettings['send'] = (msg) => {
/**
* TODO we could improve performance
* by only sending the message to the 'correct' sender
* and removing senders whose browser window is closed.
*/
openRenderers.forEach(sender => {
sender.send(channelId, msg);
});

};
exposeRxStorageMessageChannel({
storage: args.storage,
onCreateRemoteStorage$
});


args.ipcMain.on(IPC_RENDERER_TO_MAIN, (_event: any, message: RxStorageMessageToRemote) => {
const port = getFromMapOrThrow(portByDatabaseInstanceToken, message.instanceId);
ensureNotFalsy(port.onmessage as any)({
data: message
});
messages$,
send
});
}
64 changes: 32 additions & 32 deletions src/plugins/electron/rx-storage-ipc-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { Subject } from 'rxjs';
import {
getRxStorageMessageChannel,
RxStorageMessageChannel,
RxStorageMessageToRemote
RxStorageMessageChannelSettings,
RxStorageMessageFromRemote
} from '../../rx-storage-message-channel';
import type {
RxStorageStatics
} from '../../types';
import { getFromMapOrThrow } from '../../util';
import {
IPC_RENDERER_KEY_PREFIX,
IPC_RENDERER_TO_MAIN
IPC_RENDERER_KEY_PREFIX
} from './electron-helper';

export type RxStorageIpcRendererSettings = {
/**
* Set the same key on both sides
* to ensure that messages do not get mixed
* up when you use more then one storage.
*/
key: string;
statics: RxStorageStatics;
ipcRenderer: any;
Expand All @@ -22,38 +27,33 @@ export type RxStorageIpcRenderer = RxStorageMessageChannel;
export function getRxStorageIpcRenderer(
settings: RxStorageIpcRendererSettings
): RxStorageIpcRenderer {
const channelId = [
IPC_RENDERER_KEY_PREFIX,
settings.key
].join('|');

const messages$ = new Subject<RxStorageMessageFromRemote>();
settings.ipcRenderer.on(channelId, (_event: any, message: any) => {
messages$.next(message);
});


settings.ipcRenderer.postMessage(
channelId,
false
);

const send: RxStorageMessageChannelSettings['send'] = (msg) => {
settings.ipcRenderer.postMessage(
channelId,
msg
);
};
const storage = getRxStorageMessageChannel({
name: 'ipc-renderer',
statics: settings.statics,
createRemoteStorage: (
port,
params
) => {

/**
* Electron does not allow to send messages
* via ports from ipcRenderer->ipcMain.
* Therefore we have to overwrite the port1.postMessage()
* so that it works over args.ipcMain.on() messages.
*/
const messageChannel = getFromMapOrThrow(storage.messageChannelByPort, port);
const otherPort = messageChannel.port1;
otherPort.postMessage = function (message: RxStorageMessageToRemote) {
settings.ipcRenderer.send(IPC_RENDERER_TO_MAIN, message);
};

settings.ipcRenderer.postMessage(
[
IPC_RENDERER_KEY_PREFIX,
'postMessage',
settings.key,
'createStorageInstance'
].join('|'),
params,
[port]
);
}
messages$,
send
});
return storage;
}
Loading

0 comments on commit 6fdf597

Please sign in to comment.