Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

leveldb persistence for scuttlebutts (scuttlebutt/crdt/append-only and friends)

tree: f9e2b91955

Fetching latest commit…


Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 test
Octocat-spinner-32 .gitignore
Octocat-spinner-32 .travis.yml
Octocat-spinner-32 LICENSE
Octocat-spinner-32 client.js
Octocat-spinner-32 index.js
Octocat-spinner-32 package.json


Plugin to add persistence and querying scuttlebutt documents stored in leveldb.

Instead of representing an object as a single document, scuttlebutt represents a document as a series of immutable transactions. The 'document' is modified by appending a new transaction. Old transactions that are no longer relevant can be cleaned up, but you can never modify a transaction in place. As it turns out, leveldb (a log-structured merge tree) is optimized for exactly this sort of data.


//a scuttlebutt model.
var Model = require('scuttlebutt/model')

//level-scuttlebutt needs to have an unique identifier of the current instance
var udid = require('udid')

//create a leveldb instanc
var levelup = require("levelup")
var db = levelup(DB_FILE)

//patch it with level-scuttlebutt.
var level_scuttlebutt = require("level-scuttlebutt")
level_scuttlebutt(db, udid, function (name) {
  //create a scuttlebutt instance given a name.
  //the key will match the start of the name.
  return new Model()
  //now is a good time to customize the scuttlebutt instance.

//see below...

//open a scuttlebutt instance by name., function (err, model) {
  model.on('change:key', console.log) //...
  model.set('key', value)


Add level-scuttlebutt plugin to the db object var level_scuttlebutt = require('level-scuttlebutt'); level_scuttlebutt(db, ID, schema)

ID is a unique string that identifies the node instance and should be tied to the leveldb instance. I suggest using udid.

schema should be a function that takes a string (the name of the scuttlebutt instance) and returns and empty scuttlebutt instance. You can use scuttlebutt-schema.

Map Reduce

create a map-reduce db.scuttlebutt.addMapReduce(mapReduceOptions). This is the same as db.mapReduce.add(mapReduceOptions) in map-reduce except that you should leave off start and end, and that in map: function (key, value) {...} value will be your scuttlebutt instance.

Do not assign event listeners during the map function.


get the 10 latest documents edited.

  name: 'latest10',
  map: function (key, sb) {
    var name = sb.meta.get('name') || 'no_name'
    //emit 0-many group-value pairs.
    //value must be a string or a buffer.
    this.emit([], JSON.stringify({name: name, time:, length: sb.text.length}))
  //merge the latest value into the accumulator.
  reduce: function (acc, value) {
    var all = parse(acc).concat(parse(value))
    //sort by time, decending.
    all.sort(function (a, b) {
      return b.time - a.time
    //top ten most recent
    var all = all.slice(0, 10)
    return JSON.stringify(all)
  //the first value for the accumulator.
  //since we are parsing it, it needs to be valid JSON.
  initial: '[]'



Something went wrong with that request. Please try again.