@laplace.live/ws 6.3.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,9 @@
1
+ import { Buffer } from 'buffer'
2
+ import { inflate } from 'pako'
3
+
4
+ import { BrotliDecode } from './brotli'
5
+
6
+ const inflateAsync = (d: Buffer) => Buffer.from(inflate(d))
7
+ const brotliDecompressAsync = (d: Buffer) => Buffer.from(BrotliDecode(Int8Array.from(d)))
8
+
9
+ export const inflates = { inflateAsync, brotliDecompressAsync, Buffer }
@@ -0,0 +1,11 @@
1
+ import { promisify } from 'node:util'
2
+ import { brotliDecompress, inflate } from 'node:zlib'
3
+ import { Buffer } from 'buffer'
4
+
5
+ const inflateAsync = promisify<Parameters<typeof inflate>[0], Parameters<Parameters<typeof inflate>[2]>[1]>(inflate)
6
+ const brotliDecompressAsync = promisify<
7
+ Parameters<typeof brotliDecompress>[0],
8
+ Parameters<Parameters<typeof brotliDecompress>[1]>[1]
9
+ >(brotliDecompress)
10
+
11
+ export const inflates = { inflateAsync, brotliDecompressAsync, Buffer }
package/src/tcp.ts ADDED
@@ -0,0 +1,48 @@
1
+ import net, { Socket } from 'net'
2
+
3
+ import { Inflates } from './buffer'
4
+ import { LiveOptions, Live } from './common'
5
+
6
+ export type TCPOptions = LiveOptions & { host?: string, port?: number }
7
+
8
+ export class LiveTCPBase extends Live {
9
+ socket: Socket
10
+ buffer: Buffer
11
+ i: number
12
+
13
+ constructor(inflates: Inflates, roomid: number, { host = 'broadcastlv.chat.bilibili.com', port = 2243, ...options}: TCPOptions = {}) {
14
+ const socket = net.connect(port, host)
15
+ const send = (data: Buffer) => {
16
+ socket.write(data)
17
+ }
18
+ const close = () => this.socket.end()
19
+
20
+ super(inflates, roomid, { send, close, ...options })
21
+
22
+ this.i = 0
23
+ this.buffer = Buffer.alloc(0)
24
+
25
+ socket.on('ready', () => this.emit('open'))
26
+ socket.on('close', () => this.emit('close'))
27
+ socket.on('error', (...params) => this.emit('_error', ...params))
28
+ socket.on('data', buffer => {
29
+ this.buffer = Buffer.concat([this.buffer, buffer])
30
+ this.splitBuffer()
31
+ })
32
+ this.socket = socket
33
+ }
34
+
35
+ splitBuffer() {
36
+ while (this.buffer.length >= 4 && this.buffer.readInt32BE(0) <= this.buffer.length) {
37
+ const size = this.buffer.readInt32BE(0)
38
+ const pack = this.buffer.slice(0, size)
39
+ this.buffer = this.buffer.slice(size)
40
+ this.i++
41
+ if (this.i > 5) {
42
+ this.i = 0
43
+ this.buffer = Buffer.from(this.buffer)
44
+ }
45
+ this.emit('message', pack)
46
+ }
47
+ }
48
+ }
package/src/ws.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { EventEmitter } from 'events'
2
+ import { Agent } from 'http'
3
+ import IsomorphicWebSocket from 'isomorphic-ws'
4
+
5
+ import { Inflates } from './buffer'
6
+ import { LiveOptions, Live } from './common'
7
+
8
+ export type WSOptions = LiveOptions & { address?: string, agent?: Agent }
9
+
10
+ export const isNode = !!IsomorphicWebSocket.Server
11
+
12
+ class WebSocket extends EventEmitter {
13
+ ws: IsomorphicWebSocket
14
+
15
+ constructor(address: string, inflates: Inflates, ...args: any[]) {
16
+ super()
17
+
18
+ const ws = new IsomorphicWebSocket(address, ...(isNode ? args : []))
19
+ this.ws = ws
20
+
21
+ ws.onopen = () => this.emit('open')
22
+ ws.onmessage = isNode ? ({ data }) => this.emit('message', data) : async ({ data }) => this.emit('message', inflates.Buffer.from(await new Response(data as unknown as InstanceType<typeof Blob>).arrayBuffer()))
23
+ ws.onerror = () => this.emit('error')
24
+ ws.onclose = () => this.emit('close')
25
+ }
26
+
27
+ get readyState() {
28
+ return this.ws.readyState
29
+ }
30
+
31
+ send(data: Buffer) {
32
+ this.ws.send(data)
33
+ }
34
+
35
+ close(code?: number, data?: string) {
36
+ this.ws.close(code, data)
37
+ }
38
+ }
39
+
40
+ export class LiveWSBase extends Live {
41
+ ws: InstanceType<typeof WebSocket>
42
+
43
+ constructor(inflates: Inflates, roomid: number, { address = 'wss://broadcastlv.chat.bilibili.com/sub', agent, ...options }: WSOptions = {}) {
44
+ const ws = new WebSocket(address, inflates, { agent })
45
+ const send = (data: Buffer) => {
46
+ if (ws.readyState === 1) {
47
+ ws.send(data)
48
+ }
49
+ }
50
+ const close = () => this.ws.close()
51
+
52
+ super(inflates, roomid, { send, close, ...options })
53
+
54
+ ws.on('open', (...params) => this.emit('open', ...params))
55
+ ws.on('message', data => this.emit('message', data as Buffer))
56
+ ws.on('close', (code, reason) => this.emit('close', code, reason))
57
+ ws.on('error', error => this.emit('_error', error))
58
+
59
+ this.ws = ws
60
+ }
61
+ }