Skip to content

Instantly share code, notes, and snippets.

@martinklepsch
Last active October 22, 2018 16:44
Show Gist options
  • Save martinklepsch/2709f81aa8c7840b00ea595d3943d7c8 to your computer and use it in GitHub Desktop.
Save martinklepsch/2709f81aa8c7840b00ea595d3943d7c8 to your computer and use it in GitHub Desktop.
(ns cljdoc.pathom3
(:require [com.wsscode.pathom.core :as p]
[com.wsscode.pathom.connect :as pc]
[clojure.core.async :as async]
[clojure.set]
[cljdoc.util.repositories :as repos]
[cljdoc.util.pom :as pom]
[cljdoc.config :as config]
[cljdoc.storage.sqlite-impl :as cljdoc-sqlite]))
;; util --------------------------------------------------------------
(defn- index-by [k xs]
(->> (for [[k vs] (group-by k xs)]
(if (second vs)
(throw (ex-info (format "Duplicate item for key %s: (files: %s)" k (mapv :file vs)) {:vs vs}))
[k (first vs)]))
(into {})))
(def namespaces-resolver
{::pc/sym `namespaces-resolver
::pc/input #{:cljdoc.artifact/sql-id}
::pc/output [:cljdoc.artifact/namespaces]
::pc/resolve (fn [env input]
{:cljdoc.artifact/namespaces ['some-stuff]})})
(def artifact-id-resolver
{::pc/sym `artifact-id-resolver
::pc/input #{:cljdoc/artifact}
::pc/output [:cljdoc.artifact/sql-id]
::pc/resolve (fn [env {:keys [cljdoc/artifact] :as in}]
(let [{:keys [group name version]} artifact]
{:cljdoc.artifact/sql-id (#'cljdoc-sqlite/get-version-id +db+ group name version)}))})
(defn build-index
"Build the Pathom Connect index based on resolvers and mutations provided."
[{:keys [resolvers mutations]}]
(reduce (fn [index {::pc/keys [sym] :as config}]
(if (::pc/resolve config)
(pc/add index sym (dissoc config ::pc/resolve))
(pc/add-mutation index sym (dissoc config ::pc/mutate))))
{}
(into resolvers mutations)))
(defn compile-resolvers
"Turn a list of resolvers into a single function that can be called
like `(single-resolve env input)` and will dispatch based on
::pc/resolver-data provided via the env."
[resolvers]
(let [as-map (index-by ::pc/sym resolvers)]
(fn [env input]
(let [resolve-sym (get-in env [::pc/resolver-data ::pc/sym])
resolve-fn (get-in as-map [resolve-sym ::pc/resolve])]
(resolve-fn env input)))))
;; Create a parser that uses the resolvers:
(def parser
(let [resolvers [namespaces-resolver artifact-id-resolver]
resolve-fn (compile-resolvers resolvers)
connect-index (build-index {:resolvers resolvers})]
(p/parallel-parser {::p/env (fn [env]
(merge
{::p/reader [p/map-reader p/env-placeholder-reader
pc/parallel-reader pc/open-ident-reader ]
::p/placeholder-prefixes #{">"}
::pc/resolver-dispatch resolve-fn
::pc/indexes connect-index}
env))
::p/plugins [p/error-handler-plugin
p/request-cache-plugin
p/trace-plugin]})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment