This repository has been archived by the owner on Jan 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 63
/
index.js
115 lines (101 loc) · 3.92 KB
/
index.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
var assert = require('assert')
var fs = require('fs')
var path = require('path')
var hyperdrive = require('hyperdrive')
var resolveDatLink = require('dat-link-resolve')
var debug = require('debug')('dat-node')
var datStore = require('./lib/storage')
var Dat = require('./dat')
module.exports = createDat
/**
* Create a Dat instance, archive storage, and ready the archive.
* @param {string|object} dirOrStorage - Directory or hyperdrive storage object.
* @param {object} [opts] - Dat-node options and any hyperdrive init options.
* @param {String|Buffer} [opts.key] - Hyperdrive key
* @param {Boolean} [opts.createIfMissing = true] - Create storage if it does not exit.
* @param {Boolean} [opts.errorIfExists = false] - Error if storage exists.
* @param {Boolean} [opts.temp = false] - Use random-access-memory for temporary storage
* @param {function(err, dat)} cb - callback that returns `Dat` instance
* @see defaultStorage for storage information
*/
function createDat (dirOrStorage, opts, cb) {
if (!cb) {
cb = opts
opts = {}
}
assert.ok(dirOrStorage, 'dat-node: directory or storage required')
assert.strictEqual(typeof opts, 'object', 'dat-node: opts should be type object')
assert.strictEqual(typeof cb, 'function', 'dat-node: callback required')
var archive
var key = opts.key
var dir = (typeof dirOrStorage === 'string') ? dirOrStorage : null
var storage = datStore(dirOrStorage, opts)
var createIfMissing = !(opts.createIfMissing === false)
var errorIfExists = opts.errorIfExists || false
var hasDat = false
opts = Object.assign({
// TODO: make sure opts.dir is a directory, not file
dir: dir,
latest: true
}, opts)
if (!opts.dir) return create() // TODO: check other storage
checkIfExists()
/**
* Check if archive storage folder exists.
* @private
*/
function checkIfExists () {
// Create after we check for pre-sleep .dat stuff
var createAfterValid = (createIfMissing && !errorIfExists)
var missingError = new Error('Dat storage does not exist.')
missingError.name = 'MissingError'
var existsError = new Error('Dat storage already exists.')
existsError.name = 'ExistsError'
var oldError = new Error('Dat folder contains incompatible metadata. Please remove your metadata (rm -rf .dat).')
oldError.name = 'IncompatibleError'
fs.readdir(path.join(opts.dir, '.dat'), function (err, files) {
// TODO: omg please make this less confusing.
var noDat = !!(err || !files.length)
hasDat = !noDat
var validSleep = (files && files.length && files.indexOf('metadata.key') > -1)
var badDat = !(noDat || validSleep)
if ((noDat || validSleep) && createAfterValid) return create()
else if (badDat) return cb(oldError)
if (err && !createIfMissing) return cb(missingError)
else if (!err && errorIfExists) return cb(existsError)
return create()
})
}
/**
* Create the archive and call `archive.ready()` before callback.
* Set `archive.resumed` if archive has a content feed.
* @private
*/
function create () {
if (dir && !opts.temp && !key && (opts.indexing !== false)) {
// Only set opts.indexing if storage is dat-storage
// TODO: this should be an import option instead, https://github.com/mafintosh/hyperdrive/issues/160
opts.indexing = true
}
if (!key) return createArchive()
resolveDatLink(key, function (err, resolvedKey) {
if (err) return cb(err)
key = resolvedKey
createArchive()
})
function createArchive () {
archive = hyperdrive(storage, key, opts)
archive.on('error', cb)
archive.ready(function () {
debug('archive ready. version:', archive.version)
if (hasDat || (archive.metadata.has(0) && archive.version)) {
archive.resumed = true
} else {
archive.resumed = false
}
archive.removeListener('error', cb)
cb(null, Dat(archive, opts))
})
}
}
}