fs-write-stream-atomic
Advanced tools
Comparing version 1.0.4 to 1.0.5
38
index.js
var fs = require('graceful-fs') | ||
var util = require('util') | ||
var crypto = require('crypto') | ||
var MurmurHash3 = require('imurmurhash') | ||
function md5hex () { | ||
var hash = crypto.createHash('md5') | ||
for (var ii=0; ii<arguments.length; ++ii) { | ||
hash.update(''+arguments[ii]) | ||
function murmurhex () { | ||
var hash = MurmurHash3('') | ||
for (var ii = 0; ii < arguments.length; ++ii) { | ||
hash.hash(hash + arguments[ii]) | ||
} | ||
return hash.digest('hex') | ||
return hash.result() | ||
} | ||
var invocations = 0; | ||
var invocations = 0 | ||
function getTmpname (filename) { | ||
return filename + "." + md5hex(__filename, process.pid, ++invocations) | ||
return filename + '.' + murmurhex(__filename, process.pid, ++invocations) | ||
} | ||
@@ -22,7 +22,7 @@ | ||
function WriteStream (path, options) { | ||
if (!options) | ||
options = {} | ||
if (!options) options = {} | ||
if (!(this instanceof WriteStream)) | ||
if (!(this instanceof WriteStream)) { | ||
return new WriteStream(path, options) | ||
} | ||
@@ -53,7 +53,7 @@ this.__atomicTarget = path | ||
WriteStream.prototype.emit = function (ev) { | ||
if (ev === 'error') | ||
cleanupSync.call(this) | ||
if (ev === 'error') cleanupSync.call(this) | ||
if (ev !== 'close' && ev !== 'finish') | ||
if (ev !== 'close' && ev !== 'finish') { | ||
return fs.WriteStream.prototype.emit.apply(this, arguments) | ||
} | ||
@@ -64,4 +64,3 @@ // We handle emitting finish and close after the rename. | ||
atomicDoStuff.call(this, function (er) { | ||
if (er) | ||
cleanup.call(this, er) | ||
if (er) cleanup.call(this, er) | ||
}.bind(this)) | ||
@@ -72,5 +71,6 @@ } | ||
function atomicDoStuff(cb) { | ||
if (this.__atomicDidStuff) | ||
function atomicDoStuff (cb) { | ||
if (this.__atomicDidStuff) { | ||
throw new Error('Already did atomic move-into-place') | ||
} | ||
@@ -96,3 +96,3 @@ this.__atomicDidStuff = true | ||
fs.WriteStream.prototype.emit.call(this, 'finish') | ||
process.nextTick(function() { | ||
process.nextTick(function () { | ||
fs.WriteStream.prototype.emit.call(this, 'close') | ||
@@ -99,0 +99,0 @@ }.bind(this)) |
{ | ||
"name": "fs-write-stream-atomic", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "Like `fs.createWriteStream(...)`, but atomic.", | ||
@@ -10,9 +10,11 @@ "main": "index.js", | ||
"dependencies": { | ||
"graceful-fs": "^4.1.2" | ||
"graceful-fs": "^4.1.2", | ||
"imurmurhash": "^0.1.4" | ||
}, | ||
"devDependencies": { | ||
"tap": "^1.2.0" | ||
"standard": "^5.4.1", | ||
"tap": "^2.3.1" | ||
}, | ||
"scripts": { | ||
"test": "tap test/*.js" | ||
"test": "standard && tap --coverage test/*.js" | ||
}, | ||
@@ -19,0 +21,0 @@ "repository": { |
@@ -22,27 +22,29 @@ var test = require('tap').test | ||
var verifierCalled = 0 | ||
function verifier (ev) { return function () { | ||
if (ev === 'close') | ||
t.equal(this.__emittedFinish, true) | ||
else { | ||
this.__emittedFinish = true | ||
t.equal(ev, 'finish') | ||
} | ||
function verifier (ev) { | ||
return function () { | ||
if (ev === 'close') { | ||
t.equal(this.__emittedFinish, true) | ||
} else { | ||
this.__emittedFinish = true | ||
t.equal(ev, 'finish') | ||
} | ||
// make sure that one of the atomic streams won. | ||
var res = fs.readFileSync(target, 'utf8') | ||
var lines = res.trim().split(/\n/) | ||
lines.forEach(function (line) { | ||
var first = lines[0].match(/\d+$/)[0] | ||
var cur = line.match(/\d+$/)[0] | ||
t.equal(cur, first) | ||
}) | ||
// make sure that one of the atomic streams won. | ||
var res = fs.readFileSync(target, 'utf8') | ||
var lines = res.trim().split(/\n/) | ||
lines.forEach(function (line) { | ||
var first = lines[0].match(/\d+$/)[0] | ||
var cur = line.match(/\d+$/)[0] | ||
t.equal(cur, first) | ||
}) | ||
var resExpr = /^first write \d+\nsecond write \d+\nthird write \d+\nfinal write \d+\n$/ | ||
t.similar(res, resExpr) | ||
var resExpr = /^first write \d+\nsecond write \d+\nthird write \d+\nfinal write \d+\n$/ | ||
t.similar(res, resExpr) | ||
// should be called once for each close, and each finish | ||
if (++verifierCalled === n * 2) { | ||
t.end() | ||
// should be called once for each close, and each finish | ||
if (++verifierCalled === n * 2) { | ||
t.end() | ||
} | ||
} | ||
}} | ||
} | ||
@@ -49,0 +51,0 @@ // now write something to each stream. |
@@ -5,3 +5,3 @@ var path = require('path') | ||
function repeat(times, string) { | ||
function repeat (times, string) { | ||
var output = '' | ||
@@ -14,5 +14,11 @@ for (var ii = 0; ii < times; ++ii) { | ||
var target = path.resolve(__dirname, repeat(1000,'test')) | ||
var target = path.resolve(__dirname, repeat(1000, 'test')) | ||
test('name too long', function (t) { | ||
// 0.8 streams smh | ||
if (process.version.indexOf('v0.8') !== -1) { | ||
t.plan(1) | ||
} else { | ||
t.plan(2) | ||
} | ||
var stream = writeStream(target) | ||
@@ -22,3 +28,3 @@ var hadError = false | ||
if (!hadError) { | ||
t.is(er.code, 'ENAMETOOLONG', target.length + " character name results in ENAMETOOLONG") | ||
t.is(er.code, 'ENAMETOOLONG', target.length + ' character name results in ENAMETOOLONG') | ||
hadError = true | ||
@@ -28,5 +34,5 @@ } | ||
stream.on('close', function () { | ||
t.end() | ||
t.ok(hadError, 'got error before close') | ||
}) | ||
stream.end() | ||
}) |
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
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
8433
8
190
2
2
+ Addedimurmurhash@^0.1.4
+ Addedimurmurhash@0.1.4(transitive)