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 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
}