@libp2p/utils 4.0.7-effcfaa8e → 5.0.0

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 (43) hide show
  1. package/README.md +1 -1
  2. package/dist/src/abstract-stream.d.ts +144 -0
  3. package/dist/src/abstract-stream.d.ts.map +1 -0
  4. package/dist/src/abstract-stream.js +340 -0
  5. package/dist/src/abstract-stream.js.map +1 -0
  6. package/dist/src/address-sort.d.ts +1 -1
  7. package/dist/src/address-sort.d.ts.map +1 -1
  8. package/dist/src/address-sort.js.map +1 -1
  9. package/dist/src/array-equals.js.map +1 -1
  10. package/dist/src/close-source.d.ts +4 -0
  11. package/dist/src/close-source.d.ts.map +1 -0
  12. package/dist/src/close-source.js +11 -0
  13. package/dist/src/close-source.js.map +1 -0
  14. package/dist/src/ip-port-to-multiaddr.d.ts.map +1 -1
  15. package/dist/src/ip-port-to-multiaddr.js +2 -6
  16. package/dist/src/ip-port-to-multiaddr.js.map +1 -1
  17. package/dist/src/is-promise.d.ts +2 -0
  18. package/dist/src/is-promise.d.ts.map +1 -0
  19. package/dist/src/is-promise.js +9 -0
  20. package/dist/src/is-promise.js.map +1 -0
  21. package/dist/src/multiaddr/is-private.js.map +1 -1
  22. package/dist/src/peer-job-queue.d.ts +33 -0
  23. package/dist/src/peer-job-queue.d.ts.map +1 -0
  24. package/dist/src/peer-job-queue.js +81 -0
  25. package/dist/src/peer-job-queue.js.map +1 -0
  26. package/dist/src/stream-to-ma-conn.d.ts +2 -1
  27. package/dist/src/stream-to-ma-conn.d.ts.map +1 -1
  28. package/dist/src/stream-to-ma-conn.js +57 -35
  29. package/dist/src/stream-to-ma-conn.js.map +1 -1
  30. package/dist/src/tracked-map.d.ts +17 -0
  31. package/dist/src/tracked-map.d.ts.map +1 -0
  32. package/dist/src/tracked-map.js +38 -0
  33. package/dist/src/tracked-map.js.map +1 -0
  34. package/dist/typedoc-urls.json +36 -0
  35. package/package.json +43 -9
  36. package/src/abstract-stream.ts +508 -0
  37. package/src/address-sort.ts +1 -1
  38. package/src/close-source.ts +14 -0
  39. package/src/ip-port-to-multiaddr.ts +2 -7
  40. package/src/is-promise.ts +9 -0
  41. package/src/peer-job-queue.ts +118 -0
  42. package/src/stream-to-ma-conn.ts +59 -36
  43. package/src/tracked-map.ts +65 -0
@@ -1,14 +1,11 @@
1
- import { logger } from '@libp2p/logger'
2
- import type { AbortOptions } from '@libp2p/interface'
3
- import type { MultiaddrConnection, Stream } from '@libp2p/interface/connection'
1
+ import type { ComponentLogger, MultiaddrConnection, Stream } from '@libp2p/interface'
4
2
  import type { Multiaddr } from '@multiformats/multiaddr'
5
3
 
6
- const log = logger('libp2p:stream:converter')
7
-
8
4
  export interface StreamProperties {
9
5
  stream: Stream
10
6
  remoteAddr: Multiaddr
11
7
  localAddr: Multiaddr
8
+ logger: ComponentLogger
12
9
  }
13
10
 
14
11
  /**
@@ -16,49 +13,75 @@ export interface StreamProperties {
16
13
  * https://github.com/libp2p/interface-transport#multiaddrconnection
17
14
  */
