import type { OrchestrationEvent, ThreadId } from "@t3tools/contracts"; export interface OrchestrationBatchEffects { promoteDraftThreadIds: ThreadId[]; clearDeletedThreadIds: ThreadId[]; removeTerminalStateThreadIds: ThreadId[]; needsProviderInvalidation: boolean; } export function deriveOrchestrationBatchEffects( events: readonly OrchestrationEvent[], ): OrchestrationBatchEffects { const threadLifecycleEffects = new Map< ThreadId, { clearPromotedDraft: boolean; clearDeletedThread: boolean; removeTerminalState: boolean; } >(); let needsProviderInvalidation = false; for (const event of events) { switch (event.type) { case "thread.turn-diff-completed": case "thread.reverted": { needsProviderInvalidation = true; break; } case "thread.created": { threadLifecycleEffects.set(event.payload.threadId, { clearPromotedDraft: true, clearDeletedThread: false, removeTerminalState: false, }); break; } case "thread.deleted": { threadLifecycleEffects.set(event.payload.threadId, { clearPromotedDraft: false, clearDeletedThread: true, removeTerminalState: true, }); break; } case "thread.archived": { threadLifecycleEffects.set(event.payload.threadId, { clearPromotedDraft: false, clearDeletedThread: false, removeTerminalState: true, }); break; } case "thread.unarchived": { threadLifecycleEffects.set(event.payload.threadId, { clearPromotedDraft: false, clearDeletedThread: false, removeTerminalState: false, }); break; } default: { break; } } } const promoteDraftThreadIds: ThreadId[] = []; const clearDeletedThreadIds: ThreadId[] = []; const removeTerminalStateThreadIds: ThreadId[] = []; for (const [threadId, effect] of threadLifecycleEffects) { if (effect.clearPromotedDraft) { promoteDraftThreadIds.push(threadId); } if (effect.clearDeletedThread) { clearDeletedThreadIds.push(threadId); } if (effect.removeTerminalState) { removeTerminalStateThreadIds.push(threadId); } } return { promoteDraftThreadIds, clearDeletedThreadIds, removeTerminalStateThreadIds, needsProviderInvalidation, }; }