@playlive/realtime-pipeline
    Preparing search index...

    Interface PipelineStore

    Public store surface. Every field is read directly from store.getState(); every action is invoked via store.getState().setX(...).

    Action surface is split into three tiers:

    1. Connectionconnect, disconnect, identify, refresh, setCurrentURL, setAutoConnect, setAdminApiKey, setCurrentType.
    2. Public dataaddCampaign(ID), addFundraisingEvent(ID), updateTiltifySettings, setOverlayInfo, setTwitchUsername, feature-flag toggles, reset.
    3. Internal (prefixed _) — wired by the createPipelineConnection factory only; consumers should never call these directly.
    interface PipelineStore {
        _addMessage: (message: WebSocketMessage) => void;
        _deleteDonationTrain: (train: DonationTrain) => void;
        _processDonation: (donation: TiltifyDonation) => void;
        _processFirehoseMessage: (msg: AdminWebhookFirehoseMessage) => void;
        _processScheduleTransition: (payload: ScheduleTransitionPayload) => void;
        _processSubscriptions: (
            subscriptions: ConnectionMessageSubscriptions | undefined,
        ) => void;
        _processTestDonation: (donation: TiltifyDonationWithTestFlag) => void;
        _processTwitchChatMessage: (msg: TwitchChatMessage) => void;
        _setConnectionState: (connected: boolean, connecting: boolean) => void;
        _setConnectionType: (type: "client" | "admin") => void;
        _setHasReceivedInitialData: (value: boolean) => void;
        _setIdentify: (fn: () => void) => void;
        _setLastIdentityMessage: (message: ConnectionMessage) => void;
        _setLastRefreshResponse: (msg: RefreshResponseMessage) => void;
        _setRefresh: (fn: (filters?: RefreshCommandFilters) => void) => void;
        _shouldConnect: boolean;
        _updateCampaign: (
            campaign: TiltifyCampaign | TiltifyTeamCampaign,
            options?: { allowDecrease?: boolean },
        ) => void;
        _updateDonationTrain: (train: DonationTrain) => void;
        _updateDonorSpotlight: (spotlight: ComputedSpotlight) => void;
        _updateDonorSpotlightSettings: (settings: DonorSpotlightSettings) => void;
        _updateLeaderboardExclusionsForCampaign: (
            campaignID: string,
            exclusions: LeaderboardExclusion[],
        ) => void;
        _updateLeaderboardForCampaign: (
            campaignID: string,
            entries: TiltifyLeaderboardEntry[],
        ) => void;
        _updatePollForCampaign: (
            campaignID: string,
            poll: TiltifyPoll,
            deltas?: PollOptionDelta[],
        ) => void;
        _updateScheduleForCampaign: (
            campaignID: string,
            schedule: ScheduleTransitionBlock[],
        ) => void;
        _updateSettingsFromServer: (
            settings: Partial<TiltifyWebSocketSettings>,
        ) => void;
        _updateSubathonTimer: (timer: SubathonTimer) => void;
        _updateTickData: (data: TiltifyTickMessageData) => void;
        addCampaign: (
            campaign: TiltifyCampaign | TiltifyTeamCampaign,
            isTeam: boolean,
        ) => void;
        addCampaignID: (id: string, isTeam: boolean, causeID?: string) => void;
        addFundraisingEvent: (event: TiltifyFundraisingEvent) => void;
        addFundraisingEventID: (id: string) => void;
        adminApiKey: string | null;
        auctionHouses: AuctionHouse[];
        autoConnect: boolean;
        campaignIDs: string[];
        campaigns: TiltifyCampaign[];
        causeIDs: string[];
        causes: TiltifyCause[];
        charityType: CharityType;
        connect: () => void;
        connected: boolean;
        connecting: boolean;
        connectionType: "client" | "admin" | null;
        disconnect: () => void;
        donations: Record<string, TiltifyDonationWithTestFlag[]>;
        donationTrains: Record<string, DonationTrain[]>;
        donationTrainsEnabled: boolean;
        donorSpotlightEnabled: boolean;
        donorSpotlights: Record<string, ComputedSpotlight>;
        donorSpotlightSettings: Record<string, DonorSpotlightSettings>;
        fundraisingEventIDs: string[];
        fundraisingEvents: TiltifyFundraisingEvent[];
        fundraisingEventSupportingCampaigns: Record<string, TiltifyCampaign[]>;
        getAllFundraisingEventSupportingCampaigns: () => TiltifyCampaign[];
        getDonations: (id: string) => TiltifyDonationWithTestFlag[];
        getDonationTrains: (
            id: string,
            withStatus?: DonationTrainStatus | null,
        ) => DonationTrain[];
        getDonorSpotlight: (id: string) => ComputedSpotlight | null;
        getFirstCampaign: () => TiltifyCampaign | null;
        getFirstCause: () => TiltifyCause | null;
        getFirstFundraisingEvent: () => TiltifyFundraisingEvent | null;
        getFirstTeamCampaign: () => TiltifyTeamCampaign | null;
        getFundraisingEventSupportingCampaigns: (id: string) => TiltifyCampaign[];
        getLastScheduleTransition: (
            campaignID: string,
        ) => ScheduleTransitionPayload | null;
        getLeaderboardEntries: (id: string) => TiltifyLeaderboardEntry[];
        getLeaderboardExclusions: (campaignID: string) => LeaderboardExclusion[];
        getMilestones: (id: string) => TiltifyMilestone[];
        getPolls: (id: string) => TiltifyPoll[];
        getRewards: (id: string) => TiltifyReward[];
        getSchedule: (campaignID: string) => ScheduleTransitionBlock[];
        getSubathonTimers: (
            id: string,
            withStatus?: SubathonTimerStatus | null,
        ) => SubathonTimer[];
        getSubscription: (id: string) => TiltifyWebhookSubscription | null;
        getTargets: (id: string) => TiltifyTarget[];
        getTestDonations: (id: string) => TiltifyDonationWithTestFlag[];
        hasReceivedInitialData: boolean;
        hasSetOverlayInfo: boolean;
        identify: () => void;
        isUpdatingSettings: boolean;
        lastFirehoseMessage: AdminWebhookFirehoseMessage | null;
        lastIdentified: Date | null;
        lastIdentityMessage: ConnectionMessage | null;
        lastMessage: WebSocketMessage | null;
        lastPollDeltas: Record<string, PollOptionDelta[]>;
        lastRefreshResponse: RefreshResponseMessage | null;
        lastScheduleTransitions: Record<string, ScheduleTransitionPayload>;
        leaderboardEntries: Record<string, TiltifyLeaderboardEntry[]>;
        leaderboardExclusions: Record<string, LeaderboardExclusion[]>;
        messages: WebSocketMessage[];
        milestones: Record<string, TiltifyMilestone[]>;
        overlayConfig: Record<string, string>;
        overlayName: string;
        overlayPath: string;
        polls: Record<string, TiltifyPoll[]>;
        refresh: (filters?: RefreshCommandFilters) => void;
        removeCampaign: (
            campaign: TiltifyCampaign | TiltifyTeamCampaign,
            isTeam: boolean,
        ) => void;
        removeCampaignID: (id: string, isTeam: boolean) => void;
        removeFundraisingEvent: (event: TiltifyFundraisingEvent) => void;
        removeFundraisingEventID: (id: string) => void;
        reset: (type: CharityType) => void;
        rewards: Record<string, TiltifyReward[]>;
        schedules: Record<string, ScheduleTransitionBlock[]>;
        setAdminApiKey: (key: string | null) => void;
        setAutoConnect: (autoConnect: boolean) => void;
        setCurrentType: (type: CharityType) => void;
        setCurrentURL: (url: string) => void;
        setOverlayInfo: (info: OverlayInfo) => void;
        setTwitchUsername: (username: string | null) => void;
        subathonTimerEnabled: boolean;
        subathonTimers: Record<string, SubathonTimer[]>;
        subscriptions: Record<string, TiltifyWebhookSubscription>;
        targets: Record<string, TiltifyTarget[]>;
        teamCampaignIDs: string[];
        teamCampaigns: TiltifyTeamCampaign[];
        teamUserSlug: string;
        testDonations: Record<string, TiltifyDonationWithTestFlag[]>;
        tiltifySettings: TiltifyWebSocketSettings;
        toggleDonationTrains: (enable: boolean) => void;
        toggleDonorSpotlight: (enable: boolean) => void;
        toggleSubathonTimer: (enable: boolean) => void;
        twitchChatMessages: TwitchChatMessage[];
        twitchUsername: string | null;
        updateTiltifySettings: (
            settings: Partial<TiltifyWebSocketSettings>,
            sendBackToServer: boolean,
        ) => void;
        wsURL: string;
    }
    Index
    _addMessage _deleteDonationTrain _processDonation _processFirehoseMessage _processScheduleTransition _processSubscriptions _processTestDonation _processTwitchChatMessage _setConnectionState _setConnectionType _setHasReceivedInitialData _setIdentify _setLastIdentityMessage _setLastRefreshResponse _setRefresh _shouldConnect _updateCampaign _updateDonationTrain _updateDonorSpotlight _updateDonorSpotlightSettings _updateLeaderboardExclusionsForCampaign _updateLeaderboardForCampaign _updatePollForCampaign _updateScheduleForCampaign _updateSettingsFromServer _updateSubathonTimer _updateTickData addCampaign addCampaignID addFundraisingEvent addFundraisingEventID adminApiKey auctionHouses autoConnect campaignIDs campaigns causeIDs causes charityType connect connected connecting connectionType disconnect donations donationTrains donationTrainsEnabled donorSpotlightEnabled donorSpotlights donorSpotlightSettings fundraisingEventIDs fundraisingEvents fundraisingEventSupportingCampaigns getAllFundraisingEventSupportingCampaigns getDonations getDonationTrains getDonorSpotlight getFirstCampaign getFirstCause getFirstFundraisingEvent getFirstTeamCampaign getFundraisingEventSupportingCampaigns getLastScheduleTransition getLeaderboardEntries getLeaderboardExclusions getMilestones getPolls getRewards getSchedule getSubathonTimers getSubscription getTargets getTestDonations hasReceivedInitialData hasSetOverlayInfo identify isUpdatingSettings lastFirehoseMessage lastIdentified lastIdentityMessage lastMessage lastPollDeltas lastRefreshResponse lastScheduleTransitions leaderboardEntries leaderboardExclusions messages milestones overlayConfig overlayName overlayPath polls refresh removeCampaign removeCampaignID removeFundraisingEvent removeFundraisingEventID reset rewards schedules setAdminApiKey setAutoConnect setCurrentType setCurrentURL setOverlayInfo setTwitchUsername subathonTimerEnabled subathonTimers subscriptions targets teamCampaignIDs teamCampaigns teamUserSlug testDonations tiltifySettings toggleDonationTrains toggleDonorSpotlight toggleSubathonTimer twitchChatMessages twitchUsername updateTiltifySettings wsURL
    _addMessage: (message: WebSocketMessage) => void
    _deleteDonationTrain: (train: DonationTrain) => void
    _processDonation: (donation: TiltifyDonation) => void
    _processFirehoseMessage: (msg: AdminWebhookFirehoseMessage) => void
    _processScheduleTransition: (payload: ScheduleTransitionPayload) => void

    Merge a schedule-block transition payload into lastScheduleTransitions[campaignID], overwriting any prior entry. Called from _updateTickData when the tick carries a scheduleTransition field.

    _processSubscriptions: (
        subscriptions: ConnectionMessageSubscriptions | undefined,
    ) => void
    _processTestDonation: (donation: TiltifyDonationWithTestFlag) => void
    _processTwitchChatMessage: (msg: TwitchChatMessage) => void
    _setConnectionState: (connected: boolean, connecting: boolean) => void
    _setConnectionType: (type: "client" | "admin") => void
    _setHasReceivedInitialData: (value: boolean) => void
    _setIdentify: (fn: () => void) => void
    _setLastIdentityMessage: (message: ConnectionMessage) => void
    _setLastRefreshResponse: (msg: RefreshResponseMessage) => void
    _setRefresh: (fn: (filters?: RefreshCommandFilters) => void) => void
    _shouldConnect: boolean

    Internal connect trigger — set by connect() / disconnect().

    _updateCampaign: (
        campaign: TiltifyCampaign | TiltifyTeamCampaign,
        options?: { allowDecrease?: boolean },
    ) => void

    Merge an incoming campaign row into the store.

    By default, amount_raised / total_amount_raised are guarded by a monotonic-increase rule: an incoming value lower than the currently stored one is silently discarded (defends against out-of-order Tiltify webhooks blipping the top total down).

    Pass { allowDecrease: true } to bypass that guard — required for operator-initiated rewinds (e.g. the GreenRoom POST /_admin/tiltify/campaigns/:id/reset-donations endpoint, which broadcasts fact_updated with sourceType: "reset" and relies on the client actually applying the lower value).

    _updateDonationTrain: (train: DonationTrain) => void
    _updateDonorSpotlight: (spotlight: ComputedSpotlight) => void
    _updateDonorSpotlightSettings: (settings: DonorSpotlightSettings) => void
    _updateLeaderboardExclusionsForCampaign: (
        campaignID: string,
        exclusions: LeaderboardExclusion[],
    ) => void

    Replace leaderboardExclusions[campaignID] with a fresh list. Used by the updateLeaderboardExclusions realtime push. The server sends the full current list on every mutation so the client can treat this as a wholesale replace — no diff, no per-row merge. Pass an empty array to clear all exclusions for the campaign.

    _updateLeaderboardForCampaign: (
        campaignID: string,
        entries: TiltifyLeaderboardEntry[],
    ) => void

    Replace leaderboardEntries[campaignID] with a fresh top-N list. Used by the updateLeaderboard realtime push. The store keeps one flat entry per campaign because each connection subscribes to a single leaderboardTimeType at a time — the server sends the right slice per connection.

    _updatePollForCampaign: (
        campaignID: string,
        poll: TiltifyPoll,
        deltas?: PollOptionDelta[],
    ) => void

    Id-merge poll into polls[campaignID] and, when provided, record deltas under lastPollDeltas[poll.id]. Used by the updatePoll realtime push. Creates the campaign's polls array if absent.

    _updateScheduleForCampaign: (
        campaignID: string,
        schedule: ScheduleTransitionBlock[],
    ) => void

    Replace schedules[campaignID] with a fresh full schedule. Used by the updateSchedule realtime push. The server sends the full ordered array on every mutation so the client treats this as a wholesale replace — no diff, no per-block merge. Pass an empty array to clear the campaign's schedule.

    _updateSettingsFromServer: (settings: Partial<TiltifyWebSocketSettings>) => void
    _updateSubathonTimer: (timer: SubathonTimer) => void
    _updateTickData: (data: TiltifyTickMessageData) => void
    addCampaign: (
        campaign: TiltifyCampaign | TiltifyTeamCampaign,
        isTeam: boolean,
    ) => void
    addCampaignID: (id: string, isTeam: boolean, causeID?: string) => void
    addFundraisingEvent: (event: TiltifyFundraisingEvent) => void
    addFundraisingEventID: (id: string) => void
    adminApiKey: string | null
    auctionHouses: AuctionHouse[]
    autoConnect: boolean
    campaignIDs: string[]
    campaigns: TiltifyCampaign[]
    causeIDs: string[]
    causes: TiltifyCause[]
    charityType: CharityType
    connect: () => void
    connected: boolean
    connecting: boolean
    connectionType: "client" | "admin" | null
    disconnect: () => void
    donations: Record<string, TiltifyDonationWithTestFlag[]>
    donationTrains: Record<string, DonationTrain[]>
    donationTrainsEnabled: boolean
    donorSpotlightEnabled: boolean
    donorSpotlights: Record<string, ComputedSpotlight>
    donorSpotlightSettings: Record<string, DonorSpotlightSettings>
    fundraisingEventIDs: string[]
    fundraisingEvents: TiltifyFundraisingEvent[]
    fundraisingEventSupportingCampaigns: Record<string, TiltifyCampaign[]>
    getAllFundraisingEventSupportingCampaigns: () => TiltifyCampaign[]
    getDonations: (id: string) => TiltifyDonationWithTestFlag[]
    getDonationTrains: (
        id: string,
        withStatus?: DonationTrainStatus | null,
    ) => DonationTrain[]
    getDonorSpotlight: (id: string) => ComputedSpotlight | null
    getFirstCampaign: () => TiltifyCampaign | null
    getFirstCause: () => TiltifyCause | null
    getFirstFundraisingEvent: () => TiltifyFundraisingEvent | null
    getFirstTeamCampaign: () => TiltifyTeamCampaign | null
    getFundraisingEventSupportingCampaigns: (id: string) => TiltifyCampaign[]
    getLastScheduleTransition: (
        campaignID: string,
    ) => ScheduleTransitionPayload | null

    Fresh read of the latest schedule-block transition for a campaign, or null if none has been observed since the store was created / reset. Convenience wrapper over store.getState().lastScheduleTransitions[campaignID].

    getLeaderboardEntries: (id: string) => TiltifyLeaderboardEntry[]
    getLeaderboardExclusions: (campaignID: string) => LeaderboardExclusion[]

    Fresh read of the current exclusion list for a campaign. Returns an empty array when the server has not published one yet.

    getMilestones: (id: string) => TiltifyMilestone[]
    getPolls: (id: string) => TiltifyPoll[]
    getRewards: (id: string) => TiltifyReward[]
    getSchedule: (campaignID: string) => ScheduleTransitionBlock[]

    Fresh read of the last server-pushed schedule for a campaign. Returns an empty array when the server has not pushed one yet (fresh connection pre-identify, or campaign genuinely has no schedule). Same convention as getLeaderboardExclusions.

    getSubathonTimers: (
        id: string,
        withStatus?: SubathonTimerStatus | null,
    ) => SubathonTimer[]
    getSubscription: (id: string) => TiltifyWebhookSubscription | null
    getTargets: (id: string) => TiltifyTarget[]
    getTestDonations: (id: string) => TiltifyDonationWithTestFlag[]
    hasReceivedInitialData: boolean
    hasSetOverlayInfo: boolean
    identify: () => void

    Wired by createPipelineConnection. No-op before then.

    isUpdatingSettings: boolean
    lastFirehoseMessage: AdminWebhookFirehoseMessage | null

    Last admin-only webhook firehose message received.

    lastIdentified: Date | null
    lastIdentityMessage: ConnectionMessage | null
    lastMessage: WebSocketMessage | null
    lastPollDeltas: Record<string, PollOptionDelta[]>

    Latest server-computed deltas per poll, keyed by poll.id. Written by _updatePollForCampaign on every realtime updatePoll push. Absent for polls that have only ever arrived via tick (no prior snapshot to diff against on first push).

    lastRefreshResponse: RefreshResponseMessage | null
    lastScheduleTransitions: Record<string, ScheduleTransitionPayload>

    Latest schedule-block transition per campaign, keyed by campaignID. Written by _updateTickData (and its callee _processScheduleTransition) whenever a tick payload carries a scheduleTransition field. Steady-state ticks never mutate this map — the pipeline-side emitter only sends transitions on boundary crossings.

    Consumers subscribe via usePipelineLastScheduleTransition / useOnScheduleTransition from @playlive/react-pipeline.

    leaderboardEntries: Record<string, TiltifyLeaderboardEntry[]>
    leaderboardExclusions: Record<string, LeaderboardExclusion[]>

    Latest server-published exclusion list per campaign, keyed by campaignID. Replaced wholesale on each updateLeaderboardExclusions push (see _updateLeaderboardExclusionsForCampaign). Overlays that render off the WS leaderboardEntries slice should subtract this list client-side so a freshly-added exclusion takes effect without waiting for the next REST refetch cycle.

    Consumers subscribe via usePipelineLeaderboardExclusions / useOnLeaderboardExclusionsChange from @playlive/react-pipeline.

    messages: WebSocketMessage[]
    milestones: Record<string, TiltifyMilestone[]>
    overlayConfig: Record<string, string>
    overlayName: string
    overlayPath: string
    polls: Record<string, TiltifyPoll[]>
    refresh: (filters?: RefreshCommandFilters) => void

    Wired by createPipelineConnection. Admin-only.

    removeCampaign: (
        campaign: TiltifyCampaign | TiltifyTeamCampaign,
        isTeam: boolean,
    ) => void
    removeCampaignID: (id: string, isTeam: boolean) => void
    removeFundraisingEvent: (event: TiltifyFundraisingEvent) => void
    removeFundraisingEventID: (id: string) => void
    reset: (type: CharityType) => void
    rewards: Record<string, TiltifyReward[]>
    schedules: Record<string, ScheduleTransitionBlock[]>

    Latest server-published full schedule per campaign, keyed by campaignID. Replaced wholesale on each updateSchedule push (see _updateScheduleForCampaign). Empty array means the campaign has no schedule; absent key means the server has not pushed one yet.

    Introduced in Phase 35. The Phase 34 lastScheduleTransitions slice still tracks boundary crossings (current + next only) and is unaffected; consumers that want a full array should prefer this slice via usePipelineSchedule from @playlive/react-pipeline. useLiveSchedule (fusion) reads this slice first and only falls back to the transition-derived synthesis or REST when it's absent — the wholesale replace preserves that fallback order without leaking stale state on re-identify (see reset).

    setAdminApiKey: (key: string | null) => void
    setAutoConnect: (autoConnect: boolean) => void
    setCurrentType: (type: CharityType) => void
    setCurrentURL: (url: string) => void
    setOverlayInfo: (info: OverlayInfo) => void
    setTwitchUsername: (username: string | null) => void
    subathonTimerEnabled: boolean
    subathonTimers: Record<string, SubathonTimer[]>
    subscriptions: Record<string, TiltifyWebhookSubscription>
    targets: Record<string, TiltifyTarget[]>
    teamCampaignIDs: string[]
    teamCampaigns: TiltifyTeamCampaign[]
    teamUserSlug: string
    testDonations: Record<string, TiltifyDonationWithTestFlag[]>
    tiltifySettings: TiltifyWebSocketSettings
    toggleDonationTrains: (enable: boolean) => void
    toggleDonorSpotlight: (enable: boolean) => void
    toggleSubathonTimer: (enable: boolean) => void
    twitchChatMessages: TwitchChatMessage[]
    twitchUsername: string | null
    updateTiltifySettings: (
        settings: Partial<TiltifyWebSocketSettings>,
        sendBackToServer: boolean,
    ) => void
    wsURL: string