basic setup to remove @electron/remote

This commit is contained in:
Labhansh Agrawal 2023-07-22 19:27:32 +05:30
parent af41b343e3
commit db2be9fe50
10 changed files with 37 additions and 25 deletions

View file

@ -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());

View file

@ -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);
});
}

7
common.d.ts vendored
View file

@ -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<string, {css: string[]}>;
getDecoratedConfig: (profile: string) => configOptions;
getDecoratedKeymaps: () => Record<string, string[]>;
};
export interface IpcMainWithCommands extends IpcMain {

View file

@ -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<string, (event: any, dispatch: HyperDispatch) => void> = {
'editor:search-close': (e, dispatch) => {
@ -12,8 +9,8 @@ let commands: Record<string, (event: any, dispatch: HyperDispatch) => void> = {
}
};
export const getRegisteredKeys = () => {
const keymaps = getDecoratedKeymaps();
export const getRegisteredKeys = async () => {
const keymaps = await ipcRenderer.invoke('getDecoratedKeymaps');
return Object.keys(keymaps).reduce((result: Record<string, string>, actionName) => {
const commandKeys = keymaps[actionName];

View file

@ -25,7 +25,7 @@ class Hyper extends React.PureComponent<HyperProps> {
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<HyperProps> {
}
};
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<HyperProps> {
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<HyperProps> {
}
componentDidMount() {
this.attachKeyListeners();
void this.attachKeyListeners();
window.rpc.on('term selectAll', this.handleSelectAll);
}

View file

@ -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

View file

@ -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') {

4
lib/utils/ipc.ts Normal file
View file

@ -0,0 +1,4 @@
import {ipcRenderer as _ipc} from 'electron';
import type {IpcRendererWithCommands} from '../../common';
export const ipcRenderer = _ipc as IpcRendererWithCommands;

View file

@ -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);

View file

@ -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<RendererEvents>;
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');