-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlog.js
66 lines (59 loc) · 1.49 KB
/
log.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
var u = require('./util')
/*
this uses localStorage, so it doesn't need async,
but i used async api anyway,
so it will be easy to switch to indexeddb.
*/
module.exports = function (prefix, storage) {
//pass in non-local storage, to make testing easy.
storage = storage || localStorage
var log
function _append (data, cb) {
var log = u.parse(storage[prefix]) || []
log.unshift(data)
storage[prefix] = JSON.stringify(log)
cb(null, data)
}
function filtered (log) {
var revert = null
var output = []
for(var i = 0; i < log.length; i++) {
var item = log[i]
if(revert && revert <= item.ts) //this op was reverted.
;
else if(item.revert)
revert = item.revert
else
output.push(item)
}
return output
}
function getLog() {
return u.parse(storage[prefix]) || []
}
return log = {
head: function (cb) {
cb(null, filtered(getLog())[0])
},
filtered: function (cb) {
cb(null, filtered(getLog()))
},
unfiltered: function (cb) {
cb(null, getLog())
},
append: function (data, cb) {
_append({value: data, ts: Date.now()}, cb)
},
revert: function (ts, cb) {
if(!ts) return cb(new Error('log.revert: must provide ts to revert to'))
_append({revert: ts, ts: Date.now()}, function (err) {
if(err) cb(err)
else cb(null, filtered(getLog())[0])
})
},
destroy: function (cb) {
delete storage[prefix]
cb()
}
}
}