 (run-example example-c 10)
 
 (run-example example-d {"counter" 0})
+
+(step-example example-d [] {"counter" 0})
+
+(take 10 (iterate #(step-example example-d [] %) {"counter" 0}))
 
 (defn print-stack
   ([frame]


(defrecord Cursor [path value])

(defn run-pipe [program node inputs output stack]
  (let [vars #js {}
        calls #js []
        frame #js {:id (:id node) :vars vars :calls calls}]

          "c+1" ["c" "one"] (cljs-ref +)
          "nil" ["c" "c+1"] replace)})

(defn run-example [example this-state]
  (let [stack #js []
        id->node (into {} (for [pipe example] [(:id pipe) pipe]))
        next-state (atom state)
        result (run-pipe id->node (get id->node "root") [(Cursor. [] this-state)] next-state stack)]
    (try
      [result @next-state (aget stack 0)]
      (catch :default exception
        [exception @next-state (aget stack 0)]))))

(defn step-example [example watchers input]
  (let [[_ output _] (run-example example input)]
    (doseq [watcher watchers]
      (watcher (:output output)))
    (dissoc output :output)))

(run-example example-b {"a" 1 "b" 2})
(run-example example-b {"a" 1 "c" 2})
