@libp2p/webrtc 4.0.8 → 4.0.9-341581166

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.
@@ -1,10 +1,9 @@
1
1
  import { CodeError } from '@libp2p/interface'
2
2
  import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
3
3
  import { pbStream } from 'it-protobuf-stream'
4
- import pDefer, { type DeferredPromise } from 'p-defer'
5
4
  import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
6
5
  import { Message } from './pb/message.js'
7
- import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
6
+ import { readCandidatesUntilConnected } from './util.js'
8
7
  import type { Logger } from '@libp2p/interface'
9
8
  import type { IncomingStreamData } from '@libp2p/interface-internal'
10
9
 
@@ -20,41 +19,27 @@ export async function handleIncomingStream ({ peerConnection, stream, signal, co
20
19
  const messageStream = pbStream(stream).pb(Message)
21
20
 
22
21
  try {
23
- const connectedPromise: DeferredPromise<void> = pDefer()
24
- const answerSentPromise: DeferredPromise<void> = pDefer()
25
-
26
- signal.onabort = () => {
27
- connectedPromise.reject(new CodeError('Timed out while trying to connect', 'ERR_TIMEOUT'))
28
- }
29
-
30
22
  // candidate callbacks
31
23
  peerConnection.onicecandidate = ({ candidate }) => {
32
- answerSentPromise.promise.then(
33
- async () => {
34
- // a null candidate means end-of-candidates, an empty string candidate
35
- // means end-of-candidates for this generation, otherwise this should
36
- // be a valid candidate object
37
- // see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
38
- const data = JSON.stringify(candidate?.toJSON() ?? null)
39
-
40
- log.trace('recipient sending ICE candidate %s', data)
41
-
42
- await messageStream.write({
43
- type: Message.Type.ICE_CANDIDATE,
44
- data
45
- }, {
46
- signal
47
- })
48
- },
49
- (err) => {
50
- log.error('cannot set candidate since sending answer failed', err)
51
- connectedPromise.reject(err)
52
- }
53
- )
24
+ // a null candidate means end-of-candidates, an empty string candidate
25
+ // means end-of-candidates for this generation, otherwise this should
26
+ // be a valid candidate object
27
+ // see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
28
+ const data = JSON.stringify(candidate?.toJSON() ?? null)
29
+
30
+ log.trace('recipient sending ICE candidate %s', data)
31
+
32
+ messageStream.write({
33
+ type: Message.Type.ICE_CANDIDATE,
34
+ data
35
+ }, {
36
+ signal
37
+ })
38
+ .catch(err => {
39
+ log.error('error sending ICE candidate', err)
40
+ })
54
41
  }
55
42
 
56
- resolveOnConnected(peerConnection, connectedPromise)
57
-
58
43
  // read an SDP offer
59
44
  const pbOffer = await messageStream.read({
60
45
  signal
@@ -79,7 +64,6 @@ export async function handleIncomingStream ({ peerConnection, stream, signal, co
79
64
  // create and write an SDP answer
80
65
  const answer = await peerConnection.createAnswer().catch(err => {
81
66
  log.error('could not execute createAnswer', err)
82
- answerSentPromise.reject(err)
83
67
  throw new CodeError('Failed to create answer', 'ERR_SDP_HANDSHAKE_FAILED')
84
68
  })
85
69
 
@@ -92,25 +76,17 @@ export async function handleIncomingStream ({ peerConnection, stream, signal, co
92
76
 
93
77
  await peerConnection.setLocalDescription(answer).catch(err => {
94
78
  log.error('could not execute setLocalDescription', err)
95
- answerSentPromise.reject(err)
96
79
  throw new CodeError('Failed to set localDescription', 'ERR_SDP_HANDSHAKE_FAILED')
97
80
  })
98
81
 
99
- answerSentPromise.resolve()
100
-
101
82
  log.trace('recipient read candidates until connected')
102
83
 
103
84
  // wait until candidates are connected
104
- await readCandidatesUntilConnected(connectedPromise, peerConnection, messageStream, {
85
+ await readCandidatesUntilConnected(peerConnection, messageStream, {
105
86
  direction: 'recipient',
106
87
  signal,
107
88
  log
108
89
  })
109
-
110
- log.trace('recipient connected, closing signaling stream')
111
- await messageStream.unwrap().unwrap().close({
112
- signal
113
- })
114
90
  } catch (err: any) {
115
91
  if (peerConnection.connectionState !== 'connected') {
116
92
  log.error('error while handling signaling stream from peer %a', connection.remoteAddr, err)
@@ -1,4 +1,4 @@
1
- import { CodeError } from '@libp2p/interface'
1
+ import { CodeError, setMaxListeners } from '@libp2p/interface'
2
2
  import { type CreateListenerOptions, type DialOptions, transportSymbol, type Transport, type Listener, type Upgrader, type ComponentLogger, type Logger, type Connection, type PeerId, type CounterGroup, type Metrics, type Startable } from '@libp2p/interface'
3
3
  import { peerIdFromString } from '@libp2p/peer-id'
4
4
  import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
@@ -56,6 +56,7 @@ export class WebRTCTransport implements Transport, Startable {
56
56
  ) {
57
57
  this.log = components.logger.forComponent('libp2p:webrtc')
58
58
  this.shutdownController = new AbortController()
59
+ setMaxListeners(Infinity, this.shutdownController.signal)
59
60
 
60
61
  if (components.metrics != null) {
61
62
  this.metrics = {
@@ -1,6 +1,5 @@
1
1
  import { CodeError } from '@libp2p/interface'
2
- import { closeSource } from '@libp2p/utils/close-source'
3
- import { anySignal } from 'any-signal'
2
+ import pDefer from 'p-defer'
4
3
  import { isFirefox } from '../util.js'
5
4
  import { RTCIceCandidate } from '../webrtc/index.js'
6
5
  import { Message } from './pb/message.js'
@@ -12,32 +11,19 @@ export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions {
12
11
  direction: string
13
12
  }
14
13
 
15
- export const readCandidatesUntilConnected = async (connectedPromise: DeferredPromise<void>, pc: RTCPeerConnection, stream: MessageStream<Message, Stream>, options: ReadCandidatesOptions): Promise<void> => {
16
- // if we connect, stop trying to read from the stream
17
- const controller = new AbortController()
18
- connectedPromise.promise.then(() => {
19
- controller.abort()
20
- }, () => {
21
- controller.abort()
22
- })
23
-
24
- const signal = anySignal([
25
- controller.signal,
26
- options.signal
27
- ])
28
-
29
- const abortListener = (): void => {
30
- closeSource(stream.unwrap().unwrap().source, options.log)
31
- }
32
-
33
- signal.addEventListener('abort', abortListener)
34
-
14
+ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream: MessageStream<Message, Stream>, options: ReadCandidatesOptions): Promise<void> => {
35
15
  try {
16
+ const connectedPromise: DeferredPromise<void> = pDefer()
17
+ resolveOnConnected(pc, connectedPromise)
18
+
36
19
  // read candidates until we are connected or we reach the end of the stream
37
20
  while (true) {
21
+ // if we connect, stop trying to read from the stream
38
22
  const message = await Promise.race([
39
23
  connectedPromise.promise,
40
- stream.read()
24
+ stream.read({
25
+ signal: options.signal
26
+ })
41
27
  ])
42
28
 
43
29
  // stream ended or we became connected
@@ -72,15 +58,20 @@ export const readCandidatesUntilConnected = async (connectedPromise: DeferredPro
72
58
  }
73
59
  } catch (err) {
74
60
  options.log.error('%s error parsing ICE candidate', options.direction, err)
75
- } finally {
76
- signal.removeEventListener('abort', abortListener)
77
- signal.clear()
61
+
62
+ if (options.signal?.aborted === true) {
63
+ throw err
64
+ }
78
65
  }
79
66
  }
80
67
 
81
- export function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<void>): void {
68
+ function getConnectionState (pc: RTCPeerConnection): string {
69
+ return isFirefox ? pc.iceConnectionState : pc.connectionState
70
+ }
71
+
72
+ function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<void>): void {
82
73
  pc[isFirefox ? 'oniceconnectionstatechange' : 'onconnectionstatechange'] = (_) => {
83
- switch (isFirefox ? pc.iceConnectionState : pc.connectionState) {
74
+ switch (getConnectionState(pc)) {
84
75
  case 'connected':
85
76
  promise.resolve()
86
77
  break
@@ -0,0 +1,5 @@
1
+ export {
2
+ RTCIceCandidate,
3
+ RTCPeerConnection,
4
+ RTCSessionDescription
5
+ } from 'react-native-webrtc'
@@ -1,8 +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
- "webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
5
- ".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
6
- "webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
7
- ".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
8
- }