Bug
Live queries with joins don't update when a Temporal date field changes on a row. Simple queries (no joins) work fine.
Cause
The hashing function in db-ivm uses Object.keys() to structurally hash objects. Temporal dates have no enumerable own properties, so Object.keys() returns [] and every Temporal date hashes to the same value regardless of the actual date.
When a Temporal date changes on a row, the join index sees hash(oldRow) === hash(newRow), treats them as identical, and the -1 and +1 multiplicities cancel out. The update gets silently swallowed.
Reproduction
Works: q.from({ todo: todoCollection })
Broken: q.from({ todo: todoCollection }).innerJoin({ list: listCollection }, ({ todo, list }) => eq(todo.list_id, list.id)).select(({ todo, list }) => ({ todo, list }))
Updating a Temporal date field (e.g. dueDate) on a todo will not propagate through the live query when a join is involved.
Proposed fix
In hashObject() in packages/db-ivm/src/hashing/hash.ts, detect Temporal objects via Symbol.toStringTag and hash them by their toString() representation instead of by enumerable keys.
Bug
Live queries with joins don't update when a Temporal date field changes on a row. Simple queries (no joins) work fine.
Cause
The hashing function in
db-ivmusesObject.keys()to structurally hash objects. Temporal dates have no enumerable own properties, soObject.keys()returns[]and every Temporal date hashes to the same value regardless of the actual date.When a Temporal date changes on a row, the join index sees
hash(oldRow) === hash(newRow), treats them as identical, and the -1 and +1 multiplicities cancel out. The update gets silently swallowed.Reproduction
Works:
q.from({ todo: todoCollection })Broken:
q.from({ todo: todoCollection }).innerJoin({ list: listCollection }, ({ todo, list }) => eq(todo.list_id, list.id)).select(({ todo, list }) => ({ todo, list }))Updating a Temporal date field (e.g.
dueDate) on a todo will not propagate through the live query when a join is involved.Proposed fix
In
hashObject()inpackages/db-ivm/src/hashing/hash.ts, detect Temporal objects viaSymbol.toStringTagand hash them by theirtoString()representation instead of by enumerable keys.