Mostly just a note to myself, but in case someone needs to know, here is how I quick fixed it.
(def cljs-to-js-dir "_cljs_to_js_out")
(def js-options { :output-dir cljs-to-js-dir})
(defn js-compile [quoted-expr]
(let [ result (cljs.closure/build quoted-expr js-options)
file-name ((re-find #"(/.+\.js)" result) 0)]
(slurp (str cljs-to-js-dir "/" file-name))))
(defmacro to-js [expr]
(js-compile `((fn [] ~expr))))
Using this code, you can then (from the repl) type:
=> (to-js (swap! my-project.my-namespace.my-atom inc))
<= "(function (){\nreturn cljs.core.swap_BANG_.call(null,my_project.my_namespace.my_atom,cljs.core.inc);\n}).call(null);\n"
I bet you are curious as to why I wrapped the expr(ession) in a immediately called no argument function. It is because cljs.closure/build will optimize away code if it is not actually used. For instance:
=> (js-compile '(fn [a b] (+ a b)))
<= ""
however
=> (js-compile '((fn [a b] (+ a b)) 2 3))
<= "(function (a,b){\nreturn (a + b);\n}).call(null,2,3);\n"
Details aside, (to-js)
seems to do what I want.