git ssb

0+

ev / microbay



forked from Dominic / patchbay

Tree: 5ed0ef75a42972670b29aada99be810a8bde7b80

Files: 5ed0ef75a42972670b29aada99be810a8bde7b80 / modules / names.js

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

Built with git-ssb-web