Removing a chip can emit one item twice and silently drop another.
When a chip is removed, the picker rebuilds the value by looking each remaining chip up in value by its stringified chip id. Chip ids are not unique — items sharing a value id, or having none, produce the same id — so with three items where two of them collide, removing the third leaves the lookup matching the first collider twice: it is emitted duplicated and the
second one is lost.
Suggested direction
A chip already carries the item it was made from (createChip sets value: listItem), so there is nothing to look up: mapping through chip.value keeps every remaining item, once, in order, and cannot produce undefined.
That does not fix the underlying collision — limel-chip-set still removes chips that share an id as a group, since it filters on the id. Doing something about that needs a decision about items the consumer gave no id: generate one, or require one.
Found while reviewing #4223.
Removing a chip can emit one item twice and silently drop another.
When a chip is removed, the picker rebuilds the value by looking each remaining chip up in
valueby its stringified chip id. Chip ids are not unique — items sharing a value id, or having none, produce the same id — so with three items where two of them collide, removing the third leaves the lookup matching the first collider twice: it is emitted duplicated and thesecond one is lost.
Suggested direction
A chip already carries the item it was made from (
createChipsetsvalue: listItem), so there is nothing to look up: mapping throughchip.valuekeeps every remaining item, once, in order, and cannot produceundefined.That does not fix the underlying collision —
limel-chip-setstill removes chips that share an id as a group, since it filters on the id. Doing something about that needs a decision about items the consumer gave no id: generate one, or require one.Found while reviewing #4223.