UNPKG

@mertushka/node-datachannel

Version:

WebRTC For Node.js and Electron. libdatachannel node bindings.

1 lines 5.21 kB
{"version":3,"file":"datachannel-stream.cjs","sources":["../../../src/lib/datachannel-stream.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport * as stream from 'stream';\n\n/**\n * Turns a node-datachannel DataChannel into a real Node.js stream, complete with buffering,\n * backpressure (up to a point - if the buffer fills up, messages are dropped), and\n * support for piping data elsewhere.\n *\n * Read & written data may be either UTF-8 strings or Buffers - this difference exists at\n * the protocol level, and is preserved here throughout.\n */\nexport default class DataChannelStream extends stream.Duplex {\n private _rawChannel: any;\n private _readActive: boolean;\n\n constructor(rawChannel: any, streamOptions?: Omit<stream.DuplexOptions, 'objectMode'>) {\n super({\n allowHalfOpen: false, // Default to autoclose on end().\n ...streamOptions,\n objectMode: true, // Preserve the string/buffer distinction (WebRTC treats them differently)\n });\n\n this._rawChannel = rawChannel;\n this._readActive = true;\n\n rawChannel.onMessage((msg: any) => {\n if (!this._readActive) return; // If the buffer is full, drop messages.\n\n // If the push is rejected, we pause reading until the next call to _read().\n this._readActive = this.push(msg);\n });\n\n // When the DataChannel closes, the readable & writable ends close\n rawChannel.onClosed(() => {\n this.push(null);\n this.destroy();\n });\n\n rawChannel.onError((errMsg: string) => {\n this.destroy(new Error(`DataChannel error: ${errMsg}`));\n });\n\n // Buffer all writes until the DataChannel opens\n if (!rawChannel.isOpen()) {\n this.cork();\n rawChannel.onOpen(() => this.uncork());\n }\n }\n\n _read(): void {\n // Stop dropping messages, if the buffer filling up meant we were doing so before.\n this._readActive = true;\n }\n\n _write(chunk, _encoding, callback): void {\n let sentOk;\n\n try {\n if (Buffer.isBuffer(chunk)) {\n sentOk = this._rawChannel.sendMessageBinary(chunk);\n } else if (typeof chunk === 'string') {\n sentOk = this._rawChannel.sendMessage(chunk);\n } else {\n const typeName = chunk.constructor.name || typeof chunk;\n throw new Error(`Cannot write ${typeName} to DataChannel stream`);\n }\n } catch (err) {\n return callback(err);\n }\n\n if (sentOk) {\n callback(null);\n } else {\n callback(new Error('Failed to write to DataChannel'));\n }\n }\n\n _final(callback): void {\n if (!this.allowHalfOpen) this.destroy();\n callback(null);\n }\n\n _destroy(maybeErr, callback): void {\n // When the stream is destroyed, we close the DataChannel.\n this._rawChannel.close();\n callback(maybeErr);\n }\n\n get label(): string {\n return this._rawChannel.getLabel();\n }\n\n get id(): number {\n return this._rawChannel.getId();\n }\n\n get protocol(): string {\n return this._rawChannel.getProtocol();\n }\n}\n"],"names":["stream"],"mappings":"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"}