@libp2p/webrtc 5.2.24-a02cb0461 → 5.2.24-f5932c294

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.
Files changed (87) hide show
  1. package/README.md +20 -10
  2. package/dist/index.min.js +14 -14
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/constants.d.ts +15 -0
  5. package/dist/src/constants.d.ts.map +1 -1
  6. package/dist/src/constants.js +15 -0
  7. package/dist/src/constants.js.map +1 -1
  8. package/dist/src/index.d.ts +22 -12
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +22 -12
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/maconn.d.ts +58 -0
  13. package/dist/src/maconn.d.ts.map +1 -0
  14. package/dist/src/maconn.js +56 -0
  15. package/dist/src/maconn.js.map +1 -0
  16. package/dist/src/muxer.d.ts +46 -14
  17. package/dist/src/muxer.d.ts.map +1 -1
  18. package/dist/src/muxer.js +135 -32
  19. package/dist/src/muxer.js.map +1 -1
  20. package/dist/src/private-to-private/initiate-connection.d.ts +4 -3
  21. package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
  22. package/dist/src/private-to-private/initiate-connection.js +5 -23
  23. package/dist/src/private-to-private/initiate-connection.js.map +1 -1
  24. package/dist/src/private-to-private/signaling-stream-handler.d.ts +4 -4
  25. package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
  26. package/dist/src/private-to-private/signaling-stream-handler.js +6 -10
  27. package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
  28. package/dist/src/private-to-private/transport.d.ts +2 -2
  29. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  30. package/dist/src/private-to-private/transport.js +15 -30
  31. package/dist/src/private-to-private/transport.js.map +1 -1
  32. package/dist/src/private-to-private/util.d.ts +1 -3
  33. package/dist/src/private-to-private/util.d.ts.map +1 -1
  34. package/dist/src/private-to-private/util.js +3 -15
  35. package/dist/src/private-to-private/util.js.map +1 -1
  36. package/dist/src/private-to-public/listener.js +2 -2
  37. package/dist/src/private-to-public/listener.js.map +1 -1
  38. package/dist/src/private-to-public/transport.js +1 -1
  39. package/dist/src/private-to-public/transport.js.map +1 -1
  40. package/dist/src/private-to-public/utils/connect.d.ts +1 -1
  41. package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
  42. package/dist/src/private-to-public/utils/connect.js +14 -17
  43. package/dist/src/private-to-public/utils/connect.js.map +1 -1
  44. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +4 -4
  45. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
  46. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +2 -13
  47. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
  48. package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
  49. package/dist/src/private-to-public/utils/sdp.js +3 -8
  50. package/dist/src/private-to-public/utils/sdp.js.map +1 -1
  51. package/dist/src/private-to-public/utils/stun-listener.js +1 -1
  52. package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
  53. package/dist/src/stream.d.ts +26 -13
  54. package/dist/src/stream.d.ts.map +1 -1
  55. package/dist/src/stream.js +166 -64
  56. package/dist/src/stream.js.map +1 -1
  57. package/dist/src/util.d.ts +1 -3
  58. package/dist/src/util.d.ts.map +1 -1
  59. package/dist/src/util.js +0 -19
  60. package/dist/src/util.js.map +1 -1
  61. package/dist/src/webrtc/index.d.ts +1 -1
  62. package/dist/src/webrtc/index.d.ts.map +1 -1
  63. package/dist/src/webrtc/index.js +1 -1
  64. package/dist/src/webrtc/index.js.map +1 -1
  65. package/package.json +29 -26
  66. package/src/constants.ts +18 -0
  67. package/src/index.ts +22 -12
  68. package/src/maconn.ts +101 -0
  69. package/src/muxer.ts +166 -43
  70. package/src/private-to-private/initiate-connection.ts +9 -31
  71. package/src/private-to-private/signaling-stream-handler.ts +9 -12
  72. package/src/private-to-private/transport.ts +17 -33
  73. package/src/private-to-private/util.ts +4 -21
  74. package/src/private-to-public/listener.ts +2 -2
  75. package/src/private-to-public/transport.ts +1 -1
  76. package/src/private-to-public/utils/connect.ts +15 -18
  77. package/src/private-to-public/utils/get-rtcpeerconnection.ts +4 -16
  78. package/src/private-to-public/utils/sdp.ts +3 -8
  79. package/src/private-to-public/utils/stun-listener.ts +1 -1
  80. package/src/stream.ts +194 -74
  81. package/src/util.ts +1 -22
  82. package/src/webrtc/index.ts +1 -1
  83. package/dist/src/rtcpeerconnection-to-conn.d.ts +0 -12
  84. package/dist/src/rtcpeerconnection-to-conn.d.ts.map +0 -1
  85. package/dist/src/rtcpeerconnection-to-conn.js +0 -43
  86. package/dist/src/rtcpeerconnection-to-conn.js.map +0 -1
  87. package/src/rtcpeerconnection-to-conn.ts +0 -62
package/src/stream.ts CHANGED
@@ -1,15 +1,20 @@
1
- import { StreamStateError } from '@libp2p/interface'
2
- import { AbstractStream } from '@libp2p/utils'
1
+ import { StreamStateError, TimeoutError } from '@libp2p/interface'
2
+ import { AbstractStream } from '@libp2p/utils/abstract-stream'
3
+ import { anySignal } from 'any-signal'
3
4
  import * as lengthPrefixed from 'it-length-prefixed'
4
5
  import { pushable } from 'it-pushable'
6
+ import pDefer from 'p-defer'
7
+ import pTimeout from 'p-timeout'
8
+ import { raceEvent } from 'race-event'
5
9
  import { raceSignal } from 'race-signal'
6
10
  import { Uint8ArrayList } from 'uint8arraylist'
7
- import { MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, PROTOBUF_OVERHEAD } from './constants.js'
11
+ import { BUFFERED_AMOUNT_LOW_TIMEOUT, FIN_ACK_TIMEOUT, MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, OPEN_TIMEOUT, PROTOBUF_OVERHEAD } from './constants.js'
8
12
  import { Message } from './private-to-public/pb/message.js'
9
13
  import type { DataChannelOptions } from './index.js'
10
- import type { AbortOptions, MessageStreamDirection, Logger } from '@libp2p/interface'
11
- import type { AbstractStreamInit, SendResult } from '@libp2p/utils'
14
+ import type { AbortOptions, Direction, Logger } from '@libp2p/interface'
15
+ import type { AbstractStreamInit } from '@libp2p/utils/abstract-stream'
12
16
  import type { Pushable } from 'it-pushable'
17
+ import type { DeferredPromise } from 'p-defer'
13
18
 
