datascript

2024-12-23T21:12:43.324509Z

Any advice on how to do tree manipulations? I'm not sure how I feel about this function which inserts a new node x after an existing one entity :

(defn insert-after
  [entity x]
  (let [parent-box (:box/_children entity)
        new-sibling (assoc x :orderable/order (inc (:orderable/order entity)))
        new-db (d/db-with (d/entity-db entity)
                          (concat
                           [{:db/id (:db/id parent-box) :box/children new-sibling}]

                           ;;update order of all following children, if any
                           (->> (:box/children parent-box)
                                (remove #(< (:orderable/order %) (:orderable/order new-sibling)))
                                (map (fn [c]
                                       [:db/add (:db/id c) :orderable/order (inc (:orderable/order c))])))))]
    (d/entity new-db (:db/id entity))))
In particular I'm not sure what the "right" return value should be. I made it the original entity since at my callsite I'm inserting a bunch of things and so I can (reduce insert-after target new-nodes) . However I can see a strong case that the return should be the new node OR the new database. If the return value is the new database, I'd be inclined to make the function signature [db target new-sibling] but that itself feels a bit weird since the db can be had from target . Maybe [db target-eid x] then?

refset 2025-01-08T18:10:08.536569Z

(having now read this again properly with a focused brain 🙂) I imagine you can't go too wrong following established zipper API patterns here, so https://clojuredocs.org/clojure.zip/insert-right is essentially what you have built ...which seems sound to me 👍 > Inserts the item as the right sibling of the node at this loc, without moving