level-ttl
Advanced tools
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. |
225
test.js
@@ -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() |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
33232
3
755
87
1
- Removedlevel-spaces@>=1.1.1 <1.2.0-0
- Removedabstract-leveldown@0.12.41.0.0(transitive)
- Removedbl@0.8.2(transitive)
- Removeddeferred-leveldown@0.2.0(transitive)
- Removederrno@0.1.8(transitive)
- Removedexternr@1.0.0(transitive)
- Removedisarray@0.0.1(transitive)
- Removedlevel-spaces@1.1.1(transitive)
- Removedlevel-updown@1.1.1(transitive)
- Removedlevelup@0.18.6(transitive)
- Removedprr@0.0.01.0.1(transitive)
- Removedreadable-stream@1.0.34(transitive)
- Removedsemver@2.3.2(transitive)
- Removedxtend@3.0.0(transitive)