Fork me on GitHub
#code-reviews
<
2022-11-18
>
zharinov11:11:46

How folks do you survive in REPL on promise-heavy CLJS projects? Here is approach I'm about to try:

(ns p-dev
  "Utilities for REPL-driven development with Promise-heavy tasks."
  (:require
    [promesa.core :as p])
  #?(:cljs (:require-macros [p-dev])))

(def ^:private pending (atom nil))

(defn- get-pending []
  (deref pending))

(defn- set-pending! [value]
  (reset! pending value))

(defmacro p-do
  [& body]
  `(let [pending# (get-pending)]
     (set-pending!
       (p/do
         pending#
         ~@body))))

(defmacro p-def
  [name p-val]
  `(p-do
     (p/let [val# ~p-val]
       (def ~name val#))))
Usage:
(ns playground
  (:require
    [p-dev :refer-macros [p-def p-do]]
    [promesa.core :as p]))

(defn defer-value [value]
  (p/create
    (fn [resolve-cb]
      (js/setTimeout
        (fn []
          (resolve-cb value))
        500))))

(p-def val-1 (defer-value 1))
(p-do (println val-1))

(p-def val-2 (defer-value (inc val-1)))
(p-do (println val-2))

(p-def val-3 (defer-value (inc val-2)))
(p-do (println val-3))
(https://gist.github.com/zharinov/e9536a50a6ef67fe4ac98ba12ad6b5e7)

pez12:11:14

Wonderful. Thanks for sharing!

zharinov12:11:25

In the CLJ side, it's so easy to create some intermediate objects during exploratory REPL session (using def), but when dealing with many of Node.js APIs I realized I'm lacking this possibility