mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Change where extension IPC is exported
- Now under Ipc.IpcMain and Ipc.IpcRenderer - Allow listener's to be cleaned up early by extensions Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
76d3a4b180
commit
ccac859b0b
@ -31,6 +31,7 @@ import * as Util from "./utils";
|
|||||||
import * as Interface from "../interfaces";
|
import * as Interface from "../interfaces";
|
||||||
import * as Catalog from "./catalog";
|
import * as Catalog from "./catalog";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
|
import * as Ipc from "./ipc";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
App,
|
App,
|
||||||
@ -40,4 +41,5 @@ export {
|
|||||||
Store,
|
Store,
|
||||||
Types,
|
Types,
|
||||||
Util,
|
Util,
|
||||||
|
Ipc,
|
||||||
};
|
};
|
||||||
|
|||||||
23
src/extensions/core-api/ipc.ts
Normal file
23
src/extensions/core-api/ipc.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2021 OpenLens Authors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { IpcMain } from "../ipc/ipc-main";
|
||||||
|
export { IpcRegistrar } from "../ipc/ipc-registrar";
|
||||||
@ -20,5 +20,3 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export { ExtensionStore } from "../extension-store";
|
export { ExtensionStore } from "../extension-store";
|
||||||
export { MainIpcStore } from "../main-ipc-store";
|
|
||||||
export { RendererIpcStore } from "../renderer-ipc-store";
|
|
||||||
|
|||||||
@ -19,27 +19,43 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import { ipcMain } from "electron";
|
import { ipcMain } from "electron";
|
||||||
import { IpcPrefix, IpcStore } from "./ipc-store";
|
import { IpcPrefix, IpcRegistrar } from "./ipc-registrar";
|
||||||
import { Disposers } from "./lens-extension";
|
import { Disposers } from "../lens-extension";
|
||||||
import type { LensMainExtension } from "./lens-main-extension";
|
import type { LensMainExtension } from "../lens-main-extension";
|
||||||
|
import type { Disposer } from "../../common/utils";
|
||||||
|
import { once } from "lodash";
|
||||||
|
|
||||||
export abstract class MainIpcStore extends IpcStore {
|
export abstract class IpcMain extends IpcRegistrar {
|
||||||
constructor(extension: LensMainExtension) {
|
constructor(extension: LensMainExtension) {
|
||||||
super(extension);
|
super(extension);
|
||||||
extension[Disposers].push(() => MainIpcStore.resetInstance());
|
extension[Disposers].push(() => IpcMain.resetInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for broadcasts within your extension
|
||||||
|
* @param channel The channel to listen for broadcasts on
|
||||||
|
* @param listener The function that will be called with the arguments of the broadcast
|
||||||
|
* @returns An optional disopser, Lens will cleanup when the extension is disabled or uninstalled even if this is not called
|
||||||
|
*/
|
||||||
|
listenIpc(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): Disposer {
|
||||||
|
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||||
|
const cleanup = once(() => ipcMain.removeListener(prefixedChannel, listener));
|
||||||
|
|
||||||
|
ipcMain.addListener(prefixedChannel, listener);
|
||||||
|
this.extension[Disposers].push(cleanup);
|
||||||
|
|
||||||
|
return cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare a RPC over `channel`. Lens will cleanup when the extension is disabled or uninstalled
|
||||||
|
* @param channel The name of the RPC
|
||||||
|
* @param handler The remote procedure that is called
|
||||||
|
*/
|
||||||
handleIpc(channel: string, handler: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any): void {
|
handleIpc(channel: string, handler: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any): void {
|
||||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||||
|
|
||||||
ipcMain.handle(prefixedChannel, handler);
|
ipcMain.handle(prefixedChannel, handler);
|
||||||
this.extension[Disposers].push(() => ipcMain.removeHandler(prefixedChannel));
|
this.extension[Disposers].push(() => ipcMain.removeHandler(prefixedChannel));
|
||||||
}
|
}
|
||||||
|
|
||||||
listenIpc(channel: string, listener: (event: Electron.IpcMainEvent, ...args: any[]) => any): void {
|
|
||||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
|
||||||
|
|
||||||
ipcMain.addListener(prefixedChannel, listener);
|
|
||||||
this.extension[Disposers].push(() => ipcMain.removeListener(prefixedChannel, listener));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -18,14 +18,14 @@
|
|||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import { Singleton } from "../common/utils";
|
import { Singleton } from "../../common/utils";
|
||||||
import type { LensExtension } from "./lens-extension";
|
import type { LensExtension } from "../lens-extension";
|
||||||
import { createHash } from "crypto";
|
import { createHash } from "crypto";
|
||||||
import { broadcastMessage } from "../common/ipc";
|
import { broadcastMessage } from "../../common/ipc";
|
||||||
|
|
||||||
export const IpcPrefix = Symbol();
|
export const IpcPrefix = Symbol();
|
||||||
|
|
||||||
export abstract class IpcStore extends Singleton {
|
export abstract class IpcRegistrar extends Singleton {
|
||||||
readonly [IpcPrefix]: string;
|
readonly [IpcPrefix]: string;
|
||||||
|
|
||||||
constructor(protected extension: LensExtension) {
|
constructor(protected extension: LensExtension) {
|
||||||
@ -33,6 +33,11 @@ export abstract class IpcStore extends Singleton {
|
|||||||
this[IpcPrefix] = createHash("sha256").update(extension.id).digest("hex");
|
this[IpcPrefix] = createHash("sha256").update(extension.id).digest("hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param channel The channel to broadcast to your whole extension, both `main` and `renderer`
|
||||||
|
* @param args The arguments passed to all listeners
|
||||||
|
*/
|
||||||
broadcastIpc(channel: string, ...args: any[]): void {
|
broadcastIpc(channel: string, ...args: any[]): void {
|
||||||
broadcastMessage(`extensions@${this[IpcPrefix]}:${channel}`, ...args);
|
broadcastMessage(`extensions@${this[IpcPrefix]}:${channel}`, ...args);
|
||||||
}
|
}
|
||||||
@ -19,23 +19,40 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
import { IpcPrefix, IpcStore } from "./ipc-store";
|
import { IpcPrefix, IpcRegistrar } from "./ipc-registrar";
|
||||||
import { Disposers } from "./lens-extension";
|
import { Disposers } from "../lens-extension";
|
||||||
import type { LensRendererExtension } from "./lens-renderer-extension";
|
import type { LensRendererExtension } from "../lens-renderer-extension";
|
||||||
|
import type { Disposer } from "../../common/utils";
|
||||||
|
import { once } from "lodash";
|
||||||
|
|
||||||
export abstract class RendererIpcStore extends IpcStore {
|
export abstract class IpcRenderer extends IpcRegistrar {
|
||||||
constructor(extension: LensRendererExtension) {
|
constructor(extension: LensRendererExtension) {
|
||||||
super(extension);
|
super(extension);
|
||||||
extension[Disposers].push(() => RendererIpcStore.resetInstance());
|
extension[Disposers].push(() => IpcRenderer.resetInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
listenIpc(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): void {
|
/**
|
||||||
|
* Listen for broadcasts within your extension
|
||||||
|
* @param channel The channel to listen for broadcasts on
|
||||||
|
* @param listener The function that will be called with the arguments of the broadcast
|
||||||
|
* @returns An optional disopser, Lens will cleanup even if this is not called
|
||||||
|
*/
|
||||||
|
listenIpc(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): Disposer {
|
||||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||||
|
const cleanup = once(() => ipcRenderer.removeListener(prefixedChannel, listener));
|
||||||
|
|
||||||
ipcRenderer.addListener(prefixedChannel, listener);
|
ipcRenderer.addListener(prefixedChannel, listener);
|
||||||
this.extension[Disposers].push(() => ipcRenderer.removeListener(prefixedChannel, listener));
|
this.extension[Disposers].push(cleanup);
|
||||||
|
|
||||||
|
return cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request main to execute its function over the `channel` channel.
|
||||||
|
* @param channel The channel to invoke a RPC on
|
||||||
|
* @param args The arguments to pass to the RPC
|
||||||
|
* @returns A promise of the resulting value
|
||||||
|
*/
|
||||||
invokeIpc(channel: string, ...args: any[]): Promise<any> {
|
invokeIpc(channel: string, ...args: any[]): Promise<any> {
|
||||||
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`;
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user