pub(crate) fn apply_shadow_projection(state: &Arc<AppState>, event: &Event)Expand description
Apply a launcher event to host’s shadow projections, then fan the event out to every top-level renderer via the JS bridge.
Shadows are updated FIRST so any renderer-side code that reads
host state via the IPC HTTP path (e.g. listWindowInstances)
sees a consistent view at the moment the typed event lands.
Phase B.7.3.3 — the bespoke window-instances-changed re-emit
is gone; renderers now consume typed events directly via the
CEF JS bridge dispatcher (launcher_event_bridge).
Pure shadow-state projection — extracted from apply_event_to_shadow
for property testing per master spec §8.14 (subscriber idempotency
contract). Mutates ONLY the shadow Mutexshadow_instance_registry, shadow_window_meta,
shadow_backend_window_ids. No UI tasks, no renderer dispatch, no
CEF calls — those live in the wrapper apply_event_to_shadow.
Idempotent by construction: every arm is HashMap::insert /
HashMap::remove keyed by label, both naturally idempotent past
the first call. The drift-compare branch in WindowOpened is
read-only (logs a warning, doesn’t mutate). Locked in by the
shadow_projection_idempotent_under_replay proptest.