import { getItemDescriptor } from "../../utils";
export function buildWorkboxDescriptorRequest(slots) {
    const perSlot = slots.map((slot) => {
        const sharedItems = [];
        const treeRendered = [];
        if (slot.page?.item)
            treeRendered.push(slot.page.item);
        if (slot.page?.rootComponent)
            collectAllItems(slot.page.rootComponent, sharedItems, treeRendered);
        return { slot, sharedItems, treeRendered };
    });
    const treeKeySets = perSlot.map(({ treeRendered }) => new Set(treeRendered.map(getContainmentKey)));
    const items = [];
    const renderedItems = [];
    perSlot.forEach(({ slot, sharedItems, treeRendered }, index) => {
        if (slot.itemDescriptor) {
            // A slot item that another open slot already renders as part of its page
            // (a datasource opened next to its page) is not a separate top-level
            // item — keeping it out preserves the page-only request shape.
            const key = getContainmentKey(slot.itemDescriptor);
            const containedElsewhere = treeKeySets.some((keys, i) => i !== index && keys.has(key));
            if (!containedElsewhere)
                items.push(slot.itemDescriptor);
            renderedItems.push(slot.itemDescriptor);
        }
        items.push(...sharedItems);
        renderedItems.push(...treeRendered);
    });
    return {
        items: dedupeItemDescriptors(items.filter(Boolean)),
        renderedItems: dedupeItemDescriptors(renderedItems.filter(Boolean)),
    };
}
function collectAllItems(component, items, renderedItems) {
    component.items.forEach((item) => renderedItems.push(item));
    if (component.datasourceItem)
        renderedItems.push(component.datasourceItem);
    component.placeholders.forEach((x) => {
        x.components.forEach((y) => {
            if (y.isShared && y.datasourceItem) {
                items.push(y.datasourceItem);
            }
            collectAllItems(y, items, renderedItems);
        });
    });
}
// Containment keys normalize braces/dashes in ids and default the database to
// "master": slot descriptors (from loadItem callers) and page-model descriptors
// can carry different GUID formats, and only the latter always set a database.
function getContainmentKey(item) {
    const descriptor = getItemDescriptor(item);
    return [
        descriptor.id?.toLowerCase().replace(/[{}-]/g, ""),
        descriptor.language?.toLowerCase(),
        descriptor.version ?? 0,
        descriptor.database?.toLowerCase() || "master",
    ].join("|");
}
function dedupeItemDescriptors(items) {
    const seen = new Set();
    const result = [];
    items.forEach((item) => {
        const descriptor = getItemDescriptor(item);
        const key = [
            descriptor.id?.toLowerCase(),
            descriptor.language?.toLowerCase(),
            descriptor.version ?? 0,
            descriptor.database?.toLowerCase() ?? "",
        ].join("|");
        if (seen.has(key))
            return;
        seen.add(key);
        result.push(descriptor);
    });
    return result;
}
//# sourceMappingURL=workboxDescriptors.js.map