Comparing version 0.2.1 to 0.3.0
22
index.js
@@ -7,9 +7,6 @@ var fs = require('fs') | ||
this.filename = filename | ||
this._callbacks = [] | ||
} | ||
Writer.prototype.setCallback = function(callback) { | ||
this.callback = callback | ||
} | ||
Writer.prototype.callback = function(err, data, next) { | ||
Writer.prototype._callback = function(err, data, next) { | ||
if (err) throw err | ||
@@ -19,7 +16,12 @@ next() | ||
Writer.prototype.write = function(data) { | ||
Writer.prototype.setCallback = function(cb) { | ||
this._callback = cb | ||
} | ||
Writer.prototype.write = function(data, cb) { | ||
if (this.lock) { | ||
this.next = data | ||
if (cb) this._callbacks.push(cb) | ||
@@ -42,3 +44,9 @@ } else { | ||
self.callback(err, data, next) | ||
self._callback(err, data, next) | ||
var c | ||
while (c = self._callbacks.shift()) { | ||
c(err) | ||
} | ||
if (cb) cb(err) | ||
}) | ||
@@ -45,0 +53,0 @@ |
{ | ||
"name": "steno", | ||
"version": "0.2.1", | ||
"description": "File writer", | ||
"version": "0.3.0", | ||
"description": "Fast non-blocking file writer for Node", | ||
"main": "index.js", | ||
@@ -20,3 +20,5 @@ "scripts": { | ||
"synchronous", | ||
"stenograph" | ||
"race", | ||
"condition", | ||
"safe" | ||
], | ||
@@ -30,3 +32,3 @@ "author": "typicode", | ||
"devDependencies": { | ||
"husky": "^0.6.1", | ||
"husky": "^0.6.2", | ||
"tap-dot": "^0.2.3", | ||
@@ -33,0 +35,0 @@ "tape": "^3.0.1" |
@@ -1,11 +0,35 @@ | ||
# steno [![Build Status](https://travis-ci.org/typicode/steno.svg?branch=master)](https://travis-ci.org/typicode/steno) [![npm version](https://badge.fury.io/js/steno.svg)](http://badge.fury.io/js/steno) | ||
# steno [![](https://badge.fury.io/js/steno.svg)](http://badge.fury.io/js/steno) [![](https://travis-ci.org/typicode/steno.svg?branch=master)](https://travis-ci.org/typicode/steno) | ||
> Super fast non-blocking file writer for Node | ||
> Fast and safe non-blocking file writer for Node | ||
```javascript | ||
var steno = require('steno') | ||
steno('file.txt').write('data') | ||
``` | ||
## Example | ||
If you need to write to file, you either use `writeFileSync` or `writeFile`. The first is blocking and the second doesn't prevent race condition. | ||
For example: | ||
```javascript | ||
var steno = require('steno') | ||
// Very slow but file's content will always be 10000 | ||
for (var i = 0; i < 10000; i++) { | ||
fs.writeFileSync('file.txt', i) | ||
} | ||
``` | ||
```javascript | ||
// Very fast but file's content may be 5896, 2563, 9856, ... | ||
for (var i = 0; i < 10000; i++) { | ||
fs.writeFile('file.txt', i, function() {}) | ||
} | ||
``` | ||
With steno: | ||
```javascript | ||
// Very fast and file's content will always be 10000 | ||
for (var i = 0; i < 10000; i++) { | ||
steno('file.txt').write(i) | ||
@@ -15,3 +39,3 @@ } | ||
This code runs in `2ms` versus `~5500ms` with `fs.writeFileSync`. | ||
Also, it will run in `2ms` versus `~5500ms` with `fs.writeFileSync`. | ||
@@ -23,6 +47,10 @@ ## How it works | ||
steno('file.txt').write('B') // still writing A, B is buffered | ||
steno('file.txt').write('C') // still writing A, C replaces B | ||
// A has been written to file, starts writting C (B is skipped) | ||
steno('file.txt').write('C') // still writing A, B is replaced by C | ||
// ... | ||
// A has been written to file | ||
// starts writting C (B has been skipped) | ||
``` | ||
When file is being written, data is stored in memory and flushed to disk as soon as possible. Please note also that steno skips intermediate data (B in this example). | ||
## Methods | ||
@@ -34,16 +62,13 @@ | ||
__writer.write(data)__ | ||
__writer.write(data, [cb])__ | ||
Writes data to file. If file is already being written, data is buffered until it can be written. | ||
Writes data to file. If file is already being written, data is buffered until it can be written. An optional callback can also be set to be notified when data has been written to disk. | ||
__writer.setCallback(cb)__ | ||
Sets a callback. Useful for creating atomic writers, logging, delaying, ... | ||
Sets a writer level callback that is called just after file has been written. Useful for creating atomic writers, logging, delaying, ... | ||
```javascript | ||
var atomic = steno('tmp-file.txt').setCallback(function(err, data, next) { | ||
// Writing is stopped until next is called | ||
var atomicWriter = steno('tmp-file.txt').setCallback(function(err, data, next) { | ||
if (err) throw err | ||
fs.rename('tmp-file.txt', 'file.txt', function(err) { | ||
@@ -55,17 +80,7 @@ if (err) throw err | ||
atomic.write('Hello world') | ||
atomicWriter.write('Hello world') | ||
``` | ||
## Properties | ||
__writer.lock__ | ||
`true` if file is being written. | ||
__writer.next__ | ||
`null` when there's no more data waiting to be written to file. | ||
## License | ||
MIT - [Typicode](https://github.com/typicode) |
28
test.js
@@ -12,3 +12,3 @@ var fs = require('fs') | ||
test('steno without callback', function(t) { | ||
test('writer without callback', function(t) { | ||
reset() | ||
@@ -26,16 +26,21 @@ t.plan(1) | ||
test('steno default callback', function(t) { | ||
test('writer default callback', function(t) { | ||
reset() | ||
t.plan(2) | ||
writer.callback(null, '', function() { | ||
// default callback should call function next | ||
// when err is null | ||
var err = null | ||
var next = function() { | ||
t.pass('next was called') | ||
}) | ||
} | ||
writer._callback(err, '', next) | ||
// default callback should throw an error | ||
t.throws(function() { | ||
writer.callback(new Error()) | ||
writer._callback(new Error()) | ||
}) | ||
}) | ||
test('steno with callback', function(t) { | ||
test('writer with callback', function(t) { | ||
reset() | ||
@@ -56,3 +61,3 @@ t.plan(1) | ||
test('steno error with callback', function(t) { | ||
test('writer error with callback', function(t) { | ||
reset() | ||
@@ -69,1 +74,10 @@ t.plan(1) | ||
}) | ||
test('write callback', function(t) { | ||
reset() | ||
t.plan(3) | ||
writer.write('A', t.false) | ||
writer.write('B', t.false) | ||
writer.write('C', t.false) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7172
126
83