git ssb

1+

mixmix / scuttle-book



Tree:
📄.gitignore
📄README.md
📁async
📄index.js
📄isBook.js
📁obs
📄package-lock.json
📄package.json
📁pull
📁schema
📁sync
📁tests
README.md

Scuttle-book

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.

The parts of this modules are :

Usage

const Book = require('scuttle-book')
const book = Book(server)   // server is sometimes called sbot

const newBook = {
  title: 'The Dispossessed',
  author: 'Ursula le Guin'
}

book.async.create(newBook, (err, bookMsg) => {
  if (err) // handle error

  book.isBook(bookMsg)
  // => true
})

Constructor API

Book(server, opts)

server is a connection to your scuttlebutt server provided by ssb-client (sometimes called sbot in other docs).

opts (options) an Object with over-ride options for the scuttle-book instance:

{
  // TODO: REVISE THIS
  aboutWinner: function (sbot, attr, attrOpinions, cb) {
    // In the event there are differing opinions about a given book attribute, 
    // this function determines which one 'wins'.
    // By default, the fallback for attribute is :
    //    [ myOpinion, publishersOpinion, friendsOpinion, strangersOpinion ] 
    //    'friendsOpinion' is the most recent opinion by a friend
  }
}

Instance API

book.async.create(book, cb)

book - an Object which must at least have title, author. If a book doesn't pass the isBook validator, the callback is called with the errors : cb(errors)

book.async.update(id, attributes, cb)

book.async.comment(id, text, cb)

book.sync.isBook(bookMsg)

Checks if a given message is a valid book message, where a 'message' can be either a raw message from the database or msg.value.content.

This method doesn't need an sbot connection so can be accessed directly like:

const isBook = require('scuttle-book/isBook')

book.async.isBookKey(key, cb)

Looks up a key to see if it belongs to a valid book message.

book.async.isBookUpdate(aboutMsg, cb)

Check if it's an about message, and directed at a valid book message.

book.isBookComment(postMsg, cb)

Check if it's a post message, and directed at a valid book message.

book.pull.books()

A stream of all books. These are just raw book messages.

book.pull.comments()

A stream of comments on books

book.pull.updates()

A stream of updates on books. You can filter this yourself to pull out just ratings, or description updates etc).

book.obs.get(key)

Returns an observeable which provides live updating data for a particular book.

var favBook = book.obs.get('%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256"')

favBook( function listener (newBookState) {
  // this function is passed the newBookState whenever there's an update
})

favBook()
// => get the state right now

state has form:

// {
//   key: '%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256',
//   value: {  },          // the original message content
//   attributes: {  },     // contains the single 'winning' state for each attr
//   comments: [ ],        // the collection of replies in the order they were published
//   latestAttributes: { } // the latest state of each attribute from each peer
// }

where attributes and latestAttributes:

{
  title:       String,
  authors:     String | Array,
  description: String,
  image:       Blob,
  series:      String,
  seriesNo:    Number,
  review,
  rating,      
  ratingMax,  
  ratingType,
  shelve, // this one may not make any sense!
  genre
}

book.async.get(key, cb)

Similar to book.obs.get but an asynchronous method for e.g. backend rendering.

book.obs.shelves()

book.obs.authors()

Schemas

A new book:

{
  type:       'bookclub',
  title:       String,
  authors:     String | Array,
  description: String,  (optional)
  image:       Blob,    (optional)
  series:      String,  (optional)
  seriesNo:    Number   (optional)
}

Updating a book : (note arj seperated this into amending vs subjective comments, I think this can be done by providing convenience methods)

{
  type:       'about',
  about:       MessageId,    // the original book id
  title:       String,  (optional)
  authors:     String,  (optional)
  description: String,  (optional)
  image:       Blob,    (optional)
  series:      String,  (optional)
  seriesNo:    Number,  (optional)
  review,
  rating,      // ??? type
  ratingMax,   // ??? < I think we should just have an opinion
  ratingType,  // do we need this? 
  shelve,
  genre
}

Commenting on a book:

{
  type: 'post',
  root: MessageId,    // the original book id
  text: String,
  branch: String | Array
}

Development

Run the tests with npm test

Some tests require an sbot to be running and currently use your personal identity to read real books. TODO - build a test harness with an in-memory db.

Built with git-ssb-web