/**
 * DOM event bridge for the section runtime engine adapter (M7 — Variant
 * C, layered).
 *
 * Translates canonical engine outputs (`stage-change`,
 * `loading-complete`, `framework-error`) into DOM `CustomEvent`
 * dispatches on the host element. Mirrors the kernel's existing
 * `dispatch("pie-stage-change", …)` / `dispatch("pie-loading-complete", …)`
 * / `dispatch("framework-error", …)` emit chain bit-for-bit so the M6
 * canonical event surface stays stable while the kernel migrates onto
 * the engine in PR 5.
 *
 * **Detail-shape contract.** The engine core emits structurally minimal
 * outputs (`{ stage, status, cohort }`, `{ cohort, itemCount,
 * loadedCount }`). The bridge enriches them with `runtimeId`,
 * `sourceCe`, and `timestamp` so the dispatched DOM event detail
 * matches the canonical
 * `packages/players-shared/src/pie/stages.ts#StageChangeDetail` and
 * `LoadingCompleteDetail` shapes verbatim. `runtimeId` and `sourceCe`
 * are supplied at adapter construction time (one per engine instance);
 * `timestamp` is captured per-emit via the injected `now()` clock so
 * tests can pin a deterministic value.
 *
 * **Why not import the stage tracker.** The tracker's monotonic /
 * skipped-fill enforcement now lives in the engine core's transition
 * function. The bridge is purely an output-to-DOM translator — it does
 * not gate emissions, does not re-order, does not de-duplicate. That
 * keeps the responsibility clean and matches the "outputs are already
 * ordered correctly by the core" contract from
 * `engine-transition.ts`.
 *
 * The bridge **must not** import `svelte`; per the M7 layering
 * constraint the adapter is plain TS.
 */
export function createDomEventBridge(options) {
    const { runtimeId, sourceCe } = options;
    let host = options.host;
    const now = options.now ?? (() => new Date().toISOString());
    function dispatchStageChange(output) {
        const detail = {
            stage: output.stage,
            status: output.status,
            runtimeId,
            sectionId: output.cohort?.sectionId,
            attemptId: output.cohort?.attemptId ? output.cohort.attemptId : undefined,
            timestamp: now(),
            sourceCe,
        };
        host.dispatchEvent(new CustomEvent("pie-stage-change", { detail }));
    }
    function dispatchLoadingComplete(output) {
        const detail = {
            runtimeId,
            sectionId: output.cohort.sectionId,
            attemptId: output.cohort.attemptId ? output.cohort.attemptId : undefined,
            itemCount: output.itemCount,
            loadedCount: output.loadedCount,
            timestamp: now(),
            sourceCe,
        };
        host.dispatchEvent(new CustomEvent("pie-loading-complete", {
            detail,
        }));
    }
    function dispatchFrameworkError(output) {
        // Mirror the kernel's existing surface — the `framework-error`
        // DOM event detail is the framework-error model. The
        // `framework-error-bridge` separately reports the same model
        // into the bus so subscribers see one fan-out per error.
        host.dispatchEvent(new CustomEvent("framework-error", { detail: output.error }));
    }
    function dispatch(output) {
        switch (output.kind) {
            case "stage-change":
                dispatchStageChange(output);
                return;
            case "loading-complete":
                dispatchLoadingComplete(output);
                return;
            case "framework-error":
                dispatchFrameworkError(output);
                return;
            default: {
                const exhaustive = output;
                void exhaustive;
                return;
            }
        }
    }
    function setHost(next) {
        host = next;
    }
    return { dispatch, setHost };
}
//# sourceMappingURL=dom-event-bridge.js.map