Fork me on GitHub
#shadow-cljs
<
2023-09-13
>
Егор Шундеев12:09:14

Has anyone successfully used philoskim/debux-stubs with shadow-cljs? I'm using debux for debugging but ran into an issue where I forgot to remove a #d/clog tag from a commit, breaking the application. I've seen an https://github.com/day8/re-frame-debux/issues/30#issue-607861849 where @thheller suggests using ns aliases (`{:ns-aliases {debux.cs.core debux.cs.stubs}}` in my case, I guess) in the build options. However, it seems this approach doesn't work for tags. I assume this is because the tag is explicitly defined as {d/clog debux.cs.core/clog-tag}, making it impossible to substitute the namespace? Does anyone have a solution for safely using debux tags in shadow-cljs, or is manual removal before making a commit the only way to go?

Егор Шундеев12:09:16

I'm currently attempting to reimplement data_readers.cljc for the project, but maybe there is a more graceful way to handle the issue?

thheller13:09:24

hmm yeah reader literals are not handled by aliases

pmooser14:09:41

I'm still (unfortunately) on this path of using webpack as an external bundler with a wasm library (automerge 2) ... and I've had it working at various points, but after a library upgrade and some changes, I see some errors I don't understand when loading the page. I'll put them in reply so as not to pollute the channel ...

pmooser14:09:35

Any idea what I might be doing wrong (presumably with webpack) that would cause this error?

thheller15:09:41

not loading the webpack output before the shadow-cljs output

thheller15:09:17

you should have two script tags in the html

pmooser15:09:37

I do - but maybe something changed and my webpack config has to be different - I'll work on it some more and see if I can resolve the error through the webpack config.

pmooser15:09:39

Thank you!

pmooser11:09:34

@thheller I'm still on this path of trying to use a wasm library. I previously had it working, and the wasm library would show up in my cljs code as a promise, and you helped me use js-await to access the contents of that promise, and then I was able to use that module from there. They've made an update to the library, and now it doesn't appear as a promise anymore, but when I try to do things with it, it complains that .use hasn't been called on the module, which sounds like maybe it's not being loaded correctly. I know this isn't exactly supported territory for shadow-cljs, but do you have any ideas for things I might try? I'm currently using an import like this:

["@automerge/automerge" :rename {next automerge}]

thheller11:09:21

this means absolutely nothing to me. can you provide more context? JS examples/docs?

pmooser11:09:01

Yes, I'm sorry - the project I'm trying to use is: https://github.com/automerge/automerge/ I'm using webpack as an external js-provider with shadow-cljs. A javascript example of using it with webpack is provided here, about half a page down: https://automerge.org/docs/quickstart/

pmooser11:09:39

Essentially, I'm just trying to call .init on automerge, as they show there. And this has worked previously with this wasm setup, but at some point they upgraded their library in such a way that it no longer works, and notably, as I mentioned, it doesn't show up as a promise anymore in cljs.

thheller12:09:16

and why are you not following the docs exactly, but try to do something else?

thheller12:09:46

AFAICT the docs don't mention calling .next on anything?

pmooser12:09:55

In what way have you identified that I'm not following the docs? Ah.

thheller12:09:19

I see const Automerge = require('@automerge/automerge') and then let doc1 = Automerge.init()

pmooser12:09:41

next is the API they're migrating to, so certain things are essentially only possible in next, so despite it not being mentioned in the quickstart, it is supported and in fact recommended in their library.

thheller12:09:54

translated to cljs that is (:require ["@automerge/automerge" :as Automerge]) and then (def doc (Automerge/init))

pmooser12:09:02

Here - I think for the purposes of this discussion, I can probably reproduce the same error without next. One minute, and I can verify.

thheller12:09:32

I see no mention of next, so I have no clue what you are talking about

pmooser12:09:58

Are you an expert in automerge?

pmooser12:09:03

In that case, I'm not surprised you haven't heard of next.

pmooser12:09:07

I just explained it to you.

thheller12:09:09

no, I have never looked at it

pmooser12:09:37

So if I use this import instead:

pmooser12:09:49

["@automerge/automerge" :as am]

pmooser12:09:09

And I just try to do (.init am) exactly the same error as I described occurs.

pmooser12:09:14

So in fact it has nothing to do with next.

thheller12:09:33

and what is the error?

pmooser12:09:21

And speaking with the developers of automerge, they said that users should never have to call use themselves, and that it normally happens as a result of loading the module.

thheller12:09:33

looks like a JS problem to me?

thheller12:09:40

did you configure webpack correctly?

thheller12:09:15

shadow-cljs is not involved in the JS bundler with :js-provider :external

pmooser12:09:18

Yes, I mean, in so far as: • this configuration worked with a previous version of the library • webpack runs and emits js that I can load in the browser • it's the same webpack config present in the quickstart I linked above

pmooser12:09:54

Which part of what you see above is related to the js bundler? Just webpack doing the packaging?

thheller12:09:58

and you verified that a basic pure JS example works?

pmooser12:09:21

The developers say it does. Maybe I can go try to do that next.

pmooser12:09:32

Anyway, it sounds like you think this isn't anything related whatsoever to shadow-cljs.

pmooser12:09:35

Thanks for taking a look.

thheller12:09:59

I would put this in a JS file

import * as Automerge from "@automerge/automerge"
let doc = Automerge.init()
console.log(doc)

thheller12:09:08

run webpack over it and load it in a browser

pmooser12:09:17

Ok, I will give it a try, thank you.

thheller12:09:29

if that works we can look further and figure out what adding shadow-cljs into the mix does

pmooser12:09:49

Ok, thanks. I'll go work on this. I appreciate the pointers you're giving me.

pmooser12:09:08

@thheller Ok, so I did what you asked, and it works for both the "normal" library and the "next" submodule. The output looks like this in the console (not very useful, but just to prove I did it):

thheller12:09:41

and what does it look like if you translate that JS code to CLJS. only that. nothing else?

pmooser12:09:16

Do you mean that I should try to create the most minimal cljs project that does just this? I can certainly try that and report back.

thheller12:09:31

yes, ideally one you can share so I can look at it

pmooser12:09:50

Ok, I will try to do exactly that - but it will probably take me a bit. I'll report back to you once I have it set up.

thheller12:09:52

always hard to debug anything without seeing the code

pmooser12:09:00

Of course, that's very reasonable.

pmooser12:09:04

Thanks. I'll let you know.

pmooser12:09:26

