import { Injectable } from '@angular/core'; import { buildAttachmentChunkAckKey } from '../../domain/logic/attachment-chunk-ack.rules'; @Injectable({ providedIn: 'root' }) export class AttachmentChunkAckService { private readonly waiters = new Map void>(); waitForAck( messageId: string, fileId: string, index: number, timeoutMs = 60_000 ): Promise { const key = buildAttachmentChunkAckKey(messageId, fileId, index); return new Promise((resolve, reject) => { const timer = setTimeout(() => { this.waiters.delete(key); reject(new Error('attachment chunk ack timeout')); }, timeoutMs); this.waiters.set(key, () => { clearTimeout(timer); this.waiters.delete(key); resolve(); }); }); } resolveAck(messageId: string, fileId: string, index: number): void { this.waiters.get(buildAttachmentChunkAckKey(messageId, fileId, index))?.(); } cancelPendingForFile(messageId: string, fileId: string): void { const prefix = `${messageId}:${fileId}:`; for (const [key, resolve] of this.waiters) { if (!key.startsWith(prefix)) { continue; } resolve(); this.waiters.delete(key); } } }