Just to be clear, I'm not talking about the default/general local state 
semantics, but the 'no-local-state-methods' semantics. Since the sole purpose 
of this function is to handle loading/saving local state from/to global state - 
why not make it work for initialising as well? 

Initially I expected it to work this way, using the local state inside the 
global state and applying the init-state data as defaults.

Stephan

On Saturday, January 31, 2015 at 5:20:59 PM UTC+1, David Nolen wrote:
> We're not going to change local state semantics. You will need to consider 
> alternative strategies.
> 
> On Saturday, January 31, 2015, stephanos <[email protected]> wrote:
> Now there is still one problem.
> 
> 
> 
> If the database is filled with data already (e.g. when loading data from 
> localstorage into it upon page refresh), it is overridden by Om since it 
> calls 'init-state' and uses swap! + assoc to put the database in the global 
> state.
> 
> 
> 
> @David Would it make sense to use 'merge' instead? In order to respect the 
> data that exists prior to the first 'init-state' call?
> 
> 
> 
> Stephan
> 
> 
> 
> 
> 
> On Saturday, January 31, 2015 at 4:39:45 PM UTC+1, stephanos wrote:
> 
> > Okay, I finally made it. Here is the implementation:
> 
> >
> 
> >   (defn- read-map
> 
> >     [db]
> 
> >     (or (first (d/q '[:find ?e ?v :in :where [?e :map ?v]] db)) [nil nil]))
> 
> >
> 
> >   (defn- write-map
> 
> >     [conn fn]
> 
> >     (let [[old-id old-val] (read-map @conn)
> 
> >           new-id (if old-id {:db/id old-id} {})
> 
> >           new-val (or (fn (or old-val {})) {})]
> 
> >       (d/transact! conn [(merge new-id {:map new-val})])))
> 
> >
> 
> >   (deftype DatabaseWrapper [db]
> 
> >     IDeref
> 
> >     (-deref [_]
> 
> >       db)
> 
> >     ILookup
> 
> >     (-lookup [this k]
> 
> >       (-lookup this k nil))
> 
> >     (-lookup [_ k not-found]
> 
> >       (let [[_ map] (read-map db)]
> 
> >         (if (nil? k)
> 
> >           map
> 
> >           (or (get map k) not-found)))))
> 
> >
> 
> >   (deftype DatabaseCursor [conn]
> 
> >     IAtom
> 
> >     IDeref
> 
> >     (-deref [_]
> 
> >       (DatabaseWrapper. @conn))
> 
> >     ILookup
> 
> >     (-lookup [this k]
> 
> >       (-lookup this k nil))
> 
> >     (-lookup [this k not-found]
> 
> >       (-lookup @this k not-found))
> 
> >     IAssociative
> 
> >     (-contains-key? [this k]
> 
> >       (not (= (-lookup this k ::not-found) ::not-found)))
> 
> >     (-assoc [this k v]
> 
> >       (write-map conn #(assoc % k v))
> 
> >       this)
> 
> >     IMap
> 
> >     (-dissoc [this k]
> 
> >       (write-map conn #(dissoc % k))
> 
> >       this)
> 
> >     ICloneable
> 
> >     (-clone [this]
> 
> >       this)
> 
> >     IHash
> 
> >     (-hash [_]
> 
> >       (hash @conn))
> 
> >     ISwap
> 
> >     (-swap! [_ fn]
> 
> >       (write-map conn #(fn %)))
> 
> >     (-swap! [_ fn x]
> 
> >       (write-map conn #(fn % x)))
> 
> >     (-swap! [_ fn x y]
> 
> >       (write-map conn #(fn % x y)))
> 
> >     (-swap! [_ fn x y xs]
> 
> >       (write-map conn #(fn % x y xs)))
> 
> >     IMeta
> 
> >     (-meta [_]
> 
> >       (meta conn))
> 
> >     om/ITransact
> 
> >     (-transact! [_ _ _ _]
> 
> >       (throw js/Error "not supported"))
> 
> >     om/IValue
> 
> >     (-value [_]
> 
> >       @conn)
> 
> >     om/ICursor
> 
> >     (-path [_]
> 
> >       [])
> 
> >     (-state [_]
> 
> >       nil)
> 
> >     IEquiv
> 
> >     (-equiv [_ other]
> 
> >       (if (instance? DatabaseCursor other)
> 
> >         (= @conn @@other)
> 
> >         (= @conn other)))
> 
> >     IWatchable
> 
> >     (-notify-watches [_ oldval newval]
> 
> >       (-notify-watches conn oldval newval))
> 
> >     (-add-watch [_ key f]
> 
> >       (-add-watch conn key f))
> 
> >     (-remove-watch [_ key]
> 
> >       (-remove-watch conn key))
> 
> >     IPrintWithWriter
> 
> >     (-pr-writer [_ writer opts]
> 
> >       (-pr-writer @conn writer opts)))
> 
> >
> 
> > A new cursor can be simple created with
> 
> >
> 
> >   (DatabaseCursor. (d/create-conn {}))
> 
> >
> 
> > Now when you enable instrumentation
> 
> >
> 
> >   (defn- instrument
> 
> >     [f cursor m]
> 
> >     (let [custom-opts (assoc m :descriptor (om/no-local-descriptor 
> >om/no-local-state-methods))]
> 
> >       (om/build* f cursor custom-opts)))
> 
> >
> 
> > local state will be saved to the DataScript db.
> 
> >
> 
> > Stephan
> 
> >
> 
> > On Sunday, January 25, 2015 at 11:09:25 AM UTC+1, stephanos wrote:
> 
> > > Hey there,
> 
> > >
> 
> > > I'm trying to integrate Om and DataScript.
> 
> > >
> 
> > > At first I used David Nolen's gist [1] that implements 'om/IToCursor' for 
> > > DataScript's DB type. That worked out well for some time. But now I try 
> > > to apply Om's experimental support for writing all local state into the 
> > > app state [2]. This requires an associative data structure because of its 
> > > use of 'assoc' and 'get-in'.
> 
> > >
> 
> > > So I attempted to write a wrapper around the DataScript DB atom, 
> > > DatabaseCursor. Now, while I succeeded in saving the local state to it by 
> > > implementing IAssociative and ILookup, the app does not re-render on 
> > > change anymore :(
> 
> > >
> 
> > > I originally assumed all I needed was to implement the IEquiv or IHash 
> > > protocol, but that does not seem to work (both are never called). So I'm 
> > > stuck right now. Here is my DatabaseCursor:
> 
> > >
> 
> > >   (deftype DatabaseCursor [conn]
> 
> > >     ILookup
> 
> > >     (-lookup [this k]
> 
> > >       (-lookup this k nil))
> 
> > >     (-lookup [_ k not-found]
> 
> > >       (let [v (ffirst (d/q '[:find ?v :in $ ?k :where [?e :key ?k] [?e 
> > >:value ?v]] @conn k))]
> 
> > >         (or v not-found)))
> 
> > >     IAssociative
> 
> > >     (-contains-key? [_ k]
> 
> > >       (not (empty? (d/q '[:find ?e :in $ ?k :where [?e :key ?k]] @conn 
> > >k))))
> 
> > >     (-assoc [this k v]
> 
> > >       (let [old-id (ffirst (d/q '[:find ?e :in $ ?k :where [?e :key ?k]] 
> > >@conn k))
> 
> > >             new-id (if old-id {:db/id old-id} {})]
> 
> > >         (d/transact! conn [(merge new-id {:key k, :value v})]))
> 
> > >       this)
> 
> > >     om/IToCursor
> 
> > >     (-to-cursor [this _] this)
> 
> > >     (-to-cursor [this _ _] this))
> 
> > >
> 
> > > How to I need to modify my custom cursor to make Om aware of changes to 
> > > the DataScript DB?
> 
> > >
> 
> > > [1] https://gist.github.com/swannodette/11308901
> 
> > > [2] 
> > > https://github.com/swannodette/om/commit/ee9d92bf1191a391df804c066868c8180f9d64cf
> 
> 
> 
> --
> 
> 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.

-- 
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.

Reply via email to