@laplace.live/ws 7.0.0 → 7.0.1

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.
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Platform-specific inflate/decompress implementations injected into the
3
+ * decoder at construction time.
4
+ *
5
+ * - **Node / Bun**: backed by `node:zlib` (`inflate` + `brotliDecompress`).
6
+ * - **Browser**: backed by `pako` (inflate) + a bundled JS Brotli decoder.
7
+ */
8
+ type Inflates = {
9
+ inflateAsync: (b: Uint8Array) => Uint8Array | Promise<Uint8Array>;
10
+ brotliDecompressAsync: (b: Uint8Array) => Uint8Array | Promise<Uint8Array>;
11
+ };
12
+
13
+ /**
14
+ * A typed {@link Event} that carries an arbitrary data payload.
15
+ *
16
+ * Used throughout the library to deliver structured messages such as
17
+ * heartbeat counts, danmaku payloads, and other server-pushed data.
18
+ *
19
+ * Also used internally with `DataEvent<Event>` as a catch-all meta-event
20
+ * (type `"event"`) to forward all events through {@link KeepLive}.
21
+ *
22
+ * @typeParam T - The type of the data payload attached to this event.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * live.on<number>('heartbeat', (e) => {
27
+ * console.log('online:', e.data)
28
+ * })
29
+ * ```
30
+ */
31
+ declare class DataEvent<T> extends Event {
32
+ data: T;
33
+ constructor(type: string, data: T);
34
+ }
35
+
36
+ /**
37
+ * Options for configuring the Bilibili live connection authentication.
38
+ *
39
+ * When {@link authBody} is provided it takes precedence over all other
40
+ * fields and is sent as the join payload verbatim.
41
+ */
42
+ type LiveOptions = {
43
+ /** Protocol version. Defaults to `3` (brotli-compressed). */
44
+ protover?: 1 | 2 | 3;
45
+ /** Authentication token obtained from the danmaku info API. */
46
+ key?: string;
47
+ /**
48
+ * Pre-built authentication body. When supplied as a `Uint8Array` it is
49
+ * sent raw; when supplied as an object it is JSON-encoded before sending.
50
+ * Takes precedence over {@link key}, {@link uid}, and {@link buvid}.
51
+ */
52
+ authBody?: Uint8Array | Record<string, unknown>;
53
+ /** User ID. Defaults to `0` (anonymous). */
54
+ uid?: number;
55
+ /** Browser unique visitor ID used for risk-control tracking. */
56
+ buvid?: string;
57
+ };
58
+ /**
59
+ * Base class for a single Bilibili live room connection.
60
+ *
61
+ * Extends {@link EventTarget} and emits the following events:
62
+ *
63
+ * | Event | Payload | Description |
64
+ * |---------------|--------------------|--------------------------------------------------|
65
+ * | `open` | — | Underlying transport connected. |
66
+ * | `live` | — | Server acknowledged the join (room entered). |
67
+ * | `heartbeat` | `DataEvent<number>`| Online viewer count received from server. |
68
+ * | `msg` | `DataEvent<any>` | Any server command message. |
69
+ * | `DANMU_MSG` | `DataEvent<any>` | Danmaku (chat) message. |
70
+ * | `close` | — | Connection closed. |
71
+ * | `error` | — | Unrecoverable error (connection is closed). |
72
+ * | `event` | `DataEvent<Event>` | Meta-event wrapping every dispatched event. |
73
+ *
74
+ * Subclasses ({@link LiveWSBase}, {@link LiveTCPBase}) provide the concrete
75
+ * transport and supply `send` / `close` callbacks to this constructor.
76
+ *
77
+ * @param inflates - Platform-specific inflate + brotli decompressors.
78
+ * @param roomid - Numeric Bilibili live room ID.
79
+ * @param options - Transport callbacks and authentication options.
80
+ *
81
+ * @throws {Error} If `roomid` is not a finite number.
82
+ */
83
+ declare class Live extends EventTarget {
84
+ /** The live room ID this instance is connected to. */
85
+ roomid: number;
86
+ /** Latest known online viewer count, updated on each heartbeat. */
87
+ online: number;
88
+ /** `true` after the server acknowledges the join (`welcome` packet). */
89
+ live: boolean;
90
+ /** `true` after {@link close} has been called. */
91
+ closed: boolean;
92
+ /** @internal Handle for the heartbeat interval timer. */
93
+ timeout: ReturnType<typeof setTimeout>;
94
+ /** Send raw binary data over the underlying transport. */
95
+ send: (data: Uint8Array) => void;
96
+ /** Gracefully close the connection and set {@link closed} to `true`. */
97
+ close: () => void;
98
+ constructor(inflates: Inflates, roomid: number, { send, close, protover, key, authBody, uid, buvid, }: {
99
+ send: (data: Uint8Array) => void;
100
+ close: () => void;
101
+ } & LiveOptions);
102
+ /**
103
+ * Overridden to also dispatch a `DataEvent<Event>` with type `"event"`
104
+ * for every event, enabling catch-all listeners.
105
+ */
106
+ dispatchEvent(event: Event): boolean;
107
+ /** Send a heartbeat packet to the server. */
108
+ heartbeat(): void;
109
+ /**
110
+ * Send a heartbeat and resolve with the online viewer count from the
111
+ * next heartbeat response.
112
+ * @returns A promise that resolves with the current online count.
113
+ */
114
+ getOnline(): Promise<number>;
115
+ /**
116
+ * Subscribe to an event type with a typed {@link DataEvent} listener.
117
+ * Convenience wrapper around {@link EventTarget.addEventListener}.
118
+ *
119
+ * @typeParam T - Expected data type carried by the event.
120
+ * @param type - Event name (e.g. `"heartbeat"`, `"msg"`, `"DANMU_MSG"`).
121
+ * @param listener - Callback receiving a {@link DataEvent DataEvent\<T\>}.
122
+ * @param options - Standard `addEventListener` options.
123
+ */
124
+ on<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | AddEventListenerOptions): void;
125
+ /**
126
+ * Unsubscribe a previously registered listener.
127
+ * Convenience wrapper around {@link EventTarget.removeEventListener}.
128
+ *
129
+ * @typeParam T - Data type matching the original subscription.
130
+ * @param type - Event name.
131
+ * @param listener - The same function reference passed to {@link on}.
132
+ * @param options - Standard `removeEventListener` options.
133
+ */
134
+ off<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | EventListenerOptions): void;
135
+ }
136
+
137
+ /**
138
+ * Auto-reconnecting wrapper around a {@link Live} subclass.
139
+ *
140
+ * `KeepLive` maintains a persistent connection to a Bilibili live room by
141
+ * automatically re-creating the underlying {@link Live} instance whenever
142
+ * the connection drops or a heartbeat timeout is reached. All events from
143
+ * the inner connection are forwarded to this instance.
144
+ *
145
+ * @typeParam Base - The concrete {@link Live} subclass to manage
146
+ * (e.g. `typeof LiveWSBase` or `typeof LiveTCPBase`).
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * const keep = new KeepLiveWS(12345, { key: '...' })
151
+ * keep.on('heartbeat', (e) => console.log('online:', e.data))
152
+ * keep.on('DANMU_MSG', (e) => console.log('danmaku:', e.data))
153
+ * ```
154
+ */
155
+ declare class KeepLive<Base extends typeof Live> extends EventTarget {
156
+ /** @internal Stored constructor arguments for reconnection. */
157
+ params: ConstructorParameters<Base>;
158
+ /** `true` after {@link close} has been called; prevents further reconnects. */
159
+ closed: boolean;
160
+ /** Delay in milliseconds before attempting a reconnect. */
161
+ interval: number;
162
+ /** Maximum milliseconds to wait for a heartbeat before forcing a reconnect. */
163
+ timeout: number;
164
+ /** The current underlying connection instance. */
165
+ connection: InstanceType<Base>;
166
+ /** @internal The base class constructor used to create new connections. */
167
+ Base: Base;
168
+ constructor(Base: Base, ...params: ConstructorParameters<Base>);
169
+ /**
170
+ * Overridden to also dispatch a `DataEvent<Event>` with type `"event"`
171
+ * for every event, enabling catch-all listeners.
172
+ */
173
+ dispatchEvent(event: Event): boolean;
174
+ /**
175
+ * Wire up event forwarding and timeout handling on the current connection.
176
+ * When `reconnect` is `true`, the previous connection is closed and a fresh
177
+ * one is created from the stored constructor parameters.
178
+ *
179
+ * @param reconnect - Whether to tear down and recreate the connection first.
180
+ */
181
+ connect(reconnect?: boolean): void;
182
+ /** Latest known online viewer count from the underlying connection. */
183
+ get online(): number;
184
+ /** The live room ID. */
185
+ get roomid(): number;
186
+ /** Permanently close the connection and stop reconnecting. */
187
+ close(): void;
188
+ /** Send a heartbeat packet to the server. */
189
+ heartbeat(): void;
190
+ /**
191
+ * Send a heartbeat and resolve with the online viewer count from the
192
+ * next heartbeat response.
193
+ * @returns A promise that resolves with the current online count.
194
+ */
195
+ getOnline(): Promise<number>;
196
+ /**
197
+ * Send raw binary data through the underlying connection.
198
+ * @param data - The binary packet to send.
199
+ */
200
+ send(data: Uint8Array): void;
201
+ /**
202
+ * Subscribe to an event type with a typed {@link DataEvent} listener.
203
+ *
204
+ * @typeParam T - Expected data type carried by the event.
205
+ * @param type - Event name (e.g. `"heartbeat"`, `"msg"`, `"DANMU_MSG"`).
206
+ * @param listener - Callback receiving a {@link DataEvent DataEvent\<T\>}.
207
+ * @param options - Standard `addEventListener` options.
208
+ */
209
+ on<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | AddEventListenerOptions): void;
210
+ /**
211
+ * Unsubscribe a previously registered listener.
212
+ *
213
+ * @typeParam T - Data type matching the original subscription.
214
+ * @param type - Event name.
215
+ * @param listener - The same function reference passed to {@link on}.
216
+ * @param options - Standard `removeEventListener` options.
217
+ */
218
+ off<T = unknown>(type: string, listener: (event: DataEvent<T>) => void, options?: boolean | EventListenerOptions): void;
219
+ }
220
+
221
+ /**
222
+ * Configuration options for WebSocket-based live connections.
223
+ * Extends {@link LiveOptions} with an optional WebSocket server address.
224
+ */
225
+ type WSOptions = LiveOptions & {
226
+ /** WebSocket server URL. Defaults to `wss://broadcastlv.chat.bilibili.com/sub`. */
227
+ address?: string;
228
+ };
229
+ /**
230
+ * WebSocket transport for Bilibili live room connections.
231
+ *
232
+ * Wraps a native {@link WebSocket}, wiring its lifecycle events (`open`,
233
+ * `message`, `close`, `error`) into the {@link Live} event system. Binary
234
+ * frames are forwarded as `DataEvent<Uint8Array>` for protocol decoding.
235
+ *
236
+ * Not typically instantiated directly — use {@link LiveWS} (server) or the
237
+ * browser-specific `LiveWS` which inject the appropriate inflate
238
+ * implementation.
239
+ *
240
+ * @param inflates - Platform-specific inflate/brotli decompressors.
241
+ * @param roomid - Numeric Bilibili live room ID.
242
+ * @param options - WebSocket address and authentication options.
243
+ */
244
+ declare class LiveWSBase extends Live {
245
+ /** The underlying native WebSocket instance. */
246
+ ws: WebSocket;
247
+ constructor(inflates: Inflates, roomid: number, { address, ...options }?: WSOptions);
248
+ }
249
+
250
+ export { DataEvent as D, type Inflates as I, KeepLive as K, Live as L, type WSOptions as W, type LiveOptions as a, LiveWSBase as b };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laplace.live/ws",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Bilibili Live WebSocket/TCP API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,67 +0,0 @@
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?: Uint8Array | Record<string, unknown>;
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
- type WSOptions = LiveOptions & {
60
- address?: string;
61
- };
62
- declare class LiveWSBase extends Live {
63
- ws: WebSocket;
64
- constructor(inflates: Inflates, roomid: number, { address, ...options }?: WSOptions);
65
- }
66
-
67
- export { DataEvent as D, EventEvent as E, type Inflates as I, KeepLive as K, Live as L, type WSOptions as W, type LiveOptions as a, LiveWSBase as b };