Files: eac1a89db33ba24513a85795a552c0f28da8c4bf / validator.js
2401 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) { |
26 | |
27 | var write = util.BatchQueue(ssb) |
28 | |
29 | function getLatest (id, cb) { |
30 | ssb.getLatest(id, function (err, data) { |
31 | if(err) return cb(null, {key: null, value: null, type: 'put', public: null, ready: true}) |
32 | cb(null, { |
33 | key: data.key, value: data.value, type: 'put', |
34 | public: data.value && data.value.author, ready: true |
35 | }) |
36 | }) |
37 | } |
38 | |
39 | var latest = {} |
40 | |
41 | function setLatest(id) { |
42 | if(latest[id].ready) |
43 | throw new Error('setLatest should only be called once') |
44 | ssb.getLatest(id, function (err, data) { |
45 | latest[id].ready = true |
46 | if(data) { |
47 | latest[id].key = data.key |
48 | latest[id].value = data.value |
49 | } |
50 | validate(id) |
51 | }) |
52 | } |
53 | |
54 | function validate(id) { |
55 | var feed = latest[id] |
56 | if(!feed.queue.length) return |
57 | if(!feed.ready) return |
58 | |
59 | while(feed.queue.length) { |
60 | var op = feed.queue.shift() |
61 | |
62 | |
63 | if('function' == typeof op.create) { |
64 | op.value = op.create(feed.key, feed.value) |
65 | op.key = '%'+hash(encode(op.value)) |
66 | } |
67 | |
68 | var err = |
69 | util.isInvalidShape(op.value) || |
70 | util.isInvalid(id, op.value, feed) |
71 | |
72 | if(err) |
73 | op.cb(err) |
74 | else { |
75 | feed.key = op.key |
76 | feed.value = op.value |
77 | feed.ts = Date.now() |
78 | write(op) |
79 | } |
80 | } |
81 | } |
82 | |
83 | function queue (id, job) { |
84 | if(!latest[id]) { |
85 | latest[id] = { |
86 | key:null, value: null, |
87 | ready: false, queue: [], |
88 | ts: Date.now() |
89 | } |
90 | latest[id].queue.push(job) |
91 | setLatest(id) |
92 | } |
93 | else |
94 | latest[id].queue.push(job) |
95 | |
96 | validate(id) |
97 | } |
98 | |
99 | function add (msg, cb) { |
100 | var err = util.isInvalidShape(msg) |
101 | if(err) return cb(err) |
102 | |
103 | queue(msg.author, { |
104 | key: '%'+hash(encode(msg)), |
105 | value: msg, cb: cb, |
106 | create: null |
107 | }) |
108 | } |
109 | |
110 | add.queue = function (id, create, cb) { |
111 | queue(id, { |
112 | key: null, value: null, |
113 | create: create, cb: cb |
114 | }) |
115 | |
116 | } |
117 | |
118 | return add |
119 | } |
120 |
Built with git-ssb-web