@libp2p/utils 4.0.7-c960eb659 → 4.0.7-d8f5bc211

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.
@@ -1,14 +1,12 @@
1
- import { logger } from '@libp2p/logger'
2
- import type { AbortOptions } from '@libp2p/interface'
1
+ import type { ComponentLogger } from '@libp2p/interface'
3
2
  import type { MultiaddrConnection, Stream } from '@libp2p/interface/connection'
4
3
  import type { Multiaddr } from '@multiformats/multiaddr'
5
4
 
6
- const log = logger('libp2p:stream:converter')
7
-
8
5
  export interface StreamProperties {
9
6
  stream: Stream
10
7
  remoteAddr: Multiaddr
11
8
  localAddr: Multiaddr
9
+ logger: ComponentLogger
12
10
  }
13
11
 
14
12
  /**
@@ -16,49 +14,75 @@ export interface StreamProperties {
16
14
  * https://github.com/libp2p/interface-transport#multiaddrconnection
17
15
  */
18
16
  export function streamToMaConnection (props: StreamProperties): MultiaddrConnection {
19
- const { stream, remoteAddr } = props
20
- const { sink, source } = stream
17
+ const { stream, remoteAddr, logger } = props
18
+ const log = logger.forComponent('libp2p:stream:converter')
19
+
20
+ let closedRead = false
21
+ let closedWrite = false
22
+
23
+ // piggyback on `stream.close` invocations to close maconn
24
+ const streamClose = stream.close.bind(stream)
25
+ stream.close = async (options) => {
26
+ await streamClose(options)
27
+ close(true)
28
+ }
21
29
 
22
- const mapSource = (async function * () {
23
- for await (const list of source) {
24
- if (list instanceof Uint8Array) {
25
- yield list
26
- } else {
27
- yield * list
30
+ // piggyback on `stream.abort` invocations to close maconn
31
+ const streamAbort = stream.abort.bind(stream)
32
+ stream.abort = (err) => {
33
+ streamAbort(err)
34
+ close(true)
35
+ }
36
+
37
+ // piggyback on `stream.sink` invocations to close maconn
38
+ const streamSink = stream.sink.bind(stream)
39
+ stream.sink = async (source) => {
40
+ try {
41
+ await streamSink(source)
42
+ } catch (err: any) {
43
+ // If aborted we can safely ignore
44
+ if (err.type !== 'aborted') {
45
+ // If the source errored the socket will already have been destroyed by
46
+ // toIterable.duplex(). If the socket errored it will already be
47
+ // destroyed. There's nothing to do here except log the error & return.
48
+ log(err)
28
49
  }
50
+ } finally {
51
+ closedWrite = true
52
+ close()
29
53
  }
30
- }())
54
+ }
31
55
 
32
56
  const maConn: MultiaddrConnection = {
33
- async sink (source) {
57
+ log,
58
+ sink: stream.sink,
59
+ source: (async function * () {
34
60
  try {
35
- await sink(source)
36
- close()
37
- } catch (err: any) {
38
- // If aborted we can safely ignore
39
- if (err.type !== 'aborted') {
40
- // If the source errored the socket will already have been destroyed by
41
- // toIterable.duplex(). If the socket errored it will already be
42
- // destroyed. There's nothing to do here except log the error & return.
43
- log(err)
61
+ for await (const list of stream.source) {
62
+ if (list instanceof Uint8Array) {
63
+ yield list
64
+ } else {
65
+ yield * list
66
+ }
44
67
  }
68
+ } finally {
69
+ closedRead = true
70
+ close()
45
71
  }
46
- },
47
- source: mapSource,
72
+ }()),
48
73
  remoteAddr,
49
74
  timeline: { open: Date.now(), close: undefined },
50
- async close (options?: AbortOptions) {
51
- close()
52
- await stream.close(options)
53
- },
54
- abort (err: Error): void {
55
- close()
56
- stream.abort(err)
57
- }
75
+ close: stream.close,
76
+ abort: stream.abort
58
77
  }
59
78
 
60
- function close (): void {
61
- if (maConn.timeline.close == null) {
79
+ function close (force?: boolean): void {
80
+ if (force === true) {
81
+ closedRead = true
82
+ closedWrite = true
83
+ }
84
+
85
+ if (closedRead && closedWrite && maConn.timeline.close == null) {
62
86
  maConn.timeline.close = Date.now()
63
87
  }
64
88
  }