From db2be9fe5072959b45d28f38838b70eab4b3c052 Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Sat, 22 Jul 2023 19:27:32 +0530 Subject: [PATCH] basic setup to remove @electron/remote --- app/plugins.ts | 7 +++++++ app/rpc.ts | 2 +- common.d.ts | 7 +++++++ lib/command-registry.ts | 9 +++------ lib/containers/hyper.tsx | 8 ++++---- lib/utils/config.ts | 2 +- lib/utils/ipc-child-process.ts | 4 +--- lib/utils/ipc.ts | 4 ++++ lib/utils/plugins.ts | 6 ++---- lib/utils/rpc.ts | 13 +++++++------ 10 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 lib/utils/ipc.ts diff --git a/app/plugins.ts b/app/plugins.ts index a839c435..3f53cb8e 100644 --- a/app/plugins.ts +++ b/app/plugins.ts @@ -467,3 +467,10 @@ ipcMain.handle('child_process.exec', (event, command, options) => { ipcMain.handle('child_process.execFile', (event, file, args, options) => { return promisify(execFile)(file, args, options); }); + +ipcMain.handle('getLoadedPluginVersions', () => getLoadedPluginVersions()); +ipcMain.handle('getPaths', () => getPaths()); +ipcMain.handle('getBasePaths', () => getBasePaths()); +ipcMain.handle('getDeprecatedConfig', () => getDeprecatedConfig()); +ipcMain.handle('getDecoratedConfig', (e, profile) => getDecoratedConfig(profile)); +ipcMain.handle('getDecoratedKeymaps', () => getDecoratedKeymaps()); diff --git a/app/rpc.ts b/app/rpc.ts index 13f41e67..129a406f 100644 --- a/app/rpc.ts +++ b/app/rpc.ts @@ -28,7 +28,7 @@ export class Server { // to support reloading the window and re-initializing // the channel this.wc.on('did-finish-load', () => { - this.wc.send('init', uid); + this.wc.send('init', uid, win.profileName); }); } diff --git a/common.d.ts b/common.d.ts index 7ab9fc1c..5797b4e9 100644 --- a/common.d.ts +++ b/common.d.ts @@ -1,6 +1,7 @@ import type parseUrl from 'parse-url'; import type {IpcMain, IpcRenderer} from 'electron'; import type {ExecFileOptions, ExecOptions} from 'child_process'; +import type {configOptions} from './lib/config'; export type Session = { uid: string; @@ -115,6 +116,12 @@ export type IpcCommands = { stdout: string; stderr: string; }; + getLoadedPluginVersions: () => {name: string; version: string}[]; + getPaths: () => {plugins: string[]; localPlugins: string[]}; + getBasePaths: () => {path: string; localPath: string}; + getDeprecatedConfig: () => Record; + getDecoratedConfig: (profile: string) => configOptions; + getDecoratedKeymaps: () => Record; }; export interface IpcMainWithCommands extends IpcMain { diff --git a/lib/command-registry.ts b/lib/command-registry.ts index 27bbe172..0379c50b 100644 --- a/lib/command-registry.ts +++ b/lib/command-registry.ts @@ -1,9 +1,6 @@ -import {require as remoteRequire} from '@electron/remote'; +import {ipcRenderer} from './utils/ipc'; import type {HyperDispatch} from './hyper'; import {closeSearch} from './actions/sessions'; -// TODO: Should be updates to new async API https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31 - -const {getDecoratedKeymaps} = remoteRequire('./plugins') as typeof import('../app/plugins'); let commands: Record void> = { 'editor:search-close': (e, dispatch) => { @@ -12,8 +9,8 @@ let commands: Record void> = { } }; -export const getRegisteredKeys = () => { - const keymaps = getDecoratedKeymaps(); +export const getRegisteredKeys = async () => { + const keymaps = await ipcRenderer.invoke('getDecoratedKeymaps'); return Object.keys(keymaps).reduce((result: Record, actionName) => { const commandKeys = keymaps[actionName]; diff --git a/lib/containers/hyper.tsx b/lib/containers/hyper.tsx index 53efda6c..ea6c15c0 100644 --- a/lib/containers/hyper.tsx +++ b/lib/containers/hyper.tsx @@ -25,7 +25,7 @@ class Hyper extends React.PureComponent { componentDidUpdate(prev: HyperProps) { const {lastConfigUpdate} = this.props; if (lastConfigUpdate && lastConfigUpdate !== prev.lastConfigUpdate) { - this.attachKeyListeners(); + void this.attachKeyListeners(); } if (prev.activeSession !== this.props.activeSession) { this.handleFocusActive(this.props.activeSession); @@ -46,7 +46,7 @@ class Hyper extends React.PureComponent { } }; - attachKeyListeners() { + async attachKeyListeners() { if (!this.mousetrap) { // eslint-disable-next-line @typescript-eslint/no-unsafe-call this.mousetrap = new (Mousetrap as any)(window, true); @@ -58,7 +58,7 @@ class Hyper extends React.PureComponent { this.mousetrap.reset(); } - const keys = getRegisteredKeys(); + const keys = await getRegisteredKeys(); Object.keys(keys).forEach((commandKeys) => { this.mousetrap.bind( commandKeys, @@ -75,7 +75,7 @@ class Hyper extends React.PureComponent { } componentDidMount() { - this.attachKeyListeners(); + void this.attachKeyListeners(); window.rpc.on('term selectAll', this.handleSelectAll); } diff --git a/lib/utils/config.ts b/lib/utils/config.ts index 0cdab4d8..7ed1531b 100644 --- a/lib/utils/config.ts +++ b/lib/utils/config.ts @@ -1,4 +1,4 @@ -import {ipcRenderer} from 'electron'; +import {ipcRenderer} from './ipc'; import {require as remoteRequire, getCurrentWindow} from '@electron/remote'; // TODO: Should be updates to new async API https://medium.com/@nornagon/electrons-remote-module-considered-harmful-70d69500f31 diff --git a/lib/utils/ipc-child-process.ts b/lib/utils/ipc-child-process.ts index cf6d2b73..0dc4db57 100644 --- a/lib/utils/ipc-child-process.ts +++ b/lib/utils/ipc-child-process.ts @@ -1,7 +1,5 @@ -import electron from 'electron'; -import type {IpcRendererWithCommands} from '../../common'; import type {ExecFileOptions, ExecOptions} from 'child_process'; -const ipcRenderer = electron.ipcRenderer as IpcRendererWithCommands; +import {ipcRenderer} from './ipc'; export function exec(command: string, options: ExecOptions, callback: (..._args: any) => void) { if (typeof options === 'function') { diff --git a/lib/utils/ipc.ts b/lib/utils/ipc.ts new file mode 100644 index 00000000..55a7eeb1 --- /dev/null +++ b/lib/utils/ipc.ts @@ -0,0 +1,4 @@ +import {ipcRenderer as _ipc} from 'electron'; +import type {IpcRendererWithCommands} from '../../common'; + +export const ipcRenderer = _ipc as IpcRendererWithCommands; diff --git a/lib/utils/plugins.ts b/lib/utils/plugins.ts index 456bc3f9..ddf55aa1 100644 --- a/lib/utils/plugins.ts +++ b/lib/utils/plugins.ts @@ -5,7 +5,7 @@ import {require as remoteRequire} from '@electron/remote'; import type {Options} from 'react-redux'; import {connect as reduxConnect} from 'react-redux'; -import {basename} from 'path'; +import pathModule from 'path'; // patching Module._load // so plugins can `require` them without needing their own version @@ -219,8 +219,6 @@ const clearModulesCache = () => { } }; -const pathModule = window.require('path') as typeof import('path'); - const getPluginName = (path: string) => pathModule.basename(path); const getPluginVersion = (path: string): string | null => { @@ -269,7 +267,7 @@ const loadModules = () => { const loadedPlugins = plugins.getLoadedPluginVersions().map((plugin: any) => plugin.name); modules = paths.plugins .concat(paths.localPlugins) - .filter((plugin) => loadedPlugins.indexOf(basename(plugin)) !== -1) + .filter((plugin) => loadedPlugins.indexOf(pathModule.basename(plugin)) !== -1) .map((path) => { let mod: hyperPlugin; const pluginName = getPluginName(path); diff --git a/lib/utils/rpc.ts b/lib/utils/rpc.ts index 0cc5e364..6b67a582 100644 --- a/lib/utils/rpc.ts +++ b/lib/utils/rpc.ts @@ -1,16 +1,16 @@ import {EventEmitter} from 'events'; -import type {IpcRenderer, IpcRendererEvent} from 'electron'; -import electron from 'electron'; -import type {FilterNever, MainEvents, RendererEvents, TypedEmitter} from '../../common'; +import type {IpcRendererEvent} from 'electron'; +import type {FilterNever, IpcRendererWithCommands, MainEvents, RendererEvents, TypedEmitter} from '../../common'; +import {ipcRenderer} from './ipc'; export default class Client { emitter: TypedEmitter; - ipc: IpcRenderer; + ipc: IpcRendererWithCommands; id!: string; constructor() { this.emitter = new EventEmitter(); - this.ipc = electron.ipcRenderer; + this.ipc = ipcRenderer; this.emit = this.emit.bind(this); if (window.__rpcId) { setTimeout(() => { @@ -19,11 +19,12 @@ export default class Client { this.emitter.emit('ready'); }, 0); } else { - this.ipc.on('init', (ev: IpcRendererEvent, uid: string) => { + this.ipc.on('init', (ev: IpcRendererEvent, uid: string, profileName: string) => { // we cache so that if the object // gets re-instantiated we don't // wait for a `init` event window.__rpcId = uid; + // window.profileName = profileName; this.id = uid; this.ipc.on(uid, this.ipcListener); this.emitter.emit('ready');