An open API service indexing awesome lists of open source software.

https://github.com/envoy-vc/aos-playground

Web Interface for "ao" Permaweb Computer Grid 🐰 🕳️ 👈
https://github.com/envoy-vc/aos-playground

aos arweave editor lua monaco-editor terminal wasm

Last synced: about 2 months ago
JSON representation

Web Interface for "ao" Permaweb Computer Grid 🐰 🕳️ 👈

Awesome Lists containing this project

README

        




AOS Playground Logo

Welcome to the AOS Web Playground! Web Interface for 'ao' Permaweb Computer Grid 🐰 🕳️ 👈


Features
How it works?
Tech Stack
Try Now ↗️

AOS Playground Image

## Features

- 🌐 **Decentralized**: AOS Playground is hosted on the Permaweb network.
- ✨ **Multi-modal Support**: Multi-modal editor with a native file explorer built in.
- 📦 **Resolved Imports**: Import from other files in the explorer using `pcall`.
- 🗣️ **Language Formatting**: Language formatting for Lua files using wasm module.
- 🐞 **Debugging**: Supports debugging using the Lua AST Parser.
- 💾 **Persistence**: Entire application is persisted using LocalStorage and IndexedDB.
- 🎨 **Themes**: Supports Multiple themes such as `Andromeda`, `Poimandres`, `Github Light/Dark`, `Slack Ochin`, and more

## How it works?

AOS Playground is a web interface for the AO Operating System. It is hosted on the Permaweb network and uses the `@permaweb/aoconnect` SDK to interact with the network.

The main part of the application using `monaco-editor` by Microsoft. The editor is configured to support Lua language.

Language formatting is done using a custom compiled wasm module which runs in workers. (`⌘ + S` to test it)

The core feature of the editor is module resolve and import. Let's take an example to see how it works

```lua
-- src/file1.lua

file1 = {
message = "Message from File 1"
}
```

```lua
-- index.lua

local ok = pcall(require,".src.file1")

return file1.message
```

What happens when you run `index.lua` file?

First a Abstract Syntax Trr will be generated for the Lua file.

Abstract Syntax Tree for index.lua

```json
{
"type": "Chunk",
"body": [
{
"type": "LocalStatement",
"variables": [
{
"type": "Identifier",
"name": "ok"
}
],
"init": [
{
"type": "CallExpression",
"base": {
"type": "Identifier",
"name": "pcall"
},
"arguments": [
{
"type": "Identifier",
"name": "require"
},
{
"type": "StringLiteral",
"value": null,
"raw": "\".src.file1\""
}
]
}
]
},
{
"type": "ReturnStatement",
"arguments": [
{
"type": "MemberExpression",
"indexer": ".",
"identifier": {
"type": "Identifier",
"name": "message"
},
"base": {
"type": "Identifier",
"name": "file1"
}
}
]
}
],
"comments": [
{
"type": "Comment",
"value": " index.lua",
"raw": "-- index.lua"
}
]
}
```

Then the content is traversed for any pcall statements. If a pcall statement is found, the value of the CallExpression is resolved in the local file explorer.

If the file is found then it recursively checks that file for other imports until there are no more imports.

Then the order of execution is determined and the files are executed in that order.

> **Why pcall instead of require?**
>
> The reason for using pcall is to catch any errors that might occur during the execution of the file. If an error occurs, the error is caught and the error message is returned instead of the throwing the actual error.

## Tech Stack

- **Frontend**: `React`, `TypeScript`, `TailwindCSS`, `@shadcn/ui`
- **Editor**: `Monaco Editor`, `skiki` (Syntax highlighting)
- **Persistence**: `Dexie` and `LocalStorage`
- **Querying**: `React Query`
- **AO Operations**: `@permaweb/aoconnect`
- **Language Formatting**: Custom compiled `wasm` module
- **Debugging**: `Lua AST Parser`

## License

MIT