-
-
Notifications
You must be signed in to change notification settings - Fork 715
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Datascript example #36
Comments
I'm not aware of any example. |
Just to be clear, you'd need to rewrite the reference implementation, rethinking the subscriptions process, etc. There'd be a bit in it. But an interesting exercise!! |
Ok many thanks |
Anyone who sees this thread and thinks, 'oh, now I'll go away and rewrite the reference implementation': actually you only need to swap in a Datascript database for the re-frame |
Has anyone actually done this yet? I'm trying, but having problems triggering reactions. Note that I'm new to everything clojure, so I might just be missing something obvious. |
Check out this: https://github.com/rmoehn/theatralia/blob/compl-recon/src/cljs/theatralia/thomsky.cljs Tomorrow (Japanese time) I'll be able to help more if you need. It would also make it easier for me if you posted the relevant snippets of your code. |
OK. So I've had a look now at thomsky, and think I have a better idea of whats missing for these reactions to take place. I'll have a go tomorrow and see if things pan out 😀 |
I've just realized that it doesn't work in all cases (unless I'm mistaken). I haven't thought about which cases those are, but probably enough that I wouldn't use the approach. See my new comment on https://gist.github.com/allgress/11348685. I don't know yet what I'll do with Thomsky. |
OK, I'm starting to feel some time-pressure, so I'm going to just maintain another atom based on the data from datascript. I have a better idea of how to cause those reactions to fire then. |
Still, this should be researched further. Something tells me that using datascript and some kind of sync-layer with datomic would be really future-proof. Add in declerative queries like with atomic and datomic-junk and your already way into the future 😀 |
There are alternatives:
David Nolen talks about the sync thing in his teaser for Om Next. He also says he wrote a Datascript adapter in a few lines of ClojureScript. I'm curious what approach he chose. |
Has there been any progress in making re-frame work seamlessly with datascript? |
I've changed my approach to querying the whole database instead of the thomsky.cljs is everything you need in order to use Datascript from re-frame. Since it's MIT license software, you can just copy and paste it into your code (a Credits line would be nice) and see how it performs. It's fairly well documented, I'd say. You'll find examples for event handlers using it in theatralia.handlers and for subscription handlers in theatralia.subs. |
I just noticed that Datascript has moved on quite a bit since I wrote @pupeno Can you give me a link to the relevant bits on Slack? Because I don't know how he meant that. I can't imagine how it should be easier, but I'm not very familiar with Datascript. |
@rmoehn I hope this link works: https://clojurians.slack.com/archives/clojurescript/p1444029537000112 |
So, you would use I'd really like a setup whereas I can fetch initial load from Datomic, work with that data realtime in Datascript and have a web-socket layer that tries to keep them both in sync. Such eventual consistency would be good enough for 99% of the projects I work on I guess. |
@pupeno Apparently I can't look into Slack archives, because I'm not on Slack. :-( Why do people communicate about open source projects on a closed platform? So the point was to use All in all, you if you don't use the @hkjels Why don't you program the synchronization stuff? Or help programming it? I'm pretty sure there are already projects on the way. Om Next is not far I think, and it might have a good deal of these ideas already supported. (Er, sorry for advertising Om Next in a re-frame issue.) |
I've tried a few approaches already, but I'm new to all of these technologies, so you might say I'm having some difficulties. |
@rmoehn Can you shed some light on why components in the db-with scenario would all re-render whenever |
Sorry, it's been a while, so I need some time in order to answer this properly. I'll get around to it on 25th or 26th. (Although if your cost of delay is high, I could fit it in today.) |
No hurry at all, it can definitely wait until then. Thank you. |
Thanks for your patience! I'm still struggling to get into my head from four months ago and I'm not so confident in my statements about re-renders anymore. However, here a two examples that might shed some light. The first is the usual case without DataScript: cljs.user=> (require '[reagent.core :as r]
'[reagent.ratom :as ratom :include-macros true])
nil
cljs.user=> (def map-atom (r/atom {}))
#'cljs.user/map-atom
cljs.user=> (def r2 (ratom/reaction (get @map-atom :x1 nil)))
#'cljs.user/r2
cljs.user=> (swap! map-atom assoc :x1 {:name "bla"})
{:x1 {:name "bla"}}
cljs.user=> (def val3 @r2)
#'cljs.user/val3
cljs.user=> (swap! map-atom assoc :x2 {:name "blu"})
{:x1 {:name "bla"}, :x2 {:name "blu"}}
cljs.user=> (def val4 @r2)
#'cljs.user/val4
cljs.user=> val3
{:name "bla"}
cljs.user=> (identical? val3 val4)
true You see that even though the map as a whole inside the ratom is a different one after the second The second example is with DataScript: cljs.user=> (require '[datascript.core :as d]
'[reagent.core :as r]
'[reagent.ratom :as ratom :include-macros true])
nil
cljs.user=> (def conn (d/create-conn))
#'cljs.user/conn
cljs.user=> (def r1 (ratom/reaction (d/q '[:find ?x :where [?x :name "bla"]] @conn)))
#'cljs.user/r1
(d/transact! conn [{:id -1
:name "bla"}])
[…]
cljs.user=> (def val1 @r1)
#'cljs.user/val1
(d/transact! conn [{:id -1
:name "blu"}])
[…]
cljs.user=> (def val2 @r1)
#'cljs.user/val2
cljs.user=> val1
#{[1]}
cljs.user=> (identical? val1 val2)
false
cljs.user=> (= val1 val2)
true Here, the results you get are not identical, even though they are equal, because DataScript allocates new data structures for every query's return value. I'm not yet sure, but I think the current stable version of Reagent re-renders everytime the results are not identical and in the next release it will be changed to re-render only for non-equal results. Therefore, whenever As I said, I'm not sure about these. If you know more about the inner workings of Reagent, I would be happy to be enlightened by you. Otherwise I will dig around some more. |
Your comments about re-renders were indeed correct, thank you for your thorough response. I'm afraid I don't know much about Reagent's inner workings, and your explanation makes sense. In any case, I tested query reactions with Reagent Also, to address the loss of transaction reports in the immutable DB value case, I wrote a middleware factory, which returns a middleware that wraps a function from DataScript DB values and event vectors to transaction data. The (defn transact-mid
"Create a middleware wrapping a DataScript transaction."
[& {:keys [listeners]}]
(fn [handler]
(fn [db v]
(let [tx-data (handler db v)
report (ds/with db tx-data)]
(doseq [cb listeners] (cb report))
(:db-after report)))))
;; example
(def tx-mid
(transact-mid
;; The listener handler will be called synchronously
;; with the transaction, and will take the transaction
;; report as its sole argument.
:listeners [(partial println "tx-report:")])
(defn make-named-thing
[datascript-db-value [_ name]]
[{:db/id -1 :thing/name name}])
(register-handler
:make-named-thing
[tx-mid] ;; We assume that app-db is a DataScript DB value
make-named-thing)
(dispatch [:make-named-thing "foobar"])
;; adds a thing/name fact and prints a tx-report to the console.
The body of (defn update-ds
[handler]
(fn [db v]
(update db :datascript-db handler v)))
(register-handler
:make-named-thing
[update-ds tx-mid]
make-named-thing) I'm not entirely sure how good or useful this solution is. It may feel limiting to only return |
Cool! Looks like you've dug re-frame much more than me! |
@mike-thompson-day8 et al -- anyone know if anyone has gone further down this road in the meantime? We're making some front-end architectural decisions, and I'd love to be able to put re-frame + datascript on the table. |
I suggest putting it on the table with all the other reasonable choices, and evaluating them for what they are. |
Sure, but there's a difference between 1) re-frame + datascript and 2) reframe + we-rewrite-re-frame-for-datascript. It'll go on the table either way, but it's a much easier sell if there's already an implementation out there that works well with datascript. |
But why would you want to sell it if it's not adequate? That's like »see here's this hammer. I really like it, because it feels good in my hand and has a great picture of a scruffy blacksmith on it. We should use it. By the way, it's also good for cooling a black eye.« Rather than »see, we have to fasten this picture to the wall. How solid does it have to be? Can we make permanent changes or do we have to remove it when we move out? Any other considerations? Which tools are available? To what degree do they fulfil the criteria we set when analysing the problem?« |
Sorry, I'm missing your point. You just wanted to know whether there are new developments and I can't answer that question. No developments on my table at least. |
It should be trivial to implement a Datascript based db with pure-frame. |
@rmoehn -- thanks for all the input. I definitely don't want to try to sell it if it's the wrong choice. Maybe I didn't communicate effectively -- we've got some investment already in datascript (we're syncing with a datomic backend), so we probably wouldn't consider re-frame if we couldn't use it with datascript. Of course we could write our own re-frame implementation from scratch that used datascript, but that would require a substantially larger time commitment, which is why it would be a more difficult sell. @thenonameguy, awesome! I wasn't aware of pure-frame -- very cool. That does seem like it'd make it way easier to swap out the data store. |
You might find this helpful On Saturday, March 19, 2016, Egg Syntax (Davis) notifications@github.com
Sent from Gmail Mobile |
@Conaws thanks! |
Here an alternative solution |
I've just released a library that allows combining re-frame and DataScript together DataFrame |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
Hi,
I wonder how i can use datascript with re-frame ?
Is there an example somewhere ?
Many thanks,
Samuel
The text was updated successfully, but these errors were encountered: