@laplace.live/ws 6.3.5 → 6.3.7

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/dist/browser.js CHANGED
@@ -1,45 +1,60 @@
1
- // src/common.ts
2
- import { EventEmitter } from "events";
3
-
4
1
  // src/buffer.ts
2
+ var textEncoder = new TextEncoder();
3
+ var textDecoder = new TextDecoder();
4
+ function concatUint8Arrays(arrs) {
5
+ let totalLength = 0;
6
+ for (const arr of arrs) totalLength += arr.length;
7
+ const result = new Uint8Array(totalLength);
8
+ let offset = 0;
9
+ for (const arr of arrs) {
10
+ result.set(arr, offset);
11
+ offset += arr.length;
12
+ }
13
+ return result;
14
+ }
5
15
  var cutBuffer = (buffer) => {
6
16
  const bufferPacks = [];
17
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
7
18
  let size;
8
19
  for (let i = 0; i < buffer.length; i += size) {
9
- size = buffer.readInt32BE(i);
20
+ size = view.getInt32(i);
10
21
  bufferPacks.push(buffer.slice(i, i + size));
11
22
  }
12
23
  return bufferPacks;
13
24
  };
14
25
  var makeDecoder = ({ inflateAsync: inflateAsync2, brotliDecompressAsync: brotliDecompressAsync2 }) => {
15
26
  const decoder = async (buffer) => {
16
- const packs = await Promise.all(cutBuffer(buffer).map(async (buf) => {
17
- const body = buf.slice(16);
18
- const protocol = buf.readInt16BE(6);
19
- const operation = buf.readInt32BE(8);
20
- let type = "unknow";
21
- if (operation === 3) {
22
- type = "heartbeat";
23
- } else if (operation === 5) {
24
- type = "message";
25
- } else if (operation === 8) {
26
- type = "welcome";
27
- }
28
- let data;
29
- if (protocol === 0) {
30
- data = JSON.parse(String(body));
31
- }
32
- if (protocol === 1 && body.length === 4) {
33
- data = body.readUIntBE(0, 4);
34
- }
35
- if (protocol === 2) {
36
- data = await decoder(await inflateAsync2(body));
37
- }
38
- if (protocol === 3) {
39
- data = await decoder(await brotliDecompressAsync2(body));
40
- }
41
- return { buf, type, protocol, data };
42
- }));
27
+ const packs = await Promise.all(
28
+ cutBuffer(buffer).map(async (buf) => {
29
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
30
+ const body = buf.slice(16);
31
+ const protocol = view.getInt16(6);
32
+ const operation = view.getInt32(8);
33
+ let type = "unknow";
34
+ if (operation === 3) {
35
+ type = "heartbeat";
36
+ } else if (operation === 5) {
37
+ type = "message";
38
+ } else if (operation === 8) {
39
+ type = "welcome";
40
+ }
41
+ let data;
42
+ if (protocol === 0) {
43
+ data = JSON.parse(textDecoder.decode(body));
44
+ }
45
+ if (protocol === 1 && body.length === 4) {
46
+ const bodyView = new DataView(body.buffer, body.byteOffset, body.byteLength);
47
+ data = bodyView.getUint32(0);
48
+ }
49
+ if (protocol === 2) {
50
+ data = await decoder(await inflateAsync2(body));
51
+ }
52
+ if (protocol === 3) {
53
+ data = await decoder(await brotliDecompressAsync2(body));
54
+ }
55
+ return { buf, type, protocol, data };
56
+ })
57
+ );
43
58
  return packs.flatMap((pack) => {
44
59
  if (pack.protocol === 2 || pack.protocol === 3) {
45
60
  return pack.data;
@@ -49,42 +64,47 @@ var makeDecoder = ({ inflateAsync: inflateAsync2, brotliDecompressAsync: brotliD
49
64
  };
50
65
  return decoder;
51
66
  };
52
- var encoder = (type, { Buffer: Buffer2 }, body = "") => {
53
- const blank = Buffer2.alloc(16);
67
+ var encoder = (type, body = "") => {
54
68
  if (typeof body !== "string") {
55
69
  body = JSON.stringify(body);
56
70
  }
57
- const head = Buffer2.from(blank);
58
- const buffer = Buffer2.from(body);
59
- head.writeInt32BE(buffer.length + head.length, 0);
60
- head.writeInt16BE(16, 4);
61
- head.writeInt16BE(1, 6);
71
+ const head = new Uint8Array(16);
72
+ const headView = new DataView(head.buffer, head.byteOffset, head.byteLength);
73
+ const buffer = textEncoder.encode(body);
74
+ headView.setInt32(0, buffer.length + head.length);
75
+ headView.setInt16(4, 16);
76
+ headView.setInt16(6, 1);
62
77
  if (type === "heartbeat") {
63
- head.writeInt32BE(2, 8);
78
+ headView.setInt32(8, 2);
64
79
  }
65
80
  if (type === "join") {
66
- head.writeInt32BE(7, 8);
81
+ headView.setInt32(8, 7);
67
82
  }
68
- head.writeInt32BE(1, 12);
69
- return Buffer2.concat([head, buffer]);
83
+ headView.setInt32(12, 1);
84
+ return concatUint8Arrays([head, buffer]);
70
85
  };
71
86
 
72
87
  // src/common.ts
73
- var relayEvent = /* @__PURE__ */ Symbol("relay");
74
- var NiceEventEmitter = class extends EventEmitter {
75
- emit(eventName, ...params) {
76
- super.emit(eventName, ...params);
77
- super.emit(relayEvent, eventName, ...params);
78
- return true;
88
+ var DataEvent = class extends Event {
89
+ data;
90
+ constructor(type, data) {
91
+ super(type);
92
+ this.data = data;
93
+ }
94
+ };
95
+ var EventEvent = class extends Event {
96
+ event;
97
+ constructor(event) {
98
+ super("event");
99
+ this.event = event;
79
100
  }
80
101
  };
81
- var Live = class extends NiceEventEmitter {
102
+ var Live = class extends EventTarget {
82
103
  roomid;
83
104
  online;
84
105
  live;
85
106
  closed;
86
107
  timeout;
87
- inflates;
88
108
  send;
89
109
  close;
90
110
  constructor(inflates2, roomid, {
@@ -100,7 +120,6 @@ var Live = class extends NiceEventEmitter {
100
120
  throw new Error(`roomid ${roomid} must be Number not NaN`);
101
121
  }
102
122
  super();
103
- this.inflates = inflates2;
104
123
  this.roomid = roomid;
105
124
  this.online = 0;
106
125
  this.live = false;
@@ -112,37 +131,39 @@ var Live = class extends NiceEventEmitter {
112
131
  this.closed = true;
113
132
  close();
114
133
  };
115
- this.on("message", async (buffer) => {
116
- const packs = await makeDecoder(inflates2)(buffer);
134
+ const decode = makeDecoder(inflates2);
135
+ this.addEventListener("message", async (e) => {
136
+ const buffer = e.data;
137
+ const packs = await decode(buffer);
117
138
  packs.forEach(({ type, data }) => {
118
139
  if (type === "welcome") {
119
140
  this.live = true;
120
- this.emit("live");
121
- this.send(encoder("heartbeat", inflates2));
141
+ this.dispatchEvent(new Event("live"));
142
+ this.send(encoder("heartbeat"));
122
143
  }
123
144
  if (type === "heartbeat") {
124
145
  this.online = data;
125
146
  clearTimeout(this.timeout);
126
147
  this.timeout = setTimeout(() => this.heartbeat(), 1e3 * 30);
127
- this.emit("heartbeat", this.online);
148
+ this.dispatchEvent(new DataEvent("heartbeat", this.online));
128
149
  }
129
150
  if (type === "message") {
130
- this.emit("msg", data);
131
- const cmd = data.cmd || data.msg && data.msg.cmd;
151
+ this.dispatchEvent(new DataEvent("msg", data));
152
+ const cmd = data.cmd || data.msg?.cmd;
132
153
  if (cmd) {
133
154
  if (cmd.includes("DANMU_MSG")) {
134
- this.emit("DANMU_MSG", data);
155
+ this.dispatchEvent(new DataEvent("DANMU_MSG", data));
135
156
  } else {
136
- this.emit(cmd, data);
157
+ this.dispatchEvent(new DataEvent(cmd, data));
137
158
  }
138
159
  }
139
160
  }
140
161
  });
141
162
  });
142
- this.on("open", () => {
163
+ this.addEventListener("open", () => {
143
164
  if (authBody) {
144
165
  if (typeof authBody === "object") {
145
- authBody = encoder("join", inflates2, authBody);
166
+ authBody = encoder("join", authBody);
146
167
  }
147
168
  this.send(authBody);
148
169
  } else {
@@ -153,27 +174,40 @@ var Live = class extends NiceEventEmitter {
153
174
  if (buvid) {
154
175
  hi.buvid = buvid;
155
176
  }
156
- const buf = encoder("join", inflates2, hi);
177
+ const buf = encoder("join", hi);
157
178
  this.send(buf);
158
179
  }
159
180
  });
160
- this.on("close", () => {
181
+ this.addEventListener("close", () => {
161
182
  clearTimeout(this.timeout);
162
183
  });
163
- this.on("_error", (error) => {
184
+ this.addEventListener("_error", () => {
164
185
  this.close();
165
- this.emit("error", error);
186
+ this.dispatchEvent(new Event("error"));
166
187
  });
167
188
  }
189
+ dispatchEvent(event) {
190
+ const result = super.dispatchEvent(event);
191
+ super.dispatchEvent(new EventEvent(event));
192
+ return result;
193
+ }
168
194
  heartbeat() {
169
- this.send(encoder("heartbeat", this.inflates));
195
+ this.send(encoder("heartbeat"));
170
196
  }
171
197
  getOnline() {
172
198
  this.heartbeat();
173
- return new Promise((resolve) => this.once("heartbeat", resolve));
199
+ return new Promise(
200
+ (resolve) => this.addEventListener("heartbeat", (e) => resolve(e.data), { once: true })
201
+ );
202
+ }
203
+ on(type, listener, options) {
204
+ this.addEventListener(type, listener, options);
205
+ }
206
+ off(type, listener, options) {
207
+ this.removeEventListener(type, listener, options);
174
208
  }
175
209
  };
176
- var KeepLive = class extends EventEmitter {
210
+ var KeepLive = class extends EventTarget {
177
211
  params;
178
212
  closed;
179
213
  interval;
@@ -190,6 +224,11 @@ var KeepLive = class extends EventEmitter {
190
224
  this.Base = Base;
191
225
  this.connect(false);
192
226
  }
227
+ dispatchEvent(event) {
228
+ const result = super.dispatchEvent(event);
229
+ super.dispatchEvent(new EventEvent(event));
230
+ return result;
231
+ }
193
232
  connect(reconnect = true) {
194
233
  if (reconnect) {
195
234
  this.connection.close();
@@ -198,27 +237,32 @@ var KeepLive = class extends EventEmitter {
198
237
  const connection = this.connection;
199
238
  let timeout = setTimeout(() => {
200
239
  connection.close();
201
- connection.emit("timeout");
240
+ connection.dispatchEvent(new Event("timeout"));
202
241
  }, this.timeout);
203
- connection.on(relayEvent, (eventName, ...params) => {
204
- if (eventName !== "error") {
205
- this.emit(eventName, ...params);
242
+ connection.addEventListener("event", (e) => {
243
+ const evt = e.event;
244
+ if (evt.type !== "error") {
245
+ if (evt instanceof DataEvent) {
246
+ this.dispatchEvent(new DataEvent(evt.type, evt.data));
247
+ } else {
248
+ this.dispatchEvent(new Event(evt.type));
249
+ }
206
250
  }
207
251
  });
208
- connection.on("error", (e) => this.emit("e", e));
209
- connection.on("close", () => {
252
+ connection.addEventListener("error", () => this.dispatchEvent(new Event("e")));
253
+ connection.addEventListener("close", () => {
210
254
  if (!this.closed) {
211
255
  setTimeout(() => this.connect(), this.interval);
212
256
  }
213
257
  });
214
- connection.on("heartbeat", () => {
258
+ connection.addEventListener("heartbeat", () => {
215
259
  clearTimeout(timeout);
216
260
  timeout = setTimeout(() => {
217
261
  connection.close();
218
- connection.emit("timeout");
262
+ connection.dispatchEvent(new Event("timeout"));
219
263
  }, this.timeout);
220
264
  });
221
- connection.on("close", () => {
265
+ connection.addEventListener("close", () => {
222
266
  clearTimeout(timeout);
223
267
  });
224
268
  }
@@ -241,10 +285,15 @@ var KeepLive = class extends EventEmitter {
241
285
  send(data) {
242
286
  return this.connection.send(data);
243
287
  }
288
+ on(type, listener, options) {
289
+ this.addEventListener(type, listener, options);
290
+ }
291
+ off(type, listener, options) {
292
+ this.removeEventListener(type, listener, options);
293
+ }
244
294
  };
245
295
 
246
296
  // src/inflate/browser.ts
247
- import { Buffer } from "buffer";
248
297
  import { inflate } from "pako";
249
298
 
250
299
  // src/inflate/brotli.ts
@@ -2029,38 +2078,15 @@ var makeBrotliDecode = () => {
2029
2078
  var BrotliDecode = makeBrotliDecode();
2030
2079
 
2031
2080
  // src/inflate/browser.ts
2032
- var inflateAsync = (d) => Buffer.from(inflate(d));
2033
- var brotliDecompressAsync = (d) => Buffer.from(BrotliDecode(Int8Array.from(d)));
2034
- var inflates = { inflateAsync, brotliDecompressAsync, Buffer };
2081
+ var inflateAsync = (d) => inflate(d);
2082
+ var brotliDecompressAsync = (d) => Uint8Array.from(BrotliDecode(Int8Array.from(d)));
2083
+ var inflates = { inflateAsync, brotliDecompressAsync };
2035
2084
 
2036
2085
  // src/ws-client.ts
2037
- import { EventEmitter as EventEmitter2 } from "events";
2038
- var WSWrapper = class extends EventEmitter2 {
2039
- ws;
2040
- constructor(address, inflates2) {
2041
- super();
2042
- const ws = new WebSocket(address);
2043
- this.ws = ws;
2044
- ws.binaryType = "arraybuffer";
2045
- ws.onopen = () => this.emit("open");
2046
- ws.onmessage = ({ data }) => this.emit("message", inflates2.Buffer.from(data));
2047
- ws.onerror = () => this.emit("error");
2048
- ws.onclose = () => this.emit("close");
2049
- }
2050
- get readyState() {
2051
- return this.ws.readyState;
2052
- }
2053
- send(data) {
2054
- this.ws.send(data);
2055
- }
2056
- close(code, reason) {
2057
- this.ws.close(code, reason);
2058
- }
2059
- };
2060
2086
  var LiveWSBase = class extends Live {
2061
2087
  ws;
2062
2088
  constructor(inflates2, roomid, { address = "wss://broadcastlv.chat.bilibili.com/sub", ...options } = {}) {
2063
- const ws = new WSWrapper(address, inflates2);
2089
+ const ws = new WebSocket(address);
2064
2090
  const send = (data) => {
2065
2091
  if (ws.readyState === 1) {
2066
2092
  ws.send(data);
@@ -2068,10 +2094,14 @@ var LiveWSBase = class extends Live {
2068
2094
  };
2069
2095
  const close = () => this.ws.close();
2070
2096
  super(inflates2, roomid, { send, close, ...options });
2071
- ws.on("open", (...params) => this.emit("open", ...params));
2072
- ws.on("message", (data) => this.emit("message", data));
2073
- ws.on("close", (code, reason) => this.emit("close", code, reason));
2074
- ws.on("error", (error) => this.emit("_error", error));
2097
+ ws.binaryType = "arraybuffer";
2098
+ ws.addEventListener("open", (e) => this.dispatchEvent(new Event(e.type)));
2099
+ ws.addEventListener(
2100
+ "message",
2101
+ (e) => this.dispatchEvent(new DataEvent("message", new Uint8Array(e.data)))
2102
+ );
2103
+ ws.addEventListener("close", (e) => this.dispatchEvent(new Event(e.type)));
2104
+ ws.addEventListener("error", () => this.dispatchEvent(new Event("_error")));
2075
2105
  this.ws = ws;
2076
2106
  }
2077
2107
  };
@@ -2088,7 +2118,8 @@ var KeepLiveWS = class extends KeepLive {
2088
2118
  }
2089
2119
  };
2090
2120
  export {
2121
+ DataEvent,
2122
+ EventEvent,
2091
2123
  KeepLiveWS,
2092
- LiveWS,
2093
- relayEvent
2124
+ LiveWS
2094
2125
  };
@@ -0,0 +1,59 @@
1
+ type Inflates = {
2
+ inflateAsync: (b: Uint8Array) => Uint8Array | Promise<Uint8Array>;
3
+ brotliDecompressAsync: (b: Uint8Array) => Uint8Array | Promise<Uint8Array>;
4
+ };
5
+
6
+ type LiveOptions = {
7
+ protover?: 1 | 2 | 3;
8
+ key?: string;
9
+ authBody?: any;
10
+ uid?: number;
11
+ buvid?: string;
12
+ };
13
+ declare class DataEvent<T> extends Event {
14
+ data: T;
15
+ constructor(type: string, data: T);
16
+ }
17
+ declare class EventEvent extends Event {
18
+ event: Event;
19
+ constructor(event: Event);
20
+ }
21
+ declare class Live extends EventTarget {
22
+ roomid: number;
23
+ online: number;
24
+ live: boolean;
25
+ closed: boolean;
26
+ timeout: ReturnType<typeof setTimeout>;
27
+ send: (data: Uint8Array) => void;
28
+ close: () => void;
29
+ constructor(inflates: Inflates, roomid: number, { send, close, protover, key, authBody, uid, buvid, }: {
30
+ send: (data: Uint8Array) => void;
31
+ close: () => void;
32
+ } & LiveOptions);
33
+ dispatchEvent(event: Event): boolean;
34
+ heartbeat(): void;
35
+ getOnline(): Promise<number>;
36
+ on<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | AddEventListenerOptions): void;
37
+ off<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | EventListenerOptions): void;
38
+ }
39
+ declare class KeepLive<Base extends typeof Live> extends EventTarget {
40
+ params: ConstructorParameters<Base>;
41
+ closed: boolean;
42
+ interval: number;
43
+ timeout: number;
44
+ connection: InstanceType<Base>;
45
+ Base: Base;
46
+ constructor(Base: Base, ...params: ConstructorParameters<Base>);
47
+ dispatchEvent(event: Event): boolean;
48
+ connect(reconnect?: boolean): void;
49
+ get online(): number;
50
+ get roomid(): number;
51
+ close(): void;
52
+ heartbeat(): void;
53
+ getOnline(): Promise<number>;
54
+ send(data: Uint8Array): void;
55
+ on<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | AddEventListenerOptions): void;
56
+ off<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | EventListenerOptions): void;
57
+ }
58
+
59
+ export { DataEvent as D, EventEvent as E, type Inflates as I, KeepLive as K, Live as L, type LiveOptions as a };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import { L as Live, I as Inflates, a as LiveOptions, K as KeepLive } from './common-BGRg5uk7.js';
2
- export { r as relayEvent } from './common-BGRg5uk7.js';
1
+ import { L as Live, I as Inflates, a as LiveOptions, K as KeepLive } from './common-DWwvds2J.js';
2
+ export { D as DataEvent, E as EventEvent } from './common-DWwvds2J.js';
3
3
  import { Socket } from 'node:net';
4
4
  import { Agent } from 'node:http';
5
- import { EventEmitter } from 'events';
6
5
  import WS from 'ws';
7
6
 
8
7
  type TCPOptions = LiveOptions & {
@@ -11,7 +10,7 @@ type TCPOptions = LiveOptions & {
11
10
  };
12
11
  declare class LiveTCPBase extends Live {
13
12
  socket: Socket;
14
- buffer: Buffer;
13
+ buf: Buffer;
15
14
  i: number;
16
15
  constructor(inflates: Inflates, roomid: number, { host, port, ...options }?: TCPOptions);
17
16
  splitBuffer(): void;
@@ -21,15 +20,8 @@ type WSOptions = LiveOptions & {
21
20
  address?: string;
22
21
  agent?: Agent;
23
22
  };
24
- declare class WSWrapper extends EventEmitter {
25
- ws: WS;
26
- constructor(address: string, ...args: any[]);
27
- get readyState(): 0 | 1 | 3 | 2;
28
- send(data: Buffer): void;
29
- close(code?: number, data?: string): void;
30
- }
31
23
  declare class LiveWSBase extends Live {
32
- ws: WSWrapper;
24
+ ws: WS;
33
25
  constructor(inflates: Inflates, roomid: number, { address, agent, ...options }?: WSOptions);
34
26
  }
35
27