Files: f1cc08ac986f18880000b780dae6fb2043e76948 / modules / names.js
3544 bytesRaw
1 | var pull = require('pull-stream') |
2 | var many = require('pull-many') |
3 | var mfr = require('map-filter-reduce') |
4 | |
5 | var links2 = require('./scuttlebot').links2 |
6 | var sbotQuery = require('./scuttlebot').query |
7 | |
8 | /*function all(stream, cb) { |
9 | pull(stream, pull.collect(cb)) |
10 | }*/ |
11 | |
12 | exports.gives = { |
13 | signifier: true, |
14 | signified: true, |
15 | } |
16 | |
17 | var filter = { |
18 | $filter: { |
19 | rel: ["mentions", {$prefix: "@"}] |
20 | } |
21 | } |
22 | var map = { |
23 | $map: { |
24 | name: ['rel', 1], |
25 | id: 'dest', |
26 | ts: 'ts', |
27 | } |
28 | } |
29 | |
30 | var reduce = { |
31 | $reduce: { |
32 | name: 'name', |
33 | id: 'id', |
34 | rank: {$count: true}, |
35 | ts: {$max: 'ts'} |
36 | } |
37 | } |
38 | |
39 | var filter2 = { |
40 | $filter: { |
41 | value: { |
42 | content: { |
43 | type: "about", |
44 | name: {"$prefix": ""}, |
45 | about: {"$prefix": ""} |
46 | } |
47 | } |
48 | } |
49 | } |
50 | |
51 | var map2 = { |
52 | $map: { |
53 | name: ["value", "content", "name"], |
54 | id: ['value', 'content', 'about'], |
55 | ts: "timestamp" |
56 | } |
57 | } |
58 | |
59 | var names = NAMES = [] |
60 | function update(name) { |
61 | var n = names.find(function (e) { |
62 | return e.id == name.id && e.name == e.name |
63 | }) |
64 | if(!n) { |
65 | name.rank = 1 |
66 | names.push(name) |
67 | } |
68 | else |
69 | n.rank = n.rank += (name.rank || 1) |
70 | } |
71 | |
72 | var ready = false, waiting = [] |
73 | |
74 | var merge = { |
75 | $reduce: { |
76 | name: 'name', |
77 | id: 'id', |
78 | rank: {$sum: 'rank'}, |
79 | ts: {$max: 'ts'} |
80 | } |
81 | } |
82 | |
83 | function add_sigil(stream) { |
84 | return pull(stream, pull.map(function (e) { |
85 | if (e && e.id && e.name && e.id[0] !== e.name[0]) |
86 | e.name = e.id[0] + e.name |
87 | return e |
88 | }) |
89 | ) |
90 | } |
91 | |
92 | var queryNamedGitRepos = [ |
93 | {$filter: { |
94 | value: { |
95 | content: { |
96 | type: "git-repo", |
97 | name: {"$prefix": ""} |
98 | } |
99 | } |
100 | }}, |
101 | {$map: { |
102 | name: ["value", "content", "name"], |
103 | id: ['key'], |
104 | ts: "timestamp" |
105 | }}, |
106 | reduce |
107 | ] |
108 | exports.create = function (api) { |
109 | |
110 | var exports = {} |
111 | //exports.connection_status = function (err) { |
112 | //if(!err) { |
113 | pull( |
114 | many([ |
115 | links2({query: [filter, map, reduce]}), |
116 | add_sigil(sbotQuery({query: [filter2, map2, reduce]})), |
117 | add_sigil(sbotQuery({query: queryNamedGitRepos})) |
118 | ]), |
119 | //reducing also ensures order by the lookup properties |
120 | //in this case: [name, id] |
121 | mfr.reduce(merge), |
122 | pull.collect(function (err, ary) { |
123 | if(!err) { |
124 | NAMES = names = ary |
125 | ready = true |
126 | while(waiting.length) waiting.shift()() |
127 | } |
128 | }) |
129 | ) |
130 | |
131 | pull(many([ |
132 | links2({query: [filter, map], old: false}), |
133 | add_sigil(sbotQuery({query: [filter2, map2], old: false})), |
134 | add_sigil(sbotQuery({query: queryNamedGitRepos, old: false})) |
135 | ]), |
136 | pull.drain(update)) |
137 | //} |
138 | //} |
139 | |
140 | function async(fn) { |
141 | return function (value, cb) { |
142 | function go () { cb(null, fn(value)) } |
143 | if(ready) go() |
144 | else waiting.push(go) |
145 | } |
146 | } |
147 | |
148 | function rank(ary) { |
149 | //sort by most used, or most recently used |
150 | return ary.sort(function (a, b) { return b.rank - a.rank || b.ts - a.ts }) |
151 | } |
152 | |
153 | //we are just iterating over the entire array. |
154 | //if this becomes a problem, maintain two arrays |
155 | //one of each sort order, but do not duplicate the objects. |
156 | //that should mean the space required is just 2x object references, |
157 | //not 2x objects, and we can use binary search to find matches. |
158 | |
159 | exports.signifier = async(function (id) { |
160 | return rank(names.filter(function (e) { return e.id == id})) |
161 | }) |
162 | |
163 | exports.signified = async(function (name) { |
164 | var rx = new RegExp('^'+name) |
165 | return rank(names.filter(function (e) { return rx.test(e.name) })) |
166 | }) |
167 | |
168 | return exports |
169 | } |
170 |
Built with git-ssb-web