uniswap-v2-loader 5.0.18 → 5.0.19
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/.github/workflows/test.yml +1 -1
- package/README.md +1 -0
- package/index.d.ts +2 -0
- package/index.js +7 -3
- package/loader.js +24 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,6 +41,7 @@ High-performance parallel fetcher for liquidity pairs. Efficiently synchronizes
|
|
|
41
41
|
| `multicall_size` | `number` | RPC batch size per multicall request. | `50` |
|
|
42
42
|
| `workers` | `number` | Number of parallel worker threads. | `CPU - 1` |
|
|
43
43
|
| `progress` | `function` | Progress callback: `(current, total) => {}`. | `undefined` |
|
|
44
|
+
| `abort_signal` | `AbortSignal` | Signal to cancel loading and release workers. | `undefined` |
|
|
44
45
|
|
|
45
46
|
**Returns**: `Promise<Pair[]>`
|
|
46
47
|
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -16,9 +16,11 @@ const load = (params = {}) => {
|
|
|
16
16
|
from = 0,
|
|
17
17
|
to,
|
|
18
18
|
progress,
|
|
19
|
+
abort_signal,
|
|
19
20
|
workers = max_workers,
|
|
20
21
|
pairs,
|
|
21
22
|
} = params
|
|
23
|
+
|
|
22
24
|
filename ??= default_cache_filename(factory)
|
|
23
25
|
workers = Math.min(workers, max_workers)
|
|
24
26
|
|
|
@@ -44,10 +46,11 @@ const load = (params = {}) => {
|
|
|
44
46
|
|
|
45
47
|
return Promise.resolve(pairs.slice(0, to))
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
|
|
48
50
|
return (to
|
|
49
51
|
? Promise.resolve(to)
|
|
50
52
|
: fetch('https://eth-mainnet.g.alchemy.com/v2/' + key, {
|
|
53
|
+
signal: abort_signal,
|
|
51
54
|
method: 'POST',
|
|
52
55
|
headers: { 'Content-Type': 'application/json' },
|
|
53
56
|
body: JSON.stringify({
|
|
@@ -92,7 +95,7 @@ const load = (params = {}) => {
|
|
|
92
95
|
const ids = []
|
|
93
96
|
for (var i = start_loading_from; i < all_pairs_length; i++)
|
|
94
97
|
ids.push(i)
|
|
95
|
-
return require('./loader')({ ids, factory, key, multicall_size }, onpair)
|
|
98
|
+
return require('./loader')({ ids, factory, key, multicall_size, abort_signal }, onpair)
|
|
96
99
|
.then(() => pairs)
|
|
97
100
|
}
|
|
98
101
|
|
|
@@ -112,13 +115,14 @@ const load = (params = {}) => {
|
|
|
112
115
|
.filter(_ => _.length)
|
|
113
116
|
.map((ids, i) => new Promise(y => {
|
|
114
117
|
const w = cluster.fork()
|
|
118
|
+
abort_signal?.addEventListener('abort', () => w.send('abort'))
|
|
115
119
|
w.send({ ids, factory, key, multicall_size })
|
|
116
120
|
w.on('message', onpair)
|
|
117
121
|
w.on('exit', y)
|
|
118
122
|
}))
|
|
119
123
|
).then(() => pairs)
|
|
120
124
|
})
|
|
121
|
-
.catch(() => new Promise(resolve => setTimeout(() => resolve(load(params)), 1000)))
|
|
125
|
+
.catch(() => abort_signal?.aborted ? pairs : new Promise(resolve => setTimeout(() => resolve(load(params)), 1000)))
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
module.exports.load = (params = {}) =>
|
package/loader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
const get_pairs_addresses = (key, factory, ids) => ids.length == 0
|
|
1
|
+
const get_pairs_addresses = (key, factory, ids, abort_signal) => ids.length == 0
|
|
2
2
|
? Promise.resolve([])
|
|
3
3
|
: fetch('https://eth-mainnet.g.alchemy.com/v2/' + key, {
|
|
4
|
+
signal: abort_signal,
|
|
4
5
|
method: 'POST',
|
|
5
6
|
headers: { 'Content-Type': 'application/json' },
|
|
6
7
|
body: JSON.stringify(ids.map((id, i) => ({
|
|
@@ -30,14 +31,15 @@ const get_pairs_addresses = (key, factory, ids) => ids.length == 0
|
|
|
30
31
|
return failed_ids.length == 0
|
|
31
32
|
? addresses
|
|
32
33
|
: new Promise(resolve => setTimeout(() => resolve(
|
|
33
|
-
get_pairs_addresses(key, factory, failed_ids).then(retried => [...addresses, ...retried])
|
|
34
|
+
get_pairs_addresses(key, factory, failed_ids, abort_signal).then(retried => [...addresses, ...retried])
|
|
34
35
|
), 10000))
|
|
35
36
|
})
|
|
36
|
-
.catch(() => new Promise(resolve => setTimeout(() => resolve(get_pairs_addresses(key, factory, ids)), 10000)))
|
|
37
|
+
.catch(() => abort_signal?.aborted ? [] : new Promise(resolve => setTimeout(() => resolve(get_pairs_addresses(key, factory, ids, abort_signal)), 10000)))
|
|
37
38
|
|
|
38
|
-
const get_tokens = (key, addresses) => addresses.length == 0
|
|
39
|
+
const get_tokens = (key, addresses, abort_signal) => addresses.length == 0
|
|
39
40
|
? Promise.resolve({})
|
|
40
41
|
: fetch('https://eth-mainnet.g.alchemy.com/v2/' + key, {
|
|
42
|
+
signal: abort_signal,
|
|
41
43
|
method: 'POST',
|
|
42
44
|
headers: { 'Content-Type': 'application/json' },
|
|
43
45
|
body: JSON.stringify(addresses.flatMap((address, i) => [
|
|
@@ -83,20 +85,20 @@ const get_tokens = (key, addresses) => addresses.length == 0
|
|
|
83
85
|
return failed_addresses.length == 0
|
|
84
86
|
? tokens
|
|
85
87
|
: new Promise(resolve => setTimeout(() => resolve(
|
|
86
|
-
get_tokens(key, failed_addresses).then(retried => ({ ...tokens, ...retried }))
|
|
88
|
+
get_tokens(key, failed_addresses, abort_signal).then(retried => ({ ...tokens, ...retried }))
|
|
87
89
|
), 10000))
|
|
88
90
|
})
|
|
89
|
-
.catch(() => new Promise(resolve => setTimeout(() => resolve(get_tokens(key, addresses)), 10000)))
|
|
91
|
+
.catch(() => abort_signal?.aborted ? {} : new Promise(resolve => setTimeout(() => resolve(get_tokens(key, addresses, abort_signal)), 10000)))
|
|
90
92
|
|
|
91
|
-
const main = ({ids, factory, key, multicall_size}, onpair) => {
|
|
93
|
+
const main = ({ids, factory, key, multicall_size, abort_signal}, onpair) => {
|
|
92
94
|
const chunks = []
|
|
93
95
|
for (let i = 0; i < ids.length; i += multicall_size)
|
|
94
96
|
chunks.push(ids.slice(i, i + multicall_size))
|
|
95
97
|
|
|
96
98
|
return chunks.reduce((p, ids, ic) =>
|
|
97
99
|
p.then(() =>
|
|
98
|
-
get_pairs_addresses(key, factory, ids).then(pairs_addresses =>
|
|
99
|
-
get_tokens(key, pairs_addresses).then(tokens =>
|
|
100
|
+
get_pairs_addresses(key, factory, ids, abort_signal).then(pairs_addresses =>
|
|
101
|
+
get_tokens(key, pairs_addresses, abort_signal).then(tokens =>
|
|
100
102
|
ids.forEach((id, i) =>
|
|
101
103
|
onpair({
|
|
102
104
|
id,
|
|
@@ -113,12 +115,20 @@ const main = ({ids, factory, key, multicall_size}, onpair) => {
|
|
|
113
115
|
}
|
|
114
116
|
|
|
115
117
|
|
|
116
|
-
if (require.main != module)
|
|
118
|
+
if (require.main != module) {
|
|
117
119
|
module.exports = main
|
|
118
|
-
else
|
|
120
|
+
} else {
|
|
121
|
+
const abort_controller = new AbortController()
|
|
122
|
+
const abort_signal = abort_controller.signal
|
|
123
|
+
|
|
119
124
|
process.on(
|
|
120
125
|
'message',
|
|
121
|
-
message =>
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
message => {
|
|
127
|
+
if (message == 'abort')
|
|
128
|
+
abort_controller.abort()
|
|
129
|
+
else
|
|
130
|
+
main({...message, abort_signal}, pair => process.send(pair))
|
|
131
|
+
.finally(() => process.exit())
|
|
132
|
+
}
|
|
124
133
|
)
|
|
134
|
+
}
|