@thheller Ok, I have it, with the same results as in my larger project (ie, I get the error which doesn't occur in plain js). How can I send you a .tgz of the project ?

pmooser12:09:55

And I will just nuke the node_modules directory rather than include it I assume.

pmooser12:09:35

Ok, let me package things up.

pmooser12:09:05

Here you go. I put some minor comments in the readme, but you just have to npm install and then you can execute the shell script run and then you can load index.html in the browser.

pmooser12:09:36

@thheller Let me know if you have any issues.

thheller13:09:33

ok, I'm guessing this is some sort of issue in webpack and its ESM/WASM bundling when used from a commonjs require file

thheller13:09:25

here is what basically happens

thheller13:09:48

the automerge package does this

thheller13:09:50

import * as wasm from "./automerge_wasm_bg.wasm";

thheller13:09:13

but .wasm imports in the browser are non-standard and therefore each bundler does something slightly different

thheller13:09:49

webpack in this case rewrites it to use the regular wasm initialization steps, which are async

thheller13:09:08

and it therefore uses its alternative loading mechanism that turns EVERY import async

thheller13:09:57

at least when working of a ESM file in the first place

thheller13:09:12

I changed the build config to

{:dev-http {8000 "resources/web"}
 :builds {:app {:target :browser
                :output-dir "resources/web/js"
                :modules {:main {:init-fn minimal.core/init}}
                :js-options {:js-provider :external
                             :external-index "target/index.js"
                             :external-index-format :esm}}}}

thheller13:09:31

which appears to work?

thheller13:09:59

but I think it can run into issues with the async loading, as in trying to use the dependencies before they finish loading

thheller13:09:17

since the webpack async loading mechanism is hidden from the user, there is no way to reliably detect it

thheller13:09:49

but at least I don't get an error on load

pmooser16:09:52

@thheller Thank you so much for looking into this - I've been in meetings all afternoon so I haven't had a chance to give this a try, but I really appreciate your thorough investigation and I'm hopeful that this can get things working for me again (although I understand what you said about async loading) ... I'm curious if it will change how the module "appears" to me (since, as I said, in the previous versions, the actual module showed up as a promise) ...

pmooser16:09:06

I'll let you know if it actually works for me, in case that's of interest.

pmooser16:09:28

It does appear to work! That's great. But what you said about async loading and not being able to reliably wait for it is disturbing, but I understand we can't do much about it. I'll give the feedback back to the automerge guys. Thank you again for your efforts on this - I didn't even know about the :external-index-format option.

thheller16:09:15

somewhat coincidence this works. that option exists for other reasons 😛

pmooser14:09:00

@thheller So as I said, that option seems to fix that fundamental issue, but what I see now is that if I load my application in a new browser window, I get the following error (followed of course by others):

pmooser14:09:11

When I refresh the page, I don't get the error anymore --

pmooser14:09:19

could this be the async loading issue that you mentioned,

pmooser14:09:36

where we don't have any real way to wait for webpack's async loading to be done?

pmooser14:09:55

And yeah, it's not even consistent - sometimes it takes more than 1 reload for the problem to go away, so it may just be pure luck whether or not it happens.

thheller14:09:10

yes, that is likely the async loading stuff

thheller14:09:41

the problem is that webpack thinks it is in control of everything and only ensures its own code is loaded properly and in order

thheller14:09:02

that of course doesn't work for us

pmooser14:09:05

Ok, thanks very much - this approach is dead in the water then. I'll go talk to the automerge devs and see if I can come up with something else !

pmooser14:09:11

Yes, that makes sense - but I appreciate your response and explanation !

thheller14:09:29

would be good if automerge had a way where you can initialize the wasm stuff yourself. i.e. not use import with a .wasm file

thheller14:09:54

as no browser supports that and is as of now a bundler feature, which shadow-cljs doesn't yet have

pmooser14:09:50

Yeah, I just asked them if there was a way to load the wasm myself (by coincidence) because it seems like that would let me bypass all of this and just use shadow-cljs like a normal person instead of in this webpack way anyway ...

thheller14:09:41

it'd be so simple if their Automerge.init just took an argument that is the wasm stuff

thheller14:09:05

import * as Automerge from "@automerge/automerge"
import { wasm } from "@automerge/automerge-wasm"
let doc = Automerge.init(wasm)
console.log(doc)

thheller14:09:19

it would be trivial to make that work with CLJS 😛

thheller14:09:43

but of course .. breaking change, so never gonna happen

pmooser14:09:50

Yes - that would be very nice indeed. Although in their typescript declarations they directly import some stuff from the wasm project (like import type { ... } from "@automerge/automerge-wasm") so I'm not sure if that's even possible for them. But I'll ask ...

thheller14:09:57

well its JS world, so maybe 😉

pmooser14:09:00

Do you have a patreon or something like that?

pmooser14:09:22

Nevermind, I found it.

thheller14:09:28

github sponsors, patreon yes 😛

pmooser14:09:16

Ok, I sent you something through the github sponsorship program - I'd rather have my company do something, but at least this shows that I appreciate the help you have given me over the past few years. Thank you again.

thheller17:09:24

thank you. much appreciated

Sam Ritchie20:10:23

Hey @U07VBK5CJ, I’m curious if you made progress here!

pmooser18:10:26

@U017QJZ9M7W was it auto merge specifically you were interested in ?

Sam Ritchie18:10:37

Yea that’s right

pmooser18:10:03

So for the time being I am stuck, because using web pack as a bundler in this way seems to introduce a loading race condition with the initialization of auto merge. However, I am talking to the auto merge guys, and they are going to eventually provide an interface that will let me load the wasm module myself, and then initialize auto merge with it, meaning that I won’t have to use the web pack bundler anymore at all. The timeline isn’t clear yet, but I am waiting on them to give me an example of how to do this.

Sam Ritchie21:10:00

Nice who are you talking to? Are you in their discord?