Files
amethyst/quartz
Claude 8517bae7a4 feat(quartz): replace items + ready with sealed ProjectionState
EventStoreProjection now exposes `state: StateFlow<ProjectionState<T>>`
instead of separate `items` + `ready` signals. ProjectionState is a
sealed interface with two cases:

  data object Loading                                  // initial state
  data class Loaded(items: List<MutableStateFlow<T>>)  // post-seed view

This lets the UI distinguish "still seeding" from "seeded but empty"
— the previous `emptyList()` initial value conflated the two. Future
extension to `Failed(throwable)` is a single case addition.

The `ready: CompletableDeferred<Unit>` signal is gone; callers use
`state.first { it is Loaded }` (or the test `awaitReady()` helper).

Test fixtures gain two private extensions on EventStoreProjection<T>:
- val items: List<MutableStateFlow<T>> — terse access to the loaded
  list (returns empty if still seeding).
- suspend awaitReady() — replaces ready.await().

awaitItems(predicate) now matches against the Loaded state. 17/17
projection + 240/240 store + interner tests pass.

https://claude.ai/code/session_01Jny85MTu1ynKgFBgysfWu5
2026-04-30 15:20:45 +00:00
..