@libp2p/webtransport 5.0.51-8484de8a2 → 5.0.51-87bc8d4fb

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 (47) hide show
  1. package/dist/index.min.js +1 -1
  2. package/dist/index.min.js.map +4 -4
  3. package/dist/src/constants.d.ts +2 -0
  4. package/dist/src/constants.d.ts.map +1 -0
  5. package/dist/src/constants.js +2 -0
  6. package/dist/src/constants.js.map +1 -0
  7. package/dist/src/index.d.ts +4 -1
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +63 -32
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/listener.d.ts +1 -0
  12. package/dist/src/listener.d.ts.map +1 -1
  13. package/dist/src/listener.js.map +1 -1
  14. package/dist/src/muxer.d.ts +5 -2
  15. package/dist/src/muxer.d.ts.map +1 -1
  16. package/dist/src/muxer.js +74 -44
  17. package/dist/src/muxer.js.map +1 -1
  18. package/dist/src/stream.d.ts +2 -21
  19. package/dist/src/stream.d.ts.map +1 -1
  20. package/dist/src/stream.js +47 -75
  21. package/dist/src/stream.js.map +1 -1
  22. package/dist/src/utils/inert-duplex.d.ts +3 -0
  23. package/dist/src/utils/inert-duplex.d.ts.map +1 -0
  24. package/dist/src/utils/inert-duplex.js +20 -0
  25. package/dist/src/utils/inert-duplex.js.map +1 -0
  26. package/dist/src/utils/parse-multiaddr.d.ts +1 -1
  27. package/dist/src/utils/parse-multiaddr.d.ts.map +1 -1
  28. package/dist/src/utils/parse-multiaddr.js +11 -17
  29. package/dist/src/utils/parse-multiaddr.js.map +1 -1
  30. package/package.json +20 -19
  31. package/src/constants.ts +1 -0
  32. package/src/index.ts +74 -36
  33. package/src/listener.ts +1 -0
  34. package/src/muxer.ts +84 -60
  35. package/src/stream.ts +55 -88
  36. package/src/utils/inert-duplex.ts +21 -0
  37. package/src/utils/parse-multiaddr.ts +12 -20
  38. package/dist/src/session-to-conn.d.ts +0 -11
  39. package/dist/src/session-to-conn.d.ts.map +0 -1
  40. package/dist/src/session-to-conn.js +0 -35
  41. package/dist/src/session-to-conn.js.map +0 -1
  42. package/dist/src/utils/webtransport-message-stream.d.ts +0 -18
  43. package/dist/src/utils/webtransport-message-stream.d.ts.map +0 -1
  44. package/dist/src/utils/webtransport-message-stream.js +0 -49
  45. package/dist/src/utils/webtransport-message-stream.js.map +0 -1
  46. package/src/session-to-conn.ts +0 -50
  47. package/src/utils/webtransport-message-stream.ts +0 -69
@@ -1,96 +1,67 @@
1
- import { AbstractStream } from '@libp2p/utils';
1
+ import { AbstractStream } from '@libp2p/utils/abstract-stream';
2
2
  import { raceSignal } from 'race-signal';
3
- export class WebTransportStream extends AbstractStream {
3
+ import { Uint8ArrayList } from 'uint8arraylist';
4
+ class WebTransportStream extends AbstractStream {
4
5
  writer;
5
6
  reader;
6
7
  constructor(init) {
7
8
  super(init);
8
- this.writer = init.stream.writable.getWriter();
9
- this.reader = init.stream.readable.getReader();
10
- void this.writer.closed
11
- .then(() => {
12
- this.log('writer closed gracefully');
13
- })
14
- .catch((err) => {
15
- // chrome/ff send different messages
16
- if (err.message.includes('STOP_SENDING') || err.message.includes('StopSending')) {
17
- // err.code === 0 so we may be able to use this to detect remote close
18
- // read instead?
19
- this.onRemoteCloseRead();
20
- }
21
- else if (err.message.includes('RESET_STREAM') || err.message.includes('Reset')) {
22
- this.onRemoteReset();
23
- }
24
- else {
25
- this.log('writer close promise rejected - %e', err);
26
- }
27
- });
28
- this.readData();
29
- }
30
- readData() {
9
+ this.writer = init.bidiStream.writable.getWriter();
10
+ this.reader = init.bidiStream.readable.getReader();
31
11
  Promise.resolve()
32
12
  .then(async () => {
33
13
  while (true) {
34
14
  const result = await this.reader.read();
35
- if (result.value != null) {
36
- this.onData(result.value);
37
- }
38
15
  if (result.done) {
39
- this.log('remote closed write');
40
- this.onRemoteCloseWrite();
16
+ init.log('remote closed write');
41
17
  return;
42
18
  }
43
- if (this.readStatus === 'paused') {
44
- break;
19
+ if (result.value != null) {
20
+ this.sourcePush(new Uint8ArrayList(result.value));
45
21
  }
46
22
  }
47
23
  })
48
24
  .catch(err => {
25
+ init.log.error('error reading from stream', err);
49
26
  this.abort(err);
50
27
  })
51
28
  .finally(() => {
52
- this.reader.releaseLock();
29
+ this.remoteCloseWrite();
30
+ });
31
+ void this.writer.closed
32
+ .then(() => {
33
+ init.log('writer closed');
34
+ })
35
+ .catch((err) => {
36
+ init.log('writer close promise rejected', err);
37
+ })
38
+ .finally(() => {
39
+ this.remoteCloseRead();
53
40
  });
54
41
  }
55
- sendData(data) {
56
- // the streams spec recommends not waiting for data to be sent
57
- // https://streams.spec.whatwg.org/#example-manual-write-dont-await
58
- for (const buf of data) {
59
- this.writer.write(buf)
42
+ sendNewStream(options) {
43
+ // this is a no-op
44
+ }
45
+ async sendData(buf, options) {
46
+ for (const chunk of buf) {
47
+ this.log('sendData waiting for writer to be ready');
48
+ await raceSignal(this.writer.ready, options?.signal);
49
+ // the streams spec recommends not waiting for data to be sent
50
+ // https://streams.spec.whatwg.org/#example-manual-write-dont-await
51
+ this.writer.write(chunk)
60
52
  .catch(err => {
61
- this.abort(err);
62
- });
63
- }
64
- this.log.trace('desired size after sending %d bytes is %d bytes', data.byteLength, this.writer.desiredSize);
65
- // null means the stream has errored - https://streams.spec.whatwg.org/#writable-stream-default-writer-get-desired-size
66
- if (this.writer.desiredSize == null) {
67
- return {
68
- sentBytes: data.byteLength,
69
- canSendMore: false
70
- };
71
- }
72
- const canSendMore = this.writer.desiredSize > 0;
73
- if (!canSendMore) {
74
- this.writer.ready.then(() => {
75
- this.safeDispatchEvent('drain');
76
- }, (err) => {
77
- this.abort(err);
53
+ this.log.error('error sending stream data', err);
78
54
  });
79
55
  }
80
- return {
81
- sentBytes: data.byteLength,
82
- canSendMore
83
- };
84
56
  }
85
- sendReset(err) {
86
- this.writer.abort(err)
87
- .catch(err => {
88
- this.log.error('error aborting writer - %e', err);
89
- });
57
+ async sendReset(options) {
58
+ this.log('sendReset aborting writer');
59
+ await raceSignal(this.writer.abort(), options?.signal);
60
+ this.log('sendReset aborted writer');
90
61
  }
91
62
  async sendCloseWrite(options) {
92
63
  this.log('sendCloseWrite closing writer');
93
- await raceSignal(this.writer.close().catch(() => { }), options?.signal);
64
+ await raceSignal(this.writer.close(), options?.signal);
94
65
  this.log('sendCloseWrite closed writer');
95
66
  }
96
67
  async sendCloseRead(options) {
@@ -98,20 +69,21 @@ export class WebTransportStream extends AbstractStream {
98
69
  await raceSignal(this.reader.cancel(), options?.signal);
99
70
  this.log('sendCloseRead cancelled reader');
100
71
  }
101
- sendPause() {
102
- }
103
- sendResume() {
104
- this.readData();
105
- }
106
72
  }
107
- export function webtransportBiDiStreamToStream(stream, streamId, direction, log, options) {
108
- return new WebTransportStream({
109
- ...options,
110
- stream,
73
+ export async function webtransportBiDiStreamToStream(bidiStream, streamId, direction, activeStreams, onStreamEnd, log) {
74
+ const stream = new WebTransportStream({
75
+ bidiStream,
111
76
  id: streamId,
112
77
  direction,
113
78
  log: log.newScope(`${direction}:${streamId}`),
114
- protocol: ''
79
+ onEnd: () => {
80
+ const index = activeStreams.findIndex(s => s === stream);
81
+ if (index !== -1) {
82
+ activeStreams.splice(index, 1);
83
+ }
84
+ onStreamEnd?.(stream);
85
+ }
115
86
  });
87
+ return stream;
116
88
  }
117
89
  //# sourceMappingURL=stream.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Duplex } from 'it-stream-types';
2
+ export declare function inertDuplex(): Duplex<any, any, any>;
3
+ //# sourceMappingURL=inert-duplex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert-duplex.d.ts","sourceRoot":"","sources":["../../../src/utils/inert-duplex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,iBAAiB,CAAA;AAGrD,wBAAgB,WAAW,IAAK,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAiBpD"}
@@ -0,0 +1,20 @@
1
+ // Duplex that does nothing. Needed to fulfill the interface
2
+ export function inertDuplex() {
3
+ return {
4
+ source: {
5
+ [Symbol.asyncIterator]() {
6
+ return {
7
+ async next() {
8
+ // This will never resolve
9
+ return new Promise(() => { });
10
+ }
11
+ };
12
+ }
13
+ },
14
+ sink: async (source) => {
15
+ // This will never resolve
16
+ return new Promise(() => { });
17
+ }
18
+ };
19
+ }
20
+ //# sourceMappingURL=inert-duplex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inert-duplex.js","sourceRoot":"","sources":["../../../src/utils/inert-duplex.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,MAAM,EAAE;YACN,CAAC,MAAM,CAAC,aAAa,CAAC;gBACpB,OAAO;oBACL,KAAK,CAAC,IAAI;wBACR,0BAA0B;wBAC1B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;oBAC/B,CAAC;iBACF,CAAA;YACH,CAAC;SACF;QACD,IAAI,EAAE,KAAK,EAAE,MAAmB,EAAE,EAAE;YAClC,0BAA0B;YAC1B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;QAC/B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -4,7 +4,7 @@ import type { MultihashDigest } from 'multiformats/hashes/interface';
4
4
  export interface ParsedMultiaddr {
5
5
  url: string;
6
6
  certhashes: MultihashDigest[];
7
- remotePeer: PeerId;
7
+ remotePeer?: PeerId;
8
8
  }
9
9
  export declare function parseMultiaddr(ma: Multiaddr): ParsedMultiaddr;
10
10
  //# sourceMappingURL=parse-multiaddr.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-multiaddr.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-multiaddr.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AASpE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,eAAe,EAAE,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,cAAc,CAAE,EAAE,EAAE,SAAS,GAAG,eAAe,CA4C9D"}
1
+ {"version":3,"file":"parse-multiaddr.d.ts","sourceRoot":"","sources":["../../../src/utils/parse-multiaddr.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AASpE,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,eAAe,EAAE,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,cAAc,CAAE,EAAE,EAAE,SAAS,GAAG,eAAe,CAoC9D"}
@@ -1,6 +1,6 @@
1
1
  import { InvalidMultiaddrError } from '@libp2p/interface';
2
2
  import { peerIdFromString } from '@libp2p/peer-id';
3
- import { getNetConfig } from '@libp2p/utils';
3
+ import { protocols } from '@multiformats/multiaddr';
4
4
  import { WebTransport } from '@multiformats/multiaddr-matcher';
5
5
  import { bases, digest } from 'multiformats/basics';
6
6
  // @ts-expect-error - Not easy to combine these types.
@@ -12,23 +12,17 @@ export function parseMultiaddr(ma) {
12
12
  if (!WebTransport.matches(ma)) {
13
13
  throw new InvalidMultiaddrError('Invalid multiaddr, was not a WebTransport address');
14
14
  }
15
- const certhashes = [];
16
- let remotePeer;
17
- for (const components of ma.getComponents()) {
18
- if (components.name === 'certhash') {
19
- certhashes.push(decodeCerthashStr(components.value ?? ''));
20
- }
21
- // only take the first peer id in the multiaddr as it may be a relay
22
- if (components.name === 'p2p' && remotePeer == null) {
23
- remotePeer = peerIdFromString(components.value ?? '');
24
- }
25
- }
26
- if (remotePeer == null) {
27
- throw new InvalidMultiaddrError('Remote peer must be present in multiaddr');
28
- }
29
- const opts = getNetConfig(ma);
15
+ const parts = ma.stringTuples();
16
+ const certhashes = parts
17
+ .filter(([name, _]) => name === protocols('certhash').code)
18
+ .map(([_, value]) => decodeCerthashStr(value ?? ''));
19
+ // only take the first peer id in the multiaddr as it may be a relay
20
+ const remotePeer = parts
21
+ .filter(([name, _]) => name === protocols('p2p').code)
22
+ .map(([_, value]) => peerIdFromString(value ?? ''))[0];
23
+ const opts = ma.toOptions();
30
24
  let host = opts.host;
31
- if (opts.type === 'ip6' && host.includes(':')) {
25
+ if (opts.family === 6 && host?.includes(':')) {
32
26
  /**
33
27
  * This resolves cases where `new WebTransport()` fails to construct because of an invalid URL being passed.
34
28
  *
@@ -1 +1 @@
1
- {"version":3,"file":"parse-multiaddr.js","sourceRoot":"","sources":["../../../src/utils/parse-multiaddr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAKnD,sDAAsD;AACtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAE3F,SAAS,iBAAiB,CAAE,CAAS;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAClD,CAAC;AAQD,MAAM,UAAU,cAAc,CAAE,EAAa;IAC3C,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,qBAAqB,CAAC,mDAAmD,CAAC,CAAA;IACtF,CAAC;IAED,MAAM,UAAU,GAAsB,EAAE,CAAA;IACxC,IAAI,UAA8B,CAAA;IAElC,KAAK,MAAM,UAAU,IAAI,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC;QAC5C,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACnC,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;QAC5D,CAAC;QAED,oEAAoE;QACpE,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACpD,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IAED,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,qBAAqB,CAAC,0CAA0C,CAAC,CAAA;IAC7E,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IAEpB,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C;;;;;;;WAOG;QACH,IAAI,GAAG,IAAI,IAAI,GAAG,CAAA;IACpB,CAAC;IAED,OAAO;QACL,kCAAkC;QAClC,GAAG,EAAE,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;QACnC,UAAU;QACV,UAAU;KACX,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"parse-multiaddr.js","sourceRoot":"","sources":["../../../src/utils/parse-multiaddr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAKnD,sDAAsD;AACtD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAE3F,SAAS,iBAAiB,CAAE,CAAS;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAClD,CAAC;AAQD,MAAM,UAAU,cAAc,CAAE,EAAa;IAC3C,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,qBAAqB,CAAC,mDAAmD,CAAC,CAAA;IACtF,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,EAAE,CAAA;IAC/B,MAAM,UAAU,GAAG,KAAK;SACrB,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;SAC1D,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAA;IAEtD,oEAAoE;IACpE,MAAM,UAAU,GAAG,KAAK;SACrB,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;SACrD,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAExD,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,EAAE,CAAA;IAC3B,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IAEpB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C;;;;;;;WAOG;QACH,IAAI,GAAG,IAAI,IAAI,GAAG,CAAA;IACpB,CAAC;IAED,OAAO;QACL,kCAAkC;QAClC,GAAG,EAAE,WAAW,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;QACnC,UAAU;QACV,UAAU;KACX,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/webtransport",
3
- "version": "5.0.51-8484de8a2",
3
+ "version": "5.0.51-87bc8d4fb",
4
4
  "description": "JavaScript implementation of the WebTransport module that libp2p uses and that implements the interface-transport spec",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webtransport#readme",
@@ -40,35 +40,36 @@
40
40
  "build": "aegir build",
41
41
  "test": "aegir test -t browser -t webworker",
42
42
  "test:chrome": "aegir test -t browser --cov",
43
- "test:chrome-webworker": "aegir test -t webworker",
44
- "test:firefox": "aegir test -t browser -- --browser firefox"
43
+ "test:chrome-webworker": "aegir test -t webworker"
45
44
  },
46
45
  "dependencies": {
47
- "@libp2p/interface": "2.11.0-8484de8a2",
48
- "@libp2p/noise": "16.1.4-8484de8a2",
49
- "@libp2p/peer-id": "5.1.9-8484de8a2",
50
- "@libp2p/utils": "6.7.2-8484de8a2",
51
- "@multiformats/multiaddr": "^13.0.1",
52
- "@multiformats/multiaddr-matcher": "^3.0.1",
46
+ "@chainsafe/libp2p-noise": "^16.1.3",
47
+ "@libp2p/interface": "2.11.0-87bc8d4fb",
48
+ "@libp2p/peer-id": "5.1.9-87bc8d4fb",
49
+ "@libp2p/utils": "6.7.2-87bc8d4fb",
50
+ "@multiformats/multiaddr": "^12.4.4",
51
+ "@multiformats/multiaddr-matcher": "^2.0.0",
52
+ "it-stream-types": "^2.0.2",
53
53
  "multiformats": "^13.3.6",
54
54
  "progress-events": "^1.0.1",
55
- "race-signal": "^2.0.0",
55
+ "race-signal": "^1.1.3",
56
56
  "uint8arraylist": "^2.4.8",
57
57
  "uint8arrays": "^5.1.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@libp2p/crypto": "5.1.8-8484de8a2",
61
- "@libp2p/daemon-client": "9.0.8-8484de8a2",
62
- "@libp2p/logger": "5.2.0-8484de8a2",
63
- "@libp2p/ping": "2.0.37-8484de8a2",
60
+ "@libp2p/crypto": "5.1.8-87bc8d4fb",
61
+ "@libp2p/daemon-client": "^9.0.6",
62
+ "@libp2p/logger": "5.2.0-87bc8d4fb",
63
+ "@libp2p/ping": "2.0.37-87bc8d4fb",
64
64
  "@noble/hashes": "^1.8.0",
65
- "aegir": "^47.0.21",
66
- "execa": "^9.6.0",
65
+ "aegir": "^47.0.14",
66
+ "execa": "^9.5.3",
67
67
  "go-libp2p": "^1.6.0",
68
- "it-all": "^3.0.9",
69
- "libp2p": "2.10.0-8484de8a2",
68
+ "it-map": "^3.1.3",
69
+ "it-to-buffer": "^4.0.9",
70
+ "libp2p": "2.10.0-87bc8d4fb",
70
71
  "p-defer": "^4.0.1",
71
- "p-event": "^6.0.1",
72
+ "p-wait-for": "^5.0.2",
72
73
  "sinon-ts": "^2.0.0"
73
74
  },
74
75
  "browser": {
@@ -0,0 +1 @@
1
+ export const MAX_INBOUND_STREAMS = 1_000
package/src/index.ts CHANGED
@@ -3,18 +3,20 @@
3
3
  *
4
4
  * A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebTransport](https://www.w3.org/TR/webtransport/).
5
5
  *
6
+ * >
6
7
  * > ⚠️ **Note**
7
8
  * >
8
9
  * > This WebTransport implementation currently only allows dialing to other nodes. It does not yet allow listening for incoming dials. This feature requires QUIC support to land in Node JS first.
9
10
  * >
10
11
  * > QUIC support in Node JS is actively being worked on. You can keep an eye on the progress by watching the [related issues on the Node JS issue tracker](https://github.com/nodejs/node/labels/quic)
12
+ * >
11
13
  *
12
14
  * @example
13
15
  *
14
16
  * ```TypeScript
15
17
  * import { createLibp2p } from 'libp2p'
16
18
  * import { webTransport } from '@libp2p/webtransport'
17
- * import { noise } from '@libp2p/noise'
19
+ * import { noise } from '@chainsafe/libp2p-noise'
18
20
  *
19
21
  * const node = await createLibp2p({
20
22
  * transports: [
@@ -27,21 +29,24 @@
27
29
  * ```
28
30
  */
29
31
 
32
+ import { noise } from '@chainsafe/libp2p-noise'
30
33
  import { InvalidCryptoExchangeError, InvalidParametersError, serviceCapabilities, transportSymbol } from '@libp2p/interface'
31
- import { noise } from '@libp2p/noise'
32
34
  import { WebTransport as WebTransportMatcher } from '@multiformats/multiaddr-matcher'
33
35
  import { CustomProgressEvent } from 'progress-events'
36
+ import { raceSignal } from 'race-signal'
37
+ import { MAX_INBOUND_STREAMS } from './constants.js'
34
38
  import createListener from './listener.js'
35
39
  import { webtransportMuxer } from './muxer.js'
36
- import { toMultiaddrConnection } from './session-to-conn.ts'
40
+ import { inertDuplex } from './utils/inert-duplex.js'
37
41
  import { isSubset } from './utils/is-subset.js'
38
42
  import { parseMultiaddr } from './utils/parse-multiaddr.js'
39
- import { WebTransportMessageStream } from './utils/webtransport-message-stream.ts'
40
43
  import WebTransport from './webtransport.js'
41
44
  import type { Upgrader, Transport, CreateListenerOptions, DialTransportOptions, Listener, ComponentLogger, Logger, Connection, MultiaddrConnection, CounterGroup, Metrics, PeerId, OutboundConnectionUpgradeEvents, PrivateKey } from '@libp2p/interface'
42
45
  import type { Multiaddr } from '@multiformats/multiaddr'
46
+ import type { Source } from 'it-stream-types'
43
47
  import type { MultihashDigest } from 'multiformats/hashes/interface'
44
48
  import type { ProgressEvent } from 'progress-events'
49
+ import type { Uint8ArrayList } from 'uint8arraylist'
45
50
 
46
51
  /**
47
52
  * PEM format server certificate and private key
@@ -58,6 +63,7 @@ interface WebTransportSessionCleanup {
58
63
  }
59
64
 
60
65
  export interface WebTransportInit {
66
+ maxInboundStreams?: number
61
67
  certificates?: WebTransportCertificate[]
62
68
  }
63
69
 
@@ -82,7 +88,6 @@ export type WebTransportDialEvents =
82
88
 
83
89
  interface AuthenticateWebTransportOptions extends DialTransportOptions<WebTransportDialEvents> {
84
90
  wt: WebTransport
85
- maConn: MultiaddrConnection
86
91
  remotePeer?: PeerId
87
92
  certhashes: Array<MultihashDigest<number>>
88
93
  }
@@ -98,6 +103,7 @@ class WebTransportTransport implements Transport<WebTransportDialEvents> {
98
103
  this.components = components
99
104
  this.config = {
100
105
  ...init,
106
+ maxInboundStreams: init.maxInboundStreams ?? MAX_INBOUND_STREAMS,
101
107
  certificates: init.certificates ?? []
102
108
  }
103
109
 
@@ -196,32 +202,36 @@ class WebTransportTransport implements Transport<WebTransportDialEvents> {
196
202
  cleanUpWTSession('remote_close')
197
203
  })
198
204
 
199
- this.metrics?.dialerEvents.increment({ open: true })
200
-
201
- maConn = toMultiaddrConnection({
202
- remoteAddr: ma,
203
- cleanUpWTSession,
204
- direction: 'outbound',
205
- log: this.components.logger.forComponent('libp2p:webtransport:connection')
206
- })
207
-
208
- authenticated = await this.authenticateWebTransport({
209
- wt,
210
- maConn,
211
- remotePeer,
212
- certhashes,
213
- ...options
214
- })
205
+ authenticated = await raceSignal(this.authenticateWebTransport({ wt, remotePeer, certhashes, ...options }), options.signal)
215
206
 
216
207
  if (!authenticated) {
217
208
  throw new InvalidCryptoExchangeError('Failed to authenticate webtransport')
218
209
  }
219
210
 
211
+ this.metrics?.dialerEvents.increment({ open: true })
212
+
213
+ maConn = {
214
+ close: async () => {
215
+ this.log('closing webtransport')
216
+ cleanUpWTSession('close')
217
+ },
218
+ abort: (err: Error) => {
219
+ this.log('aborting webtransport due to passed err', err)
220
+ cleanUpWTSession('abort')
221
+ },
222
+ remoteAddr: ma,
223
+ timeline: {
224
+ open: Date.now()
225
+ },
226
+ log: this.components.logger.forComponent('libp2p:webtransport:maconn'),
227
+ // This connection is never used directly since webtransport supports native streams.
228
+ ...inertDuplex()
229
+ }
230
+
220
231
  return await options.upgrader.upgradeOutbound(maConn, {
221
232
  ...options,
222
233
  skipEncryption: true,
223
- remotePeer,
224
- muxerFactory: webtransportMuxer(wt),
234
+ muxerFactory: webtransportMuxer(wt, wt.incomingBidirectionalStreams.getReader(), this.log, this.config),
225
235
  skipProtection: true
226
236
  })
227
237
  } catch (err: any) {
@@ -243,34 +253,61 @@ class WebTransportTransport implements Transport<WebTransportDialEvents> {
243
253
  }
244
254
  }
245
255
 
246
- async authenticateWebTransport ({ wt, maConn, remotePeer, certhashes, onProgress, signal }: AuthenticateWebTransportOptions): Promise<boolean> {
256
+ async authenticateWebTransport ({ wt, remotePeer, certhashes, onProgress, signal }: AuthenticateWebTransportOptions): Promise<boolean> {
257
+ signal?.throwIfAborted()
258
+
247
259
  onProgress?.(new CustomProgressEvent('webtransport:open-authentication-stream'))
248
260
  const stream = await wt.createBidirectionalStream()
249
- signal?.throwIfAborted()
261
+ const writer = stream.writable.getWriter()
262
+ const reader = stream.readable.getReader()
250
263
 
251
- const messages = new WebTransportMessageStream({
252
- stream,
253
- log: maConn.log.newScope('muxer')
254
- })
264
+ const duplex = {
265
+ source: (async function * () {
266
+ while (true) {
267
+ const val = await reader.read()
268
+
269
+ if (val.value != null) {
270
+ yield val.value
271
+ }
272
+
273
+ if (val.done) {
274
+ break
275
+ }
276
+ }
277
+ })(),
278
+ sink: async (source: Source<Uint8Array | Uint8ArrayList>) => {
279
+ for await (const chunk of source) {
280
+ await raceSignal(writer.ready, signal)
281
+
282
+ const buf = chunk instanceof Uint8Array ? chunk : chunk.subarray()
283
+
284
+ writer.write(buf).catch(err => {
285
+ this.log.error('could not write chunk during authentication of WebTransport stream', err)
286
+ })
287
+ }
288
+ }
289
+ }
255
290
 
256
291
  const n = noise()(this.components)
257
292
 
258
293
  onProgress?.(new CustomProgressEvent('webtransport:secure-outbound-connection'))
259
- const { remoteExtensions } = await n.secureOutbound(messages, {
294
+ const { remoteExtensions } = await n.secureOutbound(duplex, {
260
295
  signal,
261
296
  remotePeer,
262
297
  skipStreamMuxerNegotiation: true
263
298
  })
264
299
 
265
300
  onProgress?.(new CustomProgressEvent('webtransport:close-authentication-stream'))
266
-
267
301
  // We're done with this authentication stream
268
- await messages.close({
269
- signal
302
+ writer.close().catch((err: Error) => {
303
+ this.log.error(`Failed to close authentication stream writer: ${err.message}`)
304
+ })
305
+
306
+ reader.cancel().catch((err: Error) => {
307
+ this.log.error(`Failed to close authentication stream reader: ${err.message}`)
270
308
  })
271
309
 
272
- // Verify the certhashes we used when dialing are a subset of the certhashes
273
- // relayed by the remote peer
310
+ // Verify the certhashes we used when dialing are a subset of the certhashes relayed by the remote peer
274
311
  if (!isSubset(remoteExtensions?.webtransportCerthashes ?? [], certhashes.map(ch => ch.bytes))) {
275
312
  throw new InvalidParametersError("Our certhashes are not a subset of the remote's reported certhashes")
276
313
  }
@@ -281,7 +318,8 @@ class WebTransportTransport implements Transport<WebTransportDialEvents> {
281
318
  createListener (options: CreateListenerOptions): Listener {
282
319
  return createListener(this.components, {
283
320
  ...options,
284
- certificates: this.config.certificates
321
+ certificates: this.config.certificates,
322
+ maxInboundStreams: this.config.maxInboundStreams
285
323
  })
286
324
  }
287
325
 
package/src/listener.ts CHANGED
@@ -11,6 +11,7 @@ export interface WebTransportListenerInit extends CreateListenerOptions {
11
11
  handler?(conn: Connection): void
12
12
  upgrader: Upgrader
13
13
  certificates?: WebTransportCertificate[]
14
+ maxInboundStreams?: number
14
15
  }
15
16
 
16
17
  export default function createListener (components: WebTransportListenerComponents, options: WebTransportListenerInit): Listener {