npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pouch-clerk

v0.3.6

Published

PouchDB worker reacting to document changes

Downloads

6

Readme

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