@libp2p/utils 6.7.1 → 6.7.2-8484de8a2

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 (165) hide show
  1. package/README.md +16 -1
  2. package/dist/index.min.js +6 -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 +389 -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 +33 -1
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +33 -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 +5 -0
  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/socket-writer.browser.d.ts +2 -0
  92. package/dist/src/socket-writer.browser.d.ts.map +1 -0
  93. package/dist/src/socket-writer.browser.js +4 -0
  94. package/dist/src/socket-writer.browser.js.map +1 -0
  95. package/dist/src/socket-writer.d.ts +19 -0
  96. package/dist/src/socket-writer.d.ts.map +1 -0
  97. package/dist/src/socket-writer.js +43 -0
  98. package/dist/src/socket-writer.js.map +1 -0
  99. package/dist/src/stream-pair.d.ts +42 -0
  100. package/dist/src/stream-pair.d.ts.map +1 -0
  101. package/dist/src/stream-pair.js +40 -0
  102. package/dist/src/stream-pair.js.map +1 -0
  103. package/dist/src/stream-utils.d.ts +198 -0
  104. package/dist/src/stream-utils.d.ts.map +1 -0
  105. package/dist/src/stream-utils.js +369 -0
  106. package/dist/src/stream-utils.js.map +1 -0
  107. package/package.json +19 -163
  108. package/src/abstract-message-stream.ts +549 -0
  109. package/src/abstract-multiaddr-connection.ts +93 -0
  110. package/src/abstract-stream-muxer.ts +239 -0
  111. package/src/abstract-stream.ts +51 -464
  112. package/src/errors.ts +10 -0
  113. package/src/get-thin-waist-addresses.browser.ts +5 -4
  114. package/src/get-thin-waist-addresses.ts +8 -12
  115. package/src/index.ts +33 -1
  116. package/src/length-prefixed-decoder.ts +98 -0
  117. package/src/message-queue.ts +156 -0
  118. package/src/mock-muxer.ts +304 -0
  119. package/src/mock-stream.ts +101 -0
  120. package/src/multiaddr/get-net-config.ts +112 -0
  121. package/src/multiaddr/index.ts +6 -0
  122. package/src/multiaddr/is-global-unicast.ts +8 -11
  123. package/src/multiaddr/is-link-local.ts +11 -20
  124. package/src/multiaddr/is-loopback.ts +12 -7
  125. package/src/multiaddr/is-network-address.ts +4 -19
  126. package/src/multiaddr/is-private.ts +9 -14
  127. package/src/multiaddr/utils.ts +46 -0
  128. package/src/multiaddr-connection-pair.ts +147 -0
  129. package/src/queue/index.ts +30 -9
  130. package/src/rate-limiter.ts +3 -30
  131. package/src/socket-writer.browser.ts +3 -0
  132. package/src/socket-writer.ts +64 -0
  133. package/src/stream-pair.ts +90 -0
  134. package/src/stream-utils.ts +873 -0
  135. package/dist/src/abort-options.d.ts +0 -7
  136. package/dist/src/abort-options.d.ts.map +0 -1
  137. package/dist/src/abort-options.js +0 -14
  138. package/dist/src/abort-options.js.map +0 -1
  139. package/dist/src/array-equals.d.ts +0 -24
  140. package/dist/src/array-equals.d.ts.map +0 -1
  141. package/dist/src/array-equals.js +0 -31
  142. package/dist/src/array-equals.js.map +0 -1
  143. package/dist/src/close-source.d.ts +0 -4
  144. package/dist/src/close-source.d.ts.map +0 -1
  145. package/dist/src/close-source.js +0 -11
  146. package/dist/src/close-source.js.map +0 -1
  147. package/dist/src/close.d.ts +0 -21
  148. package/dist/src/close.d.ts.map +0 -1
  149. package/dist/src/close.js +0 -49
  150. package/dist/src/close.js.map +0 -1
  151. package/dist/src/multiaddr/is-ip-based.d.ts +0 -6
  152. package/dist/src/multiaddr/is-ip-based.d.ts.map +0 -1
  153. package/dist/src/multiaddr/is-ip-based.js +0 -18
  154. package/dist/src/multiaddr/is-ip-based.js.map +0 -1
  155. package/dist/src/stream-to-ma-conn.d.ts +0 -23
  156. package/dist/src/stream-to-ma-conn.d.ts.map +0 -1
  157. package/dist/src/stream-to-ma-conn.js +0 -75
  158. package/dist/src/stream-to-ma-conn.js.map +0 -1
  159. package/dist/typedoc-urls.json +0 -147
  160. package/src/abort-options.ts +0 -20
  161. package/src/array-equals.ts +0 -34
  162. package/src/close-source.ts +0 -14
  163. package/src/close.ts +0 -65
  164. package/src/multiaddr/is-ip-based.ts +0 -21
  165. 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'
@@ -101,6 +101,8 @@ export interface QueueEvents<JobReturnType, JobOptions extends AbortOptions = Ab
101
101
 
102
102
  /**
103
103
  * A job has failed
104
+ *
105
+ * @deprecated Listen for the 'failure' event instead - it gives more context and is generally more useful, this event will be removed in a future release
104
106
  */
105
107
  error: CustomEvent<Error>
106
108
 
@@ -129,6 +131,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
129
131
  public queue: Array<Job<JobOptions, JobReturnType>>
130
132
  private pending: number
131
133
  private readonly sort?: Comparator<Job<JobOptions, JobReturnType>>
134
+ private paused: boolean
132
135
 
133
136
  constructor (init: QueueInit<JobReturnType, JobOptions> = {}) {
134
137
  super()
@@ -136,6 +139,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
136
139
  this.concurrency = init.concurrency ?? Number.POSITIVE_INFINITY
137
140
  this.maxSize = init.maxSize ?? Number.POSITIVE_INFINITY
138
141
  this.pending = 0
142
+ this.paused = false
139
143
 
140
144
  if (init.metricName != null) {
141
145
  init.metrics?.registerMetricGroup(init.metricName, {
@@ -172,7 +176,24 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
172
176
  this.safeDispatchEvent('idle')
173
177
  }
174
178
 
179
+ pause (): void {
180
+ this.paused = true
181
+ }
182
+
183
+ resume (): void {
184
+ if (!this.paused) {
185
+ return
186
+ }
187
+
188
+ this.paused = false
189
+ this.tryToStartAnother()
190
+ }
191
+
175
192
  private tryToStartAnother (): boolean {
193
+ if (this.paused) {
194
+ return false
195
+ }
196
+
176
197
  if (this.size === 0) {
177
198
  this.emitEmpty()
178
199
 
@@ -263,7 +284,6 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
263
284
  }
264
285
  }
265
286
 
266
- this.safeDispatchEvent('error', { detail: err })
267
287
  this.safeDispatchEvent('failure', { detail: { job, error: err } })
268
288
 
269
289
  throw err
@@ -299,7 +319,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
299
319
  return
300
320
  }
301
321
 
302
- await raceEvent(this, 'empty', options?.signal)
322
+ await pEvent(this, 'empty', options)
303
323
  }
304
324
 
305
325
  /**
@@ -319,7 +339,8 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
319
339
  return
320
340
  }
321
341
 
322
- await raceEvent(this, 'next', options?.signal, {
342
+ await pEvent(this, 'next', {
343
+ ...options,
323
344
  filter: () => this.size < limit
324
345
  })
325
346
  }
@@ -338,7 +359,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
338
359
  return
339
360
  }
340
361
 
341
- await raceEvent(this, 'idle', options?.signal)
362
+ await pEvent(this, 'idle', options)
342
363
  }
343
364
 
344
365
  /**
@@ -395,8 +416,8 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
395
416
  }
396
417
  }
397
418
 
398
- const onQueueError = (evt: CustomEvent<Error>): void => {
399
- cleanup(evt.detail)
419
+ const onQueueFailure = (evt: CustomEvent<QueueJobFailure<JobReturnType, JobOptions>>): void => {
420
+ cleanup(evt.detail.error)
400
421
  }
401
422
 
402
423
  const onQueueIdle = (): void => {
@@ -410,7 +431,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
410
431
 
411
432
  // add listeners
412
433
  this.addEventListener('completed', onQueueJobComplete)
413
- this.addEventListener('error', onQueueError)
434
+ this.addEventListener('failure', onQueueFailure)
414
435
  this.addEventListener('idle', onQueueIdle)
415
436
  options?.signal?.addEventListener('abort', onSignalAbort)
416
437
 
@@ -419,7 +440,7 @@ export class Queue<JobReturnType = unknown, JobOptions extends AbortOptions = Ab
419
440
  } finally {
420
441
  // remove listeners
421
442
  this.removeEventListener('completed', onQueueJobComplete)
422
- this.removeEventListener('error', onQueueError)
443
+ this.removeEventListener('failure', onQueueFailure)
423
444
  this.removeEventListener('idle', onQueueIdle)
424
445
  options?.signal?.removeEventListener('abort', onSignalAbort)
425
446
 
@@ -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
 
@@ -0,0 +1,3 @@
1
+ export function socketWriter (): void {
2
+ throw new Error('Unsupported in browsers')
3
+ }