@zhin.js/core 1.0.25 → 1.0.27
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 +19 -0
- package/README.md +84 -342
- package/lib/adapter.d.ts +17 -0
- package/lib/adapter.d.ts.map +1 -1
- package/lib/adapter.js +84 -2
- package/lib/adapter.js.map +1 -1
- package/lib/ai/agent.d.ts +126 -0
- package/lib/ai/agent.d.ts.map +1 -0
- package/lib/ai/agent.js +645 -0
- package/lib/ai/agent.js.map +1 -0
- package/lib/ai/context-manager.d.ts +213 -0
- package/lib/ai/context-manager.d.ts.map +1 -0
- package/lib/ai/context-manager.js +313 -0
- package/lib/ai/context-manager.js.map +1 -0
- package/lib/ai/conversation-memory.d.ts +181 -0
- package/lib/ai/conversation-memory.d.ts.map +1 -0
- package/lib/ai/conversation-memory.js +581 -0
- package/lib/ai/conversation-memory.js.map +1 -0
- package/lib/ai/follow-up.d.ts +131 -0
- package/lib/ai/follow-up.d.ts.map +1 -0
- package/lib/ai/follow-up.js +265 -0
- package/lib/ai/follow-up.js.map +1 -0
- package/lib/ai/index.d.ts +29 -0
- package/lib/ai/index.d.ts.map +1 -0
- package/lib/ai/index.js +34 -0
- package/lib/ai/index.js.map +1 -0
- package/lib/ai/init.d.ts +30 -0
- package/lib/ai/init.d.ts.map +1 -0
- package/lib/ai/init.js +424 -0
- package/lib/ai/init.js.map +1 -0
- package/lib/ai/output.d.ts +93 -0
- package/lib/ai/output.d.ts.map +1 -0
- package/lib/ai/output.js +176 -0
- package/lib/ai/output.js.map +1 -0
- package/lib/ai/providers/anthropic.d.ts +23 -0
- package/lib/ai/providers/anthropic.d.ts.map +1 -0
- package/lib/ai/providers/anthropic.js +322 -0
- package/lib/ai/providers/anthropic.js.map +1 -0
- package/lib/ai/providers/base.d.ts +43 -0
- package/lib/ai/providers/base.d.ts.map +1 -0
- package/lib/ai/providers/base.js +135 -0
- package/lib/ai/providers/base.js.map +1 -0
- package/lib/ai/providers/index.d.ts +12 -0
- package/lib/ai/providers/index.d.ts.map +1 -0
- package/lib/ai/providers/index.js +9 -0
- package/lib/ai/providers/index.js.map +1 -0
- package/lib/ai/providers/ollama.d.ts +25 -0
- package/lib/ai/providers/ollama.d.ts.map +1 -0
- package/lib/ai/providers/ollama.js +243 -0
- package/lib/ai/providers/ollama.js.map +1 -0
- package/lib/ai/providers/openai.d.ts +46 -0
- package/lib/ai/providers/openai.d.ts.map +1 -0
- package/lib/ai/providers/openai.js +132 -0
- package/lib/ai/providers/openai.js.map +1 -0
- package/lib/ai/rate-limiter.d.ts +38 -0
- package/lib/ai/rate-limiter.d.ts.map +1 -0
- package/lib/ai/rate-limiter.js +86 -0
- package/lib/ai/rate-limiter.js.map +1 -0
- package/lib/ai/service.d.ts +81 -0
- package/lib/ai/service.d.ts.map +1 -0
- package/lib/ai/service.js +274 -0
- package/lib/ai/service.js.map +1 -0
- package/lib/ai/session.d.ts +186 -0
- package/lib/ai/session.d.ts.map +1 -0
- package/lib/ai/session.js +443 -0
- package/lib/ai/session.js.map +1 -0
- package/lib/ai/tone-detector.d.ts +19 -0
- package/lib/ai/tone-detector.d.ts.map +1 -0
- package/lib/ai/tone-detector.js +72 -0
- package/lib/ai/tone-detector.js.map +1 -0
- package/lib/ai/tools.d.ts +45 -0
- package/lib/ai/tools.d.ts.map +1 -0
- package/lib/ai/tools.js +206 -0
- package/lib/ai/tools.js.map +1 -0
- package/lib/ai/types.d.ts +264 -0
- package/lib/ai/types.d.ts.map +1 -0
- package/lib/ai/types.js +6 -0
- package/lib/ai/types.js.map +1 -0
- package/lib/ai/user-profile.d.ts +56 -0
- package/lib/ai/user-profile.d.ts.map +1 -0
- package/lib/ai/user-profile.js +130 -0
- package/lib/ai/user-profile.js.map +1 -0
- package/lib/ai/zhin-agent.d.ts +165 -0
- package/lib/ai/zhin-agent.d.ts.map +1 -0
- package/lib/ai/zhin-agent.js +707 -0
- package/lib/ai/zhin-agent.js.map +1 -0
- package/lib/built/ai-trigger.d.ts.map +1 -1
- package/lib/built/ai-trigger.js +7 -3
- package/lib/built/ai-trigger.js.map +1 -1
- package/lib/built/command.d.ts +33 -17
- package/lib/built/command.d.ts.map +1 -1
- package/lib/built/command.js +71 -44
- package/lib/built/command.js.map +1 -1
- package/lib/built/component.d.ts +42 -15
- package/lib/built/component.d.ts.map +1 -1
- package/lib/built/component.js +84 -52
- package/lib/built/component.js.map +1 -1
- package/lib/built/config.d.ts +64 -5
- package/lib/built/config.d.ts.map +1 -1
- package/lib/built/config.js +129 -12
- package/lib/built/config.js.map +1 -1
- package/lib/built/cron.d.ts +41 -18
- package/lib/built/cron.d.ts.map +1 -1
- package/lib/built/cron.js +106 -63
- package/lib/built/cron.js.map +1 -1
- package/lib/built/database.d.ts +55 -6
- package/lib/built/database.d.ts.map +1 -1
- package/lib/built/database.js +93 -22
- package/lib/built/database.js.map +1 -1
- package/lib/built/dispatcher.d.ts +118 -0
- package/lib/built/dispatcher.d.ts.map +1 -0
- package/lib/built/dispatcher.js +196 -0
- package/lib/built/dispatcher.js.map +1 -0
- package/lib/built/permission.d.ts +45 -5
- package/lib/built/permission.d.ts.map +1 -1
- package/lib/built/permission.js +56 -11
- package/lib/built/permission.js.map +1 -1
- package/lib/built/skill.d.ts +117 -0
- package/lib/built/skill.d.ts.map +1 -0
- package/lib/built/skill.js +191 -0
- package/lib/built/skill.js.map +1 -0
- package/lib/built/tool.d.ts +71 -164
- package/lib/built/tool.d.ts.map +1 -1
- package/lib/built/tool.js +212 -297
- package/lib/built/tool.js.map +1 -1
- package/lib/feature.d.ts +75 -0
- package/lib/feature.d.ts.map +1 -0
- package/lib/feature.js +69 -0
- package/lib/feature.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -1
- package/lib/plugin.d.ts +25 -17
- package/lib/plugin.d.ts.map +1 -1
- package/lib/plugin.js +180 -20
- package/lib/plugin.js.map +1 -1
- package/lib/types.d.ts +4 -9
- package/lib/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/adapter.ts +101 -2
- package/src/ai/agent.ts +772 -0
- package/src/ai/context-manager.ts +440 -0
- package/src/ai/conversation-memory.ts +774 -0
- package/src/ai/follow-up.ts +357 -0
- package/src/ai/index.ts +128 -0
- package/src/ai/init.ts +502 -0
- package/src/ai/output.ts +261 -0
- package/src/ai/providers/anthropic.ts +375 -0
- package/src/ai/providers/base.ts +173 -0
- package/src/ai/providers/index.ts +13 -0
- package/src/ai/providers/ollama.ts +292 -0
- package/src/ai/providers/openai.ts +167 -0
- package/src/ai/rate-limiter.ts +129 -0
- package/src/ai/service.ts +319 -0
- package/src/ai/session.ts +544 -0
- package/src/ai/tone-detector.ts +89 -0
- package/src/ai/tools.ts +218 -0
- package/src/ai/types.ts +296 -0
- package/src/ai/user-profile.ts +181 -0
- package/src/ai/zhin-agent.ts +845 -0
- package/src/built/ai-trigger.ts +6 -3
- package/src/built/command.ts +75 -69
- package/src/built/component.ts +94 -76
- package/src/built/config.ts +288 -128
- package/src/built/cron.ts +117 -101
- package/src/built/database.ts +128 -33
- package/src/built/dispatcher.ts +332 -0
- package/src/built/permission.ts +146 -54
- package/src/built/skill.ts +280 -0
- package/src/built/tool.ts +245 -366
- package/src/feature.ts +113 -0
- package/src/index.ts +7 -0
- package/src/plugin.ts +198 -33
- package/src/types.ts +6 -10
- package/tests/adapter.test.ts +153 -1
- package/tests/ai/agent.test.ts +614 -0
- package/tests/ai/ai-trigger.test.ts +368 -0
- package/tests/ai/context-manager.test.ts +413 -0
- package/tests/ai/conversation-memory.test.ts +128 -0
- package/tests/ai/follow-up.test.ts +175 -0
- package/tests/ai/integration.test.ts +584 -0
- package/tests/ai/output.test.ts +128 -0
- package/tests/ai/providers.integration.test.ts +227 -0
- package/tests/ai/rate-limiter.test.ts +108 -0
- package/tests/ai/session.test.ts +375 -0
- package/tests/ai/setup.ts +308 -0
- package/tests/ai/tone-detector.test.ts +80 -0
- package/tests/ai/tool.test.ts +800 -0
- package/tests/ai/tools-builtin.test.ts +346 -0
- package/tests/ai/user-profile.test.ts +73 -0
- package/tests/ai/zhin-agent.test.ts +177 -0
- package/tests/config.test.ts +46 -0
- package/tests/cron.test.ts +94 -5
- package/tests/dispatcher.test.ts +146 -0
- package/tests/feature.test.ts +145 -0
- package/tests/features-builtin.test.ts +191 -0
- package/tests/plugin.test.ts +88 -14
- package/tests/skill-feature.test.ts +179 -0
- package/tests/tool-feature.test.ts +254 -0
- package/test/minimal-bot.ts +0 -31
- package/test/stress-test.ts +0 -123
package/src/built/ai-trigger.ts
CHANGED
|
@@ -106,8 +106,9 @@ export const DEFAULT_AI_TRIGGER_CONFIG: Required<AITriggerConfig> = {
|
|
|
106
106
|
* 检查消息是否 @ 了机器人
|
|
107
107
|
*/
|
|
108
108
|
export function isAtBot<T extends object>(message: Message<T>): boolean {
|
|
109
|
+
const botId = String(message.$bot);
|
|
109
110
|
return message.$content.some(seg => {
|
|
110
|
-
return seg.data?.qq ===
|
|
111
|
+
return String(seg.data?.qq) === botId || String(seg.data?.user_id) === botId;
|
|
111
112
|
});
|
|
112
113
|
}
|
|
113
114
|
|
|
@@ -142,10 +143,12 @@ export function parseRichMediaContent(content: string): MessageElement[] {
|
|
|
142
143
|
* 移除 @ 机器人的部分
|
|
143
144
|
*/
|
|
144
145
|
export function removeAtBot<T extends object>(message: Message<T>): MessageElement[] {
|
|
146
|
+
const botId = String(message.$bot);
|
|
145
147
|
return message.$content.filter(seg => {
|
|
146
148
|
const { type, data } = seg;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
if (type !== "at") return true; // 非 at 段全部保留
|
|
150
|
+
const userId = String(data?.user_id || data?.qq);
|
|
151
|
+
return userId !== botId; // 只移除 @机器人 的段,保留 @其他人
|
|
149
152
|
});
|
|
150
153
|
}
|
|
151
154
|
|
package/src/built/command.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* CommandFeature
|
|
3
|
+
* 管理所有插件注册的命令,继承自 Feature 抽象类
|
|
4
4
|
*/
|
|
5
|
+
import { Feature, FeatureJSON } from "../feature.js";
|
|
5
6
|
import { MessageCommand } from "../command.js";
|
|
6
7
|
import { Message } from "../message.js";
|
|
7
|
-
import {
|
|
8
|
+
import { Plugin, getPlugin } from "../plugin.js";
|
|
8
9
|
import type { RegisteredAdapter, AdapterMessage } from "../types.js";
|
|
9
10
|
|
|
10
11
|
/**
|
|
@@ -20,83 +21,88 @@ declare module "../plugin.js" {
|
|
|
20
21
|
namespace Plugin {
|
|
21
22
|
interface Extensions extends CommandContextExtensions {}
|
|
22
23
|
interface Contexts {
|
|
23
|
-
command:
|
|
24
|
+
command: CommandFeature;
|
|
24
25
|
}
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
*
|
|
30
|
+
* 命令服务 Feature
|
|
30
31
|
*/
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
readonly
|
|
32
|
+
export class CommandFeature extends Feature<MessageCommand<RegisteredAdapter>> {
|
|
33
|
+
readonly name = 'command' as const;
|
|
34
|
+
readonly icon = 'Terminal';
|
|
35
|
+
readonly desc = '命令';
|
|
36
|
+
|
|
34
37
|
/** 按 pattern 索引 */
|
|
35
|
-
readonly byName
|
|
36
|
-
/** 添加命令 */
|
|
37
|
-
add(command: MessageCommand<RegisteredAdapter>, pluginName: string): () => void;
|
|
38
|
-
/** 移除命令 */
|
|
39
|
-
remove(command: MessageCommand<RegisteredAdapter>): boolean;
|
|
40
|
-
/** 按名称获取 */
|
|
41
|
-
get(pattern: string): MessageCommand<RegisteredAdapter> | undefined;
|
|
42
|
-
/** 处理消息 */
|
|
43
|
-
handle(message: Message<AdapterMessage<RegisteredAdapter>>, plugin: Plugin): Promise<any>;
|
|
44
|
-
}
|
|
38
|
+
readonly byName = new Map<string, MessageCommand<RegisteredAdapter>>();
|
|
45
39
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
get(pattern) {
|
|
77
|
-
return byName.get(pattern);
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
async handle(message, plugin) {
|
|
81
|
-
for (const command of items) {
|
|
82
|
-
const result = await command.handle(message, plugin);
|
|
83
|
-
if (result) return result;
|
|
84
|
-
}
|
|
85
|
-
return null;
|
|
40
|
+
/**
|
|
41
|
+
* 添加命令
|
|
42
|
+
*/
|
|
43
|
+
add(command: MessageCommand<RegisteredAdapter>, pluginName: string): () => void {
|
|
44
|
+
this.byName.set(command.pattern, command);
|
|
45
|
+
return super.add(command, pluginName);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 移除命令
|
|
50
|
+
*/
|
|
51
|
+
remove(command: MessageCommand<RegisteredAdapter>): boolean {
|
|
52
|
+
this.byName.delete(command.pattern);
|
|
53
|
+
return super.remove(command);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 按 pattern 获取命令
|
|
58
|
+
*/
|
|
59
|
+
get(pattern: string): MessageCommand<RegisteredAdapter> | undefined {
|
|
60
|
+
return this.byName.get(pattern);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 处理消息,依次尝试匹配命令
|
|
65
|
+
*/
|
|
66
|
+
async handle(message: Message<AdapterMessage<RegisteredAdapter>>, plugin: Plugin): Promise<any> {
|
|
67
|
+
for (const command of this.items) {
|
|
68
|
+
const result = await command.handle(message, plugin);
|
|
69
|
+
if (result) return result;
|
|
86
70
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 序列化为 JSON
|
|
76
|
+
*/
|
|
77
|
+
toJSON(pluginName?: string): FeatureJSON {
|
|
78
|
+
const list = pluginName ? this.getByPlugin(pluginName) : this.items;
|
|
79
|
+
return {
|
|
80
|
+
name: this.name,
|
|
81
|
+
icon: this.icon,
|
|
82
|
+
desc: this.desc,
|
|
83
|
+
count: list.length,
|
|
84
|
+
items: list.map(c => ({
|
|
85
|
+
name: c.pattern,
|
|
86
|
+
desc: c.helpInfo?.desc,
|
|
87
|
+
usage: c.helpInfo?.usage,
|
|
88
|
+
examples: c.helpInfo?.examples,
|
|
89
|
+
})),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 提供给 Plugin.prototype 的扩展方法
|
|
95
|
+
*/
|
|
96
|
+
get extensions() {
|
|
97
|
+
const feature = this;
|
|
98
|
+
return {
|
|
94
99
|
addCommand<T extends RegisteredAdapter>(command: MessageCommand<T>) {
|
|
95
100
|
const plugin = getPlugin();
|
|
96
|
-
const dispose =
|
|
101
|
+
const dispose = feature.add(command as MessageCommand<RegisteredAdapter>, plugin.name);
|
|
102
|
+
plugin.recordFeatureContribution(feature.name, command.pattern);
|
|
97
103
|
plugin.onDispose(dispose);
|
|
98
104
|
return dispose;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
102
108
|
}
|
package/src/built/component.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* ComponentFeature
|
|
3
|
+
* 管理所有插件注册的组件,继承自 Feature 抽象类
|
|
4
4
|
*/
|
|
5
|
+
import { Feature, FeatureJSON } from "../feature.js";
|
|
5
6
|
import { Component, renderComponents } from "../component.js";
|
|
6
7
|
import { SendOptions, MaybePromise } from "../types.js";
|
|
7
|
-
import {
|
|
8
|
+
import { Plugin, getPlugin } from "../plugin.js";
|
|
8
9
|
|
|
9
10
|
type Listener = (options: SendOptions) => MaybePromise<SendOptions>;
|
|
10
11
|
|
|
@@ -21,90 +22,107 @@ declare module "../plugin.js" {
|
|
|
21
22
|
namespace Plugin {
|
|
22
23
|
interface Extensions extends ComponentContextExtensions {}
|
|
23
24
|
interface Contexts {
|
|
24
|
-
component:
|
|
25
|
+
component: ComponentFeature;
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
|
-
*
|
|
31
|
+
* 组件服务 Feature
|
|
31
32
|
*/
|
|
32
|
-
export
|
|
33
|
+
export class ComponentFeature extends Feature<Component<any>> {
|
|
34
|
+
readonly name = 'component' as const;
|
|
35
|
+
readonly icon = 'Box';
|
|
36
|
+
readonly desc = '组件';
|
|
37
|
+
|
|
33
38
|
/** 按名称索引 */
|
|
34
|
-
readonly byName
|
|
35
|
-
/** 添加组件 */
|
|
36
|
-
add(component: Component<any>, pluginName: string): () => void;
|
|
37
|
-
/** 获取所有组件名称 */
|
|
38
|
-
getAllNames(): string[];
|
|
39
|
-
/** 移除组件 */
|
|
40
|
-
remove(component: Component<any>): boolean;
|
|
41
|
-
/** 按名称获取 */
|
|
42
|
-
get(name: string): Component<any> | undefined;
|
|
43
|
-
}
|
|
39
|
+
readonly byName = new Map<string, Component<any>>();
|
|
44
40
|
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
41
|
+
/** 内部状态:消息渲染监听器 & 宿主插件 */
|
|
42
|
+
#listener?: Listener;
|
|
43
|
+
#rootPlugin?: Plugin;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 添加组件
|
|
47
|
+
*/
|
|
48
|
+
add(component: Component<any>, pluginName: string): () => void {
|
|
49
|
+
this.byName.set(component.name, component);
|
|
50
|
+
return super.add(component, pluginName);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 移除组件
|
|
55
|
+
*/
|
|
56
|
+
remove(component: Component<any>): boolean {
|
|
57
|
+
this.byName.delete(component.name);
|
|
58
|
+
return super.remove(component);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 获取所有组件名称
|
|
63
|
+
*/
|
|
64
|
+
getAllNames(): string[] {
|
|
65
|
+
return Array.from(this.byName.keys());
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 按名称获取组件
|
|
70
|
+
*/
|
|
71
|
+
get(name: string): Component<any> | undefined {
|
|
72
|
+
return this.byName.get(name);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 生命周期: 挂载时注册消息渲染监听器
|
|
77
|
+
*/
|
|
78
|
+
mounted(plugin: Plugin): void {
|
|
79
|
+
this.#rootPlugin = plugin;
|
|
80
|
+
this.#listener = (options: SendOptions) => {
|
|
81
|
+
return renderComponents(this.byName, options);
|
|
82
|
+
};
|
|
83
|
+
plugin.root.on('before.sendMessage', this.#listener);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 生命周期: 销毁时移除监听器
|
|
88
|
+
*/
|
|
89
|
+
dispose(): void {
|
|
90
|
+
if (this.#listener && this.#rootPlugin) {
|
|
91
|
+
this.#rootPlugin.root.off('before.sendMessage', this.#listener);
|
|
92
|
+
this.#listener = undefined;
|
|
76
93
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 序列化为 JSON
|
|
98
|
+
*/
|
|
99
|
+
toJSON(pluginName?: string): FeatureJSON {
|
|
100
|
+
const list = pluginName ? this.getByPlugin(pluginName) : this.items;
|
|
101
|
+
return {
|
|
102
|
+
name: this.name,
|
|
103
|
+
icon: this.icon,
|
|
104
|
+
desc: this.desc,
|
|
105
|
+
count: list.length,
|
|
106
|
+
items: list.map(c => ({
|
|
107
|
+
name: c.name,
|
|
108
|
+
type: 'component',
|
|
109
|
+
})),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 提供给 Plugin.prototype 的扩展方法
|
|
115
|
+
*/
|
|
116
|
+
get extensions() {
|
|
117
|
+
const feature = this;
|
|
118
|
+
return {
|
|
101
119
|
addComponent<T extends Component<any>>(component: T) {
|
|
102
120
|
const plugin = getPlugin();
|
|
103
|
-
const dispose =
|
|
121
|
+
const dispose = feature.add(component, plugin.name);
|
|
122
|
+
plugin.recordFeatureContribution(feature.name, component.name);
|
|
104
123
|
plugin.onDispose(dispose);
|
|
105
124
|
return dispose;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
109
128
|
}
|
|
110
|
-
|