node-file-cache.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. 'use strict';
  2. var database = require('lowdb');
  3. var util = require('util');
  4. function create(options) {
  5. return new Cache(options || {});
  6. }
  7. exports.create = create;
  8. var Cache = (function () {
  9. function Cache(options) {
  10. this.set = function (key, value, options) {
  11. var record = this._createRecord(key, value, options || {});
  12. this.expire(key); // remove previous
  13. this.db.get('index').push(record).value();
  14. return this;
  15. };
  16. this.get = function (key) {
  17. var record = this.db.get('index').find({ key: key }).value();
  18. if (!record)
  19. return null;
  20. if (record.life < this._createTimestamp()) {
  21. this.expire(key);
  22. return null; // expired
  23. }
  24. return record.val;
  25. };
  26. /**
  27. * Clears all records from cache storage
  28. */
  29. this.clear = function () {
  30. this.db.set('index', []).value();
  31. return this;
  32. };
  33. this.config = this._merge({
  34. file: 'store.json',
  35. life: 3600 // one hour
  36. }, options || {});
  37. this.db = database(this.config.file);
  38. this.db.defaults({
  39. index: []
  40. }).value();
  41. }
  42. /**
  43. * Removes records from cache storage
  44. */
  45. Cache.prototype.expire = function (value) {
  46. var _ = this.db._;
  47. var removed, staying;
  48. switch (true) {
  49. case util.isFunction(value):
  50. // remove by filter callback
  51. removed = this.db.get('index')
  52. .filter(value)
  53. .map('key')
  54. .value();
  55. break;
  56. case util.isArray(value):
  57. // remove by tags
  58. removed = this.db.get('index')
  59. .filter(function (record) { return _.intersection(record.tags, value).length; })
  60. .map('key')
  61. .value();
  62. break;
  63. case util.isString(value):
  64. // remove by key
  65. removed = this.db.get('index')
  66. .filter(function (record) { return record.key === value; })
  67. .map('key')
  68. .value();
  69. break;
  70. default:
  71. throw new Error('Unsupported expiration method: ' + (typeof value));
  72. }
  73. staying = this.db.get('index')
  74. .filter(function (record) { return removed.indexOf(record.key) < 0; })
  75. .value();
  76. this._set(staying);
  77. return this;
  78. };
  79. Cache.prototype.size = function () {
  80. return this.db.get('index').value().length;
  81. };
  82. Cache.prototype.values = function() {
  83. let values = [];
  84. var content = this.db.get('index').value();
  85. content.forEach((item) => {
  86. values.push(item.val);
  87. });
  88. return values;
  89. }
  90. Cache.prototype._set = function (records) {
  91. this.db.set('index', records).value();
  92. };
  93. Cache.prototype._createRecord = function (key, value, options) {
  94. var tags = options.tags || [];
  95. var span = options.life || this.config.life;
  96. var life = span * 1000 + this._createTimestamp();
  97. return {
  98. key: key,
  99. val: value,
  100. life: life,
  101. tags: tags
  102. };
  103. };
  104. Cache.prototype._createTimestamp = function () {
  105. return new Date().getTime();
  106. };
  107. Cache.prototype._merge = function (a, b) {
  108. for (var p in b) {
  109. try {
  110. if (b[p].constructor === Object) {
  111. a[p] = this._merge(a[p], b[p]);
  112. }
  113. else {
  114. a[p] = b[p];
  115. }
  116. }
  117. catch (e) {
  118. a[p] = b[p];
  119. }
  120. }
  121. return a;
  122. };
  123. return Cache;
  124. }());
  125. exports.Cache = Cache;
  126. //# sourceMappingURL=index.js.map