Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

stillframe

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

stillframe - npm Package Compare versions

Comparing version 0.0.3 to 0.1.0

142

lib/index.js

@@ -13,6 +13,6 @@ 'use strict';

if(!this instanceof Stillframe)
if (!this instanceof Stillframe)
return new Stillframe(config);
if(!store || !engines || !config)
if (!store || !engines || !config)
throw new Error('Missing required arguments.');

@@ -33,9 +33,9 @@

// lookup an entry in the cache manifest
Stillframe.prototype.lookup = function lookup(engineId, hash, timestamp, ttl, callback) {
Stillframe.prototype.lookup = function lookup(hash, timestamp, ttl, callback) {
return this.redis.eval(
lookupScript, 1, [this.config.prefix, engineId, hash].join(':'),
timestamp, // current request entry
timestamp - ttl, // oldest acceptable complete entry
timestamp - this.config.timeout, // oldest acceptable pending entry
timestamp + this.config.ttl, // entry expiration
lookupScript, 1, [this.config.prefix, hash].join(':'),
timestamp, // current request entry
timestamp - ttl, // oldest acceptable complete entry
timestamp - this.config.timeout, // oldest acceptable pending entry
timestamp + this.config.ttl, // entry expiration
callback

@@ -46,7 +46,7 @@ );

// resolve a pending entry in the cache manifest
Stillframe.prototype.resolve = function resolve(engineId, hash, timestamp, callback) {
Stillframe.prototype.resolve = function resolve(hash, timestamp, callback) {
return this.redis.eval(
resolveScript, 1, [this.config.prefix, engineId, hash].join(':'),
timestamp, // current request entry
timestamp + this.config.ttl, // entry expiration
resolveScript, 1, [this.config.prefix, hash].join(':'),
timestamp, // current request entry
timestamp + this.config.ttl, // entry expiration
callback

@@ -60,10 +60,13 @@ );

var switchboard = new stream.PassThrough();
process.nextTick(function(){
process.nextTick(function() {
// make sure the engine exists
if(!self.engines[engineId])
return error(new Error('The engine "' + engineId + '" does not exist.'));
var engine = self.engines[engineId];
if (!engine) return error(new Error('The engine "' + engineId + '" does not exist.'));
// generate the hash
var hash = hasher.sha1({request: request, options: options});
var hash = hasher.sha1({
request: request,
options: options
});

@@ -76,4 +79,3 @@ // get the timestamp for this transaction

function error(err) {
if(typeof callback === 'function') {
if (typeof callback === 'function') {
callback(err);

@@ -83,3 +85,3 @@

// an error if there are listeners
if(switchboard.listeners('error').length)
if (switchboard.listeners('error').length)
switchboard.emit('error', err);

@@ -90,9 +92,9 @@

function run(){
function run() {
// lookup hash in cache manifest
return self.lookup(engineId, hash, timestamp, ttl, function(err, entry){
if(err) return error(err);
return self.lookup(hash, timestamp, ttl, function(err, entry) {
var readStream, writeStream, buffer = new stream.PassThrough();
if (err) return error(err);
var engine = self.engines[engineId];

@@ -102,15 +104,47 @@

// a cache entry exists
if(typeof entry === 'string') {
if (typeof entry === 'string') {
entry = entry.split(':');
// callback with a snapshot
if(typeof callback === 'function')
callback(null, {status: entry[0], created: parseInt(entry[1], 10)});
if (typeof callback === 'function')
callback(null, {
status: entry[0],
created: parseInt(entry[1], 10)
});
// cache is complete
else if(entry[0] === 'complete')
self.store.fetch(engineId, engine, hash, parseInt(entry[1])).pipe(switchboard);
else if (entry[0] === 'complete') {
readStream = self.store.fetch(hash, parseInt(entry[1], 10));
readStream.pipe(buffer);
// cache is pending; wait and try again...
// read from store
readStream
.on('error', error)
// forward progress events
.on('progress', function(p) {
switchboard.emit('progress', p);
})
// start piping after metadata
.once('metadata', function(m) {
// forward metadata events
switchboard.emit('metadata', m);
// pipe to the switchboard
buffer.pipe(switchboard);
});
}
// TODO: instead of polling for completion, use redis pub/sub
// to listen for and emit progress updates, fetching the file
// once it's complete.
// cache is pending; wait and try again
else setTimeout(run, self.config.retry);

@@ -126,27 +160,36 @@ }

var readStream = engine.run(request, options);
var writeStream = self.store.save(engineId, engine, hash, timestamp, ttl);
// read from engineId
readStream = engine.run(request, options);
// read from engine
readStream
.on('error', function(e){
err = e; switchboard.emit('error', err);
.on('error', error)
// forward progress events
.on('progress', function(p) {
// TODO: write progress to redis entry and emit the progress
// update using redis pub/sub
switchboard.emit('progress', p);
})
// pipe to the switchboard
.pipe(switchboard)
// start piping after metadata
.once('metadata', function(m) {
// write to the store
.pipe(writeStream)
.on('error', function(e){
err = e; switchboard.emit('error', err);
// forward metadata events
switchboard.emit('metadata', m);
// write to the store
writeStream = self.store.save(hash, timestamp, m, ttl);
readStream.pipe(writeStream);
writeStream.on('error', error);
// pipe to the switchboard
readStream.pipe(switchboard);
})
// TODO: write any progress to redis
.on('progress', function(e){})
// resolve the cache manifest entry
.on('finish', function(){
if(!err) self.resolve(engineId, hash, timestamp, function(err){
if(err) switchboard.emit('error', err);
.on('finish', function() {
if (!err) self.resolve(hash, timestamp, function(err) {
if (err) switchboard.emit('error', err);
});

@@ -156,3 +199,6 @@ });

// callback with a snapshot
if(typeof callback === 'function') return callback(null, {status: 'pending', created: timestamp});
if (typeof callback === 'function') return callback(null, {
status: 'pending',
created: timestamp
});

@@ -159,0 +205,0 @@ }

{
"name": "stillframe",
"version": "0.0.3",
"version": "0.1.0",
"description": "A simple distributed url-to-whatever framework.",
"main": "./lib/index.js",
"scripts": {
"test": "istanbul cover mocha",
"test": "istanbul cover _mocha",
"test-ci": "istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls"

@@ -20,4 +20,3 @@ },

"istanbul": "^0.3.20",
"mocha": "^2.2.4",
"stillframe-store-file": "^1.0.0"
"mocha": "^2.2.4"
},

@@ -24,0 +23,0 @@ "dependencies": {

@@ -9,22 +9,27 @@ 'use strict';

// Stub Engine
// -----------
function EchoEngine(config) {
function StubEngine(config) {
this.config = config || {};
};
}
// run the generator
// @return instance of stream.Readable
EchoEngine.prototype.run = function run(request, options) {
StubEngine.prototype.run = function run(request, options) {
var s = new stream.PassThrough();
s.metadata = {
type: 'application/json',
extension: 'json'
};
// DIRTY: this timeout exists for testing purposes
setTimeout(function(){
// DIRTY: this timeout exists for testing purposes, which
// really isn't a good idea, but works in a pinch
setTimeout(function() {
s.emit('metadata', {
contentType: 'application/json'
});
}, 10);
setTimeout(function() {
s.end(JSON.stringify(request));
}, 50);
return s;

@@ -35,27 +40,72 @@ };

// Stub Store
// ----------
function StubStore(config) {
this.config = config || {};
this.data = {};
}
// fetch a file from cache
// @return instance of stream.Readable
StubStore.prototype.fetch = function fetch(hash, timestamp) {
var self = this;
var key = [hash, timestamp].join(':');
var s = new stream.PassThrough();
setTimeout(function() {
s.emit('metadata', self.data[key].metadata );
s.emit('data', self.data[key].data );
s.emit('end');
}, 10);
return s;
};
// save a file to cache
// @return instance of stream.Writable
StubStore.prototype.save = function save(hash, timestamp, metadata, ttl) {
var self = this;
var key = [hash, timestamp].join(':');
self.data[key] = {metadata: {}, data: ''};
var s = new stream.Writable();
s._write = function(chunk, encoding, callback) {
self.data[key].data += chunk;
callback();
};
return s;
};
var config = require('../config.test.js');
var Stillframe = require('../lib/index.js');
var redis = new (require('ioredis'))(config.redis);
var redis = new(require('ioredis'))(config.redis);
var assert = require('chai').assert;
var FileStore = require('stillframe-store-file');
var tmp = __dirname + '/../tmp';
describe('Stillframe', function(){
describe('Stillframe', function() {
before(clean);
describe('-> resolve', function(){
describe('-> resolve', function() {
var timestamp, stillframe;
before(function(){
before(function() {
timestamp = Date.now();
stillframe = new Stillframe(config, new FileStore({path: tmp}), {echo: new EchoEngine()});
stillframe = new Stillframe(config, new StubStore({
path: tmp
}), {
stub: new StubEngine()
});
});
describe('new entry', function(){
it('should return null', function(done){
stillframe.resolve('echo', '804e772c9acf31c5d9321c491d0e1628ea04d985', timestamp, function(err, res){
describe('new entry', function() {
it('should return null', function(done) {
stillframe.resolve('804e772c9acf31c5d9321c491d0e1628ea04d985', timestamp, function(err, res) {
assert.isNull(err);

@@ -67,4 +117,4 @@ assert.isNull(res);

it('should create a `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), 'complete', function(err, res){
it('should create a `complete` entry', function(done) {
redis.hget([config.prefix, '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -76,4 +126,4 @@ assert.equal(res, timestamp);

it('should not create a `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), 'pending', function(err, res){
it('should not create a `pending` entry', function(done) {
redis.hget([config.prefix, '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -85,6 +135,16 @@ assert.isNull(res);

it('should set an expiration for the entry', function(done){
getExpiration([config.prefix, 'echo', '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), function(err, res){
it('should set an expiration for the entry', function(done) {
// DIRTY: make Date.now deterministic; this might be better solved by wrapping the test in a with statement
var now = Date.now;
Date.now = function() {
return timestamp;
};
getExpiration([config.prefix, '804e772c9acf31c5d9321c491d0e1628ea04d985'].join(':'), function(err, res) {
assert.isNull(err);
assert.equal(res, timestamp + config.ttl);
// restore Date.now
Date.now = now;
done(err);

@@ -95,13 +155,13 @@ });

describe('existing entry', function(){
before(function(done){
redis.hset([config.prefix, 'echo', '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'complete', timestamp, done);
describe('existing entry', function() {
before(function(done) {
redis.hset([config.prefix, '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'complete', timestamp, done);
});
before(function(done){
redis.hset([config.prefix, 'echo', '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'pending', timestamp, done);
before(function(done) {
redis.hset([config.prefix, '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'pending', timestamp, done);
});
it('should return null for an existing key', function(done){
stillframe.resolve('echo', '95578ef733b8c68839469854a0f05e4e683c0a16', timestamp + 1000, function(err, res){
it('should return null for an existing key', function(done) {
stillframe.resolve('95578ef733b8c68839469854a0f05e4e683c0a16', timestamp + 1000, function(err, res) {
assert.isNull(err);

@@ -113,4 +173,4 @@ assert.isNull(res);

it('should update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'complete', function(err, res){
it('should update the `complete` entry', function(done) {
redis.hget([config.prefix, '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -122,4 +182,4 @@ assert.equal(res, timestamp + 1000);

it('should not update a `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'pending', function(err, res){
it('should not update a `pending` entry', function(done) {
redis.hget([config.prefix, '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -131,4 +191,4 @@ assert.equal(res, timestamp);

it('should update the expiration for the entry', function(done){
getExpiration([config.prefix, 'echo', '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), function(err, res){
it('should update the expiration for the entry', function(done) {
getExpiration([config.prefix, '95578ef733b8c68839469854a0f05e4e683c0a16'].join(':'), function(err, res) {
assert.isNull(err);

@@ -144,14 +204,18 @@ assert.equal(res, timestamp + 1000 + config.ttl);

describe('-> lookup', function(){
describe('-> lookup', function() {
var timestamp, ttl, stillframe;
before(function(){
before(function() {
timestamp = Date.now();
ttl = 1000*60*60;
stillframe = new Stillframe(config, new FileStore({path: tmp}), {echo: new EchoEngine()});
ttl = 1000 * 60 * 60;
stillframe = new Stillframe(config, new StubStore({
path: tmp
}), {
stub: new StubEngine()
});
});
describe('new entry', function(){
it('should return null', function(done){
stillframe.lookup('echo', 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c', timestamp, ttl, function(err, res){
describe('new entry', function() {
it('should return null', function(done) {
stillframe.lookup('b6589fc6ab0dc82cf12099d1c2d40ab994e8410c', timestamp, ttl, function(err, res) {
assert.isNull(err);

@@ -163,4 +227,4 @@ assert.isNull(res);

it('should create a `pending` entry', function(done){
redis.hget([config.prefix, 'echo', 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), 'pending', function(err, res){
it('should create a `pending` entry', function(done) {
redis.hget([config.prefix, 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -172,4 +236,4 @@ assert.equal(res, timestamp);

it('should not create a `complete` entry', function(done){
redis.hget([config.prefix, 'echo', 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), 'complete', function(err, res){
it('should not create a `complete` entry', function(done) {
redis.hget([config.prefix, 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -181,4 +245,4 @@ assert.isNull(res);

it('should set an expiration for the entry', function(done){
getExpiration([config.prefix, 'echo', 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), function(err, res){
it('should set an expiration for the entry', function(done) {
getExpiration([config.prefix, 'b6589fc6ab0dc82cf12099d1c2d40ab994e8410c'].join(':'), function(err, res) {
assert.isNull(err);

@@ -191,9 +255,9 @@ assert.equal(res, timestamp + config.ttl);

describe('pending entry - inside timeout', function(){
before(function(done){
redis.hset([config.prefix, 'echo', '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'pending', timestamp, done);
describe('pending entry - inside timeout', function() {
before(function(done) {
redis.hset([config.prefix, '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'pending', timestamp, done);
});
it('should return the pending entry', function(done){
stillframe.lookup('echo', '527d3f1d205d23678d303a0c52c98ec6e08b4e40', timestamp + 1, ttl, function(err, res){
it('should return the pending entry', function(done) {
stillframe.lookup('527d3f1d205d23678d303a0c52c98ec6e08b4e40', timestamp + 1, ttl, function(err, res) {
assert.isNull(err);

@@ -206,4 +270,4 @@ assert.isString(res);

it('should not update the `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'pending', function(err, res){
it('should not update the `pending` entry', function(done) {
redis.hget([config.prefix, '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -215,4 +279,4 @@ assert.equal(res, timestamp);

it('should not update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'complete', function(err, res){
it('should not update the `complete` entry', function(done) {
redis.hget([config.prefix, '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -224,4 +288,4 @@ assert.isNull(res);

it('should not update the entry expiration', function(done){
getExpiration([config.prefix, 'echo', '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), function(err, res){
it('should not update the entry expiration', function(done) {
getExpiration([config.prefix, '527d3f1d205d23678d303a0c52c98ec6e08b4e40'].join(':'), function(err, res) {
assert.isNull(err);

@@ -234,9 +298,9 @@ assert.isNull(res);

describe('pending entry - past timeout', function(){
before(function(done){
redis.hset([config.prefix, 'echo', '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'pending', timestamp, done);
describe('pending entry - past timeout', function() {
before(function(done) {
redis.hset([config.prefix, '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'pending', timestamp, done);
});
it('should return null', function(done){
stillframe.lookup('echo', '76512cc7766948303ecbf3f9f498cbfe49a4f15e', timestamp + config.timeout + 1, ttl, function(err, res){
it('should return null', function(done) {
stillframe.lookup('76512cc7766948303ecbf3f9f498cbfe49a4f15e', timestamp + config.timeout + 1, ttl, function(err, res) {
assert.isNull(err);

@@ -248,4 +312,4 @@ assert.isNull(res);

it('should update the `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'pending', function(err, res){
it('should update the `pending` entry', function(done) {
redis.hget([config.prefix, '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -257,4 +321,4 @@ assert.equal(res, timestamp + config.timeout + 1);

it('should not update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'complete', function(err, res){
it('should not update the `complete` entry', function(done) {
redis.hget([config.prefix, '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -266,4 +330,4 @@ assert.isNull(res);

it('should update the entry expiration', function(done){
getExpiration([config.prefix, 'echo', '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), function(err, res){
it('should update the entry expiration', function(done) {
getExpiration([config.prefix, '76512cc7766948303ecbf3f9f498cbfe49a4f15e'].join(':'), function(err, res) {
assert.isNull(err);

@@ -276,13 +340,13 @@ assert.equal(res, timestamp + config.timeout + 1 + config.ttl);

describe('complete entry - inside ttl', function(){
before(function(done){
redis.hset([config.prefix, 'echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'complete', timestamp, done);
describe('complete entry - inside ttl', function() {
before(function(done) {
redis.hset([config.prefix, '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'complete', timestamp, done);
});
before(function(done){
redis.hset([config.prefix, 'echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'pending', timestamp, done);
before(function(done) {
redis.hset([config.prefix, '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'pending', timestamp, done);
});
it('should return the complete entry', function(done){
stillframe.lookup('echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8', timestamp + 1, ttl, function(err, res){
it('should return the complete entry', function(done) {
stillframe.lookup('8c7925c217ce8a109c90e707085d2a7cb1f4b9b8', timestamp + 1, ttl, function(err, res) {
assert.isNull(err);

@@ -295,4 +359,4 @@ assert.isString(res);

it('should not update the `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'pending', function(err, res){
it('should not update the `pending` entry', function(done) {
redis.hget([config.prefix, '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -304,4 +368,4 @@ assert.equal(res, timestamp);

it('should not update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'complete', function(err, res){
it('should not update the `complete` entry', function(done) {
redis.hget([config.prefix, '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -313,4 +377,4 @@ assert.equal(res, timestamp);

it('should not update the entry expiration', function(done){
getExpiration([config.prefix, 'echo', '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), function(err, res){
it('should not update the entry expiration', function(done) {
getExpiration([config.prefix, '8c7925c217ce8a109c90e707085d2a7cb1f4b9b8'].join(':'), function(err, res) {
assert.isNull(err);

@@ -323,13 +387,13 @@ assert.isNull(res);

describe('complete entry - past ttl', function(){
before(function(done){
redis.hset([config.prefix, 'echo', '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'complete', timestamp, done);
describe('complete entry - past ttl', function() {
before(function(done) {
redis.hset([config.prefix, '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'complete', timestamp, done);
});
before(function(done){
redis.hset([config.prefix, 'echo', '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'pending', timestamp + ttl, done);
before(function(done) {
redis.hset([config.prefix, '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'pending', timestamp + ttl, done);
});
it('should return `pending` entry', function(done){
stillframe.lookup('echo', '24440aa30f1dc8a7adbc57c35c648e6616179859', timestamp + ttl + 1, ttl, function(err, res){
it('should return `pending` entry', function(done) {
stillframe.lookup('24440aa30f1dc8a7adbc57c35c648e6616179859', timestamp + ttl + 1, ttl, function(err, res) {
assert.isNull(err);

@@ -342,4 +406,4 @@ assert.isString(res);

it('should not update the `pending` entry', function(done){
redis.hget([config.prefix, 'echo', '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'pending', function(err, res){
it('should not update the `pending` entry', function(done) {
redis.hget([config.prefix, '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -351,4 +415,4 @@ assert.equal(res, timestamp + ttl);

it('should not update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'complete', function(err, res){
it('should not update the `complete` entry', function(done) {
redis.hget([config.prefix, '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -360,4 +424,4 @@ assert.equal(res, timestamp);

it('should not update the entry expiration', function(done){
getExpiration([config.prefix, 'echo', '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), function(err, res){
it('should not update the entry expiration', function(done) {
getExpiration([config.prefix, '24440aa30f1dc8a7adbc57c35c648e6616179859'].join(':'), function(err, res) {
assert.isNull(err);

@@ -370,13 +434,13 @@ assert.isNull(res);

describe('past complete ttl and pending timeout', function(){
before(function(done){
redis.hset([config.prefix, 'echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'complete', timestamp, done);
describe('past complete ttl and pending timeout', function() {
before(function(done) {
redis.hset([config.prefix, 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'complete', timestamp, done);
});
before(function(done){
redis.hset([config.prefix, 'echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'pending', timestamp, done);
before(function(done) {
redis.hset([config.prefix, 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'pending', timestamp, done);
});
it('should return null', function(done){
stillframe.lookup('echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1', timestamp + ttl + 1, ttl, function(err, res){
it('should return null', function(done) {
stillframe.lookup('b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1', timestamp + ttl + 1, ttl, function(err, res) {
assert.isNull(err);

@@ -388,4 +452,4 @@ assert.isNull(res);

it('should update the `pending` entry', function(done){
redis.hget([config.prefix, 'echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'pending', function(err, res){
it('should update the `pending` entry', function(done) {
redis.hget([config.prefix, 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'pending', function(err, res) {
assert.isNull(err);

@@ -397,4 +461,4 @@ assert.equal(res, timestamp + ttl + 1);

it('should not update the `complete` entry', function(done){
redis.hget([config.prefix, 'echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'complete', function(err, res){
it('should not update the `complete` entry', function(done) {
redis.hget([config.prefix, 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), 'complete', function(err, res) {
assert.isNull(err);

@@ -406,4 +470,4 @@ assert.equal(res, timestamp);

it('should update the entry expiration', function(done){
getExpiration([config.prefix, 'echo', 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), function(err, res){
it('should update the entry expiration', function(done) {
getExpiration([config.prefix, 'b1245eaa50fe4ef9ec31a993a2e9b4dacfa27ab1'].join(':'), function(err, res) {
assert.isNull(err);

@@ -420,14 +484,20 @@ assert.equal(res, timestamp + ttl + 1 + config.ttl);

describe('-> take', function(){
describe('-> take', function() {
var timestamp, ttl, stillframe;
before(function(){
before(function() {
timestamp = Date.now();
ttl = 1000*60*60;
stillframe = new Stillframe(config, new FileStore({path: tmp}), {echo: new EchoEngine()});
ttl = 1000 * 60 * 60;
stillframe = new Stillframe(config, new StubStore({
path: tmp
}), {
stub: new StubEngine()
});
});
describe('(callback)', function(done){
it('returns an error for a nonexistant engine', function(done){
stillframe.take('nonexistant', {url: 'http://www.example.com/callback'}, {}, ttl, function(err, snapshot){
describe('(callback)', function(done) {
it('returns an error for a nonexistant engine', function(done) {
stillframe.take('nonexistant', {
url: 'http://www.example.com/callback'
}, {}, ttl, function(err, snapshot) {
assert.instanceOf(err, Error);

@@ -438,10 +508,17 @@ done();

it('should return a new pending snapshot', function(done){
it('should return a new pending snapshot', function(done) {
// DIRTY: make Date.now deterministic; this might be better solved by wrapping the test in a with statement
var now = Date.now;
Date.now = function(){ return timestamp; };
Date.now = function() {
return timestamp;
};
stillframe.take('echo', {url: 'http://www.example.com/callback'}, {}, ttl, function(err, snapshot){
stillframe.take('stub', {
url: 'http://www.example.com/callback'
}, {}, ttl, function(err, snapshot) {
assert.isNull(err);
assert.deepEqual(snapshot, {status: 'pending', created: timestamp});
assert.deepEqual(snapshot, {
status: 'pending',
created: timestamp
});

@@ -455,7 +532,12 @@ // restore Date.now

it('should return an existing pending snapshot', function(done){
// DIRTY: the echo engine has a 5ms timeout
stillframe.take('echo', {url: 'http://www.example.com/callback'}, {}, ttl, function(err, snapshot){
it('should return an existing pending snapshot', function(done) {
// DIRTY: the stub engine has a 50ms timeout
stillframe.take('stub', {
url: 'http://www.example.com/callback'
}, {}, ttl, function(err, snapshot) {
assert.isNull(err);
assert.deepEqual(snapshot, {status: 'pending', created: timestamp});
assert.deepEqual(snapshot, {
status: 'pending',
created: timestamp
});
done();

@@ -465,8 +547,13 @@ });

it('should return an complete snapshot', function(done){
// DIRTY: the echo engine has a 5ms timeout
setTimeout(function(){
stillframe.take('echo', {url: 'http://www.example.com/callback'}, {}, ttl, function(err, snapshot){
it('should return an complete snapshot', function(done) {
// DIRTY: the stub engine has a 50ms timeout
setTimeout(function() {
stillframe.take('stub', {
url: 'http://www.example.com/callback'
}, {}, ttl, function(err, snapshot) {
assert.isNull(err);
assert.deepEqual(snapshot, {status: 'complete', created: timestamp});
assert.deepEqual(snapshot, {
status: 'complete',
created: timestamp
});
done();

@@ -479,60 +566,80 @@ });

describe('(stream)', function(done){
it('emits an error for a nonexistant engine', function(done){
stillframe.take('nonexistant', {url: 'http://www.example.com/stream'}, {}, ttl)
.on('error', function(err){
assert.instanceOf(err, Error);
done();
});
describe('(stream)', function(done) {
it('emits an error for a nonexistant engine', function(done) {
stillframe.take('nonexistant', {
url: 'http://www.example.com/stream'
}, {}, ttl)
.on('error', function(err) {
assert.instanceOf(err, Error);
done();
});
});
it('should return the final result of a new pending snapshot', function(done){
it('should return the final result of a new pending snapshot', function(done) {
// DIRTY: make Date.now deterministic; this might be better solved by wrapping the test in a with statement
var now = Date.now;
Date.now = function(){ return timestamp; };
Date.now = function() {
return timestamp;
};
var data = '';
stillframe.take('echo', {url: 'http://www.example.com/stream'}, {}, ttl)
.on('error', done)
.on('data', function(chunk){ data += chunk.toString(); })
.on('finish', function(){
assert.equal(data, '{"url":"http://www.example.com/stream"}');
stillframe.take('stub', {
url: 'http://www.example.com/stream'
}, {}, ttl)
.on('error', done)
.on('data', function(chunk) {
data += chunk.toString();
})
.on('finish', function() {
assert.equal(data, '{"url":"http://www.example.com/stream"}');
// restore Date.now
Date.now = now;
// restore Date.now
Date.now = now;
done();
});
done();
});
});
it('should return the final result of an existing pending snapshot', function(done){
it('should return the final result of an existing pending snapshot', function(done) {
// DIRTY: make Date.now deterministic; this might be better solved by wrapping the test in a with statement
var now = Date.now;
Date.now = function(){ return timestamp; };
Date.now = function() {
return timestamp;
};
var data = '';
stillframe.take('echo', {url: 'http://www.example.com/stream2'}, {}, ttl, function(err, snapshot){
stillframe.take('echo', {url: 'http://www.example.com/stream2'}, ttl)
.on('error', done)
.on('data', function(chunk){ data += chunk.toString(); })
.on('finish', function(){
assert.equal(data, '{"url":"http://www.example.com/stream2"}');
stillframe.take('stub', {
url: 'http://www.example.com/stream2'
}, {}, ttl, function(err, snapshot) {
stillframe.take('stub', {
url: 'http://www.example.com/stream2'
}, {}, ttl)
.on('error', done)
.on('data', function(chunk) {
data += chunk.toString();
})
.on('finish', function() {
assert.equal(data, '{"url":"http://www.example.com/stream2"}');
// restore Date.now
Date.now = now;
// restore Date.now
Date.now = now;
done();
});
done();
});
});
});
it('should return the final result of a complete snapshot', function(done){
it('should return the final result of a complete snapshot', function(done) {
var data = '';
stillframe.take('echo', {url: 'http://www.example.com/stream'}, {}, ttl)
.on('error', done)
.on('data', function(chunk){ data += chunk.toString(); })
.on('finish', function(){
assert.equal(data, '{"url":"http://www.example.com/stream"}');
done();
});
stillframe.take('stub', {
url: 'http://www.example.com/stream'
}, {}, ttl)
.on('error', done)
.on('data', function(chunk) {
data += chunk.toString();
})
.on('finish', function() {
assert.equal(data, '{"url":"http://www.example.com/stream"}');
done();
});
});

@@ -546,6 +653,6 @@ });

function deleteFolderRecursive(path) {
if( fs.existsSync(path) ) {
fs.readdirSync(path).forEach(function(file,index){
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(function(file, index) {
var curPath = path + '/' + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
if (fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);

@@ -565,5 +672,5 @@ } else { // delete file

function clean(callback){
function clean(callback) {
deleteFolderRecursive(tmp);
return redis.eval('local keys = redis.call(\'keys\', ARGV[1]) \n for i=1,#keys,5000 do \n redis.call(\'del\', unpack(keys, i, math.min(i+4999, #keys))) \n end \n return keys', 0, config.prefix, callback);
}

Sorry, the diff of this file is not supported yet

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