git ssb

0+

cel / pull-kvdiff



Commit 6b8f19fb3b608e0c8d3ebdb9053a18257e6fe9d3

Initial commit

Charles Lehner committed on 3/31/2016, 4:29:08 AM

Files changed

README.mdadded
index.jsadded
package.jsonadded
test.jsadded
README.mdView
@@ -1,0 +1,48 @@
1 +# pull-kvdiff
2 +
3 +diff key-value streams
4 +
5 +```js
6 +var pull = require('pull-stream')
7 +var kvdiff = require('pull-kvdiff')
8 +
9 +pull(
10 + kvdiff([
11 + pull.values([
12 + {key: 'a', value: 1},
13 + {key: 'b', value: 2},
14 + {key: 'c', value: 3},
15 + ]),
16 + pull.values([
17 + {key: 'a', value: 1},
18 + {key: 'b', value: 3},
19 + {key: 'd', value: 3},
20 + ])
21 + ], 'key'),
22 + pull.log()
23 +)
24 +```
25 +output:
26 +```json
27 +{ key: 'b',
28 + values: [ { key: 'b', value: 2 }, { key: 'b', value: 3 } ],
29 + diff: { value: [ 2, 3 ] } }
30 +{ key: 'c',
31 + values: [ { key: 'c', value: 3 }, ],
32 + diff: { key: [ 'c' ], value: [ 3 ] } }
33 +{ key: 'd',
34 + values: [ , { key: 'd', value: 3 } ],
35 + diff: { key: [ , 'd' ], value: [ , 3 ] } }
36 +```
37 +
38 +#### `kvdiff(sources, keyProp) → source`
39 +
40 +## License
41 +
42 +Copyright (c) 2016 Charles Lehner
43 +
44 +Usage of the works is permitted provided that this instrument is
45 +retained with the works, so that any entity that uses the works is
46 +notified of this instrument.
47 +
48 +DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
index.jsView
@@ -1,0 +1,81 @@
1 +var multicb = require('multicb')
2 +
3 +function diff(objs) {
4 + if (objs.length < 2) return {}
5 + var results
6 + var keys = {}
7 + for (var i = 0; i < objs.length; i++)
8 + for (var k in objs[i])
9 + keys[k] = true
10 +
11 + var first = objs[0] || {}
12 + for (var i = 1; i < objs.length; i++) {
13 + var curr = objs[i] || {}
14 + for (var k in keys) {
15 + if (curr[k] !== first[k]) {
16 + changed = true
17 + var keyResults = (results || (results = {}))[k] || (results[k] = [])
18 + if (k in curr)
19 + keyResults[i] = curr[k]
20 + if (k in first)
21 + keyResults[0] = first[k]
22 + }
23 + }
24 + }
25 + return results
26 +}
27 +
28 +module.exports = function (sources, keyProp) {
29 + var n = sources.length
30 + var results = {/* key: {values: [argI: value], waiting: n} */}
31 + var got = {/* key: bool */}
32 + var waiting = n
33 + return function read(end, cb) {
34 + if (end) {
35 + if (waiting == 0)
36 + return cb(end)
37 + var done = multicb({pluck: 1})
38 + for (var j = 0; j < sources.length; j++)
39 + if (sources[j])
40 + sources[j](end, done())
41 + return done(cb)
42 + }
43 + next(cb, -1)
44 + }
45 + function next(cb, i) {
46 + do {
47 + i++
48 + i %= n
49 + } while (!sources[i])
50 + sources[i](null, function (end, item) {
51 + if (end) {
52 + sources[i] = null
53 + if (0 == --waiting) doneReading(cb)
54 + else next(cb, i)
55 + return
56 + }
57 + var key = keyProp ? item[keyProp] : String(item)
58 + var keyResults = results[key] || (results[key] = {
59 + values: new Array(n),
60 + waiting: n
61 + })
62 + keyResults.values[i] = item
63 + if (--keyResults.waiting > 0) return next(cb, i)
64 + delete results[key]
65 + var result = diff(keyResults.values, keyProp)
66 + if (!result) return next(cb, i)
67 + cb(null, {key: key, values: keyResults.values, diff: result})
68 + })
69 + }
70 + function doneReading(cb) {
71 + next = doneReading
72 + for (var key in results) {
73 + var values = results[key].values
74 + var result = diff(values, keyProp)
75 + delete results[key]
76 + if (result)
77 + return cb(null, {key: key, values: values, diff: result})
78 + }
79 + cb(true)
80 + }
81 +}
package.jsonView
@@ -1,0 +1,20 @@
1 +{
2 + "name": "pull-kvdiff",
3 + "version": "0.0.0",
4 + "description": "diff key-value streams",
5 + "homepage": "http://git-ssb.celehner.com/%25TZOXQlZsigfkBWfepmMVvm4jsvgyaXcXXD3GA8Wtmi0%3D.sha256",
6 + "bugs": "http://git-ssb.celehner.com/%25TZOXQlZsigfkBWfepmMVvm4jsvgyaXcXXD3GA8Wtmi0%3D.sha256/issues",
7 + "main": "index.js",
8 + "scripts": {
9 + "test": "node test"
10 + },
11 + "dependencies": {
12 + "multicb": "^1.2.1"
13 + },
14 + "devDependencies": {
15 + "tape": "^4.5.1",
16 + "pull-stream": "^3.2.0"
17 + },
18 + "author": "Charles Lehner (http://celehner.com/)",
19 + "license": "Fair"
20 +}
test.jsView
@@ -1,0 +1,79 @@
1 +var test = require('tape')
2 +var pull = require('pull-stream')
3 +var kvdiff = require('.')
4 +
5 +test('kvdiff', function (t) {
6 + pull(
7 + kvdiff([
8 + pull.values([
9 + {key: 'a', value: 1},
10 + {key: 'b', value: 2},
11 + {key: 'c', value: 3},
12 + ]),
13 + pull.values([
14 + {key: 'a', value: 1},
15 + {key: 'b', value: 2},
16 + {key: 'c', value: 4},
17 + ]),
18 + pull.values([
19 + {key: 'a', value: 1},
20 + {key: 'b', value: 2},
21 + {key: 'd', value: 3},
22 + ])
23 + ],
24 + 'key'
25 + ),
26 + pull.collect(function (err, diff) {
27 + t.error(err, 'collect')
28 + t.deepEquals(diff, [
29 + {
30 + diff: {
31 + key: [ 'c', , ],
32 + value: [ 3, 4, ]
33 + },
34 + key: 'c',
35 + values: [ { key: 'c', value: 3 }, { key: 'c', value: 4 }, ] },
36 + {
37 + diff: {
38 + key: [ , , 'd' ],
39 + value: [ , , 3 ]
40 + },
41 + key: 'd',
42 + values: [ , , { key: 'd', value: 3 } ] }
43 +
44 + ], 'values')
45 + t.end()
46 + }))
47 +})
48 +
49 +test('kvdiff 2', function (t) {
50 + pull(
51 + kvdiff([
52 + pull.values([
53 + {key: 'a', value: 1},
54 + {key: 'b', value: 2},
55 + {key: 'c', value: 3},
56 + ]),
57 + pull.values([
58 + {key: 'a', value: 1},
59 + {key: 'b', value: 3},
60 + {key: 'd', value: 3},
61 + ])
62 + ], 'key'),
63 + pull.collect(function (err, diff) {
64 + t.error(err, 'collect')
65 + t.deepEquals(diff, [
66 + { key: 'b',
67 + values: [ { key: 'b', value: 2 }, { key: 'b', value: 3 } ],
68 + diff: { value: [ 2, 3 ] } },
69 + { key: 'c',
70 + values: [ { key: 'c', value: 3 }, ],
71 + diff: { key: [ 'c', ], value: [ 3, ] } },
72 + { key: 'd',
73 + values: [ , { key: 'd', value: 3 } ],
74 + diff: { key: [ , 'd' ], value: [ , 3 ] } }
75 + ])
76 + t.end()
77 + })
78 + )
79 +})

Built with git-ssb-web