Files: d245481b81b4075ba2a29823d0441ec941545a32 / sbot / search.js
2179 bytesRaw
1 | var pull = require('pull-stream') |
2 | var pullCat = require('pull-cat') |
3 | |
4 | module.exports = function (ssb, config) { |
5 | return { |
6 | linear: function ({lt, gt, reverse, limit, query, old, live}) { |
7 | // handle markers passed in to lt / gt |
8 | var opts = {reverse, old, live} |
9 | if (lt && typeof lt.timestamp === 'number') lt = lt.timestamp |
10 | if (gt && typeof gt.timestamp === 'number') gt = gt.timestamp |
11 | if (typeof lt === 'number') opts.lt = lt |
12 | if (typeof gt === 'number') opts.gt = gt |
13 | |
14 | var matchesQuery = searchFilter(query) |
15 | var marker = {marker: true, timestamp: null} |
16 | |
17 | var stream = pull( |
18 | ssb.createLogStream(opts), |
19 | pull.map(msg => { |
20 | if (msg.value && typeof msg.value.content === 'string') { |
21 | var unboxed = ssb.private.unbox(msg) |
22 | if (unboxed) { |
23 | return unboxed |
24 | } |
25 | } |
26 | return msg |
27 | }), |
28 | pull.through(msg => { |
29 | marker.timestamp = msg.timestamp |
30 | }), |
31 | pull.filter(matchesQuery) |
32 | ) |
33 | |
34 | // TRUNCATE |
35 | if (typeof limit === 'number') { |
36 | var count = 0 |
37 | return pullCat([ |
38 | pull( |
39 | stream, |
40 | pull.take(limit), |
41 | pull.through(() => { |
42 | count += 1 |
43 | }) |
44 | ), |
45 | |
46 | // send truncated marker for resuming search |
47 | pull( |
48 | pull.values([marker]), |
49 | pull.filter(() => count === limit) |
50 | ) |
51 | ]) |
52 | } else { |
53 | return stream |
54 | } |
55 | } |
56 | } |
57 | } |
58 | |
59 | function searchFilter (terms) { |
60 | return function (msg) { |
61 | if (msg.sync) return true |
62 | var c = msg && msg.value && msg.value.content |
63 | return c && ( |
64 | msg.key === terms[0] || andSearch(terms.map(function (term) { |
65 | return new RegExp('\\b' + term + '\\b', 'i') |
66 | }), [c.text, c.name, c.title]) |
67 | ) |
68 | } |
69 | } |
70 | |
71 | function andSearch (terms, inputs) { |
72 | for (var i = 0; i < terms.length; i++) { |
73 | var match = false |
74 | for (var j = 0; j < inputs.length; j++) { |
75 | if (terms[i].test(inputs[j])) match = true |
76 | } |
77 | // if a term was not matched by anything, filter this one |
78 | if (!match) return false |
79 | } |
80 | return true |
81 | } |
82 |
Built with git-ssb-web