backbone-pouch Build Status

Backbone PouchDB Sync Adapter

Getting Started

You can use backbone-pouch on the server with node or in the browser:

On the Server

Install the module with: npm install backbone-pouch

var Backbone = require('backbone');
var BackbonePouch = require('backbone-pouch');
Backbone.sync = BackbonePouch.sync();

In the Browser

  1. Download jQuery, Underscore, Backbone and PouchDB
  2. Download the production version or the development version.
  3. In your web page:
<script src="jquery-2.0.0.min.js"></script>
<script src="underscore-min.js"></script>
<script src="backbone-min.js"></script>
<script src="pouchdb-nightly.min.js"></script>
<script src="backbone-pouch.js"></script>
<script>
  Backbone.sync = BackbonePouch.sync();
</script>

Setup backbone-pouch

You can configure Backbone to persist via backbone-pouch per model:

var MyModel = Backbone.Model.extend({
  sync: BackbonePouch.sync(options)
});

Or you might want to set backbone-pouch sync globally:

Backbone.sync = BackbonePouch.sync(defaults);

var MyModel = Backbone.Model.extend({
  pouch: options
});

BackbonePouch.attachments()

You can mixin attachment support into a single model:

var MyModel = Backbone.Model.extend(BackbonePouch.attachments());

Or you may want to mixin attachment support globally:

_.extend(Backbone.Model.prototype, BackbonePouch.attachments());

Note that you have to call the attachments function - don't forget the braces.

You can also pass the PouchDB adapter to BackbonePouch.attachments:

_.extend(Backbone.Model.prototype, BackbonePouch.attachments({
  db: PouchDB('mydb')
}));

idAttribute

You should adjust the idAttribute, because CouchDB (and therefore PouchDB) uses _id instead of the default id attribute:

Backbone.Model.prototype.idAttribute = '_id';

Usage

var MyModel = Backbone.Model.extend({
  idAttribute: '_id',
  sync: BackbonePouch.sync({
    db: PouchDB('mydb')
  })
});

Query documents of type post

Retrieve single documents with all conflicts. Retrieve collections via Map Reduce, filtering all documents of type post, ordered by position. Limit results to 10.

var Post = Backbone.Model.extend({
  idAttribute: '_id',
  sync: BackbonePouch.sync({
    db: PouchDB('mydb')
  })
});
var Posts = Backbone.Collection.extend({
  model: Post,
  sync: BackbonePouch.sync({
    db: PouchDB('mydb'),
    fetch: 'query',
    options: {
      query: {
        include_docs: true,
        fun: {
          map: function(doc) {
            if (doc.type === 'post') {
              emit(doc.position, null)
            }
          }
        },
        limit: 10
      },
      changes: {
        include_docs: true,
        filter: function(doc) {
          return doc._deleted || doc.type === 'post';
        }
      }
    }
  }),
  parse: function(result) {
    return _.pluck(result.rows, 'doc');
  }
});

Global Backbone Sync Configuration

Use mydb as default for all databases. Setup Map Reduce as default query method. Limit resultset to 10. Authors are returnd by name, Posts by date.

Backbone.sync =  BackbonePouch.sync({
  db: PouchDB('mydb'),
  fetch: 'query',
  options: {
    query: {
      include_docs: true,
      limit: 10
    }
  }
});
Backbone.Model.prototype.idAttribute = '_id';

Then you can define your models and collections as usual and overwrite backbone-pouchdb settings via the pouch property:

var Author = Backbone.Model.extend();
var Authors = Backbone.Collection.extend({
  model: Author,
  pouch: {
    options: {
      query: {
        include_docs: true,
        fun: {
          map: function(doc) {
            if (doc.type === 'author') {
              emit(doc.name, null)
            }
          }
        }
      },
      changes: {
        include_docs: true,
        filter: function(doc) {
          return doc._deleted || doc.type === 'author';
        }
      }
    }
  },
  parse: function(result) {
    return _.pluck(result.rows, 'doc');
  }
});
var Post = Backbone.Model.extend();
var Posts = Backbone.Collection.extend({
  model: Post,
  pouch: {
    options: {
      query: {
        include_docs: true,
        fun: {
          map: function(doc) {
            if (doc.type === 'post') {
              emit(doc.date, null)
            }
          }
        }
      },
      changes: {
        include_docs: true,
        filter: function(doc) {
          return doc._deleted || doc.type === 'post';
        }
      }
    }
  },
  parse: function(result) {
    return _.pluck(result.rows, 'doc');
  }
});

