Socket
Socket
Sign inDemoInstall

level-ttl

Package Overview
Dependencies
10
Maintainers
2
Versions
25
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.2.0 to 3.0.0

145

level-ttl.js

@@ -1,23 +0,53 @@

const after = require('after')
, xtend = require('xtend')
, spaces = require('level-spaces')
const after = require('after')
, xtend = require('xtend')
, DEFAULT_FREQUENCY = 10000
, QUERY_SEPARATOR = 'x!'
function expirationKey (db, exp, key) {
var separator = db._ttl.options.separator
return queryStart(db) + exp + separator + key
}
function queryStart (db) {
return prefix(db) + QUERY_SEPARATOR
}
function prefix (db) {
if (db._ttl.sub)
return ''
var separator = db._ttl.options.separator
var namespace = db._ttl.options.namespace
return separator + namespace + separator
}
function startTtl (db, checkFrequency) {
db._ttl.intervalId = setInterval(function () {
var batch = []
, subBatch = []
, query = {
var batch = []
, subBatch = []
, start = queryStart(db)
, sub = db._ttl.sub
, query = {
keyEncoding: 'utf8'
, valueEncoding: 'utf8'
, end: String(Date.now())
, start: start
, end: start + String(Date.now()) + '~'
}
, createReadStream
db._ttl._checkInProgress = true
db._ttl.sub.createReadStream(query)
if (sub)
createReadStream = sub.createReadStream.bind(sub)
else
createReadStream = db.createReadStream.bind(db)
createReadStream(query)
.on('data', function (data) {
subBatch.push({ type: 'del', key: data.value })
// expirationKey that matches this query
subBatch.push({ type: 'del', key: data.key })
// the value is the key!
subBatch.push({ type: 'del', key: prefix(db) + data.value })
// the actual data that should expire now!
batch.push({ type: 'del', key: data.value })

@@ -27,4 +57,7 @@ })

.on('end', function () {
if (batch.length) {
db._ttl.sub.batch(
if (!batch.length)
return
if (sub) {
sub.batch(
subBatch

@@ -37,2 +70,3 @@ , { keyEncoding: 'utf8' }

)
db._ttl.batch(

@@ -47,2 +81,13 @@ batch

}
else {
db._ttl.batch(
subBatch.concat(batch)
, { keyEncoding: 'utf8' }
, function (err) {
if (err)
db.emit('error', err)
}
)
}
})

@@ -71,4 +116,6 @@ .on('close', function () {

function ttlon (db, keys, ttl, callback) {
var exp = String(Date.now() + ttl)
, batch = []
var exp = String(Date.now() + ttl)
, sub = db._ttl.sub
, batch = []
, batchFn = (sub ? sub.batch.bind(sub) : db._ttl.batch)

@@ -82,4 +129,4 @@ if (!Array.isArray(keys))

key = key.toString()
batch.push({ type: 'put', key: key , value: exp })
batch.push({ type: 'put', key: exp + '!' + key, value: key })
batch.push({ type: 'put', key: expirationKey(db, exp, key), value: key })
batch.push({ type: 'put', key: prefix(db) + key, value: exp })
})

@@ -90,3 +137,3 @@

db._ttl.sub.batch(
batchFn(
batch

@@ -107,4 +154,7 @@ , { keyEncoding: 'utf8', valueEncoding: 'utf8' }

var batch = []
, done = after(keys.length, function (err) {
var batch = []
, sub = db._ttl.sub
, getFn = (sub ? sub.get.bind(sub) : db.get.bind(db))
, batchFn = (sub ? sub.batch.bind(sub) : db._ttl.batch)
, done = after(keys.length, function (err) {
if (err)

@@ -116,3 +166,3 @@ db.emit('error', err)

db._ttl.sub.batch(
batchFn(
batch

@@ -132,9 +182,9 @@ , { keyEncoding: 'utf8', valueEncoding: 'utf8' }

db._ttl.sub.get(
key
getFn(
prefix(db) + key
, { keyEncoding: 'utf8', valueEncoding: 'utf8' }
, function (err, exp) {
if (!err && exp > 0) {
batch.push({ type: 'del', key: key })
batch.push({ type: 'del', key: exp + '!' + key })
batch.push({ type: 'del', key: expirationKey(db, exp, key) })
batch.push({ type: 'del', key: prefix(db) + key })
}

@@ -148,7 +198,17 @@ done(err && err.name != 'NotFoundError' && err)

function put (db, key, value, options, callback) {
var ttl
, done
if (typeof options == 'function') {
callback = options
options = {}
}
options = options || {}
if (db._ttl.options.defaultTTL > 0 && !options.ttl && options.ttl != 0) {
options.ttl = db._ttl.options.defaultTTL
}
var done
, _callback = callback
if (typeof options == 'object' && (ttl = options.ttl) > 0
if (options.ttl > 0
&& key !== null && key !== undefined

@@ -183,4 +243,14 @@ && value !== null && value !== undefined) {

function batch (db, arr, options, callback) {
var ttl
, done
if (typeof options == 'function') {
callback = options
options = {}
}
options = options || {}
if (db._ttl.options.defaultTTL > 0 && !options.ttl && options.ttl != 0) {
options.ttl = db._ttl.options.defaultTTL
}
var done
, on

@@ -190,3 +260,3 @@ , off

if (typeof options == 'object' && (ttl = options.ttl) > 0 && Array.isArray(arr)) {
if (options.ttl > 0 && Array.isArray(arr)) {
done = after(3, _callback || function () {})

@@ -234,18 +304,17 @@ callback = done

// backwards compatibility
if (!options.namespace && options.sublevel)
options.namespace = options.sublevel
options = xtend({
methodPrefix : ''
, namespace : 'ttl'
, separator : '!'
, checkFrequency : DEFAULT_FREQUENCY
, defaultTTL : 0
}, options)
db._ttl = {
put : db.put.bind(db)
, del : db.del.bind(db)
, batch : db.batch.bind(db)
, close : db.close.bind(db)
, sub : options.sub || spaces(db, options.namespace)
put : db.put.bind(db)
, del : db.del.bind(db)
, batch : db.batch.bind(db)
, close : db.close.bind(db)
, sub : options.sub
, options : options
}

@@ -252,0 +321,0 @@

@@ -7,5 +7,7 @@ {

"Matteo Collina <matteo.collina@gmail.com> (https://github.com/mcollina)",
"Josh Duff <me@JoshDuff.com> (https://github.com/TehShrike)"
"Josh Duff <me@JoshDuff.com> (https://github.com/TehShrike)",
"Erik Kristensen <erik@erikkristensen.com> (https://github.com/ekristen)",
"Lars-Magnus Skog <ralphtheninja@riseup.net> (https://github.com/ralphtheninja)"
],
"version": "2.2.0",
"version": "3.0.0",
"homepage": "https://github.com/rvagg/node-level-ttl",

@@ -29,3 +31,2 @@ "authors": [

"after": ">=0.8.1 <0.9.0-0",
"level-spaces": ">=1.1.1 <1.2.0-0",
"list-stream": ">=1.0.0 <1.1.0-0",

@@ -32,0 +33,0 @@ "xtend": ">=4.0.0 <4.1.0-0"

# Level TTL
![LevelDB Logo](https://twimg0-a.akamaihd.net/profile_images/3360574989/92fc472928b444980408147e5e5db2fa_bigger.png)
<img alt="LevelDB Logo" height="100" src="http://leveldb.org/img/logo.svg">

@@ -57,2 +57,15 @@ [![NPM](https://nodei.co/npm/level-ttl.png?downloads=true&downloadRank=true)](https://nodei.co/npm/level-ttl/)

### Default TTL
You can set a default ttl value for all your keys by passing the `'defaultTTL'` option to the `ttl()` initialiser. This can be overridden by explicitly setting the ttl value.
In the following examle `'foo'` will expire in 15 minutes while `'beep'` will expire in one minute.
```js
var db = level('/tmp/foo.db')
db = ttl(db, { defaultTTL: 15 * 60 * 1000 })
db.put('foo', 'bar', function (err) { /* .. */ })
db.put('beep', 'boop', { ttl: 60 * 1000 }, function (err) { /* .. */ })
```
### Shutting down

@@ -69,5 +82,7 @@

* [Josh Duff](https://github.com/TehShrike)
* [Erik Kristensen](https://github.com/ekristen)
* [Lars-Magnus Skog](https://github.com/ralphtheninja)
## Licence
Level TTL is Copyright (c) 2013 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licensed under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.
Level TTL is Copyright (c) 2013-2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licensed under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.

@@ -6,4 +6,4 @@ const test = require('tape')

, ttl = require('./')
, xtend = require('xtend')
function fixtape (t) {

@@ -15,4 +15,3 @@ t.like = function (str, reg, msg) {

function ltest (name, fn, opts) {
function ltest (name, fn, opts, ttl_opts) {
test(name, function (t) {

@@ -35,3 +34,3 @@ var location = '__ttl-' + Math.random()

var createReadStream = _db.createReadStream.bind(_db)
db = ttl(_db, { checkFrequency: 50 })
db = ttl(_db, xtend({ checkFrequency: 50 }, ttl_opts))

@@ -43,3 +42,2 @@ fn(db, t, createReadStream)

function db2arr (createReadStream, t, callback, opts) {

@@ -54,3 +52,2 @@ createReadStream(opts)

function contains (t, arr, key, value) {

@@ -71,3 +68,2 @@ for (var i = 0; i < arr.length; i++) {

// test that the standard API is working as it should

@@ -93,4 +89,5 @@ // kind of a lame test but we know they should throw

ts++
contains(t, arr, /\xffttl\xff\d{13}!bar/, 'bar')
contains(t, arr, '\xffttl\xffbar', /\d{13}/)
contains(t, arr, /!ttl!x!\d{13}!bar/, 'bar')
contains(t, arr, '!ttl!bar', /\d{13}/)
contains(t, arr, 'bar', 'barvalue')

@@ -113,3 +110,2 @@ contains(t, arr, 'foo', 'foovalue')

ltest('test multiple ttl entries with put', function (db, t, createReadStream) {

@@ -124,14 +120,14 @@ var expect = function (delay, keys) {

contains(t, arr, 'bar1', 'barvalue1')
contains(t, arr, /^\xffttl\xff\d{13}!bar1$/, 'bar1')
contains(t, arr, '\xffttl\xffbar1', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar1$/, 'bar1')
contains(t, arr, '!ttl!bar1', /^\d{13}$/)
}
if (keys >= 2) {
contains(t, arr, 'bar2', 'barvalue2')
contains(t, arr, /^\xffttl\xff\d{13}!bar2$/, 'bar2')
contains(t, arr, '\xffttl\xffbar2', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar2$/, 'bar2')
contains(t, arr, '!ttl!bar2', /^\d{13}$/)
}
if (keys >= 3) {
contains(t, arr, 'bar3', 'barvalue3')
contains(t, arr, /^\xffttl\xff\d{13}!bar3$/, 'bar3')
contains(t, arr, '\xffttl\xffbar3', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar3$/, 'bar3')
contains(t, arr, '!ttl!bar3', /^\d{13}$/)
}

@@ -143,15 +139,14 @@ })

db.put('afoo', 'foovalue')
db.put('bar1', 'barvalue1', { ttl: 180 })
db.put('bar2', 'barvalue2', { ttl: 120 })
db.put('bar3', 'barvalue3', { ttl: 60 })
db.put('bar1', 'barvalue1', { ttl: 400 })
db.put('bar2', 'barvalue2', { ttl: 250 })
db.put('bar3', 'barvalue3', { ttl: 100 })
expect(20, 3)
expect(110, 2)
expect(160, 1)
expect(210, 0)
expect(25, 3)
expect(150, 2)
expect(300, 1)
expect(450, 0)
setTimeout(t.end.bind(t), 275)
setTimeout(t.end.bind(t), 600)
})
ltest('test multiple ttl entries with batch-put', function (db, t, createReadStream) {

@@ -166,19 +161,19 @@ var expect = function (delay, keys) {

contains(t, arr, 'bar1', 'barvalue1')
contains(t, arr, /^\xffttl\xff\d{13}!bar1$/, 'bar1')
contains(t, arr, '\xffttl\xffbar1', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar1$/, 'bar1')
contains(t, arr, '!ttl!bar1', /^\d{13}$/)
}
if (keys >= 2) {
contains(t, arr, 'bar2', 'barvalue2')
contains(t, arr, /^\xffttl\xff\d{13}!bar2$/, 'bar2')
contains(t, arr, '\xffttl\xffbar2', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar2$/, 'bar2')
contains(t, arr, '!ttl!bar2', /^\d{13}$/)
}
if (keys >= 3) {
contains(t, arr, 'bar3', 'barvalue3')
contains(t, arr, /^\xffttl\xff\d{13}!bar3$/, 'bar3')
contains(t, arr, '\xffttl\xffbar3', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar3$/, 'bar3')
contains(t, arr, '!ttl!bar3', /^\d{13}$/)
}
if (keys >= 3) {
contains(t, arr, 'bar4', 'barvalue4')
contains(t, arr, /^\xffttl\xff\d{13}!bar4$/, 'bar4')
contains(t, arr, '\xffttl\xffbar4', /^\d{13}$/)
contains(t, arr, /^!ttl!x!\d{13}!bar4$/, 'bar4')
contains(t, arr, '!ttl!bar4', /^\d{13}$/)
}

@@ -204,6 +199,5 @@ })

ltest('test prolong entry life with additional put', function (db, t, createReadStream) {
var putBar = function () {
db.put('bar', 'barvalue', { ttl: 40 })
db.put('bar', 'barvalue', { ttl: 250 })
return Date.now()

@@ -225,4 +219,4 @@ }

contains(t, arr, 'foo', 'foovalue')
contains(t, arr, /\xffttl\xff\d{13}!bar/, 'bar')
contains(t, arr, '\xffttl\xffbar', /\d{13}/)
contains(t, arr, /!ttl!x!\d{13}!bar/, 'bar')
contains(t, arr, '!ttl!bar', /\d{13}/)
})

@@ -234,3 +228,3 @@ }, delay)

var base = putBar()
verify(base, 10)
verify(base, 50)
}, delay)

@@ -246,6 +240,5 @@ }

ltest('test prolong entry life with ttl(key, ttl)', function (db, t, createReadStream) {
var ttlBar = function () {
db.ttl('bar', 40)
db.ttl('bar', 250)
return Date.now()

@@ -267,4 +260,4 @@ }

contains(t, arr, 'foo', 'foovalue')
contains(t, arr, /\xffttl\xff\d{13}!bar/, 'bar')
contains(t, arr, '\xffttl\xffbar', /\d{13}/)
contains(t, arr, /!ttl!x!\d{13}!bar/, 'bar')
contains(t, arr, '!ttl!bar', /\d{13}/)
})

@@ -276,3 +269,3 @@ }, delay)

var base = ttlBar()
verify(base, 10)
verify(base, 25)
}, delay)

@@ -310,4 +303,4 @@ }

contains(t, arr, 'foo', 'foovalue')
contains(t, arr, /\xffttl\xff\d{13}!bar/, 'bar')
contains(t, arr, '\xffttl\xffbar', /\d{13}/)
contains(t, arr, /!ttl!x!\d{13}!bar/, 'bar')
contains(t, arr, '!ttl!bar', /\d{13}/)
}

@@ -321,10 +314,10 @@ })

base = Date.now()
db.put('bar', 'barvalue', { ttl: 200 })
verify(base, 20)
db.put('bar', 'barvalue', { ttl: 250 })
verify(base, 150)
setTimeout(function () {
db.del('bar')
}, 50)
}, 250)
// should not exist at all by 70
verify(-1, 70)
setTimeout(t.end.bind(t), 300)
verify(-1, 350)
setTimeout(t.end.bind(t), 550)
})

@@ -353,4 +346,4 @@

contains(t, arr, 'foo', '{"v":"foovalue"}')
contains(t, arr, /\xffttl\xff\d{13}!bar/, 'bar')
contains(t, arr, '\xffttl\xffbar', /\d{13}/)
contains(t, arr, /!ttl!x!\d{13}!bar/, 'bar')
contains(t, arr, '!ttl!bar', /\d{13}/)
}

@@ -364,10 +357,10 @@ }, { valueEncoding: 'utf8' })

base = Date.now()
db.put('bar', { v: 'barvalue' }, { ttl: 200 })
verify(base, 20)
db.put('bar', { v: 'barvalue' }, { ttl: 250 })
verify(base, 50)
setTimeout(function () {
db.del('bar')
}, 50)
}, 175)
// should not exist at all by 70
verify(-1, 70)
setTimeout(t.end.bind(t), 300)
verify(-1, 350)
setTimeout(t.end.bind(t), 550)
}, { keyEncoding: 'utf8', valueEncoding: 'json' })

@@ -402,3 +395,3 @@

db.put( 'foo', 'bar1', { ttl: 10 })
db.put( 'foo', 'bar1', { ttl: 25 })
setTimeout(function () {

@@ -409,3 +402,3 @@ db.get('foo', function (err, value) {

})
}, 10)
}, 40)
setTimeout(function () {

@@ -417,3 +410,3 @@ db.get('foo', function (err, value) {

})
}, 60)
}, 80)
setTimeout(function () {

@@ -429,6 +422,116 @@ db.stop(function () {

})
}, 80)
}, 120)
})
})
ltest('single put with default ttl set', function (db, t, createReadStream) {
db.put('foo', 'bar1', function(err) {
t.ok(!err, 'no error')
setTimeout(function () {
db.get('foo', function (err, value) {
t.notOk(err, 'no error')
t.equal('bar1', value)
})
}, 50)
setTimeout(function () {
db.get('foo', function (err, value) {
t.ok(err, 'got error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
})
}, 125)
})
setTimeout(t.end.bind(t), 175)
}, {}, { defaultTTL: 75 } )
ltest('single put with overridden ttl set', function (db, t, createReadStream) {
db.put('foo', 'bar1', { ttl: 99 }, function(err) {
t.ok(!err, 'no error')
setTimeout(function () {
db.get('foo', function (err, value) {
t.notOk(err, 'no error')
t.equal('bar1', value)
})
}, 50)
setTimeout(function () {
db.get('foo', function (err, value) {
t.ok(err, 'got error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
})
}, 125)
})
setTimeout(t.end.bind(t), 175)
}, {}, { defaultTTL: 75 } )
ltest('batch put with default ttl set', function (db, t, createReadStream) {
db.batch([
{ type: 'put', key: 'foo', value: 'bar1' },
{ type: 'put', key: 'bar', value: 'foo1' }
], function(err) {
t.ok(!err, 'no error')
setTimeout(function () {
db.get('foo', function (err, value) {
t.notOk(err, 'no error')
t.equal('bar1', value)
db.get('bar', function(err, value) {
t.notOk(err, 'no error')
t.equal('foo1', value)
})
})
}, 50)
setTimeout(function () {
db.get('foo', function (err, value) {
t.ok(err, 'got error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
db.get('bar', function(err, value) {
t.ok(err, 'no error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
})
})
}, 125)
})
setTimeout(t.end.bind(t), 175)
}, {}, { defaultTTL: 75 })
ltest('batch put with overriden ttl set', function (db, t, createReadStream) {
db.batch([
{ type: 'put', key: 'foo', value: 'bar1' },
{ type: 'put', key: 'bar', value: 'foo1' }
], { ttl: 99 }, function(err) {
setTimeout(function () {
db.get('foo', function (err, value) {
t.notOk(err, 'no error')
t.equal('bar1', value)
db.get('bar', function(err, value) {
t.notOk(err, 'no error')
t.equal('foo1', value)
})
})
}, 50)
setTimeout(function () {
db.get('foo', function (err, value) {
t.ok(err, 'got error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
db.get('bar', function(err, value) {
t.ok(err, 'no error')
t.ok(err.notFound, 'not found error')
t.notOk(value, 'no value')
})
})
}, 125)
})
setTimeout(t.end.bind(t), 175)
}, {}, { defaultTTL: 75 })
test('without options', function (t) {

@@ -435,0 +538,0 @@ var location = '__ttl-' + Math.random()

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc