0.3.6 • Published 10 years ago

pouch-clerk v0.3.6

Weekly downloads
4
License
ISC
Repository
github
Last release
10 years ago

pouch-clerk

Build Status

PouchDB worker reacting to document changes.

Each document has a state. A clerk listens to changes in one or more PouchDB databases and react to document state changes.

When reacting to a document state change, the clerk can:

  • change the document
  • say what the next state is going to be

Install

$ npm install pouch-clerk --save

Use

Require package and create clerk:

var Clerk = require('pouch-clerk');

var transitions = {
  // document defining state transition handlers
};

var options = {
  initialState: 'start', // defaults to `start`
  finalState: 'finished', // defaults to `finish`
  reconnectMaxTimeoutMS: 3000, // defaults to 3000 ms
  transitions: transitions,
};

var clerk = Clerk(options);

Options

  • initialState (string): the state to give new documents with no state yet
  • finalState (string or string array): the end state (or states, if you pass an array)
  • reconnectMaxTimeoutMS (number): the maximum number of miliseconds to wait before trying to (re)connect
  • transitions (object): the state transition handlers. Object where the keys are the state names and the values are functions.
  • asyncUpdaters: an array of functions that start and stop async updaters. See Async Updaters section.

The state transition handlers

The options.transitions should contain an object with a key for each state. The value for each state should be a handler function, like this:

var transitions = {
  'start': function(doc, next) {
    // ...
  }
}

Example:

var transitions = {
  'start': function(doc, next) {
    somethingAsynchronous(function(err, result) {
      if (err) {
        doc.error(err);
      } else {
        doc.result = result;
        next(null, 'waiting for driver'); // jump into next state
      }
    });
  },

  'waiting for driver': function(doc, next) {
    // ...
  }

Reentering the same state

You can force reentry on the same state (watch out for infinite loops), by passing a true as third argument to the next callback:

var transitions = {
  'waiting for driver': function(doc, next) {
    next(null, 'waiting for driver', true);
  }
}

Adding and removing databases

A clerk can react to one or more databases. During runtime you just add or remove a database:

var PouchDB = require('pouchdb');
var db = new PouchDB('somedatabase');

clerk.add(db);
clerk.remove(db);

Name databases

You can also remove by database name:

clerk.add(db, 'mydb');
clerk.remove('mydb');

You can also find out if a named database exists:

if (!clerk.has('mydb')) {
  clerk.add(db, 'mydb');
}

Async updaters

You can push async updates into documents like this:

var asyncUpdater = {
  start: function(doc) {
    this._interval = setInterval(function() {
      doc.merge(function(currentDoc) {
        currentDoc.counter = currentDoc.counter + 1;
      })
    }, 1000);
  },
  stop: function() {
    clearInterval(this._interval);
  }  
}

var options = {
  asyncUpdaters: [asyncUpdater]  
};

var clerk = Clerk(options);

(Each document creates an async updater instance, which you can reference by this inside the start or stop methods).

Async updater API

The Async Updater start method gets a doc instance for each document that is being handled. Using this document you can:

get the ID of the document

function start(doc) {
  console.log(doc._id);
}

get the latest document version:

function start(doc) {
  doc.get(function(err, latestDoc) {
    // ...
  })
}

update the document:

function start(doc) {
  doc.put(doc, function(err) {

  });
}

merge some attributes into the latest version of the document:

function start(doc) {
  doc.merge(function(latest) {
    latest.counter ++;
  }, function(err) {
    // handle err
  });
}

Error handling

The error handling strategy depends on the type of error happening.

User-land errors

If an error occurs while you're processing a state transition, you should call the next callback with that error as the first argument:

var transitions = {
  'waiting for driver': function(doc, next) {
    somethingAsynchronous(function(err) {
      if (err) return next(err);
      /// ...
    });
  }
};

This will make the document transition into the error state.

You should define an error state handler (if you don't that error will be handled as an internal error — see the next section about internal errors).

var transitions = {
  'error': function(err, doc, next) {
    // you can recover from error:
    next(null, 'some next state');
  }
}

Internal errors

Internal errors can occurr when saving document changes. You can listen for those errors on the clerk object:

clerk.on('error', function(err) {
  
});

(if you don't, an uncaught exception will be thrown);

Stop clerk

clerk.stop(callback);

License

ISC

0.3.6

10 years ago

0.3.5

10 years ago

0.3.4

10 years ago

0.3.3

10 years ago

0.3.2

10 years ago

0.3.1

10 years ago

0.3.0

10 years ago

0.2.0

10 years ago

0.1.1

10 years ago

0.1.0

10 years ago

0.0.1

10 years ago