backbone-pouch
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
- Download jQuery, Underscore, Backbone and PouchDB
- Download backbone-pouch.
- 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: new 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
```javascript
var MyModel = Backbone.Model.extend({
idAttribute: '_id',
sync: BackbonePouch.sync({
db: new 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: new PouchDB('mydb')
})
});
var Posts = Backbone.Collection.extend({
model: Post,
sync: BackbonePouch.sync({
db: new PouchDB('mydb'),
fetch: 'query',
options: {
query: {
include_docs: true,
fun: {
map: function(doc, emit) {
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: new 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, emit) {
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, emit) {
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: new PouchDB('mydb')
});
Backbone.Model.prototype.idAttribute = '_id';
var MyModel = Backbone.Model.extend(BackbonePouch.attachments());
var model = new MyModel();
model.attach(blob);
model.attachments();
model.attachment(name);
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:
- BackbonePouch defaults
- BackbonePouch sync options
- pouch object
- 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.
attachments
: Include attachment data.conflicts
: If specified conflicting leaf revisions will be attached in _conflicts array.open_revs
: Fetch all leaf revisions if open_revs='all'.rev
: Fetch specific revision of a document. Defaults to winning revision.revs_info
: Include a list of revisions of the document, and their availability.revs
: Include revision history of the 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.
attachments
: Include attachment data.conflicts
: If specified conflicting leaf revisions will be attached in _conflicts array.descending
: Return result in descending order. Default is ascending order.endkey
: Endkey of the query.include_docs
: Whether to include the document in doc
property.key
: Key of the query.keys
: Multiple keys.limit
: Limit the resultset. Default is to return all documents.startkey
: Startkey of the query.
See Fetch Documents.
query
: Retrieve Collection via Map Reduce
Query options for Map Reduce queries.
attachments
: Include attachment data.conflicts
: If specified conflicting leaf revisions will be attached in _conflicts array.descending
: Return result in descending order. Default is ascending order.endkey
: Endkey of the query.fun
: Map Reduce Function: can be a string addressing a view in a design document or an object with a map
and optional reduce
property. A map function is required, if you use the query fetch method.include_docs
: Whether to include the document in doc
property.key
: Key of the query.keys
: Multiple keys.limit
: Limit the resultset. Default is to return all documents.reduce
: Whether to include the document in doc
property. Default is to reduce if there is a reduce function.startkey
: Startkey of the query.
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.
conflicts
: If specified conflicting leaf revisions will be attached in _conflicts array.end_range
: End range of queryinclude_docs
: Whether to include the document on each change. Default is true.start_range
: Start range of query
changes
: Listen for changes
Options passed to changes feed.
filter
: Reference a filter function from a design document or define a function to selectively get updates.descending
: Return result in descending order. Default is ascending order.conflicts
: If specified conflicting leaf revisions will be attached in _conflicts array.continuous
: Continuously listen to changes. Default is true.include_docs
: Whether to include the document on each change. Default is true.
See Listen to Database Changes.
## Examples
Check out the [TODO Application](http://jo.github.io/backbone-pouch/examples/todos)
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
- Install dependencies via
npm install
- Edit
backbone-pouch.js
- Write tap tests
- Run the tests with
npm test
- Generate the docs with
npm run docs
. This will render README.md
using doc/index.html.jst
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
1.5.0
: Remove Grunt in favour of purism and switch to tap1.4.0
: Update Backbone and Underscore1.3.0
: Do not parse view results, leave that up to the user1.2.1
: Improve option inheritance1.2.0
: Change defaults: do not listen and include_docs1.1.1
: Adapt PouchDB attachment API change with seperate docId and attachment name1.1
: Attachment support1.0
: New chained api, Node support, tests. Support listen to changes feed. Use Grunt.prior 1.0
: Experimental version with example TODO apps
License
Copyright (c) 2013-2014 Johannes J. Schmidt, TF
Licensed under the MIT license.