UNPKG

fobject

Version:

A simple promise-based wrapper for file operations that treats files as objects.

197 lines (157 loc) 5.16 kB
// 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;