/**
 * In-process pub/sub for live-preview update events.
 *
 * The admin emits `notifyPreviewUpdate(collection, id, payload)` whenever a
 * draft document changes (today: the `PUT /collections/:slug/:id` route).
 * Active SSE streams subscribe via `subscribePreviewUpdates(collection, id, listener)`
 * and forward every payload through to their connected `EventSource`
 * clients.
 *
 * The bus is intentionally single-instance and in-memory:
 *
 *   - Self-hosted single-node deployments get push-to-iframe updates
 *     "for free" with zero extra infrastructure.
 *   - Multi-node deployments will see each node deliver only its own
 *     update events — fine for the Phase 2 finish-line. A future Slice
 *     can swap this for a Redis/postgres-listen backed bus without
 *     changing the public contract (`notifyPreviewUpdate` /
 *     `subscribePreviewUpdates`).
 *
 * The bus is keyed by `${collection}:${documentId}` so two simultaneously
 * open previews for different docs don't see each other's traffic.
 */
const listenersByKey = new Map();
function keyOf(collection, documentId) {
    return `${collection}:${documentId}`;
}
export function subscribePreviewUpdates(collection, documentId, listener) {
    const key = keyOf(collection, documentId);
    let set = listenersByKey.get(key);
    if (!set) {
        set = new Set();
        listenersByKey.set(key, set);
    }
    set.add(listener);
    return () => {
        const current = listenersByKey.get(key);
        if (!current)
            return;
        current.delete(listener);
        if (current.size === 0)
            listenersByKey.delete(key);
    };
}
export function notifyPreviewUpdate(collection, documentId, payload) {
    const set = listenersByKey.get(keyOf(collection, documentId));
    if (!set || set.size === 0)
        return;
    const event = {
        collection,
        documentId,
        payload,
        at: Date.now(),
    };
    for (const listener of [...set]) {
        try {
            listener(event);
        }
        catch {
            // listener throws are isolated — one buggy stream must not take down
            // every other subscriber for the same doc.
        }
    }
}
export function previewSubscriberCount(collection, documentId) {
    return listenersByKey.get(keyOf(collection, documentId))?.size ?? 0;
}
/**
 * Test helper. Drops every subscription. Production code never calls this.
 */
export function __resetPreviewEventBus() {
    listenersByKey.clear();
}
//# sourceMappingURL=event-bus.js.map