ComponentizeJS icon indicating copy to clipboard operation
ComponentizeJS copied to clipboard

Can non-function types be imported to JS?

Open bnjbvr opened this issue 1 year ago • 2 comments

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 declare types in one imported interface; those types are part of the imports. There's an exported interface which makes use of those types as function parameters and function return values. (Code below.)

wit file
package trinity:api;

interface types {
    record message {
        text: string,
        html: option<string>,
        to: string
    }

    type reaction = string;

    variant action {
        respond(message),
        react(reaction)
    }
}

interface messaging {
    use types.{action};
    on-msg: func(content: string, author-id: string, author-name: string, room: string) -> list<action>;
}

world trinity-module {
    import types;
    export messaging;
}
guest.js
import { Message } from 'trinity:api/types';

export const messaging = {
    onMsg: function(_content, _authorId, authorName, room) {
        let actions = [];
        actions.push(new Message({
            text: `hey ${authorName}!`,
            to: room,
        }));
        return actions;
    }
};
componentize.mjs
import { componentize } from '@bytecodealliance/componentize-js';
import { readFile, writeFile } from 'node:fs/promises';

const jsSource = await readFile('guest.js', 'utf8');

const { component } = await componentize(jsSource, {
    witPath: "../wit/",
    disableFeatures: ['random', 'http', 'stdio', 'clocks'],
    debug: true,
});

await writeFile('trinityjs.component.wasm', component);

When I try to use ComponentizeJS (or jco, for that matter), it complains when componentizing that the interface I've marked as being imported is, in fact, not present among the imported interfaces.

Error: Import 'trinity:api/types' is not defined by the WIT world. Available imports are: .

The WIT file seems to be valid: wasmtime and Rust guests accept it as is, and create a Rust enum Action for the function's return value.

I tried to not import anything from the types interface, assuming that it might be hard to model static types in JS, with the hope that maybe everything would be dynamically checked at the boundary. So I tweaked the component's code by removing the new Message — just use a plain object.

I've been using componentize-js @ 0.16.0, node v23.6.0.

However, this failed with a wasm trap at runtime (and no error messages, as I'm opting out of WASI for this particular host system), so there's something else. Is there something I'm doing wrong, or any chance there's a bug in there?

bnjbvr avatar Jan 24 '25 19:01 bnjbvr

Try building with these options, leaving out debug so you can get proper error messages:

  disableFeatures: ['random', 'http', 'clocks']

The resource import as you have written looks correct to me though. If you can share a test case that would help to investigate further.

guybedford avatar Jan 25 '25 01:01 guybedford

hey @bnjbvr would you mind providing a repro repo for this? would like to be able to try this out -- someone had a similar problem on Zulip (and linked me here) and we couldn't actually reproduce.

Would you also mind sharing what command you ran?

vados-cosmonic avatar Mar 27 '25 18:03 vados-cosmonic

Closing this out for now! Please let me know if it's still an issue, and isn't fixed with the latest 0.18.3 release!

vados-cosmonic avatar Jul 22 '25 06:07 vados-cosmonic