18
15
  export function streamToMaConnection (props: StreamProperties): MultiaddrConnection {
19
- const { stream, remoteAddr } = props
20
- const { sink, source } = stream
16
+ const { stream, remoteAddr, logger } = props
17
+ const log = logger.forComponent('libp2p:stream:converter')
18
+
19
+ let closedRead = false
20
+ let closedWrite = false
21
+
22
+ // piggyback on `stream.close` invocations to close maconn
23
+ const streamClose = stream.close.bind(stream)
24
+ stream.close = async (options) => {
25
+ await streamClose(options)
26
+ close(true)
27
+ }
21
28
 
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
29
+ // piggyback on `stream.abort` invocations to close maconn
30
+ const streamAbort = stream.abort.bind(stream)
31
+ stream.abort = (err) => {
32
+ streamAbort(err)
33
+ close(true)
34
+ }
35
+
36
+ // piggyback on `stream.sink` invocations to close maconn
37
+ const streamSink = stream.sink.bind(stream)
38
+ stream.sink = async (source) => {
39
+ try {
40
+ await streamSink(source)
41
+ } catch (err: any) {
42
+ // If aborted we can safely ignore
43
+ if (err.type !== 'aborted') {
44
+ // If the source errored the socket will already have been destroyed by
45
+ // toIterable.duplex(). If the socket errored it will already be
46
+ // destroyed. There's nothing to do here except log the error & return.
47
+ log(err)
28
48
  }
49
+ } finally {
50
+ closedWrite = true
51
+ close()
29
52
  }
30
- }())
53
+ }
31
54
 
32
55
  const maConn: MultiaddrConnection = {
33
- async sink (source) {
56
+ log,
57
+ sink: stream.sink,
58
+ source: (async function * () {
34
59
  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)
60
+ for await (const list of stream.source) {
61
+ if (list instanceof Uint8Array) {
62
+ yield list
63
+ } else {
64
+ yield * list
65
+ }
44
66
  }
67
+ } finally {
68
+ closedRead = true
69
+ close()
45
70
  }
46
- },
47
- source: mapSource,
71
+ }()),
48
72
  remoteAddr,
49
73
  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
- }
74
+ close: stream.close,
75
+ abort: stream.abort
58
76
  }
59
77
 
60
- function close (): void {
61
- if (maConn.timeline.close == null) {
78
+ function close (force?: boolean): void {
79
+ if (force === true) {
80
+ closedRead = true
81
+ closedWrite = true
82
+ }
83
+
84
+ if (closedRead && closedWrite && maConn.timeline.close == null) {
62
85
  maConn.timeline.close = Date.now()
63
86
  }
64
87
  }
@@ -0,0 +1,65 @@
1
+ import type { Metric, Metrics } from '@libp2p/interface'
2
+
3
+ export interface TrackedMapInit {
4
+ name: string
5
+ metrics: Metrics
6
+ }
7
+
8
+ class TrackedMap<K, V> extends Map<K, V> {
9
+ private readonly metric: Metric
10
+
11
+ constructor (init: TrackedMapInit) {
12
+ super()
13
+
14
+ const { name, metrics } = init
15
+
16
+ this.metric = metrics.registerMetric(name)
17
+ this.updateComponentMetric()
18
+ }
19
+
20
+ set (key: K, value: V): this {
21
+ super.set(key, value)
22
+ this.updateComponentMetric()
23
+ return this
24
+ }
25
+
26
+ delete (key: K): boolean {
27
+ const deleted = super.delete(key)
28
+ this.updateComponentMetric()
29
+ return deleted
30
+ }
31
+
32
+ clear (): void {
33
+ super.clear()
34
+ this.updateComponentMetric()
35
+ }
36
+
37
+ private updateComponentMetric (): void {
38
+ this.metric.update(this.size)
39
+ }
40
+ }
41
+
42
+ export interface CreateTrackedMapInit {
43
+ /**
44
+ * The metric name to use
45
+ */
46
+ name: string
47
+
48
+ /**
49
+ * A metrics implementation
50
+ */
51
+ metrics?: Metrics
52
+ }
53
+
54
+ export function trackedMap <K, V> (config: CreateTrackedMapInit): Map<K, V> {
55
+ const { name, metrics } = config
56
+ let map: Map<K, V>
57
+
58
+ if (metrics != null) {
59
+ map = new TrackedMap<K, V>({ name, metrics })
60
+ } else {
61
+ map = new Map<K, V>()
62
+ }
63
+
64
+ return map
65
+ }