Files: a1a62ab007bd365fedeb8fcaa561f0bc0971a43d / validator.js
2497 bytesRaw
1 | ; |
2 | |
3 | var hash = require('ssb-keys').hash |
4 | |
5 | // make a validation stream? |
6 | // read the latest record in the database |
7 | // check it against the incoming data, |
8 | // and then read through |
9 | |
10 | function isString (s) { |
11 | return 'string' === typeof s |
12 | } |
13 | |
14 | function isInteger (n) { |
15 | return ~~n === n |
16 | } |
17 | |
18 | function isObject (o) { |
19 | return o && 'object' === typeof o |
20 | } |
21 | |
22 | var util = require('./util') |
23 | var encode = util.encode |
24 | |
25 | module.exports = function (ssb, opts) { |
26 | opts = opts || {} |
27 | var write = util.BatchQueue(ssb) |
28 | var sign_cap = util.toBuffer(opts.caps && opts.caps.sign) |
29 | |
30 | function getLatest (id, cb) { |
31 | ssb.getLatest(id, function (err, data) { |
32 | if(err) return cb(null, {key: null, value: null, type: 'put', public: null, ready: true}) |
33 | cb(null, { |
34 | key: data.key, value: data.value, type: 'put', |
35 | public: data.value && data.value.author, ready: true |
36 | }) |
37 | }) |
38 | } |
39 | |
40 | var latest = {} |
41 | |
42 | function setLatest(id) { |
43 | if(latest[id].ready) |
44 | throw new Error('setLatest should only be called once') |
45 | ssb.getLatest(id, function (err, data) { |
46 | latest[id].ready = true |
47 | if(data) { |
48 | latest[id].key = data.key |
49 | latest[id].value = data.value |
50 | } |
51 | validate(id) |
52 | }) |
53 | } |
54 | |
55 | function validate(id) { |
56 | var feed = latest[id] |
57 | if(!feed.queue.length) return |
58 | if(!feed.ready) return |
59 | |
60 | while(feed.queue.length) { |
61 | var op = feed.queue.shift() |
62 | |
63 | |
64 | if('function' == typeof op.create) { |
65 | op.value = op.create(feed.key, feed.value) |
66 | op.key = '%'+hash(encode(op.value)) |
67 | } |
68 | |
69 | var err = |
70 | util.isInvalidShape(op.value) || |
71 | util.isInvalid(id, op.value, feed, sign_cap) |
72 | |
73 | if(err) |
74 | op.cb(err) |
75 | else { |
76 | feed.key = op.key |
77 | feed.value = op.value |
78 | feed.ts = Date.now() |
79 | write(op) |
80 | } |
81 | } |
82 | } |
83 | |
84 | function queue (id, job) { |
85 | if(!latest[id]) { |
86 | latest[id] = { |
87 | key:null, value: null, |
88 | ready: false, queue: [], |
89 | ts: Date.now() |
90 | } |
91 | latest[id].queue.push(job) |
92 | setLatest(id) |
93 | } |
94 | else |
95 | latest[id].queue.push(job) |
96 | |
97 | validate(id) |
98 | } |
99 | |
100 | function add (msg, cb) { |
101 | var err = util.isInvalidShape(msg) |
102 | if(err) return cb(err) |
103 | |
104 | queue(msg.author, { |
105 | key: '%'+hash(encode(msg)), |
106 | value: msg, cb: cb, |
107 | create: null |
108 | }) |
109 | } |
110 | |
111 | add.queue = function (id, create, cb) { |
112 | queue(id, { |
113 | key: null, value: null, |
114 | create: create, cb: cb |
115 | }) |
116 | |
117 | } |
118 | |
119 | return add |
120 | } |
121 | |
122 |
Built with git-ssb-web