Stream: ComponentizeJS

Topic: Can non-function types be imported to JS? #183


view this post on Zulip David Justice (Mar 27 2025 at 14:53):

Hey Folks, I'm running into an issue importing / generating types for a JS component I'm working on. I have no problem generating function imports, but the types that are needed by that function are failing to generate. The error is as follows:

Error: Import 'example:domain/types@0.3.1' is not defined by the WIT world. Available imports are: 'example:domain/adder@0.3.1', 'example:domain/chat@0.3.1', 'wasi:clocks/monotonic-clock@0.2.3', 'wasi:http/types@0.2.3', 'wasi:io/error@0.2.3', 'wasi:io/poll@0.2.3', 'wasi:io/streams@0.2.3'.

The offending import is example:domain/types@0.3.1', which can be found in the wit deps dir in the linked repo. The code is located here: https://github.com/devigned/wasm-packs/tree/3a82b341e3b9ba43bc3844f59102c0e432217206/apps/compose/app-js

I was not the OP for https://github.com/bytecodealliance/ComponentizeJS/issues/183, but I believe I'm seeing the same problem.

Contribute to devigned/wasm-packs development by creating an account on GitHub.
Hi! I've started to use ComponentizeJS for a small project and I'm rather excited at the possibility of allowing javascript as a way for wasm plugins in my program. I have a WIT file where I declar...

view this post on Zulip Guy Bedford (Mar 27 2025 at 16:07):

@David Justice haven't looked into this too thoroughly, but perhaps the domain WIT package needs to explicitly export the types interface as it only imports it currently?

view this post on Zulip Victor Adossi (Mar 27 2025 at 16:09):

Hey @David Justice would you mind sharing the commands you're running?

When I pull your repo, jco types actually works fine:

 npx jco types -o generated wit

  Generated Type Files:

 - generated/interfaces/example-domain-adder.d.ts          0.1 KiB
 - generated/interfaces/wasi-clocks-monotonic-clock.d.ts  0.37 KiB
 - generated/interfaces/wasi-http-incoming-handler.d.ts   0.85 KiB
 - generated/interfaces/wasi-http-types.d.ts              25.1 KiB
 - generated/interfaces/wasi-io-error.d.ts                0.18 KiB
 - generated/interfaces/wasi-io-poll.d.ts                 0.25 KiB
 - generated/interfaces/wasi-io-streams.d.ts              1.14 KiB
 - generated/wit.d.ts                                     0.81 KiB

Of course your build target also works fine for me as well

view this post on Zulip Victor Adossi (Mar 27 2025 at 16:10):

Note that npx jco transpile also works just fine for me -- I do wonder what you could be running into

view this post on Zulip David Justice (Mar 27 2025 at 17:28):

Yeah, jco types works like a charm. I had the same result and thought about just going down the jco path. However, I looked and saw an open issue in componentize-js without a repro, so thought I'd bring it up and see if we could sort it out.

The build is basically https://github.com/devigned/wasm-packs/blob/a42b6f4d67bcd916e4180181fac5f8330c9e0ea3/apps/compose/app-js/package.json#L14.

  "scripts": {
    "build:rollup": "rollup -c",
    "build": "wkg wit fetch && npm run build:rollup  && node componentize.js"
  },

And a really simple componentize.js script (almost the same as the example).

import { readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";

import { componentize } from "@bytecodealliance/componentize-js";

// AoT compilation makes use of weval (https://github.com/bytecodealliance/weval)
const enableAot = process.env.ENABLE_AOT == "1";

const jsSource = await readFile("./dist/index.js", "utf8");

const { component } = await componentize(jsSource, {
  witPath: resolve("wit"),
  debug: true,
  enableAot,
});

let componentName = process.env.COMPONENT_NAME ?? "server.component.wasm";
await writeFile(componentName, component);

https://github.com/devigned/wasm-packs/blob/main/apps/compose/app-js/componentize.js

I tried to breaking up the wit files for example:domain. I tried to copy the same format at the WASI wit specs. I tried multiple combinations of import and use. Eventually, I gave up after seeing jco produce the expected output.

Contribute to devigned/wasm-packs development by creating an account on GitHub.
Contribute to devigned/wasm-packs development by creating an account on GitHub.

view this post on Zulip Victor Adossi (Mar 27 2025 at 19:43):

Ah sorry I'm a little confused (that rollup command is new to me -- that wasn't there when I ran the code in your repo before), but does that mean things worked?

Are you seeing this error:

