-
Notifications
You must be signed in to change notification settings - Fork 1
UX: StatusMap as IDeref container #13
Copy link
Copy link
Open
Description
Problem
execute returns a full status-map with internal structures, errors, stats, etc. But 99% of the time users only need the resolved instruction:
;; Current — verbose
(:instruction (commando/execute reg instruction))
;; Every single call site has this patternThe status-map is valuable as a container (errors, patching, debug) but the default UX forces everyone to unwrap it.
Solution: defrecord + IDeref
Make status-map a record type that implements IDeref. @ returns :instruction on success, throws ExceptionInfo (with full status-map as ex-data) on failure.
;; Happy path — clean, 99% of use cases
@(execute reg instruction)
;; => {"1" 1, "2" 1, "3" 1}
;; Explicit error handling — full control
(let [r (execute reg instruction)]
(if (ok? r)
@r
(handle-errors (:errors r))))
;; try/catch style
(try
@(execute reg instruction)
(catch #?(:clj ExceptionInfo :cljs ExceptionInfo) e
(let [{:keys [errors status]} (ex-data e)]
...)))
;; Patching — pass the container, deref the final result
(let [r (execute reg instruction)]
@(execute reg changed {:previous r}))Implementation sketch
(defrecord StatusMap [status instruction errors warnings successes stats uuid]
#?(:clj clojure.lang.IDeref
:cljs IDeref)
(#?(:clj deref :cljs -deref) [this]
(if (= status :failed)
(throw (ex-info "Commando execution failed" (into {} this)))
instruction)))Why defrecord works here
assoc/update/get/destructuring — all work, extra keys (:internal/*) stored in overflow map- No
dissocon status-map fields anywhere in the pipeline (verified) - Record field access (
:status,:instruction) is direct Java/JS field lookup — faster than hash-map - CLJS has
IDerefprotocol — cross-platform (= record plain-map)breaks, but tests compare individual keys, not entire status-maps
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels