git ssb

1+

mixmix / scuttle-book



Commit ca816818ec9f749ff0cd2d1fcacc082af7bf6574

documentation

mix irving committed on 1/15/2018, 6:19:06 AM

Files changed

README.mdadded
async/comment.jsadded
async/create.jsadded
async/get.jsadded
async/isBookComment.jsadded
async/isBookUpdate.jsadded
async/update.jsadded
index.jsadded
isBook.jsadded
obs/authors.jsadded
obs/book.jsadded
obs/shelves.jsadded
pull/books.jsadded
pull/comments.jsadded
pull/updates.jsadded
schemas/book.jsadded
schemas/bookComment.jsadded
schemas/bookUpdate.jsadded
README.mdView
@@ -1,0 +1,189 @@
1 +# Scuttle-book
2 +
3 +A helper module which covers all your ssb `book` related needs from fetching book data, creating new book entries, and validating whether a message is of a standard form.
4 +
5 +The parts of this modules are :
6 +- queries/ getters
7 +- publishing helpers
8 +- schemas
9 +
10 +## Usage
11 +
12 +```js
13 +const Book = require('scuttle-book')
14 +const book = Book(client) // an ssb-client (sbot)
15 +
16 +const newBook = {
17 + title: 'The Dispossessed',
18 + author: 'Ursula le Guin'
19 +}
20 +
21 +book.async.create(newBook, (err, bookMsg) => {
22 + if (err) // handle error
23 +
24 + book.isBook(bookMsg)
25 + // => true
26 +})
27 +
28 +```
29 +
30 +## Constructor API
31 +
32 +### `Book(client, opts)`
33 +
34 +`client` an ssb-client instance (sometimes called sbot in other docs).
35 +
36 +`opts` (options) an Object with over-ride options for the scuttle-book instance:
37 +
38 +```js
39 +{
40 + // TODO: REVISE THIS
41 + aboutWinner: function (sbot, attr, attrOpinions, cb) {
42 + // In the event there are differing opinions about a given book attribute,
43 + // this function determines which one 'wins'.
44 + // By default, the fallback for attribute is :
45 + // [ myOpinion, publishersOpinion, friendsOpinion, strangersOpinion ]
46 + // 'friendsOpinion' is the most recent opinion by a friend
47 + }
48 +}
49 +```
50 +
51 +## Instance API
52 +
53 +### `book.async.create(book, cb)`
54 +
55 +`book` - an Object which must at least have `title`, `author`
56 +
57 +### `book.async.update(id, attributes, cb)`
58 +### `book.async.comment(id, text, cb)`
59 +
60 +### `book.sync.isBook(bookMsg)`
61 +
62 +Checks if a given message is a valid book message.
63 +
64 +This method doesn't need an sbot connection so can be accessed directly like:
65 +
66 +```js
67 +const isBook = require('scuttle-book/isBook')
68 +```
69 +
70 +### `book.async.isBook(id, cb)`
71 +
72 +Looks up an id to see if it's a valid book message.
73 +
74 +
75 +### `book.async.isBookUpdate(aboutMsg, cb)`
76 +
77 +Check if it's an `about` message, and directed at a valid book message.
78 +
79 +### `book.isBookComment(postMsg, cb)`
80 +
81 +Check if it's a `post` message, and directed at a valid book message.
82 +
83 +### `book.pull.books()`
84 +
85 +A stream of all books. These are just raw book messages.
86 +
87 +### `book.pull.comments()`
88 +
89 +A stream of comments on books
90 +
91 +### `book.pull.updates()`
92 +
93 +A stream of updates on books. You can filter this yourself to pull out just ratings, or description updates etc).
94 +
95 +### `book.obs.get(id)`
96 +
97 +Returns an observeable which provides live updating data for a particular book.
98 +
99 +```js
100 +var favBook = book.obs.book('%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256"')
101 +
102 +favBook( function listener (newBookState) {
103 + // this function is passed the newBookState whenever there's an update
104 +})
105 +
106 +favBook()
107 +// => get the state right now
108 +// {
109 +// key: '%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256',
110 +// value: { }, // the original message content
111 +// attributes: { }, // contains the single 'winning' state for each attr
112 +// comments: [ ], // the collection of replies in the order they were published
113 +// latestAttributes: { } // the latest state of each attribute from each peer
114 +// }
115 +```
116 +
117 +`attributes`:
118 +```js
119 +{
120 + title: String,
121 + authors: String,
122 + description: String,
123 + image: Blob,
124 + series: String,
125 + seriesNo: Number,
126 + review,
127 + rating,
128 + ratingMax,
129 + ratingType,
130 + shelve, // this one may not make any sense!
131 + genre
132 +}
133 +```
134 +
135 +### `book.async.get(id, cb)`
136 +
137 +Similar to `book.obs.get` but an asynchronous method for e.g. backend rendering.
138 +
139 +### `book.obs.shelves()`
140 +
141 +### `book.obs.authors()`
142 +
143 +
144 +
145 +## Schemas
146 +
147 +A new book:
148 +```js
149 +{
150 + type: 'bookclub',
151 + title: String,
152 + authors: String,
153 + description: String, (optional)
154 + image: Blob, (optional)
155 + series: String, (optional)
156 + seriesNo: Number (optional)
157 +}
158 +```
159 +
160 +Updating a book :
161 +(note arj seperated this into amending vs subjective comments, I think this can be done by providing convenience methods)
162 +```js
163 +{
164 + type: 'about',
165 + about: MessageId, // the original book id
166 + title: String, (optional)
167 + authors: String, (optional)
168 + description: String, (optional)
169 + image: Blob, (optional)
170 + series: String, (optional)
171 + seriesNo: Number, (optional)
172 + review,
173 + rating, // ??? type
174 + ratingMax, // ??? < I think we should just have an opinion
175 + ratingType, // do we need this?
176 + shelve,
177 + genre
178 +}
179 +```
180 +
181 +Commenting on a book:
182 +```js
183 +{
184 + type: 'post',
185 + root: MessageId, // the original book id
186 + text: String,
187 + branch: String | Array
188 +}
189 +```
async/comment.jsView
@@ -1,0 +1,11 @@
1 +module.exports = function (client) {
2 + return function (id, text, cb) {
3 + // lookup the book and existing messages attached (just comments?)
4 + // calculate the correct branch (using ssb-sort ?)
5 +
6 + // create a correctly formed message
7 + // publish it
8 + // callback with the error / newly created message
9 + }
10 +}
11 +
async/create.jsView
async/get.jsView
async/isBookComment.jsView
@@ -1,0 +1,5 @@
1 +const validator = require('is-my-json-valid')
2 +const schema = require('../schemas/bookComment')
3 +
4 +module.exports = validator(schema)
5 +
async/isBookUpdate.jsView
@@ -1,0 +1,5 @@
1 +const validator = require('is-my-json-valid')
2 +const schema = require('../schemas/bookUpdate')
3 +
4 +module.exports = validator(schema)
5 +
async/update.jsView
index.jsView
@@ -1,0 +1,51 @@
1 +const inject = require('./inject')
2 +
3 +const methods = {
4 + async: {
5 + comment: require('./async/comment'),
6 + create: require('./async/create'),
7 + get: require('./async/get'),
8 + isBookComment: require('./async/isBookComment'),
9 + isBookUpdate: require('./async/isBookUpdate'),
10 + update: require('./async/update'),
11 + },
12 + obs: {
13 + authors: require('./obs/authors'),
14 + book: require('./obs/book'),
15 + shelves: require('./obs/shelves'),
16 + },
17 + pull: {
18 + books: require('./pull/books'),
19 + comments: require('./pull/comments'),
20 + updates: require('./pull/updates'),
21 + },
22 + sync: {
23 + isBook: require('./isBook'), // << exception
24 + }
25 +}
26 +
27 +// Note : if you don't like this export pattern, there's no reason we can't add different mappings !!
28 +// e.g. book.validate.bookComment
29 +
30 +module.exports = function Book (client, opts) {
31 + return inject(client, methods)
32 +}
33 +
34 +
35 +// auto-inject the ssb-client instance to all methods to reduce repition
36 +function inject (client, methods) {
37 + for (var key in methods) {
38 + if (typeof methods[key] === 'function') {
39 + methods[key] = methods[key](client)
40 +
41 + // TODO skip isBook
42 + }
43 + else {
44 + methods[key] = inject(client, methods[key])
45 + }
46 + }
47 +
48 + return methods
49 +}
50 +
51 +
isBook.jsView
@@ -1,0 +1,5 @@
1 +const validator = require('is-my-json-valid')
2 +const schema = require('./schemas/book')
3 +
4 +module.exports = validator(schema)
5 +
obs/authors.jsView
obs/book.jsView
obs/shelves.jsView
pull/books.jsView
pull/comments.jsView
pull/updates.jsView
schemas/book.jsView
schemas/bookComment.jsView
schemas/bookUpdate.jsView

Built with git-ssb-web