11/*! simple-peer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
22import debug from 'debug'
33import { RTCPeerConnection , RTCSessionDescription , RTCIceCandidate , RTCDataChannel , RTCDataChannelEvent , RTCPeerConnectionIceEvent , MediaStream , MediaStreamTrack } from 'webrtc-polyfill'
4- import { EventEmitter } from 'eventemitter3'
4+ import { EventEmitter } from 'eventemitter3'
55import errCode from 'err-code'
66import { randomBytes , arr2hex , text2arr } from 'uint8-util'
77
88type Callback = ( err : Error | null ) => void
9+ type DataChunk = ArrayBufferView | ArrayBuffer | Uint8Array | string | Blob
910
1011const Debug = debug ( 'simple-peer' )
1112
@@ -46,7 +47,7 @@ interface PeerOptions {
4647 trickle ?: boolean
4748 allowHalfTrickle ?: boolean
4849 iceCompleteTimeout ?: number
49- objectMode ?: boolean
50+ binary ?: boolean
5051 allowHalfOpen ?: boolean
5152}
5253
@@ -88,13 +89,13 @@ interface LegacyStatsResult {
8889 stat : ( name : string ) => unknown
8990}
9091
91- interface PeerEvents {
92+ interface PeerEvents < TData > {
9293 signal : ( data : SignalData ) => void
9394 connect : ( ) => void
9495 disconnect : ( ) => void
9596 close : ( ) => void
9697 error : ( err : Error ) => void
97- data : ( data : Uint8Array | string ) => void
98+ data : ( data : TData ) => void
9899 end : ( ) => void
99100 finish : ( ) => void
100101 iceStateChange : ( iceConnectionState : RTCIceConnectionState , iceGatheringState : RTCIceGatheringState ) => void
@@ -110,7 +111,7 @@ interface PeerEvents {
110111 * WebRTC peer connection. Same API as node core `net.Socket`, plus a few extra methods.
111112 * Extends EventEmitter for event handling.
112113 */
113- class Peer extends EventEmitter < PeerEvents > {
114+ class Peer < TData extends DataChunk = Uint8Array > extends EventEmitter < PeerEvents < TData > > {
114115 _pc : RTCPeerConnection | null
115116 _id : string
116117 channelName : string | null
@@ -149,13 +150,13 @@ class Peer extends EventEmitter<PeerEvents> {
149150 _closingInterval : ReturnType < typeof setInterval > | null
150151 _remoteTracks : Array < { track : MediaStreamTrack ; stream : MediaStream } > | null
151152 _remoteStreams : MediaStream [ ] | null
152- _chunk : ArrayBufferView | ArrayBuffer | Uint8Array | string | Blob | null
153+ _chunk : TData | null
153154 _cb : Callback | null
154155 _interval : ReturnType < typeof setInterval > | null
155156 _isReactNativeWebrtc : boolean
156157 _connecting : boolean
157158 _onFinishBound : ( ( ) => void ) | null
158- __objectMode : boolean
159+ _binary : boolean
159160
160161 static WEBRTC_SUPPORT : boolean
161162 static config : RTCConfiguration
@@ -167,7 +168,6 @@ class Peer extends EventEmitter<PeerEvents> {
167168 this . destroyed = false
168169 this . _readableEnded = false
169170 this . _writableEnded = false
170- this . __objectMode = ! ! opts . objectMode
171171
172172 this . _id = arr2hex ( randomBytes ( 4 ) ) . slice ( 0 , 7 )
173173 this . _debug ( 'new peer %o' , opts )
@@ -225,7 +225,10 @@ class Peer extends EventEmitter<PeerEvents> {
225225 this . _chunk = null
226226 this . _cb = null
227227 this . _interval = null
228+ this . _isReactNativeWebrtc = typeof window !== 'undefined' && ( window as typeof window & { ReactNativeWebRTCDebug ?: unknown } ) . ReactNativeWebRTCDebug != null
228229 this . _connecting = false
230+ this . _onFinishBound = null
231+ this . _binary = opts . binary !== undefined ? opts . binary : true
229232
230233 try {
231234 this . _pc = new RTCPeerConnection ( this . config )
@@ -366,10 +369,10 @@ class Peer extends EventEmitter<PeerEvents> {
366369 /**
367370 * Send text/binary data to the remote peer.
368371 */
369- send ( chunk : ArrayBufferView | ArrayBuffer | Uint8Array | string | Blob ) : void {
372+ send ( chunk : TData ) : void {
370373 if ( this . _destroying ) return
371374 if ( this . destroyed ) throw errCode ( new Error ( 'cannot send after peer is destroyed' ) , 'ERR_DESTROYED' )
372- this . _channel ! . send ( chunk as string | Blob | ArrayBuffer | ArrayBufferView )
375+ this . _channel ! . send ( chunk as DataChunk )
373376 }
374377
375378 _needsNegotiation ( ) : void {
@@ -420,7 +423,7 @@ class Peer extends EventEmitter<PeerEvents> {
420423 /**
421424 * Push data to the readable side. If data is null, signals end of stream.
422425 */
423- push ( data : Uint8Array | string | null ) : void {
426+ push ( data : TData | null ) : void {
424427 if ( data === null ) {
425428 this . _readableEnded = true
426429 this . emit ( 'end' )
@@ -432,7 +435,7 @@ class Peer extends EventEmitter<PeerEvents> {
432435 /**
433436 * Write data to the peer (with optional callback).
434437 */
435- write ( chunk : ArrayBufferView | ArrayBuffer | Uint8Array | string | Blob , cb ?: Callback ) : void {
438+ write ( chunk : TData , cb ?: Callback ) : void {
436439 this . _write ( chunk , cb || ( ( ) => { } ) )
437440 }
438441
@@ -567,7 +570,7 @@ class Peer extends EventEmitter<PeerEvents> {
567570 } , CHANNEL_CLOSING_TIMEOUT )
568571 }
569572
570- _write ( chunk : ArrayBufferView | ArrayBuffer | Uint8Array | string | Blob , cb : Callback ) : void {
573+ _write ( chunk : TData , cb : Callback ) : void {
571574 if ( this . destroyed ) return cb ( errCode ( new Error ( 'cannot write after peer is destroyed' ) , 'ERR_DATA_CHANNEL' ) )
572575
573576 if ( this . _connected ) {
@@ -983,13 +986,16 @@ class Peer extends EventEmitter<PeerEvents> {
983986
984987 _onChannelMessage ( event : MessageEvent ) : void {
985988 if ( this . destroyed ) return
986- let data : Uint8Array | string = event . data
989+ let data : unknown = event . data
987990 if ( data instanceof ArrayBuffer ) {
988991 data = new Uint8Array ( data )
989- } else if ( this . __objectMode === false ) {
992+ }
993+ if ( ArrayBuffer . isView ( data ) ) {
994+ // keep binary views as-is
995+ } else if ( typeof data === 'string' && this . _binary ) {
990996 data = text2arr ( data as string )
991997 }
992- this . push ( data as Uint8Array )
998+ this . push ( data as TData )
993999 }
9941000
9951001 _onChannelBufferedAmountLow ( ) : void {
0 commit comments