diff --git a/src/status_im/data_store/realm/core.cljs b/src/status_im/data_store/realm/core.cljs index 760ed6f2c5..428ed341bb 100644 --- a/src/status_im/data_store/realm/core.cljs +++ b/src/status_im/data_store/realm/core.cljs @@ -120,10 +120,67 @@ (defn filtered [results filter-query] (.filtered results filter-query)) +(defn add-js->clj-array + "Extends type with IEncodeClojure and treats it as js array." + [t] + (extend-type t + IEncodeClojure + (-js->clj + ([x options] + (vec (map #(apply clj->js % options) x)))))) + +(defn add-js->clj-object [t] + "Extends type with IEncodeClojure and treats it as js object." + (extend-type t + IEncodeClojure + (-js->clj + ([x options] + (let [{:keys [keywordize-keys]} options + keyfn (if keywordize-keys keyword str)] + (dissoc + (into + {} + (for [k (js-keys x)] + ;; ignore properties that are added with IEncodeClojure + (if (#{"cljs$core$IEncodeClojure$" + "cljs$core$IEncodeClojure$_js__GT_clj$arity$2"} + k) + [nil nil] + (let [v (aget x k)] + ;; check if property is of List type and wasn't succesfully + ;; transformed to ClojureScript data structure + (when (and v + (not (string? v)) + (not (boolean? v)) + (not (number? v)) + (not (coll? v)) + (not (satisfies? IEncodeClojure v)) + (str/includes? (type->str (type v)) "List")) + (add-js->clj-object (type v))) + [(keyfn k) (js->clj v :keywordize-keys keywordize-keys)])))) + nil)))))) + +(defn check-collection + "Checks if collection was succesfully transformed to ClojureScript, + extends it with IEncodeClojure if necessary" + [coll] + (cond + (not (coll? coll)) + (do (add-js->clj-array (type coll)) + (check-collection (js->clj coll :keywordize-keys true))) + + (let [f (first coll)] + (and f (not (map? f)))) + (do (add-js->clj-object (type (first coll))) + (js->clj coll :keywordize-keys true)) + + :else coll)) + (defn realm-collection->list [collection] (-> collection (.map (fn [object _ _] object)) - (js->clj :keywordize-keys true))) + (js->clj :keywordize-keys true) + check-collection)) (defn list->array [record list-field] (update-in record [list-field] (comp vec vals))) @@ -132,8 +189,12 @@ (-> (aget result 0))) (defn single-cljs [result] - (some-> (aget result 0) - (js->clj :keywordize-keys true))) + (let [res (some-> (aget result 0) + (js->clj :keywordize-keys true))] + (if (and res (not (map? res))) + (do (add-js->clj-object (type res)) + (js->clj res :keywordize-keys true)) + res))) (defn get-by-filter [realm schema-name filter] (-> realm @@ -148,7 +209,7 @@ (defn- field-type [realm schema-name field] (let [schema-by-name (get-schema-by-name (js->clj (.-schema realm) :keywordize-keys true)) - field-def (get-in schema-by-name [schema-name :properties field])] + field-def (get-in schema-by-name [schema-name :properties field])] (if (map? field-def) (:type field-def) field-def)))