I’ve added a hobby project to my GitHub profile that has been given the title “Apps” as it is a progressive web app that aims to adhere to the App Shell model. The primary routes are prerendered as static HTML during the build process and are loaded lazily at runtime to ensure a smaller client-side JavaScript bundle. The source code is hosted on GitHub and comprises several components that operate within the Angular framework. Check it out at: https://kherrick.github.io/apps/
I’ve talked about an experiment with Blazor in the past, but wanted to see how it would go building something small in C# for the browser without going through that process. With .NET 7 it doesn’t seem too hard, so I went ahead and created an example repo to demonstrate.
I am relying on “JSExport” to expose C# to the JavaScript application and have decided to make things simple by using strings for the arguments and return values as well as forgetting about how inefficient this is (for what this is actually doing).
using System.Globalization;
using System.Runtime.InteropServices.JavaScript;
public partial class Calculator
{
// ...
[JSExport]
internal static string add(string first, string second)
{
Decimal firstNumber = Decimal.Parse(first, NumberStyles.Float);
Decimal secondNumber = Decimal.Parse(second, NumberStyles.Float);
return (firstNumber + secondNumber).ToString();
}
// ...
}
Using something like DotNetJS seems more appropriate for use cases like this in the short-term, and I wonder where WASI and Wasmtime .NET solutions will wind up going forward?
When using the terminal on my Mac, I often use the open command to get a view of the current directory in Finder and generally use it to… open up things. So, while using other operating systems, I have naturally wanted similar functionality. To my recent surprise, I found it within Haiku, and it turns out it’s coming to Debian as well!
HTML, JavaScript, and CSS are key parts of the Open Web Platform as they assist in creating customized, yet reusable solutions that anyone might need to build high quality, robust web applications—without requiring unnecessary complexity.
In this small example, a few support libraries work together to provide efficient templating, as well as an implementation of React’s Hooks API, allowing us to use state of the art features, while still preserving compatibility with the wider ecosystem on the Web.
And the element rendered (with a default value included even), we can define new and interesting behavior without much trouble at all.
<x-hook-component value="5"></x-hook-component>
Being that custom elements and dynamic import are so widely supported now—adding functionality and content in this way is starting to make a lot more sense for many use cases—especially seeing how once loaded and cached, the cost to reload any support libraries seems barely noticeable. Try this example on CodeSandbox.
It seemed like a neat idea to encapsulate syntax highlighting responsibilities for the various code snippets that I share at times, so I went ahead and wrote a custom element to help me take care of the job. To try it out, install x-postpress-code with your favorite package manager and import into your project. If you like going buildless [1, 2], load it from a CDN like unpkg or skypack:
Once registered, the web component requires a type attribute to identify which supported language should be highlighted. The content of the code itself can either be lazy loaded using the src attribute, or by including the source in the default slot surrounded by pre tags:
<x-postpress-code type="bash"><pre>
#/usr/bin/env bash
for file in *; do
echo $file
done
</pre></x-postpress-code>
One nice side effect of defining the code this way, is that if JavaScript is disabled for whatever reason, the original is still rendered (although unhighlighted). Try it out at JS Bin, or checkout the project page for more information.
I thought it was a good time to revisit trying to control an RC car’s handheld remote, so I returned to the community assistance I first started at and gave it a try. In the end, I just had to wire up some transistors to the remote control as well as a few resistors leading back to the GPIO pins on the Pi.
The software side is fairly straightforward as it implements basic driving functionality and requires only a few Node.js dependencies (the rpio library and an experimental one to handle keyup and keydown events). Running the main script from the github repo sets up four pins as outputs, and are triggered when the arrow keys are pressed. Ctrl+C can be used to exit.
Controlling the car directly would be more efficient, but as far as a proof of concept, doing it indirectly through the remote control works really well. Adding the Camera Module would be a good next step, but even at this point the process has got me thinking that a Pi Zero would be a nice addition to a platform like RC car that you can buy at the store — especially something like this Fast Traxx. Driving it with a keyboard over SSH is such a cool experience.
After experimenting with the AIY Vision kit and the Coral USB Accelerator I decided to try “edge computing” from another angle by wrapping up TensorFlow.js with LitElement to make a few Web Components for testing. The tfjs-backend-wasm package is loaded to use WebAssembly for the backend and while it seems similar to WebGL for lite models, it performs worse when using medium-sized ones. Fortunately, they’re commited to supporting the platform and will continue to improve it.
The models are setup with little modification to the configuration, so watching what’s detected and how things are classified before diving into the actual building and changing of them is interesting. Google’s AutoML project might be something to check out next. Each component has methods exposed so the user can provide images or video to inference—for example:
The last thing of note is that all image classification, object, and facial detection is completed client-side. It’s by design, more private by not sending the data to the server—kind of neat.
While there are many ways to generate strong passwords, I’ve been a fan of using pwgen for systems that I stand up. It’s usually been an “apt-get install” away, but there have been times while away from a Linux machine where I couldn’t access it like I normally would; right on the cli.
After coming across a Docker image that sets up most of the environment to compile a C/C++ project using Emscripten, it got me thinking that it might be easier than I thought to build a Wasm version of the original pwgen. It progressed something like this, “I can currently use it on the Linux command line—but with WebAssembly on Node.js and Wasmer, I could run it on Mac OS X, Windows, and really anywhere a runtime is—I think I can wrap this in a custom element.”
So, I gave it a shot, and I couldn’t be more pleased with how easy the results are to use and in how many environments it runs on. Does the system already have a recent setup of npm/npx installed? Start generating passwords with the command below (wapm is similar), or pass “‐‐help” for additional options to be printed.
npx pwgen
What about from the browser?
The PWA works offline, includes a minimal view for displaying passwords, some sliders to adjust the settings, and the x-pwgen Web Component that wraps up everything. At first I was a bit surprised that the JavaScript wrapper that Emscripten provides to load the module is larger than the Wasm itself, but it still loads fast. To use it in React, Angular or anywhere else HTML likes to hide out, declare the following:
Finally, I felt like this was a good opportunity to investigate Web Bundles [1 ,2] seeing how the hosted version is a just a set of static files. If you use Chrome 80 or higher and want to test it, set your browser’s chrome://flags/#web-bundles flag to enabled, download the pwgen.wbn file, and then drag and drop it onto a Chrome window.
I’ve been enjoying learning a little bit more about WebAssembly. The journey has been long and a bit sporadic as my first introduction to the concepts were with Emscripten shortly after the release of asm.js. Since then, the scope of the project seems to have widened and the landscape has grown — it’s more than the browser [1, 2, 3, 4].
With that said, here are a few projects that have caught my attention for use in that environment:
…wait, PHP in the browser. I’ve always wanted that.
So just for fun I decided to clone PIB, build with the latest versions, and wrap it up as Web Component called <x-php>. In my opinion, the most exciting part is defining the contents of the PHP script inside of an actual HTML script tag and passing it along inside of the default slot. The MIME type I chose for the type attribute is debatable, but it seems to work in the browsers I’ve tested it in.
Rendering x-weather along with some of Polymer’s App Layout custom elements makes it look a lot better and paves the way for additional features. Also, learning more about various ways to isolate component functionality and exposing desired behavior has been appreciated. Implementing some kind of location search seems like it would be a good next step.
State management has been particularly interesting to me, especially when various caching systems are involved, so there has been a bit of opportunity to gain additional understanding in this area as well. Even with all of the JavaScript used the initial Lighthouse and WebPageTest scores are promising: