Well!
It's been about two weeks since the last update. Birch development has been steadily progressing and even picking up in the last few days. I researched and thought a bunch about different design decisions (summarized below), but lately it's been coding, coding, and more coding! I guess that's how it goes :)
With the progression detailed below, Birch has evolved. It's gone from a project of 100% vision and 0% usefulness, to something that can actually be used to code in. You can write functions. The functions can access data. The data then updates in real time. It's starting to feel, dare I say, alive!
Birch is a platform where developers can author and interact with live functions and tables on a 2d canvas. These functions can be run by hand, by a POST request, or on a timer.
Birch aims to dramatically lower the bar for the amount of information and thought required to get code running in the cloud.
Birch functions can call each other and access tables! Tables are bound to Javascript objects with methods like map
, forEach
, and insert
.
These database-related functions are not async! Nearly every other database toolkit for Javascript requires adding await
before each call.
This probably makes sense in the context of a browser or webserver, but it's wholly unnecessary for a platform that runs only one function at a time.
As a result, Birch users don't have to learn async/await, they don't have to navigate a third type of card (Functions, Tables, and now Async Functions??), and they don't have to deal with the cognitive overhead of adding awaits everywhere!
Synchronous database from javascript is made possible by dynamically linking in some Rust glue to call rusqlite. I couldn't use existing javascript bindings for sqlite because they are all async!
Tables update live in the client when a function edits them serverside.
Tables are now paginated, whereas before they only ever displayed the first 10 entries π
The 2d canvas is now scrollable and expends as new functions or tables are made closer to its edge.
Errors are not yet communicated in the UI at all β parse errors, runtime errors, you name it! This is a major issue standing in the way of Birch being really usable.
A function's return value is not communicated either. I don't really know where to display it. Should it pop up below the function in question? And then fade out after some time? Should return values all be accumulated in a sidebar? I want something that will feel natural to users; maybe it's time to get some users!
I'm realizing that it would be nice to document a table's methods (as well as other potential capabilities I might add in the future like fetch
). Perhaps there's a way to build this into the Birch editor environment...
Instead of using Deno's FFI to link in Rust, I briefly considered compiling Javascript down to Webassembly so I could use synchronous database primitives. Also I trust Webassembly's sandboxing more than Deno's. But the compiler I found β Javy by Shopify β didn't have nice error messages and introduced too much latency between writing code and running it.
I saw Shopify pop up again while investigating the possibility of adding Ruby to Birch. They have a sandbox for MRuby called MRubyEngine. Both Javy and MRubyEngine were written for Shopify's user-facing scripting environment. It's nice to see other people go down the same path of trying to sandbox scripting languages in user space π
"Why not use an existing Functions-as-a-Service solution as the backend of Birch?" I looked into it. It seems like most FaaS providers can take a few minutes to deploy a newly edited function. This is way too long for users to feel like they are directly editing their production environment!
Deno Deploy β a FaaS platform offered by the same people who wrote Deno β seemed like a good option at first since it only takes a few seconds to deploy a new function. (Still orders of magnitude higher than I'd like, but could be a good starting place.) Turns out they also limit all functions to a 100ms execution time! Not a constraint I want to pass on to Birch.
On the UI side of things, I have card actions behind a right-click context menu at the moment:
While it's nice that right-click context menus are well-known pattern, I'm worried people won't expect Birch to support them, as most webapps don't. I'd have to add some kind of pop-up saying, "Try right-clicking!"
So instead I've been exploring a mode of interaction where these options are discoverable through hovering. On mouseover they would appear as icons to the right of a card:
Hovering over each option would then surface a description of what the icon does:
This is perhaps more visually distracting than hiding them behind a context menu, but it could be a win for discoverability.
I'm curious what people think! Do you strongly support context menus? Have a better idea? Let me know.
On a more general note, it's no longer feeling like "Step 1: Get the functions to run". I'm beginning to see a whole slew of largely independent prerequisites to launching.
Speaking of, I intend to get some sort of pre-alpha preview up soon. Maybe in time for the next post!
There you have it! Thanks for reading and hope you have a great day :)
Charles
P.S. Feel free to reach out on twitter @charlesetc or email at [email protected]!