<repo_name>slamdunking/pouchdb-facade<file_sep>/main.js
/**
 * @class Angular controller for notes list.
 * @param  {angularScope} $scope
 */
var remoteDbUrl = 'http://localhost:5984/notes',

    NotesController = function ($scope) {

        var notes = $scope.notes = [],

            onDbError = function (err) {
                console.error(err);
            },

            onDbGetAll = function (result) {
                $scope.loadNotes(result.rows);
            }

            onDbCreated = function (db) {
                dbHelper.getAll().then(onDbGetAll, onDbError);
            },

            onDbGet = function (doc) {
                $scope.$apply(function () {
                    $scope.notes.push(doc);
                });
            },

            // I would love to use angularjs $q, however it sucks
            // so I'm using q.js instead.
            dbHelper = new DB(window.PouchDB, Q, _, remoteDbUrl);

        dbHelper.createDB('notes').then(onDbCreated, onDbError);

        $scope.onDbChange = function (change) {
            console.log(change);
        };

        dbHelper.onChange($scope.onDbChange);

        $scope.loadNotes = function (notes) {
            var i;

            for (i = 0; i < (notes.length - 1); i += 1) {
                var note = notes[i];
                dbHelper.get(note.id).then(onDbGet, onDbError);
            };
        };

        $scope.addNote = function () {
            var newNote = $scope.newNote.trim(),
                noteData = {
                    _id: new Date().toISOString(),
                    body: newNote
                };

            notes.push(noteData);

            dbHelper.put(noteData);
        };

        $scope.removeNote = function (note) {
            notes.splice(notes.indexOf(note), 1);
            dbHelper.remove(note);
        };
    };
<file_sep>/DB.js
/**
 * @example
 * var db = new DB(window.PouchDB, Q);
 *
 * @param  {PouchDB}    DB https://github.com/daleharvey/pouchdb
 * @param  {Q} Deferred        https://github.com/kriskowal/q
 * @param  {Object} options
 * @return {DB}
 */
var DB = function (DB, Deferred, _, remoteDbUrl) {

    var remoteCouch = false,
        _db,
        _rdb,

        _name,

        getDbName = function () {
            return _name;
        },

        _dbCallback = function (description, deferred) {
            return function (error, response) {

                if (error) {
                    console.error(error);
                    if (deferred) {
                        deferred.reject(new Error(error.error + ':' + error.reason));
                    }
                    return;
                }

                console.info(description);

                if (deferred) {
                    deferred.resolve(response);
                }
            }
        },

        /**
         * Creates your db for you. How nice.
         *
         * @param  {String} name The name you wish your db to use.
         * @return {Promise}
         */
        createDB = function (name) {
            var deferred = Deferred.defer(),
                rdeferred,
                localMessage = 'Created db: ' + name;

            _name = name;

            _db = new DB(
                name,
                function () {
                    var remoteDbMessage;

                    _dbCallback(localMessage, deferred)();

                    if (!!remoteDbUrl) {
                        rdeferred = Deferred.defer();

                        remoteDbMessage = 'Created remote db: ' + remoteDbUrl;

                        _rdb = new DB(
                            remoteDbUrl,
                            function () {
                                _dbCallback(remoteDbMessage, rdeferred)();
                                syncDbs();
                            }
                        );
                    }
                }
            );

            return deferred.promise;
        },

        put = function (data) {
            var deferred = Deferred.defer();
            _db.put(data, _dbCallback('Put data', deferred));
            return deferred.promise;
        },

        remove = function (data) {
            var deferred = Deferred.defer();
            _db.remove(data, _dbCallback('Removed data', deferred));
            return deferred.promise;
        },

        get = function (id) {
            var deferred = Deferred.defer();

            _db.get(id, _dbCallback('Got data: ' + id , deferred));

            return deferred.promise;
        },

        _consoleDocs = function (err, doc) {
            console.log(err || doc);
        },

        onChange = function (callback) {
            var options = {
                continuous: true,
                // callback(change)
                onChange  : callback
            };

            _db.info(function (err, info) {
                options.since = info.update_seq;
                _db.changes(options);
            });
        },

        /**
         * options.filter    : Reference a filter function from a design document to selectively
         *                     get updates.
         *
         * options.complete  : Function called when all changes have been processed.
         * options.onChange  : Function called on each change processed.
         *
         * options.continuous: If true starts subscribing to future changes in the source database
         *                     and continue replicating them.
         *
         * @param {String} direction Can be 'to' or 'from'.
         * @param  {Object} options
         * @return {Promise}
         */
        updateRemote = function (direction, options) {
            var deferred,
                origOnComplete,
                validDirections = ['to', 'from'];

            if (!direction || !_(validDirections).indexOf(direction) === -1) {
                throw new Error('Direction must be specified');
            }

            options = options || {};

            deferred = Deferred.defer();

            console.log(!remoteDbUrl);

            if (!remoteDbUrl) {
                deferred.reject(new Error('No remote db specified'));

            } else {
                if (options.complete) {
                    origOnComplete = options.complete;
                }

                options.complete = function () {
                    if (origOnComplete) {
                        origOnComplete();
                    }

                    deferred.resolve();
                };

                _db.replicate[direction](remoteDbUrl, options);
            }

            return deferred.promise;
        },

        updateRemoteDb = function (options) {
            return updateRemote('to', options);
        },

        updateLocalDb = function (options) {
            return updateRemote('from', options);
        },

        syncDbs = function (options) {
            updateRemoteDb(options);
            updateLocalDb(options);
        },

        getAll = function () {
            var deferred = Deferred.defer(),
                options = {
                    include_docs: true,
                    descending  : true
                };

            _db.allDocs(options, _dbCallback('Got all', deferred));

            return deferred.promise;
        };

    return {
        'onChange'      : onChange,
        'createDB'      : createDB,
        'updateLocalDb' : updateLocalDb,
        'updateRemoteDb': updateRemoteDb,
        'getAll'        : getAll,
        'getDbName'     : getDbName,
        'get'           : get,
        'put'           : put,
        'remove'        : remove
    };
};
<file_sep>/README.md
Just started, using angular js but the pouchdb part is the part we're interested in.
