This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-26
Channels
- # adventofcode (2)
- # announcements (7)
- # babashka (20)
- # beginners (77)
- # brompton (6)
- # calva (4)
- # clj-kondo (28)
- # clj-together (1)
- # cljdoc (2)
- # cljfx (10)
- # cljsrn (1)
- # clojure (77)
- # clojure-europe (33)
- # clojure-gamedev (12)
- # clojure-uk (11)
- # clojurescript (95)
- # clojureverse-ops (4)
- # core-async (4)
- # core-logic (1)
- # cryogen (2)
- # cursive (14)
- # data-science (3)
- # datomic (47)
- # duct (1)
- # emacs (7)
- # fulcro (51)
- # gratitude (8)
- # helix (14)
- # hoplon (4)
- # improve-getting-started (60)
- # jobs (1)
- # jobs-discuss (4)
- # joker (11)
- # lsp (99)
- # meander (62)
- # membrane (5)
- # news-and-articles (3)
- # off-topic (64)
- # pathom (3)
- # polylith (11)
- # practicalli (7)
- # react (1)
- # reagent (8)
- # reveal (15)
- # shadow-cljs (78)
- # specter (7)
- # sql (16)
- # tools-build (1)
- # tools-deps (29)
- # workspaces (1)
- # xtdb (17)
What do you folks use to make #clj-kondo happy with Fulcro/RAD and Pathom code? There is https://raw.githubusercontent.com/clj-kondo/config/master/resources/clj-kondo.exports/clj-kondo/fulcro/config.edn but it only has defsc. Surely somebody has a more elaborate config?
{:dependencies true
:copy-configs true
:config-paths ["com.wsscode/async" "com.wsscode/pathom"]
:lint-as
{clojure.test.check.properties/for-all clojure.core/let
com.fulcrologic.fulcro.components/defsc clojure.core/defn
com.fulcrologic.fulcro.routing.dynamic-routing/defrouter clojure.core/defn
com.fulcrologic.fulcro.ui-state-machines/defstatemachine clojure.core/def}
:hooks
{:analyze-call {com.fulcrologic.fulcro.mutations/defmutation hooks.fulcro/defmutation}}}
(ns hooks.fulcro
""
{:author "Adam Helins"}
(:require
[clj-kondo.hooks-api :as hook]))
(defn defmutation
[{:keys [node]}]
(let [[_call
sym
& arg+] (:children node)
docstring (first arg+)
[[param+
& fn-like+]
docstring-2] (if (hook/string-node? docstring)
[(rest arg+)
docstring]
[arg+
nil])]
{:node (hook/list-node (concat [(hook/token-node 'defn)
sym]
(when docstring-2
[docstring-2])
[param+
(hook/vector-node (map #(let [[_sym
arg+
& body] (:children %)]
(hook/list-node (list* (hook/token-node 'fn)
arg+
body)))
fn-like+))]))}))
Thank you! Where do I place the hooks/fulcro.clj?
.clj-kondo/
.clj-kondo/config.edn
.clj-kondo/com.wsscode
.clj-kondo/com.wsscode/pathom
.clj-kondo/com.wsscode/pathom/config.edn
.clj-kondo/com.wsscode/async
.clj-kondo/com.wsscode/async/config.edn
.clj-kondo/.gitignore
.clj-kondo/hooks
.clj-kondo/hooks/fulcro.clj
would you consider sending a PR to https://github.com/clj-kondo/config/tree/master/resources/clj-kondo.exports/clj-kondo/fulcro ?
Sure. This could also live in the fulcro repo. Don't know which is preferable though
@U0522TWDA Pathom and Pathom 3 have some clj-kondo exports setup: https://github.com/wilkerlucio/pathom/blob/master/resources/clj-kondo.exports/com.wsscode/pathom/config.edn https://github.com/wilkerlucio/pathom3/blob/master/resources/clj-kondo.exports/com.wsscode/pathom3/config.edn
in my computer I have this alias setup to pull in kondo export deps:
alias kdeps="clj-kondo --copy-configs --dependencies --lint \"$(clojure -Spath -A:provided:dev)\" --parallel"
I think Fulcro could do the same, to allow Kondo to pull the hooks in the same way
@U0CKQ19AQ any thoughts? ☝️
@U0P7ZBZCK regarding :dependencies true
, what is it? I do not see it at https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md
we can also move that config to fulcro itself now that @U0CKQ19AQ gave the green light
yeah, it probably makes sense for additional contributions and edits of that to go on Fulcro’s dime, and not be noise on clj-kondo
@U0CKQ19AQ That also has the benefit that the config can be adapted per version of fulcro since it's attached to the artifact
@U0522TWDA you mind cleaning that up (ns name to com.fulcrologic…) and sending a PR?
I have put that on my todo list 🙂
Note that I just merged a PR to clj-kondo/config for fulcro as well: https://github.com/clj-kondo/config/pull/12#issuecomment-906542425 Might be good to compare if something is missing on either side (and then deprecate the clj-kondo/config side)
Small nitpick, but I haven't seen any config for Fulcro's testing macros, like the =>
symbol Fulcro uses for assertions. I'm not sure how to fix it on my own, but seems topical to point out here.
https://book.fulcrologic.com/#_behaviors_components_and_assertions
This has come up a couple of times. I think @adam678 has a complete config. I would suggest to either contribute it to fulcro or https://github.com/clj-kondo/config
There is that one PR that looks like it has quite a few related improvements for Fulcro https://github.com/clj-kondo/config/pull/12
Looks like the fulcro book online was republished without RAW docs. Section 18 is back to Dynamic routers.
I can't seem to get fulcro inspector working on the book.
book.js:267 Uncaught Error: Minified React error #200; visit for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
at Object.q.render (book.js:267)
at book.js:5931
at book.js:6128
is in console already at page load, and pressing any of those "Focus Inspector" buttons gives
VM95 :1176 Uncaught ReferenceError: book is not defined
at HTMLButtonElement.onclick (VM95 :1176)
This is on Chrome, where fulcro inspector works on my own codeActually, it should be ok (now?). I republished without rebuilding js, but the js was the right version
I'm creating two entities in a single transact!
call and using tempids for them (a list and an item in that list). The second mutation needs access to the server-generated realid of the first mutation. How should that be handled? Do I need to use :tempid->realid
in ok-action
to "patch" those persistent entities that need those realids?
What 2nd mutation? You mean y do (transact! [mut1 mut2])? I guess I would transact a single mutation and have its ok-action transact the 2nd mutation, with real ids.
Yep, just like that. Okay, that makes sense. I just wasn't sure how to compose dependent mutations like that. Thanks.
@U0522TWDA I need some additional params for mut2 that are not required for mut1. I don't think there's anything wrong with just adding them to the param map, but do you happen to know how to access the param map inside the ok-action
? I see that it's available in one form or another under various env
keys like :transacted-ast
, :transmitted-ast
, and a bunch of others, but is there a "correct" one to use?
@UPWHQK562 what do you mean by “Patching” the ids? Fulcro does that for you.
There is never a need to manually rewrite tempids to realids if you implemented your server middleware correctly, though it is easy to mess this up (unfortunately).
In fact, if you handle your own tempids you’ll probably miss something. See the list of what Fulcro does (for you) in that section. For example, rewriting the network queue is a very important aspect that is easy to not think about, and is very hard to do yourself (or in most other libraries)
If you were using something else, you’d be sending these things with your own mechanism. A lot of ppl would just do an async request…well, now you cannot think about ordering of operations (the user quickly adds, then deletes something, before the ID is rewritten). If it’s a non-queue based async operation, you’re screwed.
So, then you end up generating UUIDs on the client, but NOW you lose the ability to easily tell from a request (or app state) that something is new, and end up inventing some flag like “new?“, but you still haven’t fixed all the issues, because the nature of parallel processing in the async world means that the quick add/delete could see the delete be processed by the server before the add! Not to mention that you have to remember to remove the new?
flag or you’re in a screwed up state..but it is only safe to do that after the server actually confirms the data was saved.
These are the kinds of complexities Fulcro is trying to get out of your way. I highly recommend using the built-in tempid support.
@UPWHQK562 maybe if you explain a little more what/why you need? Do you use the built-in facilities for tempids? If I understand it well, your first mutation creates some entities and the second mutation then does some work on them (and thus needs their real IDs). I guess there are good reasons why you don't want a single server-side mutation that does both. As Tony said, Fulcro resolves the tmp to real IDs automatically but I am not sure what is the simplest way to get at them in the subsequent mutation.
@U0522TWDA that's an accurate description of what I'm trying to do. I am indeed using Fulcro's tempid support as much as I understand how to: creating tempids in the UI and passing them to the mutation functions, and having the server-side mutations create realids, returning the tempid->realid map. Here's some sample code:
;;; ui.cljs
(let [item-list-id (tempid/tempid)
item-id (tempid/tempid)]
(comp/transact! this
[(add-item-list
{:item-list/id item-list-id})
(add-item
{:item/id item-id
:item/item-list item-list-id})]))
;;; mutations.clj
(pc/defmutation add-item-list
[{:keys [crux] :as env}
{:item-list/keys [id] :as params}]
{::pc/sym `add-item-list}
(log/info "Creating" {:item-list/id id})
(let [internal-id (UUID/randomUUID)
updated-params (assoc params :item-list/id internal-id)]
(m/add-item-list! crux updated-params)
{:tempids {id internal-id}}))
(pc/defmutation add-item
[{:keys [crux] :as env}
{:item/keys [id text item-list ranges] :as params}]
{::pc/sym `add-item}
;; FIXME: item-list here is the tempid, not resolved realid from
;; add-item-list
(log/info "Creating" {:item/id id :item/item-list item-list})
(let [internal-id (UUID/randomUUID)
updated-params (assoc params :item/id internal-id)]
(m/add-item! crux updated-params)
{:tempids {id internal-id}}))
The FIXME
is where I'm having an issue - I need to persist the realid of the item-list instead of its tempid.
There is not a good reason why I don't just do it in a single server-side mutation. I have got it working that way before, but I thought that having discrete mutations for adding the list and then an item to that list would be better than some compound mutation like add-list-and-list-item
. Maybe I'm wrong in this case.