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?(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