Error: Import 'example:domain/types@0.3.1' is not defined by the WIT world. Available imports are: 'example:domain/adder@0.3.1', 'example:domain/chat@0.3.1', 'wasi:clocks/monotonic-clock@0.2.3', 'wasi:http/types@0.2.3', 'wasi:io/error@0.2.3', 'wasi:io/poll@0.2.3', 'wasi:io/streams@0.2.3'.

Anymore? If you are, what command are you running? Or is this happening when you're running the component somewhere else?

view this post on Zulip David Justice (Mar 27 2025 at 19:52):

The code in main works, but was super hacky. I ended up creating a JS object in the shape of what the chat function needed without using the generated types. Surprisingly, that worked!

This link is a perma-link to the project when I was getting the error: https://github.com/devigned/wasm-packs/tree/a42b6f4d67bcd916e4180181fac5f8330c9e0ea3/apps/compose/app-js. If you add the line import { ChatRequest } from "example:domain/types@0.3.0"; to line 10 of ./src/server.js, the error is reproduced when running npm run build. (probably should have pushed it with the line in there, but...)

Rollup is used for bundling js deps together. I introduced a router to the incoming-handler to make dev feel more like a regular JS web experience.

Contribute to devigned/wasm-packs development by creating an account on GitHub.

view this post on Zulip Milan (rajsite) (Mar 27 2025 at 22:51):

I didn't fully try your build but betting you need to configure externals in your rollup config for any wit imports so rollup doesn't try to resolve them, i.e. external: /wasi:.*/, and also for your custom example: imports

view this post on Zulip David Justice (Mar 28 2025 at 12:19):

Rollup complains a bit, but there is no issue with other function definitions in the same wit package (example:domain). The problem is only with type definitions in the example:domain wit package. Due to that, I believe that the error has very little to do with rollup and more to do with how the type definitions in the wit interface are handled when producing the wasm component.

view this post on Zulip David Justice (Mar 28 2025 at 12:24):

Related, but not germane to this issue, would folks be interested in an example for componentize-js demonstrating how to bundle js dependencies? I feel like the hello world example doesn't really hit the mainstream developer whom is likely to want to build something more akin to a HTTP API using an off the shelf router. WDYT?

view this post on Zulip Victor Adossi (Mar 31 2025 at 17:19):

David Justice said:

Related, but not germane to this issue, would folks be interested in an example for componentize-js demonstrating how to bundle js dependencies? I feel like the hello world example doesn't really hit the mainstream developer whom is likely to want to build something more akin to a HTTP API using an off the shelf router. WDYT?

We'd definitely love to have that as an example! Would be happy to field such a PR :)

view this post on Zulip David Justice (Apr 10 2025 at 11:19):

Ok, based on chatting with @Till Schneidereit, currently, JS types will not be generated for type definitions. I believe the project is working as expected. However, that just means that JS type generation is a feature rather than a bug.

Till also had mentioned the implementation would be non-trivial. I'm not entirely sure how non-trivial at this point, but I'll hack a bit at it and see if I can make progress.

I believe a passing test for this should look something like this: https://github.com/bytecodealliance/ComponentizeJS/compare/main...devigned:ComponentizeJS:js-type-gen?expand=1

JS -> WebAssembly Component. Contribute to bytecodealliance/ComponentizeJS development by creating an account on GitHub.

view this post on Zulip David Justice (Apr 10 2025 at 11:24):

Victor Adossi said:

David Justice said:

Related, but not germane to this issue, would folks be interested in an example for componentize-js demonstrating how to bundle js dependencies? I feel like the hello world example doesn't really hit the mainstream developer whom is likely to want to build something more akin to a HTTP API using an off the shelf router. WDYT?

We'd definitely love to have that as an example! Would be happy to field such a PR :)

@Tomasz Andrzejak and I discussed this yesterday. He ran with it and has a clean implementation that should be pretty easy to follow.

Would the example be best as a GitHub template repository or as an example in a directory in componentize-js? @Yosh Wuyts, do you have any opinions on template repos vs examples?

view this post on Zulip Tomasz Andrzejak (Apr 10 2025 at 12:35):

Here, I created a repo (similar to Rust sample that we already have in bytecodealliance) that demonstrates creating a router application:

https://github.com/andreiltd/sample-wasi-http-js

An example `wasi:http` server component written in JavaScript - andreiltd/sample-wasi-http-js

view this post on Zulip Ralph (Apr 10 2025 at 13:47):

image.png

view this post on Zulip Ralph (Apr 10 2025 at 13:47):

seems to work

view this post on Zulip Ralph (Apr 10 2025 at 13:47):

:-)


Last updated: Dec 06 2025 at 06:05 UTC