level-hooks
Advanced tools
Comparing version 2.0.0 to 3.0.0
178
index.js
@@ -6,105 +6,119 @@ | ||
module.exports = function (db) { | ||
if(db) return hooks(db) | ||
function hooks (db) { | ||
if(db.hooks) { | ||
return | ||
} | ||
if(db.hooks) { | ||
return | ||
} | ||
var posthooks = [] | ||
var prehooks = [] | ||
var posthooks = [] | ||
var prehooks = [] | ||
function getPrefix (p) { | ||
return p && ( | ||
'string' === typeof p ? p | ||
: 'string' === typeof p.prefix ? p.prefix | ||
: 'function' === typeof p.prefix ? p.prefix() | ||
: '' | ||
) | ||
} | ||
function getPrefix (p) { | ||
return p && ( | ||
'string' === typeof p ? p | ||
: 'string' === typeof p.prefix ? p.prefix | ||
: 'function' === typeof p.prefix ? p.prefix() | ||
: '' | ||
) | ||
} | ||
function checker(range) { | ||
if ('string' === typeof range) | ||
return function (key) { | ||
return key.indexOf(range) == 0 | ||
} | ||
else if(range instanceof RegExp) | ||
return function (key) { | ||
return range.test(key) | ||
} | ||
else if('object' === typeof range) | ||
return function (key) { | ||
return key >= range.start && key <= range.end | ||
} | ||
else if('function' === typeof range) | ||
return range | ||
} | ||
db.hooks = { | ||
post: function (hook) { | ||
db.on('hooks:post', hook) | ||
return db | ||
}, | ||
pre: function (prefix, hook) { | ||
if(!hook) hook = prefix, prefix = '' | ||
prehooks.push({prefix: getPrefix(prefix), hook: hook}) | ||
return db | ||
}, | ||
posthooks: posthooks, | ||
prehooks: prehooks | ||
} | ||
db.hooks = { | ||
post: function (hook) { | ||
if(!hook) hook = prefix, prefix = '' | ||
posthooks.push({test: checker(prefix), hook: hook}) | ||
return db | ||
}, | ||
pre: function (prefix, hook) { | ||
if(!hook) hook = prefix, prefix = '' | ||
prehooks.push({test: checker(prefix), hook: hook}) | ||
return db | ||
}, | ||
posthooks: posthooks, | ||
prehooks: prehooks | ||
} | ||
//POST HOOKS | ||
//POST HOOKS | ||
function each (e) { | ||
if(e && e.type) | ||
db.emit('hooks:post', e) | ||
function each (e) { | ||
if(e && e.type) { | ||
posthooks.forEach(function (h) { | ||
if(h.test(e.key)) h.hook(e) | ||
}) | ||
} | ||
} | ||
db.on('put', function (key, val) { | ||
each({type: 'put', key: key, value: val}) | ||
}) | ||
db.on('del', function (key, val) { | ||
each({type: 'del', key: key, value: val}) | ||
}) | ||
db.on('batch', function onBatch (ary) { | ||
ary.forEach(each) | ||
}) | ||
db.on('put', function (key, val) { | ||
each({type: 'put', key: key, value: val}) | ||
}) | ||
db.on('del', function (key, val) { | ||
each({type: 'del', key: key, value: val}) | ||
}) | ||
db.on('batch', function onBatch (ary) { | ||
ary.forEach(each) | ||
}) | ||
//PRE HOOKS | ||
//PRE HOOKS | ||
var put = db.put | ||
var del = db.del | ||
var batch = db.batch | ||
var put = db.put | ||
var del = db.del | ||
var batch = db.batch | ||
function callHooks (isBatch, b, opts, cb) { | ||
function callHooks (isBatch, b, opts, cb) { | ||
b.forEach(function hook(e, i) { | ||
prehooks.forEach(function (h) { | ||
if(e.key.indexOf(h.prefix) == 0) | ||
h.hook(e, function (ch, db) { | ||
if(ch === false) | ||
return delete b[i] | ||
var prefix = getPrefix(db) || h.prefix || '' | ||
ch.key = prefix + ch.key | ||
console.log('batch - add', ch) | ||
b.push(ch) | ||
hook(ch, b.length - 1) | ||
}) | ||
}) | ||
b.forEach(function hook(e, i) { | ||
prehooks.forEach(function (h) { | ||
if(h.test(e.key)) | ||
h.hook(e, function (ch, db) { | ||
if(ch === false) | ||
return delete b[i] | ||
var prefix = getPrefix(db) || h.prefix || '' | ||
ch.key = prefix + ch.key | ||
b.push(ch) | ||
hook(ch, b.length - 1) | ||
}) | ||
}) | ||
}) | ||
b = b.filter(function (e) { | ||
return e && e.type //filter out empty items | ||
}) | ||
b = b.filter(function (e) { | ||
return e && e.type //filter out empty items | ||
}) | ||
if(b.length == 1 && !isBatch) { | ||
var change = b[0] | ||
return change.type == 'put' | ||
? put.call(db, change.key, change.value, opts, cb) | ||
: del.call(db, change.key, opts, cb) | ||
} | ||
return batch.call(db, b, opts, cb) | ||
if(b.length == 1 && !isBatch) { | ||
var change = b[0] | ||
return change.type == 'put' | ||
? put.call(db, change.key, change.value, opts, cb) | ||
: del.call(db, change.key, opts, cb) | ||
} | ||
return batch.call(db, b, opts, cb) | ||
} | ||
db.put = function (key, value, opts, cb ) { | ||
var batch = [{key: key, value: value, type: 'put'}] | ||
return callHooks(false, batch, opts, cb) | ||
} | ||
db.put = function (key, value, opts, cb ) { | ||
var batch = [{key: key, value: value, type: 'put'}] | ||
return callHooks(false, batch, opts, cb) | ||
} | ||
db.del = function (key, opts, cb) { | ||
var batch = [{key: key, type: 'del'}] | ||
return callHooks(false, batch, opts, cb) | ||
} | ||
db.del = function (key, opts, cb) { | ||
var batch = [{key: key, type: 'del'}] | ||
return callHooks(false, batch, opts, cb) | ||
} | ||
db.batch = function (batch, opts, cb) { | ||
return callHooks(true, batch, opts, cb) | ||
} | ||
db.batch = function (batch, opts, cb) { | ||
return callHooks(true, batch, opts, cb) | ||
} | ||
return hooks | ||
} |
{ | ||
"name": "level-hooks", | ||
"description": "pre/post hooks for leveldb", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"homepage": "https://github.com/dominictarr/level-hooks", | ||
@@ -6,0 +6,0 @@ "repository": { |
@@ -6,3 +6,3 @@ # Pre/Post hooks for leveldb | ||
## Warning - Breaking Changes | ||
The API for implementing pre hooks has changed. | ||
@@ -13,4 +13,10 @@ Instead of mutating an array at once, the prehook | ||
## Examlpe | ||
Also, attaching hooks to leveldb is now simpler | ||
``` js | ||
var Hooks = require('level-hooks') | ||
Hooks(db) //previously: Hooks()(db) | ||
``` | ||
## Example | ||
``` js | ||
@@ -24,3 +30,3 @@ var levelup = require('levelup') | ||
//install hooks onto db. | ||
hooks()(db) | ||
hooks(db) | ||
@@ -53,2 +59,3 @@ db.hooks.pre(function (change, add) { | ||
}) | ||
``` | ||
@@ -58,1 +65,28 @@ | ||
to make map-reduce durable across crashes! | ||
## API | ||
### db.hooks.pre (range?, hook(change, add(change, prefix?))) | ||
If `prefix` is a `string` or `object` that defines the range the pre-hook triggers on. | ||
If `prefix' is a string, then the hook only triggers on keys that _start_ with that | ||
string. If the hook is an object it must be of form `{start: START, end: END}` | ||
`hook` is a function, and will be called on each item in the batch | ||
(if it was a `put` or `del`, it will be called on the change) | ||
`change` is always of the form `{key: key, value: value, type:'put' | 'del'}` | ||
Pass additional changes to `add` to add them to the batch. | ||
If add is passed a string as the second argument it will prepend that prefix | ||
to any keys you add. | ||
To veto (remove) the current change call `add(false)`. | ||
### db.hooks.post (range?, hook) | ||
Post hooks do not offer any chance to change the value. | ||
but do take a range option, just like `pre` | ||
## License | ||
MIT |
@@ -14,12 +14,11 @@ var rimraf = require('rimraf') | ||
hooks()(db) | ||
hooks(db) | ||
var _batch = [] | ||
db.hooks.pre(mac(function (ch, add) { | ||
//hook keys that start with a word character | ||
db.hooks.pre(/^\w/, mac(function (ch, add) { | ||
if(ch.key != 'h') { | ||
_batch.push(ch) | ||
var a | ||
add(a = {key: 'h', value: 'hello', type: 'put'}) | ||
_batch.push(a) | ||
} | ||
_batch.push(ch) | ||
var a | ||
add(a = {key: '~h', value: 'hello', type: 'put'}) | ||
_batch.push(a) | ||
}).atLeast(1)) | ||
@@ -26,0 +25,0 @@ |
var rimraf = require('rimraf') | ||
var levelup = require('levelup') | ||
var use = require('../use') | ||
var hooks = require('..') | ||
var hooks = require('../') | ||
@@ -20,20 +19,19 @@ var assert = require('assert') | ||
use(db) | ||
.use(hooks()) | ||
.hooks.pre(mac(function (ch, add) { | ||
hooks(db) | ||
db.hooks.pre(/^\w/, mac(function (ch, add) { | ||
//iterate backwards so you can push without breaking stuff. | ||
var key = ch.key | ||
if(key < '~') { | ||
add({ | ||
type: 'put', | ||
key: new Buffer('~log~'+ ++SEQ), | ||
value: new Buffer(JSON.stringify({ | ||
type: ch.type, | ||
key: key.toString(), | ||
time: Date.now() | ||
})) | ||
}) | ||
add({ | ||
type: 'put', | ||
key: new Buffer('~log~'+ ++SEQ), | ||
value: new Buffer(JSON.stringify({ | ||
type: ch.type, | ||
key: key.toString(), | ||
time: Date.now() | ||
})) | ||
}) | ||
add({type: 'put', key: new Buffer('~seq'), value: new Buffer(SEQ.toString())}) | ||
add({type: 'put', key: new Buffer('~seq'), value: new Buffer(SEQ.toString())}) | ||
} | ||
}).atLeast(1)) | ||
@@ -40,0 +38,0 @@ |
11755
88
11
262