Skip to content

Commit

Permalink
Merge pull request #255 from kinode-dao/develop
Browse files Browse the repository at this point in the history
develop
  • Loading branch information
nick1udwig authored Nov 5, 2024
2 parents de0ab33 + 764d98b commit df5d865
Show file tree
Hide file tree
Showing 23 changed files with 222 additions and 189 deletions.
39 changes: 0 additions & 39 deletions code/mfa_fe_demo/ui/index.html

This file was deleted.

18 changes: 9 additions & 9 deletions src/apis/frontend_development.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ You **must** place your `index.html` in the top-level folder.
The structure should look like this:

```
my_package
my-package
└── pkg
└── ui (can have any name)
├── assets (can have any name)
Expand All @@ -37,8 +37,8 @@ serve_ui(&our, "ui", true, false, vec!["/"]).unwrap();
```

This will serve the `index.html` in the specified folder (here, `"ui"`) at the home path of your process.
If your process is called `my_process:my_package:template.os` and your Kinode is running locally on port 8080,
then the UI will be served at `http://localhost:8080/my_process:my_package:template.os`.
If your process is called `my-process:my-package:template.os` and your Kinode is running locally on port 8080,
then the UI will be served at `http://localhost:8080/my-process:my-package:template.os`.

`serve_ui` takes five arguments: our `&Address`, the name of the folder that contains your frontend, whether the UI requires authentication, whether the UI is local-only, and the path(s) on which to serve the UI (usually `["/"]`).

Expand All @@ -51,21 +51,21 @@ To make development easy, your setup should support a base URL and http proxying
### Base URL

All processes in Kinode OS are namespaced by process name in the standard format of `process:package:publisher`.
So if your process is called `my_process:my_package:template.os`, then your process can only bind HTTP paths that start with `/my_process:my_package:template.os`.
So if your process is called `my-process:my-package:template.os`, then your process can only bind HTTP paths that start with `/my-process:my-package:template.os`.
Your UI should be developed and compiled with the base URL set to the appropriate process path.

#### Vite

In `vite.config.ts` (or `.js`) set `base` to your full process name, i.e.
```
base: '/my_process:my_package:template.os'
base: '/my-process:my-package:template.os'
```

#### Create React App

In `package.json` set `homepage` to your full process name, i.e.
```
homepage: '/my_process:my_package:template.os'
homepage: '/my-process:my-package:template.os'
```

### Proxying HTTP Requests
Expand All @@ -87,10 +87,10 @@ proxy: 'http://localhost:8080'
### Making HTTP Requests

When making HTTP requests in your UI, make sure to prepend your base URL to the request.
For example, if your base URL is `/my_process:my_package:template.os`, then a `fetch` request to `/my-endpoint` would look like this:
For example, if your base URL is `/my-process:my-package:template.os`, then a `fetch` request to `/my-endpoint` would look like this:

```
fetch('/my_process:my_package:template.os/my-endpoint')
fetch('/my-process:my-package:template.os/my-endpoint')
```

## Local Development and "gotchas"
Expand All @@ -107,4 +107,4 @@ See your framework documentation for how to check if you are in dev or prod.
The `kit` template already handles this for you.

Developing against a remote node is simple, you just have to change the proxy target in `vite.config.ts` to the URL of your node.
By default the template will target `http://localhost:8080`.
By default the template will target `http://localhost:8080`.
4 changes: 2 additions & 2 deletions src/apis/http_authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ This process handles binding (registering) routes, simple JWT-based authenticati

Any process that you build can bind (register) any number of HTTP paths with `http_server`.
Every path that you bind will be automatically prepended with the current process' ID.
For example, bind the route `/messages` within a process called `main:my_package:myname.os` like so:
For example, bind the route `/messages` within a process called `main:my-package:myname.os` like so:

```rs
use kinode_process_lib::{http::bind_http_path};

bind_http_path("/messages", true, false).unwrap();
```

Now, any HTTP requests to your node at `/main:my_package:myname.os/messages` will be routed to your process.
Now, any HTTP requests to your node at `/main:my-package:myname.os/messages` will be routed to your process.

