diff --git a/src/common/base-store.ts b/src/common/base-store.ts index 6aab88e940..17cc8d08e1 100644 --- a/src/common/base-store.ts +++ b/src/common/base-store.ts @@ -37,12 +37,12 @@ export class BaseStore extends Singleton { return path.basename(this.storeConfig.path); } - get syncRendererChannel() { - return `store-sync-renderer:${this.name}` + protected get syncRendererChannel() { + return `store-sync-renderer:${this.path}` } - get syncMainChannel() { - return `store-sync-main:${this.name}` + protected get syncMainChannel() { + return `store-sync-main:${this.path}` } get path() { diff --git a/src/common/cluster-frames.ts b/src/common/cluster-frames.ts new file mode 100644 index 0000000000..af950b0785 --- /dev/null +++ b/src/common/cluster-frames.ts @@ -0,0 +1,3 @@ +import { observable } from "mobx" + +export const clusterFrameMap = observable.map(); diff --git a/src/common/cluster-ipc.ts b/src/common/cluster-ipc.ts index 4a84e0304b..96beb35673 100644 --- a/src/common/cluster-ipc.ts +++ b/src/common/cluster-ipc.ts @@ -4,6 +4,7 @@ import { appEventBus } from "./event-bus" import { ResourceApplier } from "../main/resource-applier"; import { ipcMain } from "electron"; import { ClusterManager } from "../main/cluster-manager"; +import { clusterFrameMap } from "./cluster-frames" export const clusterActivateHandler = "cluster:activate" export const clusterSetFrameIdHandler = "cluster:set-frame-id" @@ -23,7 +24,7 @@ if (ipcMain) { handleRequest(clusterSetFrameIdHandler, (event, clusterId: ClusterId, frameId?: number) => { const managedCluster = getById(clusterId); if (managedCluster) { - if (frameId) managedCluster.cluster.frameId = frameId; // save cluster's webFrame.routingId to be able to send push-updates + clusterFrameMap.set(managedCluster.cluster.id, frameId) return managedCluster.cluster.pushState(); } }) @@ -34,7 +35,11 @@ if (ipcMain) { handleRequest(clusterDisconnectHandler, (event, clusterId: ClusterId) => { appEventBus.emit({name: "cluster", action: "stop"}); - return getById(clusterId)?.disconnect(); + const managedCluster = getById(clusterId); + if (managedCluster) { + managedCluster.disconnect(); + clusterFrameMap.delete(managedCluster.id) + } }) handleRequest(clusterKubectlApplyAllHandler, (event, clusterId: ClusterId, resources: string[]) => { diff --git a/src/common/ipc.ts b/src/common/ipc.ts index 6e2a76c5ed..882498a3a4 100644 --- a/src/common/ipc.ts +++ b/src/common/ipc.ts @@ -2,8 +2,9 @@ // https://www.electronjs.org/docs/api/ipc-main // https://www.electronjs.org/docs/api/ipc-renderer -import { ipcMain, ipcRenderer, webContents, remote } from "electron" +import { ipcMain, ipcRenderer, webContents, remote } from "electron"; import logger from "../main/logger"; +import { clusterFrameMap } from "./cluster-frames"; export function handleRequest(channel: string, listener: (...args: any[]) => any) { ipcMain.handle(channel, listener) @@ -15,11 +16,8 @@ export async function requestMain(channel: string, ...args: any[]) { async function getSubFrames(): Promise { const subFrames: number[] = []; - const { clusterStore } = await import("./cluster-store"); - clusterStore.clustersList.forEach(cluster => { - if (cluster.frameId) { - subFrames.push(cluster.frameId) - } + clusterFrameMap.forEach((frameId, _) => { + subFrames.push(frameId) }); return subFrames; } diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index 4893cd11e2..c5339f31c9 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -3,12 +3,10 @@ import type { LensMainExtension } from "./lens-main-extension" import type { LensRendererExtension } from "./lens-renderer-extension" import type { InstalledExtension } from "./extension-manager"; import path from "path" -import { broadcastMessage, subscribeToBroadcast } from "../common/ipc" +import { broadcastMessage, handleRequest, requestMain, subscribeToBroadcast } from "../common/ipc" import { action, computed, observable, reaction, toJS, when } from "mobx" import logger from "../main/logger" import { app, ipcRenderer, remote } from "electron" -import { appEventBus } from "./core-api/event-bus" -import { clusterStore } from "./core-api/stores" import * as registries from "./registries"; import { extensionsStore } from "./extensions-store"; @@ -20,37 +18,11 @@ export function extensionPackagesRoot() { export class ExtensionLoader { protected extensions = observable.map(); protected instances = observable.map(); + protected readonly requestExtensionsChannel = "extensions:loaded" @observable isLoaded = false; whenLoaded = when(() => this.isLoaded); - constructor() { - if (ipcRenderer) { - subscribeToBroadcast("extensions:loaded", (event, extensions: [LensExtensionId, InstalledExtension][]) => { - console.log("extensions", extensions) - this.isLoaded = true; - extensions.forEach(([extId, ext]) => { - if (!this.extensions.has(extId)) { - this.extensions.set(extId, ext) - } - }) - }); - } else { - reaction(() => this.extensions.toJS(), () => { - this.broadcastExtensions() - }) - appEventBus.addListener((ev) => { - if (ev.name === "app" && ev.action === "dom-ready") { - this.broadcastExtensions() - } - }) - reaction(() => clusterStore.connectedClustersList, () => { - this.broadcastExtensions() - }) - } - extensionsStore.manageState(this); - } - @computed get userExtensions(): Map { const extensions = this.extensions.toJS(); extensions.forEach((ext, extId) => { @@ -62,11 +34,45 @@ export class ExtensionLoader { } @action - async init(extensions: Map) { - this.extensions.replace(extensions); + async init(extensions?: Map) { + if (extensions) { + this.extensions.replace(extensions); + } + if (ipcRenderer) { + this.initRenderer() + } else { + this.initMain() + } + extensionsStore.manageState(this); + } + + protected async initMain() { this.isLoaded = true; this.loadOnMain(); this.broadcastExtensions(); + + reaction(() => this.extensions.toJS(), () => { + this.broadcastExtensions() + }) + + handleRequest(this.requestExtensionsChannel, () => { + return Array.from(this.toJSON()) + }) + } + + protected async initRenderer() { + const extensionListHandler = ( extensions: [LensExtensionId, InstalledExtension][]) => { + this.isLoaded = true; + extensions.forEach(([extId, ext]) => { + if (!this.extensions.has(extId)) { + this.extensions.set(extId, ext) + } + }) + } + requestMain(this.requestExtensionsChannel).then(extensionListHandler) + subscribeToBroadcast(this.requestExtensionsChannel, (event, extensions: [LensExtensionId, InstalledExtension][]) => { + extensionListHandler(extensions) + }); } loadOnMain() { @@ -156,7 +162,7 @@ export class ExtensionLoader { } broadcastExtensions() { - broadcastMessage("extensions:loaded", Array.from(this.toJSON())) + broadcastMessage(this.requestExtensionsChannel, Array.from(this.toJSON())) } } diff --git a/src/main/cluster.ts b/src/main/cluster.ts index beb12538cf..411647809c 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -33,7 +33,6 @@ export interface ClusterState { export class Cluster implements ClusterModel, ClusterState { public id: ClusterId; - public frameId: number; public kubeCtl: Kubectl public ownerRef: string; diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index 33a943b552..019ed270eb 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -1,5 +1,4 @@ import type { ClusterId } from "../common/cluster-store"; -import { clusterStore } from "../common/cluster-store"; import { observable } from "mobx"; import { app, BrowserWindow, dialog, shell, webContents } from "electron" import windowStateKeeper from "electron-window-state" @@ -8,6 +7,7 @@ import { subscribeToBroadcast } from "../common/ipc" import { initMenu } from "./menu"; import { initTray } from "./tray"; import { Singleton } from "../common/utils"; +import { clusterFrameMap } from "../common/cluster-frames"; export class WindowManager extends Singleton { protected mainWindow: BrowserWindow; @@ -130,7 +130,7 @@ export class WindowManager extends Singleton { } reload() { - const frameId = clusterStore.getById(this.activeClusterId)?.frameId; + const frameId = clusterFrameMap.get(this.activeClusterId) if (frameId) { this.sendToView({ channel: "renderer:reload", frameId }); } else { diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index 52a92b7c11..cfadb5c379 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -14,6 +14,7 @@ import { clusterStore } from "../common/cluster-store"; import { i18nStore } from "./i18n"; import { themeStore } from "./theme.store"; import { extensionsStore } from "../extensions/extensions-store"; +import { extensionLoader } from "../extensions/extension-loader"; type AppComponent = React.ComponentType & { init?(): Promise; @@ -30,6 +31,8 @@ export async function bootstrap(App: AppComponent) { const rootElem = document.getElementById("app") rootElem.classList.toggle("is-mac", isMac); + extensionLoader.init() + // preload common stores await Promise.all([ userStore.load(),