Ergohack V


Develop a UI for creating 1010s art pieces. 1010s pieces take in text and two-way encode them to an image. This UI will enable the community to build their own to explore, share, and mint if they so choose.



I was able to complete the UI, it can be found here.

Code is here.

I did not make it to any of the bonus items.

Requirements & Details

All of the 1010s code is in Ruby. My website is static site served by sourcehut. I wanted to build UI for the browser. This left two options of porting code to JS or hosting a server. I don't want to maintain a server. This meant I needed to somehow port code from Ruby->JS.

Work had already been done to port Ruby to WASM/WASI. I utilized ruby.wasm and targeted WASI.

Once I had my WASI application I needed to load it in JS. To run WASI in the browser is a bit tricky. It requires something called a polyfill, or implementing the necessary functions of the WASI interface and importing them into a wasm module.

From the source, a better explanation:

"We have a polyfill which implements WASI and runs in browsers. At the WebAssembly level, WASI is just a set of callable functions that can be imported by a .wasm module, and these imports can be implemented in a variety of ways, including by a JavaScript polyfill library running within browsers."

JS, JS runtimes, targets, etc are not something I'm familiar with so figuring out what JS builder to use and how to configure it to play nicely with WASM/WASI took some time. I found a working example, using esbuild, and copied it from trealla.js .

Unfortunately this esbuild configuration did not work with React. And so I created another npm app with esbuild and react to build the UI.

I had 3 compilation steps to build the final UI:

Due to Ruby's dynamic nature I could not export any functions to be called by JS through WASM/WASI. The WASM/WASI interface on browsers is extremely limited, at least it takes a lot more work to accept input from the user; such as utilizing Web Workers. I wanted to keep it as simple as possible. So take in input via "command line arguments" and run once.

This influenced the UI/UX:

Work speed up once I could run the WASM/WASI module in the React App. Due to limitations on time, I hardcoded some parameters of the 1010s encoder, it also made it simpler for the User. I decided to keep the Internal Representation Size since it dramatically changes how 1010s can look, thus empowering the User.

Future Work

Dark Lord of Programming