You are reading content from Scuttlebutt
@mix %KiSCJImPPNECdvHLTaftQTie0HnRrCIx9KzQndgrD5c=.sha256

scuttle-book

ok I've started designing a helper module following this idea : %TZxzMKH...

This one is a helper module which does all the things you'd want to do (sensibly) with books. The main motivation is to make an easy module that is client-agnostic

Here's the repo : %TZxzMKH...

Comments? cc @arj @matt @dominic @mikey

and here's the README sofar (I'm doing documentation-driven development). The repo has stubs of files in case that helps you see the idea.

//////////////////////////////////////////////////////////////////////////

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 :

  • queries/ getters
  • publishing helpers
  • schemas

Usage

const Book = require('scuttle-book')
const book = Book(client)   // an ssb-client (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(client, opts)

client an ssb-client instance (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

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.

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

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

book.async.isBook(id, cb)

Looks up an id to see if it's 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(id)

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

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

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

favBook()
// => get the state right now
// {
//   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
// }

attributes:

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

book.async.get(id, 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,
  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
}
@Rich %0Y7djqJFUier64jLriP+VDE0FF2Vksk1RcZ9EjIDqXQ=.sha256

fwiw, I thought this was "book" as in "gitbook" not "book" as in "bookshelf' and I got very excited for a second

@mix %2f/wTt0gpE0fh5p/QXgE2hjNognC2dbP0U8KUP7t6jY=.sha256

@rich given there's git build into ssb, it's probably possible in the future

User has not chosen to be hosted publicly
@mix %ruFogidblKhMdWnnFYDxY5eUa071MFFY9b+pS6pWXn4=.sha256

I was thinking git-ssb + a gitbook server = decent fairly accessible wiki

@Anders %H97Occb/rgq/BItZVcfPVOAaX7Yyqzokl0kZ/1dUqlE=.sha256

This is excellent @mix!

I like the idea of splitting out the core of patchbook. It will make it much easier to test and benchmark :smiley: :rocket:

Some of these methods would be really nice for the activity thing @happy0 talked about.

I might be a good idea with a branch attribute on the book update, as that will make it easier to infer things related to your winner function.

I guess this will be quite a refactor, let me know how I can helpful.

About the rating, ratingMax and ratingType: ratingMax was added later as it was confusing the way it was before. rating & ratingMax could be replaced with a ratingPercentage but might be a bit confusing. As for the ratingType I'm very fond of that, I think it adds character :space_invader: :seedling: :star:

Lastly I have been thinking about the flumeview thing. I think it should allow for some massive speed-ups of things and I'm very keen on persuing this as I think it has applications to a lot of other areas. If you get this module into a usable state I'll do the flumeview and provide benchmarks so we can see how it behaves.

@mix %1ZU3bXLa41EkeqHOADHr9UsxlU3lSMS29AqUZRK+wRM=.sha256

thanks for the feedback @arj

The branch attribute will be a private one that is set for you by the helper methods - it's too easy to screw up, and there's a module that calculates what it should be given your current db state too :)

I've been looking at it and wondering if we can actually easily use existing flumeviews (like about). The beauty of extracting this is the user doesn't need to be concerned with how a method delivers ... and in fact it could start our crappy internally, and get better over time !

@mix %mYADRmg652a2OG24eVXpAfP39wmtRLhiz0BXDTv29XU=.sha256

btw this is meant as an exploration and if it goes well an exemplar for other apps in the ecosystem, e.g. gatherings posts loomio git-ssb

Yeah I think it's going to be a bit of refactor for patchbook / patchbay-book, but I think it will make it much easier to maintain and develop that. That's my intention anyway.

User has not chosen to be hosted publicly
User has not chosen to be hosted publicly
@mix %wslBy9rKAqNtdymXt1VNLh6/gUMwRzyXNjLNSf+rEfY=.sha256

@Connor the review have already begun. This is a refactor of part of the system that's already in use in Patchbay (which now has installers if you want to try it easily), with the intention of making it easy for any client to roll books in.

The Dispossessed is excellent isn't it. Ursula Le Guin ... phew!

@kas %e1aJr3qW66C/4qyByO2HzYDhxcdVeGmiHyShGJZyCT4=.sha256
{
  type:       'bookclub',
  title:       String,
  authors:     String,
  description: String,  (optional)
  image:       Blob,    (optional)
  series:      String,  (optional)
  seriesNo:    Number   (optional)
}

Other fields that could be interesting/relevant:

  • pages
  • edition
  • printing
  • year
  • publisher
  • language
  • isbn13

An example of a bookclub entry that uses these fields (and more): %e8I54QF…

Data could be used for e.g. BibTeX citation generation.

Join Scuttlebutt now