Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
bnjbvr opened this issue Jan 24, 2025 · 1 comment
Open

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

bnjbvr opened this issue Jan 24, 2025 · 1 comment

Comments

@bnjbvr
Copy link
Member

bnjbvr commented Jan 24, 2025

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?

@guybedford
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants