Files: 2bd24f99a6e985cb6f8d40b8f26bf2692eaab9f2 / index.js
1540 bytesRaw
1 | var FlumeQueryLinks = require('./lib/flumeview-links-raw') |
2 | var ref = require('ssb-ref') |
3 | var deepEqual = require('deep-equal') |
4 | var extend = require('xtend') |
5 | var matchChannel = /^#[^\s#]+$/ |
6 | |
7 | var indexes = [ |
8 | { key: 'DTS', value: [['dest'], ['timestamp']] }, |
9 | { key: 'DTA', value: [['dest'], ['value', 'timestamp']] }, // asserted timestamp |
10 | { key: 'TDT', value: [['value', 'content', 'type'], ['dest'], ['value', 'timestamp']] } |
11 | ] |
12 | |
13 | var indexVersion = 2 |
14 | |
15 | exports.name = 'backlinks' |
16 | exports.version = require('./package.json').version |
17 | exports.manifest = { |
18 | read: 'source' |
19 | } |
20 | |
21 | exports.init = function (ssb, config) { |
22 | return ssb._flumeUse( |
23 | 'backlinks', |
24 | FlumeQueryLinks(indexes, extractLinks, indexVersion) |
25 | ) |
26 | } |
27 | |
28 | function extractLinks (msg, emit) { |
29 | var links = new Set() |
30 | walk(msg.value.content, function (path, value) { |
31 | // HACK: handle legacy channel mentions |
32 | if (deepEqual(path, ['channel']) && typeof value === 'string' && value.length < 30) { |
33 | value = `#${value.replace(/\s/g, '')}` |
34 | } |
35 | |
36 | // TODO: should add channel matching to ref.type |
37 | if (ref.type(value) || isChannel(value)) { |
38 | links.add(value) |
39 | } |
40 | }) |
41 | links.forEach(link => { |
42 | emit(extend(msg, { |
43 | dest: link |
44 | })) |
45 | }) |
46 | } |
47 | |
48 | function isChannel (value) { |
49 | return typeof value === 'string' && value.length < 30 && matchChannel.test(value) |
50 | } |
51 | |
52 | function walk (obj, fn, prefix) { |
53 | if (obj && typeof obj === 'object') { |
54 | for (var k in obj) { |
55 | walk(obj[k], fn, (prefix || []).concat(k)) |
56 | } |
57 | } else { |
58 | fn(prefix, obj) |
59 | } |
60 | } |
61 |
Built with git-ssb-web