domain/registries/page.registry.ts

domain/registries/page.registry.ts is a file in Bane's Lab Site. 53 lines of code and 16 definitions.

import type { PageDefinition, PageEntry } from "#types/page.types";
import { createRegistry } from "#domain/registries/base.registry";

const pages = createRegistry<PageEntry>();
const loaded = new Map<string, PageDefinition>();
const pending = new Map<string, Promise<PageDefinition | undefined>>();

export const registerPage = function registerPage(page: PageEntry): void {
    pages.register(page);
};

export const getPage = function getPage(id: string): PageEntry | undefined {
    return pages.byId(id);
};

export const listPages = function listPages(): readonly PageEntry[] {
    return pages
        .all()
        .filter((page) => page.listed)
        .toSorted((a, b) => a.order - b.order);
};

export const registeredPages = function registeredPages(): readonly PageEntry[] {
    return pages.all().toSorted((a, b) => a.order - b.order);
};

export const loadedPage = function loadedPage(id: string): PageDefinition | undefined {
    return loaded.get(id);
};

export const loadPage = async function loadPage(id: string): Promise<PageDefinition | undefined> {
    const held = loaded.get(id);
    if (held !== undefined) {
        return held;
    }
    const entry = pages.byId(id);
    if (entry === undefined) {
        return undefined;
    }
    const inFlight = pending.get(id);
    if (inFlight !== undefined) {
        return inFlight;
    }
    const loading = entry.load().then((definition) => {
        loaded.set(id, definition);
        pending.delete(id);
        return definition;
    });
    pending.set(id, loading);
    return loading;
};

export const loadCompletePage = async function loadCompletePage(id: string): Promise<PageDefinition | undefined> {
    const definition = await loadPage(id);
    if (definition?.complete === undefined) {
        return definition;
    }
    const complete = await definition.complete();
    loaded.set(id, complete);
    return complete;
};