Commit e3887a34e8e4f6b4cbc0d1d1b0e549b50157b48c
initial
mix irving committed on 2/8/2018, 10:32:52 AMFiles changed
.gitignore | added |
README.md | added |
async/fetch.js | added |
index.js | added |
isBlog.js | added |
obs/get.js | added |
package-lock.json | added |
package.json | added |
schema/blog.js | added |
sync/isBlog.js | added |
tests/sync/isBlog.js | added |
README.md | ||
---|---|---|
@@ -1,0 +1,90 @@ | ||
1 … | +# Scuttle-blog | |
2 … | + | |
3 … | +A helper module which covers all your ssb `blog` related needs from blog data. | |
4 … | + | |
5 … | +The parts of this modules are : | |
6 … | +- queries/ getters | |
7 … | +- schemas/ validaters | |
8 … | + | |
9 … | +## Usage | |
10 … | + | |
11 … | +```js | |
12 … | +const Blog = require('scuttle-blog') | |
13 … | +const blog = Blog(server) // server is sometimes called sbot | |
14 … | + | |
15 … | +blog.sync.isBlog(msg) | |
16 … | +// => true | |
17 … | + | |
18 … | +blog.async.fetch(msg.key, (err, success) => { | |
19 … | + if (err) | |
20 … | + return console.error('there was an error getting your blog', err) | |
21 … | + | |
22 … | + if (success) | |
23 … | + console.log('your blog is ready to read!') | |
24 … | + else | |
25 … | + console.log('could not fetch your blog T_T') | |
26 … | +}) | |
27 … | +``` | |
28 … | + | |
29 … | +## Constructor API | |
30 … | + | |
31 … | +### `Blog(server)` | |
32 … | + | |
33 … | +`server` is a connection to your scuttlebutt server provided by `ssb-client` (sometimes called sbot in other docs). | |
34 … | + | |
35 … | + | |
36 … | +## Instance API | |
37 … | + | |
38 … | +### `blog.obs.get(keyOrMsg) => Observeable` | |
39 … | + | |
40 … | +`keyOrMsg` `(String|Object)` - either a msg key or a whole message. | |
41 … | + | |
42 … | +The observeable returned is [Mutant Struct](https://github.com/mmckegg/mutant#struct) which emits data of the form: | |
43 … | + | |
44 … | +```js | |
45 … | +{ | |
46 … | + title, | |
47 … | + summary, | |
48 … | + thumbnail, | |
49 … | + content, | |
50 … | + channel | |
51 … | +} | |
52 … | +``` | |
53 … | + | |
54 … | +The content and thumbnail will take some time to load if you haven't already got the whole blog. | |
55 … | +This method called `blog.async.fetch` under the hood. | |
56 … | + | |
57 … | + | |
58 … | +### `blog.sync.isBlog(msg) => Boolean` | |
59 … | + | |
60 … | +`msg` - is a message from a server stream (or the message content). | |
61 … | + | |
62 … | + | |
63 … | +### `blog.async.fetch(keyOrMsg, cb)` | |
64 … | + | |
65 … | +Blogs store the body of their text as an attachement. In Scuttlebutt, attachments have to be manually requested, hence this method. | |
66 … | + | |
67 … | +`keyOrMsg` `(String|Object)` - either a msg key or a whole message. | |
68 … | + | |
69 … | +`cb` `(function)` - a callback with the standard signature `(err, success)` where `success` is a `Boolean` | |
70 … | + | |
71 … | + | |
72 … | + | |
73 … | +## Schemas | |
74 … | + | |
75 … | +Blog message content: | |
76 … | +```js | |
77 … | +{ | |
78 … | + type: 'blog', | |
79 … | + title: String, | |
80 … | + blog: Blob, | |
81 … | + summary: String, (optional) | |
82 … | + thumbnail: Blob, (optional) | |
83 … | + channel: String, (optional) | |
84 … | +} | |
85 … | +``` | |
86 … | + | |
87 … | +## Development | |
88 … | + | |
89 … | +Run the tests with `npm test` | |
90 … | + |
async/fetch.js | ||
---|---|---|
@@ -1,0 +1,23 @@ | ||
1 … | +const isBlog = require('../../isBlog') | |
2 … | + | |
3 … | +// TODO take blog or blogKey? | |
4 … | + | |
5 … | +module.exports = function (server) { | |
6 … | + return function fetch (blog, cb) { | |
7 … | + if (!isBlog(blog)) return cb(`Not a valid blog ${JSON.stringify(blog, null, 2)}`) | |
8 … | + | |
9 … | + server.blobs.want(getBlob(blog), (err, success) => { | |
10 … | + if (err) throw err | |
11 … | + | |
12 … | + if (success) cb(null, success) | |
13 … | + else cb(null, 'Could not fetch blog content') | |
14 … | + }) | |
15 … | + } | |
16 … | +} | |
17 … | + | |
18 … | +function getBlob (msg) { | |
19 … | + if (msg.value.content && msg.value.content.content) return obj.value.content | |
20 … | + | |
21 … | + return obj | |
22 … | +} | |
23 … | + |
index.js | ||
---|---|---|
@@ -1,0 +1,40 @@ | ||
1 … | +const inject = require('./inject') | |
2 … | + | |
3 … | +const methods = { | |
4 … | + async: { | |
5 … | + create: require('./async/fetch'), | |
6 … | + }, | |
7 … | + obs: { | |
8 … | + get: require('./obs/get'), | |
9 … | + }, | |
10 … | + sync: { | |
11 … | + isBlog: require('./sync/isBook'), | |
12 … | + } | |
13 … | +} | |
14 … | + | |
15 … | +// Note : if you don't like this export pattern, there's no reason we can't add different mappings !! | |
16 … | +// e.g. book.validate.bookComment | |
17 … | + | |
18 … | +module.exports = function Blog (server, opts) { | |
19 … | + if (!server.about) throw new Error('scuttle-book requires you to have the ssb-about plugin installed') | |
20 … | + | |
21 … | + return inject(server, methods) | |
22 … | +} | |
23 … | + | |
24 … | + | |
25 … | +// auto-inject the ssb-server to all methods to reduce repitition | |
26 … | +function inject (server, methods) { | |
27 … | + for (var key in methods) { | |
28 … | + if (typeof methods[key] === 'function') { | |
29 … | + methods[key] = methods[key](server) | |
30 … | + | |
31 … | + } | |
32 … | + else { | |
33 … | + methods[key] = inject(server, methods[key]) | |
34 … | + } | |
35 … | + } | |
36 … | + | |
37 … | + return methods | |
38 … | +} | |
39 … | + | |
40 … | + |
obs/get.js | ||
---|---|---|
@@ -1,0 +1,23 @@ | ||
1 … | +const { Struct, Value } = require('mutant') | |
2 … | +const fetch = require('../../async/fetch') | |
3 … | + | |
4 … | +module.exports = function (server) { | |
5 … | + return function get (blog) { | |
6 … | + fetch(blog, (err, success) | |
7 … | + if (!isBlog(blog)) return cb(`Not a valid blog ${JSON.stringify(blog, null, 2)}`) | |
8 … | + | |
9 … | + server.blobs.want(getBlob(blog), (err, success) => { | |
10 … | + if (err) throw err | |
11 … | + | |
12 … | + if (success) cb(null, success) | |
13 … | + else cb(null, 'Could not fetch blog content') | |
14 … | + }) | |
15 … | + } | |
16 … | +} | |
17 … | + | |
18 … | +function getBlob (msg) { | |
19 … | + if (msg.value.content && msg.value.content.content) return obj.value.content | |
20 … | + | |
21 … | + return obj | |
22 … | +} | |
23 … | + |