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

Using --embind-emit-tsd should define auxiliary Webassembly-module members #20296

Open
jnickg opened this issue Sep 19, 2023 · 5 comments
Open
Assignees

Comments

@jnickg
Copy link
Contributor

jnickg commented Sep 19, 2023

On the latest release of EMSDK, 3.1.46, I can now use the --embind-emit-tsd flag to generate embind TS definitions for my webassembly modules. However, naively switching to this causes some TS compiler complaints about missing members and functions, as our hand-written .d.ts files included some subset of the auxiliary EmscriptenModule definitions (basically whatever we were actually using and needed). For our projects we used a pattern looking like this:

export interface WebassemblyModule {
    HEAPU8: Uint8Array;
    _malloc(size: number): number;
    _free(ptr: number): void;
    // Other auxiliary stuff might be defined here
}

export interface MyModule extends WebassemblyModule {
  myBindingsGoHere(): void;
}

declare function MyModule(options?: {
    locateFile(filename: string): string;
}): Promise<MyModule>;

export default MyModule;

In concept this can be worked around without too much effort, by emitting the embinding definitions to something like wasm.ts, then hard-coding a TS definition file like this.

import {
    type MainModule
} from "./wasm.js";

export interface WebassemblyModule {
    HEAPU8: Uint8Array;
    _malloc(size: number): number;
    _free(ptr: number): void;
}

export type MyRealModule = MainModule & WebassemblyModule;

declare function MyRealModule(options?: {
    locateFile(filename: string): string;
}): Promise<MyRealModule>;

export default MyRealModule;

export * from "./wasm.js";

Of course the downside to this is that it still has to be manually maintained, and it adds complication to builds.

If it's not a huge lift, it would be nice to include auxiliary stuff, such as things exposed by the EXPORTED_FUNCTIONS flag & whatever is always there, so users don't have to manually add them. That way, nothing needs to be manually maintained, and the d.ts file advertises (closer to) everything accessible on the module object.

@jnickg
Copy link
Contributor Author

jnickg commented Sep 21, 2023

Including stuff listed in INCOMING_MODULE_JS_API would be helpful too.

@jnickg
Copy link
Contributor Author

jnickg commented Oct 24, 2023

Bump on this -- getting a typescript .d.ts file that fully describes the types involved when loading the compiled JS file would help this feature be used more broadly, since right now it doesn't "just work" and that's a deal breaker for many users.

@brendandahl
Copy link
Collaborator

In #21279 I've added the wasm module exports to definitions. There will still be more work needed to get the full definition though.

@jnickg
Copy link
Contributor Author

jnickg commented Mar 1, 2024

@brendandahl what about stuff like MODULARIZE/EXPORT_ES6 flags? When I use those, the .d.ts output doesn't include typescript declarations for this code present in the JS output, which causes the two not to line up

var MyModule = (() => {
  var _scriptDir = import.meta.url;
  
  return (async function(moduleArg = {}) {});})();
export default MyModule;

Would that be better handled as a separate ticket? I can see reasonable arguments for handling here, or splitting it out, so I don't have a strong opinion

@jnickg
Copy link
Contributor Author

jnickg commented Mar 1, 2024

@brendandahl I took a quick stab at improving ES6 support in #21460, but I haven't contributed to Esmcripten and don't yet have a dev environment set up. I'll work on that now, but do you think you can take a quick look to let me know if, generally, the approach in the PR is sensible?

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