-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtarget.js
121 lines (105 loc) · 2.69 KB
/
target.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
117
118
119
120
121
const Resource = require('nanoresource')
const assert = require('nanoassert')
const ready = require('nanoresource-ready')
const raf = require('random-access-file')
/**
* The `Target` class represents a `nanoresource` to a target file
* backed by `random-access-storage` instance.
* @class
* @extends Resource
*/
class Target extends Resource {
/**
* `Target` class constructor.
* @param {String} filename
* @param {?(Object)} opts
* @param {?(Function|Object)} opts.storage
*/
constructor(filename, opts) {
if (!opts || 'object' !== typeof opts) {
opts = {}
}
super(opts)
assert(filename && 'string' === typeof filename,
'Filename must be a string.')
this.filename = filename
this.shouldCloseStorage = false
if ('function' === typeof opts.storage) {
this.storage = opts.storage(this.filename, opts)
} else if (opts.storage && 'object' === typeof opts.storage) {
this.storage = opts.storage
} else {
this.storage = raf(this.filename, opts)
this.shouldCloseStorage = true
}
}
/**
* The active file descriptor for the target resource. Will be `null`
* if not opened.
* @accessor
*/
get fd() {
return this.storage.fd || null
}
/**
* Implements `_open(callback)` for `nanoresource`. Will open a file
* descriptor for at the targets filename and set it on the instance.
* @param {Function} callback
*/
_open(callback) {
// istanbul ignore next
if (this.storage.opened) {
return process.nextTick(callback, null)
}
this.storage.open(callback)
}
/**
* Implements `_close(callback)` for `nanoresource`. Will close the
* underlying file descriptor for at the target.
* @param {Function} callback
*/
_close(callback) {
if (!this.shouldCloseStorage) {
return process.nextTick(callback, null)
}
// istanbul ignore next
if (this.storage.closed) {
return process.nextTick(callback, null)
}
this.storage.close(callback)
}
/**
* Queries for stats from the underlying target storage.
* @param {Function} callback
*/
stat(callback) {
this.ready(() => {
this.storage.stat(callback)
})
}
/**
* Reads data from the underlying target storage at a specified
* offset and size.
* @param {Number} offset
* @param {Number} size
* @param {Function} callback
*/
read(offset, size, callback) {
this.ready(() => {
this.storage.read(offset, size, callback)
})
}
/**
* Waits for target to be ready and calling `callback()` when it is.
* @param {Function} ready
*/
ready(callback) {
ready(this, callback)
}
}
/**
* Module exports.
*/
module.exports = {
Target
}