@libp2p/interface-compliance-tests 6.4.16 → 6.5.0-0f07e3df5

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 (132) hide show
  1. package/dist/src/connection-encryption/index.d.ts.map +1 -1
  2. package/dist/src/connection-encryption/index.js +24 -15
  3. package/dist/src/connection-encryption/index.js.map +1 -1
  4. package/dist/src/stream-muxer/base-test.d.ts.map +1 -1
  5. package/dist/src/stream-muxer/base-test.js +62 -341
  6. package/dist/src/stream-muxer/base-test.js.map +1 -1
  7. package/dist/src/stream-muxer/close-test.d.ts.map +1 -1
  8. package/dist/src/stream-muxer/close-test.js +254 -305
  9. package/dist/src/stream-muxer/close-test.js.map +1 -1
  10. package/dist/src/stream-muxer/index.js +2 -2
  11. package/dist/src/stream-muxer/index.js.map +1 -1
  12. package/dist/src/stream-muxer/{mega-stress-test.d.ts → stream-test.d.ts} +2 -2
  13. package/dist/src/stream-muxer/stream-test.d.ts.map +1 -0
  14. package/dist/src/stream-muxer/stream-test.js +289 -0
  15. package/dist/src/stream-muxer/stream-test.js.map +1 -0
  16. package/dist/src/stream-muxer/stress-test.d.ts.map +1 -1
  17. package/dist/src/stream-muxer/stress-test.js +70 -16
  18. package/dist/src/stream-muxer/stress-test.js.map +1 -1
  19. package/dist/src/transport/index.d.ts.map +1 -1
  20. package/dist/src/transport/index.js +232 -203
  21. package/dist/src/transport/index.js.map +1 -1
  22. package/dist/src/transport/utils.js +2 -2
  23. package/dist/src/transport/utils.js.map +1 -1
  24. package/package.json +23 -51
  25. package/src/connection-encryption/index.ts +27 -20
  26. package/src/stream-muxer/base-test.ts +75 -409
  27. package/src/stream-muxer/close-test.ts +304 -327
  28. package/src/stream-muxer/index.ts +2 -2
  29. package/src/stream-muxer/stream-test.ts +380 -0
  30. package/src/stream-muxer/stress-test.ts +92 -18
  31. package/src/transport/index.ts +280 -241
  32. package/src/transport/utils.ts +2 -2
  33. package/dist/src/connection-encryption/utils/index.d.ts +0 -3
  34. package/dist/src/connection-encryption/utils/index.d.ts.map +0 -1
  35. package/dist/src/connection-encryption/utils/index.js +0 -21
  36. package/dist/src/connection-encryption/utils/index.js.map +0 -1
  37. package/dist/src/matchers.d.ts +0 -12
  38. package/dist/src/matchers.d.ts.map +0 -1
  39. package/dist/src/matchers.js +0 -14
  40. package/dist/src/matchers.js.map +0 -1
  41. package/dist/src/mocks/connection-manager.d.ts +0 -27
  42. package/dist/src/mocks/connection-manager.d.ts.map +0 -1
  43. package/dist/src/mocks/connection-manager.js +0 -147
  44. package/dist/src/mocks/connection-manager.js.map +0 -1
  45. package/dist/src/mocks/connection.d.ts +0 -41
  46. package/dist/src/mocks/connection.d.ts.map +0 -1
  47. package/dist/src/mocks/connection.js +0 -234
  48. package/dist/src/mocks/connection.js.map +0 -1
  49. package/dist/src/mocks/duplex.d.ts +0 -4
  50. package/dist/src/mocks/duplex.d.ts.map +0 -1
  51. package/dist/src/mocks/duplex.js +0 -9
  52. package/dist/src/mocks/duplex.js.map +0 -1
  53. package/dist/src/mocks/index.d.ts +0 -12
  54. package/dist/src/mocks/index.d.ts.map +0 -1
  55. package/dist/src/mocks/index.js +0 -8
  56. package/dist/src/mocks/index.js.map +0 -1
  57. package/dist/src/mocks/multiaddr-connection.d.ts +0 -17
  58. package/dist/src/mocks/multiaddr-connection.d.ts.map +0 -1
  59. package/dist/src/mocks/multiaddr-connection.js +0 -64
  60. package/dist/src/mocks/multiaddr-connection.js.map +0 -1
  61. package/dist/src/mocks/muxer.d.ts +0 -36
  62. package/dist/src/mocks/muxer.d.ts.map +0 -1
  63. package/dist/src/mocks/muxer.js +0 -234
  64. package/dist/src/mocks/muxer.js.map +0 -1
  65. package/dist/src/mocks/registrar.d.ts +0 -16
  66. package/dist/src/mocks/registrar.d.ts.map +0 -1
  67. package/dist/src/mocks/registrar.js +0 -66
  68. package/dist/src/mocks/registrar.js.map +0 -1
  69. package/dist/src/mocks/upgrader.d.ts +0 -9
  70. package/dist/src/mocks/upgrader.d.ts.map +0 -1
  71. package/dist/src/mocks/upgrader.js +0 -46
  72. package/dist/src/mocks/upgrader.js.map +0 -1
  73. package/dist/src/pubsub/api.d.ts +0 -6
  74. package/dist/src/pubsub/api.d.ts.map +0 -1
  75. package/dist/src/pubsub/api.js +0 -88
  76. package/dist/src/pubsub/api.js.map +0 -1
  77. package/dist/src/pubsub/connection-handlers.d.ts +0 -6
  78. package/dist/src/pubsub/connection-handlers.d.ts.map +0 -1
  79. package/dist/src/pubsub/connection-handlers.js +0 -329
  80. package/dist/src/pubsub/connection-handlers.js.map +0 -1
  81. package/dist/src/pubsub/emit-self.d.ts +0 -6
  82. package/dist/src/pubsub/emit-self.d.ts.map +0 -1
  83. package/dist/src/pubsub/emit-self.js +0 -80
  84. package/dist/src/pubsub/emit-self.js.map +0 -1
  85. package/dist/src/pubsub/index.d.ts +0 -18
  86. package/dist/src/pubsub/index.d.ts.map +0 -1
  87. package/dist/src/pubsub/index.js +0 -17
  88. package/dist/src/pubsub/index.js.map +0 -1
  89. package/dist/src/pubsub/messages.d.ts +0 -6
  90. package/dist/src/pubsub/messages.d.ts.map +0 -1
  91. package/dist/src/pubsub/messages.js +0 -48
  92. package/dist/src/pubsub/messages.js.map +0 -1
  93. package/dist/src/pubsub/multiple-nodes.d.ts +0 -6
  94. package/dist/src/pubsub/multiple-nodes.d.ts.map +0 -1
  95. package/dist/src/pubsub/multiple-nodes.js +0 -350
  96. package/dist/src/pubsub/multiple-nodes.js.map +0 -1
  97. package/dist/src/pubsub/two-nodes.d.ts +0 -6
  98. package/dist/src/pubsub/two-nodes.d.ts.map +0 -1
  99. package/dist/src/pubsub/two-nodes.js +0 -216
  100. package/dist/src/pubsub/two-nodes.js.map +0 -1
  101. package/dist/src/pubsub/utils.d.ts +0 -5
  102. package/dist/src/pubsub/utils.d.ts.map +0 -1
  103. package/dist/src/pubsub/utils.js +0 -27
  104. package/dist/src/pubsub/utils.js.map +0 -1
  105. package/dist/src/stream-muxer/mega-stress-test.d.ts.map +0 -1
  106. package/dist/src/stream-muxer/mega-stress-test.js +0 -11
  107. package/dist/src/stream-muxer/mega-stress-test.js.map +0 -1
  108. package/dist/src/stream-muxer/spawner.d.ts +0 -4
  109. package/dist/src/stream-muxer/spawner.d.ts.map +0 -1
  110. package/dist/src/stream-muxer/spawner.js +0 -37
  111. package/dist/src/stream-muxer/spawner.js.map +0 -1
  112. package/dist/typedoc-urls.json +0 -44
  113. package/src/connection-encryption/utils/index.ts +0 -27
  114. package/src/matchers.ts +0 -18
  115. package/src/mocks/connection-manager.ts +0 -216
  116. package/src/mocks/connection.ts +0 -307
  117. package/src/mocks/duplex.ts +0 -11
  118. package/src/mocks/index.ts +0 -11
  119. package/src/mocks/multiaddr-connection.ts +0 -80
  120. package/src/mocks/muxer.ts +0 -331
  121. package/src/mocks/registrar.ts +0 -86
  122. package/src/mocks/upgrader.ts +0 -65
  123. package/src/pubsub/api.ts +0 -116
  124. package/src/pubsub/connection-handlers.ts +0 -413
  125. package/src/pubsub/emit-self.ts +0 -99
  126. package/src/pubsub/index.ts +0 -34
  127. package/src/pubsub/messages.ts +0 -59
  128. package/src/pubsub/multiple-nodes.ts +0 -440
  129. package/src/pubsub/two-nodes.ts +0 -272
  130. package/src/pubsub/utils.ts +0 -34
  131. package/src/stream-muxer/mega-stress-test.ts +0 -14
  132. package/src/stream-muxer/spawner.ts +0 -55
