Skip to content

Commit

Permalink
Separate electron imports between main and renderer, use IPC to repla…
Browse files Browse the repository at this point in the history
…ce most renderer-side electron imports (#2720)

* Move startup template loading to main process

* remove unused variable

* replace initial batch of frontend FS

* move input override code that the renderer needs

* more correct typing for read and write file, pass through options

* move shell calls to main process

* move app.quit to main

* initial clipboard replacements

* Finish moving all clipboard stuff

* split IPC into own files

* this should work

* Separate electron imports between renderer and main

* lint

* attempt fixing main webpack

* fixed webpack building

* Replace imports with TODOs

* remove some residual stuff

* remove extra newlines

* Update src/renderer/contexts/GlobalNodeState.tsx

Co-authored-by: Michael Schmidt <[email protected]>

* Replace IPC clipboard writeText calls with navigator.clipboard

* Replace some remaining clipboard calls

* Fix chain copy and paste

---------

Co-authored-by: Michael Schmidt <[email protected]>
  • Loading branch information
joeyballentine and RunDevelopment authored Mar 31, 2024
1 parent ff8f362 commit 140509f
Show file tree
Hide file tree
Showing 42 changed files with 389 additions and 244 deletions.
78 changes: 61 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"@types/yargs": "^17.0.10",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"@vercel/webpack-asset-relocator-loader": "^1.7.2",
"@vercel/webpack-asset-relocator-loader": "^1.7.3",
"babel-loader": "^8.2.5",
"babel-plugin-i18next-extract": "^0.9.0",
"concurrently": "^7.2.1",
Expand Down
121 changes: 22 additions & 99 deletions src/common/safeIpc.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import {
BrowserWindow,
IpcMainEvent,
IpcMainInvokeEvent,
IpcRendererEvent,
MessagePortMain,
WebContents,
ipcMain as unsafeIpcMain,
ipcRenderer as unsafeIpcRenderer,
} from 'electron';
import { type FileFilter, type OpenDialogReturnValue } from 'electron'; // TODO: replace with electron/common
import { MakeDirectoryOptions } from 'fs';
import { Mode, ObjectEncodingOptions, OpenMode, PathLike } from 'original-fs';
import { FileOpenResult, FileSaveResult, PythonInfo, Version } from './common-types';
Expand All @@ -26,14 +17,10 @@ export interface InvokeChannels {
'get-backend-url': ChannelInfo<string>;
'refresh-nodes': ChannelInfo<boolean>;
'get-app-version': ChannelInfo<Version>;
'dir-select': ChannelInfo<Electron.OpenDialogReturnValue, [dirPath: string]>;
'dir-select': ChannelInfo<OpenDialogReturnValue, [dirPath: string]>;
'file-select': ChannelInfo<
Electron.OpenDialogReturnValue,
[
filters: Electron.FileFilter[],
allowMultiple: boolean | undefined,
dirPath: string | undefined
]
OpenDialogReturnValue,
[filters: FileFilter[], allowMultiple: boolean | undefined, dirPath: string | undefined]
>;

'file-save-json': ChannelInfo<void, [saveData: SaveData, savePath: string]>;
Expand Down Expand Up @@ -91,6 +78,24 @@ export interface InvokeChannels {
'fs-readdir': ChannelInfo<string[], [path: string]>;
'fs-unlink': ChannelInfo<void, [path: string]>;
'fs-access': ChannelInfo<void, [path: string]>;

// Electron
'shell-showItemInFolder': ChannelInfo<void, [fullPath: string]>;
'shell-openPath': ChannelInfo<string, [fullPath: string]>;
'app-quit': ChannelInfo<void>;
'clipboard-writeText': ChannelInfo<void, [text: string]>;
'clipboard-readText': ChannelInfo<string>;
'clipboard-writeBuffer': ChannelInfo<
void,
[format: string, buffer: Buffer, type?: 'selection' | 'clipboard' | undefined]
>;
'clipboard-readBuffer': ChannelInfo<Buffer, [format: string]>;
'clipboard-availableFormats': ChannelInfo<string[]>;
'clipboard-readHTML': ChannelInfo<string>;
'clipboard-readRTF': ChannelInfo<string>;
'clipboard-readImage': ChannelInfo<Electron.NativeImage>;
'clipboard-writeImage': ChannelInfo<void, [image: Electron.NativeImage]>;
'clipboard-writeImageFromURL': ChannelInfo<void, [url: string]>;
}

export interface SendChannels {
Expand Down Expand Up @@ -135,85 +140,3 @@ export type ChannelArgs<C extends keyof (InvokeChannels & SendChannels)> = (Invo
SendChannels)[C]['args'];
export type ChannelReturn<C extends keyof (InvokeChannels & SendChannels)> = (InvokeChannels &
SendChannels)[C]['returnType'];

interface SafeIpcMain extends Electron.IpcMain {
handle<C extends keyof InvokeChannels>(
channel: C,
listener: (
event: IpcMainInvokeEvent,
...args: ChannelArgs<C>
) => Promise<ChannelReturn<C>> | ChannelReturn<C>
): void;
handleOnce<C extends keyof InvokeChannels>(
channel: C,
listener: (
event: IpcMainInvokeEvent,
...args: ChannelArgs<C>
) => Promise<ChannelReturn<C>> | ChannelReturn<C>
): void;
on<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcMainEvent, ...args: ChannelArgs<C>) => void
): this;
once<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcMainEvent, ...args: ChannelArgs<C>) => void
): this;
removeAllListeners(channel?: keyof SendChannels): this;
removeHandler(channel: keyof InvokeChannels): void;
removeListener<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcMainEvent | IpcMainInvokeEvent, ...args: ChannelArgs<C>) => void
): this;
}

