         [clojure.core.reducers :as r]
         [cljs.core.async :as async :refer [<! >!]])]))
 
+#?(:cljs
+   (when-not (satisfies? IReduce LazyTransformer)
+     (defn- seq-reduce*
+       ([f coll]
+        (if-let [s (seq coll)]
+          (reduce f (first s) (next s))
+          (f)))
+       ([f val coll]
+        (loop [val val, coll (seq coll)]
+          (if coll
+            (let [nval (f val (first coll))]
+              (if (reduced? nval)
+                @nval
+                (recur nval (next coll))))
+            val))))
+
+     (extend-type LazyTransformer
+       IReduce
+       (-reduce
+         ([coll f] (seq-reduce* f coll))
+         ([coll f start] (seq-reduce* f start coll))))))
+
 ;;#?(:clj (taoensso.timbre/set-level! :warn))
 
 ;; (warn :free-ram (.freeMemory (Runtime/getRuntime)))

  [ctx]
  (let [processor ((:processor ctx) (:signal-thresh ctx) (:collect-thresh ctx))]
    (fn [workgroup-size vertices]
      (r/fold workgroup-size single-pass-combine processor vertices))))

(defn two-pass-scheduler
  [ctx]
  (let [sig-fn  ((:signal-fn ctx) (:signal-thresh ctx))
        coll-fn ((:collect-fn ctx) (:collect-thresh ctx))]
    (fn [_ vertices]
      (let [[s-act sigs]  (sig-fn vertices)
            [c-act colls] (coll-fn vertices)]
        [(into s-act c-act) sigs colls]))))


      (execute!
        [_]
        (let [t0     (now)
              active (atom (sequence v-filter (vertices g)))
              queue  (atom #{})]
          (add-context-watches g watch-id queue)
          (loop [colls 0, sigs 0]
