mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
extensions-api -- provide lens-runtime params on extension.enable
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
01d5989894
commit
eca3cadd80
@ -3,6 +3,9 @@
|
||||
"version": "1.0.0",
|
||||
"description": "Example extension",
|
||||
"main": "example-extension.ts",
|
||||
"lens": {
|
||||
"metadata": {}
|
||||
},
|
||||
"dependencies": {
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Lens-extensions api developer's kit
|
||||
export type { LensRendererRuntimeEnv } from "./extension-api.runtime";
|
||||
export type { LensRuntimeRendererEnv } from "./lens-runtime";
|
||||
|
||||
// APIs
|
||||
export * from "./extension"
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import type { LensRuntimeRendererEnv } from "./lens-runtime";
|
||||
import path from "path";
|
||||
import fs from "fs-extra";
|
||||
import { action, comparer, observable, toJS } from "mobx";
|
||||
import { action, observable, reaction, toJS } from "mobx";
|
||||
import { BaseStore } from "../common/base-store";
|
||||
import { ExtensionId, ExtensionManifest, ExtensionVersion, LensExtension } from "./extension";
|
||||
import { isDevelopment } from "../common/vars";
|
||||
import logger from "../main/logger";
|
||||
|
||||
export interface ExtensionStoreModel {
|
||||
version: ExtensionVersion;
|
||||
@ -11,7 +13,7 @@ export interface ExtensionStoreModel {
|
||||
}
|
||||
|
||||
export interface ExtensionModel {
|
||||
id: ExtensionId;
|
||||
id?: ExtensionId; // available in lens-extension instance
|
||||
version: ExtensionVersion;
|
||||
name: string;
|
||||
manifestPath: string;
|
||||
@ -39,7 +41,7 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
@observable version: ExtensionVersion = "0.0.0";
|
||||
@observable extensions = observable.map<ExtensionId, LensExtension>();
|
||||
@observable removed = observable.map<ExtensionId, LensExtension>();
|
||||
@observable installed = observable.map<string, InstalledExtension>([], { equals: comparer.shallow });
|
||||
@observable.shallow installed = observable.map<string, InstalledExtension>([]);
|
||||
|
||||
get folderPath(): string {
|
||||
if (isDevelopment) {
|
||||
@ -49,10 +51,28 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
}
|
||||
|
||||
async load() {
|
||||
await this.loadInstalledExtensions();
|
||||
await this.loadExtensions();
|
||||
return super.load();
|
||||
}
|
||||
|
||||
enableAutoInitOnLoad(getLensRuntimeEnv: () => LensRuntimeRendererEnv, { delay = 0 } = {}) {
|
||||
logger.info('[EXTENSIONS-STORE]: enabled: auto-init loaded extensions');
|
||||
return reaction(() => Array.from(this.installed.values()), installedExtensions => {
|
||||
installedExtensions.forEach(({ extensionModule, manifest, manifestPath }) => {
|
||||
let instance = this.getById(manifestPath);
|
||||
if (!instance) {
|
||||
const LensExtension = extensionModule.default;
|
||||
instance = new LensExtension({ ...manifest }, manifest);
|
||||
this.extensions.set(manifestPath, instance); // fixme: mobx error
|
||||
instance.enable(getLensRuntimeEnv());
|
||||
}
|
||||
})
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
delay: delay,
|
||||
})
|
||||
}
|
||||
|
||||
getExtensionByManifest(manifestPath: string): InstalledExtension {
|
||||
let manifestJson: ExtensionManifest;
|
||||
let mainJs: string;
|
||||
@ -72,21 +92,13 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
}
|
||||
|
||||
@action
|
||||
async loadInstalledExtensions() {
|
||||
const extensions = await this.loadExtensions(this.folderPath);
|
||||
this.installed.replace(extensions.map(ext => [ext.manifestPath, ext]));
|
||||
|
||||
// todo: remove
|
||||
if (process.isMainFrame) {
|
||||
extensions.forEach(({ extensionModule, manifest }) => {
|
||||
const LensExtension = extensionModule.default;
|
||||
const instance = new LensExtension({ ...manifest }, manifest);
|
||||
instance.activate();
|
||||
})
|
||||
}
|
||||
async loadExtensions() {
|
||||
const extensions = await this.loadFromFolder(this.folderPath);
|
||||
const extManifestMap = new Map(extensions.map(ext => [ext.manifestPath, ext]));
|
||||
this.installed.replace(extManifestMap);
|
||||
}
|
||||
|
||||
async loadExtensions(folderPath: string): Promise<InstalledExtension[]> {
|
||||
async loadFromFolder(folderPath: string): Promise<InstalledExtension[]> {
|
||||
const paths = await fs.readdir(folderPath);
|
||||
const manifestsLoading = paths.map(fileName => {
|
||||
const absPath = path.resolve(folderPath, fileName);
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import type { ExtensionModel } from "./extension-store";
|
||||
import type { LensRendererRuntimeEnv } from "./extension-api.runtime";
|
||||
import type { LensRuntimeRendererEnv } from "./lens-runtime";
|
||||
import { readJsonSync } from "fs-extra";
|
||||
import { action, observable } from "mobx";
|
||||
import extensionManifest from "./example-extension/package.json"
|
||||
import logger from "../main/logger";
|
||||
|
||||
export type ExtensionId = string;
|
||||
export type ExtensionId = string; // id or path to "%lens-extension/manifest.json"
|
||||
export type ExtensionVersion = string | number;
|
||||
export type ExtensionManifest = typeof extensionManifest & ExtensionModel;
|
||||
|
||||
@ -19,7 +19,7 @@ export class LensExtension implements ExtensionModel {
|
||||
@observable manifest: ExtensionManifest;
|
||||
@observable manifestPath: string;
|
||||
@observable isEnabled = false;
|
||||
@observable.ref runtime: LensRendererRuntimeEnv;
|
||||
@observable.ref runtime: Partial<LensRuntimeRendererEnv> = {};
|
||||
|
||||
constructor(model: ExtensionModel, manifest: ExtensionManifest) {
|
||||
this.importModel(model, manifest);
|
||||
@ -38,38 +38,30 @@ export class LensExtension implements ExtensionModel {
|
||||
}
|
||||
}
|
||||
|
||||
async activate() {
|
||||
logger.info(`[EXTENSION]: activate ${this.name}@${this.version}`, this.getMeta());
|
||||
}
|
||||
|
||||
async deactivate() {
|
||||
logger.info(`[EXTENSION]: deactivate ${this.name}@${this.version}`, this.getMeta());
|
||||
}
|
||||
|
||||
async enable() {
|
||||
logger.info(`[EXTENSION]: enable ${this.name}@${this.version}`, this.getMeta());
|
||||
async enable(runtime: LensRuntimeRendererEnv) {
|
||||
this.isEnabled = true;
|
||||
this.runtime = runtime;
|
||||
logger.info(`[EXTENSION]: enable ${this.name}@${this.version}`, this.getMeta());
|
||||
}
|
||||
|
||||
async disable() {
|
||||
logger.info(`[EXTENSION]: disable ${this.name}@${this.version}`, this.getMeta());
|
||||
this.isEnabled = false;
|
||||
this.runtime = {};
|
||||
logger.info(`[EXTENSION]: disable ${this.name}@${this.version}`, this.getMeta());
|
||||
}
|
||||
|
||||
async install() {
|
||||
// todo
|
||||
// todo
|
||||
async install(downloadUrl?: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo
|
||||
async uninstall() {
|
||||
// todo
|
||||
return;
|
||||
}
|
||||
|
||||
async upgrade() {
|
||||
// todo
|
||||
}
|
||||
|
||||
async checkNewVersion() {
|
||||
// todo
|
||||
async hasNewVersion(): Promise<Partial<ExtensionModel>> {
|
||||
return;
|
||||
}
|
||||
|
||||
getMeta() {
|
||||
@ -78,6 +70,7 @@ export class LensExtension implements ExtensionModel {
|
||||
manifest: this.manifest,
|
||||
manifestPath: this.manifestPath,
|
||||
enabled: this.isEnabled,
|
||||
runtime: Object.keys(this.runtime),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
// Lens runtime params provider to hook up into extensions
|
||||
// Lens runtime for injecting to extension on activation
|
||||
import { apiManager, ApiManager } from "../renderer/api/api-manager";
|
||||
|
||||
export interface LensRendererRuntimeEnv {
|
||||
export interface LensRuntimeRendererEnv {
|
||||
apiManager: ApiManager;
|
||||
}
|
||||
|
||||
// todo: expose more public runtime apis: stores, managers, etc.
|
||||
export function getExtensionRuntime(): LensRendererRuntimeEnv {
|
||||
export function getLensRuntime(): LensRuntimeRendererEnv {
|
||||
return {
|
||||
apiManager,
|
||||
}
|
||||
@ -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 { extensionStore } from "../extensions/extension-store";
|
||||
import { getLensRuntime } from "../extensions/lens-runtime";
|
||||
|
||||
@observer
|
||||
export class LensApp extends React.Component {
|
||||
componentDidMount() {
|
||||
extensionStore.enableAutoInitOnLoad(getLensRuntime);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<I18nProvider i18n={_i18n}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user