14
19
  export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions {
15
20
  /**
@@ -34,24 +39,76 @@ export class WebRTCStream extends AbstractStream {
34
39
  * and then the protobuf decoder.
35
40
  */
36
41
  private readonly incomingData: Pushable<Uint8Array>
42
+
37
43
  private readonly maxBufferedAmount: number
38
- private readonly receivedFinAck: PromiseWithResolvers<void>
44
+
45
+ private readonly bufferedAmountLowEventTimeout: number
46
+
47
+ /**
48
+ * The maximum size of a message in bytes
49
+ */
50
+ private readonly maxMessageSize: number
51
+
52
+ /**
53
+ * When this promise is resolved, the remote has sent us a FIN flag
54
+ */
55
+ private readonly receiveFinAck: DeferredPromise<void>
56
+ private readonly finAckTimeout: number
57
+ private readonly openTimeout: number
58
+ private readonly closeController: AbortController
39
59
 
40
60
  constructor (init: WebRTCStreamInit) {
41
- super({
42
- ...init,
43
- maxMessageSize: (init.maxMessageSize ?? MAX_MESSAGE_SIZE) - PROTOBUF_OVERHEAD
44
- })
61
+ // override onEnd to send/receive FIN_ACK before closing the stream
62
+ const originalOnEnd = init.onEnd
63
+ init.onEnd = (err?: Error): void => {
64
+ this.log.trace('readable and writeable ends closed with status "%s"', this.status)
65
+
66
+ void Promise.resolve(async () => {
67
+ if (this.timeline.abort != null || this.timeline.reset !== null) {
68
+ return
69
+ }
70
+
71
+ // wait for FIN_ACK if we haven't received it already
72
+ try {
73
+ await pTimeout(this.receiveFinAck.promise, {
74
+ milliseconds: this.finAckTimeout
75
+ })
76
+ } catch (err) {
77
+ this.log.error('error receiving FIN_ACK', err)
78
+ }
79
+ })
80
+ .then(() => {
81
+ // stop processing incoming messages
82
+ this.incomingData.end()
83
+
84
+ // final cleanup
85
+ originalOnEnd?.(err)
86
+ })
87
+ .catch(err => {
88
+ this.log.error('error ending stream', err)
89
+ })
90
+ .finally(() => {
91
+ this.channel.close()
92
+ })
93
+ }
94
+
95
+ super(init)
45
96
 
46
97
  this.channel = init.channel
47
98
  this.channel.binaryType = 'arraybuffer'
48
99
  this.incomingData = pushable<Uint8Array>()
100
+ this.bufferedAmountLowEventTimeout = init.bufferedAmountLowEventTimeout ?? BUFFERED_AMOUNT_LOW_TIMEOUT
49
101
  this.maxBufferedAmount = init.maxBufferedAmount ?? MAX_BUFFERED_AMOUNT
50
- this.receivedFinAck = Promise.withResolvers()
102
+ this.maxMessageSize = (init.maxMessageSize ?? MAX_MESSAGE_SIZE) - PROTOBUF_OVERHEAD
103
+ this.receiveFinAck = pDefer()
104
+ this.finAckTimeout = init.closeTimeout ?? FIN_ACK_TIMEOUT
105
+ this.openTimeout = init.openTimeout ?? OPEN_TIMEOUT
106
+ this.closeController = new AbortController()
51
107
 
52
108
  // set up initial state
53
109
  switch (this.channel.readyState) {
54
110
  case 'open':
111
+ this.timeline.open = new Date().getTime()
55
112
  break
56
113
 
57
114
  case 'closed':
@@ -70,16 +127,31 @@ export class WebRTCStream extends AbstractStream {
70
127
  }
71
128
 
72
129
  // handle RTCDataChannel events
130
+ this.channel.onopen = (_evt) => {
131
+ this.timeline.open = new Date().getTime()
132
+ }
133
+
73
134
  this.channel.onclose = (_evt) => {
74
135
  this.log.trace('received onclose event')
75
136
 
76
- this.onRemoteCloseWrite()
77
- this.onTransportClosed()
137
+ // stop any in-progress writes
138
+ this.closeController.abort()
139
+
140
+ // if the channel has closed we'll never receive a FIN_ACK so resolve the
141
+ // promise so we don't try to wait later
142
+ this.receiveFinAck.resolve()
143
+
144
+ void this.close().catch(err => {
145
+ this.log.error('error closing stream after channel closed', err)
146
+ })
78
147
  }
79
148
 
80
149
  this.channel.onerror = (evt) => {
81
150
  this.log.trace('received onerror event')
82
151
 
152
+ // stop any in-progress writes
153
+ this.closeController.abort()
154
+
83
155
  const err = (evt as RTCErrorEvent).error
84
156
  this.abort(err)
85
157
  }
@@ -94,12 +166,6 @@ export class WebRTCStream extends AbstractStream {
94
166
  this.incomingData.push(new Uint8Array(data, 0, data.byteLength))
95
167
  }
96
168
 
97
- // dispatch drain event when the buffered amount drops to zero
98
- this.channel.bufferedAmountLowThreshold = 0
99
- this.channel.onbufferedamountlow = () => {
100
- this.safeDispatchEvent('drain')
101
- }
102
-
103
169
  const self = this
104
170
 
105
171
  // pipe framed protobuf messages through a length prefixed decoder, and
@@ -109,59 +175,94 @@ export class WebRTCStream extends AbstractStream {
109
175
  const message = self.processIncomingProtobuf(buf)
110
176
 
111
177
  if (message != null) {
112
- self.onData(new Uint8ArrayList(message))
178
+ self.sourcePush(new Uint8ArrayList(message))
113
179
  }
114
180
  }
115
181
  })
116
182
  .catch(err => {
117
183
  this.log.error('error processing incoming data channel messages', err)
118
184
  })
119
-
120
- // clean up the datachannel when both ends have sent a FIN
121
- const webRTCStreamOnClose = (): void => {
122
- this.channel.close()
123
- }
124
- this.addEventListener('close', webRTCStreamOnClose)
125
185
  }
