@libp2p/utils 6.7.1 → 6.7.2-6059227cb

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 (160) hide show
  1. package/README.md +16 -1
  2. package/dist/index.min.js +7 -1
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/abstract-message-stream.d.ts +129 -0
  5. package/dist/src/abstract-message-stream.d.ts.map +1 -0
  6. package/dist/src/abstract-message-stream.js +393 -0
  7. package/dist/src/abstract-message-stream.js.map +1 -0
  8. package/dist/src/abstract-multiaddr-connection.d.ts +26 -0
  9. package/dist/src/abstract-multiaddr-connection.d.ts.map +1 -0
  10. package/dist/src/abstract-multiaddr-connection.js +66 -0
  11. package/dist/src/abstract-multiaddr-connection.js.map +1 -0
  12. package/dist/src/abstract-stream-muxer.d.ts +53 -0
  13. package/dist/src/abstract-stream-muxer.d.ts.map +1 -0
  14. package/dist/src/abstract-stream-muxer.js +169 -0
  15. package/dist/src/abstract-stream-muxer.js.map +1 -0
  16. package/dist/src/abstract-stream.d.ts +14 -130
  17. package/dist/src/abstract-stream.d.ts.map +1 -1
  18. package/dist/src/abstract-stream.js +39 -321
  19. package/dist/src/abstract-stream.js.map +1 -1
  20. package/dist/src/errors.d.ts +8 -0
  21. package/dist/src/errors.d.ts.map +1 -1
  22. package/dist/src/errors.js +8 -0
  23. package/dist/src/errors.js.map +1 -1
  24. package/dist/src/get-thin-waist-addresses.browser.d.ts +1 -1
  25. package/dist/src/get-thin-waist-addresses.browser.d.ts.map +1 -1
  26. package/dist/src/get-thin-waist-addresses.browser.js +4 -3
  27. package/dist/src/get-thin-waist-addresses.browser.js.map +1 -1
  28. package/dist/src/get-thin-waist-addresses.d.ts +1 -1
  29. package/dist/src/get-thin-waist-addresses.d.ts.map +1 -1
  30. package/dist/src/get-thin-waist-addresses.js +7 -9
  31. package/dist/src/get-thin-waist-addresses.js.map +1 -1
  32. package/dist/src/index.d.ts +31 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +31 -1
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/length-prefixed-decoder.d.ts +37 -0
  37. package/dist/src/length-prefixed-decoder.d.ts.map +1 -0
  38. package/dist/src/length-prefixed-decoder.js +64 -0
  39. package/dist/src/length-prefixed-decoder.js.map +1 -0
  40. package/dist/src/message-queue.d.ts +61 -0
  41. package/dist/src/message-queue.d.ts.map +1 -0
  42. package/dist/src/message-queue.js +93 -0
  43. package/dist/src/message-queue.js.map +1 -0
  44. package/dist/src/mock-muxer.d.ts +57 -0
  45. package/dist/src/mock-muxer.d.ts.map +1 -0
  46. package/dist/src/mock-muxer.js +204 -0
  47. package/dist/src/mock-muxer.js.map +1 -0
  48. package/dist/src/mock-stream.d.ts +31 -0
  49. package/dist/src/mock-stream.d.ts.map +1 -0
  50. package/dist/src/mock-stream.js +69 -0
  51. package/dist/src/mock-stream.js.map +1 -0
  52. package/dist/src/multiaddr/get-net-config.d.ts +55 -0
  53. package/dist/src/multiaddr/get-net-config.d.ts.map +1 -0
  54. package/dist/src/multiaddr/get-net-config.js +54 -0
  55. package/dist/src/multiaddr/get-net-config.js.map +1 -0
  56. package/dist/src/multiaddr/index.d.ts +7 -0
  57. package/dist/src/multiaddr/index.d.ts.map +1 -0
  58. package/dist/src/multiaddr/index.js +7 -0
  59. package/dist/src/multiaddr/index.js.map +1 -0
  60. package/dist/src/multiaddr/is-global-unicast.d.ts.map +1 -1
  61. package/dist/src/multiaddr/is-global-unicast.js +8 -9
  62. package/dist/src/multiaddr/is-global-unicast.js.map +1 -1
  63. package/dist/src/multiaddr/is-link-local.d.ts.map +1 -1
  64. package/dist/src/multiaddr/is-link-local.js +11 -16
  65. package/dist/src/multiaddr/is-link-local.js.map +1 -1
  66. package/dist/src/multiaddr/is-loopback.d.ts.map +1 -1
  67. package/dist/src/multiaddr/is-loopback.js +12 -5
  68. package/dist/src/multiaddr/is-loopback.js.map +1 -1
  69. package/dist/src/multiaddr/is-network-address.d.ts.map +1 -1
  70. package/dist/src/multiaddr/is-network-address.js +4 -16
  71. package/dist/src/multiaddr/is-network-address.js.map +1 -1
  72. package/dist/src/multiaddr/is-private.d.ts.map +1 -1
  73. package/dist/src/multiaddr/is-private.js +9 -10
  74. package/dist/src/multiaddr/is-private.js.map +1 -1
  75. package/dist/src/multiaddr/utils.d.ts +5 -0
  76. package/dist/src/multiaddr/utils.d.ts.map +1 -0
  77. package/dist/src/multiaddr/utils.js +32 -0
  78. package/dist/src/multiaddr/utils.js.map +1 -0
  79. package/dist/src/multiaddr-connection-pair.d.ts +25 -0
  80. package/dist/src/multiaddr-connection-pair.d.ts.map +1 -0
  81. package/dist/src/multiaddr-connection-pair.js +103 -0
  82. package/dist/src/multiaddr-connection-pair.js.map +1 -0
  83. package/dist/src/queue/index.d.ts +3 -4
  84. package/dist/src/queue/index.d.ts.map +1 -1
  85. package/dist/src/queue/index.js +24 -9
  86. package/dist/src/queue/index.js.map +1 -1
  87. package/dist/src/rate-limiter.d.ts +1 -15
  88. package/dist/src/rate-limiter.d.ts.map +1 -1
  89. package/dist/src/rate-limiter.js +1 -14
  90. package/dist/src/rate-limiter.js.map +1 -1
  91. package/dist/src/stream-pair.d.ts +42 -0
  92. package/dist/src/stream-pair.d.ts.map +1 -0
  93. package/dist/src/stream-pair.js +40 -0
  94. package/dist/src/stream-pair.js.map +1 -0
  95. package/dist/src/stream-utils.d.ts +191 -0
  96. package/dist/src/stream-utils.d.ts.map +1 -0
  97. package/dist/src/stream-utils.js +370 -0
  98. package/dist/src/stream-utils.js.map +1 -0
  99. package/package.json +15 -162
  100. package/src/abstract-message-stream.ts +553 -0
  101. package/src/abstract-multiaddr-connection.ts +93 -0
  102. package/src/abstract-stream-muxer.ts +239 -0
  103. package/src/abstract-stream.ts +51 -464
  104. package/src/errors.ts +10 -0
  105. package/src/get-thin-waist-addresses.browser.ts +5 -4
  106. package/src/get-thin-waist-addresses.ts +8 -12
  107. package/src/index.ts +31 -1
  108. package/src/length-prefixed-decoder.ts +98 -0
  109. package/src/message-queue.ts +156 -0
  110. package/src/mock-muxer.ts +304 -0
  111. package/src/mock-stream.ts +101 -0
  112. package/src/multiaddr/get-net-config.ts +112 -0
  113. package/src/multiaddr/index.ts +6 -0
  114. package/src/multiaddr/is-global-unicast.ts +8 -11
  115. package/src/multiaddr/is-link-local.ts +11 -20
  116. package/src/multiaddr/is-loopback.ts +12 -7
  117. package/src/multiaddr/is-network-address.ts +4 -19
  118. package/src/multiaddr/is-private.ts +9 -14
  119. package/src/multiaddr/utils.ts +46 -0
  120. package/src/multiaddr-connection-pair.ts +147 -0
  121. package/src/queue/index.ts +28 -14
  122. package/src/rate-limiter.ts +3 -30
  123. package/src/stream-pair.ts +90 -0
  124. package/src/stream-utils.ts +865 -0
  125. package/dist/src/abort-options.d.ts +0 -7
  126. package/dist/src/abort-options.d.ts.map +0 -1
  127. package/dist/src/abort-options.js +0 -14
  128. package/dist/src/abort-options.js.map +0 -1
  129. package/dist/src/array-equals.d.ts +0 -24
  130. package/dist/src/array-equals.d.ts.map +0 -1
  131. package/dist/src/array-equals.js +0 -31
  132. package/dist/src/array-equals.js.map +0 -1
  133. package/dist/src/close-source.d.ts +0 -4
  134. package/dist/src/close-source.d.ts.map +0 -1
  135. package/dist/src/close-source.js +0 -11
  136. package/dist/src/close-source.js.map +0 -1
  137. package/dist/src/close.d.ts +0 -21
  138. package/dist/src/close.d.ts.map +0 -1
  139. package/dist/src/close.js +0 -49
  140. package/dist/src/close.js.map +0 -1
  141. package/dist/src/merge-options.d.ts +0 -7
  142. package/dist/src/merge-options.d.ts.map +0 -1
  143. package/dist/src/merge-options.js +0 -128
  144. package/dist/src/merge-options.js.map +0 -1
  145. package/dist/src/multiaddr/is-ip-based.d.ts +0 -6
  146. package/dist/src/multiaddr/is-ip-based.d.ts.map +0 -1
  147. package/dist/src/multiaddr/is-ip-based.js +0 -18
  148. package/dist/src/multiaddr/is-ip-based.js.map +0 -1
  149. package/dist/src/stream-to-ma-conn.d.ts +0 -23
  150. package/dist/src/stream-to-ma-conn.d.ts.map +0 -1
  151. package/dist/src/stream-to-ma-conn.js +0 -75
  152. package/dist/src/stream-to-ma-conn.js.map +0 -1
  153. package/dist/typedoc-urls.json +0 -147
  154. package/src/abort-options.ts +0 -20
  155. package/src/array-equals.ts +0 -34
  156. package/src/close-source.ts +0 -14
  157. package/src/close.ts +0 -65
  158. package/src/merge-options.ts +0 -161
  159. package/src/multiaddr/is-ip-based.ts +0 -21
  160. package/src/stream-to-ma-conn.ts +0 -105
