@bbki.ng/site 2.0.52 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/index.html +1 -1
- package/package.json +19 -17
- package/src/blog/app.tsx +0 -2
- package/src/blog/articles/index.ts +2 -2
- package/src/blog/articles/travel.mdx +1 -0
- package/src/blog/components/Img_ctx_menu/index.tsx +1 -1
- package/src/blog/components/app_ctx_menu/index.tsx +3 -15
- package/src/blog/components/article/index.tsx +4 -4
- package/src/blog/components/article_ctx_menu/index.tsx +1 -1
- package/src/blog/components/effect-layer/EffectLayer.tsx +1 -1
- package/src/blog/components/reaction/oh_reaction.tsx +1 -1
- package/src/blog/global/mdx.d.ts +1 -0
- package/src/blog/hooks/useTransitionCls.ts +1 -1
- package/src/blog/index.tsx +1 -1
- package/src/blog/main.css +40 -3
- package/src/blog/pages/extensions/txt/article.tsx +5 -1
- package/tailwind.config.cjs +1 -3
- package/vite.config.js +19 -12
- package/postcss.config.cjs +0 -6
- package/src/blog/components/plugin/PluginContentPage.tsx +0 -52
- package/src/blog/components/plugin/PluginDrawer.tsx +0 -39
- package/src/blog/components/plugin/PluginInit.tsx +0 -59
- package/src/blog/components/plugin/PluginInputForm.tsx +0 -117
- package/src/blog/components/plugin/PluginMenuItem.tsx +0 -70
- package/src/blog/components/plugin/PluginRoutes.tsx +0 -23
- package/src/blog/components/plugin/PluginsMenuItem.tsx +0 -70
- package/src/blog/components/plugin/hooks/useDependencies.ts +0 -80
- package/src/blog/components/plugin/hooks/usePluginOutput.tsx +0 -17
- package/src/blog/components/plugin/pluginUI/PluginUI.tsx +0 -34
- package/src/blog/demo/DemoBox.tsx +0 -15
- package/src/blog/demo/DemoMenu.tsx +0 -66
- package/src/blog/demo/ImgDemo.tsx +0 -34
- package/src/blog/demo/PluginDemo.ts +0 -24
- package/src/blog/demo/SpinnerDemo.tsx +0 -13
- package/src/blog/demo/Xwy.tsx +0 -13
- package/src/blog/plugin/Dependencies.ts +0 -14
- package/src/blog/plugin/HostFuncAdapter.ts +0 -28
- package/src/blog/plugin/Plugin.ts +0 -125
- package/src/blog/plugin/PluginEvent.ts +0 -50
- package/src/blog/plugin/PluginManager.ts +0 -166
- package/src/blog/plugin/PluginManagerPayload.ts +0 -3
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import createPlugin, { Plugin as EPlugin } from "@extism/extism";
|
|
2
|
-
import { Dependencies } from "@/plugin/Dependencies";
|
|
3
|
-
import { hostFuncAdapter } from "@/plugin/HostFuncAdapter";
|
|
4
|
-
|
|
5
|
-
export enum PluginStatus {
|
|
6
|
-
Available,
|
|
7
|
-
Installed,
|
|
8
|
-
Running,
|
|
9
|
-
Stopped,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type PluginConfig = {
|
|
13
|
-
name: string;
|
|
14
|
-
id: number;
|
|
15
|
-
version: string;
|
|
16
|
-
description: string;
|
|
17
|
-
url: string;
|
|
18
|
-
status: PluginStatus;
|
|
19
|
-
|
|
20
|
-
inputs?: PluginInput;
|
|
21
|
-
route?: string;
|
|
22
|
-
builtIn?: boolean;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export enum PluginInputFieldType {
|
|
26
|
-
String = "string",
|
|
27
|
-
Number = "number",
|
|
28
|
-
Boolean = "boolean",
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type PluginInputField = {
|
|
32
|
-
name: string;
|
|
33
|
-
type: PluginInputFieldType;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type PluginInput = PluginInputField[];
|
|
37
|
-
|
|
38
|
-
export class Plugin {
|
|
39
|
-
config: PluginConfig;
|
|
40
|
-
|
|
41
|
-
constructor(config: PluginConfig, dependencies: Dependencies) {
|
|
42
|
-
this.config = config;
|
|
43
|
-
this.dependencies = dependencies;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private plugin: EPlugin;
|
|
47
|
-
private dependencies: Dependencies;
|
|
48
|
-
|
|
49
|
-
async install() {
|
|
50
|
-
this.plugin = await createPlugin(this.config.url, {
|
|
51
|
-
useWasi: true,
|
|
52
|
-
runInWorker: true,
|
|
53
|
-
allowedHosts: ["*.bbki.ng", "api.bbki.ng"],
|
|
54
|
-
functions: hostFuncAdapter(this.dependencies),
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
if (this.config.route) {
|
|
58
|
-
this.dependencies.addRoute(this.config.route, this.config.route);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.config.status = PluginStatus.Installed;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private async getUserInput() {
|
|
65
|
-
if (!this.config.inputs || this.config.inputs.length === 0) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let userInput = "";
|
|
70
|
-
try {
|
|
71
|
-
userInput = await this.dependencies.showForm(this.config.inputs);
|
|
72
|
-
} catch (e) {
|
|
73
|
-
console.error(e);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return userInput;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async runWithParam(method: string, userInput?: string) {
|
|
80
|
-
this.config.status = PluginStatus.Running;
|
|
81
|
-
const target = method || this.config.name;
|
|
82
|
-
let out = await this.plugin.call(target, userInput);
|
|
83
|
-
try {
|
|
84
|
-
this.config.status = PluginStatus.Stopped;
|
|
85
|
-
return JSON.parse(out.text());
|
|
86
|
-
} catch (e) {
|
|
87
|
-
this.config.status = PluginStatus.Stopped;
|
|
88
|
-
this.dependencies.loading(false);
|
|
89
|
-
return out?.text();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async run(method?: string) {
|
|
94
|
-
if (this.config.status == PluginStatus.Running) {
|
|
95
|
-
console.log("Plugin is already running");
|
|
96
|
-
return "";
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this.config.status = PluginStatus.Running;
|
|
100
|
-
let userInput = await this.getUserInput();
|
|
101
|
-
if (!userInput && this.config.inputs && this.config.inputs.length > 0) {
|
|
102
|
-
console.log("userInput is empty");
|
|
103
|
-
this.config.status = PluginStatus.Stopped;
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const target = method || this.config.name;
|
|
108
|
-
try {
|
|
109
|
-
let out = await this.plugin.call(target, userInput);
|
|
110
|
-
this.config.status = PluginStatus.Stopped;
|
|
111
|
-
return out.text();
|
|
112
|
-
} catch (e) {
|
|
113
|
-
this.config.status = PluginStatus.Stopped;
|
|
114
|
-
this.dependencies.loading(false);
|
|
115
|
-
return e;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
async uninstall() {
|
|
120
|
-
this.config.status = PluginStatus.Available;
|
|
121
|
-
if (this.config.route) {
|
|
122
|
-
this.dependencies.removeRoute(this.config.route);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export enum PluginEvent {
|
|
2
|
-
INIT = "init",
|
|
3
|
-
INSTALL = "installed",
|
|
4
|
-
UNINSTALL = "uninstalled",
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
type EventHandler<T> = (data: T) => void;
|
|
8
|
-
|
|
9
|
-
type HandlerListenerPair = {
|
|
10
|
-
handler: EventHandler<any>;
|
|
11
|
-
listener: EventListener;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class PluginEventMgr {
|
|
15
|
-
private static listeners: Map<PluginEvent, HandlerListenerPair[]> = new Map();
|
|
16
|
-
|
|
17
|
-
public static dispatchEvent<T>(evt: PluginEvent, data: T) {
|
|
18
|
-
window.dispatchEvent(new CustomEvent(evt, { detail: data }));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public static addEventListener<T>(evt: PluginEvent, cb: (data: T) => void) {
|
|
22
|
-
const listener = (e: any) => {
|
|
23
|
-
cb((e as CustomEvent<T>).detail);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (!PluginEventMgr.listeners.has(evt)) {
|
|
27
|
-
PluginEventMgr.listeners.set(evt, []);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
PluginEventMgr.listeners.get(evt)?.push({ handler: cb, listener });
|
|
31
|
-
|
|
32
|
-
window.addEventListener(evt, listener);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public static removeEventListener<T>(evt: PluginEvent, cb: (data: T) => void) {
|
|
36
|
-
const listeners = PluginEventMgr.listeners.get(evt);
|
|
37
|
-
if (!listeners) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const targetPair = listeners.find((l) => l.handler === cb);
|
|
42
|
-
if (!targetPair) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
listeners.splice(listeners.indexOf(targetPair), 1);
|
|
47
|
-
|
|
48
|
-
window.removeEventListener(evt, targetPair.listener);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { Plugin, PluginConfig } from "./Plugin";
|
|
2
|
-
import { Dependencies } from "@/plugin/Dependencies";
|
|
3
|
-
import { PluginManagerPayload } from "@/plugin/PluginManagerPayload";
|
|
4
|
-
import { PluginEvent, PluginEventMgr } from "@/plugin/PluginEvent";
|
|
5
|
-
|
|
6
|
-
export class PluginManager {
|
|
7
|
-
private readonly dependencies: Dependencies;
|
|
8
|
-
|
|
9
|
-
constructor(dependencies: Dependencies) {
|
|
10
|
-
this.dependencies = dependencies;
|
|
11
|
-
this.loadInfo();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
private _info: PluginManagerPayload = {
|
|
15
|
-
installedIdList: [],
|
|
16
|
-
};
|
|
17
|
-
private static payloadKey = "pluginManagerPayload_v1.0";
|
|
18
|
-
|
|
19
|
-
private saveInfo() {
|
|
20
|
-
if (!this._info) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this._info.installedIdList = this.listInstalled().map((p) => p.config.id);
|
|
25
|
-
localStorage.setItem(PluginManager.payloadKey, JSON.stringify(this._info));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
private loadInfo() {
|
|
29
|
-
const info = localStorage.getItem(PluginManager.payloadKey);
|
|
30
|
-
if (info) {
|
|
31
|
-
this._info = JSON.parse(info);
|
|
32
|
-
console.log(this._info);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
private async restoreInstalledPlugins() {
|
|
37
|
-
await Promise.all(this.listBuiltIn().map((p) => this.install(p.id)));
|
|
38
|
-
|
|
39
|
-
if (!this._info) {
|
|
40
|
-
return Promise.resolve();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return Promise.all(
|
|
44
|
-
this._info.installedIdList.map((id) => this.install(id))
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
static instance: PluginManager;
|
|
49
|
-
|
|
50
|
-
static dispatchEvent<T>(evt: PluginEvent, data: T) {
|
|
51
|
-
PluginEventMgr.dispatchEvent(evt, data);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static addEventListener<T>(evt: PluginEvent, cb: (data: T) => void) {
|
|
55
|
-
PluginEventMgr.addEventListener(evt, cb);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static removeEventListener<T>(evt: PluginEvent, cb: (data: T) => void) {
|
|
59
|
-
PluginEventMgr.removeEventListener(evt, cb);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static async init(dependencies: Dependencies) {
|
|
63
|
-
if (PluginManager.instance) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
PluginManager.instance = new PluginManager(dependencies);
|
|
68
|
-
dependencies.loading(true);
|
|
69
|
-
const remotePlugins = await dependencies.fetchPlugins();
|
|
70
|
-
remotePlugins.forEach((p: PluginConfig) => PluginManager.instance.pluginConfigMap.set(p.id, p));
|
|
71
|
-
|
|
72
|
-
await PluginManager.instance.restoreInstalledPlugins();
|
|
73
|
-
dependencies.loading(false);
|
|
74
|
-
// dependencies.toast("Plugins initialized");
|
|
75
|
-
PluginManager.dispatchEvent<null>(PluginEvent.INIT, null);
|
|
76
|
-
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
// expose plugin manager to window for debugging
|
|
79
|
-
window.pm = PluginManager.instance;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
public async install(id: number, showToast?: boolean) {
|
|
83
|
-
const config = this.pluginConfigMap.get(id);
|
|
84
|
-
if (!config) {
|
|
85
|
-
this.dependencies.toast("Plugin not found");
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const plugin = new Plugin(config, this.dependencies);
|
|
90
|
-
await plugin.install();
|
|
91
|
-
this.plugins.set(id, plugin);
|
|
92
|
-
|
|
93
|
-
if (showToast) {
|
|
94
|
-
this.dependencies.toast("Plugin installed");
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// dispatch event
|
|
98
|
-
PluginManager.dispatchEvent<PluginConfig>(PluginEvent.INSTALL, config);
|
|
99
|
-
|
|
100
|
-
this.saveInfo();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
public async uninstall(plugin: PluginConfig) {
|
|
104
|
-
const id = plugin.id;
|
|
105
|
-
const installed = this.plugins.get(id);
|
|
106
|
-
if (!installed) {
|
|
107
|
-
this.dependencies.toast("Plugin not found");
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
await installed.uninstall();
|
|
112
|
-
this.plugins.delete(id);
|
|
113
|
-
this.dependencies.toast("Plugin uninstalled");
|
|
114
|
-
|
|
115
|
-
// dispatch event
|
|
116
|
-
PluginManager.dispatchEvent<PluginConfig>(PluginEvent.UNINSTALL, plugin);
|
|
117
|
-
|
|
118
|
-
this.saveInfo();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public listInstalled() {
|
|
122
|
-
return Array.from(this.plugins.values());
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
public listAvailable(): PluginConfig[] {
|
|
126
|
-
return Array.from(this.pluginConfigMap.values()).filter((p) => !p.builtIn);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
public listBuiltIn(): PluginConfig[] {
|
|
130
|
-
return Array.from(this.pluginConfigMap.values()).filter((p) => p.builtIn);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
public getPlugin(id: number) {
|
|
134
|
-
return this.plugins.get(id);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
public getPluginByRoute(route: string) {
|
|
138
|
-
return Array.from(this.plugins.values()).find(
|
|
139
|
-
(plugin) => plugin.config.route === route
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public async run(id: number, method?: string) {
|
|
144
|
-
const plugin = this.plugins.get(id);
|
|
145
|
-
if (!plugin) {
|
|
146
|
-
this.dependencies.toast("Plugin not found");
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return plugin.run(method);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
public async runWithParam(id: number, method: string, userInput: string) {
|
|
154
|
-
const plugin = this.plugins.get(id);
|
|
155
|
-
if (!plugin) {
|
|
156
|
-
this.dependencies.toast("Plugin not found");
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return plugin.runWithParam(method, userInput);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private pluginConfigMap: Map<number, PluginConfig> = new Map();
|
|
164
|
-
|
|
165
|
-
private plugins: Map<number, Plugin> = new Map();
|
|
166
|
-
}
|