       virtual-dom
 
       :default
-      (let [node (create-dom-node (first virtual-dom))
-            state (init-element-state! node elem-spec)
+      (let [tag (first virtual-dom)
+            node (create-dom-node tag)
             attrs? (second virtual-dom)
             attrs (when (map? attrs?) attrs?)
+            state (init-element-state! node elem-spec tag attrs)
             children (if attrs (nnext virtual-dom) (next virtual-dom))]
         (doseq [[k v] attrs]
           (bind-attr! node k v state))


(declare get-transition)

(defn- init-element-meta! [state element-spec]
  (let [m (meta element-spec)]
    (set! (.-meta state) m)
    (when-let [on-disposed (get m :node-disposed)]
      (set! (.-disposed-callback state) on-disposed))))

(defn- reset-element-spec! [state spec]
  (when-let [on-disposed (.-disposed-callback state)]
    (on-disposed)
    (set! (.-disposed-callback state) nil))
  (set! (.-element-spec state) spec)
  (init-element-meta! state spec))

(defn- init-element-state! [dom-node element-spec]
  (let [node-id (str auto-node-id)
        state (ElementState. node-id false element-spec nil)]
    (set! auto-node-id (inc auto-node-id))
    (set-attr! dom-node "data-freactive-id" node-id)
    (init-element-meta! state element-spec)
    (aset element-state-lookup node-id state)
    ;;(set! element-state-lookup (assoc element-state-lookup dom-node state))
    state))

(defn- register-with-parent-state [parent-state child-key state]


(defn- try-diff [parent vdom cur-dom-node top-level]
  (let [cur-state (get-element-state cur-dom-node)
        cur-tag (.-tag cur-state)
        new-tag (first vdom)]
    (if (keyword-identical? new-tag cur-tag)
      (do
        ;(println "diff hit" (first vdom))
        (let [old-attrs (.-attrs cur-state)
              new-attrs? (second vdom)
              new-attrs (when (map? new-attrs?) new-attrs?)]
          (reset-element-spec! cur-state vdom new-tag new-attrs)
          (replace-attrs! cur-dom-node
                          cur-state
                          old-attrs
                          new-attrs)
          (let [new-children (if new-attrs (nnext vdom) (next vdom))
                dangling-child (try-diff-subseq cur-dom-node (.-firstChild cur-dom-node) new-children)]
