Yeah, I’d maybe make a set of just the position IDs, and do a negated .has() of that set to check if the cursor was removed.
ws.onmessage = function(event) {
const positionIds = new Set(positions.map(pos => pos.id));
Object.keys(cursors).forEach((id) => {
if (!positionIds.has(id)) {
document.body.removeChild(cursors[id]);
delete cursors[id];
}
});
};
Untested but that’s probably pretty close for phone typing