scrivito
Version:
Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.
96 lines (73 loc) • 2.19 kB
text/typescript
import { onReset } from 'scrivito_sdk/common';
export interface LoaderProcess {
notifyDataRequired(): void;
notifyDataNoLongerRequired(): void;
notifyDataWasSet(): void;
setTidyCallback(tidyCallback: () => void): void;
}
interface ProcessIndex {
[index: string]: LoaderProcess | undefined;
}
let processIndex: ProcessIndex = {};
interface LoadingSubscriptions {
[index: string]: number | undefined;
}
let loadingSubscriptions: LoadingSubscriptions = {};
// for test purposes
export function subscriberCountForLoading(dataId: string): number {
return loadingSubscriptions[dataId] || 0;
}
// for test purposes
export function processIndexSize(): number {
return Object.keys(processIndex).length;
}
export function subscribeLoading(
dataId: string,
processFactory: () => LoaderProcess
): () => void {
let subscriptionActive = true;
changeSubscriptionsFor(dataId, 1);
const processToUse = getOrCreateProcessFor(dataId, processFactory);
processToUse.notifyDataRequired();
return () => {
if (!subscriptionActive) {
return;
}
subscriptionActive = false;
const numSubscriptions = changeSubscriptionsFor(dataId, -1);
if (numSubscriptions < 1) {
processToUse.notifyDataNoLongerRequired();
}
};
}
function getOrCreateProcessFor(
dataId: string,
processFactory: () => LoaderProcess
) {
const existingProcess = processIndex[dataId];
if (existingProcess) return existingProcess;
const newProcess = processFactory();
processIndex[dataId] = newProcess;
newProcess.setTidyCallback(() => {
if (processIndex[dataId] !== newProcess) return;
delete processIndex[dataId];
});
return newProcess;
}
function changeSubscriptionsFor(dataId: string, amount: number) {
const oldNumber = loadingSubscriptions[dataId] || 0;
const newNumber = oldNumber + amount;
loadingSubscriptions[dataId] = newNumber;
return newNumber;
}
export function notifyDataWasSet(
dataId: string,
processFactory: () => LoaderProcess
) {
const processToUse = getOrCreateProcessFor(dataId, processFactory);
processToUse.notifyDataWasSet();
}
onReset(() => {
processIndex = {};
loadingSubscriptions = {};
});