Fork me on GitHub

serializability. Inspect, support viewer, etc. In general if you use code in mutations or in the db you’re likely to run into problems. Computed is another story, actually. That has to do with targeted refresh.


All that said, if you want to shove code into the db, it will mostly work


mutations are symbols for a reason, though, and you can always put a symbol and data into the db, and then construct a mutation call from that…and that is perfectly fine in all of those other cases, and if you think about the overall structure of Fulcro: operations happen via mutations, so when you have an operation to “store”, shouldn’t you be storing the call, not the implementation of the call?


Ok, cool. I was wondering why, esp since I just made a big change to my app to include them 🙂

Robin Jakobsson09:05:27

I remember there being some kind of article or gist which showed HTML5-routing in Fulcro, but I can’t seem to find it. EDIT: Found it!

👍 4
Jakub Holý (HolyJak)14:05:23

the RAD demo also has built in html5 routing

👍 4

Seems like I am stuck at this now... "Parser Error: Mutation not found {:mutation com.example.model.account/check-session}". I am using the most up-to-date fulcro-rad-demo codebase as base, and there is no mention of com.example in my codebase.

Jakub Holý (HolyJak)14:05:48

I am quite sure that RAD demo has that namespace?!!


It has, but I replaced that name completely. Which means something outside of the fulcro-rad-demo repository probably has that hardcoded

Jakub Holý (HolyJak)15:05:29

When is that error thrown? As a result of a call from the frontend, I assume? What data is sent in that call?


On the initial loading of the frontend


20-05-19 15:02:24 linux-idle ERROR [com.fulcrologic.rad.pathom:73] - Parser Error: Mutation not found {:mutation com.example.model.account/check-session}
                                                                      org.jboss.threads.EnhancedQueueExecutor$    1449
                                                                org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask    1558
                                                                             org.jboss.threads.EnhancedQueueExecutor.safeRun    2019
                                                                                 io.undertow.server.HttpServerExchange$        830
                                                                            io.undertow.server.Connectors.executeRootHandler                370
                                                           io.undertow.server.session.SessionAttachmentHandler.handleRequest   68
                                    org.projectodd.wunderboss.web.undertow.async.websocket.UndertowWebsocket$2.handleRequest         109
                                                      immutant.web.internal.undertow/create-http-handler/reify/handleRequest                           undertow.clj:  239
                                                                                           ring.middleware.gzip/wrap-gzip/fn                               gzip.clj:  100
                                                                                            ring.middleware.ssl/wrap-hsts/fn                                ssl.clj:  105
                                                                                  ring.middleware.x-headers/wrap-x-header/fn                          x_headers.clj:   22 (repeats 2 times)
                                                                           ring.middleware.not-modified/wrap-not-modified/fn                       not_modified.clj:   61
                                                                     ring.middleware.default-charset/wrap-default-charset/fn                    default_charset.clj:   31
                                                                           ring.middleware.content-type/wrap-content-type/fn                       content_type.clj:   34
                                                                  ring.middleware.resource/wrap-resource-prefer-resources/fn                           resource.clj:   25
                                                               ring.middleware.absolute-redirects/wrap-absolute-redirects/fn                 absolute_redirects.clj:   47
                                                                                     ring.middleware.cookies/wrap-cookies/fn                            cookies.clj:  214
                                                                                       ring.middleware.params/wrap-params/fn                             params.clj:   67
                                                                   ring.middleware.multipart-params/wrap-multipart-params/fn                   multipart_params.clj:  171
                                                                         ring.middleware.nested-params/wrap-nested-params/fn                      nested_params.clj:   89
                                                                       ring.middleware.keyword-params/wrap-keyword-params/fn                     keyword_params.clj:   53
                                                                                     ring.middleware.session/wrap-session/fn                            session.clj:  108
                                                                  com.sompani.components.ring-middleware/wrap-html-routes/fn                    ring_middleware.clj:   53
                                                       com.fulcrologic.fulcro.server.api-middleware/wrap-transit-response/fn                     api_middleware.clj:  167
                                                         com.fulcrologic.fulcro.server.api-middleware/wrap-transit-params/fn                     api_middleware.clj:  138
                                                                               com.fulcrologic.rad.blob/wrap-blob-service/fn                              blob.cljc:  315 (repeats 2 times)
                                                 com.fulcrologic.fulcro.networking.file-upload/wrap-mutation-file-uploads/fn                        file_upload.clj:   83
                                                                          com.sompani.components.ring-middleware/wrap-api/fn                    ring_middleware.clj:   36
                                                             com.fulcrologic.fulcro.server.api-middleware/handle-api-request                     api_middleware.clj:   69
                                                          com.fulcrologic.fulcro.server.api-middleware/handle-api-request/fn                     api_middleware.clj:   70
                                                                       com.sompani.components.ring-middleware/wrap-api/fn/fn                    ring_middleware.clj:   38
                                                                        com.fulcrologic.rad.pathom/new-parser/wrapped-parser                             pathom.clj:  160
                                                      com.wsscode.pathom.core/wrap-normalize-env/wrap-normalize-env-internal                              core.cljc:  977
                                                      com.wsscode.pathom.core/wrap-normalize-env/wrap-normalize-env-internal                              core.cljc:  979
                                                            com.wsscode.pathom.connect/connect-plugin/connect-wrap-parser/fn                           connect.cljc: 1740
                                                com.wsscode.pathom.core/wrap-parser-exception/wrap-parser-exception-internal                              core.cljc:  808
                                                                                            com.fulcrologic.rad.pathom/fn/fn                             pathom.clj:  121
