-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(examples): add typescript http hello-world actor
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
1 parent
989bca3
commit 91ac021
Showing
49 changed files
with
4,690 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
v21.5.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
Oops, something went wrong.