Fork me on GitHub
#membrane
<
2021-03-21
>
phronmophobic07:03:24

This is something I'm currently working on providing better support for. I'll try to write a more detailed explanation soon. If you look at a reference, they look something like:

[(keypath :todos) 
 (nth 0)
 (keypath :complete?)]
which the equivalent query for a nested data structure would be something like:
(get-in state [:todos 0 :complete?])
If you wanted wanted to set the value at that reference, it's not too complicated to write a function that could accept the reference and set the value in a nested data structure:
(def $ref [(keypath :todos) (nth 0) (keypath :complete?)])
(set-nested state $ref true) 
Similarly, if there is a schema, it's possible to take the same reference and provide versions of read, update, delete, and set for databases.
(get-ref db $ref)
(update-ref db $ref f & args)
(delete-ref db $ref)
(set-ref db $ref v)
To make this work for a datomic-like database, you really only need to know if attributes are :db.cardinality/many and/or :db.type/ref so you could expand
(def $ref [(keypath :todos) (nth 0) (keypath :complete?)])
(set-ref db $ref true)
into:
(d/transact! conn
             [[:db/add 11 :complete? true]])

phronmophobic07:03:02

I've been hesitant to document the data format used for references since it's currently an implementation detail. The reference format was initially modeled after https://github.com/redplanetlabs/specter navigator paths since that the library I use for updating nested data structures, but it's possible that basing references on something like https://pathom3.wsscode.com/docs/ might be a better fit.

jlmr09:03:43

Thanks for the explanation! Funny, I’ve been looking at Pathom as well and have been trying to work out how to combine it with it membrane

jlmr09:03:09

Not much progress there yet though 😬