koop-cache-memory
Version:
An in-memory cache for KOop
141 lines (111 loc) • 4.53 kB
JavaScript
var Util = require('util')
var EventEmitter = require('events')
var _ = require('lodash')
var h = require('highland')
// Convenience to make callbacks optional in most functions
function noop () {}
function Cache (options) {
if ( options === void 0 ) options = {};
this.store = new Map()
this.catalog.store = new Map()
this.catalog.dataStore = this.store
}
Cache.name = 'Memory Cache'
Cache.type = 'cache'
Cache.version = require('../package.json').version
Util.inherits(Cache, EventEmitter)
Cache.prototype.insert = function (key, geojson, options, callback) {
if ( options === void 0 ) options = {};
if ( callback === void 0 ) callback = noop;
// support a feature collection or an array of features
if (this.store.has(key)) { return callback(new Error('Cache key is already in use')) }
var features = geojson.features ? geojson.features : geojson
this.store.set(key, features)
var metadata = geojson.metadata || {}
if (options.ttl) { metadata.expires = Date.now() + (options.ttl * 1000) }
this.catalog.insert(key, metadata, callback)
}
Cache.prototype.upsert = function (key, geojson, options, callback) {
if ( options === void 0 ) options = {};
if ( callback === void 0 ) callback = noop;
if (this.store.has(key)) {
this.update(key, geojson, options, callback)
} else {
this.insert(key, geojson, options, callback)
}
}
Cache.prototype.update = function (key, geojson, options, callback) {
if ( options === void 0 ) options = {};
if ( callback === void 0 ) callback = noop;
// support a feature collection or an array of features
if (!this.store.has(key)) { return callback(new Error('Resource not found')) }
var features = geojson.features ? geojson.features : geojson
this.store.set(key, features)
var existingMetadata = this.catalog.store.get(key)
var metadata = geojson.metadata || existingMetadata
if (options.ttl) { metadata.expires = Date.now() + (options.ttl * 1000) }
this.catalog.update(key, metadata, callback)
}
Cache.prototype.append = function (key, geojson, options, callback) {
if ( options === void 0 ) options = {};
if ( callback === void 0 ) callback = noop;
var features = geojson.features ? geojson.features : geojson
var existing = this.store.get(key)
this.store.set(key, features.concat(existing))
this.catalog.update(key, { updated: Date.now() })
callback()
}
Cache.prototype.retrieve = function (key, options, callback) {
if ( callback === void 0 ) callback = noop;
if (!this.store.has(key)) { return callback(new Error('Resource not found')) }
var features = this.store.get(key)
var metadata = this.catalog.store.get(key)
var geojson = { type: 'FeatureCollection', metadata: metadata, features: features }
callback(null, geojson)
return geojson
}
Cache.prototype.createStream = function (key, options) {
if ( options === void 0 ) options = {};
return h(this.store.get(key))
}
Cache.prototype.delete = function (key, callback) {
if ( callback === void 0 ) callback = noop;
if (!this.store.has(key)) { return callback(new Error('Resource not found')) }
this.store.delete(key)
var metadata = this.catalog.store.get(key)
metadata.status = 'deleted'
metadata.updated = Date.now()
this.catalog.store.set(key, metadata)
callback()
}
Cache.prototype.catalog = {}
Cache.prototype.catalog.insert = function (key, metadata, callback) {
if ( callback === void 0 ) callback = noop;
if (this.store.has(key)) { return callback(new Error('Catalog key is already in use')) }
metadata.updated = Date.now()
this.store.set(key, metadata)
callback()
}
Cache.prototype.catalog.update = function (key, update, callback) {
if ( callback === void 0 ) callback = noop;
if (!this.store.has(key)) { return callback(new Error('Resource not found')) }
var existing = this.store.get(key)
var metadata = _.merge(existing, update)
metadata.updated = Date.now()
this.store.set(key, metadata)
callback()
}
Cache.prototype.catalog.retrieve = function (key, callback) {
if ( callback === void 0 ) callback = noop;
if (!this.store.has(key)) { return callback(new Error('Resource not found')) }
var metadata = this.store.get(key)
callback(null, metadata)
return metadata
}
Cache.prototype.catalog.delete = function (key, callback) {
if ( callback === void 0 ) callback = noop;
if (this.dataStore.has(key)) { return callback(new Error('Cannot delete catalog entry while data is still in cache')) }
this.store.delete(key)
callback()
}
module.exports = Cache