@libp2p/webrtc 5.2.23 → 5.2.24-0f07e3df5
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.
- package/README.md +10 -20
- package/dist/index.min.js +18 -18
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +0 -23
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +0 -23
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +12 -22
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -22
- package/dist/src/index.js.map +1 -1
- package/dist/src/muxer.d.ts +14 -46
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +32 -135
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts +2 -3
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +23 -5
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts +4 -4
- package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.js +10 -6
- package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +2 -2
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +30 -15
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +3 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +15 -3
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +21 -15
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +3 -2
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/connect.js +18 -15
- package/dist/src/private-to-public/utils/connect.js.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +4 -4
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +13 -2
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/sdp.js +25 -13
- package/dist/src/private-to-public/utils/sdp.js.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
- package/dist/src/rtcpeerconnection-to-conn.d.ts +12 -0
- package/dist/src/rtcpeerconnection-to-conn.d.ts.map +1 -0
- package/dist/src/rtcpeerconnection-to-conn.js +43 -0
- package/dist/src/rtcpeerconnection-to-conn.js.map +1 -0
- package/dist/src/stream.d.ts +16 -26
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +65 -167
- package/dist/src/stream.js.map +1 -1
- package/dist/src/util.d.ts +3 -1
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +19 -0
- package/dist/src/util.js.map +1 -1
- package/dist/src/webrtc/index.d.ts +1 -1
- package/dist/src/webrtc/index.d.ts.map +1 -1
- package/dist/src/webrtc/index.js +1 -1
- package/dist/src/webrtc/index.js.map +1 -1
- package/package.json +26 -29
- package/src/constants.ts +0 -28
- package/src/index.ts +12 -22
- package/src/muxer.ts +43 -166
- package/src/private-to-private/initiate-connection.ts +30 -8
- package/src/private-to-private/signaling-stream-handler.ts +12 -9
- package/src/private-to-private/transport.ts +33 -17
- package/src/private-to-private/util.ts +21 -4
- package/src/private-to-public/listener.ts +22 -15
- package/src/private-to-public/transport.ts +3 -2
- package/src/private-to-public/utils/connect.ts +19 -16
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +16 -4
- package/src/private-to-public/utils/sdp.ts +29 -13
- package/src/private-to-public/utils/stun-listener.ts +1 -1
- package/src/rtcpeerconnection-to-conn.ts +62 -0
- package/src/stream.ts +78 -195
- package/src/util.ts +22 -1
- package/src/webrtc/index.ts +1 -1
- package/dist/src/maconn.d.ts +0 -58
- package/dist/src/maconn.d.ts.map +0 -1
- package/dist/src/maconn.js +0 -56
- package/dist/src/maconn.js.map +0 -1
- package/dist/typedoc-urls.json +0 -14
- package/src/maconn.ts +0 -101
package/src/stream.ts
CHANGED
@@ -1,20 +1,15 @@
|
|
1
|
-
import { StreamStateError
|
2
|
-
import { AbstractStream } from '@libp2p/utils
|
3
|
-
import { anySignal } from 'any-signal'
|
1
|
+
import { StreamStateError } from '@libp2p/interface'
|
2
|
+
import { AbstractStream } from '@libp2p/utils'
|
4
3
|
import * as lengthPrefixed from 'it-length-prefixed'
|
5
4
|
import { pushable } from 'it-pushable'
|
6
|
-
import pDefer from 'p-defer'
|
7
|
-
import pTimeout from 'p-timeout'
|
8
|
-
import { raceEvent } from 'race-event'
|
9
5
|
import { raceSignal } from 'race-signal'
|
10
6
|
import { Uint8ArrayList } from 'uint8arraylist'
|
11
|
-
import {
|
7
|
+
import { MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, PROTOBUF_OVERHEAD } from './constants.js'
|
12
8
|
import { Message } from './private-to-public/pb/message.js'
|
13
9
|
import type { DataChannelOptions } from './index.js'
|
14
|
-
import type { AbortOptions,
|
15
|
-
import type { AbstractStreamInit } from '@libp2p/utils
|
10
|
+
import type { AbortOptions, MessageStreamDirection, Logger } from '@libp2p/interface'
|
11
|
+
import type { AbstractStreamInit, SendResult } from '@libp2p/utils'
|
16
12
|
import type { Pushable } from 'it-pushable'
|
17
|
-
import type { DeferredPromise } from 'p-defer'
|
18
13
|
|
19
14
|
export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions {
|
20
15
|
/**
|
@@ -25,7 +20,7 @@ export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions
|
|
25
20
|
*/
|
26
21
|
channel: RTCDataChannel
|
27
22
|
|
28
|
-
|
23
|
+
log: Logger
|
29
24
|
}
|
30
25
|
|
31
26
|
export class WebRTCStream extends AbstractStream {
|
@@ -39,76 +34,24 @@ export class WebRTCStream extends AbstractStream {
|
|
39
34
|
* and then the protobuf decoder.
|
40
35
|
*/
|
41
36
|
private readonly incomingData: Pushable<Uint8Array>
|
42
|
-
|
43
37
|
private readonly maxBufferedAmount: number
|
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
|
38
|
+
private readonly receivedFinAck: PromiseWithResolvers<void>
|
59
39
|
|
60
40
|
constructor (init: WebRTCStreamInit) {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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)
|
41
|
+
super({
|
42
|
+
...init,
|
43
|
+
maxMessageSize: (init.maxMessageSize ?? MAX_MESSAGE_SIZE) - PROTOBUF_OVERHEAD
|
44
|
+
})
|
96
45
|
|
97
46
|
this.channel = init.channel
|
98
47
|
this.channel.binaryType = 'arraybuffer'
|
99
48
|
this.incomingData = pushable<Uint8Array>()
|
100
|
-
this.bufferedAmountLowEventTimeout = init.bufferedAmountLowEventTimeout ?? BUFFERED_AMOUNT_LOW_TIMEOUT
|
101
49
|
this.maxBufferedAmount = init.maxBufferedAmount ?? MAX_BUFFERED_AMOUNT
|
102
|
-
this.
|
103
|
-
this.receiveFinAck = pDefer()
|
104
|
-
this.finAckTimeout = init.closeTimeout ?? FIN_ACK_TIMEOUT
|
105
|
-
this.openTimeout = init.openTimeout ?? OPEN_TIMEOUT
|
106
|
-
this.closeController = new AbortController()
|
50
|
+
this.receivedFinAck = Promise.withResolvers()
|
107
51
|
|
108
52
|
// set up initial state
|
109
53
|
switch (this.channel.readyState) {
|
110
54
|
case 'open':
|
111
|
-
this.timeline.open = new Date().getTime()
|
112
55
|
break
|
113
56
|
|
114
57
|
case 'closed':
|
@@ -127,31 +70,16 @@ export class WebRTCStream extends AbstractStream {
|
|
127
70
|
}
|
128
71
|
|
129
72
|
// handle RTCDataChannel events
|
130
|
-
this.channel.onopen = (_evt) => {
|
131
|
-
this.timeline.open = new Date().getTime()
|
132
|
-
}
|
133
|
-
|
134
73
|
this.channel.onclose = (_evt) => {
|
135
74
|
this.log.trace('received onclose event')
|
136
75
|
|
137
|
-
|
138
|
-
this.
|
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
|
-
})
|
76
|
+
this.onRemoteCloseWrite()
|
77
|
+
this.onTransportClosed()
|
147
78
|
}
|
148
79
|
|
149
80
|
this.channel.onerror = (evt) => {
|
150
81
|
this.log.trace('received onerror event')
|
151
82
|
|
152
|
-
// stop any in-progress writes
|
153
|
-
this.closeController.abort()
|
154
|
-
|
155
83
|
const err = (evt as RTCErrorEvent).error
|
156
84
|
this.abort(err)
|
157
85
|
}
|
@@ -166,6 +94,12 @@ export class WebRTCStream extends AbstractStream {
|
|
166
94
|
this.incomingData.push(new Uint8Array(data, 0, data.byteLength))
|
167
95
|
}
|
168
96
|
|
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
|
+
|
169
103
|
const self = this
|
170
104
|
|
171
105
|
// pipe framed protobuf messages through a length prefixed decoder, and
|
@@ -175,94 +109,59 @@ export class WebRTCStream extends AbstractStream {
|
|
175
109
|
const message = self.processIncomingProtobuf(buf)
|
176
110
|
|
177
111
|
if (message != null) {
|
178
|
-
self.
|
112
|
+
self.onData(new Uint8ArrayList(message))
|
179
113
|
}
|
180
114
|
}
|
181
115
|
})
|
182
116
|
.catch(err => {
|
183
117
|
this.log.error('error processing incoming data channel messages', err)
|
184
118
|
})
|
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)
|
185
125
|
}
|
186
126
|
|
187
127
|
sendNewStream (): void {
|
188
128
|
// opening new streams is handled by WebRTC so this is a noop
|
189
129
|
}
|
190
130
|
|
191
|
-
|
131
|
+
_sendMessage (data: Uint8ArrayList): void {
|
192
132
|
if (this.channel.readyState === 'closed' || this.channel.readyState === 'closing') {
|
193
133
|
throw new StreamStateError(`Invalid datachannel state - ${this.channel.readyState}`)
|
194
134
|
}
|
195
135
|
|
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
|
-
|
234
136
|
try {
|
235
137
|
this.log.trace('sending message, channel state "%s"', this.channel.readyState)
|
236
138
|
// send message without copying data
|
237
|
-
|
139
|
+
for (const buf of data) {
|
140
|
+
this.channel.send(buf)
|
141
|
+
}
|
238
142
|
} catch (err: any) {
|
239
143
|
this.log.error('error while sending message', err)
|
240
144
|
}
|
241
145
|
}
|
242
146
|
|
243
|
-
|
244
|
-
const
|
245
|
-
|
246
|
-
|
247
|
-
|
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)
|
258
|
-
}
|
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)
|
259
153
|
|
260
|
-
|
154
|
+
return {
|
155
|
+
sentBytes: data.byteLength,
|
156
|
+
canSendMore: this.channel.bufferedAmount < this.maxBufferedAmount
|
157
|
+
}
|
261
158
|
}
|
262
159
|
|
263
|
-
|
160
|
+
sendReset (): void {
|
161
|
+
this.receivedFinAck.resolve()
|
162
|
+
|
264
163
|
try {
|
265
|
-
|
164
|
+
this._sendFlag(Message.Flag.RESET)
|
266
165
|
} catch (err) {
|
267
166
|
this.log.error('failed to send reset - %e', err)
|
268
167
|
} finally {
|
@@ -270,38 +169,20 @@ export class WebRTCStream extends AbstractStream {
|
|
270
169
|
}
|
271
170
|
}
|
272
171
|
|
273
|
-
async sendCloseWrite (options
|
274
|
-
if (this.channel.readyState
|
275
|
-
this.
|
276
|
-
return
|
172
|
+
async sendCloseWrite (options?: AbortOptions): Promise<void> {
|
173
|
+
if (this.channel.readyState === 'open') {
|
174
|
+
this._sendFlag(Message.Flag.FIN)
|
277
175
|
}
|
278
176
|
|
279
|
-
|
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')
|
293
|
-
}
|
294
|
-
|
295
|
-
// if we've attempted to receive a FIN_ACK, do not try again
|
296
|
-
this.receiveFinAck.resolve()
|
177
|
+
await raceSignal(this.receivedFinAck.promise, options?.signal)
|
297
178
|
}
|
298
179
|
|
299
|
-
async sendCloseRead (): Promise<void> {
|
300
|
-
if (this.channel.readyState
|
301
|
-
|
180
|
+
async sendCloseRead (options?: AbortOptions): Promise<void> {
|
181
|
+
if (this.channel.readyState === 'open') {
|
182
|
+
this._sendFlag(Message.Flag.STOP_SENDING)
|
302
183
|
}
|
303
184
|
|
304
|
-
|
185
|
+
options?.signal?.throwIfAborted()
|
305
186
|
}
|
306
187
|
|
307
188
|
/**
|
@@ -315,38 +196,33 @@ export class WebRTCStream extends AbstractStream {
|
|
315
196
|
|
316
197
|
if (message.flag === Message.Flag.FIN) {
|
317
198
|
// We should expect no more data from the remote, stop reading
|
318
|
-
this.
|
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
|
-
})
|
199
|
+
this.onRemoteCloseWrite()
|
200
|
+
this._sendFlag(Message.Flag.FIN_ACK)
|
325
201
|
}
|
326
202
|
|
327
203
|
if (message.flag === Message.Flag.RESET) {
|
204
|
+
this.receivedFinAck.resolve()
|
328
205
|
// Stop reading and writing to the stream immediately
|
329
|
-
this.
|
206
|
+
this.onRemoteReset()
|
330
207
|
}
|
331
208
|
|
332
209
|
if (message.flag === Message.Flag.STOP_SENDING) {
|
333
210
|
// The remote has stopped reading
|
334
|
-
this.
|
211
|
+
this.onRemoteCloseRead()
|
335
212
|
}
|
336
213
|
|
337
214
|
if (message.flag === Message.Flag.FIN_ACK) {
|
338
|
-
this.
|
339
|
-
this.receiveFinAck.resolve()
|
215
|
+
this.receivedFinAck.resolve()
|
340
216
|
}
|
341
217
|
}
|
342
218
|
|
343
219
|
// ignore data messages if we've closed the readable end already
|
344
|
-
if (this.readStatus === '
|
220
|
+
if (this.readStatus === 'readable' || this.readStatus === 'paused') {
|
345
221
|
return message.message
|
346
222
|
}
|
347
223
|
}
|
348
224
|
|
349
|
-
private
|
225
|
+
private _sendFlag (flag: Message.Flag): boolean {
|
350
226
|
if (this.channel.readyState !== 'open') {
|
351
227
|
// flags can be sent while we or the remote are closing the datachannel so
|
352
228
|
// if the channel isn't open, don't try to send it but return false to let
|
@@ -360,7 +236,7 @@ export class WebRTCStream extends AbstractStream {
|
|
360
236
|
const prefixedBuf = lengthPrefixed.encode.single(messageBuf)
|
361
237
|
|
362
238
|
try {
|
363
|
-
|
239
|
+
this._sendMessage(prefixedBuf)
|
364
240
|
|
365
241
|
return true
|
366
242
|
} catch (err: any) {
|
@@ -369,6 +245,14 @@ export class WebRTCStream extends AbstractStream {
|
|
369
245
|
|
370
246
|
return false
|
371
247
|
}
|
248
|
+
|
249
|
+
sendPause (): void {
|
250
|
+
// TODO: read backpressure?
|
251
|
+
}
|
252
|
+
|
253
|
+
sendResume (): void {
|
254
|
+
// TODO: read backpressure?
|
255
|
+
}
|
372
256
|
}
|
373
257
|
|
374
258
|
export interface WebRTCStreamOptions extends DataChannelOptions {
|
@@ -383,28 +267,27 @@ export interface WebRTCStreamOptions extends DataChannelOptions {
|
|
383
267
|
/**
|
384
268
|
* The stream direction
|
385
269
|
*/
|
386
|
-
direction:
|
270
|
+
direction: MessageStreamDirection
|
387
271
|
|
388
272
|
/**
|
389
|
-
*
|
273
|
+
* The logger to create a scope from
|
390
274
|
*/
|
391
|
-
|
392
|
-
|
393
|
-
logger: ComponentLogger
|
275
|
+
log: Logger
|
394
276
|
|
395
277
|
/**
|
396
278
|
* If true the underlying datachannel is being used to perform the noise
|
397
279
|
* handshake during connection establishment
|
398
280
|
*/
|
399
|
-
|
281
|
+
isHandshake?: boolean
|
400
282
|
}
|
401
283
|
|
402
284
|
export function createStream (options: WebRTCStreamOptions): WebRTCStream {
|
403
|
-
const { channel, direction,
|
285
|
+
const { channel, direction, isHandshake } = options
|
404
286
|
|
405
287
|
return new WebRTCStream({
|
288
|
+
...options,
|
406
289
|
id: `${channel.id}`,
|
407
|
-
log: options.
|
408
|
-
|
290
|
+
log: options.log.newScope(`${isHandshake === true ? 'handshake' : direction}:${channel.id}`),
|
291
|
+
protocol: ''
|
409
292
|
})
|
410
293
|
}
|
package/src/util.ts
CHANGED
@@ -2,8 +2,9 @@ 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'
|
6
5
|
import type { LoggerOptions } from '@libp2p/interface'
|
6
|
+
import type { Duplex, Source } from 'it-stream-types'
|
7
|
+
import type { PeerConnection } from 'node-datachannel'
|
7
8
|
|
8
9
|
const browser = detect()
|
9
10
|
export const isFirefox = ((browser != null) && browser.name === 'firefox')
|
@@ -12,6 +13,26 @@ export const nopSource = async function * nop (): AsyncGenerator<Uint8Array, any
|
|
12
13
|
|
13
14
|
export const nopSink = async (_: any): Promise<void> => {}
|
14
15
|
|
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
|
+
|
15
36
|
export function drainAndClose (channel: RTCDataChannel, direction: string, drainTimeout: number = DATA_CHANNEL_DRAIN_TIMEOUT, options: LoggerOptions): void {
|
16
37
|
if (channel.readyState !== 'open') {
|
17
38
|
return
|
package/src/webrtc/index.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from '
|
1
|
+
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from 'node-datachannel/polyfill'
|
package/dist/src/maconn.d.ts
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
import type { RTCPeerConnection } from './webrtc/index.js';
|
2
|
-
import type { ComponentLogger, Logger, MultiaddrConnection, MultiaddrConnectionTimeline, CounterGroup } from '@libp2p/interface';
|
3
|
-
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr';
|
4
|
-
import type { Source, Sink } from 'it-stream-types';
|
5
|
-
import type { Uint8ArrayList } from 'uint8arraylist';
|
6
|
-
interface WebRTCMultiaddrConnectionInit {
|
7
|
-
/**
|
8
|
-
* WebRTC Peer Connection
|
9
|
-
*/
|
10
|
-
peerConnection: RTCPeerConnection;
|
11
|
-
/**
|
12
|
-
* The multiaddr address used to communicate with the remote peer
|
13
|
-
*/
|
14
|
-
remoteAddr: Multiaddr;
|
15
|
-
/**
|
16
|
-
* Holds the relevant events timestamps of the connection
|
17
|
-
*/
|
18
|
-
timeline: MultiaddrConnectionTimeline;
|
19
|
-
/**
|
20
|
-
* Optional metrics counter group for this connection
|
21
|
-
*/
|
22
|
-
metrics?: CounterGroup;
|
23
|
-
}
|
24
|
-
export interface WebRTCMultiaddrConnectionComponents {
|
25
|
-
logger: ComponentLogger;
|
26
|
-
}
|
27
|
-
export declare class WebRTCMultiaddrConnection implements MultiaddrConnection {
|
28
|
-
readonly log: Logger;
|
29
|
-
/**
|
30
|
-
* WebRTC Peer Connection
|
31
|
-
*/
|
32
|
-
readonly peerConnection: RTCPeerConnection;
|
33
|
-
/**
|
34
|
-
* The multiaddr address used to communicate with the remote peer
|
35
|
-
*/
|
36
|
-
remoteAddr: Multiaddr;
|
37
|
-
/**
|
38
|
-
* Holds the life cycle times of the connection
|
39
|
-
*/
|
40
|
-
timeline: MultiaddrConnectionTimeline;
|
41
|
-
/**
|
42
|
-
* Optional metrics counter group for this connection
|
43
|
-
*/
|
44
|
-
metrics?: CounterGroup;
|
45
|
-
/**
|
46
|
-
* The stream source, a no-op as the transport natively supports multiplexing
|
47
|
-
*/
|
48
|
-
source: AsyncGenerator<Uint8Array, any, unknown>;
|
49
|
-
/**
|
50
|
-
* The stream destination, a no-op as the transport natively supports multiplexing
|
51
|
-
*/
|
52
|
-
sink: Sink<Source<Uint8Array | Uint8ArrayList>, Promise<void>>;
|
53
|
-
constructor(components: WebRTCMultiaddrConnectionComponents, init: WebRTCMultiaddrConnectionInit);
|
54
|
-
close(options?: AbortOptions): Promise<void>;
|
55
|
-
abort(err: Error): void;
|
56
|
-
}
|
57
|
-
export {};
|
58
|
-
//# sourceMappingURL=maconn.d.ts.map
|
package/dist/src/maconn.d.ts.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"maconn.d.ts","sourceRoot":"","sources":["../../src/maconn.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChI,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,UAAU,6BAA6B;IACrC;;OAEG;IACH,cAAc,EAAE,iBAAiB,CAAA;IAEjC;;OAEG;IACH,UAAU,EAAE,SAAS,CAAA;IAErB;;OAEG;IACH,QAAQ,EAAE,2BAA2B,CAAA;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB;AAED,MAAM,WAAW,mCAAmC;IAClD,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,qBAAa,yBAA0B,YAAW,mBAAmB;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAA;IAE1C;;OAEG;IACH,UAAU,EAAE,SAAS,CAAA;IAErB;;OAEG;IACH,QAAQ,EAAE,2BAA2B,CAAA;IAErC;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IAEtB;;OAEG;IACH,MAAM,EAAE,cAAc,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,CAAc;IAE9D;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,cAAc,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAU;gBAE3D,UAAU,EAAE,mCAAmC,EAAE,IAAI,EAAE,6BAA6B;IAmB3F,KAAK,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAQnD,KAAK,CAAE,GAAG,EAAE,KAAK,GAAG,IAAI;CAOzB"}
|
package/dist/src/maconn.js
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
import { nopSink, nopSource } from './util.js';
|
2
|
-
export class WebRTCMultiaddrConnection {
|
3
|
-
log;
|
4
|
-
/**
|
5
|
-
* WebRTC Peer Connection
|
6
|
-
*/
|
7
|
-
peerConnection;
|
8
|
-
/**
|
9
|
-
* The multiaddr address used to communicate with the remote peer
|
10
|
-
*/
|
11
|
-
remoteAddr;
|
12
|
-
/**
|
13
|
-
* Holds the life cycle times of the connection
|
14
|
-
*/
|
15
|
-
timeline;
|
16
|
-
/**
|
17
|
-
* Optional metrics counter group for this connection
|
18
|
-
*/
|
19
|
-
metrics;
|
20
|
-
/**
|
21
|
-
* The stream source, a no-op as the transport natively supports multiplexing
|
22
|
-
*/
|
23
|
-
source = nopSource();
|
24
|
-
/**
|
25
|
-
* The stream destination, a no-op as the transport natively supports multiplexing
|
26
|
-
*/
|
27
|
-
sink = nopSink;
|
28
|
-
constructor(components, init) {
|
29
|
-
this.log = components.logger.forComponent('libp2p:webrtc:maconn');
|
30
|
-
this.remoteAddr = init.remoteAddr;
|
31
|
-
this.timeline = init.timeline;
|
32
|
-
this.peerConnection = init.peerConnection;
|
33
|
-
const peerConnection = this.peerConnection;
|
34
|
-
const initialState = peerConnection.connectionState;
|
35
|
-
this.peerConnection.onconnectionstatechange = () => {
|
36
|
-
this.log.trace('peer connection state change', peerConnection.connectionState, 'initial state', initialState);
|
37
|
-
if (peerConnection.connectionState === 'disconnected' || peerConnection.connectionState === 'failed' || peerConnection.connectionState === 'closed') {
|
38
|
-
// nothing else to do but close the connection
|
39
|
-
this.timeline.close = Date.now();
|
40
|
-
}
|
41
|
-
};
|
42
|
-
}
|
43
|
-
async close(options) {
|
44
|
-
this.log.trace('closing connection');
|
45
|
-
this.peerConnection.close();
|
46
|
-
this.timeline.close = Date.now();
|
47
|
-
this.metrics?.increment({ close: true });
|
48
|
-
}
|
49
|
-
abort(err) {
|
50
|
-
this.log.error('closing connection due to error', err);
|
51
|
-
this.peerConnection.close();
|
52
|
-
this.timeline.close = Date.now();
|
53
|
-
this.metrics?.increment({ abort: true });
|
54
|
-
}
|
55
|
-
}
|
56
|
-
//# sourceMappingURL=maconn.js.map
|
package/dist/src/maconn.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"maconn.js","sourceRoot":"","sources":["../../src/maconn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAiC9C,MAAM,OAAO,yBAAyB;IAC3B,GAAG,CAAQ;IAEpB;;OAEG;IACM,cAAc,CAAmB;IAE1C;;OAEG;IACH,UAAU,CAAW;IAErB;;OAEG;IACH,QAAQ,CAA6B;IAErC;;OAEG;IACH,OAAO,CAAe;IAEtB;;OAEG;IACH,MAAM,GAA6C,SAAS,EAAE,CAAA;IAE9D;;OAEG;IACH,IAAI,GAA6D,OAAO,CAAA;IAExE,YAAa,UAA+C,EAAE,IAAmC;QAC/F,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAA;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QAEzC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QAC1C,MAAM,YAAY,GAAG,cAAc,CAAC,eAAe,CAAA;QAEnD,IAAI,CAAC,cAAc,CAAC,uBAAuB,GAAG,GAAG,EAAE;YACjD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,EAAE,cAAc,CAAC,eAAe,EAAE,eAAe,EAAE,YAAY,CAAC,CAAA;YAE7G,IAAI,cAAc,CAAC,eAAe,KAAK,cAAc,IAAI,cAAc,CAAC,eAAe,KAAK,QAAQ,IAAI,cAAc,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;gBACpJ,8CAA8C;gBAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAClC,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAE,OAAsB;QACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;QAEpC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAChC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,CAAE,GAAU;QACf,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAA;QAEtD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAChC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,CAAC;CACF"}
|
package/dist/typedoc-urls.json
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
3
|
-
".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
4
|
-
"TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
5
|
-
".:TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
6
|
-
"WebRTCDirectTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCDirectTransportComponents.html",
|
7
|
-
"WebRTCTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportComponents.html",
|
8
|
-
"WebRTCTransportDirectInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportDirectInit.html",
|
9
|
-
"WebRTCTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportInit.html",
|
10
|
-
"webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
11
|
-
".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
12
|
-
"webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
|
13
|
-
".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
|
14
|
-
}
|