Attachments

Backbone.sync =  BackbonePouch.sync({
  db: PouchDB('mydb')
});
Backbone.Model.prototype.idAttribute = '_id';
var MyModel = Backbone.Model.extend(BackbonePouch.attachments());
var model = new MyModel();
model.attach(blob);     // store file
model.attachments();    // list files
model.attachment(name); // retrieve file

backbone-pouch helps you with binary attachments by providing convenient methods for retrieving, storing and listing files.

attach(blob, name, type, callback)

Store an attachment.

blob must be a Blob in the browser or a Buffer in node. You can omit name if the blob has a filename property. You can omit type if the blob has a type property.

The callback is invoked with err and result callbacks. After the file is stored, the models _rev property is updated. If the model wasn't saved before, an id will be assigned and it will be created.

attachments(filter)

List attachment names.

The optional filter argument can be used to list only attachments of a certain type.

If the filter argument is a string or a RegExp, it will be matched against the content_type of each attachment and only the matching attachment names will be returned.

If filter is a function, it will be called with the attachments name and its stub.

attachment(name, callback)

Retrieve an attachment blob by name.

callback is called with error and blob arguments.

In the browser a Blob object is returned, a Buffer in node.

Configuration

You can configure every option passed to PouchDB.

Option Inheritance

Options are merged (using Underscores extend) in the following order:

  1. BackbonePouch defaults
  2. BackbonePouch sync options
  3. pouch object
  4. save / get / destroy / fetch options

backbone-pouch Options

These options control the behaviour of backbone-pouch.

db: PouchDB Adapter

Setup a database. This option is mendatory. Must be a PouchDB adapter:

PouchDB('dbname')

See Create a database.

fetch: Fetch Method

Specify the fetch method. Can be either allDocs (default), query or spatial.

Use the default allDocs if you want all documents.

Using query you can use Map-Reduce to query the database.

spatial requires the Spatial query plugin.

listen: Listen for Changes

When this is checked, backbone-pouchdb will listen for changes in the database and update the model / collection on every change. Default is true.

Note that you will need to setup a filter function when used in combination with query fetch method.

options: PouchDB Options

Those options are passed directly to PouchDB.

The keys are PouchDB methods. Possible keys are post, put, remove, get, query, allDocs and spatial.

Refer to the PouchDB API Documentation for more options.

post: Create

Options for document creation. Currently no options supported.

See Create a Document.

put: Update

Options for document update. Currently no options supported.

See Update a Document.

remove: Delete

Options for document delete. Currently no options supported.

See Delete a Document.

get: Retrieve Model

Options for fetching a single document.

See Fetch a Document.

Fetch Collections

When fetching collections from views, one might want to parse the result, eg:

parse: function(result) {
  return _.pluck(result.rows, 'doc');
}
allDocs: Retrieve Collection

Options for fetching all documents. This is a built in view which outputs all documents by id.

See Fetch Documents.

query: Retrieve Collection via Map Reduce

Query options for Map Reduce queries.

See Query the Database.

spatial: Retrieve Collection via Spatial Index

Options for Spatial query. The spatial query has not been tested. You have to use a PouchDB build with included Spatial plugin.

changes: Listen for changes

Options passed to changes feed.

See Listen to Database Changes.

Examples

Check out the TODO Application in the doc/examples folder.

It`s the standard Backbone TODO example, extended to use backbone-pouch.

Advanced TODO Sync Example

TODO Sync Application is also in the doc/examples folder.

You can setup external CouchDB (with CORS enabled) to sync your local TODO database.

Contributing

To update the Github page, change to the gh-pages branch and merge the doc subtree:

git pull -s subtree origin master

Versioning

backbone-pouch follows semver-ftw. Dont think 1.0.0 means production ready yet. There were some breaking changes, so had to move up the major version.

Release History

License

Copyright (c) 2013-2014 Johannes J. Schmidt, TF
Licensed under the MIT license.