floating-live 0.17.0-alpha.8 → 0.17.0-beta.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/LICENSE +8 -8
- package/README.md +36 -36
- package/dist/FloatingLive.d.ts +0 -2
- package/dist/FloatingLive.js +0 -4
- package/dist/app.d.ts +2 -1
- package/dist/app.js +4 -1
- package/dist/command/manager.d.ts +5 -1
- package/dist/command/manager.js +44 -4
- package/dist/command/types.d.ts +17 -8
- package/dist/error/index.d.ts +7 -3
- package/dist/error/index.js +6 -2
- package/dist/event/types.d.ts +1 -0
- package/dist/hook/manager.d.ts +1 -1
- package/dist/hook/manager.js +11 -8
- package/dist/live/message.d.ts +35 -70
- package/dist/live/messageInfo.d.ts +10 -8
- package/dist/live/platform.d.ts +1 -1
- package/dist/live/room.d.ts +27 -9
- package/dist/live/room.js +23 -23
- package/dist/plugin/context/CommonPluginContext.d.ts +2 -1
- package/dist/plugin/context/CommonPluginContext.js +4 -0
- package/dist/plugin/context/SafePluginContext.js +3 -1
- package/dist/plugin/manager.d.ts +1 -1
- package/dist/plugin/manager.js +41 -30
- package/dist/plugin/types.d.ts +6 -3
- package/dist/plugins/platform/index.d.ts +14 -6
- package/dist/plugins/platform/index.js +22 -7
- package/dist/plugins/room/index.d.ts +49 -21
- package/dist/plugins/room/index.js +174 -60
- package/dist/value/manager.d.ts +1 -1
- package/dist/value/manager.js +27 -6
- package/package.json +1 -1
package/dist/live/room.d.ts
CHANGED
|
@@ -6,11 +6,11 @@ import { UserInfo } from "./messageInfo.js";
|
|
|
6
6
|
export declare abstract class LiveRoom extends CustomEventEmitter implements LiveRoomData {
|
|
7
7
|
constructor();
|
|
8
8
|
get valid(): true;
|
|
9
|
-
get
|
|
9
|
+
get pending(): false;
|
|
10
10
|
/** 平台 */
|
|
11
11
|
abstract readonly platform: string;
|
|
12
|
-
/**
|
|
13
|
-
readonly service: string;
|
|
12
|
+
/** 服务id */
|
|
13
|
+
abstract readonly service: string;
|
|
14
14
|
/** 房间id */
|
|
15
15
|
abstract readonly id: string | number;
|
|
16
16
|
/** 房间详情 */
|
|
@@ -60,11 +60,14 @@ export declare abstract class LiveRoom extends CustomEventEmitter implements Liv
|
|
|
60
60
|
/** 无效房间 */
|
|
61
61
|
export declare class InvalidLiveRoom implements LiveRoomData {
|
|
62
62
|
get valid(): false;
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
constructor(service: string, id: string | number, { pending, error }?: {
|
|
64
|
+
pending?: boolean | undefined;
|
|
65
|
+
error?: null | undefined;
|
|
66
|
+
});
|
|
65
67
|
readonly platform: string;
|
|
66
|
-
readonly id: string | number;
|
|
67
68
|
readonly service: string;
|
|
69
|
+
readonly id: string | number;
|
|
70
|
+
pending: boolean;
|
|
68
71
|
detail: LiveRoomDetailInfo;
|
|
69
72
|
stats?: LiveRoomStatsInfo;
|
|
70
73
|
anchor: UserInfo;
|
|
@@ -73,6 +76,10 @@ export declare class InvalidLiveRoom implements LiveRoomData {
|
|
|
73
76
|
connectionStatus: LiveConnectionStatus;
|
|
74
77
|
openStatus: LiveRoomOpenStatus;
|
|
75
78
|
liveId?: string;
|
|
79
|
+
error: {
|
|
80
|
+
code: string;
|
|
81
|
+
message: string;
|
|
82
|
+
} | null;
|
|
76
83
|
get opened(): boolean;
|
|
77
84
|
available: boolean;
|
|
78
85
|
/** 生成房间数据 */
|
|
@@ -90,14 +97,14 @@ export interface LiveRoom {
|
|
|
90
97
|
export interface LiveRoomData {
|
|
91
98
|
/** 房间有效性 */
|
|
92
99
|
valid: boolean;
|
|
100
|
+
/** 房间待定状态 */
|
|
101
|
+
pending?: boolean;
|
|
93
102
|
/** 平台id */
|
|
94
103
|
platform: string;
|
|
95
|
-
/**
|
|
104
|
+
/** 服务id */
|
|
96
105
|
service: string;
|
|
97
106
|
/** 房间id */
|
|
98
107
|
id: number | string;
|
|
99
|
-
/** API服务id */
|
|
100
|
-
serviceId: string;
|
|
101
108
|
/** 房间key */
|
|
102
109
|
key: string;
|
|
103
110
|
/** 基本信息 */
|
|
@@ -120,6 +127,11 @@ export interface LiveRoomData {
|
|
|
120
127
|
opened: boolean;
|
|
121
128
|
/** 房间是否可用 */
|
|
122
129
|
available: boolean;
|
|
130
|
+
/** 错误信息 */
|
|
131
|
+
error?: {
|
|
132
|
+
code: string;
|
|
133
|
+
message: string;
|
|
134
|
+
} | null;
|
|
123
135
|
}
|
|
124
136
|
/** 房间展示信息 */
|
|
125
137
|
export interface LiveRoomDetailInfo {
|
|
@@ -140,6 +152,10 @@ export interface LiveRoomStatsInfo {
|
|
|
140
152
|
online?: number;
|
|
141
153
|
/** 人气值 */
|
|
142
154
|
popularity?: number;
|
|
155
|
+
/** 粉丝数 */
|
|
156
|
+
fans?: number;
|
|
157
|
+
/** 粉丝团人数 */
|
|
158
|
+
clubFans?: number;
|
|
143
159
|
}
|
|
144
160
|
/** 直播间状态 */
|
|
145
161
|
export declare const LiveRoomStatus: {
|
|
@@ -179,6 +195,8 @@ export declare const LiveRoomOpenStatus: {
|
|
|
179
195
|
readonly opened: 2;
|
|
180
196
|
};
|
|
181
197
|
export type LiveRoomOpenStatus = EnumValue<typeof LiveRoomOpenStatus>;
|
|
198
|
+
export declare const LiveRoomValidStatus: {};
|
|
199
|
+
export type LiveRoomValidStatus = EnumValue<typeof LiveRoomValidStatus>;
|
|
182
200
|
export interface LiveRoomEventMap {
|
|
183
201
|
/** */
|
|
184
202
|
status: {
|
package/dist/live/room.js
CHANGED
|
@@ -7,11 +7,9 @@ export class LiveRoom extends CustomEventEmitter {
|
|
|
7
7
|
get valid() {
|
|
8
8
|
return true;
|
|
9
9
|
}
|
|
10
|
-
get
|
|
11
|
-
return
|
|
10
|
+
get pending() {
|
|
11
|
+
return false;
|
|
12
12
|
}
|
|
13
|
-
/** api服务 */
|
|
14
|
-
service = "";
|
|
15
13
|
/** 统计信息 */
|
|
16
14
|
stats;
|
|
17
15
|
/** 直播状态 */
|
|
@@ -48,24 +46,24 @@ export class LiveRoom extends CustomEventEmitter {
|
|
|
48
46
|
this.emit("status", {
|
|
49
47
|
status: LiveRoomStatus.live,
|
|
50
48
|
timestamp: msg.timestamp,
|
|
51
|
-
liveId: msg.
|
|
49
|
+
liveId: msg.data.id,
|
|
52
50
|
});
|
|
53
51
|
break;
|
|
54
52
|
case "live_detail":
|
|
55
|
-
this.detail = Object.assign(this.detail, msg.
|
|
56
|
-
this.emit("detail", { detail: msg.
|
|
53
|
+
this.detail = Object.assign(this.detail, msg.data);
|
|
54
|
+
this.emit("detail", { detail: msg.data });
|
|
57
55
|
break;
|
|
58
56
|
case "live_stats":
|
|
59
|
-
this.stats = Object.assign(this.stats, msg.
|
|
60
|
-
this.emit("stats", { stats: msg.
|
|
57
|
+
this.stats = Object.assign(this.stats, msg.data);
|
|
58
|
+
this.emit("stats", { stats: msg.data });
|
|
61
59
|
break;
|
|
62
60
|
case "live_end":
|
|
63
61
|
case "live_cut":
|
|
64
|
-
this.status = msg.status || LiveRoomStatus.off;
|
|
62
|
+
this.status = msg.data.status || LiveRoomStatus.off;
|
|
65
63
|
this.timestamp = msg.timestamp;
|
|
66
64
|
this.emit("message", { message: msg });
|
|
67
65
|
this.emit("status", {
|
|
68
|
-
status: msg.status || LiveRoomStatus.off,
|
|
66
|
+
status: msg.data.status || LiveRoomStatus.off,
|
|
69
67
|
timestamp: msg.timestamp,
|
|
70
68
|
liveId: this.liveId,
|
|
71
69
|
});
|
|
@@ -81,8 +79,8 @@ export class LiveRoom extends CustomEventEmitter {
|
|
|
81
79
|
toData() {
|
|
82
80
|
return {
|
|
83
81
|
valid: this.valid,
|
|
82
|
+
pending: this.pending,
|
|
84
83
|
platform: this.platform,
|
|
85
|
-
service: this.service,
|
|
86
84
|
id: this.id,
|
|
87
85
|
detail: this.detail,
|
|
88
86
|
stats: this.stats,
|
|
@@ -95,11 +93,11 @@ export class LiveRoom extends CustomEventEmitter {
|
|
|
95
93
|
available: this.available,
|
|
96
94
|
connectionStatus: this.connectionStatus,
|
|
97
95
|
key: this.key,
|
|
98
|
-
|
|
96
|
+
service: this.service,
|
|
99
97
|
};
|
|
100
98
|
}
|
|
101
99
|
get key() {
|
|
102
|
-
return `${this.
|
|
100
|
+
return `${this.service}:${this.id}`;
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
/** 无效房间 */
|
|
@@ -107,18 +105,18 @@ export class InvalidLiveRoom {
|
|
|
107
105
|
get valid() {
|
|
108
106
|
return false;
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
constructor(serviceId, id) {
|
|
114
|
-
const [platform, ...serviceIdArr] = serviceId.split(".");
|
|
108
|
+
constructor(service, id, { pending = false, error = null } = {}) {
|
|
109
|
+
const [platform] = service.split(".");
|
|
115
110
|
this.platform = platform;
|
|
116
111
|
this.id = id;
|
|
117
|
-
this.service =
|
|
112
|
+
this.service = service;
|
|
113
|
+
this.pending = pending;
|
|
114
|
+
this.error = error;
|
|
118
115
|
}
|
|
119
116
|
platform;
|
|
120
|
-
id;
|
|
121
117
|
service;
|
|
118
|
+
id;
|
|
119
|
+
pending;
|
|
122
120
|
detail = {};
|
|
123
121
|
stats;
|
|
124
122
|
anchor = { name: "", id: 0 };
|
|
@@ -127,6 +125,7 @@ export class InvalidLiveRoom {
|
|
|
127
125
|
connectionStatus = LiveConnectionStatus.off;
|
|
128
126
|
openStatus = 0;
|
|
129
127
|
liveId;
|
|
128
|
+
error;
|
|
130
129
|
get opened() {
|
|
131
130
|
return this.openStatus == 2;
|
|
132
131
|
}
|
|
@@ -135,6 +134,7 @@ export class InvalidLiveRoom {
|
|
|
135
134
|
toData() {
|
|
136
135
|
return {
|
|
137
136
|
valid: this.valid,
|
|
137
|
+
pending: this.pending,
|
|
138
138
|
platform: this.platform,
|
|
139
139
|
service: this.service,
|
|
140
140
|
id: this.id,
|
|
@@ -148,12 +148,11 @@ export class InvalidLiveRoom {
|
|
|
148
148
|
opened: this.opened,
|
|
149
149
|
available: this.available,
|
|
150
150
|
connectionStatus: this.connectionStatus,
|
|
151
|
-
serviceId: this.serviceId,
|
|
152
151
|
key: this.key,
|
|
153
152
|
};
|
|
154
153
|
}
|
|
155
154
|
get key() {
|
|
156
|
-
return `${this.
|
|
155
|
+
return `${this.service}:${this.id}`;
|
|
157
156
|
}
|
|
158
157
|
}
|
|
159
158
|
/** 直播间状态 */
|
|
@@ -191,3 +190,4 @@ export const LiveRoomOpenStatus = {
|
|
|
191
190
|
/** 已开启 */
|
|
192
191
|
opened: 2,
|
|
193
192
|
};
|
|
193
|
+
export const LiveRoomValidStatus = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { App } from "../../app.js";
|
|
2
|
-
import type { CommandOptions, CommandCallOptions, CommandFunction, AppCommandMap } from "../../command/index.js";
|
|
2
|
+
import type { CommandOptions, CommandCallOptions, CommandFunction, AppCommandMap, AppCommandAliasMap } from "../../command/index.js";
|
|
3
3
|
import { AppEventListener, AppEventEmitOptions, AppEventDetailMap } from "../../event/index.js";
|
|
4
4
|
import { HookUseOptions, HookCallOptions, AppHookMap, HookFunction, HookContext } from "../../hook/index.js";
|
|
5
5
|
import { AppValueMap, ValueContext, ValueOptions } from "../../value/index.js";
|
|
@@ -23,6 +23,7 @@ export declare class CommonPluginContext implements PluginContext {
|
|
|
23
23
|
registerValue<K extends keyof AppValueMap>(name: K, options: ValueOptions<AppValueMap[K]>): ValueContext<AppValueMap[K]>;
|
|
24
24
|
unregisterValue(name: string): void;
|
|
25
25
|
registerCommand<T extends keyof AppCommandMap>(name: T, func: CommandFunction<AppCommandMap[T]>, options?: CommandOptions): void;
|
|
26
|
+
registerCommandAlias<T extends keyof AppCommandAliasMap>(name: T, targetName: AppCommandAliasMap[T], options?: CommandOptions): void;
|
|
26
27
|
unregisterCommand(name: string): void;
|
|
27
28
|
hasCommand(name: string): boolean;
|
|
28
29
|
on<K extends keyof AppEventDetailMap>(type: K, listener: AppEventListener<AppEventDetailMap[K]>): void;
|
|
@@ -78,6 +78,10 @@ export class CommonPluginContext {
|
|
|
78
78
|
this.#app.registerCommand(name, func, options);
|
|
79
79
|
this.#registered.commands.add(name);
|
|
80
80
|
}
|
|
81
|
+
registerCommandAlias(name, targetName, options) {
|
|
82
|
+
this.#app.registerCommandAlias(name, targetName, options);
|
|
83
|
+
this.#registered.commands.add(name);
|
|
84
|
+
}
|
|
81
85
|
unregisterCommand(name) {
|
|
82
86
|
this.#app.unregisterCommand(name);
|
|
83
87
|
this.#registered.commands.delete(name);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { appError } from "../../error/index.js";
|
|
2
2
|
import { CommonPluginContext } from "./CommonPluginContext.js";
|
|
3
|
+
// 错误列表
|
|
4
|
+
// plugin:noPermission 插件权限不足
|
|
3
5
|
export class SafePluginContext extends CommonPluginContext {
|
|
4
6
|
get safe() {
|
|
5
7
|
return true;
|
|
@@ -10,7 +12,7 @@ export class SafePluginContext extends CommonPluginContext {
|
|
|
10
12
|
this.#permissions = options.permissions;
|
|
11
13
|
}
|
|
12
14
|
throwNotPermitted(permission, reason) {
|
|
13
|
-
throw appError("plugin:
|
|
15
|
+
throw appError("plugin:noPermission", {
|
|
14
16
|
message: "插件权限不足",
|
|
15
17
|
reason,
|
|
16
18
|
permission,
|
package/dist/plugin/manager.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare class PluginManager {
|
|
|
22
22
|
whenRegister(pluginName: string, callback: WhenRegisterCallback): void;
|
|
23
23
|
/** 取消插件已注册时的执行回调 */
|
|
24
24
|
cancelWhenRegister(pluginName: string, callback: WhenRegisterCallback): void;
|
|
25
|
-
|
|
25
|
+
getData(): {
|
|
26
26
|
pluginName: string;
|
|
27
27
|
}[];
|
|
28
28
|
}
|
package/dist/plugin/manager.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { CommonPluginContext } from "./context/CommonPluginContext.js";
|
|
2
2
|
import { bindCommand } from "../utils/index.js";
|
|
3
3
|
import { appError } from "../error/index.js";
|
|
4
|
+
// 错误列表
|
|
5
|
+
// plugin:missingName 插件pluginName字段缺失
|
|
6
|
+
// plugin:duplicateName 已存在相同名称的插件
|
|
7
|
+
// plugin:unremovable 插件不可移除
|
|
8
|
+
// plugin:registerFailed 插件注册失败
|
|
9
|
+
// plugin:notFound 插件不存在
|
|
10
|
+
// app:hookPrevented 被钩子函数阻止
|
|
4
11
|
export class PluginManager {
|
|
5
12
|
/** 插件列表 */
|
|
6
13
|
list = new Map();
|
|
@@ -8,23 +15,23 @@ export class PluginManager {
|
|
|
8
15
|
app;
|
|
9
16
|
constructor(app) {
|
|
10
17
|
this.app = app;
|
|
11
|
-
app.registerCommand("plugin.
|
|
18
|
+
app.registerCommand("plugin.getData", bindCommand(this.getData, this));
|
|
12
19
|
}
|
|
13
20
|
registerSync(pluginConstructor, options = {}, { context, unremovable = false, accessApp = false, pluginType = "", } = {}) {
|
|
14
21
|
const pluginName = pluginConstructor.pluginName;
|
|
15
22
|
const role = pluginConstructor.role || "";
|
|
16
23
|
if (!pluginName) {
|
|
17
|
-
throw appError("plugin:
|
|
18
|
-
message: "
|
|
19
|
-
reason: "插件缺少pluginName字段",
|
|
24
|
+
throw appError("plugin:missingName", {
|
|
25
|
+
message: "插件注册失败: 插件缺少pluginName字段",
|
|
20
26
|
target: "plugin/#unnamed",
|
|
27
|
+
action: "plugin.registerSync",
|
|
21
28
|
});
|
|
22
29
|
}
|
|
23
30
|
if (this.list.has(pluginName)) {
|
|
24
|
-
throw appError("plugin:
|
|
25
|
-
message:
|
|
26
|
-
reason: "已存在相同id的插件",
|
|
31
|
+
throw appError("plugin:duplicateName", {
|
|
32
|
+
message: `插件注册失败[${pluginName}]: 已存在相同名称的插件`,
|
|
27
33
|
target: `plugin/${pluginName}`,
|
|
34
|
+
action: "plugin.registerSync",
|
|
28
35
|
});
|
|
29
36
|
}
|
|
30
37
|
const registerCtx = { pluginName, options };
|
|
@@ -32,10 +39,10 @@ export class PluginManager {
|
|
|
32
39
|
try {
|
|
33
40
|
const ctx = this.app.callHookSync("plugin.register", registerCtx);
|
|
34
41
|
if (ctx.defaultPrevented)
|
|
35
|
-
throw appError("
|
|
36
|
-
message:
|
|
37
|
-
reason: "插件注册被钩子函数阻止",
|
|
42
|
+
throw appError("app:hookPrevented", {
|
|
43
|
+
message: `插件注册失败${pluginName}: 插件注册被钩子函数阻止`,
|
|
38
44
|
target: `plugin/${pluginName}`,
|
|
45
|
+
action: "plugin.registerSync",
|
|
39
46
|
});
|
|
40
47
|
// 执行插件函数
|
|
41
48
|
const plugin = new pluginConstructor(pluginCtx, registerCtx.options || {});
|
|
@@ -46,6 +53,7 @@ export class PluginManager {
|
|
|
46
53
|
// 将插件数据注册到列表中
|
|
47
54
|
this.list.set(pluginName, {
|
|
48
55
|
plugin,
|
|
56
|
+
role,
|
|
49
57
|
context: pluginCtx,
|
|
50
58
|
exposes,
|
|
51
59
|
unremovable: unremovable || false,
|
|
@@ -70,10 +78,11 @@ export class PluginManager {
|
|
|
70
78
|
return plugin;
|
|
71
79
|
}
|
|
72
80
|
catch (err) {
|
|
73
|
-
throw appError("plugin:
|
|
81
|
+
throw appError("plugin:registerFailed", {
|
|
74
82
|
message: `插件注册失败: ${pluginName}`,
|
|
75
83
|
reason: err,
|
|
76
84
|
target: `plugin/${pluginName}`,
|
|
85
|
+
action: "plugin.registerSync",
|
|
77
86
|
});
|
|
78
87
|
}
|
|
79
88
|
}
|
|
@@ -82,17 +91,17 @@ export class PluginManager {
|
|
|
82
91
|
const pluginName = pluginConstructor.pluginName;
|
|
83
92
|
const role = pluginConstructor.role || "";
|
|
84
93
|
if (!pluginName) {
|
|
85
|
-
throw appError("plugin:
|
|
86
|
-
message: "
|
|
87
|
-
reason: "插件缺少pluginName字段",
|
|
94
|
+
throw appError("plugin:missingName", {
|
|
95
|
+
message: "插件注册失败: 插件缺少pluginName字段",
|
|
88
96
|
target: "plugin/#unnamed",
|
|
97
|
+
action: "plugin.register",
|
|
89
98
|
});
|
|
90
99
|
}
|
|
91
100
|
if (this.list.has(pluginName)) {
|
|
92
|
-
throw appError("plugin:
|
|
93
|
-
message:
|
|
94
|
-
reason: "已存在相同id的插件",
|
|
101
|
+
throw appError("plugin:duplicateName", {
|
|
102
|
+
message: `插件注册失败[${pluginName}]: 已存在相同名称的插件`,
|
|
95
103
|
target: `plugin/${pluginName}`,
|
|
104
|
+
action: "plugin.register",
|
|
96
105
|
});
|
|
97
106
|
}
|
|
98
107
|
const registerCtx = { pluginName, options };
|
|
@@ -101,10 +110,10 @@ export class PluginManager {
|
|
|
101
110
|
.callHook("plugin.register", registerCtx)
|
|
102
111
|
.then(async (ctx) => {
|
|
103
112
|
if (ctx.defaultPrevented)
|
|
104
|
-
throw appError("
|
|
105
|
-
message:
|
|
106
|
-
reason: "插件注册被钩子函数阻止",
|
|
113
|
+
throw appError("app:hookPrevented", {
|
|
114
|
+
message: `插件注册失败${pluginName}: 插件注册被钩子函数阻止`,
|
|
107
115
|
target: `plugin/${pluginName}`,
|
|
116
|
+
action: "plugin.register",
|
|
108
117
|
});
|
|
109
118
|
// 执行插件函数
|
|
110
119
|
const plugin = new pluginConstructor(pluginCtx, registerCtx.options || {});
|
|
@@ -114,6 +123,7 @@ export class PluginManager {
|
|
|
114
123
|
const exposes = await plugin.expose?.(pluginCtx);
|
|
115
124
|
this.list.set(pluginName, {
|
|
116
125
|
plugin,
|
|
126
|
+
role,
|
|
117
127
|
context: pluginCtx,
|
|
118
128
|
exposes,
|
|
119
129
|
unremovable: unremovable,
|
|
@@ -138,10 +148,11 @@ export class PluginManager {
|
|
|
138
148
|
return plugin;
|
|
139
149
|
})
|
|
140
150
|
.catch((err) => {
|
|
141
|
-
throw appError("plugin:
|
|
151
|
+
throw appError("plugin:registerFailed", {
|
|
142
152
|
message: `插件注册失败: ${pluginName}`,
|
|
143
153
|
reason: err,
|
|
144
154
|
target: `plugin/${pluginName}`,
|
|
155
|
+
action: "plugin.register",
|
|
145
156
|
});
|
|
146
157
|
});
|
|
147
158
|
}
|
|
@@ -150,19 +161,19 @@ export class PluginManager {
|
|
|
150
161
|
const pluginData = this.list.get(pluginName);
|
|
151
162
|
// 检测插件是否存在
|
|
152
163
|
if (!pluginData) {
|
|
153
|
-
throw appError("plugin:
|
|
154
|
-
message:
|
|
155
|
-
reason: "插件不存在",
|
|
164
|
+
throw appError("plugin:notFound", {
|
|
165
|
+
message: `插件移除失败[${pluginName}]: 插件不存在`,
|
|
156
166
|
target: `plugin/${pluginName}`,
|
|
167
|
+
action: "plugin.unregister",
|
|
157
168
|
});
|
|
158
169
|
}
|
|
159
170
|
else {
|
|
160
|
-
const { plugin, context, unremovable } = pluginData;
|
|
171
|
+
const { plugin, context, unremovable, role } = pluginData;
|
|
161
172
|
if (unremovable) {
|
|
162
|
-
throw appError("plugin:
|
|
163
|
-
message:
|
|
164
|
-
reason: "不可移除的插件",
|
|
173
|
+
throw appError("plugin:unremovable", {
|
|
174
|
+
message: `插件移除失败[${pluginName}]: 该插件已配置为不可移除`,
|
|
165
175
|
target: `plugin/${pluginName}`,
|
|
176
|
+
action: "plugin.unregister",
|
|
166
177
|
});
|
|
167
178
|
}
|
|
168
179
|
// 调用插件和上下文的destroy钩子
|
|
@@ -171,7 +182,7 @@ export class PluginManager {
|
|
|
171
182
|
// 从列表中移除插件
|
|
172
183
|
this.list.delete(pluginName);
|
|
173
184
|
// 移除插件注册事件
|
|
174
|
-
this.app.emit("plugin:unregister", { pluginName });
|
|
185
|
+
this.app.emit("plugin:unregister", { pluginName, role });
|
|
175
186
|
// 如果有whenRegister的回调,调用whenUnregistered函数并将回调函数从列表中移除
|
|
176
187
|
const callbackMap = this.whenRegisterMap.get(pluginName);
|
|
177
188
|
if (callbackMap) {
|
|
@@ -229,7 +240,7 @@ export class PluginManager {
|
|
|
229
240
|
callbackMap.delete(callback);
|
|
230
241
|
}
|
|
231
242
|
}
|
|
232
|
-
|
|
243
|
+
getData() {
|
|
233
244
|
return [...this.list.keys()].map((n) => ({ pluginName: n }));
|
|
234
245
|
}
|
|
235
246
|
}
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { App } from "../app.js";
|
|
2
|
-
import { CommandOptions, CommandCallOptions, AppCommandMap, CommandFunction } from "../command/index.js";
|
|
2
|
+
import { CommandOptions, CommandCallOptions, AppCommandMap, CommandFunction, AppCommandAliasMap } from "../command/index.js";
|
|
3
3
|
import { AppEventListener, AppEventEmitOptions, AppEventDetailMap } from "../event/index.js";
|
|
4
4
|
import { AppHookMap, HookCallOptions, HookContext, HookFunction, HookUseOptions } from "../hook/index.js";
|
|
5
5
|
import { AppValueMap, ValueContext, ValueOptions } from "../value/index.js";
|
|
@@ -43,6 +43,7 @@ export interface PluginRegisterOptions {
|
|
|
43
43
|
}
|
|
44
44
|
export interface PluginData<T> {
|
|
45
45
|
plugin: PluginItem;
|
|
46
|
+
role: string;
|
|
46
47
|
context: PluginContext;
|
|
47
48
|
exposes?: T;
|
|
48
49
|
unremovable: boolean;
|
|
@@ -87,9 +88,11 @@ export interface PluginContext {
|
|
|
87
88
|
hasPlugin(pluginName: string): boolean;
|
|
88
89
|
/** 注册指令 */
|
|
89
90
|
registerCommand<T extends keyof AppCommandMap>(name: T, func: CommandFunction<AppCommandMap[T]>, options?: CommandOptions): void;
|
|
91
|
+
/** 注册指令别名,别名指令通常只作为手动输入指令的简写,不应在代码中直接使用 */
|
|
92
|
+
registerCommandAlias<T extends keyof AppCommandAliasMap>(name: T, targetName: AppCommandAliasMap[T], options?: CommandOptions): void;
|
|
90
93
|
/** 注销指令 */
|
|
91
94
|
unregisterCommand(name: string): void;
|
|
92
|
-
/**
|
|
95
|
+
/** 检测指令是否存在 */
|
|
93
96
|
hasCommand(name: string): boolean;
|
|
94
97
|
/** 调用指令 */
|
|
95
98
|
call<T extends keyof AppCommandMap>(name: T, ...args: Parameters<AppCommandMap[T]>): ReturnType<AppCommandMap[T]>;
|
|
@@ -123,7 +126,7 @@ export interface PluginContext {
|
|
|
123
126
|
export interface AppPluginExposesMap {
|
|
124
127
|
"": {};
|
|
125
128
|
}
|
|
126
|
-
export interface
|
|
129
|
+
export interface AppExchangeDataMap {
|
|
127
130
|
plugin: {
|
|
128
131
|
pluginName: string;
|
|
129
132
|
}[];
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BasePlugin, LivePlatformInfo } from "../../index.js";
|
|
1
|
+
import { BasePlugin, LivePlatformInfo, PluginContext } from "../../index.js";
|
|
2
2
|
interface PluginExposes {
|
|
3
3
|
register(name: string, info: LivePlatformInfo, signal: AbortSignal): void;
|
|
4
4
|
get(name: string): LivePlatformInfo | undefined;
|
|
5
|
-
|
|
5
|
+
info(name: string): LivePlatformInfo | undefined;
|
|
6
|
+
getData(): {
|
|
6
7
|
name: string;
|
|
7
8
|
}[];
|
|
8
9
|
}
|
|
@@ -19,13 +20,17 @@ declare module "../../index.js" {
|
|
|
19
20
|
name: string;
|
|
20
21
|
};
|
|
21
22
|
}
|
|
23
|
+
interface AppCommandAliasMap {
|
|
24
|
+
platform: "platform.info";
|
|
25
|
+
}
|
|
22
26
|
interface AppCommandMap {
|
|
23
|
-
"platform.
|
|
27
|
+
"platform.info": (name: string) => LivePlatformInfo | undefined;
|
|
28
|
+
"platform.getData": () => {
|
|
24
29
|
name: string;
|
|
25
30
|
info: LivePlatformInfo;
|
|
26
31
|
}[];
|
|
27
32
|
}
|
|
28
|
-
interface
|
|
33
|
+
interface AppExchangeDataMap {
|
|
29
34
|
platform: {
|
|
30
35
|
name: string;
|
|
31
36
|
info: LivePlatformInfo;
|
|
@@ -35,14 +40,17 @@ declare module "../../index.js" {
|
|
|
35
40
|
export declare class Platform extends BasePlugin {
|
|
36
41
|
static pluginName: string;
|
|
37
42
|
private list;
|
|
43
|
+
init(ctx: PluginContext): void;
|
|
38
44
|
/** 注册直播平台信息 */
|
|
39
45
|
register(name: string, info: LivePlatformInfo, signal?: AbortSignal): void;
|
|
40
46
|
/** 解除注册直播平台信息 */
|
|
41
47
|
unregister(name: string): void;
|
|
42
|
-
/**
|
|
48
|
+
/** 直接获取直播平台信息 */
|
|
43
49
|
get(name: string): LivePlatformInfo | undefined;
|
|
50
|
+
/** 获取直播平台信息 */
|
|
51
|
+
info(name: string): LivePlatformInfo | undefined;
|
|
44
52
|
expose(): PluginExposes;
|
|
45
|
-
|
|
53
|
+
getData(): {
|
|
46
54
|
name: string;
|
|
47
55
|
info: LivePlatformInfo;
|
|
48
56
|
}[];
|
|
@@ -1,44 +1,59 @@
|
|
|
1
|
+
import { bindCommand } from "../../utils/index.js";
|
|
1
2
|
import { appError, BasePlugin } from "../../index.js";
|
|
2
3
|
export class Platform extends BasePlugin {
|
|
3
4
|
static pluginName = "platform";
|
|
4
5
|
list = new Map();
|
|
6
|
+
init(ctx) {
|
|
7
|
+
ctx.registerCommand("platform.getData", this.getData.bind(this));
|
|
8
|
+
ctx.registerCommand("platform.info", bindCommand(this.info, this));
|
|
9
|
+
ctx.registerCommandAlias("platform", "platform.info");
|
|
10
|
+
}
|
|
5
11
|
/** 注册直播平台信息 */
|
|
6
12
|
register(name, info, signal) {
|
|
7
13
|
if (this.list.has(name)) {
|
|
8
|
-
throw appError("platform:
|
|
9
|
-
message: "
|
|
14
|
+
throw appError("platform:alreadyExists", {
|
|
15
|
+
message: "平台信息已存在",
|
|
16
|
+
target: `platform/${name}`,
|
|
17
|
+
action: "platform.register",
|
|
10
18
|
});
|
|
11
19
|
}
|
|
12
20
|
this.list.set(name, info);
|
|
13
21
|
if (signal) {
|
|
14
22
|
signal.addEventListener("abort", () => {
|
|
15
23
|
this.unregister(name);
|
|
16
|
-
}, { once: true });
|
|
24
|
+
}, { once: true, signal: this.ctx.signal });
|
|
17
25
|
}
|
|
18
26
|
}
|
|
19
27
|
/** 解除注册直播平台信息 */
|
|
20
28
|
unregister(name) {
|
|
21
29
|
if (!this.list.has(name)) {
|
|
22
|
-
throw appError("platform:
|
|
30
|
+
throw appError("platform:notFound", {
|
|
23
31
|
message: "无法解除不存在的平台信息注册",
|
|
32
|
+
target: `platform/${name}`,
|
|
33
|
+
action: "platform.unregister",
|
|
24
34
|
});
|
|
25
35
|
}
|
|
26
36
|
this.list.delete(name);
|
|
27
37
|
}
|
|
28
|
-
/**
|
|
38
|
+
/** 直接获取直播平台信息 */
|
|
29
39
|
get(name) {
|
|
30
40
|
return this.list.get(name);
|
|
31
41
|
}
|
|
42
|
+
/** 获取直播平台信息 */
|
|
43
|
+
info(name) {
|
|
44
|
+
return structuredClone(this.list.get(name));
|
|
45
|
+
}
|
|
32
46
|
expose() {
|
|
33
47
|
return {
|
|
34
48
|
register: (name, info, signal) => {
|
|
35
49
|
this.register(name, info, signal);
|
|
36
50
|
},
|
|
37
51
|
get: (name) => this.get(name),
|
|
38
|
-
|
|
52
|
+
info: (name) => this.info(name),
|
|
53
|
+
getData: () => this.getData(),
|
|
39
54
|
};
|
|
40
55
|
}
|
|
41
|
-
|
|
56
|
+
getData() {
|
|
42
57
|
return [...this.list].map(([name, info]) => ({ name, info }));
|
|
43
58
|
}
|
|
44
59
|
}
|