summaryrefslogtreecommitdiff
path: root/node_modules/node-file-cache/src
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/node-file-cache/src')
-rw-r--r--node_modules/node-file-cache/src/index.ts173
1 files changed, 173 insertions, 0 deletions
diff --git a/node_modules/node-file-cache/src/index.ts b/node_modules/node-file-cache/src/index.ts
new file mode 100644
index 0000000..515b4a6
--- /dev/null
+++ b/node_modules/node-file-cache/src/index.ts
@@ -0,0 +1,173 @@
+'use strict';
+
+import * as database from 'lowdb';
+import * as crypto from 'crypto';
+import * as util from 'util';
+
+export interface ICacheOptions
+{
+ file?: string
+ life?: number
+}
+
+export interface IRecordOptions
+{
+ tags?: string[],
+ life?: number
+}
+
+export interface Record
+{
+ key: string
+ val: any
+ life: number
+ tags: string[]
+}
+
+export function create (options?: ICacheOptions)
+{
+ return new Cache(options || {});
+}
+
+export class Cache
+{
+ private config: ICacheOptions;
+ private db: any;
+
+ constructor (options?: ICacheOptions)
+ {
+ this.config = this._merge({
+ file: 'store.json',
+ life: 3600 // one hour
+ }, options || {});
+
+ this.db = database(this.config.file);
+ this.db.defaults({
+ index: []
+ }).value();
+ }
+
+ public set = function (key: string, value: any, options?: IRecordOptions): Cache
+ {
+ let record = this._createRecord(key, value, options || {});
+
+ this.expire(key); // remove previous
+ this.db.get('index').push(record).value();
+ return this;
+ }
+
+ public get = function (key: string): any
+ {
+ let record = this.db.get('index').find({ key: key }).value();
+
+ if (!record) return null;
+
+ if (record.life < this._createTimestamp()) {
+ this.expire(key);
+ return null; // expired
+ }
+
+ return record.val;
+ }
+
+ /**
+ * Clears all records from cache storage
+ */
+ public clear = function (): Cache
+ {
+ this.db.set('index', []).value();
+ return this;
+ }
+
+ /**
+ * Removes records from cache storage
+ */
+ public expire (value: any): Cache
+ {
+ const _ = this.db._;
+ let removed: string[],
+ staying: Record[];
+
+ switch (true) {
+ case util.isFunction(value):
+ // remove by filter callback
+ removed = this.db.get('index')
+ .filter(value)
+ .map('key')
+ .value();
+ break;
+
+ case util.isArray(value):
+ // remove by tags
+ removed = this.db.get('index')
+ .filter((record) => _.intersection(record.tags, value).length)
+ .map('key')
+ .value();
+ break;
+
+ case util.isString(value):
+ // remove by key
+ removed = this.db.get('index')
+ .filter((record) => record.key === value)
+ .map('key')
+ .value();
+ break;
+
+ default:
+ throw new Error('Unsupported expiration method: ' + (typeof value));
+ }
+
+ staying = this.db.get('index')
+ .filter((record) => removed.indexOf(record.key) < 0)
+ .value();
+ this._set(staying);
+
+ return this;
+ }
+
+ public size (): number
+ {
+ return this.db.get('index').value().length;
+ }
+
+ private _set (records: Record[]): void
+ {
+ this.db.set('index', records).value();
+ }
+
+ private _createRecord (key: string, value: any, options: IRecordOptions): Record
+ {
+ let tags = options.tags || [];
+ let span = options.life || this.config.life;
+ let life = span * 1000 + this._createTimestamp();
+
+ return {
+ key: key,
+ val: value,
+ life: life,
+ tags: tags
+ };
+ }
+
+ private _createTimestamp (): number
+ {
+ return new Date().getTime();
+ }
+
+ private _merge (a: any|any[], b: any|any[]): any|any[]
+ {
+ for (let p in b) {
+ try {
+ if (b[p].constructor === Object) {
+ a[p] = this._merge(a[p], b[p]);
+ } else {
+ a[p] = b[p];
+ }
+ } catch (e) {
+ a[p] = b[p];
+ }
+ }
+ return a;
+ }
+
+} \ No newline at end of file