import { createStore, useStore } from "./create-store.js";
const store = createStore({ offset: 0, isUserScrolled: false });
/**
 * Scroll bounds kept OUTSIDE the reactive store: they change as content/layout
 * change (driven by App), but on their own they should not trigger a viewport
 * re-render — only an actual offset change should. `setTranscriptScrollBounds`
 * re-clamps the offset and emits only when the visible offset actually moves.
 */
let maxOffset = 0;
function clamp(value) {
    return Math.min(Math.max(0, value), maxOffset);
}
/**
 * Update the maximum scroll offset (total transcript lines − viewport rows).
 * Called by App whenever content length or viewport height changes. Re-pins to
 * the bottom when the user hasn't scrolled, otherwise clamps their offset into
 * the new range. Emits only when the offset actually changes, so growing
 * content during a scroll-locked read doesn't churn renders.
 */
export function setTranscriptScrollBounds(nextMaxOffset) {
    maxOffset = Math.max(0, Math.floor(nextMaxOffset));
    const { offset, isUserScrolled } = store.getSnapshot();
    const next = isUserScrolled ? Math.min(offset, maxOffset) : 0;
    if (next !== offset)
        store.setState({ offset: next });
}
/**
 * Scroll by a signed number of lines. Positive scrolls UP (toward older
 * output), negative scrolls DOWN (toward newest). No-op when clamped to an
 * edge, so wheel jitter at the top/bottom can't churn renders.
 */
export function scrollTranscriptByLines(deltaLines) {
    if (deltaLines === 0)
        return;
    const { offset } = store.getSnapshot();
    const next = clamp(offset + deltaLines);
    if (next === offset)
        return;
    store.setState({ offset: next, isUserScrolled: next > 0 });
}
/** Set the absolute offset (used by PageUp/Down, Shift+Arrows, g/G). */
export function setTranscriptScrollOffset(targetOffset) {
    const { offset } = store.getSnapshot();
    const next = clamp(targetOffset);
    if (next === offset)
        return;
    store.setState({ offset: next, isUserScrolled: next > 0 });
}
/** Page up/down relative to the current offset by `page` lines. */
export function pageTranscriptScroll(page) {
    const { offset } = store.getSnapshot();
    setTranscriptScrollOffset(offset + page);
}
/** Snap back to the newest output (offset 0) — e.g. on a new prompt submit. */
export function resetTranscriptScroll() {
    const { offset, isUserScrolled } = store.getSnapshot();
    if (offset === 0 && !isUserScrolled)
        return;
    store.setState({ offset: 0, isUserScrolled: false });
}
/** Jump to the very top (oldest output). */
export function scrollTranscriptToTop() {
    setTranscriptScrollOffset(maxOffset);
}
/** Current clamped offset, non-reactively (for tests / imperative reads). */
export function getTranscriptScrollOffset() {
    return clamp(store.getSnapshot().offset);
}
/** Reactive hook: re-renders the caller only when the scroll offset changes. */
export function useTranscriptScrollOffset() {
    return useStore(store).offset;
}
//# sourceMappingURL=transcript-scroll-store.js.map