       (swap! state update-in [::rid rid] merge {::object nil
                                                 ::nav-stack []}))))
 
-(defmutation select-object [{:keys [oid] :as params}]
+(defmutation select-tap-object [{:keys [rid oid] :as params}]
   (action [{:keys [state] :as env}]
 
-    (let [{::keys [rid] :as obj}
-          (get-in @state [::oid oid])]
-
+    (let [obj (get-in @state [::oid oid])]
       (maybe-fetch-initial-fragment state obj)
 
-      (swap! state update-in [::rid rid] merge
+      (swap! state update-in [::tap-page rid] merge
         {::object [::oid oid]
          ::nav-stack []}))
 

  {:class RuntimeTapPage
   :factory ui-runtime-tap-page})



(defn route [tokens]
  (if-not @tool-ref
    ;; wait for websocket connect first, then do actual route

  [this summary fragment]
  (render-seq this summary fragment))

(defstyled map-root :div [env]
  {:display "grid"
   :padding "0 1rem"
   :grid-template-columns "min-content minmax(25%, auto)"
   :grid-row-gap "1px"
   :grid-column-gap ".5rem"})

(defstyled map-span :div [env]
  {:grid-column-start "span 2"})

(defstyled map-entry :div [env]
  {:display "contents"
   :cursor "pointer"})

;; {:className "pl-4 pr-2 font-bold whitespace-no-wrap truncate"}
(defstyled map-key :div [env]
  {:font-weight "bold"
   :padding "0 .25rem"
   :white-space "nowrap"
   :overflow "hidden"
   :text-overflow "ellipsis"
   :background-color "#fafafa"
   "&:hover"
   {:background-color "#eee"}})

;; {:className "pr-4 truncate"}
(defstyled map-val :div [env]
  {:white-space "nowrap"
   :overflow "hidden"
   :text-overflow "ellipsis"})

(defmethod render-view :map
  [this {:keys [oid entries] :as summary} fragment]
  (map-root {:class "font-mono"}
    (html/for [idx (range entries)
               :let [{:keys [key val] :as entry} (get fragment idx)
                     [key-limit-reached key-limit-text] key]]
      (cond
        (nil? entry)
        (map-span
          {:key idx :className "border"
           :onMouseEnter
           (fn [e]
             (fc/transact! this [(request-fragment {:oid oid
                                                    :idx idx})]))}
          "not available, fetch")

        ;; started loading
        (empty? entry)
        (map-span
          {:key idx :className "border"} "...")

        ;; long key
        #_#_(or key-limit-reached
                (> (count key-limit-text) 22))
            (html/div {:key idx
                       :className "border-b hover:bg-gray-200"
                       :onClick
                       (fn [e]
                         (fc/transact! this [(nav-object {:oid oid
                                                          :idx idx
                                                          :key key})]))}
              (html/div {:className "px-4 py-1 font-bold whitespace-no-wrap cursor-pointer truncate"}
                (render-edn-limit key))
              (html/div {:className "pl-4 pr-4 py-1 cursor-pointer truncate"}
                "↳ " (render-edn-limit val)))

        :else
        (map-entry {:key idx
                    :onClick
                    (fn [e]
                      (fc/transact! this [(nav-object {:oid oid
                                                       :idx idx
                                                       :key key})]))}
          (map-key
            (render-edn-limit key))
          (map-val
            (render-edn-limit val)))
        ))))

(defsc Runtime [this {::keys [rid] :as props}]
  {:ident
