Skip to content

Commit 5d1c390

Browse files
feat(examples): update hono examples import separation, better docs
1 parent 133a66c commit 5d1c390

File tree

11 files changed

+66
-36
lines changed

11 files changed

+66
-36
lines changed

examples/components/http-server-hono-with-bindings/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
# Hono HTTP server example
1+
# Hono HTTP server with host bindings
22

33
This repository showcases using a WebAssembly component built with the Javascript WebAssembly Component
44
toolchain (`jco`) to respond to web requests using the [Hono][hono] web framework.
55

6+
In addition to simply running a transpiled web component (see `scripts/demo.mjs`),
7+
we introduce a host binding for the [`wasi:config/[email protected]` API][wasi-config]
8+
(see [`src/host/bindings/config.ts`](./src/host/bindings/config.ts)).
9+
610
## How it works
711

812
Handling web requests is part of [WebAssembly System Interface (WASI)][wasi], under an interface called [`wasi:http`][wasi-http]
@@ -23,6 +27,13 @@ that handles incoming HTTP requests (`wasi:http/incoming-handler`).
2327
> If you don't know what any of the above means, don't worry about it -- check out the [Component Model Book][cm-book],
2428
> or keep following along and experiment!
2529
30+
**All of this is made easier to use by [`@bytecodealliance/jco-std`][jco-std]**, a package that offers
31+
easy to use exports to running on WebAssembly more Hono-native.
32+
33+
*In addition* to using `wasi:http/incoming-handler`, this project uses `jco-std`'s support for [`wasi:cli/environment`][wasi-cli-environment]
34+
to enable reading environment variables and [`wasi:config/store`][wasi-config-store], to easily access ENV variables and
35+
custom configuration on the WebAssembly + WASI platform.
36+
2637
[hono]: https://hono.dev
2738
[sm]: https://github.com/bytecodealliance/StarlingMonkey
2839
[wasi]: https://github.com/WebAssembly/WASI/tree/main
@@ -31,6 +42,9 @@ that handles incoming HTTP requests (`wasi:http/incoming-handler`).
3142
[p2-shims]: https://www.npmjs.com/package/@bytecodealliance/preview2-shim
3243
[cm-book]: https://component-model.bytecodealliance.org/
3344
[wintertc]: https://wintertc.org/
45+
[jco-std]: https://www.npmjs.com/package/@bytecodealliance/jco-std
46+
[wasi-config-store]: https://github.com/WebAssembly/wasi-config/blob/main/wit/store.wit
47+
[wasi-cli-environment]: https://github.com/WebAssembly/wasi-cli/blob/main/wit/environment.wit
3448

3549
## Quickstart
3650

