uniswap-v2-loader 5.0.18 → 5.0.20
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 +17 -12
- package/loader.js +24 -14
- package/package.json +1 -1
- package/test-esm.mjs +0 -18
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,18 +95,14 @@ 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
|
|
|
99
|
-
const missed = []
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
missed.push(ids)
|
|
104
|
-
}
|
|
105
|
-
ids.push(i)
|
|
106
|
-
}
|
|
102
|
+
const missed = Array(workers).fill(null).map(() => [])
|
|
103
|
+
|
|
104
|
+
for (var i = start_loading_from, iw = 0; i < all_pairs_length; i++)
|
|
105
|
+
missed[iw++ % workers].push(i)
|
|
107
106
|
|
|
108
107
|
cluster.setupPrimary({ exec: path.join(__dirname, 'loader.js') })
|
|
109
108
|
|
|
@@ -111,14 +110,20 @@ const load = (params = {}) => {
|
|
|
111
110
|
missed
|
|
112
111
|
.filter(_ => _.length)
|
|
113
112
|
.map((ids, i) => new Promise(y => {
|
|
113
|
+
if (abort_signal?.aborted) return y()
|
|
114
114
|
const w = cluster.fork()
|
|
115
|
+
const onabort = () => w.send('abort')
|
|
116
|
+
abort_signal?.addEventListener('abort', onabort, { once: true })
|
|
115
117
|
w.send({ ids, factory, key, multicall_size })
|
|
116
118
|
w.on('message', onpair)
|
|
117
|
-
w.on('exit',
|
|
119
|
+
w.on('exit', () => {
|
|
120
|
+
abort_signal?.removeEventListener('abort', onabort)
|
|
121
|
+
y()
|
|
122
|
+
})
|
|
118
123
|
}))
|
|
119
124
|
).then(() => pairs)
|
|
120
125
|
})
|
|
121
|
-
.catch(() => new Promise(resolve => setTimeout(() => resolve(load(params)), 1000)))
|
|
126
|
+
.catch(() => abort_signal?.aborted ? pairs : new Promise(resolve => setTimeout(() => resolve(load(params)), 1000)))
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
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
|
+
}
|
package/package.json
CHANGED
package/test-esm.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { load, subscribe } from './index.mjs'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import { describe, it } from 'node:test'
|
|
4
|
-
|
|
5
|
-
describe('ESM Support', () => {
|
|
6
|
-
it('should import load and subscribe', () => {
|
|
7
|
-
assert.equal(typeof load, 'function')
|
|
8
|
-
assert.equal(typeof subscribe, 'function')
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
it('should load first pair', () =>
|
|
12
|
-
load({ to: 1 })
|
|
13
|
-
.then(pairs => {
|
|
14
|
-
assert.equal(pairs.length, 1)
|
|
15
|
-
assert.equal(pairs[0].id, 0)
|
|
16
|
-
})
|
|
17
|
-
)
|
|
18
|
-
})
|