@libp2p/webrtc 6.0.2-8543df06b → 6.0.2-8d66d5ff1

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 (49) hide show
  1. package/dist/index.min.js +6 -6
  2. package/dist/index.min.js.map +3 -3
  3. package/dist/src/muxer.d.ts +8 -0
  4. package/dist/src/muxer.d.ts.map +1 -1
  5. package/dist/src/muxer.js +38 -15
  6. package/dist/src/muxer.js.map +1 -1
  7. package/dist/src/private-to-private/initiate-connection.d.ts +1 -2
  8. package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
  9. package/dist/src/private-to-private/initiate-connection.js +1 -0
  10. package/dist/src/private-to-private/initiate-connection.js.map +1 -1
  11. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  12. package/dist/src/private-to-private/transport.js +2 -0
  13. package/dist/src/private-to-private/transport.js.map +1 -1
  14. package/dist/src/private-to-public/listener.d.ts +1 -0
  15. package/dist/src/private-to-public/listener.d.ts.map +1 -1
  16. package/dist/src/private-to-public/listener.js +8 -3
  17. package/dist/src/private-to-public/listener.js.map +1 -1
  18. package/dist/src/private-to-public/transport.d.ts.map +1 -1
  19. package/dist/src/private-to-public/transport.js +5 -3
  20. package/dist/src/private-to-public/transport.js.map +1 -1
  21. package/dist/src/private-to-public/utils/connect.d.ts +4 -4
  22. package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
  23. package/dist/src/private-to-public/utils/connect.js +6 -8
  24. package/dist/src/private-to-public/utils/connect.js.map +1 -1
  25. package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts +6 -1
  26. package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.d.ts.map +1 -1
  27. package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js +15 -3
  28. package/dist/src/private-to-public/utils/get-rtcpeerconnection.browser.js.map +1 -1
  29. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +17 -2
  30. package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
  31. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +18 -7
  32. package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
  33. package/dist/src/rtcpeerconnection-to-conn.d.ts +0 -1
  34. package/dist/src/rtcpeerconnection-to-conn.d.ts.map +1 -1
  35. package/dist/src/rtcpeerconnection-to-conn.js.map +1 -1
  36. package/dist/src/stream.d.ts.map +1 -1
  37. package/dist/src/stream.js +24 -16
  38. package/dist/src/stream.js.map +1 -1
  39. package/package.json +8 -8
  40. package/src/muxer.ts +50 -15
  41. package/src/private-to-private/initiate-connection.ts +2 -1
  42. package/src/private-to-private/transport.ts +3 -1
  43. package/src/private-to-public/listener.ts +9 -3
  44. package/src/private-to-public/transport.ts +8 -3
  45. package/src/private-to-public/utils/connect.ts +10 -13
  46. package/src/private-to-public/utils/get-rtcpeerconnection.browser.ts +20 -3
  47. package/src/private-to-public/utils/get-rtcpeerconnection.ts +31 -8
  48. package/src/rtcpeerconnection-to-conn.ts +0 -1
  49. package/src/stream.ts +25 -17
@@ -2,8 +2,10 @@ import { Crypto } from '@peculiar/webcrypto'
2
2
  import { PeerConnection } from 'node-datachannel'
3
3
  import { RTCPeerConnection } from 'node-datachannel/polyfill'
4
4
  import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from '../../constants.js'
5
+ import { DataChannelMuxerFactory } from '../../muxer.ts'
5
6
  import { generateTransportCertificate } from './generate-certificates.js'
6
- import type { TransportCertificate } from '../../index.js'
7
+ import type { DataChannelOptions, TransportCertificate } from '../../index.js'
8
+ import type { CounterGroup } from '@libp2p/interface'
7
9
  import type { CertificateFingerprint } from 'node-datachannel'
8
10
 
9
11
  const crypto = new Crypto()
@@ -85,8 +87,17 @@ function mapIceServers (iceServers?: RTCIceServer[]): string[] {
85
87
  .flat() ?? []
86
88
  }
87
89
 
88
- export async function createDialerRTCPeerConnection (role: 'client' | 'server', ufrag: string, rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>), certificate?: TransportCertificate): Promise<DirectRTCPeerConnection> {
89
- if (certificate == null) {
90
+ export interface CreateDialerRTCPeerConnectionOptions {
91
+ rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>)
92
+ certificate?: TransportCertificate
93
+ events?: CounterGroup
94
+ dataChannel?: DataChannelOptions
95
+ }
96
+
97
+ export async function createDialerRTCPeerConnection (role: 'client', ufrag: string, options?: CreateDialerRTCPeerConnectionOptions): Promise<{ peerConnection: globalThis.RTCPeerConnection, muxerFactory: DataChannelMuxerFactory }>
98
+ export async function createDialerRTCPeerConnection (role: 'server', ufrag: string, options?: CreateDialerRTCPeerConnectionOptions): Promise<{ peerConnection: DirectRTCPeerConnection, muxerFactory: DataChannelMuxerFactory }>
99
+ export async function createDialerRTCPeerConnection (role: 'client' | 'server', ufrag: string, options: CreateDialerRTCPeerConnectionOptions = {}): Promise<{ peerConnection: globalThis.RTCPeerConnection | DirectRTCPeerConnection, muxerFactory: DataChannelMuxerFactory }> {
100
+ if (options.certificate == null) {
90
101
  // ECDSA is preferred over RSA here. From our testing we find that P-256
91
102
  // elliptic curve is supported by Pion, webrtc-rs, as well as Chromium
92
103
  // (P-228 and P-384 was not supported in Chromium). We use the same hash
@@ -96,24 +107,36 @@ export async function createDialerRTCPeerConnection (role: 'client' | 'server',
96
107
  namedCurve: 'P-256'
97
108
  }, true, ['sign', 'verify'])
98
109
 
99
- certificate = await generateTransportCertificate(keyPair, {
110
+ options.certificate = await generateTransportCertificate(keyPair, {
100
111
  days: 365
101
112
  })
102
113
  }
103
114
 
104
- const rtcConfig = typeof rtcConfiguration === 'function' ? await rtcConfiguration() : rtcConfiguration
115
+ const rtcConfig = typeof options.rtcConfiguration === 'function' ? await options.rtcConfiguration() : options.rtcConfiguration
105
116
 
106
- return new DirectRTCPeerConnection({
117
+ const peerConnection = new DirectRTCPeerConnection({
107
118
  ...rtcConfig,
108
119
  ufrag,
109
120
  peerConnection: new PeerConnection(`${role}-${Date.now()}`, {
110
121
  disableFingerprintVerification: true,
111
122
  disableAutoNegotiation: true,
112
- certificatePemFile: certificate.pem,
113
- keyPemFile: certificate.privateKey,
123
+ certificatePemFile: options.certificate.pem,
124
+ keyPemFile: options.certificate.privateKey,
114
125
  enableIceUdpMux: role === 'server',
115
126
  maxMessageSize: MAX_MESSAGE_SIZE,
116
127
  iceServers: mapIceServers(rtcConfig?.iceServers ?? DEFAULT_ICE_SERVERS.map(urls => ({ urls })))
117
128
  })
118
129
  })
130
+
131
+ const muxerFactory = new DataChannelMuxerFactory({
132
+ // @ts-expect-error https://github.com/murat-dogan/node-datachannel/pull/370
133
+ peerConnection,
134
+ metrics: options.events,
135
+ dataChannelOptions: options.dataChannel
136
+ })
137
+
138
+ return {
139
+ peerConnection,
140
+ muxerFactory
141
+ }
119
142
  }
@@ -1,5 +1,4 @@
1
1
  import { AbstractMultiaddrConnection } from '@libp2p/utils'
2
- import type { RTCPeerConnection } from './webrtc/index.js'
3
2
  import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface'
4
3
  import type { AbstractMultiaddrConnectionInit, SendResult } from '@libp2p/utils'
5
4
  import type { Uint8ArrayList } from 'uint8arraylist'
package/src/stream.ts CHANGED
@@ -88,23 +88,6 @@ export class WebRTCStream extends AbstractStream {
88
88
  }
89
89
  }
90
90
 
91
- if (this.channel.readyState !== 'open') {
92
- this.log('channel ready state is "%s" and not "open", waiting for "open" event before sending data', this.channel.readyState)
93
- pEvent(this.channel, 'open', {
94
- rejectionEvents: [
95
- 'close',
96
- 'error'
97
- ]
98
- })
99
- .then(() => {
100
- this.log('channel ready state is now "%s", dispatching drain', this.channel.readyState)
101
- this.safeDispatchEvent('drain')
102
- })
103
- .catch(err => {
104
- this.abort(err.error ?? err)
105
- })
106
- }
107
-
108
91
  // pipe framed protobuf messages through a length prefixed decoder, and
109
92
  // surface data from the `Message.message` field through a source.
110
93
  Promise.resolve().then(async () => {
@@ -124,6 +107,26 @@ export class WebRTCStream extends AbstractStream {
124
107
  }
125
108
  }
126
109
  this.addEventListener('close', cleanUpDatachannelOnClose)
110
+
111
+ // chrome can receive message events before the open even is fired - calling
112
+ // code needs to attach message event listeners before these events occur
113
+ // but we need to wait before sending any data so this has to be done async
114
+ if (this.channel.readyState !== 'open') {
115
+ this.log('channel ready state is "%s" and not "open", waiting for "open" event before sending data', this.channel.readyState)
116
+ pEvent(this.channel, 'open', {
117
+ rejectionEvents: [
118
+ 'close',
119
+ 'error'
120
+ ]
121
+ })
122
+ .then(() => {
123
+ this.log('channel ready state is now "%s", dispatching drain', this.channel.readyState)
124
+ this.safeDispatchEvent('drain')
125
+ })
126
+ .catch(err => {
127
+ this.abort(err.error ?? err)
128
+ })
129
+ }
127
130
  }
128
131
 
129
132
  sendNewStream (): void {
@@ -204,8 +207,13 @@ export class WebRTCStream extends AbstractStream {
204
207
  options?.signal?.throwIfAborted()
205
208
  this.receivedFinAck = Promise.withResolvers<void>()
206
209
 
210
+ // wait for either:
211
+ // 1. the FIN_ACK to be received
212
+ // 2. the datachannel to close
213
+ // 3. timeout
207
214
  await Promise.any([
208
215
  raceSignal(this.receivedFinAck.promise, options?.signal),
216
+ pEvent(this.channel, 'close'),
209
217
  new Promise<void>(resolve => {
210
218
  AbortSignal.timeout(this.finAckTimeout)
211
219
  .addEventListener('abort', () => {