import type { DurableJournal } from "@claudexor/journal"; /** * GLOBAL-partition emitter of `thread.head.updated` — the content-free sidebar * invalidation ping `{thread_id, project_id, revision}`. * * Thread mutations persist to their OWNING partition (`project:{id}` for * project threads), which the app's single global stream never sees. This * projection holds a handle on the GLOBAL journal so every ThreadStore can * announce "this thread's summary changed" on the one stream consumers already * follow. Content-free by contract: no thread data rides the ping — consumers * refetch the authoritative ThreadSummary from the thread endpoints. * * `revision` is a monotonic per-thread counter, journal-backed so it survives * daemon restarts: consumers may drop a ping whose revision they have already * reflected without ever trusting payload content. */ export declare class ThreadHeadPingEmitter { private readonly journal; private readonly revisions; constructor(journal: DurableJournal); private replay; ping(input: { threadId: string; projectId: string | null; }): void; /** Last emitted revision for a thread (0 = never pinged). */ revision(threadId: string): number; validateProjection(): void; } export declare function threadHeadPingProjection(): { name: string; create: (journal: DurableJournal) => ThreadHeadPingEmitter; validate: (emitter: ThreadHeadPingEmitter) => void; }; //# sourceMappingURL=thread-head-ping.d.ts.map