WIP: plain operations, simpler composite (does not build or pass tests yet)

In progress, not for review:
- KV adapters reduced to readMany/scan/write; writeIfAbsent removed
- server executes operations verbatim; SSE relays changes, no history
- composite rewritten as a combination of stores with a queue store
- client-id echo tagging (to be removed per review)

Events, event-sourced documents, tests and docs still to be updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
This commit is contained in:
Claude
2026-10-23 13:18:15 +00:00
parent 1f82ec9110
commit fe751f246e
12 changed files with 260 additions and 753 deletions
-36
View File
@@ -1,36 +0,0 @@
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])
})
})