UNPKG

cache-storage

Version:

[ABANDONED] Advanced cache storage for node js

397 lines (372 loc) 12.8 kB
// Generated by CoffeeScript 1.6.3 (function() { var BaseStorage, Cache, Storage, async, isWindow, moment, path, _ref, __hasProp = {}.hasOwnProperty, __extends = 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; }; isWindow = typeof window === 'undefined' ? false : true; if (!isWindow) { path = require('path'); } BaseStorage = require('../Storage'); moment = require('moment'); Cache = require('../../Cache'); async = require('async'); Storage = (function(_super) { __extends(Storage, _super); function Storage() { _ref = Storage.__super__.constructor.apply(this, arguments); return _ref; } Storage.prototype.async = true; Storage.prototype.read = function(key, fn) { var _this = this; return this.getData(function(err, data) { if (err) { return fn(err, null); } else if (typeof data[key] === 'undefined') { return fn(null, null); } else { return _this.findMeta(key, function(err, meta) { if (err) { return fn(err, null); } else { return _this.verify(meta, function(err, state) { if (err) { return fn(err, null); } else if (state) { return fn(null, data[key]); } else { return _this.remove(key, function(err) { if (err) { return fn(err, null); } else { return fn(null, null); } }); } }); } }); } }); }; Storage.prototype.write = function(key, data, dependencies, fn) { var _this = this; if (dependencies == null) { dependencies = {}; } return this.getData(function(err, all) { if (err) { return fn(err); } else { all[key] = data; return _this.getMeta(function(err, meta) { if (err) { return fn(err); } else { meta[key] = dependencies; return _this.writeData(all, meta, fn); } }); } }); }; Storage.prototype.remove = function(key, fn) { var _this = this; return this.getData(function(err, data) { if (err) { return fn(err); } else { return _this.getMeta(function(err, meta) { if (err) { return fn(err); } else { if (typeof data[key] !== 'undefined') { delete data[key]; delete meta[key]; } return _this.writeData(data, meta, fn); } }); } }); }; Storage.prototype.removeAll = function(fn) { return this.writeData({}, {}, fn); }; Storage.prototype.clean = function(conditions, fn) { var keys, removeKeys, type, typeFn, _this = this; typeFn = Object.prototype.toString; type = typeFn.call(conditions); if (conditions === Cache.ALL) { this.removeAll(fn); } else if (type === '[object Object]') { if (typeof conditions[Cache.TAGS] === 'undefined') { conditions[Cache.TAGS] = []; } if (typeFn(conditions[Cache.TAGS]) === '[object String]') { conditions[Cache.TAGS] = [conditions[Cache.TAGS]]; } removeKeys = function(keys) { return async.eachSeries(keys, function(key, cb) { return _this.remove(key, function(err) { return cb(err); }); }, function(err) { return fn(err); }); }; keys = []; async.eachSeries(conditions[Cache.TAGS], function(tag, cb) { return _this.findKeysByTag(tag, function(err, _keys) { keys = keys.concat(_keys); return cb(err); }); }, function(err) { if (err) { return fn(err); } else if (typeof conditions[Cache.PRIORITY] === 'undefined') { return removeKeys(keys); } else { return _this.findKeysByPriority(conditions[Cache.PRIORITY], function(err, _keys) { if (err) { return fn(err); } else { keys = keys.concat(_keys); return removeKeys(keys); } }); } }); } else { fn(null); } return this; }; Storage.prototype.findMeta = function(key, fn) { return this.getMeta(function(err, meta) { if (err) { return fn(err, null); } else if (typeof meta[key] !== 'undefined') { return fn(null, meta[key]); } else { return fn(null, null); } }); }; Storage.prototype.findKeysByTag = function(tag, fn) { return this.getMeta(function(err, metas) { var key, meta, result; if (err) { return fn(err, null); } else { result = []; for (key in metas) { meta = metas[key]; if (typeof meta[Cache.TAGS] !== 'undefined' && meta[Cache.TAGS].indexOf(tag) !== -1) { result.push(key); } } return fn(null, result); } }); }; Storage.prototype.findKeysByPriority = function(priority, fn) { return this.getMeta(function(err, metas) { var key, meta, result; if (err) { return fn(err, null); } else { result = []; for (key in metas) { meta = metas[key]; if (typeof meta[Cache.PRIORITY] !== 'undefined' && meta[Cache.PRIORITY] <= priority) { result.push(key); } } return fn(null, result); } }); }; Storage.prototype.verify = function(meta, fn) { var typefn, _this = this; typefn = Object.prototype.toString; if (typefn.call(meta) === '[object Object]') { if (typeof meta[Cache.EXPIRE] !== 'undefined') { if (moment().valueOf() >= meta[Cache.EXPIRE]) { fn(null, false); return null; } } if (typeof meta[Cache.ITEMS] === 'undefined') { meta[Cache.ITEMS] = []; } return async.eachSeries(meta[Cache.ITEMS], function(item, cb) { return _this.findMeta(item, function(err, meta) { if (err) { fn(err, null); return cb(new Error('Fake error')); } else if (meta === null) { fn(null, false); return cb(new Error('Fake error')); } else if (meta !== null) { return _this.verify(meta, function(err, state) { if (err) { fn(err, null); return cb(new Error('Fake error')); } else if (state === false) { fn(null, false); return cb(new Error('Fake error')); } else { return cb(); } }); } else { return cb(); } }); }, function(err) { var file, files, mtime, time, _ref1, _ref2, _ref3; if (!err) { if (typeof meta[Cache.FILES] === 'undefined') { meta[Cache.FILES] = []; } _this.checkFilesSupport(); if (isWindow) { _ref1 = meta[Cache.FILES]; for (file in _ref1) { time = _ref1[file]; mtime = window.require.getStats(file).mtime; if (mtime === null) { throw new Error('File stats are disabled in your simq configuration. Can not get stats for ' + file + '.'); } if (window.require.getStats(file).mtime.getTime() !== time) { fn(null, false); return null; } } return fn(null, true); } else { files = []; _ref2 = meta[Cache.FILES]; for (file in _ref2) { time = _ref2[file]; _ref3 = meta[Cache.FILES]; for (file in _ref3) { time = _ref3[file]; files.push({ file: file, time: time }); } } return async.eachSeries(files, function(item, cb) { return Cache.getFs().stat(item.file, function(err, stats) { if (err) { return cb(err); } else { if ((new Date(stats.mtime)).getTime() !== item.time) { fn(null, false); return cb(new Error('Fake error')); } else { return cb(); } } }); }, function(err) { if (err && err.message === 'Fake error') { } else if (err) { return fn(err, null); } else { return fn(null, true); } }); } } }); } else { return fn(null, true); } }; Storage.prototype.parseDependencies = function(dependencies, fn) { var file, files, item, mtime, result, time, typefn, _i, _j, _len, _len1, _ref1, _ref2; typefn = Object.prototype.toString; result = {}; if (typefn.call(dependencies) === '[object Object]') { if (typeof dependencies[Cache.EXPIRE] !== 'undefined') { switch (typefn.call(dependencies[Cache.EXPIRE])) { case '[object String]': time = moment(dependencies[Cache.EXPIRE], Cache.TIME_FORMAT); break; case '[object Object]': time = moment().add(dependencies[Cache.EXPIRE]); break; default: throw new Error('Expire format is not valid'); } result[Cache.EXPIRE] = time.valueOf(); } if (typeof dependencies[Cache.ITEMS] !== 'undefined') { result[Cache.ITEMS] = []; _ref1 = dependencies[Cache.ITEMS]; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { item = _ref1[_i]; result[Cache.ITEMS].push(this.cache.generateKey(item)); } } if (typeof dependencies[Cache.PRIORITY] !== 'undefined') { result[Cache.PRIORITY] = dependencies[Cache.PRIORITY]; } if (typeof dependencies[Cache.TAGS] !== 'undefined') { result[Cache.TAGS] = dependencies[Cache.TAGS]; } if (typeof dependencies[Cache.FILES] !== 'undefined') { this.checkFilesSupport(); files = {}; if (isWindow) { _ref2 = dependencies[Cache.FILES]; for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { file = _ref2[_j]; mtime = window.require.getStats(file).mtime; if (mtime === null) { throw new Error('File stats are disabled in your simq configuration. Can not get stats for ' + file + '.'); } file = window.require.resolve(file); files[file] = mtime.getTime(); } result[Cache.FILES] = files; fn(null, result); } else { async.eachSeries(dependencies[Cache.FILES], function(file, cb) { file = path.resolve(file); return Cache.getFs().stat(file, function(err, stats) { if (err) { return cb(err); } else { files[file] = (new Date(stats.mtime)).getTime(); return cb(); } }); }, function(err) { if (err) { return fn(err, null); } else { result[Cache.FILES] = files; return fn(null, result); } }); } return result[Cache.FILES] = files; } else { return fn(null, result); } } else { return fn(null, result); } }; return Storage; })(BaseStorage); module.exports = Storage; }).call(this);