UNPKG

caslet

Version:

A simple content addressable system

195 lines (168 loc) 5.32 kB
// Generated by CoffeeScript 1.4.0 (function() { var FSCas, crypto, filelet, fs, funclet, loglet, path, uuid, _; loglet = require('loglet'); fs = require('fs'); path = require('path'); crypto = require('crypto'); uuid = require('node-uuid'); funclet = require('funclet'); filelet = require('filelet'); _ = require('underscore'); FSCas = (function() { FSCas.initialize = function(options, cb) { var cas, defaultOpts; defaultOpts = { baseDir: path.join(process.env.HOME, '.caslet') }; options = _.extend({}, defaultOpts, options); cas = new this(options); return cas.initialize(cb); }; function FSCas(options) { this.options = options; this.pathsDir = path.join(this.options.baseDir, 'paths'); this.contentsDir = path.join(this.options.baseDir, 'contents'); this.tempDir = path.join(this.options.baseDir, 'temp'); this.cache = {}; } FSCas.prototype.initialize = function(cb) { var _this = this; return funclet.each([this.pathsDir, this.contentsDir, this.tempDir], function(dirPath, next) { return filelet.mkdirp(dirPath, next); })["catch"](cb).done(function() { return cb(null, _this); }); }; FSCas.prototype.get = function(option, cb) { if (option.path) { return this._getViaPath(option.path, cb); } else if (option.hash) { return this._getViaHash(option.hash, cb); } else { return cb({ error: 'invalid_argument', args: [option] }); } }; FSCas.prototype._getViaPath = function(pathsPath, cb) { var _this = this; if (this.cache.hasOwnProperty(pathsPath)) { return this._getViaHash(this.cache[pathsPath].hash, cb); } else { return funclet.start(function(next) { var normalized; normalized = _this._pathsFilePath(pathsPath); return fs.readFile(normalized, 'utf8', next); })["catch"](cb).done(function(data) { var parsed; parsed = JSON.parse(data); _this.cache[pathsPath] = parsed; return _this._getViaHash(parsed.hash, cb); }); } }; FSCas.prototype._getViaHash = function(hash, cb) { var hashPath, stream; try { hashPath = this._hashFilePath(hash); stream = fs.createReadStream(hashPath); return cb(null, stream); } catch (e) { return cb(e); } }; FSCas.prototype.store = function(instream, cb) { var digest, outstream, tempFilePath, _this = this; try { tempFilePath = this._tempFilePath(); digest = crypto.createHash('sha1'); digest.setEncoding('hex'); outstream = fs.createWriteStream(tempFilePath); instream.once('close', function() { var hash; try { digest.end(); outstream.end(); hash = digest.read(); instream.close(); outstream.close(); return _this._moveTempFile(tempFilePath, hash, cb); } catch (e) { return cb(e); } }); instream.once('error', cb); outstream.once('error', cb); digest.once('error', cb); instream.pipe(digest); return instream.pipe(outstream); } catch (e) { instream.close(); outstream.close(); return cb(e); } }; FSCas.prototype.storeWithPath = function(instream, destPath, cb) { var hash, _this = this; hash = null; return funclet.start(function(next) { return _this.store(instream, next); }).then(function(val, next) { hash = val; return _this._storePathMapping(hash, destPath, next); })["catch"](cb).done(function() { return cb(null, hash); }); }; FSCas.prototype._storePathMapping = function(hash, destPath, cb) { var normalizedPath, result, _this = this; normalizedPath = this._pathsFilePath(destPath); result = { type: 'fs', hash: hash }; return filelet.writeFile(normalizedPath, JSON.stringify(result, null, 2), 'utf8', function(err) { if (err) { return cb(err); } else { _this.cache[destPath] = result; return cb(null); } }); }; FSCas.prototype._moveTempFile = function(tempFilePath, hash, cb) { var hashPath; try { hashPath = this._hashFilePath(hash); return filelet.move(tempFilePath, hashPath, function(err) { if (err) { return cb(err); } else { return cb(null, hash); } }); } catch (e) { return cb(e); } }; FSCas.prototype._tempFilePath = function() { return path.join(this.tempDir, uuid.v4()); }; FSCas.prototype._pathsFilePath = function(filePath) { return path.join(this.pathsDir, filePath); }; FSCas.prototype._hashFilePath = function(hash) { var fileName, parentDir; parentDir = hash.substring(0, 3); fileName = hash.substring(3); return path.join(this.contentsDir, parentDir, fileName); }; return FSCas; })(); module.exports = FSCas; }).call(this);