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.
This commit is contained in:
Julien Fontanet 2020-09-16 10:49:54 +02:00 committed by GitHub
parent bd9bf55e43
commit 4264e34ffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -186,9 +186,14 @@ const createSubscription = cb => {
const delay = 5e3 // 5s const delay = 5e3 // 5s
const clearCacheDelay = 6e5 // 10m const clearCacheDelay = 6e5 // 10m
// contains active and lazy subscribers
const subscribers = Object.create(null) const subscribers = Object.create(null)
const hasSubscribers = () => Object.keys(subscribers).length !== 0
// only counts active subscribers
let nActiveSubscribers = 0
let cache let cache
let n = 0
let nextId = 0 let nextId = 0
let timeout let timeout
@ -220,7 +225,7 @@ const createSubscription = cb => {
result => { result => {
running = false running = false
if (n === 0) { if (nActiveSubscribers === 0) {
return uninstall() return uninstall()
} }
@ -242,7 +247,7 @@ const createSubscription = cb => {
error => { error => {
running = false running = false
if (n === 0) { if (nActiveSubscribers === 0) {
return uninstall() return uninstall()
} }
@ -259,25 +264,48 @@ const createSubscription = cb => {
asap(() => cb(cache)) asap(() => cb(cache))
} }
if (n++ === 0) { if (nActiveSubscribers++ === 0) {
run() run()
} }
return once(() => { return once(() => {
delete subscribers[id] delete subscribers[id]
if (--n === 0) { if (--nActiveSubscribers === 0) {
uninstall() uninstall()
} }
}) })
} }
subscribe.forceRefresh = () => { subscribe.forceRefresh = () => {
if (n) { if (hasSubscribers()) {
run() 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 return subscribe
} }