mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
extensions-api -- loading extension modules -- part 1
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
1e08b01423
commit
b2414542b8
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,4 +9,5 @@ static/build/**
|
||||
binaries/client/
|
||||
binaries/server/
|
||||
src/extensions/**/*.js
|
||||
src/extensions/**/*.d.ts
|
||||
locales/**/**.js
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
"compile:main": "webpack --config webpack.main.ts",
|
||||
"compile:renderer": "webpack --config webpack.renderer.ts",
|
||||
"compile:i18n": "lingui compile",
|
||||
"compile-extensions": "tsc --project src/extensions --watch",
|
||||
"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",
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import { LensExtension } from "@lens"; // fixme: provide runtime import
|
||||
// import { LensExtension } from "@lens"; // fixme: provide runtime import
|
||||
|
||||
export default class ExampleExtension extends LensExtension {
|
||||
export default class ExampleExtension /*extends LensExtension*/ {
|
||||
async init(): Promise<any> {
|
||||
console.log('Example extension: init')
|
||||
return super.init();
|
||||
// return super.init();
|
||||
}
|
||||
}
|
||||
|
||||
export const someData = {
|
||||
title: "it works"
|
||||
}
|
||||
@ -4,7 +4,6 @@ import { action, comparer, observable, 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;
|
||||
@ -24,7 +23,10 @@ export interface ExtensionModel {
|
||||
export interface InstalledExtension<T extends ExtensionModel = any> {
|
||||
manifestPath: string;
|
||||
manifest: ExtensionManifest;
|
||||
LensExtension: new (model: T, manifest?: ExtensionManifest) => LensExtension;
|
||||
extensionModule: {
|
||||
[name: string]: any;
|
||||
default: new (model: T, manifest?: ExtensionManifest) => LensExtension
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
@ -56,15 +58,16 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
let mainJs: string;
|
||||
try {
|
||||
manifestJson = __non_webpack_require__(manifestPath); // eslint-disable-line
|
||||
mainJs = path.resolve(path.dirname(manifestPath), manifestJson.main); // todo: compile *.ts on the fly?
|
||||
const LensExtension = __non_webpack_require__(mainJs).default; // eslint-disable-line
|
||||
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
|
||||
return {
|
||||
manifestPath: manifestPath,
|
||||
manifest: manifestJson,
|
||||
LensExtension: LensExtension,
|
||||
extensionModule: extensionModule,
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`[EXTENSION-STORE]: can't load extension at ${manifestPath}: ${err}`, { manifestJson, mainJs });
|
||||
console.error(`[EXTENSION-STORE]: can't load extension at ${manifestPath}: ${err}`, { manifestJson, mainJs });
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +88,7 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
});
|
||||
let extensions = await Promise.all(manifestsLoading);
|
||||
extensions = extensions.filter(v => !!v); // filter out files and invalid folders (without manifest.json)
|
||||
logger.info(`[EXTENSION-STORE]: ${extensions.length} extensions loaded`, { folderPath, extensions });
|
||||
console.info(`[EXTENSION-STORE]: ${extensions.length} extensions loaded`, { folderPath, extensions });
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@ -116,16 +119,17 @@ export class ExtensionStore extends BaseStore<ExtensionStoreModel> {
|
||||
currentExtensions.forEach(model => {
|
||||
const manifest = this.installed.get(model.manifestPath);
|
||||
if (!manifest) {
|
||||
logger.error(`[EXTENSION-STORE]: can't load extension manifest at ${model.manifestPath}`, { model })
|
||||
console.error(`[EXTENSION-STORE]: can't load extension manifest at ${model.manifestPath}`, { model })
|
||||
return;
|
||||
}
|
||||
const extension = this.getById(model.id)
|
||||
if (!extension) {
|
||||
try {
|
||||
const { LensExtension, manifest: manifestJson } = manifest;
|
||||
const { manifest: manifestJson, extensionModule } = manifest;
|
||||
const LensExtension = extensionModule.default;
|
||||
this.extensions.set(model.id, new LensExtension(model, manifestJson));
|
||||
} catch (err) {
|
||||
logger.error(`[EXTENSION-STORE]: init extension failed: ${err}`, { model, manifest })
|
||||
console.error(`[EXTENSION-STORE]: init extension failed: ${err}`, { model, manifest })
|
||||
}
|
||||
} else {
|
||||
extension.importModel(model);
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import type { ExtensionModel } from "./extension-store";
|
||||
import { readJsonSync } from "fs-extra";
|
||||
import { action, observable, when } from "mobx";
|
||||
import { ExtensionModel } from "./extension-store";
|
||||
import extensionManifest from "./example-extension/package.json"
|
||||
import logger from "../main/logger";
|
||||
|
||||
// TODO: extensions api
|
||||
// * Lazy load/unload extension (js/ts?) (from sources: local folder, npm_modules/@lens/some_plugin, etc.)
|
||||
// * figure out how to expose lens external apis to extension:
|
||||
// - opt1: import {someApi} from "@lens" => replaced to import from "$PATH/build/Lens.js" on the fly ?
|
||||
// - opt2: dynamic require() / contents.executeJavaScript / etc. ?
|
||||
// - figure out how to expose/inject lens apis to extension:
|
||||
// -- replace import "@lens" to real path to "build/Lens.js" or maybe "build/Lens-extensions.api.js"
|
||||
// -- load extension via NodeJS.require() / webContents.executeJavaScript()
|
||||
|
||||
export type ExtensionId = string;
|
||||
export type ExtensionVersion = string | number;
|
||||
|
||||
20
src/extensions/tsconfig.json
Normal file
20
src/extensions/tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"target": "ES2017",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "Node",
|
||||
"noImplicitAny": true,
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true
|
||||
},
|
||||
"files": [
|
||||
"./example-extension/example-extension.ts"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user