mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-09-07 15:07:17 +00:00
DeviceStatus.Revision is per-connection and restarts at 0. The browser compares revisions to decide which frame wins, but nothing in the frame said which revision sequence it belonged to. So a device id backed by a fresh DeviceConnection published revisions starting at 0 while an open tab still held a high revision for that id, and the tab rejected every later frame for it: a status frozen until reload. HandleDeleteDevice broadcasts after removal, which covers the ordinary remove-then-rediscover path, but a discovery sweep re-adding the host inside that window yields a snapshot that already contains the device at revision 0, so no device-less snapshot is ever sent. Every status now carries an Epoch identifying the connection that produced it, stamped by both SetStatus and UpdateStatus. The browser compares epochs first and only falls back to revisions within one epoch, so a newer connection is accepted regardless of its revision and a frame still in flight from the replaced connection is rejected regardless of its. nextStatusEpoch is seeded from the wall clock and forced strictly increasing, so epochs also keep rising across a service restart, where a plain counter would restart at 0 and reintroduce the same problem. It is in milliseconds because the browser compares it as a JSON number and a nanosecond timestamp exceeds Number.MAX_SAFE_INTEGER. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>