asami

Asami, the graph database https://github.com/threatgrid/asami
mkvlr 2021-03-09T15:06:13.167200Z

Hello 👋 We’re currently evaluating asami as our client-side triple store to complement datomic on the server and we’re excited about the durable storage on IndexedDB. It seems `zuko.util` basically brings in all of ClojureScript and has a significant size penalty https://github.com/threatgrid/zuko/blob/961ccaa484b30f28b625e5598b5288cd436f9b3c/src/zuko/util.cljc#L9-L14. Here’s the top offenders from our shadow-cljs build report in our (already pretty bloated) bundle. Is that intentional and required?

quoll 2021-03-09T15:08:36.168500Z

When you say that it’s brought in all of ClojureScript, I take it that this is in Clojure, right?

quoll 2021-03-09T15:08:55.169Z

If so, then no. I hadn’t expected that at all!

simongray 2021-03-09T15:09:09.169400Z

won’t :advanced compilation get rid of it anyway?

mkvlr 2021-03-09T15:09:21.169800Z

no, that’s in our ClojureScript bundle with :advanced

simongray 2021-03-09T15:09:29.170Z

hmm

quoll 2021-03-09T15:12:45.170600Z

That’s probably because that namespace keeps a map to all the functions in cljs.core

quoll 2021-03-09T15:13:22.171600Z

These are made available at runtime for predicates in queries

mkvlr 2021-03-09T15:13:30.171900Z

but it’s not required for ClojureScript (where c-eval isn’t implemented), or is it?

quoll 2021-03-09T15:16:11.174500Z

If you do a query with (for instance): [:find ?e :where [:e :type :my-type] [?e :value ?x] [(> ?x 5)]] Then you’ve called for cljs.core/> The same goes for any predicate you use. It also applies to bindings like: [:find ?label :where [:e :type :my-type] [?e :value ?x] [(str "value=" ?x)]]

quoll 2021-03-09T15:16:18.174700Z

So it’s a runtime requirement

quoll 2021-03-09T15:16:50.175400Z

We actually limit which functions can be called, but that’s done in Asami. It could be done in Zuko to limit the number of things brought into the map

mkvlr 2021-03-09T15:17:34.175900Z

does asami only need those? (def raw-lookup {'= = 'not= not= '< < '> > '<= <= '>= >=}))

mkvlr 2021-03-09T15:21:13.176200Z

I’ll do some experiments

mkvlr 2021-03-09T15:22:44.178Z

we also suspect known-namespaces might include the same functions several times under different keys (`'cljs.core` , 'clojure.core , "cljs.core", "clojure.core")

quoll 2021-03-09T15:27:19.179Z

Yes, but that won’t bring anything else in

quoll 2021-03-09T15:27:49.179600Z

No. Those are just the quick and easy ones.

mkvlr 2021-03-09T15:32:58.180100Z

hmm, I don’t think I understand…

quoll 2021-03-09T15:33:47.180900Z

I’m AFK for a bit, sorry. But I’ll come back to this soon

mkvlr 2021-03-09T15:34:02.181200Z

no worries, I’ll play around with this in the meantime

mkvlr 2021-03-09T16:27:07.181400Z

https://github.com/threatgrid/zuko/pull/10

mkvlr 2021-03-09T16:28:30.182300Z

this get is down from 1.85 MB to 550 kb.

mkvlr 2021-03-09T16:28:58.182800Z

(I haven’t tested this yet, hope travis takes care of that 😼)

quoll 2021-03-09T17:06:20.183900Z

Wow. I had no idea that the previous code would create duplicate structures!

quoll 2021-03-09T17:08:00.185200Z

I’m thinking it might help to take the Asami whitelist and shift it into Zuko. I can’t see any reason why the fn-for would ever be used in a situation that would require anything that isn’t in that list

mkvlr 2021-03-09T17:11:19.186500Z

ah, asami does have a whitelist? I’m away for a bit now but can take a look later or tomorrow

quoll 2021-03-09T17:11:51.187Z

we tried to be generous with it, so there are some things in there that may seem excessive

quoll 2021-03-09T17:13:05.187900Z

We’ve listed the disallowed functions, but they’re not referenced, so I can remove them

mkvlr 2021-03-09T17:55:32.191400Z

great, thanks! I’ll continue on this tomorrow. Another thing I’ll try that should reduce the bundle size is just storing the derefed vars (i.e. functions) instead the whole functions (with docstring etc) in the map. Or do you use that metadata anywhere in asami?

quoll 2021-03-09T17:55:45.191700Z

never

1👍
quoll 2021-03-09T17:55:58.192100Z

I’m actually building the map manually right now 🙂

quoll 2021-03-09T17:56:45.192500Z

So it never has to reference the entire contents of the namespace

mkvlr 2021-03-09T18:01:42.194100Z

curious to find out where this leads us with the bundle size

mkvlr 2021-03-09T18:01:59.194600Z

what’s the reason behind disallowing -> etc in the sandbox? Because they’re macros?

quoll 2021-03-09T18:02:09.194800Z

yes

quoll 2021-03-09T18:02:26.195300Z

I’d like to have and or or in there, but can’t

mkvlr 2021-03-09T18:02:35.195600Z

ok, maybe another interesting use case for https://github.com/borkdude/sci, could also be an opt-in thing

mkvlr 2021-03-09T18:03:00.196200Z

for example we’re already using sci in our app, so it would be free in terms of bundle size

mkvlr 2021-03-09T18:03:31.196700Z

the whole interpreter only adds ~500 kb in our case

borkdude 2021-03-09T18:14:27.197500Z

sci also has a :allow and :deny setting or you can just set {:namespaces {'clojurecore {'-> nil}}}

mkvlr 2021-03-09T18:16:10.198400Z

@borkdude does that even affect the bundle size then? I mean can you build a slimmer version of sci this way?

borkdude 2021-03-09T18:17:29.199600Z

@mkvlr Those settings do not affect the bundle size, but you can get a slimmer bundle size if you copy sci/impl/namespaces.cljc to your project and just delete what you don't need

1👍