Builds client SSR approach, sunsets old cljs.

This commit is contained in:
2024-01-09 21:40:43 -08:00
parent d824cdfff4
commit 8063a8fcbd
74 changed files with 4603 additions and 4047 deletions

View File

@@ -1,5 +1,8 @@
(ns iol-ion.tx.upsert-entity
(:require [datomic.api :as dc])
(:require [datomic.api :as dc]
;; [clj-time.core :as time]
;; [clj-time.coerce :as coerce]
)
(:import [java.util UUID]))
@@ -9,11 +12,11 @@
(defn -by
[f fv xs]
(reduce
#(assoc %1 (f %2) (fv %2))
{}
xs))
#(assoc %1 (f %2) (fv %2))
{}
xs))
(defn -pull-many [db read ids ]
(defn -pull-many [db read ids]
(->> (dc/q '[:find (pull ?e r)
:in $ [?e ...] r]
db
@@ -21,82 +24,93 @@
read)
(map first)))
;; TODO add DATOMIC_EXT_CLASSPATH ala https://docs.datomic.com/pro/reference/database-functions.html#transaction-functions
;; (defn transform-common [v]
;; (cond
;; (nil? v)
;; v
;; (satisfies? clj-time.core/DateTimeProtocol v)
;; (clj-time.coerce/to-date v)
;; :else
;; v))
(defn upsert-entity [db entity]
(when-not (or (:db/id entity)
(:db/ident entity))
(datomic.api/cancel {:cognitect.anomalies/category :cognitect.anomalies/incorrect
:cognitect.anomalies/message
(str "Cannot upsert without :db/id or :db/ident, " entity)}))
(:db/ident entity))
(datomic.api/cancel {:cognitect.anomalies/category :cognitect.anomalies/incorrect
:cognitect.anomalies/message
(str "Cannot upsert without :db/id or :db/ident, " entity)}))
(let [e (or (:db/id entity) (:db/ident entity))
is-new? (string? e)
extant-entity (when-not is-new?
(dc/pull db (keys entity) (or (:db/id entity) (:db/ident entity))))
ident->value-type (-by :db/ident (comp :db/ident
:db/valueType)
(-pull-many
:db/valueType)
(-pull-many
db
[{:db/valueType [:db/ident]} :db/ident]
(keys entity)))
ident->cardinality (-by :db/ident (comp :db/ident
:db/cardinality)
(-pull-many
:db/cardinality)
(-pull-many
db
[{:db/cardinality [:db/ident]} :db/ident]
(keys entity)))
ops (->> entity
(reduce
(fn [ops [a v]]
(cond
(= :db/id a)
ops
(fn [ops [a v]]
(cond
(= :db/id a)
ops
(= :db/ident a)
ops
(= :db/ident a)
ops
(or (= v (a extant-entity))
(= v (:db/ident (a extant-entity) :nope))
(= v (:db/id (a extant-entity)) :nope))
ops
(and (nil? v)
(not (nil? (a extant-entity))))
(if (= :db.cardinality/many (ident->cardinality a))
(into ops (map (fn [v]
[:db/retract e a (cond-> v
(:db/id v) :db/id)])
(a extant-entity)))
(or (= v (a extant-entity))
(= v (:db/ident (a extant-entity) :nope))
(= v (:db/id (a extant-entity)) :nope))
ops
(conj ops [:db/retract e a (cond-> (a extant-entity)
(:db/id (a extant-entity)) :db/id)]))
(and (nil? v)
(not (nil? (a extant-entity))))
(if (= :db.cardinality/many (ident->cardinality a))
(into ops (map (fn [v]
[:db/retract e a (cond-> v
(:db/id v) :db/id)])
(a extant-entity)))
(nil? v)
ops
(conj ops [:db/retract e a (cond-> (a extant-entity)
(:db/id (a extant-entity)) :db/id)]))
(nil? v)
ops
;; reset relationships if it's refs, and not a lookup (i.e., seq of maps, or empty seq)
(and (sequential? v) (= :db.type/tuple (ident->value-type a)) (not (= :db.cardinality/many (ident->cardinality a))))
(conj ops [:db/add e a v])
(and (sequential? v) (= :db.type/tuple (ident->value-type a)) (not (= :db.cardinality/many (ident->cardinality a))))
(conj ops [:db/add e a v])
(and (sequential? v) (= :db.type/ref (ident->value-type a)) (every? map? v))
(into ops [[:reset-rels e a v]])
(and (sequential? v) (= :db.type/ref (ident->value-type a)) (every? map? v))
(into ops [[:reset-rels e a v]])
(= :db.cardinality/many (ident->cardinality a))
(into ops [[:reset-scalars e a v]])
(= :db.cardinality/many (ident->cardinality a))
(into ops [[:reset-scalars e a v]])
(and (sequential? v) (not= :db.type/ref (ident->value-type a)))
(into ops [[:reset-scalars e a v]])
(and (sequential? v) (not= :db.type/ref (ident->value-type a)))
(into ops [[:reset-scalars e a v]])
(and (map? v)
(= :db.type/ref (ident->value-type a)))
(let [id (or (:db/id v) (-random-tempid))]
(-> ops
(conj [:db/add e a id])
(into [[:upsert-entity (assoc v :db/id id)]])))
(and (map? v)
(= :db.type/ref (ident->value-type a)))
(let [id (or (:db/id v) (-random-tempid))]
(-> ops
(conj [:db/add e a id])
(into [[:upsert-entity (assoc v :db/id id)]])))
:else
(conj ops [:db/add e a v])
))
[]))]
:else
(conj ops [:db/add e a v])))
[]))]
ops))