LimeJuice

LimeJuice
Login

An ambitious experiment in server-side Swift calling into WASM blobs to handle requests, with a hopeful mix of Pocketbase/Firebase/BaaS thrown in too. Uses JavaScriptCore as the WASM runtime.

The goals: - includes an Admin panel for managing WASM blobs/hooks and eventually "collections" - an API for routing requests to WASM blobs - an API that auto-generates CRUD operations for "collections" - serves up any static content in the public/ directory - stores data in a Sqlite DB that is configured to be compatible with LiteStream and friends - includes authentication and authorization tooling, configurable through the admin panel

Project Tour

Server Routes


Docs

Bare (hah, cause these are barely docs :D) with me here, I'm still fleshing out thoughts and how all of this should work, so these "docs" might not 100% reflect the current system and are by no means the canonical reference yet.

Folder Structure

LimeJuice places all of its data in the current working directories LimeJuice_data/ directory. This makes deployments super easy: just copy up the whole directory to whatever host. This directory has the following structure:

Collections

Collections, like in PocketBase, are SQlite tables which are entirely configurable through the Admin UI. An entry within a Collection is referred to as a Record. Records tend to be the primary unit of interaction for external systems with LimeJuice.

A Note on Schema Migrations

AKA: Why are they JavaScript and not also WASM?

While it'd be fun to have schema migrations for collections to be exposed to WASM-land, they ultimately have a need to be generated by LimeJuice, as a result of changes through the Admin UI so either LimeJuice would need to have a way to generate WASM for new schema migrations or we'll need another system that is friendly to both manual creation and automatic management/generation. Luckily, we're already running our WASM within a JavaScript engine already so we can just leverage that as it's easy enough to template out JavaSript.

Why not SQL scripts like <unique name>.(up/down).sql? We could do this, but the amount of friction introduced for manually created migrations is a bit too much. Part of the problem is that we need to keep both the collections backing table AND LimeJuice's internal collections metadata table in sync. By using a JavaScript migration system, we can ensure that this happens automatically by exposing a higher level API for changing a collections structure.

Why not JSON/YAML/TOML files representing a set of changes to apply in configuration? Wellllll ... We could do this too but no. While it could solve the problem that SQL scripts have with ensuring the two tables are in sync, it'd provide a less than stellar debugging experience that I'd rather avoid. Honestly JavaScript actually feels like a better fit here.

Authentication

Authorization / Permissions

Hooks

TL;DR Hooks are a way to tie into the LimeJuice runtime and extend it all from any language that can run within WASM. This lets you modify Records, requests, etc and to do things like: - Build a GraphQL endpoint - Validate or modify a Record before it's saved to the database - Implement Webhook or custom HTML Form post handling - Build out a server-rendered frontend - Even revamp the whole permission or authorization system

Hooks are the root of LimeJuice's existence and it's distinguishing feature. While not unique, PocketBase has Go hooks and is currently working on 0.17.0 which has JavaScript hooks, LimeJuice takes a different approach and uses WASM.