@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.
- package/README.md +16 -1
- package/dist/index.min.js +6 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/abstract-message-stream.d.ts +129 -0
- package/dist/src/abstract-message-stream.d.ts.map +1 -0
- package/dist/src/abstract-message-stream.js +389 -0
- package/dist/src/abstract-message-stream.js.map +1 -0
- package/dist/src/abstract-multiaddr-connection.d.ts +26 -0
- package/dist/src/abstract-multiaddr-connection.d.ts.map +1 -0
- package/dist/src/abstract-multiaddr-connection.js +66 -0
- package/dist/src/abstract-multiaddr-connection.js.map +1 -0
- package/dist/src/abstract-stream-muxer.d.ts +53 -0
- package/dist/src/abstract-stream-muxer.d.ts.map +1 -0
- package/dist/src/abstract-stream-muxer.js +169 -0
- package/dist/src/abstract-stream-muxer.js.map +1 -0
- package/dist/src/abstract-stream.d.ts +14 -130
- package/dist/src/abstract-stream.d.ts.map +1 -1
- package/dist/src/abstract-stream.js +39 -321
- package/dist/src/abstract-stream.js.map +1 -1
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +8 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/get-thin-waist-addresses.browser.d.ts +1 -1
- package/dist/src/get-thin-waist-addresses.browser.d.ts.map +1 -1
- package/dist/src/get-thin-waist-addresses.browser.js +4 -3
- package/dist/src/get-thin-waist-addresses.browser.js.map +1 -1
- package/dist/src/get-thin-waist-addresses.d.ts +1 -1
- package/dist/src/get-thin-waist-addresses.d.ts.map +1 -1
- package/dist/src/get-thin-waist-addresses.js +7 -9
- package/dist/src/get-thin-waist-addresses.js.map +1 -1
- package/dist/src/index.d.ts +33 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +33 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/length-prefixed-decoder.d.ts +37 -0
- package/dist/src/length-prefixed-decoder.d.ts.map +1 -0
- package/dist/src/length-prefixed-decoder.js +64 -0
- package/dist/src/length-prefixed-decoder.js.map +1 -0
- package/dist/src/message-queue.d.ts +61 -0
- package/dist/src/message-queue.d.ts.map +1 -0
- package/dist/src/message-queue.js +93 -0
- package/dist/src/message-queue.js.map +1 -0
- package/dist/src/mock-muxer.d.ts +57 -0
- package/dist/src/mock-muxer.d.ts.map +1 -0
- package/dist/src/mock-muxer.js +204 -0
- package/dist/src/mock-muxer.js.map +1 -0
- package/dist/src/mock-stream.d.ts +31 -0
- package/dist/src/mock-stream.d.ts.map +1 -0
- package/dist/src/mock-stream.js +69 -0
- package/dist/src/mock-stream.js.map +1 -0
- package/dist/src/multiaddr/get-net-config.d.ts +55 -0
- package/dist/src/multiaddr/get-net-config.d.ts.map +1 -0
- package/dist/src/multiaddr/get-net-config.js +54 -0
- package/dist/src/multiaddr/get-net-config.js.map +1 -0
- package/dist/src/multiaddr/index.d.ts +7 -0
- package/dist/src/multiaddr/index.d.ts.map +1 -0
- package/dist/src/multiaddr/index.js +7 -0
- package/dist/src/multiaddr/index.js.map +1 -0
- package/dist/src/multiaddr/is-global-unicast.d.ts.map +1 -1
- package/dist/src/multiaddr/is-global-unicast.js +8 -9
- package/dist/src/multiaddr/is-global-unicast.js.map +1 -1
- package/dist/src/multiaddr/is-link-local.d.ts.map +1 -1
- package/dist/src/multiaddr/is-link-local.js +11 -16
- package/dist/src/multiaddr/is-link-local.js.map +1 -1
- package/dist/src/multiaddr/is-loopback.d.ts.map +1 -1
- package/dist/src/multiaddr/is-loopback.js +12 -5
- package/dist/src/multiaddr/is-loopback.js.map +1 -1
- package/dist/src/multiaddr/is-network-address.d.ts.map +1 -1
- package/dist/src/multiaddr/is-network-address.js +4 -16
- package/dist/src/multiaddr/is-network-address.js.map +1 -1
- package/dist/src/multiaddr/is-private.d.ts.map +1 -1
- package/dist/src/multiaddr/is-private.js +9 -10
- package/dist/src/multiaddr/is-private.js.map +1 -1
- package/dist/src/multiaddr/utils.d.ts +5 -0
- package/dist/src/multiaddr/utils.d.ts.map +1 -0
- package/dist/src/multiaddr/utils.js +32 -0
- package/dist/src/multiaddr/utils.js.map +1 -0
- package/dist/src/multiaddr-connection-pair.d.ts +25 -0
- package/dist/src/multiaddr-connection-pair.d.ts.map +1 -0
- package/dist/src/multiaddr-connection-pair.js +103 -0
- package/dist/src/multiaddr-connection-pair.js.map +1 -0
- package/dist/src/queue/index.d.ts +5 -0
- package/dist/src/queue/index.d.ts.map +1 -1
- package/dist/src/queue/index.js +24 -9
- package/dist/src/queue/index.js.map +1 -1
- package/dist/src/rate-limiter.d.ts +1 -15
- package/dist/src/rate-limiter.d.ts.map +1 -1
- package/dist/src/rate-limiter.js +1 -14
- package/dist/src/rate-limiter.js.map +1 -1
- package/dist/src/socket-writer.browser.d.ts +2 -0
- package/dist/src/socket-writer.browser.d.ts.map +1 -0
- package/dist/src/socket-writer.browser.js +4 -0
- package/dist/src/socket-writer.browser.js.map +1 -0
- package/dist/src/socket-writer.d.ts +19 -0
- package/dist/src/socket-writer.d.ts.map +1 -0
- package/dist/src/socket-writer.js +43 -0
- package/dist/src/socket-writer.js.map +1 -0
- package/dist/src/stream-pair.d.ts +42 -0
- package/dist/src/stream-pair.d.ts.map +1 -0
- package/dist/src/stream-pair.js +40 -0
- package/dist/src/stream-pair.js.map +1 -0
- package/dist/src/stream-utils.d.ts +198 -0
- package/dist/src/stream-utils.d.ts.map +1 -0
- package/dist/src/stream-utils.js +369 -0
- package/dist/src/stream-utils.js.map +1 -0
- package/package.json +19 -163
- package/src/abstract-message-stream.ts +549 -0
- package/src/abstract-multiaddr-connection.ts +93 -0
- package/src/abstract-stream-muxer.ts +239 -0
- package/src/abstract-stream.ts +51 -464
- package/src/errors.ts +10 -0
- package/src/get-thin-waist-addresses.browser.ts +5 -4
- package/src/get-thin-waist-addresses.ts +8 -12
- package/src/index.ts +33 -1
- package/src/length-prefixed-decoder.ts +98 -0
- package/src/message-queue.ts +156 -0
- package/src/mock-muxer.ts +304 -0
- package/src/mock-stream.ts +101 -0
- package/src/multiaddr/get-net-config.ts +112 -0
- package/src/multiaddr/index.ts +6 -0
- package/src/multiaddr/is-global-unicast.ts +8 -11
- package/src/multiaddr/is-link-local.ts +11 -20
- package/src/multiaddr/is-loopback.ts +12 -7
- package/src/multiaddr/is-network-address.ts +4 -19
- package/src/multiaddr/is-private.ts +9 -14
- package/src/multiaddr/utils.ts +46 -0
- package/src/multiaddr-connection-pair.ts +147 -0
- package/src/queue/index.ts +30 -9
- package/src/rate-limiter.ts +3 -30
- package/src/socket-writer.browser.ts +3 -0
- package/src/socket-writer.ts +64 -0
- package/src/stream-pair.ts +90 -0
- package/src/stream-utils.ts +873 -0
- package/dist/src/abort-options.d.ts +0 -7
- package/dist/src/abort-options.d.ts.map +0 -1
- package/dist/src/abort-options.js +0 -14
- package/dist/src/abort-options.js.map +0 -1
- package/dist/src/array-equals.d.ts +0 -24
- package/dist/src/array-equals.d.ts.map +0 -1
- package/dist/src/array-equals.js +0 -31
- package/dist/src/array-equals.js.map +0 -1
- package/dist/src/close-source.d.ts +0 -4
- package/dist/src/close-source.d.ts.map +0 -1
- package/dist/src/close-source.js +0 -11
- package/dist/src/close-source.js.map +0 -1
- package/dist/src/close.d.ts +0 -21
- package/dist/src/close.d.ts.map +0 -1
- package/dist/src/close.js +0 -49
- package/dist/src/close.js.map +0 -1
- package/dist/src/multiaddr/is-ip-based.d.ts +0 -6
- package/dist/src/multiaddr/is-ip-based.d.ts.map +0 -1
- package/dist/src/multiaddr/is-ip-based.js +0 -18
- package/dist/src/multiaddr/is-ip-based.js.map +0 -1
- package/dist/src/stream-to-ma-conn.d.ts +0 -23
- package/dist/src/stream-to-ma-conn.d.ts.map +0 -1
- package/dist/src/stream-to-ma-conn.js +0 -75
- package/dist/src/stream-to-ma-conn.js.map +0 -1
- package/dist/typedoc-urls.json +0 -147
- package/src/abort-options.ts +0 -20
- package/src/array-equals.ts +0 -34
- package/src/close-source.ts +0 -14
- package/src/close.ts +0 -65
- package/src/multiaddr/is-ip-based.ts +0 -21
- 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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cidrContains } from '@chainsafe/netmask'
|
|
2
|
-
import {
|
|
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
|
-
|
|
11
|
-
if (value == null) {
|
|
12
|
-
continue
|
|
13
|
-
}
|
|
10
|
+
const config = getNetConfig(ma)
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
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 {
|
|
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
|
-
|
|
10
|
-
if (code === CODE_IP6ZONE) {
|
|
11
|
-
continue
|
|
12
|
-
}
|
|
9
|
+
const config = getNetConfig(ma)
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
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 {
|
|
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
|
-
|
|
19
|
-
if (code === CODE_IP6ZONE) {
|
|
20
|
-
continue
|
|
21
|
-
}
|
|
9
|
+
getNetConfig(ma)
|
|
22
10
|
|
|
23
|
-
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
+
}
|
package/src/queue/index.ts
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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('
|
|
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('
|
|
443
|
+
this.removeEventListener('failure', onQueueFailure)
|
|
423
444
|
this.removeEventListener('idle', onQueueIdle)
|
|
424
445
|
options?.signal?.removeEventListener('abort', onSignalAbort)
|
|
425
446
|
|
package/src/rate-limiter.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|