From 8a793c01dbf10bf5f828352cdb4bc361e0e3d185 Mon Sep 17 00:00:00 2001 From: Jari Kolehmainen Date: Tue, 6 Oct 2020 14:37:42 +0300 Subject: [PATCH] support extensions in main process Signed-off-by: Jari Kolehmainen --- .gitignore | 1 + extensions/example-extension/index.tsx | 51 ------------------- extensions/example-extension/main.ts | 11 ++++ extensions/example-extension/package.json | 3 +- extensions/example-extension/page.tsx | 32 ++++++++++++ extensions/example-extension/renderer.ts | 24 +++++++++ extensions/example-extension/tsconfig.json | 3 +- package.json | 6 +-- src/common/vars.ts | 3 ++ src/extensions/extension-api.ts | 13 +---- src/extensions/extension-loader.ts | 49 ++++++++++++++---- src/extensions/extension-renderer-api.ts | 14 +++++ src/extensions/lens-extension.ts | 43 +++++----------- src/extensions/lens-main-extension.ts | 11 ++++ src/extensions/lens-renderer-extension.ts | 16 ++++++ src/extensions/lens-runtime.ts | 26 ++++------ .../{register-page.tsx => page-store.ts} | 4 +- src/extensions/rollup.config.ts | 15 +++++- src/main/index.ts | 2 + src/renderer/bootstrap.tsx | 3 -- src/renderer/components/app.tsx | 7 ++- .../cluster-manager/cluster-manager.tsx | 4 +- src/renderer/lens-app.tsx | 6 +++ webpack.renderer.ts | 16 +++++- 24 files changed, 227 insertions(+), 136 deletions(-) delete mode 100644 extensions/example-extension/index.tsx create mode 100644 extensions/example-extension/main.ts create mode 100644 extensions/example-extension/page.tsx create mode 100644 extensions/example-extension/renderer.ts create mode 100644 src/extensions/extension-renderer-api.ts create mode 100644 src/extensions/lens-main-extension.ts create mode 100644 src/extensions/lens-renderer-extension.ts rename src/extensions/{register-page.tsx => page-store.ts} (93%) diff --git a/.gitignore b/.gitignore index 68c773c895..16803f4b39 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ src/extensions/*/*.js src/extensions/*/*.d.ts src/extensions/example-extension/src/** types/extension-api.d.ts +types/extension-renderer-api.d.ts diff --git a/extensions/example-extension/index.tsx b/extensions/example-extension/index.tsx deleted file mode 100644 index f46a9dd1fc..0000000000 --- a/extensions/example-extension/index.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Button, DynamicPageType, Icon, IconProps, LensExtension, React } from "@lens/extensions"; -import { CoffeeDoodle } from "react-open-doodles"; -import path from "path"; - -export default class ExampleExtension extends LensExtension { - onActivate() { - console.log('EXAMPLE EXTENSION: ACTIVATED', this.getMeta()); - this.registerPage({ - type: DynamicPageType.CLUSTER, - path: "/extension-example", - menuTitle: "Example Extension", - components: { - Page: () => , - MenuIcon: ExtensionIcon, - } - }) - } - - onDeactivate() { - console.log('EXAMPLE EXTENSION: DEACTIVATED', this.getMeta()); - } -} - -export function ExtensionIcon(props: IconProps) { - return -} - -export class ExtensionPage extends React.Component<{ extension: ExampleExtension }> { - deactivate = () => { - const { extension } = this.props; - extension.runtime.navigate("/") - extension.disable(); - } - - render() { - const { TabLayout } = this.props.extension.runtime.components; - const doodleStyle = { - width: "200px" - } - return ( - -
-
-

Hello from Example extension!

-

File: {__filename}

-
-
- ) - } -} diff --git a/extensions/example-extension/main.ts b/extensions/example-extension/main.ts new file mode 100644 index 0000000000..c193836341 --- /dev/null +++ b/extensions/example-extension/main.ts @@ -0,0 +1,11 @@ +import { LensExtension } from "@lens/extensions"; + +export default class ExampleExtensionMain extends LensExtension { + onActivate() { + console.log('EXAMPLE EXTENSION MAIN: ACTIVATED', this.getMeta()); + } + + onDeactivate() { + console.log('EXAMPLE EXTENSION MAIN: DEACTIVATED', this.getMeta()); + } +} diff --git a/extensions/example-extension/package.json b/extensions/example-extension/package.json index 18cafd26fa..795aace9d1 100644 --- a/extensions/example-extension/package.json +++ b/extensions/example-extension/package.json @@ -2,7 +2,8 @@ "name": "extension-example", "version": "1.0.0", "description": "Example extension", - "main": "dist/index.js", + "main": "dist/main.js", + "renderer": "dist/renderer.js", "lens": { "metadata": {}, "styles": [] diff --git a/extensions/example-extension/page.tsx b/extensions/example-extension/page.tsx new file mode 100644 index 0000000000..823888387a --- /dev/null +++ b/extensions/example-extension/page.tsx @@ -0,0 +1,32 @@ +import { Button, Icon, IconProps, LensRendererExtension, React } from "@lens/ui-extensions"; +import { CoffeeDoodle } from "react-open-doodles"; +import path from "path"; + +export function ExtensionIcon(props: IconProps) { + return +} + +export class ExtensionPage extends React.Component<{ extension: LensRendererExtension }> { + deactivate = () => { + const { extension } = this.props; + extension.disable(); + } + + render() { + const doodleStyle = { + width: "200px" + } + return ( +
+
+

Hello from Example extension!

+

File: {__filename}

+
+ ) + } +} + +export function examplePage(ext: LensRendererExtension) { + return () => +} diff --git a/extensions/example-extension/renderer.ts b/extensions/example-extension/renderer.ts new file mode 100644 index 0000000000..f52c896514 --- /dev/null +++ b/extensions/example-extension/renderer.ts @@ -0,0 +1,24 @@ +import { DynamicPageType, LensRendererExtension, PageStore } from "@lens/ui-extensions"; +import { examplePage, ExtensionIcon } from "./page" + +export default class ExampleExtension extends LensRendererExtension { + onActivate() { + console.log('EXAMPLE EXTENSION RENDERER: ACTIVATED', this.getMeta()); + } + + registerPages(pageStore: PageStore) { + this.registerPage(pageStore, { + type: DynamicPageType.CLUSTER, + path: "/extension-example", + menuTitle: "Example Extension", + components: { + Page: examplePage(this), + MenuIcon: ExtensionIcon, + } + }) + } + + onDeactivate() { + console.log('EXAMPLE EXTENSION RENDERER: DEACTIVATED', this.getMeta()); + } +} diff --git a/extensions/example-extension/tsconfig.json b/extensions/example-extension/tsconfig.json index 3ba216b67b..1eda85a2d5 100644 --- a/extensions/example-extension/tsconfig.json +++ b/extensions/example-extension/tsconfig.json @@ -16,7 +16,8 @@ }, "include": [ "../../types", - "./index.tsx" + "./index.ts", + "./main.ts" ], "exclude": [ "node_modules", diff --git a/package.json b/package.json index a4e44bab2b..f36fd31e83 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,12 @@ "dev-run": "nodemon --watch static/build/main.js --exec \"electron --inspect .\"", "dev:main": "yarn compile:main --watch", "dev:renderer": "yarn compile:renderer --watch", - "dev:extensions": "yarn compile:extensions --watch", + "dev:extension-api": "yarn compile:extension-api --watch", "compile": "env NODE_ENV=production concurrently yarn:compile:*", "compile:main": "webpack --config webpack.main.ts", "compile:renderer": "webpack --config webpack.renderer.ts", "compile:i18n": "lingui compile", - "compile:extensions": "rollup --config src/extensions/rollup.config.js", + "compile:extension-api": "rollup --config src/extensions/rollup.config.js", "build:linux": "yarn compile && electron-builder --linux --dir -c.productName=Lens", "build:mac": "yarn compile && electron-builder --mac --dir -c.productName=Lens", "build:win": "yarn compile && electron-builder --win --dir -c.productName=Lens", @@ -320,8 +320,8 @@ "progress-bar-webpack-plugin": "^2.1.0", "raw-loader": "^4.0.1", "react": "^16.13.1", - "react-dom": "^16.13.1", "react-beautiful-dnd": "^13.0.0", + "react-dom": "^16.13.1", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-select": "^3.1.0", diff --git a/src/common/vars.ts b/src/common/vars.ts index 0ee9e05eb4..1bbfd87548 100644 --- a/src/common/vars.ts +++ b/src/common/vars.ts @@ -24,6 +24,7 @@ export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss"); // Extensions export const extensionsLibName = `${appName}-extensions.api` +export const extensionsRendererLibName = `${appName}-extensions-renderer.api` export const extensionsDir = path.join(contextDir, "src/extensions"); // Special runtime paths @@ -39,8 +40,10 @@ defineGlobal("__static", { // Special dynamic module aliases if (isProduction && process.resourcesPath) { addAlias("@lens/extensions", path.join(process.resourcesPath, "static", `build/${extensionsLibName}.js`)) + addAlias("@lens/ui-extensions", path.join(process.resourcesPath, "static", `build/${extensionsRendererLibName}.js`)) } else { addAlias("@lens/extensions", path.join(contextDir, "static", `build/${extensionsLibName}.js`)) + addAlias("@lens/ui-extensions", path.join(contextDir, "static", `build/${extensionsRendererLibName}.js`)) } // Apis diff --git a/src/extensions/extension-api.ts b/src/extensions/extension-api.ts index 7f364898dd..250a271b30 100644 --- a/src/extensions/extension-api.ts +++ b/src/extensions/extension-api.ts @@ -1,14 +1,5 @@ // Lens-extensions api developer's kit -export type { LensRuntimeRendererEnv } from "./lens-runtime"; +export type { LensExtensionRuntimeEnv } from "./lens-runtime"; // APIs -export * from "./lens-extension" -export { DynamicPageType } from "./register-page"; - -// TODO: add more common re-usable UI components + refactor interfaces (Props -> ComponentProps) -export { default as React } from "react" -export * from "../renderer/components/icon" -export * from "../renderer/components/tooltip" -export * from "../renderer/components/button" -export * from "../renderer/components/tabs" -export * from "../renderer/components/badge" +export * from "./lens-main-extension" diff --git a/src/extensions/extension-loader.ts b/src/extensions/extension-loader.ts index d34ecd4eb6..83eda276b7 100644 --- a/src/extensions/extension-loader.ts +++ b/src/extensions/extension-loader.ts @@ -1,10 +1,12 @@ import type { ExtensionId, LensExtension, ExtensionManifest, ExtensionModel } from "./lens-extension" +import type { LensRendererExtension } from "./lens-renderer-extension" import { broadcastIpc } from "../common/ipc" -import type { LensRuntimeRendererEnv } from "./lens-runtime" +import type { LensExtensionRuntimeEnv } from "./lens-runtime" import path from "path" import { observable, reaction, toJS, } from "mobx" import logger from "../main/logger" import { app, remote, ipcRenderer } from "electron" +import { pageStore } from "./page-store"; export interface InstalledExtension extends ExtensionModel { manifestPath: string; @@ -42,8 +44,28 @@ export class ExtensionLoader { } } - autoEnableOnLoad(getLensRuntimeEnv: () => LensRuntimeRendererEnv, { delay = 0 } = {}) { - logger.info('[EXTENSIONS-LOADER]: auto-activation loaded extensions: ON'); + loadOnClusterRenderer(getLensRuntimeEnv: () => LensExtensionRuntimeEnv) { + logger.info('[EXTENSIONS-LOADER]: load on cluster renderer') + this.autoloadExtensions(getLensRuntimeEnv, (instance: LensRendererExtension) => { + instance.registerPages(pageStore) + }) + } + + loadOnMainRenderer(getLensRuntimeEnv: () => LensExtensionRuntimeEnv) { + logger.info('[EXTENSIONS-LOADER]: load on main renderer') + this.autoloadExtensions(getLensRuntimeEnv, (instance: LensRendererExtension) => { + instance.registerPages(pageStore) + }) + } + + loadOnMain(getLensRuntimeEnv: () => LensExtensionRuntimeEnv) { + logger.info('[EXTENSIONS-LOADER]: load on main') + this.autoloadExtensions(getLensRuntimeEnv, (instance: LensExtension) => { + // todo + }) + } + + protected autoloadExtensions(getLensRuntimeEnv: () => LensExtensionRuntimeEnv, callback: (instance: LensExtension) => void) { return reaction(() => this.extensions.toJS(), installedExtensions => { installedExtensions.forEach((ext) => { let instance = this.instances.get(ext.manifestPath) @@ -55,23 +77,32 @@ export class ExtensionLoader { } const LensExtensionClass = extensionModule.default; instance = new LensExtensionClass({ ...ext.manifest, manifestPath: ext.manifestPath, id: ext.manifestPath }, ext.manifest); - instance.enable(getLensRuntimeEnv()); + instance.enable(getLensRuntimeEnv()) + callback(instance) this.instances.set(ext.id, instance) } }) }, { fireImmediately: true, - delay: delay, + delay: 0, }) } protected requireExtension(extension: InstalledExtension) { + let extEntrypoint = "" return withExtensionPackagesRoot(() => { try { - const extMain = path.join(path.dirname(extension.manifestPath), extension.manifest.main) - return __non_webpack_require__(extMain) + if (ipcRenderer) { + extEntrypoint = path.join(path.dirname(extension.manifestPath), extension.manifest.renderer) + } else { + extEntrypoint = path.join(path.dirname(extension.manifestPath), extension.manifest.main) + } + if (extEntrypoint !== "") { + return __non_webpack_require__(extEntrypoint) + } } catch (err) { - console.error(`[EXTENSION-LOADER]: can't load extension main at ${extension.manifestPath}: ${err}`, { extension }); + console.trace(err) + console.error(`[EXTENSION-LOADER]: can't load extension main at ${extEntrypoint}: ${err}`, { extension }); } }) } @@ -84,7 +115,7 @@ export class ExtensionLoader { const extension = this.getById(id); if (extension) { const instance = this.instances.get(extension.id) - if (instance) { await instance.uninstall() } + if (instance) { await instance.disable() } this.extensions.delete(id); } } diff --git a/src/extensions/extension-renderer-api.ts b/src/extensions/extension-renderer-api.ts new file mode 100644 index 0000000000..33a7b6933e --- /dev/null +++ b/src/extensions/extension-renderer-api.ts @@ -0,0 +1,14 @@ +// Lens-extensions api developer's kit +export type { LensExtensionRuntimeEnv, PageStore } from "./lens-runtime"; + +// APIs +export * from "./lens-renderer-extension" +export { DynamicPageType } from "./page-store"; + +// TODO: add more common re-usable UI components + refactor interfaces (Props -> ComponentProps) +export { default as React } from "react" +export * from "../renderer/components/icon" +export * from "../renderer/components/tooltip" +export * from "../renderer/components/button" +export * from "../renderer/components/tabs" +export * from "../renderer/components/badge" diff --git a/src/extensions/lens-extension.ts b/src/extensions/lens-extension.ts index 9fc766f7a9..27cdaad83e 100644 --- a/src/extensions/lens-extension.ts +++ b/src/extensions/lens-extension.ts @@ -1,5 +1,4 @@ -import type { LensRuntimeRendererEnv } from "./lens-runtime"; -import type { PageRegistration } from "./register-page"; +import type { LensExtensionRuntimeEnv } from "./lens-runtime"; import { readJsonSync } from "fs-extra"; import { action, observable, toJS } from "mobx"; import logger from "../main/logger"; @@ -19,7 +18,8 @@ export interface ExtensionModel { } export interface ExtensionManifest extends ExtensionModel { - main: string; + main?: string; + renderer?: string; description?: string; // todo: add more fields similar to package.json + some extra } @@ -34,7 +34,7 @@ export class LensExtension implements ExtensionModel { @observable manifest: ExtensionManifest; @observable manifestPath: string; @observable isEnabled = false; - @observable.ref runtime: LensRuntimeRendererEnv; + @observable.ref runtime: LensExtensionRuntimeEnv; constructor(model: ExtensionModel, manifest: ExtensionManifest) { this.importModel(model, manifest); @@ -52,10 +52,14 @@ export class LensExtension implements ExtensionModel { } } - async enable(runtime: LensRuntimeRendererEnv) { + async migrate(appVersion: string) { + // mock + } + + async enable(runtime: LensExtensionRuntimeEnv) { this.isEnabled = true; this.runtime = runtime; - console.log(`[EXTENSION]: enabled ${this.name}@${this.version}`, this.getMeta()); + logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`, this.getMeta()); this.onActivate(); } @@ -65,7 +69,7 @@ export class LensExtension implements ExtensionModel { this.runtime = null; this.disposers.forEach(cleanUp => cleanUp()); this.disposers.length = 0; - console.log(`[EXTENSION]: disabled ${this.name}@${this.version}`, this.getMeta()); + logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`, this.getMeta()); } // todo: add more hooks @@ -77,27 +81,12 @@ export class LensExtension implements ExtensionModel { // mock } - // todo - async install(downloadUrl?: string) { - return; - } - - // todo - async uninstall() { - return; - } - - async hasNewVersion(): Promise> { - return; - } - getMeta() { return toJS({ id: this.id, manifest: this.manifest, manifestPath: this.manifestPath, - enabled: this.isEnabled, - runtime: this.runtime, + enabled: this.isEnabled }, { recurseEverything: true }) @@ -116,12 +105,4 @@ export class LensExtension implements ExtensionModel { recurseEverything: true, }) } - - // Runtime helpers - protected registerPage(params: PageRegistration, autoDisable = true) { - const dispose = this.runtime.dynamicPages.register(params); - if (autoDisable) { - this.disposers.push(dispose); - } - } } diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts new file mode 100644 index 0000000000..05a303ccad --- /dev/null +++ b/src/extensions/lens-main-extension.ts @@ -0,0 +1,11 @@ +import { LensExtension } from "./lens-extension" + +export class LensMainExtension extends LensExtension { + async registerAppMenus() { + // + } + + async registerPrometheusProviders(registry: any) { + // + } +} diff --git a/src/extensions/lens-renderer-extension.ts b/src/extensions/lens-renderer-extension.ts new file mode 100644 index 0000000000..4ca4620522 --- /dev/null +++ b/src/extensions/lens-renderer-extension.ts @@ -0,0 +1,16 @@ +import type { PageStore } from "./lens-runtime" +import type { PageRegistration } from "./page-store" +import { LensExtension } from "./lens-extension" + +export class LensRendererExtension extends LensExtension { + registerPages(pageStore: PageStore) { + // mock + } + + + // Runtime helpers + protected registerPage(pageStore: PageStore, params: PageRegistration) { + const dispose = pageStore.register(params); + this.disposers.push(dispose) + } +} diff --git a/src/extensions/lens-runtime.ts b/src/extensions/lens-runtime.ts index 1518dbc9de..a9a5f727de 100644 --- a/src/extensions/lens-runtime.ts +++ b/src/extensions/lens-runtime.ts @@ -1,26 +1,18 @@ -// Lens renderer runtime params available to extensions after activation +// Lens extension runtime params available to extensions after activation import logger from "../main/logger"; -import { dynamicPages } from "./register-page"; -import { TabLayout } from "../renderer/components/layout/tab-layout"; -import { navigate } from "../renderer/navigation"; +import { PageRegistration } from "./page-store"; -export interface LensRuntimeRendererEnv { - navigate: typeof navigate; - logger: typeof logger; - dynamicPages: typeof dynamicPages - components: { - TabLayout: typeof TabLayout - } +export interface PageStore { + register(params: PageRegistration): () => void } -export function getLensRuntime(): LensRuntimeRendererEnv { +export interface LensExtensionRuntimeEnv { + logger: typeof logger; +} + +export function getLensRuntime(): LensExtensionRuntimeEnv { return { logger, - navigate, - dynamicPages, - components: { - TabLayout // fixme: refactor, import as pure component from "@lens/extensions" - } } } diff --git a/src/extensions/register-page.tsx b/src/extensions/page-store.ts similarity index 93% rename from src/extensions/register-page.tsx rename to src/extensions/page-store.ts index 34317c1d93..78a9b767cf 100644 --- a/src/extensions/register-page.tsx +++ b/src/extensions/page-store.ts @@ -21,7 +21,7 @@ export interface PageComponents { MenuIcon: React.ComponentType; } -export class PagesStore { +export class PageStore { protected pages = observable.array([], { deep: false }); @computed get globalPages() { @@ -43,4 +43,4 @@ export class PagesStore { } } -export const dynamicPages = new PagesStore(); +export const pageStore = new PageStore(); diff --git a/src/extensions/rollup.config.ts b/src/extensions/rollup.config.ts index 8d802ef495..4c90d1e232 100644 --- a/src/extensions/rollup.config.ts +++ b/src/extensions/rollup.config.ts @@ -22,6 +22,19 @@ const config: RollupOptions = { ], }; +const rendererConfig: RollupOptions = { + input: "src/extensions/extension-renderer-api.ts", + output: [ + { file: "types/extension-renderer-api.d.ts", format: "es", } + ], + plugins: [ + dts(), + dtsModuleWrap({ name: "@lens/ui-extensions" }), + ignoreImport({ extensions: ['.scss'] }), + json(), + ], +}; + function dtsModuleWrap({ name }: { name: string }): Plugin { return { name, @@ -56,4 +69,4 @@ function dtsModuleWrap({ name }: { name: string }): Plugin { } } -export default config; \ No newline at end of file +export default [config, rendererConfig]; diff --git a/src/main/index.ts b/src/main/index.ts index 973aa27a8e..80a40ba3b5 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -19,6 +19,7 @@ import { workspaceStore } from "../common/workspace-store"; import { tracker } from "../common/tracker"; import { extensionManager } from "../extensions/extension-manager"; import { extensionLoader } from "../extensions/extension-loader"; +import { getLensRuntime } from "../extensions/lens-runtime"; import logger from "./logger" const workingDir = path.join(app.getPath("appData"), appName); @@ -78,6 +79,7 @@ async function main() { // create window manager and open app windowManager = new WindowManager(proxyPort); + extensionLoader.loadOnMain(getLensRuntime) extensionLoader.extensions.replace(await extensionManager.load()) } diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index 021aca3208..37fdc35e03 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -4,13 +4,11 @@ import { render, unmountComponentAtNode } from "react-dom"; import { isMac } from "../common/vars"; import { userStore } from "../common/user-store"; import { workspaceStore } from "../common/workspace-store"; -import { extensionLoader } from "../extensions/extension-loader"; import { clusterStore } from "../common/cluster-store"; import { i18nStore } from "./i18n"; import { themeStore } from "./theme.store"; import { App } from "./components/app"; import { LensApp } from "./lens-app"; -import { getLensRuntime } from "../extensions/lens-runtime"; type AppComponent = React.ComponentType & { init?(): void; @@ -31,7 +29,6 @@ export async function bootstrap(App: AppComponent) { // Register additional store listeners clusterStore.registerIpcListener(); - extensionLoader.autoEnableOnLoad(getLensRuntime); // init app's dependencies if any if (App.init) { diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 84be150cda..bd79258780 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -36,7 +36,9 @@ import { getHostedCluster, getHostedClusterId } from "../../common/cluster-store import logger from "../../main/logger"; import { clusterIpc } from "../../common/cluster-ipc"; import { webFrame } from "electron"; -import { dynamicPages } from "../../extensions/register-page"; +import { pageStore } from "../../extensions/page-store"; +import { extensionLoader } from "../../extensions/extension-loader"; +import { getLensRuntime } from "../../extensions/lens-runtime"; @observer export class App extends React.Component { @@ -47,6 +49,7 @@ export class App extends React.Component { await Terminal.preloadFonts() await clusterIpc.activate.invokeFromRenderer(clusterId, frameId); await getHostedCluster().whenReady; // cluster.refresh() is done at this point + extensionLoader.loadOnClusterRenderer(getLensRuntime) } get startURL() { @@ -74,7 +77,7 @@ export class App extends React.Component { - {dynamicPages.clusterPages.map(({ path, components: { Page } }) => { + {pageStore.clusterPages.map(({ path, components: { Page } }) => { return })} diff --git a/src/renderer/components/cluster-manager/cluster-manager.tsx b/src/renderer/components/cluster-manager/cluster-manager.tsx index cd3af5391c..4e68fa5623 100644 --- a/src/renderer/components/cluster-manager/cluster-manager.tsx +++ b/src/renderer/components/cluster-manager/cluster-manager.tsx @@ -14,7 +14,7 @@ import { ClusterSettings, clusterSettingsRoute } from "../+cluster-settings"; import { clusterViewRoute, clusterViewURL, getMatchedCluster, getMatchedClusterId } from "./cluster-view.route"; import { clusterStore } from "../../../common/cluster-store"; import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views"; -import { dynamicPages } from "../../../extensions/register-page"; +import { pageStore } from "../../../extensions/page-store"; @observer export class ClusterManager extends React.Component { @@ -63,7 +63,7 @@ export class ClusterManager extends React.Component { - {dynamicPages.globalPages.map(({ path, components: { Page } }) => { + {pageStore.globalPages.map(({ path, components: { Page } }) => { return })} diff --git a/src/renderer/lens-app.tsx b/src/renderer/lens-app.tsx index 9b4fffc6a1..c7af7d6cce 100644 --- a/src/renderer/lens-app.tsx +++ b/src/renderer/lens-app.tsx @@ -11,9 +11,15 @@ import { ErrorBoundary } from "./components/error-boundary"; import { WhatsNew, whatsNewRoute } from "./components/+whats-new"; import { Notifications } from "./components/notifications"; import { ConfirmDialog } from "./components/confirm-dialog"; +import { extensionLoader } from "../extensions/extension-loader"; +import { getLensRuntime } from "../extensions/lens-runtime"; @observer export class LensApp extends React.Component { + static async init() { + extensionLoader.loadOnMainRenderer(getLensRuntime) + } + render() { return ( diff --git a/webpack.renderer.ts b/webpack.renderer.ts index 37ed000384..3a949ddd20 100755 --- a/webpack.renderer.ts +++ b/webpack.renderer.ts @@ -1,4 +1,4 @@ -import { appName, buildDir, extensionsDir, extensionsLibName, htmlTemplate, isDevelopment, isProduction, publicPath, rendererDir, sassCommonVars } from "./src/common/vars"; +import { appName, buildDir, extensionsDir, extensionsLibName, extensionsRendererLibName, htmlTemplate, isDevelopment, isProduction, publicPath, rendererDir, sassCommonVars } from "./src/common/vars"; import path from "path"; import webpack from "webpack"; import HtmlWebpackPlugin from "html-webpack-plugin"; @@ -10,6 +10,7 @@ import ProgressBarPlugin from "progress-bar-webpack-plugin"; export default [ webpackLensRenderer, webpackExtensionsApi, + webpackExtensionsRendererApi ] // todo: use common chunks/externals for "react", "react-dom", etc. @@ -24,6 +25,17 @@ export function webpackExtensionsApi(): webpack.Configuration { return config; } +export function webpackExtensionsRendererApi(): webpack.Configuration { + const config = webpackLensRenderer({ showVars: false }); + config.name = "extensions-renderer-api" + config.entry = { + [extensionsRendererLibName]: path.resolve(extensionsDir, "extension-renderer-api.ts") + }; + config.output.libraryTarget = "commonjs2" + config.devtool = "nosources-source-map"; + return config; +} + export function webpackLensRenderer({ showVars = true } = {}): webpack.Configuration { if (showVars) { console.info('WEBPACK:renderer', require("./src/common/vars")); @@ -184,4 +196,4 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura }), ], } -} \ No newline at end of file +}