@libp2p/interface-compliance-tests 6.5.0-8484de8a2 → 6.5.0-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 (131) hide show
  1. package/dist/src/connection-encryption/index.d.ts.map +1 -1
  2. package/dist/src/connection-encryption/index.js +15 -24
  3. package/dist/src/connection-encryption/index.js.map +1 -1
  4. package/dist/src/connection-encryption/utils/index.d.ts +3 -0
  5. package/dist/src/connection-encryption/utils/index.d.ts.map +1 -0
  6. package/dist/src/connection-encryption/utils/index.js +21 -0
  7. package/dist/src/connection-encryption/utils/index.js.map +1 -0
  8. package/dist/src/matchers.d.ts +12 -0
  9. package/dist/src/matchers.d.ts.map +1 -0
  10. package/dist/src/matchers.js +14 -0
  11. package/dist/src/matchers.js.map +1 -0
  12. package/dist/src/mocks/connection-manager.d.ts +27 -0
  13. package/dist/src/mocks/connection-manager.d.ts.map +1 -0
  14. package/dist/src/mocks/connection-manager.js +147 -0
  15. package/dist/src/mocks/connection-manager.js.map +1 -0
  16. package/dist/src/mocks/connection.d.ts +41 -0
  17. package/dist/src/mocks/connection.d.ts.map +1 -0
  18. package/dist/src/mocks/connection.js +236 -0
  19. package/dist/src/mocks/connection.js.map +1 -0
  20. package/dist/src/mocks/duplex.d.ts +4 -0
  21. package/dist/src/mocks/duplex.d.ts.map +1 -0
  22. package/dist/src/mocks/duplex.js +9 -0
  23. package/dist/src/mocks/duplex.js.map +1 -0
  24. package/dist/src/mocks/index.d.ts +12 -0
  25. package/dist/src/mocks/index.d.ts.map +1 -0
  26. package/dist/src/mocks/index.js +8 -0
  27. package/dist/src/mocks/index.js.map +1 -0
  28. package/dist/src/mocks/multiaddr-connection.d.ts +17 -0
  29. package/dist/src/mocks/multiaddr-connection.d.ts.map +1 -0
  30. package/dist/src/mocks/multiaddr-connection.js +64 -0
  31. package/dist/src/mocks/multiaddr-connection.js.map +1 -0
  32. package/dist/src/mocks/muxer.d.ts +36 -0
  33. package/dist/src/mocks/muxer.d.ts.map +1 -0
  34. package/dist/src/mocks/muxer.js +234 -0
  35. package/dist/src/mocks/muxer.js.map +1 -0
  36. package/dist/src/mocks/registrar.d.ts +16 -0
  37. package/dist/src/mocks/registrar.d.ts.map +1 -0
  38. package/dist/src/mocks/registrar.js +66 -0
  39. package/dist/src/mocks/registrar.js.map +1 -0
  40. package/dist/src/mocks/upgrader.d.ts +9 -0
  41. package/dist/src/mocks/upgrader.d.ts.map +1 -0
  42. package/dist/src/mocks/upgrader.js +46 -0
  43. package/dist/src/mocks/upgrader.js.map +1 -0
  44. package/dist/src/pubsub/api.d.ts +6 -0
  45. package/dist/src/pubsub/api.d.ts.map +1 -0
  46. package/dist/src/pubsub/api.js +88 -0
  47. package/dist/src/pubsub/api.js.map +1 -0
  48. package/dist/src/pubsub/connection-handlers.d.ts +6 -0
  49. package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
  50. package/dist/src/pubsub/connection-handlers.js +329 -0
  51. package/dist/src/pubsub/connection-handlers.js.map +1 -0
  52. package/dist/src/pubsub/emit-self.d.ts +6 -0
  53. package/dist/src/pubsub/emit-self.d.ts.map +1 -0
  54. package/dist/src/pubsub/emit-self.js +80 -0
  55. package/dist/src/pubsub/emit-self.js.map +1 -0
  56. package/dist/src/pubsub/index.d.ts +18 -0
  57. package/dist/src/pubsub/index.d.ts.map +1 -0
  58. package/dist/src/pubsub/index.js +17 -0
  59. package/dist/src/pubsub/index.js.map +1 -0
  60. package/dist/src/pubsub/messages.d.ts +6 -0
  61. package/dist/src/pubsub/messages.d.ts.map +1 -0
  62. package/dist/src/pubsub/messages.js +48 -0
  63. package/dist/src/pubsub/messages.js.map +1 -0
  64. package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
  65. package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
  66. package/dist/src/pubsub/multiple-nodes.js +350 -0
  67. package/dist/src/pubsub/multiple-nodes.js.map +1 -0
  68. package/dist/src/pubsub/two-nodes.d.ts +6 -0
  69. package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
  70. package/dist/src/pubsub/two-nodes.js +216 -0
  71. package/dist/src/pubsub/two-nodes.js.map +1 -0
  72. package/dist/src/pubsub/utils.d.ts +5 -0
  73. package/dist/src/pubsub/utils.d.ts.map +1 -0
  74. package/dist/src/pubsub/utils.js +27 -0
  75. package/dist/src/pubsub/utils.js.map +1 -0
  76. package/dist/src/stream-muxer/base-test.d.ts.map +1 -1
  77. package/dist/src/stream-muxer/base-test.js +345 -62
  78. package/dist/src/stream-muxer/base-test.js.map +1 -1
  79. package/dist/src/stream-muxer/close-test.d.ts.map +1 -1
  80. package/dist/src/stream-muxer/close-test.js +320 -253
  81. package/dist/src/stream-muxer/close-test.js.map +1 -1
  82. package/dist/src/stream-muxer/index.js +2 -2
  83. package/dist/src/stream-muxer/index.js.map +1 -1
  84. package/dist/src/stream-muxer/{stream-test.d.ts → mega-stress-test.d.ts} +2 -2
  85. package/dist/src/stream-muxer/mega-stress-test.d.ts.map +1 -0
  86. package/dist/src/stream-muxer/mega-stress-test.js +11 -0
  87. package/dist/src/stream-muxer/mega-stress-test.js.map +1 -0
  88. package/dist/src/stream-muxer/spawner.d.ts +4 -0
  89. package/dist/src/stream-muxer/spawner.d.ts.map +1 -0
  90. package/dist/src/stream-muxer/spawner.js +39 -0
  91. package/dist/src/stream-muxer/spawner.js.map +1 -0
  92. package/dist/src/stream-muxer/stress-test.d.ts.map +1 -1
  93. package/dist/src/stream-muxer/stress-test.js +16 -70
  94. package/dist/src/stream-muxer/stress-test.js.map +1 -1
  95. package/dist/src/transport/index.d.ts.map +1 -1
  96. package/dist/src/transport/index.js +203 -232
  97. package/dist/src/transport/index.js.map +1 -1
  98. package/dist/src/transport/utils.js +2 -2
  99. package/dist/src/transport/utils.js.map +1 -1
  100. package/package.json +51 -23
  101. package/src/connection-encryption/index.ts +20 -27
  102. package/src/connection-encryption/utils/index.ts +27 -0
  103. package/src/matchers.ts +18 -0
  104. package/src/mocks/connection-manager.ts +216 -0
  105. package/src/mocks/connection.ts +309 -0
  106. package/src/mocks/duplex.ts +11 -0
  107. package/src/mocks/index.ts +11 -0
  108. package/src/mocks/multiaddr-connection.ts +80 -0
  109. package/src/mocks/muxer.ts +331 -0
  110. package/src/mocks/registrar.ts +86 -0
  111. package/src/mocks/upgrader.ts +65 -0
  112. package/src/pubsub/api.ts +116 -0
  113. package/src/pubsub/connection-handlers.ts +413 -0
  114. package/src/pubsub/emit-self.ts +99 -0
  115. package/src/pubsub/index.ts +34 -0
  116. package/src/pubsub/messages.ts +59 -0
  117. package/src/pubsub/multiple-nodes.ts +440 -0
  118. package/src/pubsub/two-nodes.ts +272 -0
  119. package/src/pubsub/utils.ts +34 -0
  120. package/src/stream-muxer/base-test.ts +413 -75
  121. package/src/stream-muxer/close-test.ts +343 -304
  122. package/src/stream-muxer/index.ts +2 -2
  123. package/src/stream-muxer/mega-stress-test.ts +14 -0
  124. package/src/stream-muxer/spawner.ts +57 -0
  125. package/src/stream-muxer/stress-test.ts +18 -92
  126. package/src/transport/index.ts +241 -280
  127. package/src/transport/utils.ts +2 -2
  128. package/dist/src/stream-muxer/stream-test.d.ts.map +0 -1
  129. package/dist/src/stream-muxer/stream-test.js +0 -289
  130. package/dist/src/stream-muxer/stream-test.js.map +0 -1
  131. package/src/stream-muxer/stream-test.ts +0 -380
@@ -0,0 +1,34 @@
1
+ import { generateKeyPair } from '@libp2p/crypto/keys'
2
+ import { defaultLogger } from '@libp2p/logger'
3
+ import { peerIdFromPrivateKey } from '@libp2p/peer-id'
4
+ import { TypedEventEmitter } from 'main-event'
5
+ import { pEvent } from 'p-event'
6
+ import pWaitFor from 'p-wait-for'
7
+ import { mockConnectionManager, mockRegistrar, mockNetwork } from '../mocks/index.js'
8
+ import type { MockNetworkComponents } from '../mocks/index.js'
9
+ import type { PeerId, PubSub, SubscriptionChangeData } from '@libp2p/interface'
10
+
11
+ export async function waitForSubscriptionUpdate (a: PubSub, b: PeerId): Promise<void> {
12
+ await pWaitFor(async () => {
13
+ const event = await pEvent<'subscription-change', CustomEvent<SubscriptionChangeData>>(a, 'subscription-change')
14
+
15
+ return event.detail.peerId.equals(b)
16
+ })
17
+ }
18
+
19
+ export async function createComponents (): Promise<MockNetworkComponents> {
20
+ const privateKey = await generateKeyPair('Ed25519')
21
+
22
+ const components: any = {
23
+ peerId: peerIdFromPrivateKey(privateKey),
24
+ privateKey,
25
+ registrar: mockRegistrar(),
26
+ events: new TypedEventEmitter(),
27
+ logger: defaultLogger()
28
+ }
29
+ components.connectionManager = mockConnectionManager(components)
30
+
31
+ mockNetwork.addNode(components)
32
+
33
+ return components
34
+ }
@@ -1,120 +1,458 @@
1
- import { multiaddrConnectionPair, byteStream } from '@libp2p/utils'
2
1
  import { expect } from 'aegir/chai'
3
- import { pEvent } from 'p-event'
2
+ import all from 'it-all'
3
+ import { byteStream } from 'it-byte-stream'
4
+ import map from 'it-map'
5
+ import { duplexPair } from 'it-pair/duplex'
6
+ import { pipe } from 'it-pipe'
7
+ import defer from 'p-defer'
8
+ import { Uint8ArrayList } from 'uint8arraylist'
4
9
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
10
+ import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
11
+ import { isValidTick } from '../is-valid-tick.js'
5
12
  import type { TestSetup } from '../index.js'
6
- import type { Stream, StreamMuxer, StreamMuxerFactory } from '@libp2p/interface'
13
+ import type { Stream, StreamMuxerFactory } from '@libp2p/interface'
14
+ import type { Source } from 'it-stream-types'
15
+ import type { DeferredPromise } from 'p-defer'
7
16
 
8
17
  export default (common: TestSetup<StreamMuxerFactory>): void => {
9
18
  describe('base', () => {
10
- let dialer: StreamMuxer
11
- let listener: StreamMuxer
12
-
13
- beforeEach(async () => {
14
- const [outboundConnection, inboundConnection] = multiaddrConnectionPair()
19
+ it('should open a stream from the dialer', async () => {
20
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
21
+ const onStreamPromise: DeferredPromise<Stream> = defer()
22
+ const onStreamEndPromise: DeferredPromise<Stream> = defer()
15
23
 
16
24
  const dialerFactory = await common.setup()
17
- dialer = dialerFactory.createStreamMuxer(outboundConnection)
25
+ const dialer = dialerFactory.createStreamMuxer({
26
+ direction: 'outbound'
27
+ })
18
28
 
19
29
  const listenerFactory = await common.setup()
20
- listener = listenerFactory.createStreamMuxer(inboundConnection)
21
- })
30
+ const listener = listenerFactory.createStreamMuxer({
31
+ direction: 'inbound',
32
+ onIncomingStream: (stream) => {
33
+ onStreamPromise.resolve(stream)
34
+ },
35
+ onStreamEnd: (stream) => {
36
+ onStreamEndPromise.resolve(stream)
37
+ }
38
+ })
22
39
 
23
- afterEach(async () => {
24
- await dialer?.close()
25
- await listener?.close()
26
- })
40
+ void pipe(p[0], dialer, p[0])
41
+ void pipe(p[1], listener, p[1])
27
42
 
28
- it('should have a protocol', async () => {
29
- expect(dialer.protocol).to.be.a('string')
30
- })
43
+ const dialerStream = await dialer.newStream()
44
+ expect(dialer.streams).to.include(dialerStream)
45
+ expect(isValidTick(dialerStream.timeline.open)).to.equal(true)
31
46
 
32
- it('should be open', async () => {
33
- expect(dialer.status).to.equal('open')
34
- })
47
+ const dialerBytes = byteStream(dialerStream)
48
+ void dialerBytes.write(uint8ArrayFromString('hello'))
35
49
 
36
- it('should be closing during closing', async () => {
37
- const closePromise = dialer.close()
38
- expect(dialer.status).to.equal('closing')
50
+ const listenerStream = await onStreamPromise.promise
51
+ expect(isValidTick(listenerStream.timeline.open)).to.equal(true)
52
+ // Make sure the stream is being tracked
53
+ expect(listener.streams).to.include(listenerStream)
39
54
 
40
- await closePromise
41
- })
55
+ await dialerStream.close()
56
+ await listenerStream.close()
57
+
58
+ // Make sure stream is closed properly
59
+ const endedStream = await onStreamEndPromise.promise
60
+ expect(listener.streams).to.not.include(endedStream)
61
+
62
+ if (endedStream.timeline.close == null) {
63
+ throw new Error('timeline had no close time')
64
+ }
65
+
66
+ // Make sure the stream is removed from tracking
67
+ expect(isValidTick(endedStream.timeline.close)).to.equal(true)
42
68
 
43
- it('should be closed after closing', async () => {
44
69
  await dialer.close()
70
+ await listener.close()
45
71
 
46
- expect(dialer.status).to.equal('closed')
72
+ // ensure we have no streams left
73
+ expect(dialer.streams).to.have.length(0)
74
+ expect(listener.streams).to.have.length(0)
47
75
  })
48
76
 
49
- it('should open a stream', async () => {
50
- const [
51
- listenerStream,
52
- dialerStream
53
- ] = await Promise.all([
54
- pEvent<'stream', CustomEvent<Stream>>(listener, 'stream').then(evt => evt.detail),
55
- dialer.createStream()
56
- ])
77
+ it('should open a stream from the listener', async () => {
78
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
79
+ const onStreamPromise: DeferredPromise<Stream> = defer()
80
+ const onStreamEndPromise: DeferredPromise<Stream> = defer()
81
+ const dialerFactory = await common.setup()
82
+ const dialer = dialerFactory.createStreamMuxer({
83
+ direction: 'outbound',
84
+ onIncomingStream: (stream: Stream) => {
85
+ onStreamPromise.resolve(stream)
86
+ },
87
+ onStreamEnd: (stream) => {
88
+ onStreamEndPromise.resolve(stream)
89
+ }
90
+ })
57
91
 
58
- const dialerBytes = byteStream(dialerStream)
92
+ const listenerFactory = await common.setup()
93
+ const listener = listenerFactory.createStreamMuxer({
94
+ direction: 'inbound'
95
+ })
96
+
97
+ void pipe(p[0], dialer, p[0])
98
+ void pipe(p[1], listener, p[1])
99
+
100
+ const listenerStream = await listener.newStream()
59
101
  const listenerBytes = byteStream(listenerStream)
102
+ void listenerBytes.write(uint8ArrayFromString('hello'))
60
103
 
61
- const input = uint8ArrayFromString('hello')
104
+ const dialerStream = await onStreamPromise.promise
62
105
 
63
- const [, output] = await Promise.all([
64
- dialerBytes.write(input),
65
- listenerBytes.read()
66
- ])
106
+ expect(isValidTick(dialerStream.timeline.open)).to.equal(true)
107
+ expect(listener.streams).to.include(listenerStream)
108
+ expect(isValidTick(listenerStream.timeline.open)).to.equal(true)
67
109
 
68
- expect(output?.subarray()).to.equalBytes(input.subarray())
110
+ await dialerStream.close()
111
+ await listenerStream.close()
112
+
113
+ // Make sure stream is closed properly
114
+ const endedStream = await onStreamEndPromise.promise
115
+ expect(dialer.streams).to.not.include(endedStream)
116
+
117
+ if (endedStream.timeline.close == null) {
118
+ throw new Error('timeline had no close time')
119
+ }
120
+
121
+ // Make sure the stream is removed from tracking
122
+ expect(isValidTick(endedStream.timeline.close)).to.equal(true)
123
+
124
+ await dialer.close()
125
+ await listener.close()
69
126
  })
70
127
 
71
128
  it('should open a stream on both sides', async () => {
72
- const [
73
- listenerInboundStream,
74
- dialerOutboundStream,
129
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
130
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
131
+ const onListenerStreamPromise: DeferredPromise<Stream> = defer()
132
+ const dialerFactory = await common.setup()
133
+ const dialer = dialerFactory.createStreamMuxer({
134
+ direction: 'outbound',
135
+ onIncomingStream: (stream) => {
136
+ onDialerStreamPromise.resolve(stream)
137
+ }
138
+ })
75
139
 
76
- dialerInboundStream,
77
- listenerOutboundStream
78
- ] = await Promise.all([
79
- pEvent<'stream', CustomEvent<Stream>>(listener, 'stream').then(evt => evt.detail),
80
- dialer.createStream(),
140
+ const listenerFactory = await common.setup()
141
+ const listener = listenerFactory.createStreamMuxer({
142
+ direction: 'inbound',
143
+ onIncomingStream: (stream) => {
144
+ onListenerStreamPromise.resolve(stream)
145
+ }
146
+ })
147
+
148
+ void pipe(p[0], dialer, p[0])
149
+ void pipe(p[1], listener, p[1])
81
150
 
82
- pEvent<'stream', CustomEvent<Stream>>(dialer, 'stream').then(evt => evt.detail),
83
- listener.createStream()
151
+ const dialerInitiatorStream = await dialer.newStream()
152
+ const listenerInitiatorStream = await listener.newStream()
153
+
154
+ await Promise.all([
155
+ dialerInitiatorStream.close(),
156
+ listenerInitiatorStream.close(),
157
+ onDialerStreamPromise.promise.then(async stream => { await stream.close() }),
158
+ onListenerStreamPromise.promise.then(async stream => { await stream.close() })
84
159
  ])
85
160
 
86
- const dialerOutboundBytes = byteStream(dialerOutboundStream)
87
- const listenerInboundBytes = byteStream(listenerInboundStream)
161
+ await Promise.all([
162
+ dialer.close(),
163
+ listener.close()
164
+ ])
165
+ })
88
166
 
89
- const listenerOutboundBytes = byteStream(listenerOutboundStream)
90
- const dialerInboundBytes = byteStream(dialerInboundStream)
167
+ it('should open a stream on one side, write, open a stream on the other side', async () => {
168
+ const toString = (source: Source<Uint8ArrayList>): AsyncGenerator<string> => map(source, (u) => uint8ArrayToString(u.subarray()))
169
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
170
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
171
+ const onListenerStreamPromise: DeferredPromise<Stream> = defer()
172
+ const dialerFactory = await common.setup()
173
+ const dialer = dialerFactory.createStreamMuxer({
174
+ direction: 'outbound',
175
+ onIncomingStream: (stream) => {
176
+ onDialerStreamPromise.resolve(stream)
177
+ }
178
+ })
179
+ const listenerFactory = await common.setup()
180
+ const listener = listenerFactory.createStreamMuxer({
181
+ direction: 'inbound',
182
+ onIncomingStream: (stream) => {
183
+ onListenerStreamPromise.resolve(stream)
184
+ }
185
+ })
91
186
 
92
- const inputA = uint8ArrayFromString('hello')
93
- const inputB = uint8ArrayFromString('world')
187
+ void pipe(p[0], dialer, p[0])
188
+ void pipe(p[1], listener, p[1])
94
189
 
95
- const [, outputA] = await Promise.all([
96
- dialerOutboundBytes.write(inputA),
97
- listenerInboundBytes.read(),
190
+ const dialerConn = await dialer.newStream()
191
+ const listenerConn = await listener.newStream()
98
192
 
99
- listenerOutboundBytes.write(inputB),
100
- dialerInboundBytes.read()
101
- ])
193
+ void pipe([new Uint8ArrayList(uint8ArrayFromString('hey'))], dialerConn)
194
+ void pipe([new Uint8ArrayList(uint8ArrayFromString('hello'))], listenerConn)
102
195
 
103
- expect(outputA?.subarray()).to.equalBytes(inputA.subarray())
104
- expect(inputB?.subarray()).to.equalBytes(inputB.subarray())
105
- })
196
+ const [
197
+ dialerStream,
198
+ listenerStream
199
+ ] = await Promise.all([
200
+ onDialerStreamPromise.promise,
201
+ onListenerStreamPromise.promise
202
+ ])
106
203
 
107
- it('should store a stream in the streams list', async () => {
108
204
  const [
109
- listenerStream,
110
- dialerStream
205
+ listenerChunks,
206
+ dialerChunks
111
207
  ] = await Promise.all([
112
- pEvent<'stream', CustomEvent<Stream>>(listener, 'stream').then(evt => evt.detail),
113
- dialer.createStream()
208
+ pipe(listenerStream, toString, async (source) => all(source)),
209
+ pipe(dialerStream, toString, async (source) => all(source))
114
210
  ])
115
211
 
116
- expect(dialer.streams).to.include(dialerStream, 'dialer did not store outbound stream')
117
- expect(listener.streams).to.include(listenerStream, 'listener did not store inbound stream')
212
+ expect(listenerChunks).to.be.eql(['hey'])
213
+ expect(dialerChunks).to.be.eql(['hello'])
214
+ })
215
+
216
+ it('should echo a small value via a pipe', async () => {
217
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
218
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
219
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
220
+ const dialerFactory = await common.setup()
221
+ const dialer = dialerFactory.createStreamMuxer({
222
+ direction: 'outbound',
223
+ onIncomingStream: (stream) => {
224
+ onDialerStreamPromise.resolve(stream)
225
+ }
226
+ })
227
+ const listenerFactory = await common.setup()
228
+ const listener = listenerFactory.createStreamMuxer({
229
+ direction: 'inbound',
230
+ onIncomingStream: (stream) => {
231
+ void Promise.resolve().then(async () => {
232
+ const output = new Uint8ArrayList()
233
+
234
+ for await (const buf of stream.source) {
235
+ output.append(buf)
236
+ }
237
+
238
+ onDataReceivedPromise.resolve(output.subarray())
239
+ })
240
+ }
241
+ })
242
+
243
+ void pipe(p[0], dialer, p[0])
244
+ void pipe(p[1], listener, p[1])
245
+
246
+ const stream = await dialer.newStream()
247
+ const input = Uint8Array.from([0, 1, 2, 3, 4])
248
+
249
+ await pipe(
250
+ [input],
251
+ stream
252
+ )
253
+ await stream.close()
254
+
255
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
256
+ })
257
+
258
+ it('should echo a large value via a pipe', async () => {
259
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
260
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
261
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
262
+ const dialerFactory = await common.setup()
263
+ const dialer = dialerFactory.createStreamMuxer({
264
+ direction: 'outbound',
265
+ onIncomingStream: (stream) => {
266
+ onDialerStreamPromise.resolve(stream)
267
+ }
268
+ })
269
+ const listenerFactory = await common.setup()
270
+ const listener = listenerFactory.createStreamMuxer({
271
+ direction: 'inbound',
272
+ onIncomingStream: (stream) => {
273
+ void Promise.resolve().then(async () => {
274
+ const output = new Uint8ArrayList()
275
+
276
+ for await (const buf of stream.source) {
277
+ output.append(buf)
278
+ }
279
+
280
+ onDataReceivedPromise.resolve(output.subarray())
281
+ })
282
+ }
283
+ })
284
+
285
+ void pipe(p[0], dialer, p[0])
286
+ void pipe(p[1], listener, p[1])
287
+
288
+ const stream = await dialer.newStream()
289
+ const input = Uint8Array.from(new Array(1024 * 1024 * 10).fill(0))
290
+
291
+ await pipe(
292
+ [input],
293
+ stream
294
+ )
295
+ await stream.close()
296
+
297
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
298
+ })
299
+
300
+ it('should echo a small value via sink', async () => {
301
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
302
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
303
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
304
+ const dialerFactory = await common.setup()
305
+ const dialer = dialerFactory.createStreamMuxer({
306
+ direction: 'outbound',
307
+ onIncomingStream: (stream) => {
308
+ onDialerStreamPromise.resolve(stream)
309
+ }
310
+ })
311
+ const listenerFactory = await common.setup()
312
+ const listener = listenerFactory.createStreamMuxer({
313
+ direction: 'inbound',
314
+ onIncomingStream: (stream) => {
315
+ void Promise.resolve().then(async () => {
316
+ const output = new Uint8ArrayList()
317
+
318
+ for await (const buf of stream.source) {
319
+ output.append(buf)
320
+ }
321
+
322
+ onDataReceivedPromise.resolve(output.subarray())
323
+ })
324
+ }
325
+ })
326
+
327
+ void pipe(p[0], dialer, p[0])
328
+ void pipe(p[1], listener, p[1])
329
+
330
+ const stream = await dialer.newStream()
331
+ const input = Uint8Array.from([0, 1, 2, 3, 4])
332
+
333
+ await stream.sink([input])
334
+ await stream.close()
335
+
336
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
337
+ })
338
+
339
+ it('should echo a large value via sink', async () => {
340
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
341
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
342
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
343
+ const dialerFactory = await common.setup()
344
+ const dialer = dialerFactory.createStreamMuxer({
345
+ direction: 'outbound',
346
+ onIncomingStream: (stream) => {
347
+ onDialerStreamPromise.resolve(stream)
348
+ }
349
+ })
350
+ const listenerFactory = await common.setup()
351
+ const listener = listenerFactory.createStreamMuxer({
352
+ direction: 'inbound',
353
+ onIncomingStream: (stream) => {
354
+ void Promise.resolve().then(async () => {
355
+ const output = new Uint8ArrayList()
356
+
357
+ for await (const buf of stream.source) {
358
+ output.append(buf)
359
+ }
360
+
361
+ onDataReceivedPromise.resolve(output.subarray())
362
+ })
363
+ }
364
+ })
365
+
366
+ void pipe(p[0], dialer, p[0])
367
+ void pipe(p[1], listener, p[1])
368
+
369
+ const stream = await dialer.newStream()
370
+ const input = Uint8Array.from(new Array(1024 * 1024 * 10).fill(0))
371
+
372
+ await stream.sink([input])
373
+ await stream.close()
374
+
375
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
376
+ })
377
+
378
+ it('should echo a small value via a pushable', async () => {
379
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
380
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
381
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
382
+ const dialerFactory = await common.setup()
383
+ const dialer = dialerFactory.createStreamMuxer({
384
+ direction: 'outbound',
385
+ onIncomingStream: (stream) => {
386
+ onDialerStreamPromise.resolve(stream)
387
+ }
388
+ })
389
+ const listenerFactory = await common.setup()
390
+ const listener = listenerFactory.createStreamMuxer({
391
+ direction: 'inbound',
392
+ onIncomingStream: (stream) => {
393
+ void Promise.resolve().then(async () => {
394
+ const output = new Uint8ArrayList()
395
+
396
+ for await (const buf of stream.source) {
397
+ output.append(buf)
398
+ }
399
+
400
+ onDataReceivedPromise.resolve(output.subarray())
401
+ })
402
+ }
403
+ })
404
+
405
+ void pipe(p[0], dialer, p[0])
406
+ void pipe(p[1], listener, p[1])
407
+
408
+ const stream = await dialer.newStream()
409
+ const input = Uint8Array.from([0, 1, 2, 3, 4])
410
+
411
+ const pushable = byteStream(stream)
412
+ await pushable.write(input)
413
+ await pushable.unwrap().close()
414
+
415
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
416
+ })
417
+
418
+ it('should echo a large value via a pushable', async () => {
419
+ const p = duplexPair<Uint8Array | Uint8ArrayList>()
420
+ const onDialerStreamPromise: DeferredPromise<Stream> = defer()
421
+ const onDataReceivedPromise: DeferredPromise<Uint8Array> = defer()
422
+ const dialerFactory = await common.setup()
423
+ const dialer = dialerFactory.createStreamMuxer({
424
+ direction: 'outbound',
425
+ onIncomingStream: (stream) => {
426
+ onDialerStreamPromise.resolve(stream)
427
+ }
428
+ })
429
+ const listenerFactory = await common.setup()
430
+ const listener = listenerFactory.createStreamMuxer({
431
+ direction: 'inbound',
432
+ onIncomingStream: (stream) => {
433
+ void Promise.resolve().then(async () => {
434
+ const output = new Uint8ArrayList()
435
+
436
+ for await (const buf of stream.source) {
437
+ output.append(buf)
438
+ }
439
+
440
+ onDataReceivedPromise.resolve(output.subarray())
441
+ })
442
+ }
443
+ })
444
+
445
+ void pipe(p[0], dialer, p[0])
446
+ void pipe(p[1], listener, p[1])
447
+
448
+ const stream = await dialer.newStream()
449
+ const input = Uint8Array.from(new Array(1024 * 1024 * 10).fill(0))
450
+
451
+ const pushable = byteStream(stream)
452
+ await pushable.write(input)
453
+ await pushable.unwrap().close()
454
+
455
+ expect(await onDataReceivedPromise.promise).to.equalBytes(input)
118
456
  })
119
457
  })
120
458
  }