com.wsscode.pathom.core/post-process-parser-plugin/transform-parser-out-plugin-external/transform-parser-out-plugin-internal                              core.cljc:  718 (repeats 2 times)
                                          com.wsscode.pathom.core/env-plugin/env-plugin-wrap-parser/env-plugin-wrap-internal                              core.cljc:  878
                                         com.wsscode.pathom.core/env-wrap-plugin/env-wrap-wrap-parser/env-wrap-wrap-internal                              core.cljc:  886 (repeats 4 times)
                                          com.wsscode.pathom.core/env-plugin/env-plugin-wrap-parser/env-plugin-wrap-internal                              core.cljc:  878
                                                                                       com.wsscode.pathom.parser/parser/self                            parser.cljc:  235
                                  com.wsscode.pathom.core/wrap-mutate-handle-exception/wrap-mutate-handle-exception-internal                              core.cljc:  783
                                                                                           com.wsscode.pathom.connect/mutate                           connect.cljc: 1522
clojure.lang.ExceptionInfo: Mutation not found
    mutation: com.example.model.account/check-session


Fulcro Inspect is full of mentionings of com.example though

Jakub Holý (HolyJak)15:05:43

Look not at the server but client, that is initiating the call. I guess your cleanup was not so successfull. Perhaps stop shadow and rm -rf all generated .js? I guess you don't have and anymore?


I can run an ag -Q com.example in the root directory of the project and get zero results


I deleted .shadow-cljs, .cpcache and all generated javascript


And yes, I don't have these anymore

Jakub Holý (HolyJak)15:05:34

BTW I did what you did, using the demo as a starting point and then getting rid of com.example, and I do not have the problem


It did not help, but what did help was to tinker around with the script src in index.html. Why it managed to even get as far as it did without a valid script is beyond me...


But thanks!

👍 4

