Files
qbz/crates
vicrodh 63d9f6b496 refactor(qconnect): route liveness/lifecycle/diagnostic emits through event sink (slice 3)
Add five QconnectAppEvent variants (RendererUnreachable, RendererDisconnected,
ResyncComplete, LifecycleChanged, Diagnostic) and a Tauri mapper so the
session/liveness/diagnostic signals flow through the QconnectEventSink trait
instead of raw app_handle.emit calls. Move QconnectLifecycleState into
qconnect-app (pure data); Tauri types.rs re-exports it for the command surface.

No logic moves: the session logic still lives Tauri-side but now calls
sink.on_event(variant) at each rewired emit site. The sink mapper turns each
variant back into the exact same qconnect:* channel + payload, so the Svelte
wire surface is byte-identical. Each dedicated channel still fires exactly once
per occurrence (raw emits are replaced, not duplicated). The blanket
qconnect:event emit now also carries the new variants, which is additive and
ignored by the Svelte listener (pattern-matches known keys only).

Rewired emit sites:
- event_sink.rs freeze helper now takes/emits the freeze variant
  (RendererUnreachable/RendererDisconnected); the mapper emits the dedicated
  channel. State mutation precedes on_event and the variant arms only emit, so
  there is no re-entrancy/recursion into the watchdog/session dispatch.
- service.rs resync-complete -> ResyncComplete; inbound_queue_event/cloud_error/
  max_reconnect -> Diagnostic; update_lifecycle_state_if_running -> LifecycleChanged.

Tests: add qconnect-app unit tests asserting the new variants flow through a
sink and that QconnectLifecycleState serializes snake_case (matching the wire
payload). crates green (qconnect-app 33 passed); src-tauri cargo test qconnect
42 passed.

cc
2026-06-01 09:20:12 -06:00
..