126
186
 
127
187
  sendNewStream (): void {
128
188
  // opening new streams is handled by WebRTC so this is a noop
129
189
  }
130
190
 
131
- _sendMessage (data: Uint8ArrayList): void {
191
+ async _sendMessage (data: Uint8ArrayList, checkBuffer: boolean = true): Promise<void> {
132
192
  if (this.channel.readyState === 'closed' || this.channel.readyState === 'closing') {
133
193
  throw new StreamStateError(`Invalid datachannel state - ${this.channel.readyState}`)
134
194
  }
135
195
 
196
+ if (this.channel.readyState !== 'open') {
197
+ const timeout = AbortSignal.timeout(this.openTimeout)
198
+ const signal = anySignal([
199
+ this.closeController.signal,
200
+ timeout
201
+ ])
202
+
203
+ try {
204
+ this.log('channel state is "%s" and not "open", waiting for "open" event before sending data', this.channel.readyState)
205
+ await raceEvent(this.channel, 'open', signal)
206
+ } finally {
207
+ signal.clear()
208
+ }
209
+
210
+ this.log('channel state is now "%s", sending data', this.channel.readyState)
211
+ }
212
+
213
+ if (checkBuffer && this.channel.bufferedAmount > this.maxBufferedAmount) {
214
+ const timeout = AbortSignal.timeout(this.bufferedAmountLowEventTimeout)
215
+ const signal = anySignal([
216
+ this.closeController.signal,
217
+ timeout
218
+ ])
219
+
220
+ try {
221
+ this.log('channel buffer is %d, wait for "bufferedamountlow" event', this.channel.bufferedAmount)
222
+ await raceEvent(this.channel, 'bufferedamountlow', signal)
223
+ } catch (err: any) {
224
+ if (timeout.aborted) {
225
+ throw new TimeoutError(`Timed out waiting for DataChannel buffer to clear after ${this.bufferedAmountLowEventTimeout}ms`)
226
+ }
227
+
228
+ throw err
229
+ } finally {
230
+ signal.clear()
231
+ }
232
+ }
233
+
136
234
  try {
137
235
  this.log.trace('sending message, channel state "%s"', this.channel.readyState)
138
236
  // send message without copying data
139
- for (const buf of data) {
140
- this.channel.send(buf)
141
- }
237
+ this.channel.send(data.subarray())
142
238
  } catch (err: any) {
143
239
  this.log.error('error while sending message', err)
144
240
  }
145
241
  }
146
242
 
147
- sendData (data: Uint8ArrayList): SendResult {
148
- const messageBuf = Message.encode({
149
- message: data.subarray()
150
- })
151
- const prefixedBuf = lengthPrefixed.encode.single(messageBuf)
152
- this._sendMessage(prefixedBuf)
153
-
154
- return {
155
- sentBytes: data.byteLength,
156
- canSendMore: this.channel.bufferedAmount < this.maxBufferedAmount
243
+ async sendData (data: Uint8ArrayList): Promise<void> {
244
+ const bytesTotal = data.byteLength
245
+ // sending messages is an async operation so use a copy of the list as it
246
+ // may be changed beneath us
247
+ data = data.sublist()
248
+
249
+ while (data.byteLength > 0) {
250
+ const toSend = Math.min(data.byteLength, this.maxMessageSize)
251
+ const buf = data.subarray(0, toSend)
252
+ const messageBuf = Message.encode({ message: buf })
253
+ const sendBuf = lengthPrefixed.encode.single(messageBuf)
254
+ this.log.trace('sending %d/%d bytes on channel', buf.byteLength, bytesTotal)
255
+ await this._sendMessage(sendBuf)
256
+
257
+ data.consume(toSend)
157
258
  }
158
- }
159
259
 
160
- sendReset (): void {
161
- this.receivedFinAck.resolve()
260
+ this.log.trace('finished sending data, channel state "%s"', this.channel.readyState)
261
+ }
162
262
 
263
+ async sendReset (): Promise<void> {
163
264
  try {
164
- this._sendFlag(Message.Flag.RESET)
265
+ await this._sendFlag(Message.Flag.RESET)
165
266
  } catch (err) {
166
267
  this.log.error('failed to send reset - %e', err)
167
268
  } finally {
@@ -169,20 +270,38 @@ export class WebRTCStream extends AbstractStream {
169
270
  }
170
271
  }
171
272
 
172
- async sendCloseWrite (options?: AbortOptions): Promise<void> {
173
- if (this.channel.readyState === 'open') {
174
- this._sendFlag(Message.Flag.FIN)
273
+ async sendCloseWrite (options: AbortOptions): Promise<void> {
274
+ if (this.channel.readyState !== 'open') {
275
+ this.receiveFinAck.resolve()
276
+ return
277
+ }
278
+
279
+ const sent = await this._sendFlag(Message.Flag.FIN)
280
+
281
+ if (sent) {
282
+ this.log.trace('awaiting FIN_ACK')
283
+ try {
284
+ await raceSignal(this.receiveFinAck.promise, options?.signal, {
285
+ errorMessage: 'sending close-write was aborted before FIN_ACK was received',
286
+ errorName: 'FinAckNotReceivedError'
287
+ })
288
+ } catch (err) {
289
+ this.log.error('failed to await FIN_ACK', err)
290
+ }
291
+ } else {
292
+ this.log.trace('sending FIN failed, not awaiting FIN_ACK')
175
293
  }
176
294
 
177
- await raceSignal(this.receivedFinAck.promise, options?.signal)
295
+ // if we've attempted to receive a FIN_ACK, do not try again
296
+ this.receiveFinAck.resolve()
178
297
  }
179
298
 
180
- async sendCloseRead (options?: AbortOptions): Promise<void> {
181
- if (this.channel.readyState === 'open') {
182
- this._sendFlag(Message.Flag.STOP_SENDING)
299
+ async sendCloseRead (): Promise<void> {
300
+ if (this.channel.readyState !== 'open') {
301
+ return
183
302
  }
184
303
 
185
- options?.signal?.throwIfAborted()
304
+ await this._sendFlag(Message.Flag.STOP_SENDING)
186
305
  }
187
306
 
188
307
  /**
@@ -196,33 +315,38 @@ export class WebRTCStream extends AbstractStream {
196
315
 
197
316
  if (message.flag === Message.Flag.FIN) {
198
317
  // We should expect no more data from the remote, stop reading
199
- this.onRemoteCloseWrite()
200
- this._sendFlag(Message.Flag.FIN_ACK)
318
+ this.remoteCloseWrite()
319
+
320
+ this.log.trace('sending FIN_ACK')
321
+ void this._sendFlag(Message.Flag.FIN_ACK)
322
+ .catch(err => {
323
+ this.log.error('error sending FIN_ACK immediately', err)
324
+ })
201
325
  }
202
326
 
203
327
  if (message.flag === Message.Flag.RESET) {
204
- this.receivedFinAck.resolve()
205
328
  // Stop reading and writing to the stream immediately
206
- this.onRemoteReset()
329
+ this.reset()
207
330
  }
208
331
 
209
332
  if (message.flag === Message.Flag.STOP_SENDING) {
210
333
  // The remote has stopped reading
211
- this.onRemoteCloseRead()
334
+ this.remoteCloseRead()
212
335
  }
213
336
 
214
337
  if (message.flag === Message.Flag.FIN_ACK) {
215
- this.receivedFinAck.resolve()
338
+ this.log.trace('received FIN_ACK')
339
+ this.receiveFinAck.resolve()
216
340
  }
217
341
  }
218
342
 
219
343
  // ignore data messages if we've closed the readable end already
220
- if (this.readStatus === 'readable' || this.readStatus === 'paused') {
344
+ if (this.readStatus === 'ready') {
221
345
  return message.message
222
346
  }
223
347
  }
224
348
 
225
- private _sendFlag (flag: Message.Flag): boolean {
349
+ private async _sendFlag (flag: Message.Flag): Promise<boolean> {
226
350
  if (this.channel.readyState !== 'open') {
227
351
  // flags can be sent while we or the remote are closing the datachannel so
228
352
  // if the channel isn't open, don't try to send it but return false to let
@@ -236,7 +360,7 @@ export class WebRTCStream extends AbstractStream {
236
360
  const prefixedBuf = lengthPrefixed.encode.single(messageBuf)
237
361
 
238
362
  try {
239
- this._sendMessage(prefixedBuf)
363
+ await this._sendMessage(prefixedBuf, false)
240
364
 
241
365
  return true
242
366
  } catch (err: any) {
@@ -245,14 +369,6 @@ export class WebRTCStream extends AbstractStream {
245
369
 
246
370
  return false
247
371
  }
248
-
249
- sendPause (): void {
250
- // TODO: read backpressure?
251
- }
252
-
253
- sendResume (): void {
254
- // TODO: read backpressure?
255
- }
256
372
  }
257
373
 
258
374
  export interface WebRTCStreamOptions extends DataChannelOptions {
@@ -267,7 +383,12 @@ export interface WebRTCStreamOptions extends DataChannelOptions {
267
383
  /**
268
384
  * The stream direction
269
385
  */
270
- direction: MessageStreamDirection
386
+ direction: Direction
387
+
388
+ /**
389
+ * A callback invoked when the channel ends
390
+ */
391
+ onEnd?(err?: Error | undefined): void
271
392
 
272
393
  /**
273
394
  * The logger to create a scope from
@@ -278,16 +399,15 @@ export interface WebRTCStreamOptions extends DataChannelOptions {
278
399
  * If true the underlying datachannel is being used to perform the noise
279
400
  * handshake during connection establishment
280
401
  */
281
- isHandshake?: boolean
402
+ handshake?: boolean
282
403
  }
283
404
 
284
405
  export function createStream (options: WebRTCStreamOptions): WebRTCStream {
285
- const { channel, direction, isHandshake } = options
406
+ const { channel, direction, handshake } = options
286
407
 
287
408
  return new WebRTCStream({
288
409
  ...options,
289
410
  id: `${channel.id}`,
290
- log: options.log.newScope(`${isHandshake === true ? 'handshake' : direction}:${channel.id}`),
291
- protocol: ''
411
+ log: options.log.newScope(`${handshake === true ? 'handshake' : direction}:${channel.id}`)
292
412
  })
293
413
  }
package/src/util.ts CHANGED
@@ -2,9 +2,8 @@ import { detect } from 'detect-browser'
2
2
  import pDefer from 'p-defer'
3
3
  import pTimeout from 'p-timeout'
4
4
  import { DATA_CHANNEL_DRAIN_TIMEOUT, DEFAULT_ICE_SERVERS, UFRAG_ALPHABET, UFRAG_PREFIX } from './constants.js'
5
+ import type { PeerConnection } from '@ipshipyard/node-datachannel'
5
6
  import type { LoggerOptions } from '@libp2p/interface'
6
- import type { Duplex, Source } from 'it-stream-types'
7
- import type { PeerConnection } from 'node-datachannel'
8
7
 
9
8
  const browser = detect()
10
9
  export const isFirefox = ((browser != null) && browser.name === 'firefox')
@@ -13,26 +12,6 @@ export const nopSource = async function * nop (): AsyncGenerator<Uint8Array, any
13
12
 
14
13
  export const nopSink = async (_: any): Promise<void> => {}
15
14
 
16
- // Duplex that does nothing. Needed to fulfill the interface
17
- export function inertDuplex (): Duplex<any, any, any> {
18
- return {
19
- source: {
20
- [Symbol.asyncIterator] () {
21
- return {
22
- async next () {
23
- // This will never resolve
24
- return new Promise(() => { })
25
- }
26
- }
27
- }
28
- },
29
- sink: async (source: Source<any>) => {
30
- // This will never resolve
31
- return new Promise(() => { })
32
- }
33
- }
34
- }
35
-
36
15
  export function drainAndClose (channel: RTCDataChannel, direction: string, drainTimeout: number = DATA_CHANNEL_DRAIN_TIMEOUT, options: LoggerOptions): void {
37
16
  if (channel.readyState !== 'open') {
38
17
  return
@@ -1 +1 @@
1
- export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from 'node-datachannel/polyfill'
1
+ export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill'
@@ -1,12 +0,0 @@
1
- import type { RTCPeerConnection } from './webrtc/index.js';
2
- import type { MultiaddrConnection } from '@libp2p/interface';
3
- import type { AbstractMultiaddrConnectionInit } from '@libp2p/utils';
4
- export interface RTCPeerConnectionMultiaddrConnectionInit extends Omit<AbstractMultiaddrConnectionInit, 'stream'> {
5
- peerConnection: RTCPeerConnection;
6
- }
7
- /**
8
- * Convert a RTCPeerConnection into a MultiaddrConnection
9
- * https://github.com/libp2p/interface-transport#multiaddrconnection
10
- */
11
- export declare const toMultiaddrConnection: (init: RTCPeerConnectionMultiaddrConnectionInit) => MultiaddrConnection;
12
- //# sourceMappingURL=rtcpeerconnection-to-conn.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rtcpeerconnection-to-conn.d.ts","sourceRoot":"","sources":["../../src/rtcpeerconnection-to-conn.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAgB,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,KAAK,EAAE,+BAA+B,EAAc,MAAM,eAAe,CAAA;AAGhF,MAAM,WAAW,wCAAyC,SAAQ,IAAI,CAAC,+BAA+B,EAAE,QAAQ,CAAC;IAC/G,cAAc,EAAE,iBAAiB,CAAA;CAClC;AA+CD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM,wCAAwC,KAAG,mBAEtF,CAAA"}
@@ -1,43 +0,0 @@
1
- import { AbstractMultiaddrConnection } from '@libp2p/utils';
2
- class RTCPeerConnectionMultiaddrConnection extends AbstractMultiaddrConnection {
3
- peerConnection;
4
- constructor(init) {
5
- super(init);
6
- this.peerConnection = init.peerConnection;
7
- const initialState = init.peerConnection.connectionState;
8
- this.peerConnection.onconnectionstatechange = () => {
9
- this.log.trace('peer connection state change %s initial state %s', this.peerConnection.connectionState, initialState);
10
- if (this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed' || this.peerConnection.connectionState === 'closed') {
11
- // nothing else to do but close the connection
12
- this.onTransportClosed();
13
- }
14
- };
15
- }
16
- sendData(data) {
17
- return {
18
- sentBytes: data.byteLength,
19
- canSendMore: true
20
- };
21
- }
22
- async sendClose(options) {
23
- this.peerConnection.close();
24
- options?.signal?.throwIfAborted();
25
- }
26
- sendReset() {
27
- this.peerConnection.close();
28
- }
29
- sendPause() {
30
- // TODO: readable backpressure?
31
- }
32
- sendResume() {
33
- // TODO: readable backpressure?
34
- }
35
- }
36
- /**
37
- * Convert a RTCPeerConnection into a MultiaddrConnection
38
- * https://github.com/libp2p/interface-transport#multiaddrconnection
39
- */
40
- export const toMultiaddrConnection = (init) => {
41
- return new RTCPeerConnectionMultiaddrConnection(init);
42
- };
43
- //# sourceMappingURL=rtcpeerconnection-to-conn.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rtcpeerconnection-to-conn.js","sourceRoot":"","sources":["../../src/rtcpeerconnection-to-conn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAU3D,MAAM,oCAAqC,SAAQ,2BAA2B;IACpE,cAAc,CAAmB;IAEzC,YAAa,IAA8C;QACzD,KAAK,CAAC,IAAI,CAAC,CAAA;QAEX,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QAEzC,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAA;QAExD,IAAI,CAAC,cAAc,CAAC,uBAAuB,GAAG,GAAG,EAAE;YACjD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kDAAkD,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,CAAA;YAErH,IAAI,IAAI,CAAC,cAAc,CAAC,eAAe,KAAK,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,eAAe,KAAK,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;gBACnK,8CAA8C;gBAC9C,IAAI,CAAC,iBAAiB,EAAE,CAAA;YAC1B,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAED,QAAQ,CAAE,IAAoB;QAC5B,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,UAAU;YAC1B,WAAW,EAAE,IAAI;SAClB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAE,OAAsB;QACrC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IACnC,CAAC;IAED,SAAS;QACP,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;IAC7B,CAAC;IAED,SAAS;QACP,+BAA+B;IACjC,CAAC;IAED,UAAU;QACR,+BAA+B;IACjC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,IAA8C,EAAuB,EAAE;IAC3G,OAAO,IAAI,oCAAoC,CAAC,IAAI,CAAC,CAAA;AACvD,CAAC,CAAA"}
@@ -1,62 +0,0 @@
1
- import { AbstractMultiaddrConnection } from '@libp2p/utils'
2
- import type { RTCPeerConnection } from './webrtc/index.js'
3
- import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface'
4
- import type { AbstractMultiaddrConnectionInit, SendResult } from '@libp2p/utils'
5
- import type { Uint8ArrayList } from 'uint8arraylist'
6
-
7
- export interface RTCPeerConnectionMultiaddrConnectionInit extends Omit<AbstractMultiaddrConnectionInit, 'stream'> {
8
- peerConnection: RTCPeerConnection
9
- }
10
-
11
- class RTCPeerConnectionMultiaddrConnection extends AbstractMultiaddrConnection {
12
- private peerConnection: RTCPeerConnection
13
-
14
- constructor (init: RTCPeerConnectionMultiaddrConnectionInit) {
15
- super(init)
16
-
17
- this.peerConnection = init.peerConnection
18
-
19
- const initialState = init.peerConnection.connectionState
20
-
21
- this.peerConnection.onconnectionstatechange = () => {
22
- this.log.trace('peer connection state change %s initial state %s', this.peerConnection.connectionState, initialState)
23
-
24
- if (this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed' || this.peerConnection.connectionState === 'closed') {
25
- // nothing else to do but close the connection
26
- this.onTransportClosed()
27
- }
28
- }
29
- }
30
-
31
- sendData (data: Uint8ArrayList): SendResult {
32
- return {
33
- sentBytes: data.byteLength,
34
- canSendMore: true
35
- }
36
- }
37
-
38
- async sendClose (options?: AbortOptions): Promise<void> {
39
- this.peerConnection.close()
40
- options?.signal?.throwIfAborted()
41
- }
42
-
43
- sendReset (): void {
44
- this.peerConnection.close()
45
- }
46
-
47
- sendPause (): void {
48
- // TODO: readable backpressure?
49
- }
50
-
51
- sendResume (): void {
52
- // TODO: readable backpressure?
53
- }
54
- }
55
-
56
- /**
57
- * Convert a RTCPeerConnection into a MultiaddrConnection
58
- * https://github.com/libp2p/interface-transport#multiaddrconnection
59
- */
60
- export const toMultiaddrConnection = (init: RTCPeerConnectionMultiaddrConnectionInit): MultiaddrConnection => {
61
- return new RTCPeerConnectionMultiaddrConnection(init)
62
- }