Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for new GHC JS backend #7

Merged
merged 5 commits into from
May 13, 2024
Merged

Conversation

sevanspowell
Copy link
Contributor

  • Update the project to allow it to compile with newer versions of servant-client-core (while still being backwards-compatible).
  • Modify cabal file so it compiles when using the new GHC JS backend.

Related to #6 (sorry I didn't see this earlier).

@tysonzero
Copy link

Were you able to get this working? I'm getting:

ReferenceError: $1 is not defined
    at h$$26a10042 (script.js:149851:30)
    at h$runThreadSlice (script.js:14475:11)
    at h$runThreadSliceCatch (script.js:14449:12)
    at h$mainLoop (script.js:14444:9)

and nothing is showing up in the network tab or on the server side.

@sevanspowell
Copy link
Contributor Author

@tysonzero

I definitely encountered issues like that. That's probably due to using too low a version of ghcjs-base and/or ghcjs-dom.

That $1 was used a lot in the old style of Javascript imports:

foreign import javascript interruptible "h$dom$sendXHR($1, $2, $c);" js_send :: XMLHttpRequest -> JSVal -> IO Int

Now it should look like:

foreign import javascript interruptible "((x, y, c) => { h$dom$sendXHR(x, y, c); } )" js_send :: XMLHttpRequest -> JSVal -> IO Int
-- OR equivalent:
foreign import javascript interruptible "h$dom$sendXHR" js_send :: XMLHttpRequest -> JSVal -> IO Int

There have been updates to ghcjs-base and ghcjs-dom to fix this, but they didn't quite hit all areas. I've made updates to ghcjs-base and ghcjs-dom to fix the issues with this I've found.

You can't rely on cabal to pick these changes up, because I doubt they've reached hackage yet (though there are PRs: ghcjs/ghcjs-base#136 and ghcjs/ghcjs-dom#105).

I found this cabal.project worked for me:

source-repository-package
    type: git
    location: https://github.com/sambnt/servant-jsaddle.git
    tag: 31bf67d913257c42924a4c9fdc6e02bd36cb0489
    --sha256: 0607avxc2rshq5zpc0qsp9fz6pfwkm2ka9qgykjjkhdx870d7jxc

source-repository-package
    type: git
    location: https://github.com/ghcjs/ghcjs-dom.git
    tag: 032f89efbf5afa3b5ea9d0c04b3b3a718c4795f3
    --sha256: 0vpciimn0rc44razx1w3zxmx3mhnidm1mf5yjaxa8i8pcj8vrp3g
    subdir:
      ghcjs-dom

source-repository-package
    type: git
    location: https://github.com/sambnt/ghcjs-base.git
    tag: 930050a115bc2b78394f705df060e1b79004bb71
    --sha256: 1cwfv9n01q0xf688vqqpadvncbrv8chk5yxvh1w1qxlaiwcj9s2z

You might get away with just the ghcjs-dom source-repository-package.

For a working example see: https://github.com/sambnt/haskell-js-templates

Let me know if that works for you! If not, link me to a repo and I'll try to reproduce.

@tysonzero
Copy link

@sevanspowell

Thanks so much for the info and the cabal.project, building it all now to see if that fixes it.

After reading the various linked threads it seems like you have been working on getting miso's examples to build with the new backend. So I was wondering if you wanted to be a part of the work mentioned at the bottom of dmjio/miso#738.

I haven't properly tried to get miso's examples fully working with the new backend, I just copy pasted the TodoMVC code into my own new project to get the code sizes I posted there. If you by chance have or almost have a working build of miso's examples it would be great to have those in a public repo, or even in miso's repo (whether as a fork/unmerged-PR or merged into miso proper) so that binary sizes can be easily compared between the two.

@tysonzero
Copy link

tysonzero commented May 8, 2024

@sevanspowell

Still getting a $1 is not defined error that point to h$dom$sendXHR($1, $2, $c); in the compiled code.

Perhaps I'm still somehow using some older/incorrect code, or it's a caching issue? I do still see h$dom$sendXHR($1, $2, $c); here, however if your template is working then it seems that shouldn't be a blocker?

I'm also on x86_64-darwin if that impacts things.

@tysonzero
Copy link

Ah ok the issue was that even though it was using a newer ghcjs-dom, it was still using an older ghcjs-dom-javascript. If I add the latter to the subdir and move the commit back once to avoid ghcjs/ghcjs-dom#107 then it works!

source-repository-package
    type: git
    location: https://github.com/ghcjs/ghcjs-dom.git
    tag: 9b4b41a0ce2a6763e48b7603a0264cc9d97d8152
    --sha256: sha256-hq8h7HyS9maf++H1GAqIm0DUMNA6e2YQoO3cmvXoz1s=
    subdir:
      ghcjs-dom
      ghcjs-dom-javascript
source-repository-package
    type: git
    location: https://github.com/sambnt/ghcjs-base.git
    tag: 930050a115bc2b78394f705df060e1b79004bb71
    --sha256: sha256-X+gkGY+Kdhx4gLv7MiFDOy9md1MX442QcR3gAGzajrM=
source-repository-package
    type: git
    location: https://github.com/sambnt/servant-jsaddle.git
    tag: 31bf67d913257c42924a4c9fdc6e02bd36cb0489
    --sha256: sha256-rMvTwEG9wSnl9A8nNUWd3F3zXboaA3Z/wVBnwfpWBxg=

Although weirdly enough putStrLn still doesn't work, requiring me to use trace instead even to debug MonadIO code.

Given the above I think we should definitely try to get this PR merged and uploaded to hackage. To get it more merge-ready I think it might be worth making the cabal file more consistent with servant-client-core, such as bumping the version to 0.20 and giving upper version bounds to dependencies / possibly moving up the lower bounds too.

@sevanspowell
Copy link
Contributor Author

sevanspowell commented May 9, 2024

Hey @tysonzero,

I'm glad you were able to get the example working, turns out I needed ghcjs-dom-javascript too, I just didn't notice because of some browser caching (I suspect), which I will be on the lookout for from now on!

I absolutely want to help getting everything together. My only issue is that I'm so used to using haskell.nix I don't have much experience with using any other dependency manager, but I'll do my best. What is your preferred path? Nixpkgs + cabal, just cabal, stack?

  • I have a PR for the working miso examples: Update examples to use new JS backend syntax dmjio/miso#740.
  • I have a branch with working miso examples using haskell.nix: https://github.com/sambnt/miso/tree/hix-working-examples
    git clone -b hix-working-examples [email protected]:sambnt/miso.git
    cd miso
    nix develop
    javascript-unknown-ghcjs-cabal build miso-examples:exe:canvas2d
    python3 -m http.server --dir ./dist-newstyle/build/javascript-ghcjs/ghc-9.8.2/miso-examples-1.8.3.0/x/canvas2d/build/canvas2d/canvas2d.jsexe
    
  • On putStrLn, how are you executing your example? I'm serving the example locally via python3 -m http.server --dir ..., and in that case putStrLn works. The binary produced hasn't been working at all and I haven't investigated why yet. putStrLn works for me here.

The miso tag has been bumped without including my PR to fix the miso examples. It is a bit of a chicken-egg problem, where my PR won't be accepted until they update their nix scripts, which required a version bump (inferred from dmjio/miso#738 (comment)).

@sevanspowell
Copy link
Contributor Author

@phadej What can I do to get this PR merged? In particular w.r.t. the cabal file.

@phadej
Copy link
Contributor

phadej commented May 9, 2024

I'm not maintaining servant packages. Ping appropriate maintainers

@tysonzero
Copy link

@sevanspowell

haskell.nix is totally fine and what I'm using locally (although I'm not using flakes), the only issue I personally have with that hix-working-examples branch is that it doesn't work on x86_64-darwin!

I'm serving my example via a servant web server that provides a simple html template and a script tag that calls into it via serveDirectoryWebApp. Weirdly enough in certain situations the putStrLn would go through, but just on a couple second delay compared to trace, and most of the time it doesn't appear at all.

I could be wrong but i'm under the impression that @dmjio would be open to merging dmjio/miso#740 if we can just demonstrate that it works, even if the PR for upgrading to miso's core nix infra to the new stuff is probably a little way outs (binary size and potentially other regressions), assuming of course it doesn't break with the existing infrastructure (which it seems like it doesn't).

@sevanspowell
Copy link
Contributor Author

@jkarni @arianvp @fisx

Sorry, I'm not sure who the right person to reach out to here is.

Copy link
Member

@fisx fisx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested this, and I'm really not maintaining this package any more either :), but it looks fine to me. I'm happy to merge this if you add new upper version bounds.

Thanks for contributing!

- Moved upper version bounds to latest version tested.
- Left lower bounds as-is, as changes should be compatible with existing tested
  versions.
@sevanspowell
Copy link
Contributor Author

Thanks so much @fisx.

I've re-instated the version upper bounds and moved them to the latest versions I tested.

I also bumped the version of the package, although in hindsight that might not be necessary, as the API hasn't changed.

I'd be happy to put my hand up to maintain the package, my only hesitation is that the package was never released on hackage and hasn't been maintained for a while. Was there a reason for that?

If it's just because it wasn't being used, no problem. But if it's something more sinister, then let me know.

Would you mind floating the idea to the haskell-servant maintainers? ❤️

@fisx fisx merged commit 6ce40e9 into haskell-servant:master May 13, 2024
@fisx
Copy link
Member

fisx commented May 13, 2024

i'm still officially a servant* maintainer, and i'm using servant professionally, i'm just not very active in my duties as maintainer.

i'm not using ghcjs in particular, though.

as for the question of maintainership: great that you want to step up. it would be nice to meet in person. you don't happen to be at zurihac this year by any chance?

@sevanspowell
Copy link
Contributor Author

I won't be at Zurihac this year :'( I live in Australia so it's a little bit too expensive for me at the moment.

At this stage it looks like I will continue using servant-jsaddle, as it seems to be the best choice for interacting with Servant APIs with the Javascript backend. I will contribute any changes I make as I go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants