// Only a new, recent, authoritative transition can trigger an effect. // Initial loads, duplicate acknowledgements and old replayed events stay silent. export function roomSound(previous, next, now = Date.now()) { if (!previous || previous.id !== next.id) return null; if (next.result?.cancelled || next.events?.at(-1)?.type === 'leave') return null; if (previous.status === 'waiting' && next.status === 'playing') return 'start'; const last = next.events?.at(-1); if (!last || last.sequence <= (previous.events?.at(-1)?.sequence ?? 0)) return null; const age = now - Date.parse(last.createdAt); if (age < -5000 || age > 5000) return null; if (next.status === 'finished' && previous.status !== 'finished') { const outcome = next.players.find((p) => p.seat === next.seat)?.outcome; return outcome === 'win' ? 'win' : outcome === 'loss' ? 'loss' : 'draw'; } return last.sound ?? 'move'; }