Skip to content

Commit ddb9c54

Browse files
author
Guy Bedford
authored
feat: support fetch via async functions (#131)
1 parent 2e4101e commit ddb9c54

22 files changed

Lines changed: 602 additions & 540 deletions

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ lib/spidermonkey-embedding-splicer.js: target/wasm32-wasi/release/spidermonkey_e
2020
target/wasm32-wasi/release/spidermonkey_embedding_splicer.wasm: Cargo.toml crates/spidermonkey-embedding-splicer/Cargo.toml crates/spidermonkey-embedding-splicer/src/*.rs
2121
cargo build --release --target wasm32-wasi
2222

23-
lib/starlingmonkey_embedding.wasm: StarlingMonkey/cmake/* embedding/* StarlingMonkey/runtime/* StarlingMonkey/builtins/* StarlingMonkey/builtins/**/* StarlingMonkey/include/* | lib
23+
lib/starlingmonkey_embedding.wasm: StarlingMonkey/cmake/* embedding/* StarlingMonkey/runtime/* StarlingMonkey/builtins/* StarlingMonkey/builtins/*/* StarlingMonkey/builtins/*/*/* StarlingMonkey/include/* | lib
2424
cmake -B build-release -DCMAKE_BUILD_TYPE=Release
2525
make -j16 -C build-release
2626
@cp build-release/starling.wasm/starling.wasm $@
2727

28-
lib/starlingmonkey_embedding.debug.wasm: StarlingMonkey/cmake/* embedding/* StarlingMonkey/runtime/* StarlingMonkey/builtins/* StarlingMonkey/builtins/**/* StarlingMonkey/include/* | lib
28+
lib/starlingmonkey_embedding.debug.wasm: StarlingMonkey/cmake/* embedding/* StarlingMonkey/runtime/* StarlingMonkey/builtins/* StarlingMonkey/builtins/*/* StarlingMonkey/builtins/*/*/* StarlingMonkey/include/* | lib
2929
cmake -B build-debug -DCMAKE_BUILD_TYPE=RelWithDebInfo
3030
make -j16 -C build-debug
3131
@cp build-debug/starling.wasm/starling.wasm $@
@@ -42,4 +42,4 @@ obj/builtins:
4242
clean:
4343
rm -r obj
4444
rm lib/spidermonkey-embedding-splicer.js
45-
rm lib/spidermonkey_embedding.wasm
45+
rm lib/starlingmonkey_embedding.wasm

README.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,23 @@ await writeFile('test.component.wasm', component);
100100

101101
The component iself can be executed in any component runtime, see the [example](EXAMPLE.md) for an end to end workflow in Wasmtime.
102102

103+
### Async Support
104+
105+
To support asynchronous operations, all functions may optionally be written as sync or async functions, even though they will always be turned into sync component functions.
106+
107+
For example, to use `fetch` which requires async calls, we can write the same example component using an async function:
108+
109+
```js
110+
export async function sayHello (name) {
111+
const text = await (await fetch(`http://localhost:8080/${name}`)).text();
112+
console.log(text);
113+
}
114+
```
115+
116+
ComponentizeJS will automatically resolve promises returned by functions to syncify their return values, running the event loop within the JS component to resolution.
117+
118+
This asynchrony is only supported for exported functions - imported functions can only be synchronous pending component-model-level async support.
119+
103120
### CLI
104121

105122
ComponentizeJS can be used as a CLI from `jco`:
@@ -125,13 +142,13 @@ The default set of features includes:
125142
* `'stdio'`: Output to stderr and stdout for errors and console logging, depends on `wasi:cli` and `wasi:io`.
126143
* `'random'`: Support for cryptographic random, depends on `wasi:random`. **When disabled, random numbers will still be generated but will not be random and instead fully deterministic.**
127144
* `'clocks'`: Support for clocks and duration polls, depends on `wasi:clocks` and `wasi:io`. **When disabled, using any timer functions like setTimeout or setInterval will panic.**
145+
* `'http'`: Support for outbound HTTP via the `fetch` global in JS.
128146

129-
Setting `disableFeatures: ['random', 'stdio', 'clocks']` will disable all features creating a minimal "pure component", that does not depend on any WASI APIs at all and just the target world.
147+
Setting `disableFeatures: ['random', 'stdio', 'clocks', 'http']` will disable all features creating a minimal "pure component", that does not depend on any WASI APIs at all and just the target world.
130148

131149
Note that pure components **will not report errors and will instead trap**, so that this should only be enabled after very careful testing.
132150

133-
Note that features explicitly imported by the target world cannot be disabled - if you target a component to a world
134-
that imports `wasi:clocks`, then `disableFeatures: ['clocks']` will not be supported.
151+
Note that features explicitly imported by the target world cannot be disabled - if you target a component to a world that imports `wasi:clocks`, then `disableFeatures: ['clocks']` will not be supported.
135152

136153
## Using StarlingMonkey's `fetch-event`
137154

crates/spidermonkey-embedding-splicer/src/bindgen.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -910,15 +910,16 @@ impl JsBindgen<'_> {
910910
binding_name(&resource.func_name(fn_name), &iface_name)
911911
);
912912

913-
uwrite!(self.src, "\nexport function {binding_name}");
913+
// all exports are supported as async functions
914+
uwrite!(self.src, "\nexport async function {binding_name}");
914915

915916
// exports are canonicalized as imports because
916917
// the function bindgen as currently written still makes this assumption
917918
let sig = self.resolve.wasm_signature(AbiVariant::GuestImport, func);
918919

919920
self.bindgen(
920921
sig.params.len(),
921-
&callee,
922+
&format!("await {callee}"),
922923
string_encoding,
923924
func,
924925
AbiVariant::GuestImport,

crates/spidermonkey-embedding-splicer/src/splice.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ pub fn splice(
3434
exports: Vec<(String, CoreFn)>,
3535
debug: bool,
3636
) -> Result<Vec<u8>> {
37-
let config = walrus::ModuleConfig::new();
37+
let mut config = walrus::ModuleConfig::new();
38+
config.generate_dwarf(true);
3839
let mut module = config.parse(&engine)?;
3940

4041
// since StarlingMonkey implements CLI Run and incoming handler,

0 commit comments

Comments
 (0)