(ns ird.async
"Macro half of ird.async: `<?` and `go-try`. Loaded automatically when a
ClojureScript namespace requires ird.async (it self-requires this file), so
consumers write (:require [ird.async :refer [<? go-try]]).")
(defmacro <?
"Take from CH inside a go block. When the delivered value is an error
(any js/Error, including ExceptionInfo) it is thrown right there instead
of being returned — turning ird's error-as-value channels back into
ordinary try/catch flow."
[ch]
`(ird.async/throw-err (cljs.core.async/<! ~ch)))
(defmacro go-try
"A go block whose body may throw: the exception is delivered on the
returned channel as a value instead of escaping (an exception escaping a
plain go block closes its channel and surfaces as an uncaught Node
exception). Returns a promise-chan, so the single result can be taken any
number of times; a nil result closes the channel."
[& body]
`(let [out# (cljs.core.async/promise-chan)]
(cljs.core.async/go
(let [v# (try ~@body (catch :default e# e#))]
(if (nil? v#)
(cljs.core.async/close! out#)
(cljs.core.async/put! out# v#))))
out#))