Add purpose, architecture, and public API summary to each crate README following chanora_resolver pattern. Update verification master plan with new evidence sources and entry/exit criteria.
65 lines
2.9 KiB
Markdown
65 lines
2.9 KiB
Markdown
# chanora_state
|
|
|
|
Authoritative client-side mirror of server state: channel tree, client list, and connection lifecycle. Owns the reducers that fold protocol events into state and produce deltas for the bridge (per SAD §7.2 and SDD §5).
|
|
|
|
## Architecture
|
|
|
|
### Core reducer pattern
|
|
|
|
The crate exposes a single `reduce(state: &mut Option<ServerState>, event: StateEvent) -> Reduction` function. Callers own state storage and pass it by `&mut`. The reducer returns a `Reduction` containing only the emitted `Delta` values. This satisfies:
|
|
|
|
- **SRS-056** — deterministic deltas: the same `(state, event)` always produces the same `Reduction`
|
|
- **SRS-057** — per-connection ordering
|
|
- **SRS-058** — reducer functions are pure
|
|
|
|
### Module: `channel_join`
|
|
|
|
A more specialized reducer for voice-channel join/leave state tracking with:
|
|
- Optimistic `UserJoinRequested` events
|
|
- `AuthoritativeSelfMove` confirmation from live deltas
|
|
- `SnapshotReady` reconciliation after connects/reconnects
|
|
- `ChannelJoinProjection` for UI rendering (in_channel, can_join, can_leave, sync_state)
|
|
- `ConnectionEpoch` tracking to disambiguate stale events across reconnects
|
|
|
|
### State model
|
|
|
|
- `ServerState` — owned `HashMap<u64, ChannelInfo>` and `HashMap<u64, ClientInfo>` with stable ordering vectors. Built from `ServerSnapshot`, updated incrementally via `StateEvent`s.
|
|
- `ConnectionState` — enum: Idle / Connecting / Ready / Reconnecting / Lost
|
|
|
|
## Public API Summary
|
|
|
|
### Types
|
|
|
|
| Type | Role |
|
|
|---|---|
|
|
| `ServerState` | Authoritative mirror of connected server state |
|
|
| `ConnectionState` | Lifecycle enum (Idle, Connecting, Ready, Reconnecting, Lost) |
|
|
| `StateEvent` | Protocol-layer input events (Snapshot, ChannelChanged, ClientChanged, etc.) |
|
|
| `Delta` | Bridge output events (SnapshotApplied, ChannelUpserted, ClientRemoved, etc.) |
|
|
| `Reduction` | Result of `reduce()`: a `Vec<Delta>` |
|
|
| `StateError` | Reducer errors (Unknown entity, invariant violation) |
|
|
|
|
### Key functions
|
|
|
|
- `reduce(state, event)` → `Reduction` — apply a protocol event, return deltas
|
|
- `reduce_reconnect_snapshot(state, snap)` → `Reduction` — replace all state on reconnect (SRS-059)
|
|
|
|
### `ServerState` methods
|
|
|
|
- `channel(id)` / `client(id)` — lookup by id
|
|
- `channels()` / `clients()` — ordered iterators
|
|
- `own_channel()` — the channel our client is in
|
|
- `clients_in_channel(channel_id)` — filtered iterator
|
|
|
|
### `channel_join` module
|
|
|
|
- `reduce(state, event)` → `JoinReduction` — channel-join state machine
|
|
- `project(state)` → `ChannelJoinProjection` — UI-ready snapshot
|
|
- `ChannelJoinEvent`, `ChannelJoinState`, `ChannelJoinProjection` — state machine types
|
|
|
|
## Design notes
|
|
|
|
- Events are ignored when state is `None` (disconnected), except `Snapshot` (creates state) and `ConnectionChanged`.
|
|
- Deleting a channel also removes all clients in that channel.
|
|
- Duplicate IDs in snapshots are deduplicated deterministically.
|