-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstore.js
115 lines (99 loc) · 3.12 KB
/
store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const leveldb = require('level')
const hypercontent = require('hyper-content-db')
const mkdirp = require('mkdirp')
const p = require('path')
const util = require('util')
const exitHook = require('async-exit-hook')
const localSocketStream = require('./lib/local-socket-stream.js')
const { logEvents } = require('./util/debug')
const hyperswarm = require('@hyperswarm/replicator')
// const hyperdiscovery = require('hyperdiscovery')
const mapView = require('./lib/view-mapping')
const sonarView = require('./lib/view-sonar')
const log = require('./lib/log').child({ name: 'db' })
module.exports = {
makeStore
}
function makeStore (opts = {}) {
const basePath = opts.storage
if (!opts.key) opts.key = null
const paths = {
level: p.join(basePath, 'level'),
corestore: p.join(basePath, 'corestore'),
sonar: p.join(basePath, 'sonar')
}
Object.values(paths).forEach(p => mkdirp.sync(p))
const level = leveldb(paths.level, 'level')
const store = hypercontent(paths.corestore, opts.key, {
level,
sparse: false
})
store.useRecordView('mapView', mapView, { mappings: opts.mappings })
store.useRecordView('search', sonarView, { storage: paths.sonar })
store.ready(() => {
log.info('Database key: %s', store.key.toString('hex'))
console.log('Database key: %s', store.key.toString('hex'))
})
replicate(store)
return store
}
function replicate (store) {
store.ready(() => {
// replicateHyperswarm(store)
// replicateHyperdiscovery(store)
replicateLocal(store)
})
}
// This is a quick hack because hyperswarm keeps
// failing to replicate between two processes
// running on my dev laptop. It checks if socket
// on /tmp/archipel.sock exists, and if so connects
// to it, otherwise opens it. Then the database
// replication stream is passed into it, unencrypted.
// Note that discovery keys are not respected.
function replicateLocal (store) {
// const name = 'archipel-' + store.discoveryKey.toString('hex')
const name = 'archipel-replication'
localSocketStream(name, (err, stream) => {
if (err) return console.error('cannot setup local replication: ', err)
const repl = store.replicate({ encrypt: false, live: true })
repl.pipe(stream).pipe(repl)
})
}
function replicateHyperswarm (store) {
const swarm = hyperswarm(store.multidrive.primaryDrive, {
live: true,
announce: true,
lookup: true
})
swarm.on('join', dkey => log.debug('Joining swarm for %s', dkey.toString('hex')))
swarm.on('connection', peer => log.info('New peer'))
store.sources(drives => {
for (let drive of drives) {
swarm.join(drive.discoveryKey)
}
})
store.on('source', drive => {
swarm.join(drive.discoveryKey)
})
logEvents(swarm, 'hyperswarm')
}
// function replicateHyperdiscovery (store) {
// const swarm = hyperdiscovery(store)
// store.sources(drives => {
// for (let drive of drives) {
// swarm.add(drive)
// }
// })
// // store.on('source', drive => {
// // swarm.add(drive)
// // })
// logEvents(swarm, 'hyperdiscovery')
// }
function once (fn) {
let wrapper = (...args) => {
wrapper = () => {}
fn(...args)
}
return wrapper
}