-
Notifications
You must be signed in to change notification settings - Fork 177
Description
Golem only has two methods of interaction:
- The REST API
- The Command-Line Interface (
golem-cli)
Both of these are useful for programmatic purposes, while the CLI is designed mostly for developers in mind. However, neither of these methods are discoverable or provide a high-level graphical user-interface with a wonderful developer experience. While Golem Cloud comes with Console, a high-level graphical user-interface, Console is deeply integrated into the Cloud offering and relies on APIs that don't even exist in OSS or make sense there.
In order to provide developers a new graphical way of interacting with Golem, we wish to sponsor a ticket that is primarily intended for TypeScript developers -- with a shout-out to developers familiar with Effect TS (though use of this library or any other is not required). The end result will be a GUI for Golem that ships with the single executable (even though you could use it elsewhere) and makes it easy for developers to do local development and testing.
In order to claim this bounty, you need two do two things:
- Build a TypeScript application that allows graphical management of Golem, supporting all the APIs that Golem supports. This requires knowledge of TypeScript, front-ends, cross-browser development, user-experience, user-interface design (including usability), and developer experience.
- Serve the application as part of the Single Executable build of Golem (which bundles everything together in a single executable). This may require a tiny amount of Rust knowledge, but you can probably get by with Google and Copilot.
In particular, the application must support:
- Component management. Developers can create, update, and delete components visually. All backend APIs should have a way to perform the function visually.
- Worker management. Developers can create, update, manage, and delete workers visually. All backend APIs should have a way to perform the function visually.
- API management. Developers can create, update, manage, and delete APIs visually. All backend APIs should have a way to perform the function visually.
- Plugin management. All backend APIs should have a way to perform the function visually (chiefly about installing / uninstalling plug-ins inside components and workers).
Although one can take inspiration from Console, this is not necessary, as Cloud is designed for use in a multi-tenant environment, which does not apply to Golem. However, the breadth of support for backend APIs, as well as the polish and attention to aesthetics, should be similar to Console. You are free to make your own decisions on design, user-interface, user-experience, etc. However, if you choose poorly, and your user-interface is ugly, difficult to use, inconsistent, incomplete, or buggy, then your PR won't be merged.
A winning pull-request will include screenshots of every major area of the user-interface and attach pre-compiled single-executable binaries for Linux / MacOS or both.
Getting Started
In order to test the functionality that you develop in the GUI, you must develop and deploy your own backend on Golem. In fact, this should be the FIRST thing you do in order to solve this ticket--because otherwise you will not understand how Golem works or what sort of experience is required in order to build and deploy for Golem.
The steps are as follows:
- Pick a programming language supported by Golem (basically, any language that can compile or be bundled to WASM Components); see https://learn.golem.cloud.
- Define a WIT interface for your component. I included a WIT interface for a simple TODO backend below.
- Implement code for your component, which satisfies the WIT-based interface. How you do this is language-specific and documented here, among other places.
- Deploy your component on Golem. You can use Golem single executable, Golem Cloud, or deploy Golem in the cloud.
- Build an API for your component. You should use one worker per user, and have APIs like the following:
Together with other APIs for user profile, getting uncompleted todos, etc.
GET /{user-id}/todos/ POST /{user-id}/todos/ GET /{user-id}/todos/{todo-id} PUT /{user-id}/todos/{todo-id} DELETE /{user-id}/todos/{todo-id} - Once you test this REST API, which will be served by the Worker Gateway, you are ready to proceed to implementing the solution.
After you implement the solution, you will be able to visually complete all of the above steps, as well as diagnose and debug issues related to development, update your component, and do all other functions supported by the Golem APIs.
package todo:personal@0.1.0;
interface types {
// Basic timestamp type (Unix timestamp in milliseconds)
type timestamp = u64;
// User profile information
record profile {
name: string,
email: string,
created-at: timestamp,
updated-at: timestamp,
}
// Input for updating profile
record update-profile-input {
name: option<string>,
email: option<string>,
}
// Represents a task
record task {
id: u64,
title: string,
description: string,
completed: bool,
due-date: option<timestamp>,
created-at: timestamp,
updated-at: timestamp,
}
// Input for creating a task
record create-task-input {
title: string,
description: string,
due-date: option<timestamp>,
}
// Input for updating a task
record update-task-input {
title: option<string>,
description: option<string>,
completed: option<bool>,
due-date: option<timestamp>,
}
// Error types
enum error {
not-found,
invalid-input,
internal-error,
}
}
// Profile management interface
interface profile {
use types.{error, profile, update-profile-input};
// Get the current user's profile
get: func() -> result<profile, error>;
// Update the current user's profile
update: func(input: update-profile-input) -> result<profile, error>;
}
// Task management interface
interface tasks {
use types.{error, task, create-task-input, update-task-input, timestamp};
// Create a new task
create: func(input: create-task-input) -> result<task, error>;
// Get a specific task by ID
get: func(id: u64) -> result<task, error>;
// Update an existing task
update: func(id: u64, input: update-task-input) -> result<task, error>;
// Delete a task
delete: func(id: u64) -> result<_, error>;
// List all tasks
list: func() -> result<list<task>, error>;
// List tasks due before a specific timestamp
list-due-before: func(before: timestamp) -> result<list<task>, error>;
// List all completed tasks
list-completed: func() -> result<list<task>, error>;
// List all incomplete tasks
list-incomplete: func() -> result<list<task>, error>;
}
// Main world definition
world todo-worker {
import types;
export profile;
export tasks;
}