Ian, I've been wanting to do something similar with a database store. It seems
like the best way to support arbitrary data structures and prevent being forced
to model your data as a tree. I've played around with
https://github.com/tonsky/datascript and have been thinking about writing a
similar wrapper that does what you're calling per-query dependency tracking
(great name by the way).
This is what I'm thinking, let me know if this is what you're doing! Couldn't
find the derive code on github, is the repo public?
Instead of passing cursors containing data to components, pass a cursor
containing a query. init-state runs query against database. any changes to the
query will trigger did-update and rerun the query. init-state will also
register the query with a central database controller and subscribe to events
that will trigger component refresh on stale state. What i'm assuming you mean
by per-query dependency tracking, is that you can run a query against a
database transaction to determine if its effect on the entire dataset would
cause the query output to change. if so, you submit an event back to the
component to trigger a refresh.
I personally prefer channels for process communications, it sounds like you
prefer functions now? Can you elaborate on why you've moved away from channels?
I use a similar setup of event submission to central controller(s) that process
events either into further events handled elsewhere, api calls, etc. ending in
app-state (or database) transactions. I create channels around om/root and pass
both the channels to which events can be submkit, and mults/pubs created from
them that can then be listened to by controllers.
On Tuesday, September 23, 2014 7:36:35 PM UTC-4, Ian Eslick wrote:
> Actually, it turns out if you call a child with a merged {:shared ...}
> argument to pass shared values down the subtree.
>
> (om/build child app {:shared {:actions (merge-actions owner {...})}})
>
> You can tighten this up with macros, etc. Hopefully David won't make this
> impossible in future versions because I find it INSANELY useful both for
> testing and for selective overrides of default state.
>
> For example, I've had issues with the somewhat non-deterministic behavior and
> operational latency of core.async particularly in the mobile app / browser
> context at scale (especially on the abandoned Pedestal App 0.3 which we have
> in limited production).
>
> In our current project, we've dropped core.async and instead manage all side
> effects via direct transacts on cursors and calls to "actions" which are
> passed in shared state from the root of the tree via shared. We use
> controller components to coordinate the behavior of sets of related
> components (like all the authentication screens of a mobile app) which
> capture all the child actions and then call the service layer actions passed
> into the root. Most of our interactions fall into these camps:
>
> Event -> om/set-state!
> Event -> om/transact!
> Event -> Action -> Service Call -> (swap! data ...)
> Event -> Action -> Service Call -> Callback -> om/transact!
> Event -> Action -> Parent Handler -> Action -> Service Call ...
>
> Actions are synchronous and explicitly named, so short and easy to reason
> about. We added callbacks to handle things like 'loading' notifications,
> error handling, etc. Again, lightweight. For heavy interactions, the
> service calls just side effects the top level atom, or....
>
> We manage most of our state in a client-side database (NativeStore) that does
> per-query dependency tracking so we can automatically call refresh! on
> components that have stale state (open source project at github
> vitalreactor/derive). We'll post about this when we get our app done and
> roll out v0.2 of the derive library and nativestore.
>
>
>
> On Tuesday, September 23, 2014 4:38:33 AM UTC-7, Michiel Borkent wrote:
> > What I would like to see is something like :shared but only shared within a
> > subtree, so for example:
> >
> > (defn child [app owner]
> > (om/component
> > (dom/p nil (str "Yo, I've got"
> > (om/get-shared owner :some)
> > :state))))
> >
> > (defn parent [app owner]
> > om/IShared
> > (shared [_]
> > {:some :state})
> > om/IRender
> > (render [_]
> > (om/build child app))
> >
> > This way you can share state with child components and you don't have to
> > deal with channels/callbacks as much in certain situations. What do you
> > think?
--
Note that posts from new members are moderated - please be patient with your
first post.
---
You received this message because you are subscribed to the Google Groups
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.