Files: 61da396c13a5c46a54a687885b89f5108fce69eb / backlinks-plugin.js
1877 bytesRaw
1 | // this shouldn't really be in patchcore, should be its own module |
2 | |
3 | var FlumeQueryLinks = require('./flumeview-links-raw') |
4 | var ref = require('ssb-ref') |
5 | var deepEqual = require('deep-equal') |
6 | var extend = require('xtend') |
7 | var matchChannel = /^#[^\s#]+$/ |
8 | |
9 | function isString (s) { |
10 | return typeof s === 'string' |
11 | } |
12 | |
13 | var indexes = [ |
14 | { key: 'DTS', value: [['dest'], ['timestamp']] }, |
15 | { key: 'DTY', value: [['dest'], ['value', 'content', 'type'], ['timestamp']] } |
16 | ] |
17 | |
18 | var indexVersion = 0 |
19 | |
20 | exports.name = 'backlinks' |
21 | exports.version = require('./package.json').version |
22 | exports.manifest = { |
23 | read: 'source' |
24 | } |
25 | |
26 | exports.init = function (ssb, config) { |
27 | var s = ssb._flumeUse('backlinks', FlumeQueryLinks(indexes, extractLinks, indexVersion)) |
28 | var read = s.read |
29 | s.read = function (opts) { |
30 | if (!opts) opts = {} |
31 | // accept json, makes it easier to query from cli. |
32 | if (isString(opts)) { |
33 | opts = {query: JSON.parse(opts)} |
34 | } else if (isString(opts.query)) { |
35 | opts.query = JSON.parse(opts.query) |
36 | } |
37 | return read(opts) |
38 | } |
39 | return s |
40 | } |
41 | |
42 | function extractLinks (msg, emit) { |
43 | var links = new Set() |
44 | walk(msg.value.content, function (path, value) { |
45 | // HACK: handle legacy channel mentions |
46 | if (deepEqual(path, ['channel']) && typeof value === 'string' && value.length < 30) { |
47 | value = `#${value.replace(/\s/g, '')}` |
48 | } |
49 | |
50 | // TODO: should add channel matching to ref.type |
51 | if (ref.type(value) || isChannel(value)) { |
52 | links.add(value) |
53 | } |
54 | }) |
55 | links.forEach(link => { |
56 | emit(extend(msg, { |
57 | dest: link |
58 | })) |
59 | }) |
60 | } |
61 | |
62 | function isChannel (value) { |
63 | return typeof value === 'string' && value.length < 30 && matchChannel.test(value) |
64 | } |
65 | |
66 | function walk (obj, fn, prefix) { |
67 | if (obj && typeof obj === 'object') { |
68 | for (var k in obj) { |
69 | walk(obj[k], fn, (prefix || []).concat(k)) |
70 | } |
71 | } else { |
72 | fn(prefix, obj) |
73 | } |
74 | } |
75 |
Built with git-ssb-web