Socket
Socket
Sign inDemoInstall

sane

Package Overview
Dependencies
6
Maintainers
1
Versions
58
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.2 to 0.1.0

80

index.js

@@ -43,5 +43,7 @@ var fs = require('fs');

this.watchers = [];
this.changeTimers = {};
this.watched = Object.create(null);
this.changeTimers = Object.create(null);
this.dir = dir
this.watchdir = this.watchdir.bind(this);
this.stopWatching = this.stopWatching.bind(this);
this.watchdir(dir);

@@ -61,10 +63,26 @@ recReaddir(dir, this.watchdir, this.emit.bind(this, 'ready'));

Watcher.prototype.watchdir = function(dir) {
var relativePath = path.relative(this.dir, dir);
var watcher = fs.watch(dir, function(event, filename) {
this.onChange(path.join(relativePath, filename));
}.bind(this));
this.watchers.push(watcher);
if (this.watched[dir]) return;
var watcher = fs.watch(
dir,
{ persistent: this.persistent },
this.processChange.bind(this, dir)
);
this.watched[dir] = watcher;
};
/**
* Stop watching a dir.s
*
* @param {string} dir
* @private
*/
Watcher.prototype.stopWatching = function(dir) {
if (this.watched[dir]) {
this.watched[dir].close();
this.watched[dir] = null;
}
};
/**
* End watching.

@@ -76,6 +94,3 @@ *

Watcher.prototype.close = function() {
var watchers = this.watchers;
for (var i = 0; i < watchers.length; i++) {
watchers[i].close();
}
Object.keys(this.watched).forEach(this.stopWatching);
this.removeAllListeners();

@@ -85,22 +100,47 @@ };

/**
* Triggers a 'change' event after debounding it to take care of duplicate
* events on os x.
* Process a change event.
*
* @private
* @param {string} dir
* @param {string} event
* @param {string} file
* @public
*/
Watcher.prototype.onChange = function(file) {
clearTimeout(this.changeTimers[file]);
this.changeTimers[file] = setTimeout(function() {
var globs = this.globs;
if (globs.length) {
Watcher.prototype.processChange = function(dir, event, file) {
var fullPath = path.join(dir, file);
var relativePath = path.join(path.relative(this.dir, dir), file);
fs.stat(fullPath, function(error, stat) {
if (error && error.code === 'ENOENT') {
this.stopWatching(fullPath);
return;
} else if (error) {
this.emit('error', error);
return;
} else if (stat.isDirectory()) {
this.watchdir(fullPath);
} else if (this.globs.length) {
var globs = this.globs;
for (var i = 0; i < globs.length; i++) {
if (minimatch(file, globs[i])) {
this.emit('change', file);
this.emitChange(relativePath);
}
}
} else {
this.emit('change', file);
this.emitChange(relativePath);
}
}.bind(this));
};
/**
* Triggers a 'change' event after debounding it to take care of duplicate
* events on os x.
*
* @private
*/
Watcher.prototype.emitChange = function(file) {
clearTimeout(this.changeTimers[file]);
this.changeTimers[file] = setTimeout(function() {
this.changeTimers[file] = null;
this.emit('change', file);
}.bind(this), 100);

@@ -107,0 +147,0 @@ };

{
"name": "sane",
"version": "0.0.2",
"version": "0.1.0",
"description": "Sane aims to be fast, small, and reliable file system watcher. No bells and whistles, just change events.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -0,1 +1,2 @@

var os = require('os');
var fs = require('fs');

@@ -7,3 +8,6 @@ var sane = require('../');

var testdir = '/private/tmp/sane_test';
var tmpdir = os.tmpdir();
var jo = path.join.bind(path);
var testdir = jo(tmpdir, 'sane_test');
before(function() {

@@ -15,4 +19,4 @@ rimraf.sync(testdir);

for (var i = 0; i < 10; i++) {
fs.writeFileSync(testdir + '/file_' + i, 'test_' + i);
var subdir = testdir + '/sub_' + i;
fs.writeFileSync(jo(testdir, 'file_' + i), 'test_' + i);
var subdir = jo(testdir, 'sub_' + i);
try {

@@ -22,3 +26,3 @@ fs.mkdirSync(subdir);

for (var j = 0; j < 10; j++) {
fs.writeFileSync(subdir + '/file_' + j, 'test_' + j);
fs.writeFileSync(jo(subdir, 'file_' + j), 'test_' + j);
}

@@ -42,3 +46,3 @@ }

it('change emits event', function(done) {
var testfile = testdir + '/file_1';
var testfile = jo(testdir, 'file_1');
this.watcher.on('change', function(filepath) {

@@ -54,3 +58,3 @@ assert.equal(filepath, path.relative(testdir, testfile));

it('emits change events for subdir files', function(done) {
var testfile = testdir + '/sub_1/file_1';
var testfile = jo(testdir, 'sub_1', 'file_1');
this.watcher.on('change', function(filepath) {

@@ -66,3 +70,3 @@ assert.equal(filepath, path.relative(testdir, testfile));

it('adding a file will trigger a change', function(done) {
var testfile = testdir + '/file_x' + Math.floor(Math.random() * 10000);
var testfile = jo(testdir, 'file_x' + Math.floor(Math.random() * 10000));
this.watcher.on('change', function(filepath) {

@@ -76,2 +80,35 @@ assert.equal(filepath, path.relative(testdir, testfile));

});
it('adding in a new subdir will trigger a change', function(done) {
var subdir = jo(testdir, 'sub_x' + Math.floor(Math.random() * 10000));
var testfile = jo(subdir, 'file_x' + Math.floor(Math.random() * 10000));
this.watcher.on('change', function(filepath) {
assert.equal(filepath, path.relative(testdir, testfile));
done();
});
this.watcher.on('ready', function() {
fs.mkdirSync(subdir);
defer(function() {
fs.writeFileSync(testfile, 'wow');
});
});
});
it('closes watchers when dirs are deleted', function(done) {
var subdir = jo(testdir, 'sub_1');
var testfile = jo(subdir, 'file_1');
this.watcher.on('change', function(filepath) {
assert.equal(filepath, path.relative(testdir, testfile));
done();
});
this.watcher.on('ready', function() {
rimraf.sync(subdir);
defer(function() {
fs.mkdirSync(subdir);
defer(function() {
fs.writeFileSync(testfile, 'wow');
});
});
});
});
});

@@ -95,8 +132,12 @@

this.watcher.on('ready', function() {
fs.writeFileSync(testdir + '/file_1', 'wow');
fs.writeFileSync(testdir + '/file_9', 'wow');
fs.writeFileSync(testdir + '/file_3', 'wow');
fs.writeFileSync(testdir + '/file_2', 'wow');
fs.writeFileSync(jo(testdir, 'file_1'), 'wow');
fs.writeFileSync(jo(testdir, 'file_9'), 'wow');
fs.writeFileSync(jo(testdir, 'file_3'), 'wow');
fs.writeFileSync(jo(testdir, 'file_2'), 'wow');
});
});
});
function defer(fn) {
setTimeout(fn, 300);
}
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