kopia lustrzana https://github.com/c9/core
add watcher support to vfs mock
rodzic
e8ba27ec67
commit
d22f15a549
|
@ -16,8 +16,10 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
var fsData = {};
|
var fsData = {};
|
||||||
|
|
||||||
|
var pathLib = require("path");
|
||||||
var Stream = require("stream").Stream;
|
var Stream = require("stream").Stream;
|
||||||
var basename = require("path").basename;
|
var basename = require("path").basename;
|
||||||
|
var EventEmitter = require("events").EventEmitter;
|
||||||
var noop = function() { console.error("not implemented"); };
|
var noop = function() { console.error("not implemented"); };
|
||||||
var silent = function() {};
|
var silent = function() {};
|
||||||
var connection = {};
|
var connection = {};
|
||||||
|
@ -57,14 +59,14 @@ define(function(require, exports, module) {
|
||||||
prev = data;
|
prev = data;
|
||||||
data = data["!" + parts[i]];
|
data = data["!" + parts[i]];
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
if (create && typeof prev != "string")
|
if (create && !isFile(prev))
|
||||||
data = prev["!" + parts[i]] = {};
|
data = prev["!" + parts[i]] = {};
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (val)
|
if (val != null)
|
||||||
data = prev["!" + parts[parts.length - 1]] = val;
|
data = prev["!" + parts[parts.length - 1]] = { v: val, t: Date.now() };
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +76,14 @@ define(function(require, exports, module) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isFile(node) {
|
||||||
|
return typeof node == "string" || node && node.v != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileConets(node) {
|
||||||
|
return typeof node == "string" ? node : node && node.v;
|
||||||
|
}
|
||||||
|
|
||||||
function sendStream(data, callback) {
|
function sendStream(data, callback) {
|
||||||
var stream = new Stream();
|
var stream = new Stream();
|
||||||
stream.readable = true;
|
stream.readable = true;
|
||||||
|
@ -88,6 +98,22 @@ define(function(require, exports, module) {
|
||||||
stream.emit("end");
|
stream.emit("end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readStream(callback) {
|
||||||
|
return function(err, meta) {
|
||||||
|
if (err) return callback(err);
|
||||||
|
var buffer = [];
|
||||||
|
meta.stream.on("data", function(data) {
|
||||||
|
if (typeof data == "string")
|
||||||
|
buffer += data;
|
||||||
|
else
|
||||||
|
buffer = buffer.concat(data);
|
||||||
|
});
|
||||||
|
meta.stream.on("end", function() {
|
||||||
|
callback(null, buffer);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function readBlob(blob, callback) {
|
function readBlob(blob, callback) {
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function() {
|
reader.onload = function() {
|
||||||
|
@ -99,6 +125,37 @@ define(function(require, exports, module) {
|
||||||
reader.readAsText(blob);
|
reader.readAsText(blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var watcher = new EventEmitter();
|
||||||
|
watcher.addChange = function(path) {
|
||||||
|
plugin.stat(path, {}, function(err, stat) {
|
||||||
|
var dir = pathLib.dirname(path);
|
||||||
|
var name = pathLib.basename(path);
|
||||||
|
plugin.readdir(dir, {}, readStream(function(e, stats) {
|
||||||
|
watcher.emit(dir, "directory", name, stat, stats);
|
||||||
|
}));
|
||||||
|
watcher.emit(path, err ? "delete" : "change", name, stat);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
watcher.watch = function(path, options, callback) {
|
||||||
|
if (!callback) callback = options;
|
||||||
|
setTimeout(function() {
|
||||||
|
var w = new EventEmitter();
|
||||||
|
var sendEvent = function(event, filename, stat, files) {
|
||||||
|
w.emit("change", event, filename, stat, files);
|
||||||
|
};
|
||||||
|
watcher.on(path, sendEvent);
|
||||||
|
w.close = function() {
|
||||||
|
watcher.off(path, sendEvent);
|
||||||
|
};
|
||||||
|
callback(null, { watcher: w });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
watcher.unwatch = function(path, options, callback) {
|
||||||
|
if (!callback) callback = options;
|
||||||
|
watcher.removeAllListeners(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
plugin.on("load", load);
|
plugin.on("load", load);
|
||||||
plugin.on("unload", unload);
|
plugin.on("unload", unload);
|
||||||
|
|
||||||
|
@ -146,10 +203,10 @@ define(function(require, exports, module) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var data = findNode(path);
|
var data = findNode(path);
|
||||||
if (typeof data !== "string")
|
if (!isFile(data))
|
||||||
return console.error("not implemented");
|
return console.error("not implemented");
|
||||||
var a = document.createElement('a');
|
var a = document.createElement('a');
|
||||||
a.href = URL.createObjectURL(new Blob([data], { type: "text/plain" }));
|
a.href = URL.createObjectURL(new Blob([fileConets(data)], { type: "text/plain" }));
|
||||||
a.download = filename || basename(path);
|
a.download = filename || basename(path);
|
||||||
|
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
|
@ -169,13 +226,14 @@ define(function(require, exports, module) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
var isFile = typeof data == "string";
|
var value = fileConets(data);
|
||||||
|
var isFileNode = value != null;
|
||||||
var stat = {
|
var stat = {
|
||||||
name: name.substr(1),
|
name: name,
|
||||||
size: isFile ? data.length : 1,
|
size: isFileNode ? value.length : 1,
|
||||||
mtime: 0,
|
mtime: data.t || 0,
|
||||||
ctime: 0,
|
ctime: data.ct || data.t || 0,
|
||||||
mime: isFile ? "" : "folder"
|
mime: isFileNode ? "" : "folder"
|
||||||
};
|
};
|
||||||
callback(null, stat);
|
callback(null, stat);
|
||||||
}, 20);
|
}, 20);
|
||||||
|
@ -183,23 +241,25 @@ define(function(require, exports, module) {
|
||||||
readfile: function(path, options, callback) {
|
readfile: function(path, options, callback) {
|
||||||
var data = findNode(path);
|
var data = findNode(path);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (typeof data != "string")
|
var value = fileConets(data);
|
||||||
|
if (value == null)
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
sendStream(data, callback);
|
sendStream(value, callback);
|
||||||
}, 20);
|
}, 20);
|
||||||
},
|
},
|
||||||
readdir: function(path, options, callback) {
|
readdir: function(path, options, callback) {
|
||||||
var data = findNode(path);
|
var data = findNode(path);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!data || typeof data == "string")
|
if (!data || isFile(data))
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
var stats = Object.keys(data).map(function(n) {
|
var stats = Object.keys(data).map(function(n) {
|
||||||
var isFile = typeof data[n] == "string";
|
var value = fileConets(data[n]);
|
||||||
|
var isFile = value != null;
|
||||||
return {
|
return {
|
||||||
name: n.substr(1),
|
name: n.substr(1),
|
||||||
size: isFile ? data[n].length : 1,
|
size: isFile ? value.length : 1,
|
||||||
mtime: 0,
|
mtime: data[n].t || 0,
|
||||||
ctime: 0,
|
ctime: data[n].ct || data[n].t,
|
||||||
mime: isFile ? "" : "folder"
|
mime: isFile ? "" : "folder"
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -217,18 +277,22 @@ define(function(require, exports, module) {
|
||||||
options.stream.on("end", function(e) {
|
options.stream.on("end", function(e) {
|
||||||
if (e) val += e;
|
if (e) val += e;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!parent || typeof parent[name] == "object")
|
if (!parent)
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
parent[name] = val;
|
if (parent[name] && !isFile(parent[name]))
|
||||||
|
return callback(new Error("EISDIR"));
|
||||||
|
parent[name] = { v: val, t: Date.now() };
|
||||||
|
watcher.addChange(path);
|
||||||
callback(null);
|
callback(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
mkdir: function(path, options, callback) {
|
mkdir: function(path, options, callback) {
|
||||||
var data = findNode(path, true);
|
var data = findNode(path, true);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!data)
|
if (!data)
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
|
watcher.addChange(path);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -237,6 +301,7 @@ define(function(require, exports, module) {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!data)
|
if (!data)
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
|
watcher.addChange(path);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -248,9 +313,10 @@ define(function(require, exports, module) {
|
||||||
var parent = findNode(parts.join("/"));
|
var parent = findNode(parts.join("/"));
|
||||||
if (!parent || !parent[name])
|
if (!parent || !parent[name])
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
if (typeof parent[name] != "string")
|
if (!isFile(parent[name]))
|
||||||
return callback(new Error("EISDIR"));
|
return callback(new Error("EISDIR"));
|
||||||
delete parent[name];
|
delete parent[name];
|
||||||
|
watcher.addChange(path);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -261,9 +327,10 @@ define(function(require, exports, module) {
|
||||||
var parent = findNode(parts.join("/"));
|
var parent = findNode(parts.join("/"));
|
||||||
if (!parent || !parent[name])
|
if (!parent || !parent[name])
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
if (typeof parent[name] == "string")
|
if (isFile(parent[name]))
|
||||||
return callback(new Error("EISFILE"));
|
return callback(new Error("EISFILE"));
|
||||||
delete parent[name];
|
delete parent[name];
|
||||||
|
watcher.addChange(path);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -284,6 +351,8 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
toParent[toName] = fromParent[fromName];
|
toParent[toName] = fromParent[fromName];
|
||||||
delete fromParent[fromName];
|
delete fromParent[fromName];
|
||||||
|
watcher.addChange(from);
|
||||||
|
watcher.addChange(to);
|
||||||
callback(null);
|
callback(null);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -306,7 +375,8 @@ define(function(require, exports, module) {
|
||||||
|
|
||||||
toParent[toName] = fromParent[fromName];
|
toParent[toName] = fromParent[fromName];
|
||||||
toParts.push(toName.substr(1));
|
toParts.push(toName.substr(1));
|
||||||
callback(null, {to: toParts.join("/")});
|
watcher.addChange(to);
|
||||||
|
callback(null, { to: toParts.join("/") });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
chmod: noop,
|
chmod: noop,
|
||||||
|
@ -329,17 +399,17 @@ define(function(require, exports, module) {
|
||||||
readFileWithMetadata: function(path, options, callback) {
|
readFileWithMetadata: function(path, options, callback) {
|
||||||
var data = findNode(path);
|
var data = findNode(path);
|
||||||
var metadata = findNode("/.c9/metadata" + path);
|
var metadata = findNode("/.c9/metadata" + path);
|
||||||
setTimeout(function() {
|
var timer = setTimeout(function() {
|
||||||
if (typeof data != "string")
|
if (!isFile(data))
|
||||||
return callback(ENOENT());
|
return callback(ENOENT());
|
||||||
// TODO metadata
|
callback(null, fileConets(data), fileConets(metadata));
|
||||||
callback(null, data, metadata);
|
|
||||||
});
|
});
|
||||||
return { abort: function() {} };
|
return { abort: function() { clearTimeout(timer); } };
|
||||||
},
|
},
|
||||||
|
|
||||||
// Wrapper around fs.watch or fs.watchFile
|
// Wrapper around fs.watch or fs.watchFile
|
||||||
watch: silent,
|
watch: watcher.watch,
|
||||||
|
unwatch: watcher.unwatch,
|
||||||
|
|
||||||
// Network connection
|
// Network connection
|
||||||
connect: noop,
|
connect: noop,
|
||||||
|
|
Ładowanie…
Reference in New Issue