defaultMemoize.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createCacheKeyComparator = createCacheKeyComparator;
  6. exports.defaultEqualityCheck = void 0;
  7. exports.defaultMemoize = defaultMemoize;
  8. // Cache implementation based on Erik Rasmussen's `lru-memoize`:
  9. // https://github.com/erikras/lru-memoize
  10. var NOT_FOUND = 'NOT_FOUND';
  11. function createSingletonCache(equals) {
  12. var entry;
  13. return {
  14. get: function get(key) {
  15. if (entry && equals(entry.key, key)) {
  16. return entry.value;
  17. }
  18. return NOT_FOUND;
  19. },
  20. put: function put(key, value) {
  21. entry = {
  22. key: key,
  23. value: value
  24. };
  25. },
  26. getEntries: function getEntries() {
  27. return entry ? [entry] : [];
  28. },
  29. clear: function clear() {
  30. entry = undefined;
  31. }
  32. };
  33. }
  34. function createLruCache(maxSize, equals) {
  35. var entries = [];
  36. function get(key) {
  37. var cacheIndex = entries.findIndex(function (entry) {
  38. return equals(key, entry.key);
  39. }); // We found a cached entry
  40. if (cacheIndex > -1) {
  41. var entry = entries[cacheIndex]; // Cached entry not at top of cache, move it to the top
  42. if (cacheIndex > 0) {
  43. entries.splice(cacheIndex, 1);
  44. entries.unshift(entry);
  45. }
  46. return entry.value;
  47. } // No entry found in cache, return sentinel
  48. return NOT_FOUND;
  49. }
  50. function put(key, value) {
  51. if (get(key) === NOT_FOUND) {
  52. // TODO Is unshift slow?
  53. entries.unshift({
  54. key: key,
  55. value: value
  56. });
  57. if (entries.length > maxSize) {
  58. entries.pop();
  59. }
  60. }
  61. }
  62. function getEntries() {
  63. return entries;
  64. }
  65. function clear() {
  66. entries = [];
  67. }
  68. return {
  69. get: get,
  70. put: put,
  71. getEntries: getEntries,
  72. clear: clear
  73. };
  74. }
  75. var defaultEqualityCheck = function defaultEqualityCheck(a, b) {
  76. return a === b;
  77. };
  78. exports.defaultEqualityCheck = defaultEqualityCheck;
  79. function createCacheKeyComparator(equalityCheck) {
  80. return function areArgumentsShallowlyEqual(prev, next) {
  81. if (prev === null || next === null || prev.length !== next.length) {
  82. return false;
  83. } // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible.
  84. var length = prev.length;
  85. for (var i = 0; i < length; i++) {
  86. if (!equalityCheck(prev[i], next[i])) {
  87. return false;
  88. }
  89. }
  90. return true;
  91. };
  92. }
  93. // defaultMemoize now supports a configurable cache size with LRU behavior,
  94. // and optional comparison of the result value with existing values
  95. function defaultMemoize(func, equalityCheckOrOptions) {
  96. var providedOptions = typeof equalityCheckOrOptions === 'object' ? equalityCheckOrOptions : {
  97. equalityCheck: equalityCheckOrOptions
  98. };
  99. var _providedOptions$equa = providedOptions.equalityCheck,
  100. equalityCheck = _providedOptions$equa === void 0 ? defaultEqualityCheck : _providedOptions$equa,
  101. _providedOptions$maxS = providedOptions.maxSize,
  102. maxSize = _providedOptions$maxS === void 0 ? 1 : _providedOptions$maxS,
  103. resultEqualityCheck = providedOptions.resultEqualityCheck;
  104. var comparator = createCacheKeyComparator(equalityCheck);
  105. var cache = maxSize === 1 ? createSingletonCache(comparator) : createLruCache(maxSize, comparator); // we reference arguments instead of spreading them for performance reasons
  106. function memoized() {
  107. var value = cache.get(arguments);
  108. if (value === NOT_FOUND) {
  109. // @ts-ignore
  110. value = func.apply(null, arguments);
  111. if (resultEqualityCheck) {
  112. var entries = cache.getEntries();
  113. var matchingEntry = entries.find(function (entry) {
  114. return resultEqualityCheck(entry.value, value);
  115. });
  116. if (matchingEntry) {
  117. value = matchingEntry.value;
  118. }
  119. }
  120. cache.put(arguments, value);
  121. }
  122. return value;
  123. }
  124. memoized.clearCache = function () {
  125. return cache.clear();
  126. };
  127. return memoized;
  128. }