(ns ird.p2p.impl.node
"Node platform bits the pure namespaces need: errors, promises, the clock,
the environment. Internal interop namespace."
(:require [cljs.core.async :as async]))
(defn error?
"True when V is an error value (any js/Error, which includes ExceptionInfo)."
[v]
(instance? js/Error v))
(defn promise->chan
"A promise-chan delivering the promise's resolution (nil closes the
channel) or its rejection as an error value (wrapped when not an Error)."
[p]
(let [c (async/promise-chan)]
(.then p
(fn [v] (if (nil? v) (async/close! c) (async/put! c v)))
(fn [e] (async/put! c (if (error? e) e (js/Error. (str "Promise rejected: " e))))))
c))
(defn now-ms
"Milliseconds since the epoch."
[]
(js/Date.now))
(defn env
"The environment variable NAME, or nil when unset or blank."
[name]
(let [v (aget (.-env js/process) name)]
(when (and (string? v) (pos? (count (.trim v)))) v)))
(defn error-message
"The message of a JS error (or the string form of anything else)."
[e]
(if (error? e) (.-message e) (str e)))
(defn log-error
"console.error, for the rare diagnostics the SDK prints."
[& parts]
(apply js/console.error parts))
(defn chan->promise
"A Promise of the first value CH delivers; rejects when (error? v)."
[ch error?]
(js/Promise. (fn [resolve reject]
(async/take! ch (fn [v] (if (error? v) (reject v) (resolve v)))))))