import instances from './instances.js';
const sameSelection = (a, b) => {
    if (a === b) {
        return true;
    }
    if (!a || !b) {
        return false;
    }
    return a.sx === b.sx && a.sy === b.sy && a.ex === b.ex && a.ey === b.ey;
};
// Creates the bidirectional bridge between the application and the renderer:
// the app reads the latest composited frame (getFrame) and pushes a selection
// (setSelection) that the renderer highlights before serialization. setSelection
// deduplicates and schedules exactly one repaint through Ink's own throttle via
// the requestRender callback, so it never mutates already-committed frame state.
export const createFrameController = (requestRender) => {
    let currentSelection = null;
    let lastFrame = null;
    const listeners = new Set();
    return {
        getFrame: () => lastFrame,
        getSelection: () => currentSelection,
        setSelection(selection) {
            if (sameSelection(currentSelection, selection)) {
                return;
            }
            currentSelection = selection;
            requestRender();
        },
        subscribe(listener) {
            listeners.add(listener);
            return () => {
                listeners.delete(listener);
            };
        },
        publishFrame(frame) {
            lastFrame = frame;
            for (const listener of listeners) {
                listener(frame);
            }
        },
    };
};
export const getFrameController = (stdout) => instances.get(stdout)?.frameController;
//# sourceMappingURL=frame-controller.js.map