interface SafeIpcRenderer extends Electron.IpcRenderer {
invoke<C extends keyof InvokeChannels>(
channel: C,
...args: ChannelArgs<C>
): Promise<ChannelReturn<C>>;
on<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcRendererEvent, ...args: ChannelArgs<C>) => void
): this;
once<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcRendererEvent, ...args: ChannelArgs<C>) => void
): this;
postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePort[]): void;
removeAllListeners(channel: keyof SendChannels): this;
removeListener<C extends keyof SendChannels>(
channel: C,
listener: (event: IpcRendererEvent, ...args: ChannelArgs<C>) => void
): this;
send<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): void;
sendSync<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): void;
sendTo<C extends keyof SendChannels>(
webContentsId: number,
channel: C,
...args: ChannelArgs<C>
): void;
sendToHost<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): void;
}

interface WebContentsWithSafeIcp extends WebContents {
invoke<C extends keyof SendChannels>(
channel: C,
...args: ChannelArgs<C>
): Promise<ChannelReturn<C>>;
postMessage(channel: keyof SendChannels, message: unknown, transfer?: MessagePortMain[]): void;
send<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): void;
sendSync<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): ChannelReturn<C>;
sendTo<C extends keyof SendChannels>(
webContentsId: number,
channel: C,
...args: ChannelArgs<C>
): void;
sendToHost<C extends keyof SendChannels>(channel: C, ...args: ChannelArgs<C>): void;
}
export interface BrowserWindowWithSafeIpc extends BrowserWindow {
webContents: WebContentsWithSafeIcp;
}

export const ipcMain = unsafeIpcMain as SafeIpcMain;
export const ipcRenderer = unsafeIpcRenderer as SafeIpcRenderer;
2 changes: 1 addition & 1 deletion src/main/backend/process.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
import { app } from 'electron';
import { app } from 'electron/main';
import { existsSync } from 'fs';
import path from 'path';
import { getBackend } from '../../common/Backend';
Expand Down
2 changes: 1 addition & 1 deletion src/main/cli/create.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { app } from 'electron';
import electronLog from 'electron-log';
import { app } from 'electron/main';
import { log } from '../../common/log';
import { Exit } from './exit';

