diff --git a/.gitignore b/.gitignore index 11f4e39..893b351 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store .eslintcache .nyc_output coverage diff --git a/package-lock.json b/package-lock.json index 70c2060..f78e76f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18886,11 +18886,8 @@ } }, "packages/promise-swr": { - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", - "dependencies": { - "debug": "^4.3.2" - }, "engines": { "node": ">= 14" } @@ -29366,10 +29363,7 @@ } }, "promise-swr": { - "version": "file:packages/promise-swr", - "requires": { - "debug": "^4.3.2" - } + "version": "file:packages/promise-swr" }, "promise-throttle-bucket": { "version": "file:packages/promise-throttle-bucket", diff --git a/packages/promise-swr/README.md b/packages/promise-swr/README.md index 79d853c..a6089bf 100644 --- a/packages/promise-swr/README.md +++ b/packages/promise-swr/README.md @@ -73,6 +73,7 @@ Type: `number` Default: `Infinity` The maximum time in milliseconds to keep a value in the cache. +Using this default will prevent cache entries from being evicted and cache size can then grow indefinitely ##### options.resolver? @@ -81,6 +82,7 @@ Default: `(...args) => args[0]` Determines how the caching key will be computed. By default, it will only consider the first argument and use strict equality to evaluate a match. +Provide your custom resolver if the wrapped function takes multiple arguments or uses objects/arrays as argument. ##### options.revalidate? diff --git a/packages/promise-swr/package.json b/packages/promise-swr/package.json index faec28f..92a074e 100644 --- a/packages/promise-swr/package.json +++ b/packages/promise-swr/package.json @@ -1,6 +1,6 @@ { "name": "promise-swr", - "version": "1.0.1", + "version": "1.0.2", "description": "Caches a promise-returning function with a stale-while-revalidate strategy", "keywords": [ "async", @@ -26,9 +26,6 @@ "deps:check": "dependency-check --no-dev .", "test": "mocha" }, - "dependencies": { - "debug": "^4.3.2" - }, "nyc": { "all": true, "include": [ diff --git a/packages/promise-swr/src/index.js b/packages/promise-swr/src/index.js index 674fbea..d0dc674 100644 --- a/packages/promise-swr/src/index.js +++ b/packages/promise-swr/src/index.js @@ -1,7 +1,5 @@ 'use strict' -const debug = require('debug')('promise-swr') - /** * Caches a promise-returning function with a stale-while-revalidate strategy. * @@ -12,13 +10,16 @@ const debug = require('debug')('promise-swr') * the data is below the revalidation threshold, it is fresh and is returned * right away. * - * @param {Function} fn The function to cache. + * @template {any[]} T Tuple of argument types for the wrapped function. + * @template K Type of the cache key. + * @template R Return type of the wrapped function. + * @param {(...args: T) => R | Promise} fn The function to cache. * @param {object} [options] The options. - * @param {Map} [options.cache] The storage. Must implement the `Map` interface. + * @param {Map} [options.cache] The cache. Follows the `Map` interface. * @param {number} [options.maxAge] The max time to cache any result in ms. - * @param {Function} [options.resolver] The key resolver function. + * @param {(...args: T) => K} [options.resolver] The key resolver function. * @param {number} [options.revalidate] The max time to wait until revalidating. - * @returns {Function} The cached function. + * @returns {(...args: T) => Promise} A function that caches `fn`. */ function pSwr(fn, options = {}) { const { @@ -29,21 +30,13 @@ function pSwr(fn, options = {}) { } = options return function (...args) { - debug('Function called') - const key = resolver(...args) - const cached = cache.get(key) - const keyAge = cached - ? cached.revalidating - ? 0 - : Date.now() - cached.timestamp - : 0 + const keyAge = + !cached || cached.revalidating ? 0 : Date.now() - cached.timestamp if (!cached || keyAge > maxAge) { - debug(cached ? 'Cache expired' : 'Cache is empty') - const _cached = { data: Promise.resolve(fn(...args)), revalidating: true, @@ -55,34 +48,23 @@ function pSwr(fn, options = {}) { .then(function () { _cached.timestamp = Date.now() _cached.revalidating = false - - debug('Cache set') }) - .catch(function (err) { - debug('Cache set failed: %s', err.message) - + .catch(function () { cache.delete(key) }) - } else if (keyAge > revalidate) { - debug('Cache is stale, revalidating') - + } else if (keyAge > revalidate && !cached.revalidating) { cached.revalidating = true Promise.resolve(fn(...args)) .then(function (result) { cached.data = Promise.resolve(result) cached.timestamp = Date.now() cached.revalidating = false - - debug('Cache revalidated') }) - .catch(function (err) { - debug('Cache revalidation failed: %s', err.message) - + .catch(function () { cached.revalidating = false }) } - debug('Returning cached data') return cache.get(key).data } } diff --git a/packages/promise-swr/test/src.index.spec.js b/packages/promise-swr/test/src.index.spec.js index 854fc26..a72ed29 100644 --- a/packages/promise-swr/test/src.index.spec.js +++ b/packages/promise-swr/test/src.index.spec.js @@ -109,7 +109,7 @@ describe('Stale While Revalidating', function () { .then(function (res) { res.should.equal(1) fn.callCount.should.equal(1) - return setTimeout(ticks(4)) + return setTimeout(ticks(5)) }) .then(wrapped) .then(function (res) {