Skip to content

Commit d98db8f

Browse files
amesgenTerrorJack
andcommitted
Initial commit
Initial commit of ghc-wasm-reflex-examples forked from ghc-wasm-miso-examples. Co-authored-by: Cheng Shao <[email protected]>
0 parents  commit d98db8f

File tree

16 files changed

+790
-0
lines changed

16 files changed

+790
-0
lines changed

.github/workflows/build.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: build
2+
3+
on:
4+
merge_group:
5+
pull_request:
6+
push:
7+
branches:
8+
- main
9+
workflow_dispatch:
10+
11+
jobs:
12+
nix-build:
13+
name: nix-build
14+
runs-on: ubuntu-latest
15+
steps:
16+
17+
- name: checkout
18+
uses: actions/checkout@v4
19+
20+
- name: install-nix
21+
uses: DeterminateSystems/nix-installer-action@v15
22+
23+
- name: build-frontend
24+
run: |
25+
nix develop --command bash -c "cd frontend && wasm32-wasi-cabal update && exec ./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz"
26+
27+
ghcup-build:
28+
name: ghcup-build
29+
runs-on: ubuntu-latest
30+
steps:
31+
32+
- name: install-happy
33+
run: |
34+
cabal path --installdir >> "$GITHUB_PATH"
35+
cabal update -z
36+
cabal install -z happy
37+
38+
- name: checkout
39+
uses: actions/checkout@v4
40+
41+
- name: ghc-wasm-meta
42+
run: |
43+
pushd "$(mktemp -d)"
44+
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
45+
SKIP_GHC=1 ./setup.sh
46+
~/.ghc-wasm/add_to_github_path.sh
47+
popd
48+
49+
- name: cabal
50+
run: |
51+
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-prereleases-0.0.8.yaml
52+
ghcup install cabal --set 3.15.0.0.2024.10.3
53+
54+
- name: wasm32-wasi-ghc
55+
run: |
56+
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/develop/ghcup-cross-0.0.8.yaml
57+
ghcup install ghc --set wasm32-wasi-9.10.1.20241021 -- $CONFIGURE_ARGS
58+
59+
- name: build-frontend
60+
run: |
61+
cd frontend
62+
cabal \
63+
--with-compiler=wasm32-wasi-ghc \
64+
--with-hc-pkg=wasm32-wasi-ghc-pkg \
65+
--with-hsc2hs=wasm32-wasi-hsc2hs \
66+
update
67+
./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz
68+
69+
non-nix-build:
70+
name: non-nix-build
71+
runs-on: ubuntu-latest
72+
permissions:
73+
pages: write
74+
id-token: write
75+
steps:
76+
77+
- name: install-happy
78+
run: |
79+
cabal path --installdir >> "$GITHUB_PATH"
80+
cabal update -z
81+
cabal install -z happy
82+
83+
- name: checkout
84+
uses: actions/checkout@v4
85+
86+
- name: ghc-wasm-meta
87+
run: |
88+
pushd "$(mktemp -d)"
89+
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
90+
./setup.sh
91+
~/.ghc-wasm/add_to_github_path.sh
92+
popd
93+
env:
94+
FLAVOUR: '9.10'
95+
96+
- name: build-frontend
97+
run: |
98+
cd frontend
99+
./build.sh --debuginfo --low-memory-unused --converge --gufa --flatten --rereloop -Oz
100+
101+
- name: upload-pages-artifact
102+
uses: actions/upload-pages-artifact@v3
103+
with:
104+
path: frontend/dist
105+
retention-days: 90
106+
107+
- name: deploy-pages
108+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist-newstyle/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) Tweag I/O Limited.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# `ghc-wasm-reflex-examples`
2+
3+
[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/#haskell-wasm:matrix.terrorjack.com)
4+
5+
The GHC wasm backend supports the
6+
[JSFFI](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/wasm.html#javascript-ffi-in-the-wasm-backend)
7+
feature, allowing Haskell wasm apps to interop with JavaScript
8+
seamlessly in the browser. This repo contains an example to
9+
demonstrate this ability based on the
10+
[`reflex`](https://reflex-frp.org/) frontend framework as well as an
11+
experimental [`jsaddle-wasm`](https://github.com/amesgen/jsaddle-wasm)
12+
library under the hood.
13+
14+
See also:
15+
[`ghc-wasm-miso-examples`](https://github.com/tweag/ghc-wasm-miso-examples)
16+
17+
## Live demo
18+
19+
- [reflex-todomvc](https://tweag.github.io/ghc-wasm-reflex-examples/reflex-todomvc.html)
20+
21+
## Building
22+
23+
### With nix
24+
25+
Within the `nix develop` shell:
26+
27+
```sh
28+
cd frontend
29+
wasm32-wasi-cabal update
30+
./build.sh
31+
```
32+
33+
If you pass additional arguments to `build.sh`, they will be
34+
redirected to `wasm-opt`, otherwise a dev build without `wasm-opt`
35+
will be performed.
36+
37+
The artifacts will be available in `frontend/dist`.
38+
39+
### Without nix
40+
41+
You can set up the toolchain by either:
42+
43+
- Using
44+
[`ghc-wasm-meta`](https://gitlab.haskell.org/ghc/ghc-wasm-meta#getting-started-without-nix)
45+
directly to set up ghc 9.10
46+
- Using [`ghcup`](https://www.haskell.org/ghcup/guide/#cross-support)
47+
to set up ghc 9.10 (9.10.1.20241021 or later, with TemplateHaskell
48+
support) and cabal >=3.14.
49+
50+
Then:
51+
52+
```sh
53+
source ~/.ghc-wasm/env
54+
cd frontend
55+
./build.sh
56+
```
57+
58+
## Acknowledgements
59+
60+
The examples are vendored and modified from the following projects:
61+
62+
- reflex-todomvc: based on https://github.com/reflex-frp/reflex-todomvc

app/App.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module App (start) where
2+
3+
import GHC.Wasm.Prim
4+
import Language.Javascript.JSaddle (JSM)
5+
import Reflex.TodoMVC qualified
6+
7+
start :: JSString -> JSM ()
8+
start e =
9+
case fromJSString e of
10+
"reflex-todomvc" -> Reflex.TodoMVC.main
11+
_ -> fail "unknown example"

app/Main.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module MyMain (main) where
2+
3+
import App (start)
4+
import GHC.Wasm.Prim
5+
import Language.Javascript.JSaddle.Wasm qualified as JSaddle.Wasm
6+
7+
foreign export javascript "hs_start" main :: JSString -> IO ()
8+
9+
main :: JSString -> IO ()
10+
main e = JSaddle.Wasm.run $ start e

cabal.project

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
packages: . reflex-todomvc
2+
3+
index-state: 2024-11-11T12:54:21Z
4+
5+
if arch(wasm32)
6+
-- Required for TemplateHaskell. When using wasm32-wasi-cabal from
7+
-- ghc-wasm-meta, this is superseded by the global cabal.config.
8+
shared: True
9+
10+
-- https://github.com/haskellari/time-compat/issues/37
11+
-- Older versions of time don't build on WASM.
12+
constraints: time installed
13+
allow-newer: time
14+
15+
-- https://github.com/haskellari/splitmix/pull/73
16+
source-repository-package
17+
type: git
18+
location: https://github.com/amesgen/splitmix
19+
tag: 5f5b766d97dc735ac228215d240a3bb90bc2ff75
20+
21+
package aeson
22+
flags: -ordered-keymap
23+
24+
-- for reflex-frp
25+
26+
-- GHC 9.10 compat
27+
source-repository-package
28+
type: git
29+
location: https://github.com/amesgen/reflex-dom
30+
tag: e43e0525d643f656a0a5b0f10e13e2a04712cd4e
31+
subdir: reflex-dom-core
32+
33+
allow-newer: dependent-sum-template:template-haskell

flake.lock

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
inputs = {
3+
ghc-wasm-meta.url = "gitlab:ghc/ghc-wasm-meta?host=gitlab.haskell.org";
4+
};
5+
outputs = inputs: inputs.ghc-wasm-meta.inputs.flake-utils.lib.eachDefaultSystem (system:
6+
let pkgs = inputs.ghc-wasm-meta.inputs.nixpkgs.legacyPackages.${system};
7+
in
8+
{
9+
devShells.default = pkgs.mkShell {
10+
packages = [
11+
inputs.ghc-wasm-meta.packages.${system}.all_9_10
12+
];
13+
};
14+
});
15+
}

frontend/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
dist/
3+
ghc_wasm_jsffi.js

0 commit comments

Comments
 (0)