@@ -1,307 +0,0 @@
1
- import { ConnectionClosedError } from '@libp2p/interface'
2
- import { defaultLogger, logger } from '@libp2p/logger'
3
- import * as mss from '@libp2p/multistream-select'
4
- import { peerIdFromString } from '@libp2p/peer-id'
5
- import { closeSource } from '@libp2p/utils/close-source'
6
- import { duplexPair } from 'it-pair/duplex'
7
- import { pipe } from 'it-pipe'
8
- import { Uint8ArrayList } from 'uint8arraylist'
9
- import { mockMultiaddrConnection } from './multiaddr-connection.js'
10
- import { mockMuxer } from './muxer.js'
11
- import { mockRegistrar } from './registrar.js'
12
- import type { AbortOptions, ComponentLogger, Logger, MultiaddrConnection, Connection, Stream, Direction, ConnectionTimeline, ConnectionStatus, PeerId, StreamMuxer, StreamMuxerFactory, NewStreamOptions, ConnectionLimits } from '@libp2p/interface'
13
- import type { Registrar } from '@libp2p/interface-internal'
14
- import type { Multiaddr } from '@multiformats/multiaddr'
15
- import type { Duplex, Source } from 'it-stream-types'
16
-
17
- export interface MockConnectionOptions {
18
- direction?: Direction
19
- registrar?: Registrar
20
- muxerFactory?: StreamMuxerFactory
21
- logger?: ComponentLogger
22
- }
23
-
24
- interface MockConnectionInit {
25
- remoteAddr: Multiaddr
26
- remotePeer: PeerId
27
- direction: Direction
28
- maConn: MultiaddrConnection
29
- muxer: StreamMuxer
30
- logger: ComponentLogger
31
- }
32
-
33
- class MockConnection implements Connection {
34
- public id: string
35
- public remoteAddr: Multiaddr
36
- public remotePeer: PeerId
37
- public direction: Direction
38
- public timeline: ConnectionTimeline
39
- public multiplexer?: string
40
- public encryption?: string
41
- public status: ConnectionStatus
42
- public streams: Stream[]
43
- public tags: string[]
44
- public limits?: ConnectionLimits
45
- public log: Logger
46
-
47
- private readonly muxer: StreamMuxer
48
- private readonly maConn: MultiaddrConnection
49
- private readonly logger: ComponentLogger
50
-
51
- constructor (init: MockConnectionInit) {
52
- const { remoteAddr, remotePeer, direction, maConn, muxer, logger } = init
53
-
54
- this.id = `mock-connection-${Math.random()}`
55
- this.remoteAddr = remoteAddr
56
- this.remotePeer = remotePeer
57
- this.direction = direction
58
- this.status = 'open'
59
- this.direction = direction
60
- this.timeline = maConn.timeline
61
- this.multiplexer = 'test-multiplexer'
62
- this.encryption = 'yes-yes-very-secure'
63
- this.streams = []
64
- this.tags = []
65
- this.muxer = muxer
66
- this.maConn = maConn
67
- this.logger = logger
68
- this.log = logger.forComponent(this.id)
69
- }
70
-
71
- async newStream (protocols: string | string[], options?: NewStreamOptions): Promise<Stream> {
72
- if (!Array.isArray(protocols)) {
73
- protocols = [protocols]
74
- }
75
-
76
- if (protocols.length === 0) {
77
- throw new Error('protocols must have a length')
78
- }
79
-
80
- if (this.status !== 'open') {
81
- throw new ConnectionClosedError('connection must be open to create streams')
82
- }
83
-
84
- options?.signal?.throwIfAborted()
85
-
86
- const id = `${Math.random()}`
87
- const stream = await this.muxer.newStream(id)
88
- const result = await mss.select(stream, protocols, {
89
- ...options,
90
- log: this.logger.forComponent('libp2p:mock-connection:stream:mss:select')
91
- })
92
-
93
- stream.protocol = result.protocol
94
- stream.direction = 'outbound'
95
- stream.sink = result.stream.sink
96
- stream.source = result.stream.source
97
-
98
- this.streams.push(stream)
99
-
100
- return stream
101
- }
102
-
103
- async close (options?: AbortOptions): Promise<void> {
104
- this.status = 'closing'
105
- await Promise.all(
106
- this.streams.map(async s => s.close(options))
107
- )
108
- await this.maConn.close()
109
- this.status = 'closed'
110
- this.timeline.close = Date.now()
111
- }
112
-
113
- abort (err: Error): void {
114
- this.status = 'closing'
115
- this.streams.forEach(s => {
116
- s.abort(err)
117
- })
118
- this.maConn.abort(err)
119
- this.status = 'closed'
120
- this.timeline.close = Date.now()
121
- }
122
- }
123
-
124
- export function mockConnection (maConn: MultiaddrConnection, opts: MockConnectionOptions = {}): Connection {
125
- const remoteAddr = maConn.remoteAddr
126
- const remotePeerIdStr = remoteAddr.getPeerId() ?? '12D3KooWCrhmFM1BCPGBkNzbPfDk4cjYmtAYSpZwUBC69Qg2kZyq'
127
- const logger = opts.logger ?? defaultLogger()
128
-
129
- if (remotePeerIdStr == null) {
130
- throw new Error('Remote multiaddr must contain a peer id')
131
- }
132
-
133
- const remotePeer = peerIdFromString(remotePeerIdStr)
134
- const direction = opts.direction ?? 'inbound'
135
- const registrar = opts.registrar ?? mockRegistrar()
136
- const muxerFactory = opts.muxerFactory ?? mockMuxer()
137
- const log = logger.forComponent('libp2p:mock-muxer')
138
-
139
- const muxer = muxerFactory.createStreamMuxer({
140
- direction,
141
- onIncomingStream: (muxedStream) => {
142
- try {
143
- mss.handle(muxedStream, registrar.getProtocols(), {
144
- log
145
- })
146
- .then(({ stream, protocol }) => {
147
- log('%s: incoming stream opened on %s', direction, protocol)
148
- muxedStream.protocol = protocol
149
- muxedStream.sink = stream.sink
150
- muxedStream.source = stream.source
151
-
152
- connection.streams.push(muxedStream)
153
- const { handler } = registrar.getHandler(protocol)
154
-
155
- handler({ connection, stream: muxedStream })
156
- }).catch(err => {
157
- log.error(err)
158
- })
159
- } catch (err: any) {
160
- log.error(err)
161
- }
162
- },
163
- onStreamEnd: (muxedStream) => {
164
- connection.streams = connection.streams.filter(stream => stream.id !== muxedStream.id)
165
- }
166
- })
167
-
168
- void pipe(
169
- maConn, muxer, maConn
170
- )
171
-
172
- const connection = new MockConnection({
173
- remoteAddr,
174
- remotePeer,
175
- direction,
176
- maConn,
177
- muxer,
178
- logger
179
- })
180
-
181
- return connection
182
- }
183
-
184
- export interface StreamInit {
185
- direction?: Direction
186
- protocol?: string
187
- id?: string
188
- }
189
-
190
- export function mockStream (stream: Duplex<AsyncGenerator<Uint8ArrayList>, Source<Uint8ArrayList | Uint8Array>, Promise<void>>, init: StreamInit = {}): Stream {
191
- const id = `stream-${Date.now()}`
192
- const log = logger(`libp2p:mock-stream:${id}`)
193
-
194
- // ensure stream output is `Uint8ArrayList` as it would be from an actual
195
- // Stream where everything is length-varint encoded
196
- const originalSource = stream.source
197
- stream.source = (async function * (): AsyncGenerator<Uint8ArrayList, any, unknown> {
198
- for await (const buf of originalSource) {
199
- if (buf instanceof Uint8Array) {
200
- yield new Uint8ArrayList(buf)
201
- } else {
202
- yield buf
203
- }
204
- }
205
- })()
206
-
207
- const abortSinkController = new AbortController()
208
- const originalSink = stream.sink.bind(stream)
209
- stream.sink = async (source) => {
210
- abortSinkController.signal.addEventListener('abort', () => {
211
- closeSource(source, log)
212
- })
213
-
214
- await originalSink(source)
215
- }
216
-
217
- const mockStream: Stream = {
218
- ...stream,
219
- close: async (options) => {
220
- await mockStream.closeRead(options)
221
- await mockStream.closeWrite(options)
222
- },
223
- closeRead: async () => {
224
- closeSource(originalSource, log)
225
- mockStream.timeline.closeRead = Date.now()
226
-
227
- if (mockStream.timeline.closeWrite != null) {
228
- mockStream.timeline.close = Date.now()
229
- }
230
- },
231
- closeWrite: async () => {
232
- abortSinkController.abort()
233
- mockStream.timeline.closeWrite = Date.now()
234
-
235
- if (mockStream.timeline.closeRead != null) {
236
- mockStream.timeline.close = Date.now()
237
- }
238
- },
239
- abort: () => {
240
- closeSource(originalSource, log)
241
- mockStream.timeline.closeWrite = Date.now()
242
- mockStream.timeline.closeRead = Date.now()
243
- mockStream.timeline.close = Date.now()
244
- },
245
- direction: 'outbound',
246
- protocol: '/foo/1.0.0',
247
- timeline: {
248
- open: Date.now()
249
- },
250
- metadata: {},
251
- id: `stream-${Date.now()}`,
252
- status: 'open',
253
- readStatus: 'ready',
254
- writeStatus: 'ready',
255
- log: logger('mock-stream'),
256
- ...init
257
- }
258
-
259
- return mockStream
260
- }
261
-
262
- export interface StreamPairInit {
263
- duplex: Duplex<AsyncGenerator<Uint8ArrayList>, Source<Uint8ArrayList | Uint8Array>, Promise<void>>
264
- init?: StreamInit
265
- }
266
-
267
- export function streamPair (a: StreamPairInit, b: StreamPairInit, init: StreamInit = {}): [Stream, Stream] {
268
- return [
269
- mockStream(a.duplex, {
270
- direction: 'outbound',
271
- ...init,
272
- ...(a.init ?? {})
273
- }),
274
- mockStream(b.duplex, {
275
- direction: 'inbound',
276
- ...init,
277
- ...(b.init ?? {})
278
- })
279
- ]
280
- }
281
-
282
- export interface Peer {
283
- peerId: PeerId
284
- registrar: Registrar
285
- }
286
-
287
- export function multiaddrConnectionPair (a: { peerId: PeerId, registrar: Registrar }, b: { peerId: PeerId, registrar: Registrar }): [ MultiaddrConnection, MultiaddrConnection ] {
288
- const [peerBtoPeerA, peerAtoPeerB] = duplexPair<Uint8Array | Uint8ArrayList>()
289
-
290
- return [
291
- mockMultiaddrConnection(peerAtoPeerB, b.peerId),
292
- mockMultiaddrConnection(peerBtoPeerA, a.peerId)
293
- ]
294
- }
295
-
296
- export function connectionPair (a: { peerId: PeerId, registrar: Registrar }, b: { peerId: PeerId, registrar: Registrar }): [ Connection, Connection ] {
297
- const [peerBtoPeerA, peerAtoPeerB] = multiaddrConnectionPair(a, b)
298
-
299
- return [
300
- mockConnection(peerBtoPeerA, {
301
- registrar: a.registrar
302
- }),
303
- mockConnection(peerAtoPeerB, {
304
- registrar: b.registrar
305
- })
306
- ]
307
- }
@@ -1,11 +0,0 @@
1
- import type { Duplex, Source } from 'it-stream-types'
2
- import type { Uint8ArrayList } from 'uint8arraylist'
3
-
4
- export function mockDuplex (): Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>, Source<Uint8Array | Uint8ArrayList>, Promise<void>> {
5
- return {
6
- source: (async function * () {
7
- yield * []
8
- }()),
9
- sink: async () => {}
10
- }
11
- }
@@ -1,11 +0,0 @@
1
- export { mockConnectionManager, mockNetwork } from './connection-manager.js'
2
- export { mockConnection, mockStream, streamPair, connectionPair } from './connection.js'
3
- export { mockMultiaddrConnection, mockMultiaddrConnPair } from './multiaddr-connection.js'
4
- export { mockMuxer } from './muxer.js'
5
- export { mockRegistrar } from './registrar.js'
6
- export { mockUpgrader } from './upgrader.js'
7
- export { mockDuplex } from './duplex.js'
8
- export type { MockUpgraderInit } from './upgrader.js'
9
- export type { MockNetworkComponents, MockConnectionManagerComponents, MockNetwork } from './connection-manager.js'
10
- export type { MockConnectionOptions, StreamInit, StreamPairInit } from './connection.js'
11
- export type { MockMultiaddrConnPairOptions } from './multiaddr-connection.js'
@@ -1,80 +0,0 @@
1
- import { logger } from '@libp2p/logger'
2
- import { multiaddr } from '@multiformats/multiaddr'
3
- import { abortableSource } from 'abortable-iterator'
4
- import { duplexPair } from 'it-pair/duplex'
5
- import type { MultiaddrConnection, PeerId } from '@libp2p/interface'
6
- import type { Multiaddr } from '@multiformats/multiaddr'
7
- import type { Duplex } from 'it-stream-types'
8
- import type { Uint8ArrayList } from 'uint8arraylist'
9
-
10
- export function mockMultiaddrConnection (source: Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> & Partial<MultiaddrConnection>, peerId: PeerId): MultiaddrConnection {
11
- const maConn: MultiaddrConnection = {
12
- async close () {
13
-
14
- },
15
- abort: () => {},
16
- timeline: {
17
- open: Date.now()
18
- },
19
- remoteAddr: multiaddr(`/ip4/127.0.0.1/tcp/4001/p2p/${peerId.toString()}`),
20
- log: logger('mock-maconn'),
21
- ...source
22
- }
23
-
24
- return maConn
25
- }
26
-
27
- export interface MockMultiaddrConnPairOptions {
28
- addrs: Multiaddr[]
29
- remotePeer: PeerId
30
- }
31
-
32
- /**
33
- * Returns both sides of a mocked MultiaddrConnection
34
- */
35
- export function mockMultiaddrConnPair (opts: MockMultiaddrConnPairOptions): { inbound: MultiaddrConnection, outbound: MultiaddrConnection } {
36
- const { addrs, remotePeer } = opts
37
- const controller = new AbortController()
38
- const [localAddr, remoteAddr] = addrs
39
- const [inboundStream, outboundStream] = duplexPair<Uint8Array | Uint8ArrayList>()
40
-
41
- const outbound: MultiaddrConnection = {
42
- ...outboundStream,
43
- remoteAddr: remoteAddr.toString().includes(`/p2p/${remotePeer.toString()}`) ? remoteAddr : remoteAddr.encapsulate(`/p2p/${remotePeer.toString()}`),
44
- timeline: {
45
- open: Date.now()
46
- },
47
- close: async () => {
48
- outbound.timeline.close = Date.now()
49
- controller.abort()
50
- },
51
- abort: (err: Error) => {
52
- outbound.timeline.close = Date.now()
53
- controller.abort(err)
54
- },
55
- log: logger('mock-maconn-outbound')
56
- }
57
-
58
- const inbound: MultiaddrConnection = {
59
- ...inboundStream,
60
- remoteAddr: localAddr,
61
- timeline: {
62
- open: Date.now()
63
- },
64
- close: async () => {
65
- inbound.timeline.close = Date.now()
66
- controller.abort()
67
- },
68
- abort: (err: Error) => {
69
- outbound.timeline.close = Date.now()
70
- controller.abort(err)
71
- },
72
- log: logger('mock-maconn-inbound')
73
- }
74
-
75
- // Make the sources abortable so we can close them easily
76
- inbound.source = abortableSource(inbound.source, controller.signal)
77
- outbound.source = abortableSource(outbound.source, controller.signal)
78
-
79
- return { inbound, outbound }
80
- }