tonsky/datascript

equality on ^Entity bypasses db

dustingetz opened this issue · 3 comments

Here:

;; (= db (.-db ^Entity that))

This breaks reactive programming semantics where, when db updates, (d/entity db x) updates but the result is = to the prior result and therefore continuous time reactive engines will skip downstream computation, reusing a buffered prior instance of the entity that is inconsistent with the latest db.

Appears to have been introduced in 8264eb0 , and seems not deeply considered – will you accept a PR uncommenting that check? What needs to be tested?

I don’t remember why we removed db check here. But comparing DBs might be expensive. How about identical? here? Would that work for you?

Provided fix accounts for db in entity equality, using identical?.

The following test is interesting. It shows this is not a perfect solution, but the tradeoff is acceptable for us.

(deftest test-entity-equality
  (let [db1 (-> (d/empty-db {})
              (d/db-with [{:db/id 1, :name "Ivan"}]))
        db2 (d/db-with db1 [])]
    (testing "Two entities are equal if they have the same :db/id and refer to the same database"
      (is (= db1 db2))
      (is (not= (d/entity db1 1) (d/entity db2 1))))))

Thanks! Pushed 1.3.14