git ssb

0+

mixmix / scuttle-blog



Commit e3887a34e8e4f6b4cbc0d1d1b0e549b50157b48c

initial

mix irving committed on 2/8/2018, 10:32:52 AM

Files changed

.gitignoreadded
README.mdadded
async/fetch.jsadded
index.jsadded
isBlog.jsadded
obs/get.jsadded
package-lock.jsonadded
package.jsonadded
schema/blog.jsadded
sync/isBlog.jsadded
tests/sync/isBlog.jsadded
.gitignoreView
@@ -1,0 +1,1 @@
1 +node_modules
README.mdView
@@ -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.jsView
@@ -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.jsView
@@ -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 +
isBlog.jsView
@@ -1,0 +1,2 @@
1 +module.exports = require('./sync/isBlog')()
2 +
obs/get.jsView
@@ -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 +