-
Notifications
You must be signed in to change notification settings - Fork 4
/
validator.js
121 lines (97 loc) · 2.44 KB
/
validator.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
'use strict';
var hash = require('ssb-keys').hash
// make a validation stream?
// read the latest record in the database
// check it against the incoming data,
// and then read through
function isString (s) {
return 'string' === typeof s
}
function isInteger (n) {
return ~~n === n
}
function isObject (o) {
return o && 'object' === typeof o
}
var util = require('./util')
var encode = util.encode
module.exports = function (ssb, opts) {
opts = opts || {}
var write = util.BatchQueue(ssb)
var sign_cap = util.toBuffer(opts.caps && opts.caps.sign)
function getLatest (id, cb) {
ssb.getLatest(id, function (err, data) {
if(err) return cb(null, {key: null, value: null, type: 'put', public: null, ready: true})
cb(null, {
key: data.key, value: data.value, type: 'put',
public: data.value && data.value.author, ready: true
})
})
}
var latest = {}
function setLatest(id) {
if(latest[id].ready)
throw new Error('setLatest should only be called once')
ssb.getLatest(id, function (err, data) {
latest[id].ready = true
if(data) {
latest[id].key = data.key
latest[id].value = data.value
}
validate(id)
})
}
function validate(id) {
var feed = latest[id]
if(!feed.queue.length) return
if(!feed.ready) return
while(feed.queue.length) {
var op = feed.queue.shift()
if('function' == typeof op.create) {
op.value = op.create(feed.key, feed.value)
op.key = '%'+hash(encode(op.value))
}
var err =
util.isInvalidShape(op.value) ||
util.isInvalid(id, op.value, feed, sign_cap)
if(err)
op.cb(err)
else {
feed.key = op.key
feed.value = op.value
feed.ts = Date.now()
write(op)
}
}
}
function queue (id, job) {
if(!latest[id]) {
latest[id] = {
key:null, value: null,
ready: false, queue: [],
ts: Date.now()
}
latest[id].queue.push(job)
setLatest(id)
}
else
latest[id].queue.push(job)
validate(id)
}
function add (msg, cb) {
var err = util.isInvalidShape(msg)
if(err) return cb(err)
queue(msg.author, {
key: '%'+hash(encode(msg)),
value: msg, cb: cb,
create: null
})
}
add.queue = function (id, create, cb) {
queue(id, {
key: null, value: null,
create: create, cb: cb
})
}
return add
}