| 1 | export type GuidanceReceiptTracker = { |
| 2 | start(draftKey: string): void; |
| 3 | recordConsumed(draftKey: string, itemId: string): void; |
| 4 | takeConsumed(draftKey: string, itemId: string): boolean; |
| 5 | finish(draftKey: string): void; |
| 6 | }; |
| 7 | |
| 8 | export function createGuidanceReceiptTracker(): GuidanceReceiptTracker { |
| 9 | const inFlight = new Map<string, number>(); |
| 10 | const consumedBeforeReceipt = new Map<string, Set<string>>(); |
| 11 | return { |
| 12 | start(draftKey) { |
| 13 | inFlight.set(draftKey, (inFlight.get(draftKey) ?? 0) + 1); |
| 14 | }, |
| 15 | recordConsumed(draftKey, itemId) { |
| 16 | if ((inFlight.get(draftKey) ?? 0) === 0) return; |
| 17 | const consumed = consumedBeforeReceipt.get(draftKey) ?? new Set<string>(); |
| 18 | consumed.add(itemId); |
| 19 | consumedBeforeReceipt.set(draftKey, consumed); |
| 20 | }, |
| 21 | takeConsumed(draftKey, itemId) { |
| 22 | return consumedBeforeReceipt.get(draftKey)?.delete(itemId) ?? false; |
| 23 | }, |
| 24 | finish(draftKey) { |
| 25 | const remaining = (inFlight.get(draftKey) ?? 1) - 1; |
| 26 | if (remaining > 0) { |
| 27 | inFlight.set(draftKey, remaining); |
| 28 | return; |
| 29 | } |
| 30 | inFlight.delete(draftKey); |
| 31 | consumedBeforeReceipt.delete(draftKey); |
| 32 | }, |
| 33 | }; |
| 34 | } |
| 35 |