New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

level-hooks

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

level-hooks - npm Package Compare versions

Comparing version 4.3.0 to 4.3.1

162

index.js
var ranges = require('string-range')
var locker = require('lock')
module.exports = function (db) {
var lock = locker()
if(db.hooks) {

@@ -10,5 +9,4 @@ return

var posthooks = []
var prehooks = []
var asynchooks = []
var posthooks = []
var prehooks = []

@@ -46,11 +44,4 @@ function getPrefix (p) {

},
async: function (prefix, hook) {
if(!hook) hook = prefix, prefix = ''
var h = {test: ranges.checker(prefix), hook: hook, async: true}
asynchooks.push(h)
return remover(asynchooks, h)
},
posthooks : posthooks,
prehooks : prehooks,
asynchooks: asynchooks
posthooks: posthooks,
prehooks: prehooks
}

@@ -85,103 +76,60 @@

function callHooks (isBatch, b, opts, cb) {
if(!cb)
cb = opts, opts = {}
//ASYNC HOOKS
var toHook = [], toLock = [], n = 0, locked = false
//skip this if there are no async hooks.
if(!asynchooks.length)
return n=1, sync()
b.forEach(function (e) {
asynchooks.forEach(function (h) {
try {
b.forEach(function hook(e, i) {
prehooks.forEach(function (h) {
if(h.test(String(e.key))) {
locked = true
// should I lock the whole batch?
// or just the keys that have asynchooks?
// just locking the hooked keys for now...
toLock.push(e.key)
toHook.push(function (cb) {
h.hook(e, cb)
})
n++
}
})
})
if(toLock.length)
lock(toLock, function (release) {
//release the lock when the callback is called
//after the batch is processed!
cb = release(cb)
toHook.forEach(function (f) { f(sync) })
})
else
n=1, sync()
//SYNC HOOKS
function sync () {
if(--n) return
try {
b.forEach(function hook(e, i) {
prehooks.forEach(function (h) {
if(h.test(String(e.key))) {
//optimize this?
//maybe faster to not create a new object each time?
//have one object and expose scope to it?
var context = {
add: function (ch, db) {
if(typeof ch === 'undefined') {
return this
}
if(ch === false)
return delete b[i]
var prefix = (
getPrefix(ch.prefix) ||
getPrefix(db) ||
h.prefix || ''
)
ch.key = prefix + ch.key
if(h.test(String(ch.key))) {
//this usually means a stack overflow.
throw new Error('prehook cannot insert into own range')
}
b.push(ch)
hook(ch, b.length - 1)
//optimize this?
//maybe faster to not create a new object each time?
//have one object and expose scope to it?
var context = {
add: function (ch, db) {
if(typeof ch === 'undefined') {
return this
},
put: function (ch, db) {
if('object' === typeof ch) ch.type = 'put'
return this.add(ch, db)
},
del: function (ch, db) {
if('object' === typeof ch) ch.type = 'del'
return this.add(ch, db)
},
veto: function () {
return this.add(false)
}
if(ch === false)
return delete b[i]
var prefix = (
getPrefix(ch.prefix) ||
getPrefix(db) ||
h.prefix || ''
)
ch.key = prefix + ch.key
if(h.test(String(ch.key))) {
//this usually means a stack overflow.
throw new Error('prehook cannot insert into own range')
}
b.push(ch)
hook(ch, b.length - 1)
return this
},
put: function (ch, db) {
if('object' === typeof ch) ch.type = 'put'
return this.add(ch, db)
},
del: function (ch, db) {
if('object' === typeof ch) ch.type = 'del'
return this.add(ch, db)
},
veto: function () {
return this.add(false)
}
h.hook.call(context, e, context.add, b)
}
})
h.hook.call(context, e, context.add, b)
}
})
} catch (err) {
db.emit('error', err)
return (cb || opts)(err)
}
b = b.filter(function (e) {
return e && e.type //filter out empty items
})
})
} catch (err) {
return (cb || opts)(err)
}
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)
}

@@ -188,0 +136,0 @@

{
"name": "level-hooks",
"description": "pre/post hooks for leveldb",
"version": "4.3.0",
"version": "4.3.1",
"homepage": "https://github.com/dominictarr/level-hooks",

@@ -12,10 +12,9 @@ "repository": {

"dependencies": {
"string-range": "~1.2",
"lock": "0.0.3"
"string-range": "~1.2"
},
"devDependencies": {
"levelup": "~0.8",
"rimraf": "~2.0.2",
"macgyver": "~1.9",
"range-bucket": "0.0.0",
"level-test": "~1.1.1"
"range-bucket": "0.0.0"
},

@@ -22,0 +21,0 @@ "scripts": {

@@ -5,5 +5,2 @@ # Pre/Post hooks for leveldb

[![Build Status](https://travis-ci.org/dominictarr/level-hooks.png?branch=master)
](https://travis-ci.org/dominictarr/level-hooks)
## Warning - Breaking Changes

@@ -29,16 +26,18 @@

var db = levelup(file)
levelup(file, {createIfMissing: true}, function (err, db) {
//install hooks onto db.
hooks(db)
//install hooks onto db.
hooks(db)
db.hooks.pre({start: '', end: '~'}, function (change, add) {
//change is same pattern as the an element in the batch array.
//add a log to record every put operation.
add({type: 'put', key: '~log-'+timestamp()+'-'+change.type, value: change.key})
})
db.hooks.pre({start: '', end: '~'}, function (change, add) {
//change is same pattern as the an element in the batch array.
//add a log to record every put operation.
add({type: 'put', key: '~log-'+timestamp()+'-'+change.type, value: change.key})
})
//add a hook that responds after an operation has completed.
db.hooks.post(function (ch) {
//{type: 'put'|'del', key: ..., value: ...}
//add a hook that responds after an operation has completed.
db.hooks.post(function (ch) {
//{type: 'put'|'del', key: ..., value: ...}
})
})

@@ -50,29 +49,2 @@ ```

## Async Example
``` js
var levelup = require('levelup')
var timestamp = require('monotonic-timestamp')
var hooks = require('level-hooks')
var db = levelup(file)
//install hooks onto db.
hooks(db)
db.hooks.pre('counter!', function (op, done) {
db.get(op.key, function (err, val) {
op.value = Number(op.value || 0) + Number(val || 0)
cb()
})
})
db.put('counter!foo', 1, function (err) {
db.put('counter!foo', 2, function (err) {
db.get('counter!foo', console.log) //3!
})
})
```
## API

@@ -105,14 +77,4 @@

### rm = db.hooks.async(range?, hook)
Async hooks are another kind of prehook that allow IO to happen
before the batch/put/del is processed.
Also, async hooked keys are processed strictly in series,
subsequent calls being queued until the previous call has returned.
This may be an issue for write heavy applications!
## License
MIT
var rimraf = require('rimraf')
var levelup = require('level-test')()
var levelup = require('levelup')

@@ -9,20 +9,21 @@ var Hooks = require('../')

var db = levelup('throw')
var dir ='/tmp/map-reduce-prehook-test'
Hooks(db)
rimraf(dir, function () {
levelup(dir, function (err, db) {
if(err) throw err
db.hooks.pre({min: 'a', max:'z'}, function (ch, add) {
add(ch) //this should cause an error
})
Hooks(db)
db.on('error', mac(function (err) {
assert.ok(err)
console.log('expect error:', err)
}).once())
db.hooks.pre({min: 'a', max:'z'}, function (ch, add) {
add(ch) //this should cause an error
})
db.put('c', 'whatever', mac(function (err) {
assert.ok(err)
console.log('expect error:', err)
}).once())
db.put('c', 'whatever', mac(function (err) {
assert.ok(err)
console.log('expect error:', err)
}).once())
})
})
var rimraf = require('rimraf')
var levelup = require('level-test')()
var levelup = require('levelup')

@@ -9,28 +9,34 @@ var hooks = require('..')

var db = levelup('map-reduce-intercept-test')
var dir ='/tmp/map-reduce-intercept-test'
rimraf(dir, function () {
levelup(dir, {createIfMissing: true}, function (err, db) {
hooks(db)
var _batch = []
//hook keys that start with a word character
db.hooks.pre(/^\w/, mac(function (ch, add) {
_batch.push(ch)
var a
add(a = {key: '~h', value: 'hello', type: 'put'})
_batch.push(a)
}).atLeast(1))
hooks(db)
var _batch = []
//hook keys that start with a word character
db.hooks.pre(/^\w/, mac(function (ch, add) {
_batch.push(ch)
var a
add(a = {key: '~h', value: 'hello', type: 'put'})
_batch.push(a)
}).atLeast(1))
//assert that it really became a batch
db.on('batch', mac(function (batch) {
console.log('batch', _batch)
assert.deepEqual(_batch, batch.map(function (e) {
return {key: ''+e.key, value: ''+ e.value, type: e.type}
}))
}).once())
//assert that it really became a batch
db.on('batch', mac(function (batch) {
console.log('batch', _batch)
assert.deepEqual(_batch, batch.map(function (e) {
return {key: ''+e.key, value: ''+ e.value, type: e.type}
}))
}).once())
db.put('hello' , 'whatever' , mac(function (){
db.put('hello' , 'whatever' , mac(function (){
}).once())
}).once())
})
})
var rimraf = require('rimraf')
var levelup = require('level-test')()
var levelup = require('levelup')

@@ -13,48 +13,52 @@ var Hooks = require('../')

var db = levelup('map-reduce-prehook-test')
rimraf(dir, function () {
levelup(dir, function (err, db) {
if(err) throw err
var SEQ = 0
var bucket = Bucket('prehook')
var SEQ = 0
var bucket = Bucket('prehook')
Hooks(db)
Hooks(db)
db.hooks.pre(/^\w/, mac(function (ch, add, batch) {
//iterate backwards so you can push without breaking stuff.
db.hooks.pre(/^\w/, mac(function (ch, add, batch) {
//iterate backwards so you can push without breaking stuff.
assert.ok(Array.isArray(batch))
assert.notEqual(batch.indexOf(ch), -1)
var key = ch.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('~seq'), value: new Buffer(SEQ.toString())})
assert.ok(Array.isArray(batch))
assert.notEqual(batch.indexOf(ch), -1)
var key = ch.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('~seq'), value: new Buffer(SEQ.toString())})
}).atLeast(1))
}).atLeast(1))
var n = 3
var n = 3
var next = mac(function () {
console.log('test', n)
if(--n) return
var next = mac(function () {
console.log('test', n)
if(--n) return
db.get('~seq', mac(function (err, val) {
console.log('seq=', ''+val)
assert.equal(Number(''+val), 3)
db.createReadStream({start: '~log~', end: '~log~~'})
.on('data', function (data) {
console.log(data.key.toString(), data.value.toString())
})
}).once())
}).times(3)
db.get('~seq', mac(function (err, val) {
console.log('seq=', ''+val)
assert.equal(Number(''+val), 3)
db.createReadStream({start: '~log~', end: '~log~~'})
.on('data', function (data) {
console.log(data.key.toString(), data.value.toString())
})
}).once())
}).times(3)
db.put('hello' , 'whatever' , next)
db.put('hi' , 'message' , next)
db.put('yoohoo', 'test 1, 2', next)
db.put('hello' , 'whatever' , next)
db.put('hi' , 'message' , next)
db.put('yoohoo', 'test 1, 2', next)
})
})
var rimraf = require('rimraf')
var levelup = require('level-test')()
var levelup = require('levelup')

@@ -10,94 +10,99 @@ var Hooks = require('../')

var dir ='/tmp/map-reduce-prehook-test'
var db = levelup('test-prehook2')
rimraf(dir, function () {
levelup(dir, function (err, db) {
if(err) throw err
var SEQ = 0, LOGSEQ = 0
var bucket = Bucket('prehook')
var SEQ = 0, LOGSEQ = 0
var bucket = Bucket('prehook')
Hooks(db)
Hooks(db)
db.hooks.pre(/^\w/, mac(function (ch, add) {
//iterate backwards so you can push without breaking stuff.
var key = ch.key
add({
type: 'put',
key: ++SEQ,
value: key.toString()
}, '~log~')
db.hooks.pre(/^\w/, mac(function (ch, add) {
//iterate backwards so you can push without breaking stuff.
var key = ch.key
add({
type: 'put',
key: ++SEQ,
value: key.toString()
}, '~log~')
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))
}).atLeast(1))
var removeLogHook = db.hooks.pre('~log', mac(function (ch, add) {
//iterate backwards so you can push without breaking stuff.
console.log('LOG2', ch)
var key = ch.key
add({
type: 'put',
key: ++LOGSEQ,
value: Date.now(),
prefix: '~LOGSEQ~'
})
var removeLogHook = db.hooks.pre('~log', mac(function (ch, add) {
//iterate backwards so you can push without breaking stuff.
console.log('LOG2', ch)
var key = ch.key
add({
type: 'put',
key: ++LOGSEQ,
value: Date.now(),
prefix: '~LOGSEQ~'
})
}).atLeast(1))
}).atLeast(1))
var n = 4
var n = 4
var next = mac(function () {
console.log('test', n)
if(--n) return
var next = mac(function () {
console.log('test', n)
if(--n) return
db.get('~seq', mac(function (err, val) {
console.log('seq=', ''+val)
assert.equal(Number(''+val), 4)
db.readStream({start: '~log~', end: '~log~~'})
.on('data', function (data) {
console.log(data.key.toString(), data.value.toString())
})
}).once())
db.get('~seq', mac(function (err, val) {
console.log('seq=', ''+val)
assert.equal(Number(''+val), 4)
db.readStream({start: '~log~', end: '~log~~'})
.on('data', function (data) {
console.log(data.key.toString(), data.value.toString())
})
}).once())
var all = {}
var all = {}
db.readStream()
.on('data', function (data) {
all[data.key.toString()] = data.value.toString()
})
.on('end', function () {
console.log(all)
db.readStream()
.on('data', function (data) {
all[data.key.toString()] = data.value.toString()
})
.on('end', function () {
console.log(all)
//these will be times, and will have changed.
delete all['~LOGSEQ~1']
delete all['~LOGSEQ~2']
delete all['~LOGSEQ~3']
//these will be times, and will have changed.
delete all['~LOGSEQ~1']
delete all['~LOGSEQ~2']
delete all['~LOGSEQ~3']
assert.deepEqual(all, {
hello: 'whatever',
hi: 'message',
thing: 'WHATEVER',
yoohoo: 'test 1, 2',
'~log~1': 'hello',
'~log~2': 'hi',
'~log~3': 'yoohoo',
'~log~4': 'thing',
'~seq': '4'
})
assert.deepEqual(all, {
hello: 'whatever',
hi: 'message',
thing: 'WHATEVER',
yoohoo: 'test 1, 2',
'~log~1': 'hello',
'~log~2': 'hi',
'~log~3': 'yoohoo',
'~log~4': 'thing',
'~seq': '4'
})
})
})
}).times(4)
}).times(4)
db.put('hello' , 'whatever' , next)
db.put('hi' , 'message' , next)
db.put('yoohoo', 'test 1, 2', next)
db.put('hello' , 'whatever' , next)
db.put('hi' , 'message' , next)
db.put('yoohoo', 'test 1, 2', next)
removeLogHook()
removeLogHook()
db.put('thing' , 'WHATEVER' , next)
db.put('thing' , 'WHATEVER' , next)
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc