cache-storage
Version:
[ABANDONED] Advanced cache storage for node js
322 lines (265 loc) • 7.02 kB
text/coffeescript
isWindow = if typeof window == 'undefined' then false else true
if !isWindow
path = require 'path'
BaseStorage = require '../Storage'
moment = require 'moment'
Cache = require '../../Cache'
async = require 'async'
class Storage extends BaseStorage
async: true
read: (key, fn) ->
write: (key, data, dependencies = {}, fn) ->
remove: (key, fn) ->
removeAll: (fn) ->
clean: (conditions, fn) ->
typeFn = Object.prototype.toString
type = typeFn.call(conditions)
if conditions == Cache.ALL
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 = (keys) =>
async.eachSeries(keys, (key, cb) =>
, (err) ->
fn(err)
)
keys = []
async.eachSeries(conditions[Cache.TAGS], (tag, cb) =>
, (err) =>
if err
fn(err)
else if typeof conditions[Cache.PRIORITY] == 'undefined'
removeKeys(keys)
else
)
else
fn(null)
return @
findMeta: (key, fn) ->
findKeysByTag: (tag, fn) ->
findKeysByPriority: (priority, fn) ->
verify: (meta, fn) ->
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] = []
async.eachSeries(meta[Cache.ITEMS], (item, cb) =>
, (err) =>
if !err
if typeof meta[Cache.FILES] == 'undefined'
meta[Cache.FILES] = []
if isWindow
for file, time of meta[Cache.FILES]
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
fn(null, true)
else
files = []
for file, time of meta[Cache.FILES]
files.push(file: file, time: time) for file, time of meta[Cache.FILES]
async.eachSeries(files, (item, cb) =>
Cache.getFs().stat(item.file, (err, stats) ->
if err
cb(err)
else
if (new Date(stats.mtime)).getTime() != item.time
fn(null, false)
cb(new Error 'Fake error')
else
cb()
)
, (err) ->
if err && err.message == 'Fake error'
# skip
else if err
fn(err, null)
else
fn(null, true)
)
)
else
fn(null, true)
parseDependencies: (dependencies, fn) ->
typefn = Object.prototype.toString
result = {}
if typefn.call(dependencies) == '[object Object]'
if typeof dependencies[Cache.EXPIRE] != 'undefined'
switch typefn.call(dependencies[Cache.EXPIRE])
when '[object String]'
time = moment(dependencies[Cache.EXPIRE], Cache.TIME_FORMAT)
when '[object Object]'
time = moment().add(dependencies[Cache.EXPIRE])
else
throw new Error 'Expire format is not valid'
result[Cache.EXPIRE] = time.valueOf()
if typeof dependencies[Cache.ITEMS] != 'undefined'
result[Cache.ITEMS] = []
for item in dependencies[Cache.ITEMS]
result[Cache.ITEMS].push(.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'
files = {}
if isWindow
for file in dependencies[Cache.FILES]
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], (file, cb) ->
file = path.resolve(file)
Cache.getFs().stat(file, (err, stats) ->
if err
cb(err)
else
files[file] = (new Date(stats.mtime)).getTime()
cb()
)
, (err) ->
if err
fn(err, null)
else
result[Cache.FILES] = files
fn(null, result)
)
result[Cache.FILES] = files
else
fn(null, result)
else
fn(null, result)
module.exports = Storage