Has anyone used tick( with fulcro? I believe its use of time literals is causing all sorts of problems for fulcro inspector mainly during calls to pr-str by the inspector. I have a local version of the inspector running (chrome extension version) and whenever a map of data with tick values in it is printed I see:


Here's an example. If I click the copy button for the outer record, I get the max call stack error. But if I copy the habit/tasks data, there is no problem


this is the main problematic line if i change that to a plain string like:

(let [f (first content)]
  (str (if (seq? f) (first f) f)))
then inspect at least doesn't crash


Yeah, Inspect uses transit to send values across the security boundary, so any non-recognized EDN gets handled by a “default” handler. Not sure why pr-str goes into an infinite loop. that’s kind of weird.


Hm…I wonder if this is an actual error, or if you’re selecting so much data that it is a recursive algorithm and blows the stack before it manages to finish. The “outer record” is the entire db.


And your replacement code doesn’t try to print nearly as much, nor recursively down every path.


i had that thought too about it just being too much data, but it's about a screen full.. The screenshot i posted is cropped to just one property, it's not the full db




the clj formatter for devtools also blows up with it though


why is it getting into a loop I wonder…it is in the recursive algorithm, and it is running out of stack…so it is clearly going in a loop


putting a breakpoint somewhere in that stack trace and triggering the error might help


on line 10086 in core.cljs is where the main recursive part happens I think


ooh good idea - in chrome or in intellij?


yeah, see which branch it keeps going down


gotcha, that makes sense


too bad you’re not getting a source map on that


would be easier to just look at the stack trace…


yea i get a bunch of warnings that the map files can't be loaded


could be a proble with your server


network tab might be saying why


This is the error for the source map failures: DevTools failed to load SourceMap: Could not load content for <chrome-extension://hbmcmeegjjiijojkbofeekehegcjbaib/out/cljs-runtime/>: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME I'm new to all this setup so I'm a bit confused. I thought the shadow cljs webserver for fulcro inspect handles these requests. I also don't see the map files being requested the network panel of the extension's inspector


oh…the source maps for inspect itself would have to be pacakged in the chrome extension 😞


not sure how to fix that


no prob. I'm trying to trim down the problem - so i can send tick values and the network + tx tab are working..


Ok. I've narrowed down a repro. In my codebase I have the following transit writer:

(deftype TickHandler []
    (tag [_ v] "time/tick")
    (rep [_ v] (with-out-str (pr v)))
    (stringRep [_ v] nil))

  (def tick-transit-write-handler (TickHandler.))

  (def tick-transit-writer-handler-map
      (fn [m [k v]] (assoc m k v))
      (partition 2
          [Date DateTime Time Period Duration Instant]
          (repeat tick-transit-write-handler)))))

  (def date-writer (tr/writer :json {:handlers tick-transit-writer-handler-map}))
  (tr/write date-writer {:breaks #time/date "2020-05-19"})
when I write the above I get the string:
"[\"^ \",\"~:breaks\",[\"~#time/tick\",\"#time/date \\\"2020-05-19\\\"\"]]"
i copy that into the inspect repl for the ns fulcro.inspect.remote.transit and eval: (read "[\"^ \",\"~:breaks\",[\"~#time/tick\",\"#time/date \\\"2020-05-19\\\"\"]]") which gives me the error in the repl output:
Error handling response - class java.lang.ClassCastException: 
class clojure.lang.PersistentVector cannot be cast to class java.lang.CharSequence (clojure.lang.PersistentVector is in unnamed module of loader .PluginClassLoader @332e16cc; java.lang.CharSequence is in module java.base of loader 'bootstrap')
which shows up in devtools as:
RangeError: Maximum call stack size exceeded
    at Object.eval [as cljs$core$ILookup$_lookup$arity$2]
I'm pretty new to encoding types to transit, so I could foresee this being a problem with the writer I have. I think I'll try copying the default writer you're using and see if that fixes the problem


this is actually the simplest repro:

(tr/write date-writer #time/date "2020-05-19")
(f.i.r.transit/read "[\"~#time/tick\",\"#time/date \\\"2020-05-19\\\"\"]" )


reading this works in my app between FE and BE using this reader on the client:

(def date-reader (tr/reader :json {:handlers {"time/tick" #(cljs.reader/read-string %)}}))

Jakub Holý (HolyJak)15:05:30

Could something like this (from the time literals library) help?


i have transit codecs in my app for tick (time literals), but inspect does not


though, i did add them in my local dev version of spec and the pr-str bug still happens so that may actually not be the cause of the issue. esp because the DB tab works, but not network, txes, or db explore


but my implementation is different from this, so i'll give this a shot


still happening - that example just uses different tags for the time literals than what I had, so makes sense that it wouldn't work. I'll try again playing with inspect at some point


so, I finally found a solution for this.

(defrecord TestIt [a])
(write (TestIt. 5))
=> "[\"~#unknown\",\"#fulcro.inspect.remote.transit.TestIt{:a 5}\"]"
  (read "[\"~#unknown\",\"#fulcro.inspect.remote.transit.TestIt{:a 5}\"]")
=> throws the error I've been getting
to fix it I added a default read handler:
(def read-handlers
  {"js-error" (fn [[msg data]] (ex-info msg data))
   "unknown" (fn [v] (str "UknownTransitType:" v))})
js-joda dates will show up in inspector as a string "UknownTransitType:2020-05-21" which is fine by me.


oh..a default wasn’t in there? That’s an oversight


ok that's good to know. I wasn't sure if transit would somehow know what to do, but that makes sense now why it was breaking


should I open an issue for this on github?


a pR would be great


sounds good, i'll put one together

Björn Ebbinghaus18:05:54

@tony.kay There is a css problem in the Inspect Binary. The Index-Explorer has classes prefixed with com_wsscode_pathom_viz_ui but these aren't defined anywhere.


chrome or electron?

Björn Ebbinghaus18:05:55

I guess there is just a inject/style-element missing somewhere.


feel free to look around. I don’t have time to mess with it at the moment


I think I found it. What OS are you on?


@mroerni I’m uploading a new release…try it out and see if that fixes it


will be up in a moment

Björn Ebbinghaus19:05:55

I am on MacOS. It is fixed. Thanks for the quick response


I'm wondering if the fulcro inspector could be simplified by having it be embedded in the dom, alongside your app. similar to reframe 10x

Björn Ebbinghaus20:05:14

Hm.. I never experienced network problems... I quite like it to have it separate. I often have the DevTools popped out of the Window. The only thing I would like to see back is the component inspector... from v2.


have you ever encoded custom types for transit?


ever seen missing ids and data in the DB view?


it also only works for one browser


it used to be embedded in the DOM. We abandoned that because then we had a whole other host of problems (Css conflicts, etc.). I didn’t write the original inspect, or the rewrite even…to be honest I kind of prefer the “in the DOM” approach because I think it does have fewer headaches…but then now that we want electron we always have the potential “on the wire” issues…so it is kind of moot.


If you want to make a 3rd version that goes in the DOM, feel free. I have no time to address it….


oh, and the in-browser version also suffers from NPM madness: some of the inspect tabs use things like d3 etc…if your app uses those and there are conflict problems, then it totally hoses your development and you would just have to abandon the tooling


so, I think the decision for it to be “remote” is actually the right overall choice


The “in the browser” could work if you precompiled Inspect as a js file, and just included it…then you could package it up as an isolated js blob.


so then it would be “remote but not remote”


like everything worth doing the answer is "it depends there are tradeoffs"... I'll most likely start building a collection of helpers as i need them, the network and tx tab often crash because of that max callstack error I posted.


i don't understand enough about the setup between tabs, but the db tab does show the types correctly: [TaggedValue: unknown, 2020-05-19]


but the db explorer view for example, crashes


probably not hard to fix. either wrap pr-str in a try/catch, or do something else to format the special case


hard and easy are relative to the context you have...


i know what you mean, seems like is should be quick fix, but these seemingly minor fixes usually bring some surprises 🙂


then network encoding issues go away and the security restrictions from browsers