Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Initial commit of ghc-wasm-reflex-examples forked from
ghc-wasm-miso-examples.

Co-authored-by: Cheng Shao <terrorjack@type.dance>
  • Loading branch information
amesgen and TerrorJack committed Nov 12, 2024
0 parents commit d98db8f
Show file tree
Hide file tree
Showing 16 changed files with 790 additions and 0 deletions.
108 changes: 108 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
name: build

on:
merge_group:
pull_request:
push:
branches:
- main
workflow_dispatch:

jobs:
nix-build:
name: nix-build
runs-on: ubuntu-latest
steps:

- name: checkout
uses: actions/checkout@v4

- name: install-nix
uses: DeterminateSystems/nix-installer-action@v15

- name: build-frontend
run: |
nix develop --command bash -c "cd frontend && wasm32-wasi-cabal update && exec ./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz"
ghcup-build:
name: ghcup-build
runs-on: ubuntu-latest
steps:

- name: install-happy
run: |
cabal path --installdir >> "$GITHUB_PATH"
cabal update -z
cabal install -z happy
- name: checkout
uses: actions/checkout@v4

- name: ghc-wasm-meta
run: |
pushd "$(mktemp -d)"
curl -f -L --retry 5 https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/archive/master/ghc-wasm-meta-master.tar.gz | tar xz --strip-components=1
SKIP_GHC=1 ./setup.sh
~/.ghc-wasm/add_to_github_path.sh
popd
- name: cabal
run: |
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-prereleases-0.0.8.yaml
ghcup install cabal --set 3.15.0.0.2024.10.3
- name: wasm32-wasi-ghc
run: |
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-cross-0.0.8.yaml
ghcup install ghc --set wasm32-wasi-9.10.1.20241021 -- $CONFIGURE_ARGS
- name: build-frontend
run: |
cd frontend
cabal \
--with-compiler=wasm32-wasi-ghc \
--with-hc-pkg=wasm32-wasi-ghc-pkg \
--with-hsc2hs=wasm32-wasi-hsc2hs \
update
./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz
non-nix-build:
name: non-nix-build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
steps:

- name: install-happy
run: |
cabal path --installdir >> "$GITHUB_PATH"
cabal update -z
cabal install -z happy
- name: checkout
uses: actions/checkout@v4

- name: ghc-wasm-meta
run: |
pushd "$(mktemp -d)"
curl -f -L --retry 5 https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/archive/master/ghc-wasm-meta-master.tar.gz | tar xz --strip-components=1
./setup.sh
~/.ghc-wasm/add_to_github_path.sh
popd
env:
FLAVOUR: '9.10'

- name: build-frontend
run: |
cd frontend
./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz
- name: upload-pages-artifact
uses: actions/upload-pages-artifact@v3
with:
path: frontend/dist
retention-days: 90

- name: deploy-pages
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist-newstyle/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) Tweag I/O Limited.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# `ghc-wasm-reflex-examples`

[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/#haskell-wasm:matrix.terrorjack.com)

The GHC wasm backend supports the
[JSFFI](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/wasm.html#javascript-ffi-in-the-wasm-backend)
feature, allowing Haskell wasm apps to interop with JavaScript
seamlessly in the browser. This repo contains an example to
demonstrate this ability based on the
[`reflex`](https://reflex-frp.org/) frontend framework as well as an
experimental [`jsaddle-wasm`](https://github.com/amesgen/jsaddle-wasm)
library under the hood.

See also:
[`ghc-wasm-miso-examples`](https://github.com/tweag/ghc-wasm-miso-examples)

## Live demo

- [reflex-todomvc](https://tweag.github.io/ghc-wasm-reflex-examples/reflex-todomvc.html)

## Building

### With nix

Within the `nix develop` shell:

```sh
cd frontend
wasm32-wasi-cabal update
./build.sh
```

If you pass additional arguments to `build.sh`, they will be
redirected to `wasm-opt`, otherwise a dev build without `wasm-opt`
will be performed.

The artifacts will be available in `frontend/dist`.

### Without nix

You can set up the toolchain by either:

- Using
[`ghc-wasm-meta`](https://gitlab.haskell.org/ghc/ghc-wasm-meta#getting-started-without-nix)
directly to set up ghc 9.10
- Using [`ghcup`](https://www.haskell.org/ghcup/guide/#cross-support)
to set up ghc 9.10 (9.10.1.20241021 or later, with TemplateHaskell
support) and cabal >=3.14.

Then:

```sh
source ~/.ghc-wasm/env
cd frontend
./build.sh
```

## Acknowledgements

The examples are vendored and modified from the following projects:

- reflex-todomvc: based on https://github.com/reflex-frp/reflex-todomvc
11 changes: 11 additions & 0 deletions app/App.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module App (start) where

import GHC.Wasm.Prim
import Language.Javascript.JSaddle (JSM)
import Reflex.TodoMVC qualified

start :: JSString -> JSM ()
start e =
case fromJSString e of
"reflex-todomvc" -> Reflex.TodoMVC.main
_ -> fail "unknown example"
10 changes: 10 additions & 0 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module MyMain (main) where

import App (start)
import GHC.Wasm.Prim
import Language.Javascript.JSaddle.Wasm qualified as JSaddle.Wasm

foreign export javascript "hs_start" main :: JSString -> IO ()

main :: JSString -> IO ()
main e = JSaddle.Wasm.run $ start e
33 changes: 33 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
packages: . reflex-todomvc

index-state: 2024-11-11T12:54:21Z

if arch(wasm32)
-- Required for TemplateHaskell. When using wasm32-wasi-cabal from
-- ghc-wasm-meta, this is superseded by the global cabal.config.
shared: True

-- https://github.com/haskellari/time-compat/issues/37
-- Older versions of time don't build on WASM.
constraints: time installed
allow-newer: time

-- https://github.com/haskellari/splitmix/pull/73
source-repository-package
type: git
location: https://github.com/amesgen/splitmix
tag: 5f5b766d97dc735ac228215d240a3bb90bc2ff75

package aeson
flags: -ordered-keymap

-- for reflex-frp

-- GHC 9.10 compat
source-repository-package
type: git
location: https://github.com/amesgen/reflex-dom
tag: e43e0525d643f656a0a5b0f10e13e2a04712cd4e
subdir: reflex-dom-core

allow-newer: dependent-sum-template:template-haskell
81 changes: 81 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
inputs = {
ghc-wasm-meta.url = "gitlab:ghc/ghc-wasm-meta?host=gitlab.haskell.org";
};
outputs = inputs: inputs.ghc-wasm-meta.inputs.flake-utils.lib.eachDefaultSystem (system:
let pkgs = inputs.ghc-wasm-meta.inputs.nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
packages = [
inputs.ghc-wasm-meta.packages.${system}.all_9_10
];
};
});
}
3 changes: 3 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
dist/
ghc_wasm_jsffi.js
Loading

0 comments on commit d98db8f

Please sign in to comment.