From 1bcfa4b8dc2413505c141620e127f7792a308942 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 7 May 2025 11:41:26 +0200 Subject: [PATCH] :tada: Add facility to define custom js class --- frontend/src/app/util/object.cljc | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/frontend/src/app/util/object.cljc b/frontend/src/app/util/object.cljc index a04e7e4b72..072d2a5f91 100644 --- a/frontend/src/app/util/object.cljc +++ b/frontend/src/app/util/object.cljc @@ -93,6 +93,51 @@ (when (some? obj) (js* "Object.entries(~{}).reduce((a, [k,v]) => (v == null ? a : (a[k]=v, a)), {}) " obj)))) +#?(:cljs + (defn plain-object? + ^boolean + [o] + (and (some? o) + (identical? (.getPrototypeOf js/Object o) + (.-prototype js/Object))))) + +;; EXPERIMENTAL: unsafe, does not checks and not validates the input, +;; should be improved over time, for now it works for define a class +;; extending js/Error that is more than enought for a first, quick and +;; dirty macro impl for generating classes. + +(defmacro class + "Create a class instance" + [& {:keys [name extends constructor]}] + + (let [params + (if (and constructor (= 'fn (first constructor))) + (into [] (drop 1) (second constructor)) + []) + + constructor-sym + (symbol name) + + constructor + (if constructor + constructor + `(fn ~name [~'this] + (.call ~extends ~'this)))] + + `(let [konstructor# ~constructor + extends# ~extends + ~constructor-sym + (fn ~constructor-sym ~params + (cljs.core/this-as ~'this + (konstructor# ~'this ~@params)))] + + (set! (.-prototype ~constructor-sym) + (js/Object.create (.-prototype extends#))) + (set! (.-constructor (.-prototype ~constructor-sym)) + konstructor#) + + ~constructor-sym))) + (defmacro add-properties! "Adds properties to an object using `.defineProperty`" [rsym & properties]