@libp2p/utils 6.7.2 → 7.0.0-55b7e5fea

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 (160) hide show
  1. package/README.md +16 -1
  2. package/dist/index.min.js +7 -1
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/abstract-message-stream.d.ts +129 -0
  5. package/dist/src/abstract-message-stream.d.ts.map +1 -0
  6. package/dist/src/abstract-message-stream.js +393 -0
  7. package/dist/src/abstract-message-stream.js.map +1 -0
  8. package/dist/src/abstract-multiaddr-connection.d.ts +26 -0
  9. package/dist/src/abstract-multiaddr-connection.d.ts.map +1 -0
  10. package/dist/src/abstract-multiaddr-connection.js +66 -0
  11. package/dist/src/abstract-multiaddr-connection.js.map +1 -0
  12. package/dist/src/abstract-stream-muxer.d.ts +53 -0
  13. package/dist/src/abstract-stream-muxer.d.ts.map +1 -0
  14. package/dist/src/abstract-stream-muxer.js +169 -0
  15. package/dist/src/abstract-stream-muxer.js.map +1 -0
  16. package/dist/src/abstract-stream.d.ts +14 -130
  17. package/dist/src/abstract-stream.d.ts.map +1 -1
  18. package/dist/src/abstract-stream.js +39 -321
  19. package/dist/src/abstract-stream.js.map +1 -1
  20. package/dist/src/errors.d.ts +8 -0
  21. package/dist/src/errors.d.ts.map +1 -1
  22. package/dist/src/errors.js +8 -0
  23. package/dist/src/errors.js.map +1 -1
  24. package/dist/src/get-thin-waist-addresses.browser.d.ts +1 -1
  25. package/dist/src/get-thin-waist-addresses.browser.d.ts.map +1 -1
  26. package/dist/src/get-thin-waist-addresses.browser.js +4 -3
  27. package/dist/src/get-thin-waist-addresses.browser.js.map +1 -1
  28. package/dist/src/get-thin-waist-addresses.d.ts +1 -1
  29. package/dist/src/get-thin-waist-addresses.d.ts.map +1 -1
  30. package/dist/src/get-thin-waist-addresses.js +7 -9
  31. package/dist/src/get-thin-waist-addresses.js.map +1 -1
  32. package/dist/src/index.d.ts +31 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +31 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/length-prefixed-decoder.d.ts +37 -0
  37. package/dist/src/length-prefixed-decoder.d.ts.map +1 -0
  38. package/dist/src/length-prefixed-decoder.js +64 -0
  39. package/dist/src/length-prefixed-decoder.js.map +1 -0
  40. package/dist/src/message-queue.d.ts +61 -0
  41. package/dist/src/message-queue.d.ts.map +1 -0
  42. package/dist/src/message-queue.js +93 -0
  43. package/dist/src/message-queue.js.map +1 -0
  44. package/dist/src/mock-muxer.d.ts +57 -0
  45. package/dist/src/mock-muxer.d.ts.map +1 -0
  46. package/dist/src/mock-muxer.js +204 -0
  47. package/dist/src/mock-muxer.js.map +1 -0
  48. package/dist/src/mock-stream.d.ts +31 -0
  49. package/dist/src/mock-stream.d.ts.map +1 -0
  50. package/dist/src/mock-stream.js +69 -0
  51. package/dist/src/mock-stream.js.map +1 -0
  52. package/dist/src/multiaddr/get-net-config.d.ts +55 -0
  53. package/dist/src/multiaddr/get-net-config.d.ts.map +1 -0
  54. package/dist/src/multiaddr/get-net-config.js +54 -0
  55. package/dist/src/multiaddr/get-net-config.js.map +1 -0
  56. package/dist/src/multiaddr/index.d.ts +7 -0
  57. package/dist/src/multiaddr/index.d.ts.map +1 -0
  58. package/dist/src/multiaddr/index.js +7 -0
  59. package/dist/src/multiaddr/index.js.map +1 -0
  60. package/dist/src/multiaddr/is-global-unicast.d.ts.map +1 -1
  61. package/dist/src/multiaddr/is-global-unicast.js +8 -9
  62. package/dist/src/multiaddr/is-global-unicast.js.map +1 -1
  63. package/dist/src/multiaddr/is-link-local.d.ts.map +1 -1
  64. package/dist/src/multiaddr/is-link-local.js +11 -16
  65. package/dist/src/multiaddr/is-link-local.js.map +1 -1
  66. package/dist/src/multiaddr/is-loopback.d.ts.map +1 -1
  67. package/dist/src/multiaddr/is-loopback.js +12 -5
  68. package/dist/src/multiaddr/is-loopback.js.map +1 -1
  69. package/dist/src/multiaddr/is-network-address.d.ts.map +1 -1
  70. package/dist/src/multiaddr/is-network-address.js +4 -16
  71. package/dist/src/multiaddr/is-network-address.js.map +1 -1
  72. package/dist/src/multiaddr/is-private.d.ts.map +1 -1
  73. package/dist/src/multiaddr/is-private.js +9 -10
  74. package/dist/src/multiaddr/is-private.js.map +1 -1
  75. package/dist/src/multiaddr/utils.d.ts +5 -0
  76. package/dist/src/multiaddr/utils.d.ts.map +1 -0
  77. package/dist/src/multiaddr/utils.js +32 -0
  78. package/dist/src/multiaddr/utils.js.map +1 -0
  79. package/dist/src/multiaddr-connection-pair.d.ts +25 -0
  80. package/dist/src/multiaddr-connection-pair.d.ts.map +1 -0
  81. package/dist/src/multiaddr-connection-pair.js +103 -0
  82. package/dist/src/multiaddr-connection-pair.js.map +1 -0
  83. package/dist/src/queue/index.d.ts +3 -6
  84. package/dist/src/queue/index.d.ts.map +1 -1
  85. package/dist/src/queue/index.js +20 -4
  86. package/dist/src/queue/index.js.map +1 -1
  87. package/dist/src/rate-limiter.d.ts +1 -15
  88. package/dist/src/rate-limiter.d.ts.map +1 -1
  89. package/dist/src/rate-limiter.js +1 -14
  90. package/dist/src/rate-limiter.js.map +1 -1
  91. package/dist/src/stream-pair.d.ts +42 -0
  92. package/dist/src/stream-pair.d.ts.map +1 -0
  93. package/dist/src/stream-pair.js +40 -0
  94. package/dist/src/stream-pair.js.map +1 -0
  95. package/dist/src/stream-utils.d.ts +191 -0
  96. package/dist/src/stream-utils.d.ts.map +1 -0
  97. package/dist/src/stream-utils.js +371 -0
  98. package/dist/src/stream-utils.js.map +1 -0
  99. package/package.json +15 -162
  100. package/src/abstract-message-stream.ts +553 -0
  101. package/src/abstract-multiaddr-connection.ts +93 -0
  102. package/src/abstract-stream-muxer.ts +239 -0
  103. package/src/abstract-stream.ts +51 -464
  104. package/src/errors.ts +10 -0
  105. package/src/get-thin-waist-addresses.browser.ts +5 -4
  106. package/src/get-thin-waist-addresses.ts +8 -12
  107. package/src/index.ts +31 -1
  108. package/src/length-prefixed-decoder.ts +98 -0
  109. package/src/message-queue.ts +156 -0
  110. package/src/mock-muxer.ts +304 -0
  111. package/src/mock-stream.ts +101 -0
  112. package/src/multiaddr/get-net-config.ts +112 -0
  113. package/src/multiaddr/index.ts +6 -0
  114. package/src/multiaddr/is-global-unicast.ts +8 -11
  115. package/src/multiaddr/is-link-local.ts +11 -20
  116. package/src/multiaddr/is-loopback.ts +12 -7
  117. package/src/multiaddr/is-network-address.ts +4 -19
  118. package/src/multiaddr/is-private.ts +9 -14
  119. package/src/multiaddr/utils.ts +46 -0
  120. package/src/multiaddr-connection-pair.ts +147 -0
  121. package/src/queue/index.ts +24 -11
  122. package/src/rate-limiter.ts +3 -30
  123. package/src/stream-pair.ts +90 -0
  124. package/src/stream-utils.ts +866 -0
  125. package/dist/src/abort-options.d.ts +0 -7
  126. package/dist/src/abort-options.d.ts.map +0 -1
  127. package/dist/src/abort-options.js +0 -14
  128. package/dist/src/abort-options.js.map +0 -1
  129. package/dist/src/array-equals.d.ts +0 -24
  130. package/dist/src/array-equals.d.ts.map +0 -1
  131. package/dist/src/array-equals.js +0 -31
  132. package/dist/src/array-equals.js.map +0 -1
  133. package/dist/src/close-source.d.ts +0 -4
  134. package/dist/src/close-source.d.ts.map +0 -1
  135. package/dist/src/close-source.js +0 -11
  136. package/dist/src/close-source.js.map +0 -1
  137. package/dist/src/close.d.ts +0 -21
  138. package/dist/src/close.d.ts.map +0 -1
  139. package/dist/src/close.js +0 -49
  140. package/dist/src/close.js.map +0 -1
  141. package/dist/src/merge-options.d.ts +0 -7
  142. package/dist/src/merge-options.d.ts.map +0 -1
  143. package/dist/src/merge-options.js +0 -128
  144. package/dist/src/merge-options.js.map +0 -1
  145. package/dist/src/multiaddr/is-ip-based.d.ts +0 -6
  146. package/dist/src/multiaddr/is-ip-based.d.ts.map +0 -1
  147. package/dist/src/multiaddr/is-ip-based.js +0 -18
  148. package/dist/src/multiaddr/is-ip-based.js.map +0 -1
  149. package/dist/src/stream-to-ma-conn.d.ts +0 -23
  150. package/dist/src/stream-to-ma-conn.d.ts.map +0 -1
  151. package/dist/src/stream-to-ma-conn.js +0 -75
  152. package/dist/src/stream-to-ma-conn.js.map +0 -1
  153. package/dist/typedoc-urls.json +0 -147
  154. package/src/abort-options.ts +0 -20
  155. package/src/array-equals.ts +0 -34
  156. package/src/close-source.ts +0 -14
  157. package/src/close.ts +0 -65
  158. package/src/merge-options.ts +0 -161
  159. package/src/multiaddr/is-ip-based.ts +0 -21
  160. package/src/stream-to-ma-conn.ts +0 -106
@@ -0,0 +1,37 @@
1
+ import { Uint8ArrayList } from 'uint8arraylist';
2
+ export interface LengthPrefixedDecoderInit {
3
+ /**
4
+ * How large the internal buffer is allowed to grow - attempting to store more
5
+ * data than this will throw
6
+ */
7
+ maxBufferSize?: number;
8
+ /**
9
+ * Throw an error if the message that would be read from the buffer is larger
10
+ * than this value
11
+ */
12
+ maxDataLength?: number;
13
+ /**
14
+ * Read a varint from the buffer
15
+ */
16
+ lengthDecoder?(data: Uint8ArrayList | Uint8Array): number;
17
+ /**
18
+ * Return how many bytes it takes to encode the passed value
19
+ */
20
+ encodingLength?(length: number): number;
21
+ }
22
+ /**
23
+ * Decode length-prefixed data from a buffer
24
+ */
25
+ export declare class LengthPrefixedDecoder {
26
+ private readonly buffer;
27
+ private readonly maxBufferSize;
28
+ private readonly lengthDecoder;
29
+ private readonly maxDataLength;
30
+ private readonly encodingLength;
31
+ constructor(init?: LengthPrefixedDecoderInit);
32
+ /**
33
+ * Decodes length-prefixed data
34
+ */
35
+ decode(buf: Uint8Array | Uint8ArrayList): Generator<Uint8ArrayList>;
36
+ }
37
+ //# sourceMappingURL=length-prefixed-decoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length-prefixed-decoder.d.ts","sourceRoot":"","sources":["../../src/length-prefixed-decoder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAM/C,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,GAAG,MAAM,CAAA;IAEzD;;OAEG;IACH,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CACxC;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA+C;IAC7E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA4B;gBAE9C,IAAI,GAAE,yBAA8B;IAQjD;;OAEG;IACD,MAAM,CAAE,GAAG,EAAE,UAAU,GAAG,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC;CA4CvE"}
@@ -0,0 +1,64 @@
1
+ import { InvalidParametersError } from '@libp2p/interface';
2
+ import * as varint from 'uint8-varint';
3
+ import { Uint8ArrayList } from 'uint8arraylist';
4
+ import { InvalidMessageLengthError } from "./stream-utils.js";
5
+ const DEFAULT_MAX_BUFFER_SIZE = 1024 * 1024 * 4;
6
+ const DEFAULT_MAX_DATA_LENGTH = 1024 * 1024 * 4;
7
+ /**
8
+ * Decode length-prefixed data from a buffer
9
+ */
10
+ export class LengthPrefixedDecoder {
11
+ buffer;
12
+ maxBufferSize;
13
+ lengthDecoder;
14
+ maxDataLength;
15
+ encodingLength;
16
+ constructor(init = {}) {
17
+ this.buffer = new Uint8ArrayList();
18
+ this.maxBufferSize = init.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
19
+ this.maxDataLength = init.maxDataLength ?? DEFAULT_MAX_DATA_LENGTH;
20
+ this.lengthDecoder = init.lengthDecoder ?? varint.decode;
21
+ this.encodingLength = init.encodingLength ?? varint.encodingLength;
22
+ }
23
+ /**
24
+ * Decodes length-prefixed data
25
+ */
26
+ *decode(buf) {
27
+ this.buffer.append(buf);
28
+ if (this.buffer.byteLength > this.maxBufferSize) {
29
+ throw new InvalidParametersError(`Buffer length limit exceeded - ${this.buffer.byteLength}/${this.maxBufferSize}`);
30
+ }
31
+ // Loop to consume as many bytes from the buffer as possible
32
+ // Eg: when a single chunk contains several frames
33
+ while (true) {
34
+ let dataLength;
35
+ try {
36
+ dataLength = this.lengthDecoder(this.buffer);
37
+ }
38
+ catch (err) {
39
+ if (err instanceof RangeError) {
40
+ // ignore errors where we don't have enough data to read the length
41
+ // prefix
42
+ break;
43
+ }
44
+ throw err;
45
+ }
46
+ if (dataLength < 0 || dataLength > this.maxDataLength) {
47
+ throw new InvalidMessageLengthError('Invalid message length');
48
+ }
49
+ const lengthLength = this.encodingLength(dataLength);
50
+ const chunkLength = lengthLength + dataLength;
51
+ if (this.buffer.byteLength >= chunkLength) {
52
+ const buf = this.buffer.sublist(lengthLength, chunkLength);
53
+ this.buffer.consume(chunkLength);
54
+ if (buf.byteLength > 0) {
55
+ yield buf;
56
+ }
57
+ }
58
+ else {
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ //# sourceMappingURL=length-prefixed-decoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"length-prefixed-decoder.js","sourceRoot":"","sources":["../../src/length-prefixed-decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAE7D,MAAM,uBAAuB,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAA;AAC/C,MAAM,uBAAuB,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,CAAA;AA0B/C;;GAEG;AACH,MAAM,OAAO,qBAAqB;IACf,MAAM,CAAgB;IACtB,aAAa,CAAQ;IACrB,aAAa,CAA+C;IAC5D,aAAa,CAAQ;IACrB,cAAc,CAA4B;IAE3D,YAAa,OAAkC,EAAE;QAC/C,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,EAAE,CAAA;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAA;QAClE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAA;QAClE,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,MAAM,CAAA;QACxD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAA;IACpE,CAAC;IAED;;OAEG;IACH,CAAE,MAAM,CAAE,GAAgC;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAEvB,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YAChD,MAAM,IAAI,sBAAsB,CAAC,kCAAkC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC,CAAA;QACpH,CAAC;QAED,4DAA4D;QAC5D,kDAAkD;QAClD,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,UAAkB,CAAA;YAEtB,IAAI,CAAC;gBACH,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBAC9B,mEAAmE;oBACnE,SAAS;oBACT,MAAK;gBACP,CAAC;gBAED,MAAM,GAAG,CAAA;YACX,CAAC;YAED,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;gBACtD,MAAM,IAAI,yBAAyB,CAAC,wBAAwB,CAAC,CAAA;YAC/D,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;YACpD,MAAM,WAAW,GAAG,YAAY,GAAG,UAAU,CAAA;YAE7C,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,WAAW,EAAE,CAAC;gBAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;gBAE1D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;gBAEhC,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;oBACvB,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,61 @@
1
+ import { StreamMessageEvent } from '@libp2p/interface';
2
+ import { TypedEventEmitter } from 'main-event';
3
+ import type { Logger } from '@libp2p/interface';
4
+ export interface MessageQueueEvents {
5
+ /**
6
+ * Message data
7
+ */
8
+ message: StreamMessageEvent;
9
+ /**
10
+ * Emitted when the queue is empty
11
+ */
12
+ drain: Event;
13
+ /**
14
+ * The remote closed the connection abruptly
15
+ */
16
+ reset: Event;
17
+ }
18
+ export interface MessageQueueInit {
19
+ /**
20
+ * How much delay there should be between each message send in ms (note that
21
+ * even 0 introduces a small delay)
22
+ *
23
+ * @default 0
24
+ */
25
+ delay?: number;
26
+ /**
27
+ * How many messages to hold in the send queue before applying backpressure to
28
+ * the sender
29
+ */
30
+ capacity?: number;
31
+ /**
32
+ * Data messages larger than this size will be chunked into smaller messages.
33
+ *
34
+ * Defaults to the maximum TCP package size.
35
+ *
36
+ * @default 65_536
37
+ */
38
+ chunkSize?: number;
39
+ }
40
+ /**
41
+ * Accepts events to emit after a short delay, and with a configurable maximum
42
+ * queue capacity after which the send method will return false to let us
43
+ * simulate write backpressure.
44
+ */
45
+ export declare class MessageQueue<Events> extends TypedEventEmitter<Events & MessageQueueEvents> {
46
+ needsDrain: boolean;
47
+ private queue;
48
+ private capacity;
49
+ private delay;
50
+ private log;
51
+ private chunkSize;
52
+ constructor(init: MessageQueueInit & {
53
+ log: Logger;
54
+ });
55
+ send(evt: Event): boolean;
56
+ pause(): void;
57
+ resume(): void;
58
+ onIdle(): Promise<void>;
59
+ size(): number;
60
+ }
61
+ //# sourceMappingURL=message-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-queue.d.ts","sourceRoot":"","sources":["../../src/message-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAI9C,OAAO,KAAK,EAAgB,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAI7D,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAA;IAE3B;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;IAEZ;;OAEG;IACH,KAAK,EAAE,KAAK,CAAA;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,MAAM,CAAE,SAAQ,iBAAiB,CAAC,MAAM,GAAG,kBAAkB,CAAC;IAC/E,UAAU,EAAE,OAAO,CAAA;IAE1B,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,GAAG,CAAQ;IACnB,OAAO,CAAC,SAAS,CAAQ;gBAEZ,IAAI,EAAE,gBAAgB,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE;IAuBrD,IAAI,CAAE,GAAG,EAAE,KAAK,GAAG,OAAO;IA2C1B,KAAK,IAAK,IAAI;IAId,MAAM,IAAK,IAAI;IAIf,MAAM,IAAK,OAAO,CAAC,IAAI,CAAC;IAIxB,IAAI,IAAK,MAAM;CAGhB"}
@@ -0,0 +1,93 @@
1
+ import { StreamMessageEvent } from '@libp2p/interface';
2
+ import delay from 'delay';
3
+ import { TypedEventEmitter } from 'main-event';
4
+ import { raceSignal } from 'race-signal';
5
+ import { isUint8ArrayList, Uint8ArrayList } from 'uint8arraylist';
6
+ import { Queue } from './queue/index.js';
7
+ const DEFAULT_CHUNK_SIZE = 1024 * 64;
8
+ /**
9
+ * Accepts events to emit after a short delay, and with a configurable maximum
10
+ * queue capacity after which the send method will return false to let us
11
+ * simulate write backpressure.
12
+ */
13
+ export class MessageQueue extends TypedEventEmitter {
14
+ needsDrain;
15
+ queue;
16
+ capacity;
17
+ delay;
18
+ log;
19
+ chunkSize;
20
+ constructor(init) {
21
+ super();
22
+ this.needsDrain = false;
23
+ this.queue = new Queue({
24
+ concurrency: 1
25
+ });
26
+ this.capacity = init.capacity ?? 5;
27
+ this.delay = init.delay ?? 0;
28
+ this.log = init.log;
29
+ this.chunkSize = init.chunkSize ?? DEFAULT_CHUNK_SIZE;
30
+ this.queue.addEventListener('idle', () => {
31
+ if (this.needsDrain) {
32
+ this.log('network send queue drained');
33
+ this.needsDrain = false;
34
+ this.safeDispatchEvent('drain');
35
+ }
36
+ else {
37
+ this.log('network send queue idle');
38
+ }
39
+ });
40
+ }
41
+ send(evt) {
42
+ if (isMessageEvent(evt)) {
43
+ // chunk outgoing messages to match TCP packet sizes
44
+ const data = new Uint8ArrayList(evt.data);
45
+ while (data.byteLength > 0) {
46
+ const end = Math.min(this.chunkSize, data.byteLength);
47
+ const chunk = data.sublist(0, end);
48
+ data.consume(chunk.byteLength);
49
+ const chunkEvent = new StreamMessageEvent(chunk);
50
+ this.queue.add(async (opts) => {
51
+ if (this.delay > 0) {
52
+ await raceSignal(delay(this.delay), opts.signal);
53
+ }
54
+ this.dispatchEvent(opts.evt);
55
+ }, {
56
+ evt: chunkEvent
57
+ });
58
+ }
59
+ }
60
+ else {
61
+ this.queue.add(async (opts) => {
62
+ if (this.delay > 0) {
63
+ await raceSignal(delay(this.delay), opts.signal);
64
+ }
65
+ this.dispatchEvent(opts.evt);
66
+ }, {
67
+ evt
68
+ });
69
+ }
70
+ if (this.queue.size >= this.capacity) {
71
+ this.log('network send queue full');
72
+ this.needsDrain = true;
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ pause() {
78
+ this.queue.pause();
79
+ }
80
+ resume() {
81
+ this.queue.resume();
82
+ }
83
+ onIdle() {
84
+ return this.queue.onIdle();
85
+ }
86
+ size() {
87
+ return this.queue.size;
88
+ }
89
+ }
90
+ function isMessageEvent(evt) {
91
+ return evt?.data instanceof Uint8Array || isUint8ArrayList(evt?.data);
92
+ }
93
+ //# sourceMappingURL=message-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-queue.js","sourceRoot":"","sources":["../../src/message-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { AbstractStreamInit } from './abstract-stream.ts';
2
+ import type { StreamMuxerFactory, StreamMuxerOptions } from '@libp2p/interface';
3
+ import type { SupportedEncodings } from 'uint8arrays/from-string';
4
+ interface DataMessage {
5
+ id: string;
6
+ type: 'data';
7
+ chunk: Uint8Array;
8
+ }
9
+ interface ResetMessage {
10
+ id: string;
11
+ type: 'reset';
12
+ }
13
+ interface CloseWriteMessage {
14
+ id: string;
15
+ type: 'closeWrite';
16
+ }
17
+ interface CloseReadMessage {
18
+ id: string;
19
+ type: 'closeRead';
20
+ }
21
+ interface CreateMessage {
22
+ id: string;
23
+ type: 'create';
24
+ protocol?: string;
25
+ }
26
+ interface PauseMessage {
27
+ id: string;
28
+ type: 'pause';
29
+ }
30
+ interface ResumeMessage {
31
+ id: string;
32
+ type: 'resume';
33
+ }
34
+ type StreamMessage = DataMessage | ResetMessage | CloseWriteMessage | CloseReadMessage | CreateMessage | PauseMessage | ResumeMessage;
35
+ export interface MockMuxedStreamInit extends AbstractStreamInit {
36
+ sendMessage(message: StreamMessage): boolean;
37
+ encoding: SupportedEncodings;
38
+ }
39
+ interface MockMuxerInit extends StreamMuxerOptions {
40
+ /**
41
+ * How long the input queue can grow
42
+ */
43
+ maxInputQueueSize?: number;
44
+ /**
45
+ * How to encode data message
46
+ *
47
+ * @default base64
48
+ */
49
+ encoding?: SupportedEncodings;
50
+ /**
51
+ * How large muxer messages are allowed to be
52
+ */
53
+ maxMessageSize?: number;
54
+ }
55
+ export declare function mockMuxer(init?: MockMuxerInit): StreamMuxerFactory;
56
+ export {};
57
+ //# sourceMappingURL=mock-muxer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-muxer.d.ts","sourceRoot":"","sources":["../../src/mock-muxer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,KAAK,EAA6D,kBAAkB,EAAoC,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE5K,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,CAAA;CACd;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,YAAY,CAAA;CACnB;AAED,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,CAAA;CACd;AAED,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;CACf;AAED,KAAK,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,aAAa,GAAG,YAAY,GAAG,aAAa,CAAA;AAErI,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAA;IAC5C,QAAQ,EAAE,kBAAkB,CAAA;CAC7B;AAsFD,UAAU,aAAc,SAAQ,kBAAkB;IAChD;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAE7B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AA+ID,wBAAgB,SAAS,CAAE,IAAI,GAAE,aAAkB,GAAG,kBAAkB,CAEvE"}
@@ -0,0 +1,204 @@
1
+ import * as cborg from 'cborg';
2
+ import * as lp from 'it-length-prefixed';
3
+ import { pushable } from 'it-pushable';
4
+ import { Uint8ArrayList } from 'uint8arraylist';
5
+ import { AbstractStreamMuxer } from "./abstract-stream-muxer.js";
6
+ import { AbstractStream } from "./abstract-stream.js";
7
+ import { Queue } from './queue/index.js';
8
+ class MockMuxedStream extends AbstractStream {
9
+ sendMessage;
10
+ dataQueue;
11
+ encoding;
12
+ constructor(init) {
13
+ super(init);
14
+ this.sendMessage = init.sendMessage;
15
+ this.encoding = init.encoding;
16
+ this.dataQueue = new Queue({
17
+ concurrency: 1
18
+ });
19
+ if (this.direction === 'outbound') {
20
+ this.sendMessage({
21
+ id: this.id,
22
+ type: 'create',
23
+ protocol: this.protocol
24
+ });
25
+ }
26
+ }
27
+ sendData(data) {
28
+ const canSendMore = this.sendMessage({
29
+ id: this.id,
30
+ type: 'data',
31
+ chunk: data.subarray()
32
+ });
33
+ return {
34
+ sentBytes: data.byteLength,
35
+ canSendMore
36
+ };
37
+ }
38
+ sendReset() {
39
+ this.sendMessage({
40
+ id: this.id,
41
+ type: 'reset'
42
+ });
43
+ }
44
+ async sendCloseWrite(options) {
45
+ this.sendMessage({
46
+ id: this.id,
47
+ type: 'closeWrite'
48
+ });
49
+ options?.signal?.throwIfAborted();
50
+ }
51
+ async sendCloseRead(options) {
52
+ this.sendMessage({
53
+ id: this.id,
54
+ type: 'closeRead'
55
+ });
56
+ options?.signal?.throwIfAborted();
57
+ }
58
+ sendPause() {
59
+ this.sendMessage({
60
+ id: this.id,
61
+ type: 'pause'
62
+ });
63
+ }
64
+ sendResume() {
65
+ this.sendMessage({
66
+ id: this.id,
67
+ type: 'resume'
68
+ });
69
+ }
70
+ onRemotePaused() {
71
+ this.dataQueue.pause();
72
+ }
73
+ onRemoteResumed() {
74
+ this.dataQueue.resume();
75
+ }
76
+ }
77
+ // CBOR encoding of non-message data fields
78
+ const MESSAGE_OVERHEAD = 30;
79
+ class MockMuxer extends AbstractStreamMuxer {
80
+ input;
81
+ maxInputQueueSize;
82
+ encoding;
83
+ maxMessageSize;
84
+ nextStreamId;
85
+ constructor(maConn, init) {
86
+ super(maConn, {
87
+ ...init,
88
+ protocol: '/mock-muxer/1.0.0',
89
+ name: 'mock-muxer'
90
+ });
91
+ this.maxInputQueueSize = init.maxInputQueueSize ?? 1024 * 1024 * 10;
92
+ this.maxMessageSize = (init.maxMessageSize ?? 1024 * 1024 * 4) + MESSAGE_OVERHEAD;
93
+ this.encoding = init.encoding ?? 'base64';
94
+ this.input = pushable();
95
+ this.sendMessage = this.sendMessage.bind(this);
96
+ this.nextStreamId = this.maConn.direction === 'outbound' ? 0 : 1;
97
+ Promise.resolve()
98
+ .then(async () => {
99
+ for await (const buf of lp.decode(this.input, {
100
+ maxDataLength: this.maxMessageSize
101
+ })) {
102
+ this.onMessage(cborg.decode(buf.subarray()));
103
+ }
104
+ })
105
+ .catch(err => {
106
+ this.abort(err);
107
+ });
108
+ }
109
+ onData(data) {
110
+ if (this.input.readableLength >= this.maxInputQueueSize) {
111
+ this.abort(new Error(`Input queue exceeded maximum size ${this.input.readableLength} >= ${this.maxInputQueueSize}`));
112
+ return;
113
+ }
114
+ this.input.push(data);
115
+ }
116
+ sendMessage(message) {
117
+ if (message.type === 'data') {
118
+ this.log.trace('send message %o', { ...message, chunk: `[ ${message.chunk.byteLength} bytes ]` });
119
+ }
120
+ else {
121
+ this.log.trace('send message %o', message);
122
+ }
123
+ const buf = cborg.encode(message);
124
+ const encoded = lp.encode.single(buf, {
125
+ maxDataLength: this.maxMessageSize
126
+ });
127
+ return this.send(encoded);
128
+ }
129
+ onMessage(message) {
130
+ if (message.type === 'data') {
131
+ this.log.trace('incoming message %o', { ...message, chunk: `[ ${message.chunk.byteLength} bytes ]` });
132
+ }
133
+ else {
134
+ this.log.trace('incoming message %o', message);
135
+ }
136
+ let stream = this.streams.find(s => s.id === message.id);
137
+ if (message.type === 'create') {
138
+ if (stream != null) {
139
+ throw new Error(`Already had stream for ${message.id}`);
140
+ }
141
+ this.log.trace('create stream inbound %s', message.id);
142
+ stream = this._createStream(message.id, 'inbound', {
143
+ protocol: message.protocol
144
+ });
145
+ this.onRemoteStream(stream);
146
+ }
147
+ if (stream == null) {
148
+ this.log.error(`No stream found for ${message.id}`);
149
+ return;
150
+ }
151
+ if (message.type === 'data') {
152
+ stream.onData(message.chunk);
153
+ }
154
+ else if (message.type === 'reset') {
155
+ stream.onRemoteReset();
156
+ }
157
+ else if (message.type === 'closeWrite') {
158
+ stream.onRemoteCloseWrite();
159
+ }
160
+ else if (message.type === 'closeRead') {
161
+ stream.onRemoteCloseRead();
162
+ }
163
+ else if (message.type === 'pause') {
164
+ stream.onRemotePaused();
165
+ }
166
+ else if (message.type === 'resume') {
167
+ stream.onRemoteResumed();
168
+ }
169
+ }
170
+ async onCreateStream(options) {
171
+ this.nextStreamId += 2;
172
+ return this._createStream(`${this.nextStreamId}`, 'outbound', options);
173
+ }
174
+ _createStream(id, direction, options) {
175
+ this.log.trace('createStream %s %s', direction, id);
176
+ return new MockMuxedStream({
177
+ ...this.streamOptions,
178
+ ...options,
179
+ id,
180
+ direction,
181
+ log: this.log.newScope(`stream:${direction}:${id}`),
182
+ sendMessage: this.sendMessage,
183
+ encoding: this.encoding,
184
+ maxMessageSize: this.maxMessageSize - MESSAGE_OVERHEAD,
185
+ protocol: ''
186
+ });
187
+ }
188
+ }
189
+ class MockMuxerFactory {
190
+ protocol = '/mock-muxer/1.0.0';
191
+ init;
192
+ constructor(init) {
193
+ this.init = init;
194
+ }
195
+ createStreamMuxer(maConn) {
196
+ return new MockMuxer(maConn, {
197
+ ...this.init
198
+ });
199
+ }
200
+ }
201
+ export function mockMuxer(init = {}) {
202
+ return new MockMuxerFactory(init);
203
+ }
204
+ //# sourceMappingURL=mock-muxer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-muxer.js","sourceRoot":"","sources":["../../src/mock-muxer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { AbstractStream } from './abstract-stream.ts';
2
+ import type { SendResult } from './abstract-message-stream.ts';
3
+ import type { MessageQueue, MessageQueueEvents } from './message-queue.ts';
4
+ import type { AbortOptions, MessageStreamDirection, TypedEventTarget } from '@libp2p/interface';
5
+ import type { Uint8ArrayList } from 'uint8arraylist';
6
+ interface MockStreamMessages extends MessageQueueEvents {
7
+ closeWrite: Event;
8
+ closeRead: Event;
9
+ }
10
+ interface MockStreamInit {
11
+ delay?: number;
12
+ direction: MessageStreamDirection;
13
+ local: MessageQueue<MockStreamMessages>;
14
+ remote: TypedEventTarget<MockStreamMessages>;
15
+ }
16
+ export declare class MockStream extends AbstractStream {
17
+ private local;
18
+ private remote;
19
+ constructor(init: MockStreamInit);
20
+ sendData(data: Uint8ArrayList): SendResult;
21
+ sendReset(): void;
22
+ sendCloseWrite(options?: AbortOptions): Promise<void>;
23
+ sendCloseRead(options?: AbortOptions): Promise<void>;
24
+ sendPause(): void;
25
+ sendResume(): void;
26
+ onRemotePaused(): void;
27
+ onRemoteResumed(): void;
28
+ onMuxerDrain(): void;
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=mock-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-stream.d.ts","sourceRoot":"","sources":["../../src/mock-stream.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,UAAU,EAAE,KAAK,CAAA;IACjB,SAAS,EAAE,KAAK,CAAA;CACjB;AAED,UAAU,cAAc;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,sBAAsB,CAAA;IACjC,KAAK,EAAE,YAAY,CAAC,kBAAkB,CAAC,CAAA;IACvC,MAAM,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;CAC7C;AAID,qBAAa,UAAW,SAAQ,cAAc;IAC5C,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,MAAM,CAAsC;gBAEvC,IAAI,EAAE,cAAc;IA2BjC,QAAQ,CAAE,IAAI,EAAE,cAAc,GAAG,UAAU;IAS3C,SAAS,IAAK,IAAI;IAIZ,cAAc,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtD,aAAa,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3D,SAAS,IAAK,IAAI;IAIlB,UAAU,IAAK,IAAI;IAInB,cAAc,IAAK,IAAI;IAIvB,eAAe,IAAK,IAAI;IAIxB,YAAY,IAAK,IAAI;CAGtB"}
@@ -0,0 +1,69 @@
1
+ import { StreamMessageEvent } from '@libp2p/interface';
2
+ import { defaultLogger } from '@libp2p/logger';
3
+ import { raceSignal } from 'race-signal';
4
+ import { AbstractStream } from "./abstract-stream.js";
5
+ let streamId = 0;
6
+ export class MockStream extends AbstractStream {
7
+ local;
8
+ remote;
9
+ constructor(init) {
10
+ const id = `${streamId++}`;
11
+ super({
12
+ ...init,
13
+ id,
14
+ log: defaultLogger().forComponent(`libp2p:stream-pair:${init.direction}:${id}`)
15
+ });
16
+ this.local = init.local;
17
+ this.remote = init.remote;
18
+ this.local.addEventListener('drain', () => {
19
+ this.safeDispatchEvent('drain');
20
+ });
21
+ this.remote.addEventListener('message', (evt) => {
22
+ this.onData(evt.data);
23
+ });
24
+ this.remote.addEventListener('reset', (evt) => {
25
+ this.onRemoteReset();
26
+ });
27
+ this.remote.addEventListener('closeWrite', (evt) => {
28
+ this.onRemoteCloseWrite();
29
+ });
30
+ }
31
+ sendData(data) {
32
+ const canSendMore = this.local.send(new StreamMessageEvent(data));
33
+ return {
34
+ sentBytes: data.byteLength,
35
+ canSendMore
36
+ };
37
+ }
38
+ sendReset() {
39
+ this.local.send(new Event('reset'));
40
+ }
41
+ async sendCloseWrite(options) {
42
+ return raceSignal(new Promise((resolve, reject) => {
43
+ this.local.send(new Event('closeWrite'));
44
+ this.local.onIdle().then(resolve, reject);
45
+ }), options?.signal);
46
+ }
47
+ async sendCloseRead(options) {
48
+ return raceSignal(new Promise((resolve, reject) => {
49
+ this.local.send(new Event('closeRead'));
50
+ this.local.onIdle().then(resolve, reject);
51
+ }), options?.signal);
52
+ }
53
+ sendPause() {
54
+ this.local.send(new Event('pause'));
55
+ }
56
+ sendResume() {
57
+ this.local.send(new Event('resume'));
58
+ }
59
+ onRemotePaused() {
60
+ this.local.pause();
61
+ }
62
+ onRemoteResumed() {
63
+ this.local.resume();
64
+ }
65
+ onMuxerDrain() {
66
+ this.local.resume();
67
+ }
68
+ }
69
+ //# sourceMappingURL=mock-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-stream.js","sourceRoot":"","sources":["../../src/mock-stream.ts"],"names":[],"mappings":"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"}