Fork me on GitHub
#untangled
<
2017-01-13
>
sova-soars-the-sora01:01:31

Could someone explain how the pull syntax works with the ellipsis ( ... ) on this line?

adambrosio01:01:42

@sova that’s just saying it’ll pull a collection iirc it should return [name1 name2 …] instead of something weird like [[name1] [name2]]

sova-soars-the-sora01:01:59

Oh cool. Ah that makes some sense. Man, I just found Datascript... super stoked to have a client-side "db"

adambrosio01:01:43

yeah at navis/untangled we’ve tried datascript but found it slow and unnecessary for the client db when simple map lookups work fine and fast but maybe @tony.kay might have more to say on that

sova-soars-the-sora01:01:54

when you say "map lookups" ... data is stored on the client-side but in a different way?

tony.kay01:01:37

@sova why do you care about a client-side datomic database (e.g. Datascript)? There are good use-cases...I'm just wondering what yours is

sova-soars-the-sora01:01:36

Thinking forward to mobile versions, I want users to be able to browse lots (~100s) of articles without the need to constantly ask the server. And it will probably help me in learning read/mutate better, since I know Datomic well, but am still having trouble wrapping my mind around how it interops with omnext

tony.kay01:01:10

so, that would not be a use-case I'd involve datascript for

sova-soars-the-sora01:01:23

Really the main benefit is offline enjoyment of resources.. perhaps there are alternatives

tony.kay01:01:35

you're talking format, not the ability to offline

tony.kay01:01:46

Datascript stores data...so does a map

tony.kay01:01:57

so does a vector

tony.kay01:01:30

Datascript gives you a high-end parser of Datalog to do complex data operations. Using it for holding a collection is like putting in a thumbtack with a 50lb sledgehammer

sova-soars-the-sora01:01:17

Haha, well that's an illustrative way to put it. Do you think it'll slow down things considerably to "bog down the browser" with a Datascript instance?

tony.kay01:01:50

So, it will increase app load time (bigger js footprint), but not terribly. The thing is, how do you plan to use it?

tony.kay01:01:21

If using Untangled, you're going to...what...write a mutation that does a datascript query to copy data from datascript into your UI?

tony.kay01:01:06

If using Om Next, you write parser emitters for the query that would query datascript, but that is going to make your UI slower, because running a query is a heck of a lot slower than looking things up in a map(what Untangled does)

tony.kay01:01:59

and how do you populate your Datascript database? With a network request. Well, Untangled already gives you that ability, and can pull the result into it's app database (and cache it there).

tony.kay01:01:20

client local storage could be used to cache either for offline access

tony.kay01:01:20

so, it has a cool factor, but from my perspective you've done nothing but added incidental complexity

tony.kay01:01:56

For completeness: a good use-case for datascript is you want to download a bunch of data for analysis that will use the user's CPU. Put it in datascript and write the data analysis in cljs, and then you actually want datalog support on the client.

tony.kay01:01:14

kind of a trade network overhead for CPU

sova-soars-the-sora01:01:42

It's a bit of a tangential approach, but I'm thinking of working in steps. I don't mind the slow-down because the javascript app object already takes a few seconds to be mounted. Yeah, it requires a network request. To my naive beginners' eyes it seems cleaner than playing directly with an app-state atom on the client. I think it'll make it easier to reason about my app (long) into the future, though.

tony.kay01:01:12

welp, feel free. The worst that can happen is learning 🙂

sova-soars-the-sora01:01:24

Correct me if i'm not, but there's basically the Datomic-friendly read (for :remote true) and then there's the local client-side atom read ... I just like the idea of the code reuse, but it might verywellbe overkilll.

sova-soars-the-sora01:01:05

I see what you mean for a good use-case. There really isnot a lot of computation in my application. Just a lot of text sharing between server and client.

tony.kay01:01:11

In Untangled, you don't have to write any read on the client. ever.

sova-soars-the-sora01:01:37

Okay I must have missed that, since that is news to me.

tony.kay01:01:42

the remote thing sends the read over the network

tony.kay01:01:11

the response to the client read from datomic is automatically merged into the app database. There is no work for you to do.

tony.kay01:01:18

In stock Om next, there is a ton to do (network pipeline, merge augmentation, satisfying client read, etc.)

tony.kay01:01:46

Untangled exists so you don't have to do all that

sova-soars-the-sora01:01:50

Right! So much haha. But you're saying that that's all flattened out in untangled...

tony.kay01:01:08

no, we use the default app state atom format of Om Next (graph db in a map)

tony.kay01:01:16

not flattened

tony.kay01:01:24

(well, it is a form of flattening)

tony.kay01:01:29

Have you followed along on the dev guide tutorials and written a full-stack app yet?

sova-soars-the-sora01:01:43

Datascript appeals to me because I never ever want to touch db->tree.

tony.kay01:01:16

1. db->tree is cool. Don't knock it 😉 2. Untangled calls db->tree for you. So you don't have to

tony.kay01:01:42

what you do have to do is make sure your app db has what you're asking for

sova-soars-the-sora01:01:44

I'm working on an app, but starting from scratch (is good for the learns.) It just seems like an unbridge-able chasm at the moment to negotiate between the app-state atom and my datomic store

tony.kay01:01:08

@sova then you have not learned the primitives properly yet.

sova-soars-the-sora01:01:16

Such is my suspicion, haha.

tony.kay01:01:22

not only is it bridgeable, it is nearly trivial 😉

tony.kay01:01:39

thus my opinion that adding in Datascript takes you backwards

tony.kay01:01:43

it makes it harder

sova-soars-the-sora01:01:55

Man once I get this working I am going to write some awesome articles about doing all this stuff (to help the documentation efforts of all these wonderful things)

tony.kay01:01:05

Did you find the YouTube getting started videos?

tony.kay01:01:17

There are so many resources to walk you through this 🙂

sova-soars-the-sora01:01:34

Yeah? Okay, that's good to keep in mind, that datascript would kinda be a move in the opposite direction.

tony.kay01:01:41

devguide, ref manual, videos, cookbook

sova-soars-the-sora01:01:19

I have played with the devcards a bit, they are very helpful.

sova-soars-the-sora01:01:47

It's a little tough to find out exactly what knowledge I need to make everything tie together. Currently seems like a Rubiks' Cube

sova-soars-the-sora01:01:55

Messy messy messy until it all comes together at a point

tony.kay01:01:50

there's a playlist of these, but this one demos doing server integration. Imagine datomic satisfying the server query (1-2 lines of code)...the rest is the same

sova-soars-the-sora01:01:45

Hmm. So there are just a few magic lines to add to ask Datomic for all the goods... Is that where (db->tree) comes into play? Translating the graph-DB (datomic) into the app-state atom?

tony.kay01:01:05

no, the pull query of Datomic is the magic

sova-soars-the-sora01:01:10

thank you for the link, by the way.

tony.kay01:01:11

no db->tree ever

tony.kay01:01:28

Om query syntax matches Datomic pull syntax

tony.kay01:01:39

you basically just pass the Om query straight to Datomic

tony.kay01:01:49

and return the result it gives back

sova-soars-the-sora01:01:01

Okay. The pull is the magic. So there's a generic query line that talks to the DB and the pull syntax can get any biscuit I need based on color, shape, wheat, etc... (to use bread as an example)

tony.kay01:01:49

you see it looks just like Om queries...and returns data in the map structure you need

sova-soars-the-sora01:01:59

Ah yes. Okay. Still some fuzziness in my head about how it all fits together, but that makes sense. Om.next query is essentially a datomic query and what comes back is that beautiful map...

tony.kay01:01:11

yep. So typically what you do on the client is send a query from some sub-portion of your UI (say you want to pull the items in a todo list)...you send the query for Item, along with a parameter (the entity of the list)

tony.kay01:01:31

The server does a pull query anchored at that entity, which gives you back the items

tony.kay01:01:44

Untangled will automtically merge those items into your app db.

tony.kay01:01:22

Then, you can (on the client) add in a post-mutation that creates a list of idents of those items, and places them in the place you want to show them. Possibly is sorts them. Possibly it filters them. etc. etc.

tony.kay01:01:32

but getting them into your db is effortless

tony.kay01:01:48

adding a bit of linkage so your UI sees what you want it to see is just a slight bit of graph joining...which is typically as simple as (swap! state assoc-in [:todo-list/by-id 42 :items] [[:item/by-id 1] [:item/by-id 2] ...])

tony.kay01:01:22

where the list of idents can even be derived from the table

tony.kay01:01:04

e.g. (mapv (fn [i] [:item/by-id (:db/id i)]) (vals (get @state :item/by-id)))

tony.kay01:01:02

but understanding what I just said above means you need to understand, very clearly, the graph db format...which really is quite simple: top-level tables as maps, and idents for pointers

tony.kay01:01:44

good luck...I'm going to get some food. I'd really recommend watching the videos on YouTube if you have not. I walk through quite a bit of this in detail.

sova-soars-the-sora02:01:36

Thanks @tony.kay I appreciate your help as always.

sova-soars-the-sora02:01:07

I don't understand what you mean when you say "along with a parameter (the entity of the list)" ... My datomic store has many individual elements (i refer to them as blurbs) and each one has a :blurb/title, :blurb/content, :blurb/author ... i do want to bring them to the clientside but I have no ":blurb/list" element in datomic, is that something that exists (only) in the client side atom

sova-soars-the-sora03:01:21

Thanks for that video! one thing that became clear was that :whatever/by-property is actually an Om-next special syntax that messes wth the atom state :property .... i was really curious about that. like by-id (and how it knew)

tony.kay16:01:24

@sova Nothing special about it. It is a name to remind the person coding that the table has keys that are IDs. The ident function (that you write) makes these up. If you index by id, then usually you'll name the table /by-id.

tony.kay16:01:00

If you have no ownership of blurbs, then you'd just query for them all and send them down, and yes, then your client code would "make up" a :blurb-list top-level key

tony.kay16:01:16

usually you have some kind of ownership...at least to the logged-in user, or a topic, etc etc

tony.kay16:01:21

which is what I meant

michaeldrogalis18:01:56

Is it possible to access the database connection inside untangled-datomic’s migrations without using migrate-with?

sova-soars-the-sora18:01:30

I'm really thankful for Untangled and all the resources you guys have contributed and offered to the community. Really awesome. Hope I can contribute something back eventually.