Expand Down
2 changes: 1 addition & 1 deletion src/main/cli/run.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { app } from 'electron';
import { app } from 'electron/main';
import EventSource from 'eventsource';
import { Backend, BackendEventMap, getBackend } from '../../common/Backend';
import { EdgeData, NodeData, NodeSchema, SchemaId } from '../../common/common-types';
Expand Down
2 changes: 1 addition & 1 deletion src/main/gui/create.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { app, dialog } from 'electron';
import electronLog from 'electron-log';
import { app, dialog } from 'electron/main';
import { log } from '../../common/log';
import { lazy } from '../../common/util';
import { OpenArguments } from '../arguments';
Expand Down
25 changes: 23 additions & 2 deletions src/main/gui/main-window.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker, shell } from 'electron';
import { clipboard, nativeImage, shell } from 'electron/common';
import { BrowserWindow, app, dialog, nativeTheme, powerSaveBlocker } from 'electron/main';
import EventSource from 'eventsource';
import fs, { constants } from 'fs/promises';
import { t } from 'i18next';
import { BackendEventMap } from '../../common/Backend';
import { Version } from '../../common/common-types';
import { isMac } from '../../common/env';
import { log } from '../../common/log';
import { BrowserWindowWithSafeIpc, ipcMain } from '../../common/safeIpc';
import { SaveFile, openSaveFile } from '../../common/SaveFile';
import { ChainnerSettings } from '../../common/settings/settings';
import { CriticalError } from '../../common/ui/error';
Expand All @@ -15,6 +15,7 @@ import { OpenArguments, parseArgs } from '../arguments';
import { BackendProcess } from '../backend/process';
import { setupBackend } from '../backend/setup';
import { getRootDirSync } from '../platform';
import { BrowserWindowWithSafeIpc, ipcMain } from '../safeIpc';
import { writeSettings } from '../setting-storage';
import { MenuData, setMainMenu } from './menu';
import { addSplashScreen } from './splash';
Expand Down Expand Up @@ -214,6 +215,26 @@ const registerEventHandlerPreSetup = (
ipcMain.handle('fs-readdir', async (event, path) => fs.readdir(path));
ipcMain.handle('fs-unlink', async (event, path) => fs.unlink(path));
ipcMain.handle('fs-access', async (event, path) => fs.access(path));

// Handle electron
ipcMain.handle('shell-showItemInFolder', (event, fullPath) => shell.showItemInFolder(fullPath));
ipcMain.handle('shell-openPath', (event, fullPath) => shell.openPath(fullPath));
ipcMain.handle('app-quit', () => app.quit());
ipcMain.handle('clipboard-writeText', (event, text) => clipboard.writeText(text));
ipcMain.handle('clipboard-readText', () => clipboard.readText());
ipcMain.handle('clipboard-writeBuffer', (event, format, buffer, type) =>
clipboard.writeBuffer(format, buffer, type)
);
ipcMain.handle('clipboard-readBuffer', (event, format) => clipboard.readBuffer(format));
ipcMain.handle('clipboard-availableFormats', () => clipboard.availableFormats());
ipcMain.handle('clipboard-readHTML', () => clipboard.readHTML());
ipcMain.handle('clipboard-readRTF', () => clipboard.readRTF());
ipcMain.handle('clipboard-readImage', () => clipboard.readImage());
ipcMain.handle('clipboard-writeImage', (event, image) => clipboard.writeImage(image));
ipcMain.handle('clipboard-writeImageFromURL', (event, url) => {
const image = nativeImage.createFromDataURL(url);
clipboard.writeImage(image);
});
};

const registerEventHandlerPostSetup = (
Expand Down
5 changes: 3 additions & 2 deletions src/main/gui/menu.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { Menu, MenuItemConstructorOptions, app, dialog, shell } from 'electron';
import { shell } from 'electron/common';
import { Menu, MenuItemConstructorOptions, app, dialog } from 'electron/main';
import os from 'os';
import path from 'path';
import { isMac } from '../../common/env';
import { links } from '../../common/links';
import { BrowserWindowWithSafeIpc } from '../../common/safeIpc';
import { openSaveFile } from '../../common/SaveFile';
import { getLogsFolder } from '../platform';
import { BrowserWindowWithSafeIpc } from '../safeIpc';
import { getCpuInfo, getGpuInfo } from '../systemInfo';

export interface MenuData {
Expand Down
5 changes: 3 additions & 2 deletions src/main/gui/splash.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { BrowserWindow, MessageBoxOptions, app, dialog, shell } from 'electron';
import { shell } from 'electron/common';
import { BrowserWindow, MessageBoxOptions, app, dialog } from 'electron/main';
import { log } from '../../common/log';
import { BrowserWindowWithSafeIpc } from '../../common/safeIpc';
import { Progress, ProgressMonitor } from '../../common/ui/progress';
import { assertNever } from '../../common/util';
import { BrowserWindowWithSafeIpc } from '../safeIpc';

export type SplashStage = 'init' | 'done';

Expand Down
Loading

0 comments on commit 140509f

Please sign in to comment.