Skip to content

Commit 63dc010

Browse files
committed
Update: pulled out some things, now we are calling the client.drive.export command
1 parent 419cf04 commit 63dc010

1 file changed

Lines changed: 8 additions & 114 deletions

File tree

bin/commands/export.js

Lines changed: 8 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,13 @@
11
const fs = require('fs').promises
22
const p = require('path')
3-
const { EventEmitter } = require('events')
43

54
const cliProgress = require('cli-progress')
6-
const mirrorFolder = require('mirror-folder')
7-
const low = require('last-one-wins')
8-
const streamx = require('streamx')
9-
const pump = require('pump')
105
const { flags } = require('@oclif/command')
116

127
const DaemonCommand = require('../../lib/cli')
138
const { HyperdriveClient } = require('../..')
149

15-
const KEY_FILE_PATH = '.hyperdrive-export-key'
16-
17-
class DriveWatcher extends EventEmitter {
18-
constructor (client, drive, opts = {}) {
19-
super()
20-
this.client = client
21-
this.drive = drive
22-
this.recursive = !!opts.recursive
23-
this.drivesByPath = new Map([[ '/', drive ]])
24-
this.versionsByPath = new Map()
25-
this.unwatchesByPath = new Map()
26-
this.watchers = []
27-
this.timer = null
28-
this.emittingStats = false
29-
}
30-
31-
_createDiffer (path, drive) {
32-
// Last-one-wins in case the watch is triggered many times in quick succession.
33-
const self = this
34-
return low(onupdate)
35-
36-
async function onupdate (_, cb) {
37-
const lastVersion = self.versionsByPath.get(path)
38-
try {
39-
const diffStream = await drive.createDiffStream(lastVersion)
40-
const currentVersion = await drive.version()
41-
self.versionsByPath.set(path, currentVersion)
42-
return pump(diffStream, new streamx.Transform({
43-
transform: (data, cb) => {
44-
for (const watcher of self.watchers) {
45-
watcher(p.join(path, data.name))
46-
}
47-
return cb(null)
48-
}
49-
}), err => {
50-
if (err) return cb(err)
51-
return cb(null)
52-
})
53-
} catch (err) {
54-
return cb(err)
55-
}
56-
}
57-
}
58-
59-
async _emitStats () {
60-
if (this.emittingStats) return
61-
this.emittingStats = true
62-
var total = 0
63-
var downloaded = 0
64-
var peers = 0
65-
for (const [path, drive] of this.drivesByPath) {
66-
const driveStats = await drive.stats()
67-
for (const { path, content } of driveStats.stats) {
68-
if (path !== '/' || !content) continue
69-
downloaded += content.downloadedBlocks
70-
total += content.totalBlocks
71-
peers = content.peers
72-
}
73-
}
74-
this.emit('stats', { total, downloaded, peers })
75-
this.emittingStats = false
76-
}
77-
78-
async start () {
79-
// TODO: Handle dynamic (un)mounting.
80-
this.versionsByPath.set('/', await this.drive.version())
81-
this.unwatchesByPath.set('/', this.drive.watch('/', this._createDiffer('/', this.drive)))
82-
const allMounts = await this.drive.mounts({ memory: false, recursive: this.recursive })
83-
for (const { path, opts } of allMounts) {
84-
if (path === '/') continue
85-
const childDrive = await this.client.drive.get({ key: opts.key })
86-
this.drivesByPath.set(path, childDrive)
87-
this.versionsByPath.set(path, opts.version)
88-
this.unwatchesByPath.set(path, childDrive.watch('/', this._createDiffer(path, childDrive)))
89-
}
90-
this.timer = setInterval(this._emitStats.bind(this), 1000)
91-
}
92-
93-
watch (_, onwatch) {
94-
// The watch path is ignored for drives.
95-
this.watchers.push(onwatch)
96-
return () => {
97-
this.watchers.splice(this.watchers.indexOf(onwatch), 1)
98-
}
99-
}
100-
101-
async close () {
102-
for (const [path, unwatch] of this.unwatchesByPath) {
103-
await unwatch()
104-
}
105-
if (this.timer) {
106-
clearInterval(this.timer)
107-
this.timer = null
108-
}
109-
}
110-
}
10+
const { exportKeyFilePath: KEY_FILE_PATH } = require('../../lib/constants')
11111

11212
class ExportCommand extends DaemonCommand {
11313
static usage = 'export [key] [dir]'
@@ -163,29 +63,23 @@ class ExportCommand extends DaemonCommand {
16363
const drive = await this.client.drive.get({ key })
16464
if (!loadedKey) await saveKeyToFile()
16565

166-
const driveWatcher = new DriveWatcher(this.client, drive, {
167-
recursive: flags.recursive
168-
})
169-
await driveWatcher.start()
170-
17166
const progress = new cliProgress.SingleBar({
17267
format: `Exporting | {bar} | {percentage}% | {value}/{total} Content Blocks | {peers} Peers`
17368
})
17469
console.log(`Exporting ${key.toString('hex')} into ${dir} (Ctrl+c to exit)...`)
17570
console.log()
17671
progress.start(1, 0)
177-
driveWatcher.on('stats', stats => {
178-
progress.setTotal(stats.total)
179-
progress.update(stats.downloaded, { peers: stats.peers })
180-
})
18172

18273
process.on('SIGINT', cleanup)
18374
process.on('SIGTERM', cleanup)
18475

185-
const remoteMirror = mirrorFolder({ fs: drive, name: '/' }, dir, {
186-
watch: driveWatcher.watch.bind(driveWatcher),
187-
keepExisting: true,
188-
ensureParents: true
76+
const driveWatcher = this.client.drive.export(drive, dir, {recursive: flags.recursive})
77+
78+
await driveWatcher.start()
79+
80+
driveWatcher.on('stats', stats => {
81+
progress.setTotal(stats.total)
82+
progress.update(stats.downloaded, { peers: stats.peers })
18983
})
19084

19185
async function cleanup () {

0 commit comments

Comments
 (0)