Skip to content

Commit

Permalink
feat(examples): add typescript http hello-world actor
Browse files Browse the repository at this point in the history
As Javascript support for WebAssembly progresses along with the `jco`
toolchain, it's possible to build actors that work with the wasmcloud
ecosystem, leveraging the existing host, provider and actor ecosystem.

This commit adds a Typescript HTTP hello-world actor which shows how to use
the Typescript and `jco` ecosystems together with wasmcloud.

Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
  • Loading branch information
vados-cosmonic committed Jan 10, 2024
1 parent 989bca3 commit 91ac021
Show file tree
Hide file tree
Showing 49 changed files with 4,690 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/typescript/actors/http-hello-world/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# JS build output
/dist/

/node_modules/
/keys/

# wash build output
/build/*
1 change: 1 addition & 0 deletions examples/typescript/actors/http-hello-world/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v21.5.0
116 changes: 116 additions & 0 deletions examples/typescript/actors/http-hello-world/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Typescript HTTP Hello World

This repository contains a hello world HTTP actor component, written in [Typescript][ts].

This component:

- Uses Typescript for it's implementation
- Uses the [`wasi:http`][wasi-http] standard WIT definitions
- Relies on the [`httpserver` capability provider][httpserver-provider] (which exposes the [`wasmcloud:httpserver` interface][httpserver-interface])
- Return `"hello from Typescript"` to all HTTP requests
- Can be declaratively provisioned with [`wadm`][wadm]

[ts]: https://www.typescriptlang.org/
[wasi-http]: https://github.com/WebAssembly/wasi-http
[httpserver-provider]: https://github.com/wasmCloud/wasmCloud/tree/main/crates/providers/http-server
[httpserver-interface]: https://github.com/wasmCloud/interfaces/tree/main/httpserver
[wadm]: https://github.com/wasmCloud/wadm

# Dependencies

This relies on the following installed software:

| Name | Description |
|--------|-------------------------------------------------------------------------------------------------|
| `wash` | [Wasmcloud Shell][wash] controls your [wasmcloud][wasmcloud] host instances and enables building actors |
| `npm` | [Node Package Manager (NPM)][npm] which manages packages for for the NodeJS ecosystem |
| `node` | [NodeJS runtime][nodejs] (see `.nvmrc` for version) |

[wash]: https://github.com/wasmCloud/wasmCloud/tree/main/crates/wash-cli
[node]: https://nodejs.org
[npm]: https://github.com/npm/cli

# Get started

## Install NodeJS dependencies

If you have the basic dependencies installed, you can install NodeJS-level dependcies:

```console
npm install
```

## Start a wasmcloud host

To start a wasmcloud host you can use `wash`:

```console
wash up
```

This command won't return (as it's the running host process), but you can view the output of the host.

## Build the actor component

To build the [actor component][wasmcloud-actor-component], we can use `wash`:

```console
wash build
```

This will build and sign the actor and place a signed [WebAssembly component][wasm-component] at `build/index_s.wasm`.

`build` performs many substeps (see `package.json` for details):

- (`build:tsc`) transpiles Typescript code into Javascript code
- (`build:component`) builds a [WebAssembly component][wasm-component] using the [`jco` toolchain][jco]
- (`build:actor`) sign an actor for this component using `wash`

[wasmcloud-actor-component]: https://wasmcloud.com/docs/concepts/webassembly-components
[wasm-component]: https://component-model.bytecodealliance.org/
[jco]: https://github.com/bytecodealliance/jco

## Update WADM manifest with the built actor path

Before we can start the actor, we need to edit our declarative configuration to reflect the path to the built WebAssembly component in `typescript-http-hello-world.wadm.yaml`:

```yaml
properties:
# TODO: you must replace the path below to match your genreated code in build
image: file:///the/absolute/path/to/build/index_s.wasm
```

Replace the `the/absolute/path/...` above with the path to `build/index_s.wasm`.


## Start the actor along with the HTTP server provider

To start the actor, HTTP server provider and everything we need to run:

```console
npm run wadm:start
```

This command will deploy the application to your running wasmcloud host, using [`wadm`][wadm], a declarative WebAssembly orchestrator.

## Send a request to the running actor

To send a request to the running actor (via the HTTP server provider):

```console
curl localhost:8081
```

> [!INFO]
> Confused as to why it is port 8081?
>
> See `typescript-http-hello-world.wadm.yaml` for more information on the pieces of the architecture;
> actors, providers, and link definitions.
## (Optional) reload on code change

To quickly reload your application after changing the code in `index.ts`:

```console
npm run reload
```
33 changes: 33 additions & 0 deletions examples/typescript/actors/http-hello-world/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
IncomingRequest,
ResponseOutparam,
OutgoingResponse,
Fields,
} from "wasi:http/types@0.2.0-rc-2023-12-05";

// Implementation of wasi-http incoming-handler
//
// NOTE: To understand the types involved, take a look at wit/deps/http/types.wit
function handle(req: IncomingRequest, resp: ResponseOutparam) {
// Start building an outgoing response
const outgoingResponse = new OutgoingResponse(new Fields());

// Access the outgoing response body
let outgoingBody = outgoingResponse.body();
// Create a stream for the response body
let outputStream = outgoingBody.write();
// // Write hello world to the response stream
outputStream.blockingWriteAndFlush(
new Uint8Array(new TextEncoder().encode("hello from Typescript"))
);

// Set the status code for the response
outgoingResponse.setStatusCode(200);

// Set the created response
ResponseOutparam.set(resp, { tag: "ok", val: outgoingResponse });
}

export const incomingHandler = {
handle,
};
29 changes: 29 additions & 0 deletions examples/typescript/actors/http-hello-world/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "ts-example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build:tsc": "tsc",
"build:component": "jco componentize -w wit -o dist/index.wasm dist/index.js",
"build:actor": "wash build --sign-only --config-path wasmcloud.toml",
"build": "npm run build:tsc && npm run build:component && npm run build:actor",
"actor:start": "wash start actor file://$(realpath dist/index_s.wasm) --auction-timeout-ms 10000 --timeout-ms 10000",
"actor:stop": "wash stop actor typescript-http-hello-world",
"wadm:start": "wash app deploy typescript-http-hello-world.wadm.yaml",
"wadm:stop": "wash app delete typescript-http-hello-world v0.0.1",
"start": "npm run build && npm run wadm:start",
"reload": "npm run build && npm run wadm:stop && npm run wadm:start",
"stop": "npm run wadm:stop",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@bytecodealliance/componentize-js": "^0.6.0",
"@bytecodealliance/jco": "^0.14.2",
"@types/node": "^20.10.8",
"typescript": "^5.3.3"
}
}

0 comments on commit 91ac021

Please sign in to comment.