From 4264e34ffd437daf331bc5790520fec1c9005190 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Wed, 16 Sep 2020 10:49:54 +0200 Subject: [PATCH] feat(xo-web/createSubscription): support lazy subscribers (#5158) These subscribers follow the value of the subscription but do not make the subscription refresh itself. A lazy subscriber triggers an initial fetch if no value is available. --- packages/xo-web/src/common/xo/index.js | 40 ++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/xo-web/src/common/xo/index.js b/packages/xo-web/src/common/xo/index.js index e869e3828..cb96b665c 100644 --- a/packages/xo-web/src/common/xo/index.js +++ b/packages/xo-web/src/common/xo/index.js @@ -186,9 +186,14 @@ const createSubscription = cb => { const delay = 5e3 // 5s const clearCacheDelay = 6e5 // 10m + // contains active and lazy subscribers const subscribers = Object.create(null) + const hasSubscribers = () => Object.keys(subscribers).length !== 0 + + // only counts active subscribers + let nActiveSubscribers = 0 + let cache - let n = 0 let nextId = 0 let timeout @@ -220,7 +225,7 @@ const createSubscription = cb => { result => { running = false - if (n === 0) { + if (nActiveSubscribers === 0) { return uninstall() } @@ -242,7 +247,7 @@ const createSubscription = cb => { error => { running = false - if (n === 0) { + if (nActiveSubscribers === 0) { return uninstall() } @@ -259,25 +264,48 @@ const createSubscription = cb => { asap(() => cb(cache)) } - if (n++ === 0) { + if (nActiveSubscribers++ === 0) { run() } return once(() => { delete subscribers[id] - if (--n === 0) { + if (--nActiveSubscribers === 0) { uninstall() } }) } subscribe.forceRefresh = () => { - if (n) { + if (hasSubscribers()) { run() } } + subscribe.lazy = cb => { + const id = nextId++ + subscribers[id] = cb + + if (cache !== undefined) { + asap(() => cb(cache)) + } + + // trigger an initial run if necessary + if (nActiveSubscribers === 0) { + run() + } + + return once(() => { + delete subscribers[id] + + // schedule cache deletion if necessary + if (nActiveSubscribers === 0) { + uninstall() + } + }) + } + return subscribe }