The other two parameters to `bind_http_path` are `authenticated: bool` and `local_only: bool`.
`authenticated` means that `http_server` will check for an auth cookie (set at login/registration), and `local_only` means that `http_server` will only allow requests that come from `localhost`.
Expand Down
4 changes: 2 additions & 2 deletions src/apis/websocket.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The simplest way to connect from a browser is to use the `@kinode/client-api` li
```rs
const api = new KinodeEncryptorApi({
nodeId: window.our.node, // this is set if the /our.js script is present in index.html
processId: "my_package:my_package:template.os",
processId: "my-package:my-package:template.os",
onOpen: (_event, api) => {
console.log('Connected to Kinode')
// Send a message to the node via WebSocket
Expand Down Expand Up @@ -41,7 +41,7 @@ const websocket = new WebSocket("http://localhost:8080/");
const message = JSON.stringify({
"auth_token": getCookie(`kinode-auth_${nodeId}`),
"target_process": "my_package:my_package:template.os",
"target_process": "my-package:my-package:template.os",
"encrypted": false,
});
Expand Down
26 changes: 13 additions & 13 deletions src/chess_app/chess_engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Chess is a good example for a Kinode application walk-through because:
2. It's a multiplayer game, showing Kinode's p2p communications and ability to serve frontends
3. It's fun!

In `my_chess/Cargo.toml`, which should be in the `my_chess/` process directory inside the `my_chess/` package directory, add `pleco = "0.5"` to your dependencies.
In your `my_chess/src/lib.rs`, replace the existing code with:
In `my-chess/Cargo.toml`, which should be in the `my-chess/` process directory inside the `my-chess/` package directory, add `pleco = "0.5"` to your dependencies.
In your `my-chess/src/lib.rs`, replace the existing code with:

```rust
use pleco::Board;
Expand All @@ -23,9 +23,9 @@ call_init!(init);
fn init(our: Address) {
println!("started");

let my_chess_board = Board::start_pos().fen();
let my-chess_board = Board::start_pos().fen();

println!("my_chess_board: {my_chess_board}");
println!("my-chess_board: {my-chess_board}");

loop {
// Call await_message() to receive any incoming messages.
Expand All @@ -50,12 +50,12 @@ To make your app multiplayer, start by creating a persisted state for the chess

The first step to creating a multiplayer or otherwise networked project is adjusting your `manifest.json` to specify what [capabilities](../system/process/capabilities.md) your process will grant.

Go to `my_chess/manifest.json` and make sure your chess process is public and gets network access:
Go to `my-chess/manifest.json` and make sure your chess process is public and gets network access:
```json
[
{
"process_name": "my_chess",
"process_wasm_path": "/my_chess.wasm",
"process_name": "my-chess",
"process_wasm_path": "/my-chess.wasm",
"on_exit": "Restart",
"request_networking": true,
"request_capabilities": [],
Expand All @@ -65,7 +65,7 @@ Go to `my_chess/manifest.json` and make sure your chess process is public and ge
]
```

Now, in `my_chess/src/lib.rs` add the following simple Request/Response interface and persistable game state:
Now, in `my-chess/src/lib.rs` add the following simple Request/Response interface and persistable game state:
```rust
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -141,19 +141,19 @@ Below, you'll find the full code for the CLI version of the app.
You can build it and install it on a node using `kit`.
You can interact with it in the terminal, primitively, like so (assuming your first node is `fake.os` and second is `fake2.os`):
```
m our@my_chess:my_chess:template.os '{"NewGame": {"white": "fake.os", "black": "fake2.os"}}'
m our@my_chess:my_chess:template.os '{"Move": {"game_id": "fake2.os", "move_str": "e2e4"}}'
m our@my-chess:my-chess:template.os '{"NewGame": {"white": "fake.os", "black": "fake2.os"}}'
m our@my-chess:my-chess:template.os '{"Move": {"game_id": "fake2.os", "move_str": "e2e4"}}'
```
(If you want to make a more ergonomic CLI app, consider parsing `body` as a string, or better yet, writing [terminal scripts](../cookbook/writing_scripts.md) for various game actions.)

As you read through the code, you might notice a problem with this app: there's no way to see your games!
A fun project would be to add a CLI command that shows you, in-terminal, the board for a given `game_id`.
But in the [next chapter](./frontend.md), we'll add a frontend to this app so you can see your games in a browser.

`my_chess/Cargo.toml`:
`my-chess/Cargo.toml`:
```toml
[package]
name = "my_chess"
name = "my-chess"
version = "0.1.0"
edition = "2021"

Expand All @@ -178,7 +178,7 @@ crate-type = ["cdylib"]
package = "kinode:process"
```

`my_chess/src/lib.rs`:
`my-chess/src/lib.rs`:
```rust
use kinode_process_lib::{
await_message, call_init, get_typed_state, println, set_state, Address, Message, NodeId,
Expand Down
10 changes: 5 additions & 5 deletions src/chess_app/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ Additional UI dev info can be found [here](../apis/frontend_development.md).

Get the chess UI files and place them in the proper place (next to `pkg/`):
```bash
# run in the top-level directory of your my_chess package
# run in the top-level directory of your my-chess package
git clone https://github.com/kinode-dao/chess-ui ui
```

Chess will use the built-in HTTP server runtime module to serve a static frontend and receive HTTP requests from it.
You'll also use a WebSocket connection to send updates to the frontend when the game state changes.

In `my_chess/src/lib.rs`, inside `init()`:
In `my-chess/src/lib.rs`, inside `init()`:
```rust
use kinode_process_lib::{http::server, homepage};

Expand Down Expand Up @@ -63,7 +63,7 @@ These requests all serve HTTP that can only be accessed by a logged-in node user
Requests on the `/games` path will arrive as requests to your process, and you'll have to handle them and respond.
To do this, add a branch to the main request-handling function that takes requests from *our* `http_server:distro:sys`.

In `my_chess/src/lib.rs`, inside the part of `handle_request()` that handles local requests:
In `my-chess/src/lib.rs`, inside the part of `handle_request()` that handles local requests:
```rust
...
// if the message is from the HTTP server runtime module, we should handle it
Expand All @@ -82,7 +82,7 @@ This can be a security risk: if your app is handling sensitive actions from the
You should never expect users to "only install non-malicious apps" — instead, use a *secure subdomain* to isolate your app's HTTP resources from other processes.
See the [HTTP Server API](../apis/http_server.md) for more details.

In `my_chess/src/lib.rs`:
In `my-chess/src/lib.rs`:
```rust
/// Handle HTTP requests from our own frontend.
fn handle_http_request(
Expand Down Expand Up @@ -278,7 +278,7 @@ Almost there!
One more missing piece: the backend needs to send WebSocket updates to the frontend after each move in order to update the board without a refresh.
Since open channels are already tracked in `HttpServer`, you just need to send a push to each open channel when a move occurs.

In `my_chess/src/lib.rs`, add a helper function:
In `my-chess/src/lib.rs`, add a helper function:
```rust
fn send_ws_update(http_server: &mut server::HttpServer, game: &Game) {
http_server.ws_push_all_channels(
Expand Down
4 changes: 2 additions & 2 deletions src/chess_app/putting_everything_together.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Hopefully, you've been using `kit build <your_chess_app_name>` to test the code
If not, do so now in order to get a compiled package you can install onto a node.

Next, use `kit start-package <your_chess_app_name> -p <your_test_node_port>` to install the package.
You should see the printout you added to `init()` in your terminal: `my_chess:my_chess:template.os: start`.
You should see the printout you added to `init()` in your terminal: `my-chess:my-chess:template.os: start`.

Remember that you determine the process names via the `manifest.json` file inside `/pkg`, and the package & publisher name from `metadata.json` located at the top level of the project.
Open your chess frontend by navigating to your node's URL (probably something like `http://localhost:8080`), and use the names you chose as the path.
For example, if your chess process name is `my_chess`, and your package is named `my_chess`, and your publisher name is `template.os` (the default value), you would navigate to `http://localhost:8080/my_chess:my_chess:template.os`.
For example, if your chess process name is `my-chess`, and your package is named `my-chess`, and your publisher name is `template.os` (the default value), you would navigate to `http://localhost:8080/my-chess:my-chess:template.os`.

You should see something like this:
![chess frontend](./chess_home.png)
Expand Down
4 changes: 2 additions & 2 deletions src/chess_app/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

To prepare for this tutorial, follow the environment setup guide [here](../my_first_app/chapter_1.md), i.e. [start a fake node](../my_first_app/chapter_1.md#booting-a-fake-kinode-node) and then, in another terminal, run:
```
kit new my_chess --template blank
cd my_chess
kit new my-chess --template blank
cd my-chess
kit b
kit start-package
```
Expand Down
18 changes: 9 additions & 9 deletions src/cookbook/file_transfer_ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ It's also strongly recommended that you read and understand the [file transfer a
Create a new project with `kit`, passing the `--ui` flag:

```bash
kit new file_transfer --ui
kit new file-transfer --ui
```

This will create a new project with a `ui` directory for the Vite/React UI code, in addition to the `file_transfer` directory where the usual Rust code will be located.
This will create a new project with a `ui` directory for the Vite/React UI code, in addition to the `file-transfer` directory where the usual Rust code will be located.

## File Transfer

Expand Down Expand Up @@ -62,14 +62,14 @@ If you've never used Vite before, check out the [docs](https://vitejs.dev/guide/
### Build it!

To build the UI, run `kit build` (or just `kit b`).
This will build the UI and copy the files into the `pkg/ui` directory, then build `file_transfer` as usual.
The UI will be served from `http://localhost:8080` (or your custom node URL/port) at `/file_transfer:file_transfer:template.os`.
However, you will need to configure Vite to allow your UI to communicate seamlessly with the `file_transfer` app on your node.
This will build the UI and copy the files into the `pkg/ui` directory, then build `file-transfer` as usual.
The UI will be served from `http://localhost:8080` (or your custom node URL/port) at `/file-transfer:file-transfer:template.os`.
However, you will need to configure Vite to allow your UI to communicate seamlessly with the `file-transfer` app on your node.

### Configure Vite

You will be configuring your Vite environment in order to enable development on Kinode.
This step is necessary to allow your *development* UI (which will change often, and rebuild quickly) to communicate with the `file_transfer` app on your node (which will change rarely, and rebuild slowly).
This step is necessary to allow your *development* UI (which will change often, and rebuild quickly) to communicate with the `file-transfer` app on your node (which will change rarely, and rebuild slowly).

#### Example `vite.config.ts`
```ts
Expand Down Expand Up @@ -523,7 +523,7 @@ function FileEntry({ file, node }: Props) {

useEffect(() => {
// To display the filename ergonomically,
// you strip the `file_transfer:file_transfer:template.os/files/`
// you strip the `file-transfer:file-transfer:template.os/files/`
// prefix from the file name.
const filename = file.name.split('/files/').pop() || '';
setActualFilename(filename);
Expand Down Expand Up @@ -660,11 +660,11 @@ export default SearchFiles;

Now that you've written your UI code, you can build it.

1. Run `kit build` (or just `kit b`) to build the UI and file_transfer process.
1. Run `kit build` (or just `kit b`) to build the UI and `file-transfer` process.
1. Run `kit start-package -p 8080` (or just `kit s`) to install the package to your node running on port 8080.

In the future, you can run both of these steps in a single command, with `kit bs`.
The UI will be served from `http://localhost:8080/file_transfer:file_transfer:template.os`.
The UI will be served from `http://localhost:8080/file-transfer:file-transfer:template.os`.

## Next Steps

Expand Down
10 changes: 5 additions & 5 deletions src/cookbook/package_apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ However, for `interface`s that export only types, no `-api-` world (like `server
Instead, the WIT API alone suffices to export the types, and the importer writes a `world` that looks like [this, below](#wit-api-1).
For example, consider the `chat` template's `api/` and its usage in the `test/` package:
```
kit n my_chat
cat my_chat/api/my_chat\:template.os-v0.wit
cat my_chat/test/my_chat_test/api/my_chat_test\:template.os-v0.wit
kit n my-chat
cat my-chat/api/my-chat\:template.os-v0.wit
cat my-chat/test/my-chat-test/api/my-chat-test\:template.os-v0.wit
```

#### API Function Definitions
Expand Down Expand Up @@ -128,13 +128,13 @@ kit bs src/../code/remote_file_storage/server
# Build & start client.
## Here the `-p 8080` is to fetch deps for building client (see the metadata.json dependencies field).
kit b src/../code/remote_file_storage/client -p 8080 && kit s src/code/remote_file_storage/client -p 8081
kit b src/../code/remote_file_storage/client -p 8080 && kit s src/../code/remote_file_storage/client -p 8081
```

An alternative way to satisfy the `server` dependency of `client`:
```
## The `-l` satisfies the dependency using a local path.
kit b src/../code/remote_file_storage/client -l src/code/remote_file_storage/server
kit b src/../code/remote_file_storage/client -l src/../code/remote_file_storage/server
```

### Usage
Expand Down
Loading

0 comments on commit df5d865

Please sign in to comment.