 (def Root
   {:root/user
    (fn [context ast]
-     (resolve* (assoc context :user/name (:user/name (:params ast))) User :root/user (:children ast)))})
+     (resolve* (assoc context :user/name (:user/name (:params ast))) User (:children ast)))})
 
 
 (deftest new-thing-works

(defn- read-port? [x]
  (implements? async-impl/ReadPort x))

(defn resolve* [context mapping key children]
  (async/map (fn [& vals]
               {key (into {}
                          (map #(vector (:key %1) %2)
                               children vals))})
             (map (fn [ast]
                    (let [result ((get mapping (:key ast)) context ast)
                          promise (if (read-port? result)
                                    result
                                    (doto (async/promise-chan) (put! result)))]
                      (async/map (:key ast) [promise])))
                  children)))


(defn resolve [context root-mapping query]
  (let [ast (om/query->ast query)]
    (async/map ::root [(resolve* context root-mapping ::root (:children ast))])))

(def User
  {:user/name
   (fn [context ast]
     {:user/name (:user/name context)})

   :user/favorite-color
   (fn [context ast]
     (let [c (async/promise-chan)
           get-user (get-in context [:apis :get-user])]
       (get-user {:user/name (:user/name context)}
                 #(put! c %))
       c))

   :user/favorite-number

                 (fn [user]
                   (-> (resolve* (assoc context :user/name (:user/favorite-fellow-user-name user))
                                 User
                                 (:children ast))
                       (async/pipe c))))
       c))})
