uniswap-v2-loader 1.3.0 → 1.4.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [1.4.0] - 2026-02-24
2
+ - spawn -> cluster
3
+ - test order pool by factory id at CSV
4
+ - clear cache CSV file
5
+
1
6
  ## [1.3.0] - 2026-02-23
2
7
  - Add CLI version with `-c` or `--count` flag to counting loaded pairs from cache
3
8
 
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const { all, count } = require('../index')
2
+ const { all, count, clear_cache } = require('../index')
3
3
  const rl = require('readline')
4
4
 
5
5
  const progress = (c, t) => {
@@ -13,5 +13,7 @@ const progress = (c, t) => {
13
13
 
14
14
  if (process.argv[2] == '-c' || process.argv[2] == '--count')
15
15
  console.log(count())
16
+ else if (process.argv[2] == '--clear')
17
+ clear_cache()
16
18
  else
17
19
  all({progress})
package/debug.js ADDED
@@ -0,0 +1 @@
1
+ require('./index').all({to: 487283})
@@ -0,0 +1,19 @@
1
+ const path = require('path')
2
+ const env = process.env
3
+ const os = require('os')
4
+ const home = os.homedir()
5
+ const pkg = require('./package.json')
6
+
7
+ module.exports = path.join(
8
+ ...(process.platform === 'win32'
9
+ ? (env.LOCALAPPDATA || env.APPDATA)
10
+ ? [env.LOCALAPPDATA || env.APPDATA]
11
+ : [home, 'AppData', 'Local']
12
+ : process.platform === 'darwin'
13
+ ? [home, 'Library', 'Caches']
14
+ : (env.XDG_CACHE_HOME && path.isAbsolute(env.XDG_CACHE_HOME))
15
+ ? [env.XDG_CACHE_HOME]
16
+ : [home, '.cache']
17
+ ),
18
+ pkg.name + '_pairs.csv'
19
+ )
package/index.js CHANGED
@@ -1,26 +1,9 @@
1
- const { spawn } = require('child_process')
1
+ const cluster = require('cluster')
2
2
  const fs = require('fs')
3
3
  const os = require('os')
4
- const path = require('path')
5
- const env = process.env
6
- const home = os.homedir()
7
- const pkg = require('./package.json')
8
- const default_filename = path.join(
9
- ...(process.platform === 'win32'
10
- ? (env.LOCALAPPDATA || env.APPDATA)
11
- ? [env.LOCALAPPDATA || env.APPDATA]
12
- : [home, 'AppData', 'Local']
13
- : process.platform === 'darwin'
14
- ? [home, 'Library', 'Caches']
15
- : (env.XDG_CACHE_HOME && path.isAbsolute(env.XDG_CACHE_HOME))
16
- ? [env.XDG_CACHE_HOME]
17
- : [home, '.cache']
18
- ),
19
- pkg.name + '_pairs.csv'
20
- )
21
4
  const { parseAbiItem, createPublicClient, http } = require('viem')
22
5
  const { mainnet } = require('viem/chains')
23
-
6
+ const default_filename = require('./default_cache_filename')
24
7
  const workers = os.cpus().length - 1
25
8
  const missed = Array(workers).fill(null).map(() => [])
26
9
  const key = process.env.KEY || 'FZBvlPrOxtgaKBBkry3SH0W1IqH4Y5tu'
@@ -57,74 +40,55 @@ const load = params => {
57
40
  abi: [parseAbiItem('function allPairsLength() view returns (uint256)')],
58
41
  functionName: 'allPairsLength'
59
42
  }).then(_ => Number(_))
60
- ).then(allPairsLength => {
61
- var next_pair_order = 0
43
+ ).then(all_pairs_length => {
62
44
  const start_loading_from = pairs.length
63
45
  ? Math.max(from || 0, pairs[pairs.length - 1].id + 1)
64
46
  : 0
65
47
 
48
+ var next_pair_order = pairs.length
49
+ ? pairs[pairs.length - 1].id + 1
50
+ : 0
51
+
66
52
  missed.forEach(_ => _.length = 0)
67
53
 
68
- for (var i = start_loading_from, rr = 0; i < allPairsLength; i++) {
54
+ for (var i = start_loading_from, rr = 0; i < all_pairs_length; i++) {
69
55
  missed[rr].push(i)
70
56
  if (missed[rr].length % chunk_size == 0)
71
57
  rr = (rr + 1) % workers
72
58
  }
73
59
 
74
60
  var progress_i = 0
75
- const progress_end = allPairsLength - start_loading_from
76
-
77
- const jobs_data_filename = `jobs_data_${Date.now()}.json`
78
- fs.writeFileSync(jobs_data_filename, JSON.stringify({
79
- missed,
80
- factory,
81
- chunk_size,
82
- key
83
- }), 'utf8')
61
+ const progress_end = all_pairs_length - start_loading_from
84
62
 
63
+ cluster.setupPrimary({ exec: __dirname + '/loader.js' })
85
64
  return Promise.all(
86
65
  missed
87
66
  .filter(_ => _.length)
88
- .map((_, i) => new Promise(y => {
89
- const loader = spawn('node', ['loader.js', jobs_data_filename, i.toString()])
90
- loader.stdout.on('data', data => {
91
- data += data.toString()
92
- if (!data.includes('\n')) return
93
- const lines = data.split('\n')
94
- data = lines.shift()
95
- lines.forEach(line => {
96
- const a = line.split(',')
97
- const id = +a[0]
98
- pairs[id] = {
99
- id,
100
- pair: a[1],
101
- token0: a[2],
102
- token1: a[3]
103
- }
104
- })
105
- if (progress) {
106
- progress_i += lines.length
107
- progress(progress_i, progress_end)
108
- }
67
+ .map((missed, i) => new Promise(y => {
68
+ const w = cluster.fork()
69
+ w.send({ missed, factory, chunk_size, key })
70
+ w.on('message', p => {
71
+ const id = p[0]
72
+ pairs[id] = { id, pair: p[1], token0: p[2], token1: p[3] }
73
+ if (progress) progress(++progress_i, progress_end)
109
74
  if (filename) {
110
- var pair
111
- while (pair = pairs[next_pair_order]) {
112
- fs.appendFileSync(filename, pair.id + ',' + pair.pair + ',' + pair.token0 + ',' + pair.token1 + '\n')
75
+ var _
76
+ while (_ = pairs[next_pair_order]) {
77
+ fs.appendFileSync(filename, `${_.id},${_.pair},${_.token0},${_.token1}\n`)
113
78
  next_pair_order++
114
79
  }
115
80
  }
116
81
  })
117
- loader.on('close', y)
82
+ w.on('exit', y)
118
83
  }))
119
- )
120
- .then(() => {
121
- fs.unlinkSync(jobs_data_filename)
122
- return pairs
123
- })
84
+ ).then(() => pairs)
124
85
  })
125
86
  }
126
87
 
127
88
 
89
+ module.exports.clear_cache = () =>
90
+ fs.unlinkSync(default_filename)
91
+
128
92
  module.exports.all = (params = {}) =>
129
93
  load(params)
130
94
 
package/loader.js CHANGED
@@ -1,6 +1,5 @@
1
1
  const { parseAbiItem, createPublicClient, http } = require('viem')
2
2
  const { mainnet } = require('viem/chains')
3
- const fs = require('fs')
4
3
 
5
4
  const POOL = {
6
5
  ID: 0,
@@ -69,7 +68,7 @@ async function load(params) {
69
68
  pool[POOL.TOKEN0] = token0_result.result.toLowerCase()
70
69
  pool[POOL.TOKEN1] = token1_result.result.toLowerCase()
71
70
 
72
- console.log(pool.join(','))
71
+ process.send(pool)
73
72
  } else {
74
73
  retry_missed.push(pools_ok[j].id)
75
74
  }
@@ -88,17 +87,11 @@ async function load(params) {
88
87
  }
89
88
  }
90
89
 
91
- const jobs_data_filename = process.argv[2]
92
- const job_index = +process.argv[3]
90
+ process.on('message', jobs_data => {
91
+ const client = createPublicClient({
92
+ chain: mainnet,
93
+ transport: http(`https://eth-mainnet.g.alchemy.com/v2/${jobs_data.key}`)
94
+ })
93
95
 
94
- if (isNaN(job_index)) process.exit(1)
95
-
96
- const jobs_data = JSON.parse(fs.readFileSync(jobs_data_filename, 'utf8'))
97
- jobs_data.missed = jobs_data.missed[job_index]
98
-
99
- const client = createPublicClient({
100
- chain: mainnet,
101
- transport: http(`https://eth-mainnet.g.alchemy.com/v2/${jobs_data.key}`)
96
+ load({client, ...jobs_data}).then(() => process.exit())
102
97
  })
103
-
104
- load({client, ...jobs_data})
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniswap-v2-loader",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Uniswap v2 protocol loader",
5
5
  "keywords": [
6
6
  "uniswap-v2",
package/test.js CHANGED
@@ -46,3 +46,10 @@ test('Heavy test load first 3000 pairs', () =>
46
46
  assert.equal(pairs.length, 3000)
47
47
  })
48
48
  )
49
+
50
+ test('Each line at CSV cache file should be orderd by pair id (factory id)', () => {
51
+ const lines = fs.readFileSync(require('./default_cache_filename'), 'utf8').trim().split('\n')
52
+ for (var i = 0; i < lines.length; i++)
53
+ assert.equal(i, +lines[i].split(',').shift())
54
+ })
55
+