#spritely #hoot in a toot: how to deploy #Guile #Scheme as static website via #webassembly (complete #Wisp example).
The code from the two attached images, as written, runs on
https://www.draketo.de/software/hoot.html
Try it out!
It’s two pages from Naming & Logic: Programming Essentials with Wisp.
printed: https://www.epubli.com/shop/naming-and-logic-programming-essentials-with-wisp-9783565093199
website: https://www.draketo.de/software/programming-basics-wisp
This adds parallel fetches (do you see where?). If you adopt it, ensure that your server compresses application/wasm.
Load your interface (includes startup time optimizations):
#+begin_src js :tangle hoot.js
/* file: hoot.js */
var f = window.fetch; window.fetch = (inp, ini) => f(inp,
{credentials: 'include', mode: 'no-cors', ...ini});
window.addEventListener("load", () =>
fetch("hoot.wasm")
.then(r => r.arrayBuffer())
.then(bytes => Scheme.load_main(bytes, {
user_imports: { // mapped via define-foreign
document: {
body() { return document.body; },
createTextNode: Document.prototype
.createTextNode.bind(document)
},
element: {
appendChild(parent, child) {
return parent.appendChild(child);}}}})));
#+end_src
Include =reflect.js= and =hoot.js= from a HTML page:
#+begin_src html :tangle hoot.html
<!DOCTYPE html> <!-- file: hoot.html -->
<html><head><title>Hello Hoot</title>
<script type="text/javascript" src="reflect.js"></script>
<script type="text/javascript" src="hoot.js"></script>
<link rel="preload" as="fetch" href="hoot.wasm"></link>
<link rel="preload" as="fetch" href="wtf8.wasm"></link>
<link rel="preload" as="fetch" href="reflect.wasm"></link>
</head><body><h1>Hoot Test</h1></body></html>
#+end_src
For local testing, hoot provides a minimal webserver:
#+begin_src bash
guix shell guile-hoot guile-next -- \
guile -c '((@ (hoot web-server) serve))'
#+end_src
*Browser again: clientside wasm.* @@html:<a id="deploy-hoot-wasm" name="deploy-hoot-wasm"></a>@@
To run clientside, you can package your project with [[https://spritely.institute/hoot/][Hoot]]: build an interface and compile to wasm:
#+begin_src wisp :results output :tangle hoot.w
;; file: hoot.w
use-modules : hoot ffi ;; guile specific import
;; the interface
define-foreign document-body "document" "body"
. -> (ref null extern)
define-foreign make-text-node "document" "createTextNode"
. (ref string) -> (ref null extern)
define-foreign append-child! "element" "appendChild"
. (ref null extern) (ref null extern)
. -> (ref null extern)
;; your code
append-child! : document-body
make-text-node "Hello, world!"
#+end_src
Transpile with =wisp2lisp= and =guild compile-wasm=. If you run Guix:
#+begin_src bash
guix shell guile guile-wisp -- \
wisp2lisp hoot.w > hoot.scm && \
guix shell guile-hoot guile-next -- \
guild compile-wasm -o hoot.wasm hoot.scm
#+end_src
Get reflection tools from Guile Hoot (licensed Apache 2.0) with Guix:
#+latex: \ThisLLCornerWallPaper{0.26}{programming-scheme-hoot}%
#+begin_src bash
guix shell guile-hoot guile-next -- bash -c \
'cp $GUIX_ENVIRONMENT/share/*hoot/*/re*/{*.js,*.wasm} ./'
#+end_src