From ad7bfdeac306c87f4df692aed4e385e39d554618 Mon Sep 17 00:00:00 2001 From: Matt <6946110+mupperton@users.noreply.github.com> Date: Tue, 11 Oct 2022 16:03:41 +0100 Subject: [PATCH] Added ttl --- src/phunk.ts | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/phunk.ts b/src/phunk.ts index 1946d2b..e705491 100644 --- a/src/phunk.ts +++ b/src/phunk.ts @@ -1,6 +1,7 @@ interface Config { init?: boolean cacheRejections?: boolean + ttl?: number } const noop = () => {} @@ -16,21 +17,40 @@ class Phunk { #cacheRejections - constructor(fn: () => T, config?: Config) { - this.#fn = fn + #ttl + #lastResolve = 0 + constructor(fn: () => T, config?: Config) { const options = config ?? {} + if (typeof options.ttl !== 'undefined' && (!Number.isSafeInteger(options.ttl) || options.ttl < 0)) { + throw new TypeError(' must be a positive integer') + } + + this.#fn = fn + this.#cacheRejections = options.cacheRejections === true + this.#ttl = options.ttl ?? null + if (options.init === true) { this.next().catch(noop) // catch error to avoid unhandled promise exceptions } } async current() { - if (this.#promise === null) return this.next() - if (!this.#cacheRejections && this.#isRejected) return this.next() + if (this.#promise === null) { + // first invocation + return this.next() + } + if (!this.#cacheRejections && this.#isRejected) { + // Configured not to cache rejections and previously rejected + return this.next() + } + if (this.#ttl !== null && Date.now() >= (this.#lastResolve + this.#ttl)) { + // ttl expired + return this.next() + } return this.#promise } @@ -55,6 +75,9 @@ class Phunk { this.#isRejected = true throw error } finally { + if (this.#ttl !== null) { + this.#lastResolve = Date.now() + } this.#isResolving = false } }