Skip to content

Instantly share code, notes, and snippets.

@julienfantin
Last active October 22, 2016 20:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julienfantin/dc3d1bf89edfbacc1447331bf851ce97 to your computer and use it in GitHub Desktop.
Save julienfantin/dc3d1bf89edfbacc1447331bf851ce97 to your computer and use it in GitHub Desktop.
Compassus link query bug?
(ns vimsical.compassus-repro
"Disclaimer: Not 100% sure this is a valid use-case.
Context: Trying to add compassus \"on top\" of an existing om.next app, by
recursively parsing routes in order to reuse existing component/parser code.
Expectations: Recursively parsing a route from a read method should leave us
in the same situation as prior to adding Compassus.
Actual behavior: Seeing a difference with a component querying for a
link (Home in this example). The component props references the link ident,
i.e. [:current-user '_] as opposed to a simple key.
Thanks for looking! "
(:require
#?(:cljs [goog.dom :as gdom])
[om.dom :as dom]
[om.next :as om :refer [defui]]
[compassus.core :as cp]))
;; * State
(def bob {:db/id -2, :user/name "Bob"})
(def init-state
{:app/session {:db/id -1, :session/user bob},
:current-user bob})
;; * Parser
(defmulti readf ;; om/dispatch
(fn [{:keys [query]} k _]
#?(:cljs (.log js/console "Read:" k query))
k))
(defmethod readf :default
[{:keys [state query] :as env} k _]
(let [st @state]
{:value (om/db->tree query (get st k) st)}))
(defmethod readf :route/home
[{:keys [parser query] :as env} _ _]
{:value (parser env query)})
(def parser
(om/parser {:read readf}))
;; * Components
(defui User
static om/Ident
(ident [_ {:keys [db/id]}] [:db/id id])
static om/IQuery
(query [_] [:db/id :user/name]))
(defui Session
static om/Ident
(ident [_ {:keys [db/id]}] [:db/id id])
static om/IQuery
(query [_]
[:db/id {:session/user (om/get-query User)}]))
(defui Home
static om/IQuery
(query [_]
[{[:current-user '_] (om/get-query User)}])
Object
(render [this]
(let [actual (om/props this)
expected {:current-user bob}]
(if (= actual expected)
#?(:cljs (.log js/console "OK!"))
#?(:cljs (.error js/console "Home expected:" expected ", got:" actual)))
(dom/div nil
(str "Hello " (-> actual :current-user :user/name))))))
;; * Compassus App
(defui App
static om/IQuery
(query [_]
[{:app/session (om/get-query Session)}
{:current-user (om/get-query User)}])
Object
(render [this]
(let [{:keys [app/session]} (om/props this)
{:keys [owner factory props]} (om/get-computed this)]
(dom/div nil
(factory props)))))
(def app
(cp/application
{:routes {:route/home (cp/index-route Home)}
:mixins [(cp/wrap-render App)]
:reconciler-opts {:parser parser
:state init-state}}))
(let [db (-> app :config :reconciler deref)]
;; Check that App reconstructs our init-state properly:
;; OK
(assert (= init-state (om/db->tree (om/get-query App) db db))))
;; * Om App (original)
(def home-factory (om/factory Home))
(defui OmApp
static om/IQuery
(query [_]
[{:app/session (om/get-query Session)}
{:current-user (om/get-query User)}])
Object
(render [this]
(let [{:keys [app/session current-user]} (om/props this)]
(dom/div nil
(home-factory {:current-user current-user})))))
(def reconciler
(om/reconciler
{:parser parser
:state init-state}))
;; * Main
;; ** Compassus
(do
#?(:cljs
(.log js/console "----------------------------------------------------")
(.log js/console "Running Compassus..."))
(cp/mount! app #?(:cljs (gdom/getElement "app") :clj nil)))
;; ** Om
(do
#?(:cljs
(.log js/console "----------------------------------------------------")
(.log js/console "Running Om..."))
(om/add-root! reconciler OmApp #?(:cljs (gdom/getElement "app") :clj nil)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment