This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-25
Channels
- # announcements (4)
- # babashka (58)
- # beginners (21)
- # calva (42)
- # clj-kondo (15)
- # cljdoc (16)
- # cljs-dev (11)
- # clojure (57)
- # clojure-denmark (1)
- # clojure-europe (24)
- # clojure-france (4)
- # clojure-nl (1)
- # clojure-norway (16)
- # clojure-spec (6)
- # clojure-uk (2)
- # clojurescript (19)
- # clr (4)
- # conjure (1)
- # core-logic (3)
- # cursive (5)
- # data-science (2)
- # datascript (6)
- # datomic (3)
- # emacs (4)
- # events (3)
- # fulcro (17)
- # gratitude (2)
- # hyperfiddle (4)
- # introduce-yourself (3)
- # jobs-discuss (2)
- # lsp (27)
- # malli (22)
- # pathom (73)
- # portal (21)
- # re-frame (5)
- # releases (1)
- # vim (8)
- # xtdb (28)
I found two issues related to nested outputs in the regular parser, I'll work on some repro: • if a query asks for nested attributes, the result might return without them (I assume it's because they are already resolved by another but not listed as outputs of the last resolver which drops them), this happens even when lenient mode is false without a warning, if the last resolvers lists those nested attributes as output then they appear in the result • a batch resolver for a nested attribute in a collection only receives one input These issues don't appear with the parallel parser.
In the meatime this is the query I was working with for the second point, where user/latest-data-privacy
was returning 2 items, but organization/latest-data-privacy
was returning empty for the first, and I could see in the inputs of this resolver that it was only receiving the second one:
(pathom/parser {:current-user/id 5} [{[:user/id 16] [{:user/latest-data-privacy [:data-privacy/organization-id {:organization/latest-data-privacy [:data-privacy/id]} :data-privacy/id :data-privacy/version]}]}])
for the first point I had this query:
(pathom/parser {:current-user/id 5} [{[:organization/id 2] [{:organization/latest-data-privacy [:data-privacy/organization-id :data-privacy/id]}]}])
where data-privacy/organization-id
will not be in the result
organization/latest-data-privacy
was not listing data-privacy/organizatio-id
as output but the resolver that provided its input did
From what I can tell. If two resolvers output the same top level key, Pathom3 will treat them as equal regardless of nested params.
In my graph design, I’m particularly careful when modeling relationships. I’ll have resolvers with nested inputs/outputs return an ID attribute only. And the other resolvers that return data for that id.
They don't output the same top-level keys, one resolver gets the inputs that the latest-data-privacy wants as well as some attributes requested by the query, normally they should be in the response but the regular parser drops them. The parallel parser outputs them as expected
What you suggest to do is producing the case with the bug (the nested output is only the Id)
Ah ok. Not sure then. Interested to see your example.
This would be the repo for the first point
(ns com.wsscode.pathom3.test
(:require [clojure.test :as t]
[com.wsscode.pathom3.format.shape-descriptor :as pfsd]
[com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.pathom3.connect.indexes :as pci]
[com.wsscode.pathom3.connect.planner :as pcp]
[edn-query-language.core :as eql]
[com.wsscode.pathom3.interface.eql :as p.eql]
[com.wsscode.pathom3.interface.async.eql :as p.a.eql]))
(pco/defresolver toy
[env input]
{::pco/input [:toy/id]
::pco/batch? true
::pco/output [:toy/name :toy/id :toy/order]}
(map #(get {1 {:toy/name "Bobby" :toy/id 1 :toy/order 3}
2 {:toy/name "Alice" :toy/id 2 :toy/order 2}
3 {:toy/name "Rene" :toy/id 3 :toy/order 1}}
(:toy/id %))
input))
(pco/defresolver child-toys
[env input]
{::pco/input [:child/id]
::pco/batch? true
::pco/output [{:child/toys [:toy/id]}]}
[{:child/toys [{:toy/id 1}
{:toy/id 2}
{:toy/id 3}]}])
(pco/defresolver favorite-toy
[env input]
{::pco/input [{:child/toys [:toy/id :toy/order]}]
::pco/batch? true
::pco/output [{:child/favorite-toy [:toy/id]}]}
[{:child/favorite-toy (->> (:child/toys (first input))
(sort-by :toy/order)
first)}])
(def env (-> (pci/register
[toy
child-toys
favorite-toy])))
(defn test-case []
(let [query [{[:child/id 1] [{:child/favorite-toy [:toy/name]}]}]]
(println "Regular")
(println (p.eql/process env query))
(println "===========")
(println "Parallel")
(println @(p.a.eql/process (assoc env ::p.a.eql/parallel? true) query))))
Regular
{[:child/id 1] #:child{:favorite-toy {}}}
===========
Parallel
{[:child/id 1] #:child{:favorite-toy #:toy{:name Rene}}}
This is the outputmight be the same as the issue reported here https://github.com/wilkerlucio/pathom3/issues/173
thanks for the additional repro on that @U03K8V573EC, this is the next thing I'm planning to work on Pathom 3
and I think they have a good change of being the same issue (#173 & #177)
In my graph design, I’m particularly careful when modeling relationships. I’ll have resolvers with nested inputs/outputs return an ID attribute only. And the other resolvers that return data for that id.
In P3, how do I make a similar index-explorer
defresolver as I did in P2? In P2 I have
(pco/defresolver index-explorer [{::pco/keys [indexes]} _] ; FIXME for P3
{::pco/input #{:com.wsscode.pathom.viz.index-explorer/id}
::pco/output [:com.wsscode.pathom.viz.index-explorer/index]}
{:com.wsscode.pathom.viz.index-explorer/index
(p/transduce-maps
(remove (comp #{::pc/resolve ::pc/mutate} key))
indexes)})
I search the docs but found just https://pathom3.wsscode.com/docs/indexes which wasn’t helpful in this regard. Then I found https://pathom3.wsscode.com/docs/debugging/#index-explorer which reads
> To learn about this, please https://blog.wsscode.com/pathom/v2/pathom/2.2.0/connect/exploration.html. The behavior of them in Pathom 3 is the same as in Pathom 2.
but I am not sure where to find p/transduce-maps
or what to replace it with 🙏the recommend way to make that in Pathom 3 is using the boundary interface: https://pathom3.wsscode.com/docs/eql#boundary-interface
I see! And since Fulcro already uses it then I do not need to do anything for index explorer to work 🎉 Thx a lot!
Hm, this does not seem to work. Fulcro uses the boundary interface but my in-browser Fulcro Inspect’s Index Explorer tells me > Seems like the index is not available.
that's a different problem, Fulcro inspect is not updated for Pathom 3 =/
to get that working we need to update Pathom Viz in Fulcro Inspect, the catch is that Pathom Viz has migrated to Fulcro 3, while Fulcro Inspect didn't
so we need to upgrade Fulcro Inspect to Fulcro 3 first, and then update Pathom Viz, or do some weird glue to connect Fulcro 2 and 3 there, but this last one seems a bad option IMO
what you can do now is to use Pathom Viz stand alone app, that properly handles Pathom 3, a bit annoying to have one extra thing, but works
I see, thank you! Trying it out now.
How does Viz see my Fulcro app? Or rather it does not see it, in my case. so how do I connect it? It happily accepted http://localhost:3009/api as the connection url but that doesn’t really seem to be working as no resolvers are shown 🙏
it is probably hitting it just fine, but its asking for the Pathom 2 keyword for indexes, and the Pathom 3 doesn't respond to that key
I guess we may be able to do a dirty fix
but adding a new resolver ,to expose Pathom 2 key in Pathom 2 index format
ah, maybe it does work, I see errors like > ava.lang.RuntimeException: java.lang.Exception: Not supported: class com.fulcrologic.rad.resolvers_common$secure_resolver$fn__39477 > at com.cognitect.transit.impl.WriterFactory$1.write(WriterFactory.java:65)
so I guess I need to clean up the resolvers before sending them over, as I remember we needed to do with P2
there are some key things to do in this scenario:
1. a resolver with the input of com.wsscode.pathom3.connect.indexes/indexes
and output of :com.wsscode.pathom.connect/indexes
2. do a similar thing for all the namespaces for the indexes (from ::pci from p3 to ::pc from p2
3. update each resolver and mutation so the keys use pathom 2 names
4. convert input values from EQL to flat sets
I think I already have this code on Pathom Viz, let me check
actually here, in the connector sources: https://github.com/wilkerlucio/pathom-viz-connector/blob/master/src/com/wsscode/pathom/viz/ws_connector/pathom3/adapter.cljc
Thank you, I will try that. However I suspect I have the same problem in both cases - I need to “clean” the indices to remove stuff that cannot be transferred over transit, namely (resolver) functions. How do you do that? Thats how we fix it for P2: https://github.com/fulcrologic/fulcro-rad-demo/blob/c09d1c30482c63ca2b468c9a7789dd5e80604a50/src/sql/com/example/components/parser.clj#L29-L31
For integration approach #2, I have added com.wsscode.pathom.viz.ws-connector.pathom3.adapter/env
as the starting env of my parser. I assumed that it exposes indices in fulcro inspect compatible way but it does not seem to be fully the case, as it doesn’t produce the :com.wsscode.pathom.viz.index-explorer/index
resolver it is looking for. I see it declares the output of :com.wsscode.pathom.connect/indexes
, which is not the same.
I need your advice 😭 I am trying to get the external Pathom Viz working and thus to remove from indexes stuff that cannot be transferred over transit. I have fixed that but now P.V. does not like the response 😭 First, my code to ensure the data is transit-able:
(defn protect-attributes-wrapper [mse]
(fn [env source {:keys [key] :as ast}]
(if (#{:com.wsscode.pathom.connect/indexes
::pci/indexes
::pci/index-attributes
::pci/index-io
::pci/index-resolvers
::pci/transient-attrs
:com.wsscode.pathom3.connect.runner/attribute-errors
:pathom.viz/support-boundary-interface?}
key)
(walk/prewalk (fn [form] (if (fn? form) nil form)) source)
(mse env source ast))))
; create the plugin
(p.plugin/defplugin clean-indices-plugin {:com.wsscode.pathom3.format.eql/wrap-map-select-entry protect-attributes-wrapper})
and use the plugin with the parser.
Now the dev tools in P.V. show:
> The result-action mutation handler for mutation com.wsscode.pathom.viz.index-explorer/load-indexes* threw an exception.
> #error {:message “Resolver com.wsscode.pathom3.connect.indexes->com.wsscode.pathom.connect/index-resolvers--attr-transform exception at path []: No protocol method IOperation.-operation-config defined for type cljs.core/PersistentArrayMap:
> {:config {::pco/input [], ::pco/provides {:p/method {}}, ::pco/output [:p/method], ::pco/op-name :p/method-resolver, ::pco/requires {}}, :resolve nil}”
So it seems to fail b/c my cleanup code replaced :resolve
value, which was a function and thus not transit-able, with nil
. So I am in a Catch 22 😞@U0522TWDA to use the Pathom Viz I suggest you use via the pathom viz connector: https://github.com/wilkerlucio/pathom-viz-connector/#connecting-env-pathom-3
using from it will make sure all the setup/encoding stuff is properly handled
so you dont have to any transit or anything
but for your server comms anyway, I suggest you can use transito: https://github.com/wilkerlucio/transito
this is wrap top of transit, but I handle things like ensure everything encodes, no matter what (so nothing breaks from failed encoding, as functions for example)
I do use the connector and p.connector/connect-env
. How does it work? Does it start a separate server on a different port, or what?
yes, it makes a server on your side and connects the app with it
When I have added connect-env to my parser’s env and start the standalone Viz, it does not detect anything, so I guess I have to manyally add a connection? http://localhost:<some port> I assume?
it actually depends, on cljs it will make a connection with the app via web sockets
no, this is clj / backend
for clj it uses http servers (one at the client, one at the server)
it should detect automatically
you just need to load your source after opening the app
it should add a tab automatically
WDYM by “you just need to load your source after opening the app” ? Like load my parser.clj file into the repl?
yes, run the part that has the connection code (p.connector/connect-env ...)
one CLJ side I commonly use a pattern on the end of the threading to make the env, eg:
(def env
(-> {:some "config"}
(pci/register ...)
((requiring-resolve 'com.wsscode.pathom.viz.ws-connector.pathom3/connect-env)
"debug")))
the requiring-resolve here is nice because I can add/remove viz just by changing this line (no need to change anything at the ns
declaration)
ah, sorry, I did not get that it takes a parser and returns a parser, I though it takes an env and returns an env
it does take and env and return an env
that's the env in the example above
oh, I am just confused b/c the docstirng on connect-env reads >
Connect a Pathom parser to the Pathom Viz desktop app. The return of this function
> is a new parser,
> are you using the correct namespace?
pathom 3 has a different namespace
[com.wsscode.pathom.viz.ws-connector.pathom3 :as p.connector]
this is com.wsscode.pathom.viz.ws-connector.pathom3/connect-env
ah, you right, that docstring needs changing
probably copied over and missed changing it
I do not have access to the env b/c I use Fulcro’s P. parser that hides that. Can I use an env plugin? Like this
[(pbip/env-wrap-plugin #(com.wsscode.pathom.viz.ws-connector.pathom3/connect-env % {::pvc/parser-id "jhtest"}))]
but that doesn’t seem to have any effect…no, you really need to make that in the env, because it setups up some plugins, it cant be done at an env wrap level
docs updated, will be right once there is a next release
It got connected 🎉
but somehow it does not see my resolvers and attributes, only foreign-indexes-resolver and 3 pathom’s attributes
Is order important? I put it into the env before anything else
yes, order is important
if you connect before registering, things wont be there
it works 🎉 Thx a lot for the advice! I will contribute the necessary changes to Fulcro and document this.