PouchType
An type-based abstraction layer over PouchDB inspired by Hood.ie and Django
Extending the TypeHandler class
PouchType works by extending the TypeHandler class with methods to define how a document type should be handled. The resulting class is instantiated with a PouchDB instance and used to interact with documents of that type.
All subclasses of TypeHandler must override the getUniqueID method. This method should return a
unique string for documents of this type. (NOTE: The document id will be prefixed with the
type_string as well to avoid collisions across types.)
import { PouchDB } from 'pouchdb';
import { TypeHandler } from 'PouchType';
const PDB = PouchDB.plugin(find); // PouchType requires the find plugin.
class ContactHandler extends TypeHandler {
getUniqueID(doc) {
return doc.email;
}
validate(doc) {
super.validate(doc);
if (typeof doc.email != 'string') {
throw new Error('email property is required');
} else if (doc.email.length <= 2) {
throw new Error('email must be longer than 2 characters');
}
}
}
TypeHandler management methods
getUniqueID(doc)
This method must be overridden in subclasses.
Return a unique string that will be used to populate doc._id if it isn't already populated.
hash(doc)
Returns a hash string of the current document for comparison. By default this is
"doc._id:doc._rev" and will work as long as the hash is only taken after any changes are saved.
You may wish to override this to provide content-specific hashing.
index(name, fields)
Create a index to be used in a filter selector and sort options. Specify the name of the index
and the fields as an array of strings of the document properties to include in the index.
isType(doc)
Check if the passed doc belongs to this handler.
validate(doc)
Check if the passed doc has valid data before it is written. Invalidation happens by raising an
exception. For more fine-grained validation, refer to the
pouchdb-validation plugin or the
validate_doc_update function.
TypeHandler query methods
get(id)
Return the document referenced by id or null if the document does not exist.
getOrCreate(doc, defaults={})
If the passed document doesn't have a _id property, populate it. Try to lookup a document with the
id. If it exists, update it with the properties in doc. If it does not exist, add the properties
in defaults to props and save the new document.
filter(selector, options={})
Return an array of documents that match the criteria in selector. options.index can contain the
name passed to index() if needed. All other option properties are passed through to the
PouchDB.find()
watch(selector, options={})
The parameters for watch() are identical to filter() but watch() returns a
computed instance that will call subscribers whenever any data
matching the selector changes.
TypeHandler change methods
remove(docOrId)
remove accepts a document or an id string.
Flag this document as doc._deleted == true. This will cause it to not show up in get, filter
or watch results. (Note: documents are left in the database in this state to allow for deletion
to be synced to other nodes. To truly remove documents,
compact your database.)
save(doc)
If the document does not have properties _id or type, populate them appropriately. Run
TypeHandler.validate on the document. If validate doesn't throw any errors, then save the document
to the database. It's _rev property will be updated to reflect the revision in the database.
update(doc, props)
Deeply assign props to the passed doc object and save() it.
addAttachment(doc, key, blob)
Attach the passed blob to the document referenced with the key string.
removeAttachment(doc, key)
Remove a previously attached blob at key.
getAttachment(doc, key)
Return a previously attached blob at key or null if none exists.
Using Types
const db = PDB('type_example');
export const Contact = new ContactHandler(db, 'contact');
const doc = await Contact.getOrCreate({
name: "John Doe",
email: "jd@example.com"
});