Skip to content

Instantly share code, notes, and snippets.

@ertugrulcetin
Last active June 1, 2022 07:26
Show Gist options
  • Save ertugrulcetin/8d0aa38bbed171c3dc60771a48748e1e to your computer and use it in GitHub Desktop.
Save ertugrulcetin/8d0aa38bbed171c3dc60771a48748e1e to your computer and use it in GitHub Desktop.
Optimized Re-frame schema validation/check - ClojureScript, malli
(ns interceptors
(:require
[clojure.data :as d]
[malli.core :as m]
[malli.error :as me]))
(def prev-state (atom nil))
;; Applies schema only changed parts (diff) of the app-db (state)
(defn check-and-throw [schema state event]
(if @prev-state
(let [[things-only-in-prev things-only-in-current _] (d/diff @prev-state state)
changed-keys (set (concat (keys things-only-in-prev) (keys things-only-in-current)))]
(reset! prev-state state)
(when (seq changed-keys)
(let [schema* (->> schema
(rest)
(filter (fn [[schema-key & _]] (changed-keys schema-key)))
(cons :map)
(vec))]
(when-not (m/validate schema* state)
(js/console.error (str "Event: " (first event)))
(throw (js/Error. (str "Schema check failed: " (me/humanize (m/explain schema* state)))))))))
(do
(reset! prev-state state)
(when-not (m/validate schema state)
(js/console.error (str "Event: " (first event)))
(throw (js/Error. (str "Schema check failed at startup: " (me/humanize (m/explain schema state)))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment