metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.48k stars 210 forks source link

Add :xf option to map-schema #899

Closed dvingo closed 1 year ago

dvingo commented 1 year ago

This PR adds a new option the -map-schema - the :xf option for transform function.

The motivation for this is the desire to instrument helix components using malli schemas.

Helix components are plain functions which accept JavaScript objects and transform them into ClojureScript maps for you. So when instrumenting the data that malli (-instrument) sees will be a JS object, but as a user of the helix you get nice CLJS data structures. Essentially there is no opportunity to add transformation code before malli receives the JS data and that led me to add the transform option to the map-schema.

in CLJS the usage looks like this:

;; in your malli registry:
{:helix/props   (m/-map-schema {:naked-keys true :pred object? :xf cljs-bean.core/bean}
 :react/element (m/-simple-schema {:type :react/element :pred react/isValidElement})
 :js/object     (m/-simple-schema {:type :js/object :pred object?})}

and a helix component can be instrumented like so:

(defnc a-component
  {:malli/schema [:=> [:cat [:helix/props [:prop-a :string] #_etc] :js/object]
                      :react/element]}
  [props]
  ,,,)
dvingo commented 1 year ago

I've been playing with this some more and it has some deficiencies due to react components now always being functions (and thus not always able to be instrumented). I am going to close this and use the strategy to use a macro to emit two functions and instrument the delegated one so malli can be used directly.