-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlibrary.js
116 lines (94 loc) · 3.18 KB
/
library.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
116
const inherits = require('inherits')
const EventEmitter = require('events').EventEmitter
const crypto = require('hypercore-crypto')
const Archive = require('./archive')
const { asyncThunky, chainStorage, folderName } = require('./util')
module.exports = Library
function Library (storage, opts) {
if (!(this instanceof Library)) return new Library(storage, opts)
opts = opts || {}
this.storage = opts.storage || chainStorage(storage)
this.archives = {}
// this.archiveTypes = opts.archiveTypes || {}
this.archiveTypes = this._properArchiveTypes(opts.archiveTypes)
this.ready = asyncThunky(this._ready.bind(this))
}
inherits(Library, EventEmitter)
Library.prototype._ready = function (done) {
done()
}
Library.prototype._properArchiveTypes = function (archiveTypes) {
// aim: prevent registering archiveTypes directly,
// i.e. archiveTypes need to be an Object with the archive Types as children
// TODO: Improve solution
if (!archiveTypes) return {}
if (archiveTypes.ready) {
// let ret = {}
// ret[archiveTypes.constructor.name] = archiveTypes
// return ret
throw new Error('archiveTypes need to be provided as children')
}
return archiveTypes
}
Library.prototype.getArchiveConstructor = function (type) {
if (!this.archiveTypes[type]) throw new Error(`Archive type ${type} not registered.`)
return this.archiveTypes[type].constructor
}
Library.prototype.createArchive = async function (type, opts, status) {
const defaultStatus = {
loaded: true,
authorized: true
}
status = Object.assign({}, defaultStatus, status)
return this.addArchive(type, null, opts, status)
}
Library.prototype.addRemoteArchive = async function (type, key, opts, status) {
const defaultStatus = {
share: true
}
status = Object.assign({}, defaultStatus, status)
return this.addArchive(type, key, opts, status)
}
Library.prototype.addArchive = async function (type, key, opts, status) {
const defaultStatus = {
primary: true,
parent: null,
authorized: false,
loaded: false,
share: false
}
status = Object.assign({}, defaultStatus, status)
const instance = this.makeInstance(type, key, opts)
const archive = Archive(this, type, instance, status)
await this.pushArchive(archive)
this.emit('archive', archive)
return archive
}
Library.prototype.pushArchive = async function (archive) {
this.archives[archive.key] = archive
}
Library.prototype.getArchive = function (key) {
return this.archives[key]
}
Library.prototype.getArchives = function () {
return this.archives
}
Library.prototype.getArchiveInstance = function (key) {
const archive = this.getArchive(key)
return archive.getInstance()
}
Library.prototype.getPrimaryArchives = function () {
return Object.values(this.archives).filter(a => a.getState().primary)
}
Library.prototype.makeInstance = function (type, key, opts) {
opts = opts || {}
const constructor = this.getArchiveConstructor(type)
if (!key) {
const keyPair = crypto.keyPair()
key = keyPair.publicKey.toString('hex')
opts.secretKey = keyPair.secretKey
}
const storage = opts.storage || this.storage(folderName(type, key))
const instance = constructor(storage, key, opts)
return instance
}