Skip to content

wasip3 hostProvided async tasks: top-level resolves too early #1272

@ritalin

Description

@ritalin

Hi all,

I understand that asynchronous support in wasip3 is still in an early stage.
I’m testing wasip3 asynchronous host-provided functions in a JS-WASM setup. Here’s the context:

  1. WIT definitions
interface opfs-file {
    read: async func(path: string) -> string;
    write: async func(path: string, data: string) -> u32;
}

world tester-world {
    import opfs-file;
    export run: async func(path: string);
}
  • WASM implements only run()
  • read / write are provided by a JS shim
  • WASM is transpiled via jco, generating JS bindings
  1. WASM run() implementation
async fn run(path: String) -> () {
    println!("Start writing to opfs (path: {})", &path);
    let n = opfs_file::write(path.clone(), "foo-bar-baz".into()).await;
    println!("End writing to opfs (ret: {})", n);

    println!("Start reading from opfs");
    println!("contents: `{}`", opfs_file::read(path).await);
}
  1. JS Shim (boilerplate for testing)
export const read = async (path: string): Promise<string> => {
  console.info("`read` on shim called");
  return "qwerty"; // placeholder for actual async logic
};

export const write = async (path: string, data: string): Promise<number> => {
  console.info("`write` on shim called");
  return 42; // placeholder for actual async logic
};

Note: These are just boilerplate implementations for verification. Real async logic will replace the placeholders.

  1. Top-level call
await wasm.run("xyz.txt");
console.info("Terminated !");

Expected behavior

(wasm)run -> (wasm)write -> (shim)write -> (wasm)read -> (shim)read -> Terminated !

Actual behavior

Start writing to opfs (path: xyz.txt)
Terminated !
`write` on shim called
  • read never waits
  • Top-level run resolves before subtasks complete

Observations / Analysis

  • Subtasks (write / read) are registered as AsyncTask
  • _driverLoop() polls subtasks, but top-level task resolves immediately
  • Host-provided tasks do not propagate resolution to the top-level task

Question

Is this expected behavior for host-provided tasks? Should the top-level task automatically wait for JS shim completion, or is there a recommended pattern to properly await subtasks in wasip3?

Any guidance or examples would be greatly appreciated.

Thanks!

Environment

  • runtime: NodeJS 25.2.1
  • jco: 0.17.0
  • rust: 1.93.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions