fobject
Version:
A simple promise-based wrapper for file operations that treats files as objects.
197 lines (157 loc) • 5.16 kB
JavaScript
// Generated by CoffeeScript 1.10.0
var CachedFile, File, W,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
File = require('./');
W = require('when');
CachedFile = (function(superClass) {
extend(CachedFile, superClass);
/**
* The encoding of the file. Used as a default for `File.read` and
* `File.write`.
*/
CachedFile.prototype.encoding = void 0;
/**
* The content of the file. Can be modified directly and if it is edited
File.save() will be needed to persist the changes on disk.
* @type {String}
*/
CachedFile.prototype.content = '';
/**
* The content loaded from the disk (cannot be modified because we need this
when saving to avoid needing to re-read the file).
* @type {String}
* @private
*/
CachedFile.prototype._savedContent = void 0;
/**
* The time at which the file was last loaded. Used to determine if we are
overwriting new data.
* @type {Integer}
* @private
*/
CachedFile.prototype._loadTime = void 0;
/**
* @param {String|null} [options.encoding='utf8']
*/
function CachedFile(path, options) {
var ref;
if (options == null) {
options = {};
}
this.encoding = (ref = options.encoding) != null ? ref : 'utf8';
CachedFile.__super__.constructor.call(this, path, options);
}
/**
* Read from the file
* @param {String} [options.flag='r']
* @return {Promise}
*/
CachedFile.prototype.read = function(options) {
if (options == null) {
options = {};
}
options.encoding = this.encoding;
return CachedFile.__super__.read.call(this, options);
};
/**
* Write `data` to the file
* @param {String|Buffer} data
* @param {Number} [options.mode=438] default is 0666 in Octal
* @param {String} [options.flag='w']
* @return {Promise}
*/
CachedFile.prototype.write = function(data, options) {
if (options == null) {
options = {};
}
options.encoding = this.encoding;
return CachedFile.__super__.write.call(this, data, options);
};
/**
* Append `data` to the file
* @param {String|Buffer} data
* @param {Number} [options.mode=438] default is 0666 in Octal
* @param {String} [options.flag='w']
* @return {Promise}
*/
CachedFile.prototype.append = function(data, options) {
if (options == null) {
options = {};
}
options.encoding = this.encoding;
return CachedFile.__super__.append.call(this, data, options);
};
/**
* Check the file mod-time to see if the file has been edited since the last
time we loaded it. Also, make sure that we've loaded the file.
* @return {Promise}
*/
CachedFile.prototype._isFileNewerOnDisk = function() {
return this.stat().then((function(_this) {
return function(stat) {
return (_this._loadTime != null) && stat.mtime > _this._loadTime;
};
})(this));
};
/**
* Write CachedFile.content to the disk, using optimizations like appending
rather than overwriting entirely.
* @param {Boolean} [overwrite=true] Even if the file has been modified since
the last load, overwrite it.
* @return {Promise}
*/
CachedFile.prototype.save = function(overwrite) {
var promise;
if (overwrite == null) {
overwrite = true;
}
promise = W.resolve();
if (!overwrite) {
promise.then(this._isFileNewerOnDisk).then(function(isFileNewerOnDisk) {
if (isFileNewerOnDisk) {
throw new Error('File has been modified since last load');
}
});
}
return promise.then((function(_this) {
return function() {
if ((_this._savedContent != null) && _this.content.slice(0, _this._savedContent.length) === _this._savedContent) {
if (!overwrite) {
return _this.append(_this.content.slice(_this._savedContent.length));
} else {
return _this._isFileNewerOnDisk().then(function(isFileNewerOnDisk) {
if (isFileNewerOnDisk) {
return _this.write(_this.content);
} else {
return _this.append(_this.content.slice(_this._savedContent.length));
}
});
}
} else {
return _this.write(_this.content);
}
};
})(this)).then((function(_this) {
return function() {
_this._loadTime = Date.now();
_this._savedContent = _this.content;
};
})(this));
};
/**
* Load the file from the disk, overwriting anything in CachedFile.content
* @return {Promise}
*/
CachedFile.prototype.load = function() {
return this.read().then((function(_this) {
return function(data) {
var _loadTime;
_loadTime = Date.now();
return _this._savedContent = _this.content = data;
};
})(this));
};
return CachedFile;
})(File);
module.exports = CachedFile;