81 lines
1.8 KiB
JavaScript
81 lines
1.8 KiB
JavaScript
function createContextPoller({
|
|
fetchContext,
|
|
onSnapshot,
|
|
onError,
|
|
isHidden = () => false,
|
|
setTimer = setTimeout,
|
|
clearTimer = clearTimeout,
|
|
intervalMs = 8000,
|
|
}) {
|
|
let inFlight = null;
|
|
let timer = null;
|
|
let stopped = false;
|
|
let revisions = {};
|
|
let retainedSnapshot = null;
|
|
|
|
function cancelTimer() {
|
|
if (timer !== null) clearTimer(timer);
|
|
timer = null;
|
|
}
|
|
|
|
function schedule() {
|
|
cancelTimer();
|
|
if (stopped || isHidden()) return;
|
|
timer = setTimer(() => {
|
|
timer = null;
|
|
refresh();
|
|
}, intervalMs);
|
|
}
|
|
|
|
function refresh() {
|
|
if (stopped || isHidden()) return Promise.resolve(null);
|
|
if (inFlight) return inFlight;
|
|
|
|
let request;
|
|
try {
|
|
request = fetchContext({ ...revisions });
|
|
} catch (error) {
|
|
request = Promise.reject(error);
|
|
}
|
|
inFlight = Promise.resolve(request)
|
|
.then((snapshot) => {
|
|
const changedSections = ['context', 'events', 'notifications'].filter(
|
|
(section) => Object.prototype.hasOwnProperty.call(snapshot, section)
|
|
);
|
|
retainedSnapshot = retainedSnapshot ? { ...retainedSnapshot, ...snapshot } : { ...snapshot };
|
|
revisions = { ...revisions, ...(snapshot.revisions || {}) };
|
|
onSnapshot(retainedSnapshot, changedSections);
|
|
return retainedSnapshot;
|
|
})
|
|
.catch((error) => {
|
|
onError(error);
|
|
return null;
|
|
})
|
|
.finally(() => {
|
|
inFlight = null;
|
|
schedule();
|
|
});
|
|
return inFlight;
|
|
}
|
|
|
|
function setVisible(visible) {
|
|
cancelTimer();
|
|
if (!visible) return Promise.resolve(null);
|
|
return refresh();
|
|
}
|
|
|
|
return {
|
|
start: refresh,
|
|
refresh,
|
|
setVisible,
|
|
stop() {
|
|
stopped = true;
|
|
cancelTimer();
|
|
},
|
|
};
|
|
}
|
|
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = createContextPoller;
|
|
}
|