-
-
Save wilkerlucio/3547da04b525f0ab6a156d472e55d69b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns com.wsscode.fulcro3.raw-support | |
(:require | |
[oops.core :refer [oget oset! ocall oapply ocall! oapply! oget+ oset!+ ocall+ oapply+ ocall!+ oapply!+]] | |
[com.fulcrologic.fulcro.algorithms.tx-processing :as txn] | |
[com.fulcrologic.fulcro.data-fetch :as df] | |
[com.fulcrologic.fulcro.inspect.inspect-client :as inspect-client] | |
[com.fulcrologic.fulcro.raw.components :as rc] | |
[com.fulcrologic.fulcro.react.hooks :as f.hooks] | |
[com.wsscode.misc.coll :as coll] | |
[com.wsscode.pathom3.connect.operation.transit :as pcot] | |
[com.wsscode.transito :as transito] | |
[edn-query-language.core :as eql] | |
[goog.object :as gobj] | |
[promesa.core :as p] | |
["react" :as react] | |
[helix.core :as h])) | |
(defn prop-component? [x] | |
(and (map? x) | |
(some-> x meta ::fulcro-component))) | |
(def FulcroAppContext (react/createContext nil)) | |
(defn app-provider [app & children] | |
(apply h/create-element | |
(oget FulcroAppContext "Provider") | |
#js {:value app} | |
children)) | |
(defn use-app [] | |
(f.hooks/use-context FulcroAppContext)) | |
(defn pathom-remote [request] | |
{:transmit! (fn transmit! [_ {::txn/keys [ast result-handler]}] | |
(let [ok-handler (fn [result] | |
(try | |
(result-handler (assoc result :status-code 200)) | |
(catch :default e | |
(js/console.error e "Result handler for remote failed with an exception.")))) | |
error-handler (fn [error-result] | |
(try | |
(result-handler (assoc error-result :status-code 500)) | |
(catch :default e | |
(js/console.error e "Error handler for remote failed with an exception.")))) | |
key (-> ast :children first :key) | |
entity (some-> ast :children first :query meta :pathom/entity) | |
ident-ent {key (conj entity key)}] | |
(-> (p/let [res (request | |
(cond-> {:pathom/ast ast} | |
entity (assoc :pathom/entity ident-ent)))] | |
(ok-handler {:transaction (eql/ast->query ast) | |
:body res})) | |
(p/catch (fn [e] | |
(js/console.error "Pathom Remote Error" e) | |
(error-handler {:error e}))))))}) | |
(defn app-started! | |
"Register the application with Inspect, if it is available." | |
[app] | |
(let [networking (inspect-client/remotes app) | |
state* (inspect-client/state-atom app) | |
app-uuid (inspect-client/fulcro-app-id app)] | |
(swap! inspect-client/apps* assoc app-uuid app) | |
(inspect-client/record-history-entry! app @state*) | |
(swap! state* assoc inspect-client/app-uuid-key app-uuid) | |
(inspect-client/post-message :fulcro.inspect.client/init-app {inspect-client/app-uuid-key app-uuid | |
:fulcro.inspect.core/app-id (inspect-client/app-id app) | |
:fulcro.inspect.client/remotes (sort-by (juxt #(not= :remote %) str) (keys networking)) | |
:fulcro.inspect.client/initial-state @state*}) | |
(add-watch state* app-uuid #(inspect-client/db-changed! app %3 %4)))) | |
(defn load-component! | |
([props options] | |
(if (prop-component? props) | |
(let [{::keys [fulcro-app fulcro-component]} (meta props)] | |
(load-component! fulcro-app fulcro-component props options)) | |
(throw (ex-info "Invalid call to load-component" {})))) | |
([app component entity-props {::keys [entity-data]}] | |
(let [ident (rc/ident component entity-props)] | |
(df/load! app ident component | |
{:post-action (fn [{:keys [state load-params]}] | |
(let [ref (-> load-params :source-key)] | |
(swap! state update-in ref dissoc :ui/load-error))) | |
:error-action (fn [{:keys [state load-params result]}] | |
(let [ref (-> load-params :source-key)] | |
(swap! state update-in ref assoc :ui/load-error (:error result)))) | |
:update-query (fn [query] | |
(cond-> query | |
entity-data | |
(vary-meta assoc :pathom/entity entity-data)))})))) | |
(defn load-remote | |
[app component entity-props options] | |
(let [ident (rc/ident component entity-props) | |
load? (some-> entity-props meta ::load-remote)] | |
(f.hooks/use-effect | |
(fn [] | |
(if load? | |
(load-component! app component entity-props options))) | |
[load? (hash ident)]))) | |
(defn use-entity | |
([entity-props options] | |
(use-entity (use-app) entity-props options)) | |
([app entity-props {::keys [query] :as options}] | |
(let [options (merge {:initialize? true | |
:keep-existing? true} options) | |
component (f.hooks/use-memo #(rc/nc query {:initial-state (fn [] entity-props)}) | |
[(hash query) (hash entity-props)]) | |
props (f.hooks/use-component app component options)] | |
(load-remote app component entity-props options) | |
(vary-meta props assoc ::fulcro-app app ::fulcro-component component | |
::entity-props entity-props ::entity-options options)))) | |
(defn refresh! [x] | |
(let [{::keys [fulcro-app fulcro-component entity-props entity-options]} (meta x)] | |
(load-component! fulcro-app fulcro-component entity-props entity-options))) | |
(defn transact! | |
([app-or-component tx] (transact! app-or-component tx {})) | |
([app-or-component tx options] | |
(if (prop-component? app-or-component) | |
(let [{::keys [fulcro-app fulcro-component]} (meta app-or-component)] | |
(rc/transact! fulcro-app tx (coll/merge-defaults options | |
{:ref (rc/ident fulcro-component app-or-component) | |
:component fulcro-component}))) | |
(rc/transact! app-or-component tx options)))) | |
(defn load [props] | |
(vary-meta props assoc ::load-remote true)) | |
(defn mutate-remote-entity [{:keys [ast ref]} name] | |
(cond-> (assoc ast :key name :dispatch-key name) | |
ref | |
(update :params conj ref))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment