From 76f8263baf0ab8942d34e5b053f609a9ef245a27 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 3 Sep 2020 23:31:14 +0300 Subject: [PATCH] extensions-api -- in-progress Signed-off-by: Roman --- .../example-extension/example-extension.ts | 17 +++++-- .../example-extension/tsconfig.json | 3 +- src/extensions/extension-api.mock.d.ts | 3 +- src/extensions/extension-api.runtime.ts | 13 +++++ src/extensions/extension-api.ts | 1 + src/extensions/extension-store.ts | 4 +- src/extensions/extension.ts | 50 ++++++++++++------- 7 files changed, 64 insertions(+), 27 deletions(-) create mode 100644 src/extensions/extension-api.runtime.ts diff --git a/src/extensions/example-extension/example-extension.ts b/src/extensions/example-extension/example-extension.ts index 0ca7c55df8..a522e26370 100644 --- a/src/extensions/example-extension/example-extension.ts +++ b/src/extensions/example-extension/example-extension.ts @@ -1,8 +1,17 @@ -import { LensExtension } from "@lens/extensions"; +import { LensExtension, LensRendererRuntimeEnv } from "@lens/extensions"; export default class ExampleExtension extends LensExtension { - async init(): Promise { - console.log('Example extension: init') - return super.init(); + todo(){ + console.log(this.runtime.apiManager); // fixme: incorrect types import, "runtime" doesn't exists + } + + async activate(runtime: LensRendererRuntimeEnv): Promise { + await super.activate(runtime); + console.log('Example extension: activate'); + } + + async deactivate(): Promise { + console.log('Example extension: deactivate') + await super.deactivate(); } } diff --git a/src/extensions/example-extension/tsconfig.json b/src/extensions/example-extension/tsconfig.json index 3a4583fc0c..b94897c696 100644 --- a/src/extensions/example-extension/tsconfig.json +++ b/src/extensions/example-extension/tsconfig.json @@ -12,8 +12,7 @@ "esModuleInterop": true, "allowSyntheticDefaultImports": true, "resolveJsonModule": true, - "skipLibCheck": true, - "declaration": true + "skipLibCheck": true }, "include": [ "../extension-api.mock.d.ts", diff --git a/src/extensions/extension-api.mock.d.ts b/src/extensions/extension-api.mock.d.ts index d641cb7f3f..394a536828 100644 --- a/src/extensions/extension-api.mock.d.ts +++ b/src/extensions/extension-api.mock.d.ts @@ -1,10 +1,9 @@ - declare module "@lens/extensions" { export = LensExtensions } declare namespace LensExtensions { export { - LensExtension, ExtensionManifest, ExtensionVersion, ExtensionId, + LensExtension, ExtensionManifest, ExtensionVersion, ExtensionId, LensRendererRuntimeEnv } from "./extension-api" } diff --git a/src/extensions/extension-api.runtime.ts b/src/extensions/extension-api.runtime.ts new file mode 100644 index 0000000000..933f6aafd5 --- /dev/null +++ b/src/extensions/extension-api.runtime.ts @@ -0,0 +1,13 @@ +// Lens runtime params provider to hook up into extensions +import { apiManager, ApiManager } from "../renderer/api/api-manager"; + +export interface LensRendererRuntimeEnv { + apiManager: ApiManager; +} + +// todo: expose more renderer runtime variables, stores, etc. +export function getExtensionRuntime(): LensRendererRuntimeEnv { + return { + apiManager, + } +} diff --git a/src/extensions/extension-api.ts b/src/extensions/extension-api.ts index 491cf6919a..054c7443ae 100644 --- a/src/extensions/extension-api.ts +++ b/src/extensions/extension-api.ts @@ -1,4 +1,5 @@ // Lens-extensions.api.js developer kit // todo: generate types instead of extension-api.mock.d.ts +export { LensRendererRuntimeEnv } from "./extension-api.runtime"; export * from "./extension" diff --git a/src/extensions/extension-store.ts b/src/extensions/extension-store.ts index 95d8932783..81eea358ee 100644 --- a/src/extensions/extension-store.ts +++ b/src/extensions/extension-store.ts @@ -57,10 +57,10 @@ export class ExtensionStore extends BaseStore { let manifestJson: ExtensionManifest; let mainJs: string; try { - manifestJson = __non_webpack_require__(manifestPath); // eslint-disable-line + manifestJson = __non_webpack_require__(manifestPath); // "__non_webpack_require__" converts to native node's require()-call mainJs = path.resolve(path.dirname(manifestPath), manifestJson.main); mainJs = mainJs.replace(/\.ts$/i, ".js"); // todo: compile *.ts on the fly? - const extensionModule = __non_webpack_require__(mainJs); // eslint-disable-line + const extensionModule = __non_webpack_require__(mainJs); return { manifestPath: manifestPath, manifest: manifestJson, diff --git a/src/extensions/extension.ts b/src/extensions/extension.ts index bd4d653138..82ae3a5550 100644 --- a/src/extensions/extension.ts +++ b/src/extensions/extension.ts @@ -1,6 +1,7 @@ import type { ExtensionModel } from "./extension-store"; import { readJsonSync } from "fs-extra"; -import { action, observable, when } from "mobx"; +import { action, observable } from "mobx"; +import { LensRendererRuntimeEnv } from "./extension-api.runtime"; import extensionManifest from "./example-extension/package.json" import logger from "../main/logger"; @@ -17,12 +18,10 @@ export class LensExtension implements ExtensionModel { @observable version: ExtensionVersion = "0.0.0"; @observable manifest: ExtensionManifest; @observable manifestPath: string; - @observable isReady = false; @observable isEnabled = false; + @observable.ref runtime: LensRendererRuntimeEnv; - whenReady = when(() => this.isReady); - - constructor(model: ExtensionModel, manifest?: ExtensionManifest) { + constructor(model: ExtensionModel, manifest: ExtensionManifest) { this.importModel(model, manifest); } @@ -33,16 +32,30 @@ export class LensExtension implements ExtensionModel { this.manifestPath = manifestPath; this.isEnabled = enabled; Object.assign(this, model); - this.isReady = true; } catch (err) { logger.error(`[EXTENSION]: cannot read manifest at ${manifestPath}`, { ...model, err: String(err) }) this.disable(); } } - async init() { - // todo: add more app/extension lifecycle hooks? e.g. onAppExit(), etc. - // todo: provide runtime dependencies + async activate(params: LensRendererRuntimeEnv) { + logger.info(`[EXTENSION]: activate ${this.name}@${this.version}`, this.getMeta()); + this.runtime = params; + } + + async deactivate() { + logger.info(`[EXTENSION]: deactivate ${this.name}@${this.version}`, this.getMeta()); + this.runtime = null; + } + + async enable() { + logger.info(`[EXTENSION]: enable ${this.name}@${this.version}`, this.getMeta()); + this.isEnabled = true; + } + + async disable() { + logger.info(`[EXTENSION]: disable ${this.name}@${this.version}`, this.getMeta()); + this.isEnabled = false; } async install() { @@ -53,18 +66,21 @@ export class LensExtension implements ExtensionModel { // todo } + async upgrade() { + // todo + } + async checkNewVersion() { // todo } - async enable() { - this.isEnabled = true; - // todo - } - - async disable() { - this.isEnabled = false; - // todo + getMeta() { + return { + id: this.id, + manifest: this.manifest, + manifestPath: this.manifestPath, + enabled: this.isEnabled, + } } toJSON(): ExtensionModel {