@@ -0,0 +1,112 @@
1
+ import { InvalidParametersError } from '@libp2p/interface'
2
+ import type { Multiaddr } from '@multiformats/multiaddr'
3
+
4
+ export interface IP4NetConfig {
5
+ type: 'ip4'
6
+ host: string
7
+ protocol?: 'tcp' | 'udp'
8
+ port?: number
9
+ cidr?: number
10
+ sni?: string
11
+ }
12
+
13
+ export interface IP6NetConfig {
14
+ type: 'ip6'
15
+ host: string
16
+ protocol?: 'tcp' | 'udp'
17
+ port?: number
18
+ zone?: string
19
+ cidr?: string
20
+ sni?: string
21
+ }
22
+
23
+ export interface DNSNetConfig {
24
+ type: 'dns'
25
+ host: string
26
+ protocol?: 'tcp' | 'udp'
27
+ port: number
28
+ cidr?: number
29
+ }
30
+
31
+ export interface DNS4NetConfig {
32
+ type: 'dns4'
33
+ host: string
34
+ protocol?: 'tcp' | 'udp'
35
+ port: number
36
+ cidr?: number
37
+ }
38
+
39
+ export interface DNS6NetConfig {
40
+ type: 'dns6'
41
+ host: string
42
+ protocol?: 'tcp' | 'udp'
43
+ port: number
44
+ cidr?: number
45
+ }
46
+
47
+ export interface DNSAddrNetConfig {
48
+ type: 'dnsaddr'
49
+ host: string
50
+ protocol?: 'tcp' | 'udp'
51
+ port: number
52
+ cidr?: number
53
+ }
54
+
55
+ export type NetConfig = IP4NetConfig | IP6NetConfig | DNSNetConfig | DNS4NetConfig | DNS6NetConfig | DNSAddrNetConfig
56
+
57
+ /**
58
+ * Returns host/port/etc information for multiaddrs, if it is available.
59
+ *
60
+ * It will throw if the passed multiaddr does not start with a network address,
61
+ * e.g. a IPv4, IPv6, DNS, DNS4, DNS6 or DNSADDR address
62
+ */
63
+ export function getNetConfig (ma: Multiaddr): NetConfig {
64
+ const components = ma.getComponents()
65
+ const config: any = {}
66
+ let index = 0
67
+
68
+ if (components[index]?.name === 'ip6zone') {
69
+ config.zone = `${components[index].value}`
70
+ index++
71
+ }
72
+
73
+ if (components[index].name === 'ip4' || components[index].name === 'ip6') {
74
+ config.type = components[index].name
75
+ config.host = components[index].value
76
+ index++
77
+ } else if (components[index].name === 'dns' || components[index].name === 'dns4' || components[index].name === 'dns6') {
78
+ config.type = components[index].name
79
+ config.host = components[index].value
80
+ index++
81
+ } else if (components[index].name === 'dnsaddr') {
82
+ config.type = components[index].name
83
+ config.host = `_dnsaddr.${components[index].value}`
84
+ index++
85
+ }
86
+
87
+ if (components[index]?.name === 'tcp' || components[index]?.name === 'udp') {
88
+ config.protocol = components[index].name === 'tcp' ? 'tcp' : 'udp'
89
+ config.port = parseInt(`${components[index].value}`)
90
+ index++
91
+ }
92
+
93
+ if (components[index]?.name === 'ipcidr') {
94
+ if (config.type === 'ip4') {
95
+ config.cidr = parseInt(`${components[index].value}`)
96
+ } else if (config.type === 'ip6') {
97
+ config.cidr = `${components[index].value}`
98
+ }
99
+ index++
100
+ }
101
+
102
+ if (config.type == null || config.host == null) {
103
+ throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4, IPv6, DNS, DNS4, DNS6 or DNSADDR address`)
104
+ }
105
+
106
+ if (components[index]?.name === 'tls' && components[index + 1]?.name === 'sni') {
107
+ config.sni = components[index + 1].value
108
+ index += 2
109
+ }
110
+
111
+ return config
112
+ }
@@ -0,0 +1,6 @@
1
+ export * from './get-net-config.ts'
2
+ export * from './is-global-unicast.js'
3
+ export * from './is-link-local.js'
4
+ export * from './is-loopback.js'
5
+ export * from './is-network-address.js'
6
+ export * from './is-private.js'
@@ -1,5 +1,5 @@
1
1
  import { cidrContains } from '@chainsafe/netmask'
2
- import { CODE_IP6 } from '@multiformats/multiaddr'
2
+ import { getNetConfig } from './get-net-config.ts'
3
3
  import type { Multiaddr } from '@multiformats/multiaddr'
4
4
 
5
5
  /**
@@ -7,18 +7,15 @@ import type { Multiaddr } from '@multiformats/multiaddr'
7
7
  */
8
8
  export function isGlobalUnicast (ma: Multiaddr): boolean {
9
9
  try {
10
- for (const { code, value } of ma.getComponents()) {
11
- if (value == null) {
12
- continue
13
- }
10
+ const config = getNetConfig(ma)
14
11
 
15
- if (code === CODE_IP6) {
16
- return cidrContains('2000::/3', value)
17
- }
12
+ switch (config.type) {
13
+ case 'ip6':
14
+ return cidrContains('2000::/3', config.host)
15
+ default:
16
+ return false
18
17
  }
19
18
  } catch {
20
-
19
+ return false
21
20
  }
22
-
23
- return false
24
21
  }
@@ -1,4 +1,4 @@
1
- import { CODE_IP4, CODE_IP6, CODE_IP6ZONE } from '@multiformats/multiaddr'
1
+ import { getNetConfig } from './get-net-config.ts'
2
2
  import type { Multiaddr } from '@multiformats/multiaddr'
3
3
 
4
4
  /**
@@ -6,26 +6,17 @@ import type { Multiaddr } from '@multiformats/multiaddr'
6
6
  */
7
7
  export function isLinkLocal (ma: Multiaddr): boolean {
8
8
  try {
9
- for (const { code, value } of ma.getComponents()) {
10
- if (code === CODE_IP6ZONE) {
11
- continue
12
- }
9
+ const config = getNetConfig(ma)
13
10
 
14
- if (value == null) {
15
- continue
16
- }
17
-
18
- if (code === CODE_IP4) {
19
- return value.startsWith('169.254.')
20
- }
21
-
22
- if (code === CODE_IP6) {
23
- return value.toLowerCase().startsWith('fe80')
24
- }
11
+ switch (config.type) {
12
+ case 'ip4':
13
+ return config.host.startsWith('169.254.')
14
+ case 'ip6':
15
+ return config.host.toLowerCase().startsWith('fe80')
16
+ default:
17
+ return false
25
18
  }
26
- } catch {
27
-
19
+ } catch (err) {
20
+ return false
28
21
  }
29
-
30
- return false
31
22
  }
@@ -1,17 +1,22 @@
1
1
  import { isLoopbackAddr } from 'is-loopback-addr'
2
- import { isIpBased } from './is-ip-based.js'
2
+ import { getNetConfig } from './get-net-config.ts'
3
3
  import type { Multiaddr } from '@multiformats/multiaddr'
4
4
 
5
5
  /**
6
6
  * Check if a given multiaddr is a loopback address.
7
7
  */
8
8
  export function isLoopback (ma: Multiaddr): boolean {
9
- if (!isIpBased(ma)) {
10
- // not an IP based multiaddr, cannot be private
9
+ try {
10
+ const config = getNetConfig(ma)
11
+
12
+ switch (config.type) {
13
+ case 'ip4':
14
+ case 'ip6':
15
+ return isLoopbackAddr(config.host)
16
+ default:
17
+ return false
18
+ }
19
+ } catch {
11
20
  return false
12
21
  }
13
-
14
- const { address } = ma.nodeAddress()
15
-
16
- return isLoopbackAddr(address)
17
22
  }
@@ -1,30 +1,15 @@
1
- import { CODE_IP4, CODE_IP6, CODE_IP6ZONE, CODE_DNS, CODE_DNS4, CODE_DNS6, CODE_DNSADDR } from '@multiformats/multiaddr'
1
+ import { getNetConfig } from './get-net-config.ts'
2
2
  import type { Multiaddr } from '@multiformats/multiaddr'
3
3
 
4
- const NETWORK_CODECS = [
5
- CODE_IP4,
6
- CODE_IP6,
7
- CODE_DNS,
8
- CODE_DNS4,
9
- CODE_DNS6,
10
- CODE_DNSADDR
11
- ]
12
-
13
4
  /**
14
5
  * Check if a given multiaddr is a network address
15
6
  */
16
7
  export function isNetworkAddress (ma: Multiaddr): boolean {
17
8
  try {
18
- for (const { code } of ma.getComponents()) {
19
- if (code === CODE_IP6ZONE) {
20
- continue
21
- }
9
+ getNetConfig(ma)
22
10
 
23
- return NETWORK_CODECS.includes(code)
24
- }
11
+ return true
25
12
  } catch {
26
-
13
+ return false
27
14
  }
28
-
29
- return false
30
15
  }
@@ -1,5 +1,5 @@
1
1
  import { isPrivateIp } from '../private-ip.js'
2
- import { isIpBased } from './is-ip-based.js'
2
+ import { getNetConfig } from './get-net-config.ts'
3
3
  import type { Multiaddr } from '@multiformats/multiaddr'
4
4
 
5
5
  /**
@@ -7,21 +7,16 @@ import type { Multiaddr } from '@multiformats/multiaddr'
7
7
  */
8
8
  export function isPrivate (ma: Multiaddr): boolean {
9
9
  try {
10
- if (!isIpBased(ma)) {
11
- // not an IP based multiaddr, cannot be private
12
- return false
13
- }
14
-
15
- const [[, value]] = ma.stringTuples()
10
+ const config = getNetConfig(ma)
16
11
 
17
- if (value == null) {
18
- return false
12
+ switch (config.type) {
13
+ case 'ip4':
14
+ case 'ip6':
15
+ return isPrivateIp(config.host) ?? false
16
+ default:
17
+ return config.host === 'localhost'
19
18
  }
20
-
21
- return isPrivateIp(value) ?? false
22
19
  } catch {
23
-
20
+ return false
24
21
  }
25
-
26
- return true
27
22
  }
@@ -0,0 +1,46 @@
1
+ import { CODE_IP4, CODE_IP6, CODE_IP6ZONE, multiaddr } from '@multiformats/multiaddr'
2
+ import type { NetConfig } from './get-net-config.ts'
3
+ import type { Multiaddr } from '@multiformats/multiaddr'
4
+
5
+ export function getIpFromMultiaddr (ma: Multiaddr): string | undefined {
6
+ const components = ma.getComponents()
7
+ let index = 0
8
+
9
+ if (components[0]?.code === CODE_IP6ZONE) {
10
+ index++
11
+ }
12
+
13
+ if (components[index]?.code !== CODE_IP4 && components[index]?.code !== CODE_IP6) {
14
+ return
15
+ }
16
+
17
+ return components[index]?.value
18
+ }
19
+
20
+ export function netConfigToMultiaddr (config: NetConfig, port?: number | string, host?: string): Multiaddr {
21
+ const parts: Array<string | number> = [
22
+ config.type,
23
+ host ?? config.host
24
+ ]
25
+
26
+ if (config.protocol != null) {
27
+ const p = port ?? config.port
28
+
29
+ if (p != null) {
30
+ parts.push(
31
+ config.protocol,
32
+ p
33
+ )
34
+ }
35
+ }
36
+
37
+ if (config.type === 'ip6' && config.zone != null) {
38
+ parts.unshift('ip6zone', config.zone)
39
+ }
40
+
41
+ if (config.cidr != null) {
42
+ parts.push('ipcidr', config.cidr)
43
+ }
44
+
45
+ return multiaddr(`/${parts.join('/')}`)
46
+ }
@@ -0,0 +1,147 @@
1
+ import { StreamMessageEvent } from '@libp2p/interface'
2
+ import { defaultLogger } from '@libp2p/logger'
3
+ import { multiaddr } from '@multiformats/multiaddr'
4
+ import { pEvent } from 'p-event'
5
+ import { raceSignal } from 'race-signal'
6
+ import { AbstractMultiaddrConnection } from './abstract-multiaddr-connection.ts'
7
+ import { MessageQueue } from './message-queue.ts'
8
+ import type { SendResult } from './abstract-message-stream.ts'
9
+ import type { AbstractMultiaddrConnectionInit } from './abstract-multiaddr-connection.ts'
10
+ import type { MessageQueueEvents, MessageQueueInit } from './message-queue.ts'
11
+ import type { AbortOptions, Logger, MultiaddrConnection, MessageStreamDirection, TypedEventTarget } from '@libp2p/interface'
12
+ import type { Multiaddr } from '@multiformats/multiaddr'
13
+ import type { Uint8ArrayList } from 'uint8arraylist'
14
+
15
+ interface MockMultiaddrConnectionMessages extends MessageQueueEvents {
16
+ close: Event
17
+ pause: Event
18
+ resume: Event
19
+ }
20
+
21
+ export interface MockMultiaddrConnectionInit extends AbstractMultiaddrConnectionInit {
22
+ id: string,
23
+ log: Logger,
24
+ direction: MessageStreamDirection
25
+ local: MessageQueue<MockMultiaddrConnectionMessages>
26
+ remote: TypedEventTarget<MockMultiaddrConnectionMessages>
27
+ remoteAddr: Multiaddr
28
+ }
29
+
30
+ let multiaddrConnectionId = 0
31
+
32
+ class MockMultiaddrConnection extends AbstractMultiaddrConnection {
33
+ private local: MessageQueue<MockMultiaddrConnectionMessages>
34
+ private remote: TypedEventTarget<MockMultiaddrConnectionMessages>
35
+
36
+ constructor (init: MockMultiaddrConnectionInit) {
37
+ super(init)
38
+
39
+ this.local = init.local
40
+ this.remote = init.remote
41
+
42
+ this.local.addEventListener('drain', () => {
43
+ this.safeDispatchEvent('drain')
44
+ })
45
+
46
+ this.remote.addEventListener('message', (evt) => {
47
+ if (this.status !== 'open') {
48
+ return
49
+ }
50
+
51
+ this.onData(evt.data)
52
+ })
53
+ this.remote.addEventListener('reset', (evt) => {
54
+ if (this.status !== 'open') {
55
+ return
56
+ }
57
+
58
+ this.onRemoteReset()
59
+ })
60
+ this.remote.addEventListener('close', (evt) => {
61
+ this.onTransportClosed()
62
+ })
63
+ this.remote.addEventListener('pause', (evt) => {
64
+ this.local.pause()
65
+ })
66
+ this.remote.addEventListener('resume', (evt) => {
67
+ this.local.resume()
68
+ })
69
+ }
70
+
71
+ sendData (data: Uint8ArrayList): SendResult {
72
+ const canSendMore = this.local.send(new StreamMessageEvent(data))
73
+
74
+ return {
75
+ sentBytes: data.byteLength,
76
+ canSendMore
77
+ }
78
+ }
79
+
80
+ sendReset (): void {
81
+ this.local.send(new Event('reset'))
82
+ }
83
+
84
+ async sendClose (options?: AbortOptions): Promise<void> {
85
+ if (this.local.needsDrain) {
86
+ await pEvent(this.local, 'drain', {
87
+ signal: options?.signal
88
+ })
89
+ }
90
+
91
+ return raceSignal(new Promise<void>((resolve, reject) => {
92
+ this.local.send(new Event('close'))
93
+ this.local.onIdle().then(resolve, reject)
94
+ }), options?.signal)
95
+ }
96
+
97
+ sendPause (): void {
98
+ this.local.send(new Event('pause'))
99
+ }
100
+
101
+ sendResume (): void {
102
+ this.local.send(new Event('resume'))
103
+ }
104
+ }
105
+
106
+ export interface MultiaddrConnectionPairOptions extends MessageQueueInit {
107
+ outbound?: Partial<MockMultiaddrConnectionInit>
108
+ inbound?: Partial<MockMultiaddrConnectionInit>
109
+ }
110
+
111
+ export function multiaddrConnectionPair (opts: MultiaddrConnectionPairOptions = {}): [MultiaddrConnection, MultiaddrConnection] {
112
+ const inboundId = `${multiaddrConnectionId++}`
113
+ const outboundId = `${multiaddrConnectionId++}`
114
+
115
+ const outboundLog = defaultLogger().forComponent(`libp2p:mock-maconn:outbound:${inboundId}`)
116
+ const inboundLog = defaultLogger().forComponent(`libp2p:mock-maconn:inbound:${outboundId}`)
117
+
118
+ const targetA = new MessageQueue<MockMultiaddrConnectionMessages>({
119
+ ...opts,
120
+ log: outboundLog
121
+ })
122
+ const targetB = new MessageQueue<MockMultiaddrConnectionMessages>({
123
+ ...opts,
124
+ log: inboundLog
125
+ })
126
+
127
+ return [
128
+ new MockMultiaddrConnection({
129
+ ...opts.outbound,
130
+ id: outboundId,
131
+ direction: 'outbound',
132
+ local: targetA,
133
+ remote: targetB,
134
+ remoteAddr: opts?.outbound?.remoteAddr ?? multiaddr(`/ip4/127.0.0.1/tcp/${outboundId}`),
135
+ log: outboundLog
136
+ }),
137
+ new MockMultiaddrConnection({
138
+ ...opts.inbound,
139
+ id: inboundId,
140
+ direction: 'inbound',
141
+ local: targetB,
142
+ remote: targetA,
143
+ remoteAddr: opts?.inbound?.remoteAddr ?? multiaddr(`/ip4/127.0.0.1/tcp/${inboundId}`),
144
+ log: inboundLog
145
+ })
146
+ ]
147
+ }
@@ -1,7 +1,7 @@
1
1
  import { AbortError } from '@libp2p/interface'
2
2
  import { pushable } from 'it-pushable'
3
3
  import { TypedEventEmitter } from 'main-event'
4
- import { raceEvent } from 'race-event'
4
+ import { pEvent } from 'p-event'
5
5
  import { debounce } from '../debounce.js'
6
6
  import { QueueFullError } from '../errors.js'
7
7
  import { Job } from './job.js'
@@ -99,11 +99,6 @@ export interface QueueEvents<JobReturnType, JobOptions extends AbortOptions = Ab
99
99
  */
100
100
  completed: CustomEvent<JobReturnType>
101
101
 
102
- /**
103
- * A job has failed
104
- */
105
- error: CustomEvent<Error>
106
-
107
102
  /**
108
103
  * Emitted just after `"completed", a job has finished successfully - this
109
104
  * event gives access to the job and it's result
@@ -129,6 +124,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
129
124
  public queue: Array<Job<JobOptions, JobReturnType>>
130
125
  private pending: number
131
126
  private readonly sort?: Comparator<Job<JobOptions, JobReturnType>>
127
+ private paused: boolean
132
128
 
133
129
  constructor (init: QueueInit<JobReturnType, JobOptions> = {}) {
134
130
  super()
@@ -136,6 +132,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
136
132
  this.concurrency = init.concurrency ?? Number.POSITIVE_INFINITY
137
133
  this.maxSize = init.maxSize ?? Number.POSITIVE_INFINITY
138
134
  this.pending = 0
135
+ this.paused = false
139
136
 
140
137
  if (init.metricName != null) {
141
138
  init.metrics?.registerMetricGroup(init.metricName, {
@@ -172,7 +169,24 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
172
169
  this.safeDispatchEvent('idle')
173
170
  }
174
171
 
172
+ pause (): void {
173
+ this.paused = true
174
+ }
175
+
176
+ resume (): void {
177
+ if (!this.paused) {
178
+ return
179
+ }
180
+
181
+ this.paused = false
182
+ this.tryToStartAnother()
183
+ }
184
+
175
185
  private tryToStartAnother (): boolean {
186
+ if (this.paused) {
187
+ return false
188
+ }
189
+
176
190
  if (this.size === 0) {
177
191
  this.emitEmpty()
178
192
 
@@ -263,7 +277,6 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
263
277
  }
264
278
  }
265
279
 
266
- this.safeDispatchEvent('error', { detail: err })
267
280
  this.safeDispatchEvent('failure', { detail: { job, error: err } })
268
281
 
269
282
  throw err
@@ -299,7 +312,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
299
312
  return
300
313
  }
301
314
 
302
- await raceEvent(this, 'empty', options?.signal)
315
+ await pEvent(this, 'empty', options)
303
316
  }
304
317
 
305
318
  /**
@@ -319,7 +332,8 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
319
332
  return
320
333
  }
321
334
 
322
- await raceEvent(this, 'next', options?.signal, {
335
+ await pEvent(this, 'next', {
336
+ ...options,
323
337
  filter: () => this.size < limit
324
338
  })
325
339
  }
@@ -338,7 +352,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
338
352
  return
339
353
  }
340
354
 
341
- await raceEvent(this, 'idle', options?.signal)
355
+ await pEvent(this, 'idle', options)
342
356
  }
343
357
 
344
358
  /**
@@ -395,8 +409,8 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
395
409
  }
396
410
  }
397
411
 
398
- const onQueueError = (evt: CustomEvent<Error>): void => {
399
- cleanup(evt.detail)
412
+ const onQueueFailure = (evt: CustomEvent<QueueJobFailure<JobReturnType, JobOptions>>): void => {
413
+ cleanup(evt.detail.error)
400
414
  }
401
415
 
402
416
  const onQueueIdle = (): void => {
@@ -410,7 +424,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
410
424
 
411
425
  // add listeners
412
426
  this.addEventListener('completed', onQueueJobComplete)
413
- this.addEventListener('error', onQueueError)
427
+ this.addEventListener('failure', onQueueFailure)
414
428
  this.addEventListener('idle', onQueueIdle)
415
429
  options?.signal?.addEventListener('abort', onSignalAbort)
416
430
 
@@ -419,7 +433,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
419
433
  } finally {
420
434
  // remove listeners
421
435
  this.removeEventListener('completed', onQueueJobComplete)
422
- this.removeEventListener('error', onQueueError)
436
+ this.removeEventListener('failure', onQueueFailure)
423
437
  this.removeEventListener('idle', onQueueIdle)
424
438
  options?.signal?.removeEventListener('abort', onSignalAbort)
425
439
 
@@ -1,4 +1,3 @@
1
- import delay from 'delay'
2
1
  import { RateLimitError } from './errors.js'
3
2
 
4
3
  export interface RateLimiterInit {
@@ -23,20 +22,6 @@ export interface RateLimiterInit {
23
22
  */
24
23
  blockDuration?: number
25
24
 
26
- /**
27
- * Execute allowed actions evenly over duration
28
- *
29
- * @default false
30
- */
31
- execEvenly?: boolean
32
-
33
- /**
34
- * ms, works with execEvenly=true option
35
- *
36
- * @default duration * 1000 / points
37
- */
38
- execEvenlyMinDelayMs?: number
39
-
40
25
  /**
41
26
  * @default "rlflx"
42
27
  */
@@ -65,21 +50,17 @@ export class RateLimiter {
65
50
  protected points: number
66
51
  protected duration: number
67
52
  protected blockDuration: number
68
- protected execEvenly: boolean
69
- protected execEvenlyMinDelayMs: number
70
53
  protected keyPrefix: string
71
54
 
72
55
  constructor (opts: RateLimiterInit = {}) {
73
56
  this.points = opts.points ?? 4
74
57
  this.duration = opts.duration ?? 1
75
58
  this.blockDuration = opts.blockDuration ?? 0
76
- this.execEvenly = opts.execEvenly ?? false
77
- this.execEvenlyMinDelayMs = opts.execEvenlyMinDelayMs ?? (this.duration * 1000 / this.points)
78
59
  this.keyPrefix = opts.keyPrefix ?? 'rlflx'
79
60
  this.memoryStorage = new MemoryStorage()
80
61
  }
81
62
 
82
- async consume (key: string, pointsToConsume: number = 1, options: GetKeySecDurationOptions = {}): Promise<RateLimiterResult> {
63
+ consume (key: string, pointsToConsume: number = 1, options: GetKeySecDurationOptions = {}): RateLimiterResult {
83
64
  const rlKey = this.getKey(key)
84
65
  const secDuration = this._getKeySecDuration(options)
85
66
  let res = this.memoryStorage.incrby(rlKey, pointsToConsume, secDuration)
@@ -93,14 +74,6 @@ export class RateLimiter {
93
74
  }
94
75
 
95
76
  throw new RateLimitError('Rate limit exceeded', res)
96
- } else if (this.execEvenly && res.msBeforeNext > 0 && !res.isFirstInDuration) {
97
- // Execute evenly
98
- let delayMs = Math.ceil(res.msBeforeNext / (res.remainingPoints + 2))
99
- if (delayMs < this.execEvenlyMinDelayMs) {
100
- delayMs = res.consumedPoints * this.execEvenlyMinDelayMs
101
- }
102
-
103
- await delay(delayMs)
104
77
  }
105
78
 
106
79
  return res
@@ -241,8 +214,8 @@ export class MemoryStorage {
241
214
  this.storage.delete(key)
242
215
  }, durationMs)
243
216
 
244
- if (record.timeoutId.unref != null) {
245
- record.timeoutId.unref()
217
+ if ((record.timeoutId as any).unref != null) {
218
+ (record.timeoutId as any).unref()
246
219
  }
247
220
  }
248
221