From 7de278f8b53e6f19f108762d02f99106f05e6da2 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 3 Nov 2020 08:39:50 +0200 Subject: [PATCH] auto enable/disable extensions -- part 2 Signed-off-by: Roman --- src/extensions/extension-loader.ts | 42 +++++++++++++++------- src/extensions/lens-extension.ts | 16 ++------- src/extensions/registries/base-registry.ts | 16 ++++++--- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index eafe7e13d1..37bc80080d 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -3,7 +3,7 @@ import type { LensMainExtension } from "./lens-main-extension" import type { LensRendererExtension } from "./lens-renderer-extension" import path from "path" import { broadcastIpc } from "../common/ipc" -import { action, computed, observable, reaction, toJS } from "mobx" +import { action, autorun, computed, observable, reaction, toJS } from "mobx" import logger from "../main/logger" import { app, ipcRenderer, remote } from "electron" import { BaseStore } from "../common/base-store"; @@ -25,6 +25,8 @@ export function extensionPackagesRoot() { } export class ExtensionLoader extends BaseStore { + protected disposers = new Map(); + @observable extensions = observable.map([], { deep: false }); @observable instances = observable.map([], { deep: false }) @observable state = observable.map(); @@ -48,11 +50,22 @@ export class ExtensionLoader extends BaseStore { return [...this.instances.values()].filter(ext => !ext.isBundled) } + protected handleActivation(ext: LensExtension, addToRegistry: () => Function[]) { + if (ext.isEnabled) { + this.disposers.set(ext.id, addToRegistry()) + } else { + this.disposers.get(ext.id)?.forEach(dispose => dispose()) + this.disposers.delete(ext.id) + } + } + loadOnMain() { logger.info('[EXTENSIONS-LOADER]: load on main') this.autoInitExtensions(); this.autoEnableExtensions((extension: LensMainExtension) => { - extension.registerTo(registries.menuRegistry, extension.appMenus) + this.handleActivation(extension, () => [ + registries.menuRegistry.add(...extension.appMenus) + ]) }) } @@ -60,10 +73,12 @@ export class ExtensionLoader extends BaseStore { logger.info('[EXTENSIONS-LOADER]: load on main renderer (cluster manager)') this.autoInitExtensions(); this.autoEnableExtensions((extension: LensRendererExtension) => { - extension.registerTo(registries.globalPageRegistry, extension.globalPages) - extension.registerTo(registries.appPreferenceRegistry, extension.appPreferences) - extension.registerTo(registries.clusterFeatureRegistry, extension.clusterFeatures) - extension.registerTo(registries.statusBarRegistry, extension.statusBarItems) + this.handleActivation(extension, () => [ + registries.globalPageRegistry.add(...extension.globalPages), + registries.appPreferenceRegistry.add(...extension.appPreferences), + registries.clusterFeatureRegistry.add(...extension.clusterFeatures), + registries.statusBarRegistry.add(...extension.statusBarItems), + ]) }) } @@ -71,15 +86,17 @@ export class ExtensionLoader extends BaseStore { logger.info('[EXTENSIONS-LOADER]: load on cluster renderer (dashboard)') this.autoInitExtensions(); this.autoEnableExtensions((extension: LensRendererExtension) => { - extension.registerTo(registries.clusterPageRegistry, extension.clusterPages) - extension.registerTo(registries.kubeObjectMenuRegistry, extension.kubeObjectMenuItems) - extension.registerTo(registries.kubeObjectDetailRegistry, extension.kubeObjectDetailItems) + this.handleActivation(extension, () => [ + registries.clusterPageRegistry.add(...extension.clusterPages), + registries.kubeObjectMenuRegistry.add(...extension.kubeObjectMenuItems), + registries.kubeObjectDetailRegistry.add(...extension.kubeObjectDetailItems), + ]) }) } protected autoEnableExtensions(callback: (ext: LensExtension) => void) { - return reaction(() => this.instances.toJS(), instances => { - instances.forEach(ext => { + return autorun(() => { + this.instances.forEach(ext => { const extensionState = this.state.get(ext.id); const enabledInStore = !extensionState /*enabled by default*/ || extensionState.isEnabled; if (!ext.isEnabled && enabledInStore) { @@ -87,10 +104,9 @@ export class ExtensionLoader extends BaseStore { callback(ext); } else if (ext.isEnabled && !enabledInStore) { ext.disable(); + callback(ext); } }) - }, { - fireImmediately: true, }) } diff --git a/src/extensions/lens-extension.ts b/src/extensions/lens-extension.ts index 89cb77e1f0..f6579ed1f3 100644 --- a/src/extensions/lens-extension.ts +++ b/src/extensions/lens-extension.ts @@ -1,6 +1,5 @@ import { action, observable, toJS } from "mobx"; import logger from "../main/logger"; -import { BaseRegistry } from "./registries/base-registry"; import type { InstalledExtension } from "./extension-loader"; export type LensExtensionId = string; // path to manifest (package.json) @@ -24,7 +23,6 @@ export class LensExtension { public manifest: LensExtensionManifest; public manifestPath: string; public isBundled: boolean; - protected disposers: (() => void)[] = []; @observable isEnabled = false; @@ -54,17 +52,15 @@ export class LensExtension { async enable() { if (this.isEnabled) return; this.isEnabled = true; - logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`); this.onActivate(); + logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`); } @action async disable() { if (!this.isEnabled) return; - this.onDeactivate(); this.isEnabled = false; - this.disposers.forEach(cleanUp => cleanUp()); - this.disposers.length = 0; + this.onDeactivate(); logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`); } @@ -84,14 +80,6 @@ export class LensExtension { // mock } - registerTo(registry: BaseRegistry, items: T[] = []) { - const disposers = items.map(item => registry.add(item)); - this.disposers.push(...disposers); - return () => { - this.disposers = this.disposers.filter(disposer => !disposers.includes(disposer)) - }; - } - toJSON(): LensExtensionStoreModel { return toJS({ id: this.id, diff --git a/src/extensions/registries/base-registry.ts b/src/extensions/registries/base-registry.ts index 01613a59eb..ff23e36cad 100644 --- a/src/extensions/registries/base-registry.ts +++ b/src/extensions/registries/base-registry.ts @@ -1,5 +1,5 @@ // Base class for extensions-api registries -import { observable } from "mobx"; +import { action, observable } from "mobx"; export class BaseRegistry { protected items = observable([], { deep: false }); @@ -8,10 +8,16 @@ export class BaseRegistry { return this.items.toJS(); } - add(item: T) { - this.items.push(item); - return () => { + @action + add(...items: T[]) { + this.items.push(...items); + return () => this.remove(...items); + } + + @action + remove(...items: T[]) { + items.forEach(item => { this.items.remove(item); // works because of {deep: false}; - } + }) } }