import React from 'react'; export interface TicketLiveContextValue { /** Viewer has a resolved, non-anon chat identity. Surfaces (e.g. the * header cell) hide themselves when false — computed here so they * don't each spin up their own identity resolution. */ authed: boolean; /** Realtime-subscribed (server-confirmed), not merely HTTP-open. */ connected: boolean; /** Unread total across tickets — drives the header count badge. */ unreadTotal: number; /** Per-ticket unread counts (missing key = 0) — drives row dots. * The currently-open ticket is masked to 0. */ unreadByTicket: Record; /** The ticket with the NEWEST unread reply (open ticket excluded) — * the header cell routes to it via the SSOT deep link * (`buildTicketOpenHref`). Null when nothing is unread. */ nextUnreadTicketId: string | null; /** Mark a ticket read: POSTs the receipt, zeroes the ticket locally * (0-latency), then applies the response's server-computed summary. */ markRead: (ticketExternalId: string) => Promise; /** Drawer open/close registration — suppresses unread bumps for the * open ticket and masks it in the derived map. */ setOpenTicketId: (ticketExternalId: string | null) => void; /** Hint that the viewer just created a ticket — reconnects the stream * (fresh ownership set + fresh server-pushed summary). */ notifyTicketCreated: () => void; } export declare function useOptionalTicketLive(): TicketLiveContextValue | null; export declare function useTicketLive(): TicketLiveContextValue; export interface TicketLiveProviderProps { children: React.ReactNode; /** * Whether ticket realtime is available to this host at all (feature flag, * session, entitlement). `false` provides NO context — `useOptionalTicketLive()` * reads `null`, `useTicketLive()` throws, and no identity or stream request is * made: byte-for-byte what a host got by not mounting this at all. * * It exists so a host never has to mount this CONDITIONALLY. A host that writes * `enabled ? {children} : <>{children}` * changes the element TYPE at that position the moment its flag answers, and React * tears down and remounts everything below. In openframe-frontend that wrapper sat * around the whole `AppLayout`, so every cold load remounted the app shell and the * page under it — visibly, as a chat drawer opened by a deep link replaying its * open animation. Mount it always and pass the answer here instead. * * One consequence of mounting it always: a `ChatRuntime` must be above it even * while disabled. The identity resolver reads one unconditionally (Rules of * Hooks) and throws without it; `enabled` gates the request, not the read. */ enabled?: boolean; } export declare function TicketLiveProvider({ children, enabled }: TicketLiveProviderProps): React.JSX.Element; //# sourceMappingURL=ticket-live-provider.d.ts.map