Hi guys, I'm building a react demo appl with cljs (to practice cljs) and I'm thinking about changing this very appl on the fly via a remote repl. Is that possible? For example, suppose I want to change a component to correct it and re-rendering it with my appl running in production. Is it possible to make these things via repl?
But if this appl is a Electron appl which runs in a single JS process (a node process), or even a controlled number of JS processes. So in this case, in theory, I could make changes on the fly via a remote repl to inject this change on the node process running my appl and all the clients would take this change, wouldn't they? @dpsutton
obs.: in the case of a controlled number of node processes, each one running an appl's instance, I'd enter in the repl of each instance to make the change
obs.: the repl I'd connect with remotely is the one fired by the start of my appl
A repl can only change the running instance. For a long running clj process this would be fine. But a cljs process is just someone’s browser. So if you repld to a particular users browser you could change it but the next load of a page would just get the originally compiled code without any changes. The same as restarting a clj process.
Seems to work just fine for me. Try clearing all the cache and build artifacts, including the .shadow-cljs
dir.
Yes, I see. I made some tests here with my appl and re-rendering its component via repl and it works but only for one particular browser's tab or window that opens my appl. And after reloading the page, the browser takes the initial compiled code. Opening other tabs/windows and calling my appl also cause the same effect. I didn't notice that in the case of setting the browser as the target means that the repl (fired during the build) will be connected to that instance/process of the browser through I eventually open my appl.
I am uploading a video to the server like so:
(reg-event-fx
:upload-shot-video
(fn [coeffects _]
(prn "uploading video")
(let [video {:uri (-> coeffects :db :shot-video-uri)}
body (js/FormData.)]
(prn "uri is " (-> coeffects :db :shot-video-uri))
(.append body "video" video)
{:http-xhrio {:method :post
:uri (str "<http://d18a6571c2e5.ngrok.io>" "/api/upload-shot-video")
:body body
:on-success [:upload-success]
:on-failure [:upload-error]
:response-format (edn/edn-response-format)}})))
where (-> coeffects :db :shot-video-uri) is the temporary uri of the image in the ios devicethe handler that I have is the following:
For saving the input stream into a file video.mov
(defn upload-shot-video [req]
(prn "uploading video")
(prn "video is! " (-> req :params))
(prn "video is " (-> req :body))
(<http://clojure.java.io/copy|clojure.java.io/copy> (-> req :body) (<http://clojure.java.io/file|clojure.java.io/file> "./resources/public/video.mov"))
(r/response {:res "okay!"}))
But the size of the file is turning out to be 0 bytes, whereas I expect a size greater than 0 bytes
How to correctly send the video to the server?
did you look into the extensive info noisesmith provided about the middleware? How it takes the body and creates a temporary file for you?
@dpsutton I removed the middleware and created a copy manually/
the video is in (-> req :body). At least there’s an inputstream in there
copying that input stream to the file system as a file is giving a file of 0 bytes
add a prn
statement on your request. just see what's in there. i suspect you've got more middleware going on. there might be more information
@dpsutton Here’s the request:
{:reitit.core/match #reitit.core.Match{:template "/api/upload-shot-video", :data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :result #reitit.ring.Methods{:get #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :get, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :head #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :head, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :post #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :post, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :put #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :put, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :delete #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :delete, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :connect #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :connect, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :options #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :options, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :trace #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :trace, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}, :patch #reitit.ring.Endpoint{:data {:middleware [#function[humboiserver.middleware/wrap-formats]], :handler #function[humboiserver.routes.home/upload-shot-video]}, :handler #function[humboiserver.middleware/wrap-formats/fn--9418], :path "/api/upload-shot-video", :method :patch, :middleware [#reitit.middleware.Middleware{:name nil, :wrap #function[humboiserver.middleware/wrap-formats], :spec nil}]}}, :path-params {}, :path "/api/upload-shot-video"}, :reitit.core/router #object[reitit.core$lookup_router$reify__11769 0x667531a6 "reitit.core$lookup_router$reify__11769@667531a6"], :aleph/request-arrived 166349045051244, :aleph/keep-alive? true, :cookies {}, :remote-addr "0:0:0:0:0:0:0:1", :params {:video ""}, :flash nil, :headers {"host" "<http://d18a6571c2e5.ngrok.io|d18a6571c2e5.ngrok.io>", "user-agent" "Humboi/1 CFNetwork/1206 Darwin/20.1.0", "content-type" "multipart/form-data; boundary=BrxekIJ39.PWpQVKqWBWuBAz5KUTH7jhXk67qEssuW4LZbO4Df535XFNLmYDbDGWT73QsP", "content-length" "200", "accept" "application/edn", "accept-language" "en-us", "x-forwarded-for" "110.225.238.196", "accept-encoding" "gzip, deflate"}, :server-port 3000, :muuntaja/request #FormatAndCharset{:format nil, :charset "utf-8", :raw-format "multipart/form-data"}, :form-params {}, :session/key nil, :query-params {}, :uri "/api/upload-shot-video", :server-name "localhost", :query-string nil, :path-params {}, :muuntaja/response #FormatAndCharset{:format "application/edn", :charset "utf-8", :raw-format "application/edn"}, :body #object[java.io.ByteArrayInputStream 0x222b0412 "java.io.ByteArrayInputStream@222b0412"], :multipart-params {"video" ""}, :scheme :http, :request-method :post, :session {}}
The only middleware is wrap-formats
can you open up the browser network pane and make sure you're actually sending bytes across the wire?
I don’t know how to do that. How does one open a browser network pane?
@ps What browser are you using?
safari
Ah... been many years since I used that... I'm sure it has developer tools but no memory of how to get at them...
@dpsutton You mean open the developer console here?: http://localhost:8081/debugger-ui/
Chrome has "dev tools" (as does Microsoft Edge for macOS).
Develop > Show Web Inspector. then click on the network tab
wouldn’t http://localhost:8081/debugger-ui/ open the simulator debugging and not the device? I’m recording the video on the device
which is supposed to be sent to the server after video stops recording
I have a feeling that http://localhost:8081/debugger-ui/ doesn’t open debugging for the device
command option I
no actually the debugger is working with the device
but @dpsutton what should I be looking for in the network tab?
the request that has a big video payload. look for it having some form data, try to find the size of the request, etc
identify if the video is getting to your backend and the problem is finding it in the request or if the frontend is sending it and you need to fix that first. just general debugging steps. cut the problem in half and then figure out a way to cut that remaining problem in half, etc
I have been using Microsoft Edge on macOS for ages -- and cmd-opt-i is what Edge uses to open dev tools 🙂
I don’t see any new requests in the console, whereas the server is receiving the request
if you're on the network pane and its correctly hooked up and you hit refresh you should see requests to load your js and html. i don't know what you're looking at so can't help you further
I do see the other requests
but apparently not the one with the video
and the number of requests isn’t increased either
I read this on cljs-ajax which the http-xhrio library wraps
cljs-ajax
doesn’t have any other support for file uploads (although pull requests are welcome).
but in this issue the user successfully uploads the file: https://github.com/JulianBirch/cljs-ajax/issues/122
This is confusing
hi everyone, probably stupid question asked million times but
(= (hash 1) (hash 1.7))
;; => true
is that expected?Clojure has different behavior
hashes are not guaranteed consistent across platforms
you can fudge that a little bit with ClojureScript
and having hashes collide is certainly normal
for various reasons we do try to generate identical hashes where practical
numbers are problematic of course because JavaScript only has double
so aligning things here is not really worth the other complications
A quick cljs REPL experiment shows that cljs vectors appear to be more like Clojure 1.5.1 and earlier, in that they collide often for a set of vectors like:
(def grid-keys (for [x (range 100), y (range 100)]
[x y]))
That was one example of the kind of hash collisions that led Clojure to change its hash
function in Clojure 1.6.0
I don't know whether the performance tradeoffs for fancier hashing is the same in cljs -- just thought I'd mention the results of that experiment, since the code demonstrating the problem with older Clojure versions was easy to copy and paste.
Hi guys, could someone validate this scenario for me? I was thinking if it's correct or feasible The context is to see if it make sense my thought of accessing the JS process on which is running my cljs appl so that I can make changes in it on the fly
@andy.fingerhut we use the same hashing functions as Clojure at the bottom
so we have the post 1.6 stuff, whether we have the vector specific tweaks is another investigation
Is a CLJS ticket that at first simply collects some observations on latest CLJS version hash behavior as compared to latest Clojure version perhaps useful?
sure
There are special channels for that - #jobs and #remote-jobs
Make sure to read the channels' descriptions.
Absolutely and this will be my only post in here. 2 members asked me to do it to help others in the community that may be looking for work !
@bkelly This is the second time you've been told not to post jobs in general channels -- and the second time I've deleted your post. If you want to post a job, do it in the appropriate channel and provide details about location/remote and any other criteria. Just saying "DM me for more details" just wastes people's time. /admin
thanks for explanation :thumbsup::skin-tone-3: