@@ -7,14 +7,15 @@ import * as asn1X509 from '@peculiar/asn1-x509'
7
7
import { Crypto } from '@peculiar/webcrypto'
8
8
import * as x509 from '@peculiar/x509'
9
9
import * as asn1js from 'asn1js'
10
- import { pushable } from 'it-pushable'
10
+ import { queuelessPushable } from 'it-queueless -pushable'
11
11
import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
12
12
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
13
13
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
14
14
import { InvalidCertificateError } from './errors.js'
15
15
import { KeyType , PublicKey } from './pb/index.js'
16
16
import type { PeerId , PublicKey as Libp2pPublicKey , Logger , PrivateKey } from '@libp2p/interface'
17
- import type { Duplex } from 'it-stream-types'
17
+ import type { Pushable } from 'it-queueless-pushable'
18
+ import type { Duplex , Source } from 'it-stream-types'
18
19
import type { Uint8ArrayList } from 'uint8arraylist'
19
20
20
21
const crypto = new Crypto ( )
@@ -185,15 +186,19 @@ function formatAsPem (str: string): string {
185
186
}
186
187
187
188
export function itToStream ( conn : Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > ) : DuplexStream {
188
- const output = pushable ( )
189
+ const output = queuelessPushable < Uint8Array > ( )
189
190
const iterator = conn . source [ Symbol . asyncIterator ] ( ) as AsyncGenerator < Uint8Array >
190
191
191
192
const stream = new DuplexStream ( {
192
193
autoDestroy : false ,
193
194
allowHalfOpen : true ,
194
195
write ( chunk , encoding , callback ) {
195
- output . push ( chunk )
196
- callback ( )
196
+ void output . push ( chunk )
197
+ . then ( ( ) => {
198
+ callback ( )
199
+ } , err => {
200
+ callback ( err )
201
+ } )
197
202
} ,
198
203
read ( ) {
199
204
iterator . next ( )
@@ -218,53 +223,64 @@ export function itToStream (conn: Duplex<AsyncGenerator<Uint8Array | Uint8ArrayL
218
223
return stream
219
224
}
220
225
221
- export function streamToIt ( stream : DuplexStream ) : Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > {
222
- const output : Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > = {
223
- source : ( async function * ( ) {
224
- const output = pushable < Uint8Array > ( )
225
-
226
- stream . addListener ( 'data' , ( buf ) => {
227
- output . push ( buf . subarray ( ) )
228
- } )
229
- // both ends closed
230
- stream . addListener ( 'close' , ( ) => {
231
- output . end ( )
232
- } )
233
- stream . addListener ( 'error' , ( err ) => {
234
- output . end ( err )
235
- } )
236
- // just writable end closed
237
- stream . addListener ( 'finish' , ( ) => {
238
- output . end ( )
239
- } )
240
-
241
- try {
242
- yield * output
243
- } catch ( err : any ) {
244
- stream . destroy ( err )
245
- throw err
246
- }
247
- } ) ( ) ,
248
- sink : async ( source ) => {
249
- try {
250
- for await ( const buf of source ) {
251
- const sendMore = stream . write ( buf . subarray ( ) )
252
-
253
- if ( ! sendMore ) {
254
- await waitForBackpressure ( stream )
255
- }
256
- }
226
+ class DuplexIterable implements Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > {
227
+ source : Pushable < Uint8Array >
228
+ private readonly stream : DuplexStream
229
+
230
+ constructor ( stream : DuplexStream ) {
231
+ this . stream = stream
232
+ this . source = queuelessPushable < Uint8Array > ( )
257
233
258
- // close writable end
259
- stream . end ( )
260
- } catch ( err : any ) {
261
- stream . destroy ( err )
262
- throw err
234
+ stream . addListener ( 'data' , ( buf ) => {
235
+ stream . pause ( )
236
+ this . source . push ( buf . subarray ( ) )
237
+ . then ( ( ) => {
238
+ stream . resume ( )
239
+ } , ( err ) => {
240
+ stream . emit ( 'error' , err )
241
+ } )
242
+ } )
243
+ // both ends closed
244
+ stream . addListener ( 'close' , ( ) => {
245
+ this . source . end ( )
246
+ . catch ( err => {
247
+ stream . emit ( 'error' , err )
248
+ } )
249
+ } )
250
+ stream . addListener ( 'error' , ( err ) => {
251
+ this . source . end ( err )
252
+ . catch ( ( ) => { } )
253
+ } )
254
+ // just writable end closed
255
+ stream . addListener ( 'finish' , ( ) => {
256
+ this . source . end ( )
257
+ . catch ( ( ) => { } )
258
+ } )
259
+
260
+ this . sink = this . sink . bind ( this )
261
+ }
262
+
263
+ async sink ( source : Source < Uint8Array | Uint8ArrayList > ) : Promise < void > {
264
+ try {
265
+ for await ( const buf of source ) {
266
+ const sendMore = this . stream . write ( buf . subarray ( ) )
267
+
268
+ if ( ! sendMore ) {
269
+ await waitForBackpressure ( this . stream )
270
+ }
263
271
}
272
+
273
+ // close writable end
274
+ this . stream . end ( )
275
+ } catch ( err : any ) {
276
+ this . stream . destroy ( err )
277
+ throw err
264
278
}
265
279
}
280
+ }
266
281
267
- return output
282
+ export function streamToIt ( stream : DuplexStream ) : Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > {
283
+ return new DuplexIterable ( stream )
268
284
}
269
285
270
286
async function waitForBackpressure ( stream : DuplexStream ) : Promise < void > {
0 commit comments