import { describe, expect, it, vi } from 'vitest' import { KVOutbox, type OutboxEntry } from '../../src/kv-storage/kv-outbox.js' import { KVStorageInMemory } from '../../src/kv-storage/kv-storage-in-memory.js' import { RetryTimer } from '../../src/utils/retry-timer.js' import { StorageUnavailableError } from '../../src/utils/errors.js' describe('KVOutbox', () => { it('replays entries in order once the source is reachable, and survives a restart', async () => { const store = new KVStorageInMemory() let online = false const sent: OutboxEntry[] = [] const send = async (entry: OutboxEntry) => { if (!online) throw new StorageUnavailableError('offline') sent.push(entry) } const firstRetry = new RetryTimer({ baseDelay: 5, maxDelay: 5 }) const first = new KVOutbox(store, send, firstRetry) await first.push({ type: 'write', entries: [['a', 1]] }) await first.push({ type: 'remove', keys: ['a'] }) expect(first.size).toBe(2) expect(first.pending.has('a')).toBe(true) firstRetry.stop() // the first session ends... await first.replay() // ...once its in-flight replay attempt has failed // A new session over the same store picks up the queue. const second = new KVOutbox(store, send, new RetryTimer({ baseDelay: 5, maxDelay: 5 })) online = true await second.load() await vi.waitFor(() => expect(second.size).toBe(0)) expect(sent).toEqual([ { type: 'write', entries: [['a', 1]] }, { type: 'remove', keys: ['a'] }, ]) expect(await store.readMany(['~q/o/000000000001', '~q/o/000000000002'])).toEqual([undefined, undefined]) }) })