Skip to content

Instantly share code, notes, and snippets.

@nivekuil
Last active July 17, 2021 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nivekuil/1e5320b69f02cd55f39e6b9be8c48bf6 to your computer and use it in GitHub Desktop.
Save nivekuil/1e5320b69f02cd55f39e6b9be8c48bf6 to your computer and use it in GitHub Desktop.
pathom as integrant?
(ns com.nivekuil.nexus
(:require [com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.misc.macros :refer [full-symbol]]
[clojure.spec.alpha :as s]
[com.wsscode.pathom3.interface.eql :as p.eql]
[com.wsscode.pathom3.connect.indexes :as pci]
[com.wsscode.pathom3.connect.runner :as pcr]
[taoensso.timbre :as log]))
(def resolvers (atom {}))
(def done (atom []))
(def running (atom nil))
(defmacro bind!
{:style/indent 2
:arglists '([name docstring? arglist options? & body])}
[& args]
(let [{:keys [name arglist body] :as params}
(-> (s/conform ::pco/defresolver-args args)
(update :arglist pco/normalize-arglist))
arglist' (s/unform ::pco/operation-args arglist)
fqsym (full-symbol name (str *ns*))
kw (keyword fqsym)]
`(let [resolver# (pco/resolver '~fqsym ~(pco/params->resolver-options
(-> params
(assoc ::pco/op-name fqsym)
(assoc-in [:options ::pco/output] [kw])))
(fn ~name ~arglist'
(let [res# ~@body]
(swap! done conj
['~fqsym (some-> ~(:options params)
::halt
(partial res#))])
{~kw res#})))]
(swap! resolvers assoc ~kw resolver#)
resolver#)))
(defn init [config targets]
(doseq [ns (into #{} (map (comp symbol namespace)) targets)]
(require ns))
(let [env (-> (pci/register (mapv val @resolvers))
(assoc ::pcr/fail-fast? true))]
(reset! running (p.eql/process env config targets))))
(defn halt! []
(doseq [[comp-name comp-fn] (reverse @done)]
(when comp-fn
(println "halting " comp-name
(try (comp-fn)
(catch Exception e (println e))))))
(reset! running nil)
(reset! done []))
(comment
(bind! foo [{:keys [::db]}]
(str "API using " db))
(bind! cql [{:keys [cql-addr]}]
{::halt (fn [db] (str "halting db: " db))}
(str "db session on " cql-addr))
(init {:cql-addr "localhost:9042"} [::db ::api])
;; => #:nexus.core{:db "db session on localhost:9042", :api "API using db session on localhost:9042"}
(halt!)
;; => halting nexus.core/cql halting db: db session on localhost:9042
"`::db` is initialized even if we don't specify it"
(init {:cql-addr "localhost:9042"} [::api])
;; => #:nexus.core{:api "API using db session on localhost:9042"}
(halt!)
;; => halting nexus.core/cql halting db: db session on localhost:9042
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment