@havue/solutions 1.1.1 → 1.2.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.
Files changed (28) hide show
  1. package/bc-connect/__tests__/bc-connect.spec.ts +73 -0
  2. package/bc-connect/dist/bc-connect.mjs +89 -73
  3. package/bc-connect/dist/bc-connect.umd.js +89 -73
  4. package/bc-connect/dist/types/src/manager.d.ts +72 -62
  5. package/bc-connect/package.json +1 -1
  6. package/bc-connect/src/manager.ts +103 -78
  7. package/dist/solutions.full.js +156 -127
  8. package/dist/solutions.full.min.js +4 -4
  9. package/dist/solutions.full.min.js.map +1 -1
  10. package/dist/types/bc-connect/src/manager.d.ts +72 -62
  11. package/dist/types/ws-video-manager/src/loader/websocket-loader.d.ts +13 -10
  12. package/dist/types/ws-video-manager/src/manager/index.d.ts +54 -37
  13. package/dist/types/ws-video-manager/src/render/drawer.d.ts +7 -7
  14. package/dist/types/ws-video-manager/src/render/index.d.ts +35 -19
  15. package/package.json +4 -4
  16. package/vite.config.ts +1 -1
  17. package/ws-video-manager/dist/types/src/loader/websocket-loader.d.ts +13 -10
  18. package/ws-video-manager/dist/types/src/manager/index.d.ts +54 -37
  19. package/ws-video-manager/dist/types/src/render/drawer.d.ts +7 -7
  20. package/ws-video-manager/dist/types/src/render/index.d.ts +35 -19
  21. package/ws-video-manager/dist/ws-video-manager.mjs +67 -54
  22. package/ws-video-manager/dist/ws-video-manager.umd.js +67 -54
  23. package/ws-video-manager/package.json +1 -1
  24. package/ws-video-manager/src/loader/websocket-loader.ts +15 -11
  25. package/ws-video-manager/src/manager/index.ts +57 -40
  26. package/ws-video-manager/src/render/drawer.ts +22 -20
  27. package/ws-video-manager/src/render/index.ts +61 -27
  28. package/ws-video-manager/src/render/mp4box.ts +1 -1
@@ -0,0 +1,73 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { BroadcastChannelManager, BcConnectNodeTypeEnum } from '@havue/bc-connect'
3
+
4
+ async function sleep(time) {
5
+ return new Promise((res) => {
6
+ setTimeout(res, time)
7
+ })
8
+ }
9
+
10
+ const DEBUG = false
11
+
12
+ describe.sequential('BroadcastChannelManager', () => {
13
+ it('should create a new instance', () => {
14
+ const manager = new BroadcastChannelManager('test-channel', DEBUG)
15
+ expect(manager).toBeInstanceOf(BroadcastChannelManager)
16
+ manager.destroy()
17
+ })
18
+
19
+ it('should be Main', async () => {
20
+ const manager = new BroadcastChannelManager('test-channel', DEBUG)
21
+ manager.connect()
22
+ expect(manager.nodeType).toBeUndefined()
23
+ await sleep(400)
24
+ expect(manager.nodeType).toBe(BcConnectNodeTypeEnum.Main)
25
+ manager.close()
26
+ manager.destroy()
27
+ })
28
+
29
+ it('when channel closed', async () => {
30
+ const manager = new BroadcastChannelManager('test-channel', DEBUG)
31
+ manager.connect()
32
+ manager.close()
33
+ await sleep(400)
34
+ expect(manager.nodeType).toBeUndefined()
35
+ manager.destroy()
36
+ })
37
+
38
+ it('should handle messages', async () => {
39
+ const manager1 = new BroadcastChannelManager('test-channel', DEBUG)
40
+ // 确保第二个id生成在第一个之后
41
+ await sleep(10)
42
+ const manager2 = new BroadcastChannelManager('test-channel', DEBUG)
43
+ manager1.connect()
44
+ manager2.connect()
45
+ await sleep(1200)
46
+
47
+ const message1 = { type: 'test', data: 'Hello, manger2!' }
48
+ const message2 = { type: 'test', data: 'Hello, manger1!' }
49
+
50
+ manager1.on('test', (message) => {
51
+ expect(message.data).toBe(message2.data)
52
+ })
53
+ manager2.on('test', (message) => {
54
+ expect(message.data).toBe(message1.data)
55
+ })
56
+
57
+ manager1.send(message1.type, message1.data)
58
+ manager2.send(message2.type, message2.data)
59
+ expect(manager1.nodeType).toBe(BcConnectNodeTypeEnum.Main)
60
+ expect(manager2.nodeType).toBe(BcConnectNodeTypeEnum.Normal)
61
+
62
+ expect(manager1.friendList).toContain(manager2.id)
63
+ expect(manager2.friendList).toContain(manager1.id)
64
+
65
+ // wait for the message to be received
66
+ await sleep(1000)
67
+ manager1.close()
68
+ manager2.close()
69
+
70
+ manager1.destroy()
71
+ manager2.destroy()
72
+ })
73
+ })
@@ -2,14 +2,14 @@ var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
4
  var BcConnectEventTypeEnum = /* @__PURE__ */ ((BcConnectEventTypeEnum2) => {
5
- BcConnectEventTypeEnum2["Broadcast"] = "Hello world";
6
- BcConnectEventTypeEnum2["Broadcast_Reply"] = "I can hear you";
7
- BcConnectEventTypeEnum2["Main_Node_Hearbeat"] = "苍天还在,别立黄天";
8
- BcConnectEventTypeEnum2["Res_Main_Node_Hearbeat"] = "苍天在上,受我一拜";
9
- BcConnectEventTypeEnum2["Req_Be_Main_Node"] = "苍天已死,黄天当立";
10
- BcConnectEventTypeEnum2["Res_Be_Main_Node"] = "我是黄天,尔等退下";
11
- BcConnectEventTypeEnum2["Node_Type_Change"] = "node type change";
12
- BcConnectEventTypeEnum2["Friend_List_Update"] = "friend list update";
5
+ BcConnectEventTypeEnum2["Broadcast"] = "__BCM_INIT__";
6
+ BcConnectEventTypeEnum2["Broadcast_Reply"] = "__BCM_INIT_REPLY__";
7
+ BcConnectEventTypeEnum2["Main_Node_Hearbeat"] = "__BCM_MAIN_NODE_HEARBEAT__";
8
+ BcConnectEventTypeEnum2["Res_Main_Node_Hearbeat"] = "__BCM_MAIN_NODE_HEARBEAT_REPLY__";
9
+ BcConnectEventTypeEnum2["Req_Be_Main_Node"] = "__BCM_REQ_BE_MAIN_NODE__";
10
+ BcConnectEventTypeEnum2["Res_Be_Main_Node"] = "__BCM_REQ_BE_MAIN_NODE_REJECT__";
11
+ BcConnectEventTypeEnum2["Node_Type_Change"] = "__BCM_NODE_TYPE_CHANGE__";
12
+ BcConnectEventTypeEnum2["Friend_List_Update"] = "__BCM_FRIEND_LIST_UPDATE__";
13
13
  return BcConnectEventTypeEnum2;
14
14
  })(BcConnectEventTypeEnum || {});
15
15
  var BcConnectNodeTypeEnum = /* @__PURE__ */ ((BcConnectNodeTypeEnum2) => {
@@ -20,25 +20,30 @@ var BcConnectNodeTypeEnum = /* @__PURE__ */ ((BcConnectNodeTypeEnum2) => {
20
20
  const MessageTimeout = 300;
21
21
  class BroadcastChannelManager {
22
22
  constructor(name, debug = false) {
23
- /** 通道名称 */
23
+ /** 通道名称 | Channel name */
24
24
  __publicField(this, "_bcName");
25
- /** BroadcastChannel实例 */
25
+ /** BroadcastChannel instance */
26
26
  __publicField(this, "_broadcastChannel");
27
- /** 事件map */
27
+ /** Event map */
28
28
  __publicField(this, "_eventMap");
29
- /** 主节点发送心跳的interval */
29
+ /** 主节点发送心跳的interval | The interval at which the master node sends the heartbeat */
30
30
  __publicField(this, "_mainNodeMsgInterval", null);
31
- /** 认为主节点掉线的timeout */
32
- __publicField(this, "_mainNoceMsgTimeoutTimer", null);
33
- /** 当前实例id */
31
+ /** 认为主节点掉线的timeout | timeout to consider the primary node to be offline */
32
+ __publicField(this, "_mainNodeMsgTimeoutTimer", null);
33
+ /** 更新友方列表的timeout | Update the timeout of the friend list */
34
+ __publicField(this, "_updateFriendListTimer", null);
35
+ /** 当前实例id | Current instance id */
34
36
  __publicField(this, "id", Date.now() + Math.random());
35
- /** 记录的友方id数组 */
37
+ /** 其他广播通道id列表 | List of other broadcast channel ids */
36
38
  __publicField(this, "_oldFrendChannelIdList", []);
37
- /** 正在更新的右方id数组 */
39
+ /** 正在更新的id数组 | The id array being updated */
38
40
  __publicField(this, "_friendChannelIdSet", /* @__PURE__ */ new Set());
39
- /** 当前节点类型 */
41
+ /** 当前节点类型 | Current node type */
40
42
  __publicField(this, "_nodeType");
41
- /** 是否开启调试模式,会在控制台打印相关信息 */
43
+ /**
44
+ * 是否开启调试模式,会在控制台打印相关信息
45
+ * If debug mode is enabled, it will print information to the console
46
+ */
42
47
  __publicField(this, "_debug", false);
43
48
  this._debug = debug;
44
49
  this._bcName = name;
@@ -61,9 +66,19 @@ class BroadcastChannelManager {
61
66
  close() {
62
67
  this._debug && console.log("BC:bc close");
63
68
  this._broadcastChannel && this._broadcastChannel.close();
69
+ this._broadcastChannel = void 0;
70
+ this._updateFriendListTimer && clearTimeout(this._updateFriendListTimer);
71
+ this._updateFriendListTimer = null;
72
+ this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval);
73
+ this._mainNodeMsgInterval = null;
74
+ this._mainNodeMsgTimeoutTimer && clearTimeout(this._mainNodeMsgTimeoutTimer);
75
+ this._mainNodeMsgTimeoutTimer = null;
76
+ this._oldFrendChannelIdList = [];
77
+ this._friendChannelIdSet.clear();
78
+ this._nodeType = void 0;
64
79
  }
65
80
  /**
66
- * 切换节点类型
81
+ * 切换节点类型 | Switching node type
67
82
  * @param {BcConnectNodeTypeEnum} type
68
83
  * @returns
69
84
  */
@@ -72,30 +87,31 @@ class BroadcastChannelManager {
72
87
  return;
73
88
  }
74
89
  this._nodeType = type;
75
- this.emit("node type change", {
76
- type: "node type change",
90
+ this.emit("__BCM_NODE_TYPE_CHANGE__", {
91
+ type: "__BCM_NODE_TYPE_CHANGE__",
77
92
  data: type,
78
93
  id: this.id
79
94
  });
80
95
  }
81
- /** 更新友方列表 */
96
+ /** 更新广播id列表 | Update the list of broadcast ids */
82
97
  _updateFriendList() {
83
98
  this.send(
84
- "Hello world"
99
+ "__BCM_INIT__"
85
100
  /* Broadcast */
86
101
  );
87
- setTimeout(() => {
102
+ this._updateFriendListTimer && clearTimeout(this._updateFriendListTimer);
103
+ this._updateFriendListTimer = setTimeout(() => {
88
104
  this._oldFrendChannelIdList = this._getNewFriendList();
89
105
  this._debug && console.log("BC:connect:updateFriendChannelIdList:", this._oldFrendChannelIdList);
90
- this.emit("friend list update", {
91
- type: "friend list update",
106
+ this.emit("__BCM_FRIEND_LIST_UPDATE__", {
107
+ type: "__BCM_FRIEND_LIST_UPDATE__",
92
108
  data: [...this._oldFrendChannelIdList],
93
109
  id: this.id
94
110
  });
95
111
  this._updataNodeType();
96
112
  }, MessageTimeout);
97
113
  }
98
- /** 绑定事件 */
114
+ /** 绑定事件 | Bind event */
99
115
  _bindBroadcastChannelEvent() {
100
116
  this._broadcastChannel && (this._broadcastChannel.onmessage = (event) => {
101
117
  const { type, targetId } = event.data;
@@ -104,63 +120,63 @@ class BroadcastChannelManager {
104
120
  }
105
121
  this.emit(type, event.data);
106
122
  });
107
- this.on("Hello world", (data) => {
123
+ this.on("__BCM_INIT__", (data) => {
108
124
  const { id } = data;
109
125
  if (!this._friendChannelIdSet.has(id)) {
110
126
  this._friendChannelIdSet.add(id);
111
127
  }
112
- this.sendToTarget("I can hear you", id);
128
+ this.sendToTarget("__BCM_INIT_REPLY__", id);
113
129
  });
114
- this.on("I can hear you", (data) => {
130
+ this.on("__BCM_INIT_REPLY__", (data) => {
115
131
  const { id } = data;
116
132
  this._addFriend(id);
117
133
  });
118
- this.on("苍天已死,黄天当立", (data) => {
134
+ this.on("__BCM_REQ_BE_MAIN_NODE__", (data) => {
119
135
  const { id } = data;
120
136
  if (id > this.id) {
121
- this.sendToTarget("我是黄天,尔等退下", id);
137
+ this.sendToTarget("__BCM_REQ_BE_MAIN_NODE_REJECT__", id);
122
138
  }
123
139
  });
124
- this.on("苍天在上,受我一拜", (data) => {
140
+ this.on("__BCM_MAIN_NODE_HEARBEAT_REPLY__", (data) => {
125
141
  this._addFriend(data.id);
126
142
  });
127
143
  this._bindNodeEvent();
128
144
  }
129
- /** 监听节点类型切换事件 */
145
+ /** 监听节点类型切换事件 | */
130
146
  _bindNodeEvent() {
131
147
  const onMainNodeHearbeat = (data) => {
132
148
  this._timeoutToBeMainNode();
133
149
  this._catchOldFriend();
134
150
  this._addFriend(data.id);
135
151
  this.send(
136
- "苍天在上,受我一拜"
152
+ "__BCM_MAIN_NODE_HEARBEAT_REPLY__"
137
153
  /* Res_Main_Node_Hearbeat */
138
154
  );
139
155
  };
140
- this.on("node type change", (info) => {
156
+ this.on("__BCM_NODE_TYPE_CHANGE__", (info) => {
141
157
  const { data } = info;
142
158
  this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval);
143
- this._debug && console.log("BC:代理类型切换:", info.data);
159
+ this._debug && console.log("BC:NODE_TYPE_CHANGE:", info.data);
144
160
  if (data === "main") {
145
161
  this._mainNodeMsgInterval = setInterval(() => {
146
162
  this._catchOldFriend();
147
163
  this.send(
148
- "苍天还在,别立黄天"
164
+ "__BCM_MAIN_NODE_HEARBEAT__"
149
165
  /* Main_Node_Hearbeat */
150
166
  );
151
167
  }, MessageTimeout);
152
168
  } else if (data === "normal") {
153
169
  this._timeoutToBeMainNode();
154
170
  }
155
- this.on("苍天还在,别立黄天", onMainNodeHearbeat);
171
+ this.on("__BCM_MAIN_NODE_HEARBEAT__", onMainNodeHearbeat);
156
172
  });
157
173
  }
158
- /** 获取最新的友方列表 */
174
+ /** 获取最新的节点列表 | Get the latest node list */
159
175
  _getNewFriendList() {
160
176
  return [...this._friendChannelIdSet].sort((a, b) => a - b);
161
177
  }
162
178
  /**
163
- * 更新当前节点类型
179
+ * 更新当前节点类型 | Update the current node type
164
180
  */
165
181
  _updataNodeType() {
166
182
  this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval);
@@ -183,21 +199,21 @@ class BroadcastChannelManager {
183
199
  }
184
200
  }
185
201
  _timeoutToBeMainNode() {
186
- this._mainNoceMsgTimeoutTimer && clearTimeout(this._mainNoceMsgTimeoutTimer);
187
- this._mainNoceMsgTimeoutTimer = setTimeout(() => {
202
+ this._mainNodeMsgTimeoutTimer && clearTimeout(this._mainNodeMsgTimeoutTimer);
203
+ this._mainNodeMsgTimeoutTimer = setTimeout(() => {
188
204
  this._req_beMainNode();
189
205
  }, MessageTimeout * 3);
190
206
  }
191
207
  /**
192
- * 保持记录的活跃的友方id列表
193
- * 清空正在记录的友方id列表
208
+ * 保存最新的节点列表到_oldFrendChannelIdList,清空_friendChannelIdSet
209
+ * Save the latest node list to _oldFrendChannelIdList and clear _friendChannelIdSet
194
210
  */
195
211
  _catchOldFriend() {
196
212
  const newFriendList = this._getNewFriendList();
197
213
  if (this._oldFrendChannelIdList.join() !== newFriendList.join()) {
198
214
  this._debug && console.log("BC:updateFriendChannelIdList:", newFriendList);
199
- this.emit("friend list update", {
200
- type: "friend list update",
215
+ this.emit("__BCM_FRIEND_LIST_UPDATE__", {
216
+ type: "__BCM_FRIEND_LIST_UPDATE__",
201
217
  data: [...newFriendList],
202
218
  id: this.id
203
219
  });
@@ -212,12 +228,12 @@ class BroadcastChannelManager {
212
228
  this._friendChannelIdSet.clear();
213
229
  }
214
230
  /**
215
- * 申请成为主节点
231
+ * 申请成为主节点 | Apply to be a master node
216
232
  */
217
233
  _req_beMainNode() {
218
234
  this._debug && console.log("BC:req_beMainNode");
219
235
  this.send(
220
- "苍天已死,黄天当立"
236
+ "__BCM_REQ_BE_MAIN_NODE__"
221
237
  /* Req_Be_Main_Node */
222
238
  );
223
239
  const timer = setTimeout(() => {
@@ -228,13 +244,13 @@ class BroadcastChannelManager {
228
244
  }, MessageTimeout);
229
245
  const handleRes_beMainNode = () => {
230
246
  clearTimeout(timer);
231
- this.off("我是黄天,尔等退下", handleRes_beMainNode);
247
+ this.off("__BCM_REQ_BE_MAIN_NODE_REJECT__", handleRes_beMainNode);
232
248
  };
233
- this.on("我是黄天,尔等退下", handleRes_beMainNode);
249
+ this.on("__BCM_REQ_BE_MAIN_NODE_REJECT__", handleRes_beMainNode);
234
250
  }
235
251
  /**
236
- * 添加友方
237
- * @param id 节点id
252
+ * add node
253
+ * @param id id
238
254
  */
239
255
  _addFriend(id) {
240
256
  if (!this._friendChannelIdSet.has(id)) {
@@ -242,9 +258,9 @@ class BroadcastChannelManager {
242
258
  }
243
259
  }
244
260
  /**
245
- * 广播消息
246
- * @param type 消息类型
247
- * @param data 数据
261
+ * 广播消息 | Send Broadcast message
262
+ * @param type 消息类型 | Message type
263
+ * @param data 数据 | data
248
264
  */
249
265
  send(type, data) {
250
266
  var _a;
@@ -255,10 +271,10 @@ class BroadcastChannelManager {
255
271
  });
256
272
  }
257
273
  /**
258
- * 给特定id的节点发送消息
259
- * @param type 消息类型
260
- * @param targetId 目标节点id
261
- * @param data 数据
274
+ * 给特定id的节点发送消息 | Send a message to a node with a specific id
275
+ * @param type 消息类型 | Message type
276
+ * @param targetId 目标节点id | Target Node id
277
+ * @param data 数据 | data
262
278
  */
263
279
  sendToTarget(type, targetId, data) {
264
280
  var _a;
@@ -270,9 +286,9 @@ class BroadcastChannelManager {
270
286
  });
271
287
  }
272
288
  /**
273
- * 注册事件
274
- * @param { string } event 事件类型
275
- * @param callback 回调
289
+ * 注册事件 | Registering events
290
+ * @param { string } event 事件类型 | Event type
291
+ * @param callback 回调 | callback
276
292
  * @returns void
277
293
  */
278
294
  on(event, callback) {
@@ -287,9 +303,9 @@ class BroadcastChannelManager {
287
303
  callbacks.push(callback);
288
304
  }
289
305
  /**
290
- * 注销事件
291
- * @param { string } event 事件类型
292
- * @param callback 事件回调
306
+ * 注销事件 | Remove events
307
+ * @param { string } event 事件类型 | Event type
308
+ * @param callback 事件回调 | callback
293
309
  * @returns
294
310
  */
295
311
  off(event, callback) {
@@ -305,9 +321,9 @@ class BroadcastChannelManager {
305
321
  callbacks.splice(index, 1);
306
322
  }
307
323
  /**
308
- * 触发事件
309
- * @param { string } event 事件类型
310
- * @param data 数据
324
+ * 触发事件 | Triggering events
325
+ * @param { string } event 事件类型 | Event type
326
+ * @param data 数据 | data
311
327
  */
312
328
  emit(event, data) {
313
329
  const callbacks = this._eventMap.get(event) || [];
@@ -316,7 +332,7 @@ class BroadcastChannelManager {
316
332
  });
317
333
  }
318
334
  /**
319
- * 销毁
335
+ * 销毁 | destroy
320
336
  */
321
337
  destroy() {
322
338
  var _a;
@@ -330,8 +346,8 @@ class BroadcastChannelManager {
330
346
  this._nodeType = void 0;
331
347
  this._mainNodeMsgInterval && clearInterval(this._mainNodeMsgInterval);
332
348
  this._mainNodeMsgInterval = null;
333
- this._mainNoceMsgTimeoutTimer && clearInterval(this._mainNoceMsgTimeoutTimer);
334
- this._mainNoceMsgTimeoutTimer = null;
349
+ this._mainNodeMsgTimeoutTimer && clearInterval(this._mainNodeMsgTimeoutTimer);
350
+ this._mainNodeMsgTimeoutTimer = null;
335
351
  this._debug && console.log("BC:destroy");
336
352
  }
337
353
  }