Skip to content

Commit

Permalink
feat(zhi-core): support loading zhi internal plugins
Browse files Browse the repository at this point in the history
zhi will load internal plugins via plugin system

feat #178
  • Loading branch information
terwer committed Apr 18, 2023
1 parent 1afec99 commit 202a050
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 19 deletions.
80 changes: 80 additions & 0 deletions apps/zhi-core/public/core/plugin-system/zhi-plugin-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/
/* eslint-disable */

/**
* StorageManager: 'StorageManager',
* PluginSystem: 'PluginSystem',
* SystemManager: 'PluginSystemLocalManager',
* PluginLoader: 'PluginLoader',
* PluginFileManager: 'PluginFileManager',
* EventBus: 'EventBus',
* Shortcut: 'Shortcut',
* CommandManager: 'CommandManager',
* Store: 'Store',
* SettingManager: 'SettingManager',
*/

const zhiPluginBase = "/appearance/themes/zhi/plugin"
const log = window.zhiLog.info

async function init() {
const container = window.pluginSystemIocContainer
const pluginSystem = container.get("PluginSystem")
log("Check plugin system version", container)
log("pluginSystem=>", pluginSystem)

const zhiInternalPlugins = await getZhiInternalPlugins()
log("zhiInternalPlugins=>", zhiInternalPlugins)
}

async function getZhiInternalPlugins() {
const container = window.pluginSystemIocContainer
const pluginFileManager = container.get("PluginFileManager")
log("pluginFileManager=>", pluginFileManager)

const plugins = await pluginFileManager.scanPlugins(zhiPluginBase)
if (!plugins || !plugins.length) {
log("No plugin found in " + zhiPluginBase)
return []
}
const req = []
for (const p of plugins) {
log("Reading plugin from filesystem: " + p)
const key = this.getFolderName(p)
const f = async () => {
const [manifest, script] = await Promise.all([
pluginFileManager.getManifest(`${p}/manifest.json`),
this.getScript(`${p}/main.js`),
])
return { ...manifest, script, enabled: false, key }
}
req.push(f())
}
const result = await Promise.all(req)
return result || []
}

export { init as default, init }
10 changes: 9 additions & 1 deletion apps/zhi-core/public/zhi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
{
"libpath": "core/plugin-system/plugin.js",
"baseType": "ZhiTheme",
"format": "cjs",
"format": "esm",
"importType": "import",
"runAs": ["Siyuan_MainWindow", "Siyuan_Browser"],
"order": 1
},
{
"libpath": "core/plugin-system/zhi-plugin-loader.js",
"baseType": "ZhiTheme",
"format": "esm",
"importType": "import",
"runAs": ["Siyuan_MainWindow", "Siyuan_Browser"],
"order": 2
}
],
"server": [],
Expand Down
17 changes: 1 addition & 16 deletions apps/zhi-core/src/theme/core/lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import DependencyItem from "../models/DependencyItem"
import { SiyuanDevice } from "zhi-device-detection"
import ZhiCoreUtil from "./util/ZhiCoreUtil"
import logger from "zhi-log/lib/lib/logger"

/**
* zhi主题统一生命周期管理
Expand All @@ -52,11 +51,10 @@ class Lifecycle {
*
* ```
* 加载顺序如下:
* 1 核心模块-require-hacker、infra、browser-window、插件系统
* 1 核心模块-require-hacker、infra、browser-window、插件系统、内部插件
* 2 后端模块
* 3 前端模块
* 4 第三方库
* 5 插件
* ```
*/
public async load() {
Expand Down Expand Up @@ -93,9 +91,6 @@ class Lifecycle {
// 第三方组件
const vendors = zhiJson.dependencies.vendor
const vendorImports = await this.loadVendors(vendors)
// 插件-比较特殊,暂时不由核心加载,重新写加载逻辑
const plugins = zhiJson.dependencies.plugin
await this.loadPlugins(plugins)

return allImports.concat(coreModuleImports).concat(backendImports).concat(frontendImports).concat(vendorImports)
}
Expand Down Expand Up @@ -163,16 +158,6 @@ class Lifecycle {
this.logger.info(`Registered ${vendorImports.length} Vendors`)
return vendorImports
}

/**
* 加载插件 - 暂定由插件系统负责,如果顺序有问题,可由 zhi 接管
* @private
*/
private async loadPlugins(deps: object[]): Promise<void> {
this.logger.info("Loading plugins from zhi theme...")
// TODO
this.logger.info(`Loaded ${deps.length} Plugins`)
}
}

export default Lifecycle
12 changes: 10 additions & 2 deletions apps/zhi-core/src/theme/zhi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import ZhiCoreUtil from "./core/util/ZhiCoreUtil"
import DependencyItem from "./models/DependencyItem"
import Bootstrap from "./core/Bootstrap"
import { crossChalk } from "zhi-log"
import ZhiUtil from "./core/util/ZhiCoreUtil"

/**
* 主题通用类(由theme.js动态调用,除了单元测试之外请勿主动调用)
Expand Down Expand Up @@ -87,6 +88,12 @@ class Zhi {
return
}

// 挂载一个日志对象,方便后续动态使用
if (typeof window !== "undefined") {
;(window as any).zhiLog = ZhiUtil.zhiLog("zhi-core")
this.logger.info("ZhiLog mounted", (window as any).zhiLog)
}

// 初始化第三方依赖
// import
// browser esm path: "/[libpath]"
Expand Down Expand Up @@ -129,19 +136,20 @@ class Zhi {
this.logger.debug(`Current ${item.importType} lib ${item.libpath} Obj=>`, typeof libObj)
if (typeof libObj == "function") {
await libObj()
this.logger.info(`Init ${item.libpath} with default function`)
this.logger.info(`Inited ${item.libpath} with default function`)
} else {
if (libObj.init) {
const res = await libObj.init()
if (res) {
this.logger.info(`Detected output from ${item.importType} lib ${item.libpath}=>`, res)
}
this.logger.info(`Inited ${item.libpath} with init function`)
} else {
this.logger.debug(`No init method for ${item.importType} ${item.libpath}`)
}
}
} else {
this.logger.debug(`Lib entry is not a function => ${item.importType} ${item.libpath}`)
this.logger.debug(`Lib entry is not a function => ${item.importType} ${item.libpath}`, lib)
}
this.logger.info(`Success ${item.importType} ${item.libpath}`)
}
Expand Down

0 comments on commit 202a050

Please sign in to comment.