examples/components/http-server-hono-with-bindings/generated/types/wit.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/// <reference path="./interfaces/wasi-io-error.d.ts" />
77
/// <reference path="./interfaces/wasi-io-poll.d.ts" />
88
/// <reference path="./interfaces/wasi-io-streams.d.ts" />
9-
declare module 'example:hono/component' {
9+
declare module 'example:http-server-hono-with-bindings/component' {
1010
export type * as WasiCliEnvironment026 from 'wasi:cli/[email protected]'; // import wasi:cli/[email protected]
1111
export type * as WasiClocksMonotonicClock026 from 'wasi:clocks/[email protected]'; // import wasi:clocks/[email protected]
1212
export type * as WasiConfigStore020Rc1 from 'wasi:config/[email protected]'; // import wasi:config/[email protected]

examples/components/http-server-hono-with-bindings/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"scripts": {
88
"gen:types": "jco guest-types wit -o generated/types",
99
"build:ts": "rolldown -c rolldown.config.mjs",
10-
"build:component": "jco componentize -w wit -o dist/component.wasm dist/component.js",
10+
"build:component": "jco componentize -w wit -o dist/guest/component.wasm dist/guest/component.js",
1111
"build": "npm run gen:types && npm run build:ts && npm run build:component",
12-
"transpile": "jco transpile -o dist/transpiled dist/component.wasm",
13-
"serve": "jco serve dist/component.wasm",
12+
"transpile": "jco transpile -o dist/transpiled dist/guest/component.wasm",
13+
"serve": "jco serve dist/guest/component.wasm",
1414
"demo": "node scripts/demo.mjs",
1515
"all": "npm run build && npm run demo"
1616
},

examples/components/http-server-hono-with-bindings/rolldown.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default defineConfig([
1010
},
1111
},
1212
{
13-
input: "src/host/bindings/*.ts",
13+
input: "src/host/bindings/config.ts",
1414
external: /wasi:.*/,
1515
output: {
1616
dir: "dist/host/bindings",

examples/components/http-server-hono-with-bindings/scripts/demo.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ const JCO_PATH = env.JCO_PATH ?? "jco";
1818

1919
/** Path to the WASM file to be used */
2020
const WASM_PATH = fileURLToPath(
21-
new URL(env.WASM_PATH ?? "../dist/component.wasm", import.meta.url),
21+
new URL(env.WASM_PATH ?? "../dist/guest/component.wasm", import.meta.url),
2222
);
2323

2424
/** Path to the `wasi:config` bindings file to be used */
2525
const WASI_CONFIG_BINDINGS_PATH = fileURLToPath(
26-
new URL(env.WASM_PATH ?? "../host-binding-wasi-config-store.mjs", import.meta.url),
26+
new URL(env.WASM_PATH ?? "../dist/host/bindings/config.js", import.meta.url),
2727
);
2828

2929
async function main() {

examples/components/http-server-hono-with-bindings/src/guest/component.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import { logger } from 'hono/logger';
88
*
99
* @see https://github.com/WebAssembly/wasi-http
1010
*/
11-
import { fire, buildLogger } from '@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server';
11+
import { fire, buildLogger } from '@bytecodealliance/jco-std/wasi/0.2.x/http/adapters/hono/server';
12+
13+
import { wasiEnvMiddleware, type WasiEnvHelper } from '@bytecodealliance/jco-std/wasi/0.2.x/http/adapters/hono/middleware/env';
14+
import { wasiConfigMiddleware, type WasiConfigHelper } from '@bytecodealliance/jco-std/wasi/0.2.x/http/adapters/hono/middleware/config';
1215

1316
const app = new Hono();
1417

@@ -17,14 +20,38 @@ const log = buildLogger();
1720

1821
app.use(logger(log));
1922

23+
// Enable the wasi env middleware which will populate c.get('env')
24+
// with environment variables provided by the platform underneath
25+
app.use(wasiEnvMiddleware());
26+
27+
// Enable the wasi config middleware which will populate c.get('config')
28+
// with config variables provided by the platform underneath
29+
app.use(wasiConfigMiddleware());
30+
2031
app.get("/", (c) => {
32+
const env: WasiEnvHelper = c.get('env');
33+
if (!env) { return c.json({ status: 'error', msg: 'missing env helper'}); }
34+
const config: WasiConfigHelper = c.get('config');
35+
if (!config) { return c.json({ status: 'error', msg: 'missing config helper'}); }
36+
37+
// NOTE: To control what is available via these interfaces
38+
//
39+
// see:
40+
// - scripts/demo.mjs (host/platform setup, 'wasi:cli/environment' configuration via `jco serve`)
41+
// - src/host/bindings/config/env.ts (config builtin)
42+
43+
// Retrieve values from ENV/config
44+
const username = env.getAllObject()['USER'] ?? 'unknown';
45+
// see: host/bindings/config.js
46+
const testKeyValue = config.get("test-key");
47+
2148
log.debug('entered handler');
22-
return c.text("Hello World!!!!");
49+
return c.json({ status: 'success', data: { username, testKeyValue }});
2350
});
2451

2552
fire(app);
2653

2754
// Although we've called `fire()` with wasi HTTP configured for use above,
2855
// we still need to actually export the `wasi:http/incoming-handler` interface object,
2956
// as jco will be looking for the ES module export.
30-
export { incomingHandler } from '@bytecodealliance/jco-std/wasi/0.2.6/http/adapters/hono/server';
57+
export { incomingHandler } from '@bytecodealliance/jco-std/wasi/0.2.x/http/adapters/hono/server';

examples/components/http-server-hono-with-bindings/src/host/bindings/config.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@
1111
* see: https://github.com/WebAssembly/wasi-config/blob/main/wit/store.wit
1212
*/
1313

14+
const HARDCODED = {
15+
"test-key": "test-value",
16+
};
17+
1418
/** wasi:config/store.get */
15-
export const get = () => {
16-
// TODO: read from a real config source
19+
export const get = (key: string) => {
20+
if (key == "test-key") { return HARDCODED["test-key"]; }
1721
return undefined;
1822
};
1923

2024
/** wasi:config/store.getAll */
2125
export const getAll = () => {
22-
// TODO: read from a real config source
23-
return [];
26+
return Object.entries(HARDCODED);
2427
};

examples/components/http-server-hono-with-bindings/wit/component.wit

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
package example:hono;
1+
package example:http-server-hono-with-bindings;
22

33
world component {
4-
// NOTE: Since jco-std can enable ENV and config middlewares,
5-
// we include WASI interfaces for environment variables and config
4+
// NOTE: Unlike the simple http-server-hono example,
5+
// since we use middlewares that depend on 'wasi:cli/environment'
6+
// and 'wasi:config/store', we must declare those WASI interfaces
7+
// as imports for this component.
68
import wasi:cli/environment@0.2.6;
79
import wasi:config/store@0.2.0-rc.1;
810

examples/components/http-server-hono/generated/types/wit.d.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
/// <reference path="./interfaces/wasi-cli-environment.d.ts" />
21
/// <reference path="./interfaces/wasi-clocks-monotonic-clock.d.ts" />
3-
/// <reference path="./interfaces/wasi-config-store.d.ts" />
42
/// <reference path="./interfaces/wasi-http-incoming-handler.d.ts" />
53
/// <reference path="./interfaces/wasi-http-types.d.ts" />
64
/// <reference path="./interfaces/wasi-io-error.d.ts" />
75
/// <reference path="./interfaces/wasi-io-poll.d.ts" />
86
/// <reference path="./interfaces/wasi-io-streams.d.ts" />
9-
declare module 'example:hono/component' {
10-
export type * as WasiCliEnvironment026 from 'wasi:cli/[email protected]'; // import wasi:cli/[email protected]
7+
declare module 'example:http-server-hono/component' {
118
export type * as WasiClocksMonotonicClock026 from 'wasi:clocks/[email protected]'; // import wasi:clocks/[email protected]
12-
export type * as WasiConfigStore020Rc1 from 'wasi:config/[email protected]'; // import wasi:config/[email protected]
139
export type * as WasiHttpTypes026 from 'wasi:http/[email protected]'; // import wasi:http/[email protected]
1410
export type * as WasiIoError026 from 'wasi:io/[email protected]'; // import wasi:io/[email protected]
1511
export type * as WasiIoPoll026 from 'wasi:io/[email protected]'; // import wasi:io/[email protected]

examples/components/http-server-hono/scripts/demo.mjs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ const WASM_PATH = fileURLToPath(
2121
new URL(env.WASM_PATH ?? "../dist/component.wasm", import.meta.url),
2222
);
2323

24-
/** Path to the `wasi:config` bindings file to be used */
25-
const WASI_CONFIG_BINDINGS_PATH = fileURLToPath(
26-
new URL(env.WASM_PATH ?? "../host-binding-wasi-config-store.mjs", import.meta.url),
27-
);
28-
2924
async function main() {
3025
// Determine paths to jco and output wasm
3126
const wasmPathExists = await stat(WASM_PATH)
@@ -44,9 +39,7 @@ async function main() {
4439
"serve",
4540
"--port",
4641
randomPort,
47-
`--jco-map=wasi:config/store=${WASI_CONFIG_BINDINGS_PATH}`,
4842
WASM_PATH,
49-
5043
];
5144
// Spawn jco serve
5245
const proc = spawn(JCO_PATH, jcoArgs, {

0 commit comments

Comments
 (0)