115 lines
2.3 KiB
JavaScript
115 lines
2.3 KiB
JavaScript
var fs = require('fs');
|
|
var os = require('os');
|
|
var path = require('path');
|
|
var is = require('./is');
|
|
|
|
var IS_SUPPORT;
|
|
var TEMP_DIR = os.tmpdir && os.tmpdir()
|
|
|| process.env.TMPDIR
|
|
|| process.env.TEMP
|
|
|| process.cwd();
|
|
|
|
function TempStack() {
|
|
this.stack = [];
|
|
}
|
|
|
|
TempStack.prototype = {
|
|
create: function(type, base) {
|
|
var name = path.join(base,
|
|
'node-watch-' + Math.random().toString(16).substr(2)
|
|
);
|
|
this.stack.push({ name: name, type: type });
|
|
return name;
|
|
},
|
|
write: function(/* file */) {
|
|
for (var i = 0; i < arguments.length; ++i) {
|
|
fs.writeFileSync(arguments[i], ' ');
|
|
}
|
|
},
|
|
mkdir: function(/* dirs */) {
|
|
for (var i = 0; i < arguments.length; ++i) {
|
|
fs.mkdirSync(arguments[i]);
|
|
}
|
|
},
|
|
cleanup: function(fn) {
|
|
try {
|
|
var temp;
|
|
while ((temp = this.stack.pop())) {
|
|
var type = temp.type;
|
|
var name = temp.name;
|
|
if (type === 'file' && is.file(name)) {
|
|
fs.unlinkSync(name);
|
|
}
|
|
else if (type === 'dir' && is.directory(name)) {
|
|
fs.rmdirSync(name);
|
|
}
|
|
}
|
|
}
|
|
finally {
|
|
if (is.func(fn)) fn();
|
|
}
|
|
}
|
|
};
|
|
|
|
var pending = false;
|
|
|
|
module.exports = function hasNativeRecursive(fn) {
|
|
if (!is.func(fn)) {
|
|
return false;
|
|
}
|
|
if (IS_SUPPORT !== undefined) {
|
|
return fn(IS_SUPPORT);
|
|
}
|
|
|
|
if (!pending) {
|
|
pending = true;
|
|
}
|
|
// check again later
|
|
else {
|
|
return setTimeout(function() {
|
|
hasNativeRecursive(fn);
|
|
}, 300);
|
|
}
|
|
|
|
var stack = new TempStack();
|
|
var parent = stack.create('dir', TEMP_DIR);
|
|
var child = stack.create('dir', parent);
|
|
var file = stack.create('file', child);
|
|
|
|
stack.mkdir(parent, child);
|
|
|
|
var options = { recursive: true };
|
|
var watcher;
|
|
|
|
try {
|
|
watcher = fs.watch(parent, options);
|
|
} catch (e) {
|
|
if (e.code == 'ERR_FEATURE_UNAVAILABLE_ON_PLATFORM') {
|
|
return fn(IS_SUPPORT = false);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
if (!watcher) {
|
|
return false;
|
|
}
|
|
|
|
var timer = setTimeout(function() {
|
|
watcher.close();
|
|
stack.cleanup(function() {
|
|
fn(IS_SUPPORT = false);
|
|
});
|
|
}, 200);
|
|
|
|
watcher.on('change', function(evt, name) {
|
|
if (path.basename(file) === path.basename(name)) {
|
|
watcher.close();
|
|
clearTimeout(timer);
|
|
stack.cleanup(function() {
|
|
fn(IS_SUPPORT = true);
|
|
});
|
|
}
|
|
});
|
|
stack.write(file);
|
|
}
|