Stream: general

Topic: ✔ Package and namespace being renamed when building compo...


view this post on Zulip Lorenzo (Feb 04 2025 at 08:15):

Thanks for your response! I ended up figuring that out shortly after I sent the message here... lol

I published with warg instead of wkg. I wonder if these are equivalent?

I indeed published the built component rather than just the package/"interface".

It does makes sense to me now that the component wraps it in a new package/world, but initially I was confused on the difference -- specially because they are both .wasm I think.

view this post on Zulip Lorenzo (Feb 04 2025 at 08:18):

I have been working on migrating my application from wasm core modules + protobuf to just wasm components. I really like the design of components (even if all the tools are a bit overwhelming to understand at first lol) -- so many great use cases for this. I wish I had looked more into components before I went the protobuf route a few months ago haha

view this post on Zulip Notification Bot (Feb 04 2025 at 08:19):

Lorenzo has marked this topic as resolved.

view this post on Zulip Victor Adossi (Feb 04 2025 at 08:51):

I don't think it has to be a one or the other! They work great together :)

IMO WIT is a higher level than protobuf, because it does not specify things like binary encoding, so it's the more general tool. There's no reason you can't use them together!

If you run into any documentation that would have helped you figure this out faster, please feel free to point it out (or even update/send a PR if you have the time!)

view this post on Zulip Lorenzo (Feb 04 2025 at 09:27):

Yeah I agree re protobuf & WIT. I replaced protobuf in my case because the only reason I was using it was for serializing data from/to wasm, but WIT already does that, plus wasm-to-wasm calls so there's no reason for me to keep protobuf I don't think.

I'll definitely try to help contribute to docs as much as I can. I opened a PR into the component-docs repo making some adjustments to the Go example :)

view this post on Zulip Ralph (Feb 04 2025 at 17:49):

@Victor Adossi I'd like you to elaborate on "While you can use it however you'd want, I like to think of the ability to push a component to a registry to be for types-only components -- not components that are fully built with functionality as well (though of course the tooling will work with both." While that would be an OBVIOUS reason to push a component, I would think there would be several different implementations of wasi:sql or wasi:messaging, for example, that would be pushed in order to use.

view this post on Zulip Ralph (Feb 04 2025 at 17:49):

Are you thinking about it differently?

view this post on Zulip Lorenzo (Feb 05 2025 at 00:35):

Well in my case I actually require both the WIT and the component binary. So naturally I thought I could publish only the binary, and users that need only the WIT (for generating type bindings for example) can use tooling to extract just that, but the tooling doesn't seem to work this way -- where you can usetypes.wit or types.wasm you can't use component.wasm, it doesn't work, for example wkg wit build or wkg wit fetch will fail. I think it's possible to make it work though, and would make things much more intuitive.

Let me explain further:

1 - from the perspective of a user/developer writing a component, you start by writing your .wit which may import dependencies and then you generate typings for those dependencies in your preferred language, then you can start implementing the component. To generate these typings, you need the .wits

2 - from the perspective of building & running a component, the wasm component binary of all dependencies are required so that it can be composed (or alternatively linked at runtime by the host implementation -- which is what I'm doing)

Publishing a single package as a component (rather than two packages, component + WIT) would serve both of these points.

My confusion here comes from my first attempt to publish a component, then to consume it as a dependency by doingwkg wit build but that failed and I wasn't able to generate go typings from the published component.wasm.

I had to publish only the wit for wkg wit build to work from the dependent project. I am able to generate go typings by running:

# published & depends on a  WIT package (not component.wasm)
wkg wit build
# WIT package written to example:component.wasm
wit-bindgen-go generate example:component.wasm
# successfully generated types

So basically I'm trying to find out if there a way to extract the equivalent of the file outputted by wkg wit build from a component.wasm? Because I'm not able to generate typings (nor run wkg wit build itself) if my package points to a component.wasm dependency rather than a WIT. I suspect because there is some renaming of namespaces when you build a component, namely the package becomes root:component -- so it's no longer equivalent to the WIT package.

To me it seems like a component.wasm should be fully interchangeable with its WIT package but that doesn't seem to be the case currently across the tooling. I think it would make things much more intuitive for users if that were the case, and to me it seems possible and just a matter of updating the metadata or perhaps adding a new keyword to WIT to resolve it.

Curious if anyone has any thoughts on this.

view this post on Zulip Victor Adossi (Feb 05 2025 at 04:09):

Ralph said:

Victor Adossi I'd like you to elaborate on "While you can use it however you'd want, I like to think of the ability to push a component to a registry to be for types-only components -- not components that are fully built with functionality as well (though of course the tooling will work with both." While that would be an OBVIOUS reason to push a component, I would think there would be several different implementations of wasi:sql or wasi:messaging, for example, that would be pushed in order to use.

Ah I think this might be a misunderstanding -- I mean that specifically for @Lorenzo 's use case. It's not that you shouldn't push functionality to a registry, it's that you shouldn't wkg wit publish a "functional" (i.e. composed/non-composed/optimized) component if you intend to use it "for" types.

There's a sort of implicit difference between components that hold functionality and ones that exist to mostly hold WIT.

Agree that there should and will be different implementations of wasi:* or any-ns:any-package now and in the future, but when you want to pull the actual interface (for example with wkg wit fetch you're going to want to pull the WIT-only version to to build your project against). Once you want to actually compose functionality in, then you need the versions with the functionality (which have to agree on the likely types-only WIT contract).

Trying to use the "implementation" component for everything leads to a very interesting versioning problem -- given company:msg-impl@0.2.0, which version of wasi:messaging does it use? Moving between versions could introduce type changes from the underlying contract (that just happens to be used in company:msg-impl (of course you'd run into the problem Lorenzo ran into first, before you even had that problem).

So that's why for me it seems like there's an important difference here between WASMs that just hold WITs and WASMs that hold WIT and functionality.

@Lorenzo Regarding your post afterwards -- we're certainly open to issues and PRs! Maybe it should work that way (maybe it should be easier to "extract" WIT from functional WASMs for use when pulling a dep) -- the information is already there after all, it's just renamed due to the build/composition process.

Agreed that publishing as a single package would definitely be more convenient, but see the versioning issue I mentioned above -- schemas and implementations should likely be kept intentionally separate, IMO. Definitely open to thinking of a work flow that could make this intuitively work though.

Note that component.wasm has the same exact information as wkg wit build, the problem is that the output world is just renamed because there is one root world (last paragraph there). This possibly could be changed, but definitely some discussion on this discontinuity is worth discussing!

Repository for design and specification of the Component Model - WebAssembly/component-model

view this post on Zulip Victor Adossi (Feb 05 2025 at 04:09):

IMO making an issue (on the component model repo??) would be a great place to start and get discussion going

view this post on Zulip Lorenzo (Feb 05 2025 at 04:36):

Thanks @Victor Adossi! I'll look into opening an issue for this :)

I understand the versioning issues you mentioned.

The approach I am going to use with my application is to, for each component, publish every WIT & component impl under 2 different namespaces, for example company:msg for the WIT and company-component:msg for the implementation -- so the company-component namespace holds implementations and company holds WITs. I wonder if this is a common pattern used by people.

view this post on Zulip Lorenzo (Feb 05 2025 at 04:45):

If the versioning issue can be resolved in a simple & elegant way, then for use cases such as mine only the implementation could be published to the registry (inherently containing the WIT as well). It would be even better if wkg wit build & other commands that only need WIT could then download only the WIT information, to not waste bandwidth on the implementation.

view this post on Zulip Victor Adossi (Feb 05 2025 at 09:19):

Lorenzo said:

Thanks Victor Adossi! I'll look into opening an issue for this :)

I understand the versioning issues you mentioned.

The approach I am going to use with my application is to, for each component, publish every WIT & component impl under 2 different namespaces, for example company:msg for the WIT and company-component:msg for the implementation -- so the company-component namespace holds implementations and company holds WITs. I wonder if this is a common pattern used by people.

Yep this seems fine -- I'm wondering if you could have company:package and company:components-<name-of-component or something like that might make more sense, if components have well defined names.

I think it's kind of awkward to try to represent implementations of WIT interfaces behind the namespace/package mechanism -- it kind of wasn't meant for that. wkg has evolved support for OCI registries because storing runnable artifacts is a much better fit for an OCI registry (where the "namespace" is your.registry.io/whatever/org/structure/you/want/component:0.1.0)

At Cosmonic (we build wasmCloud) at least, we push both our WITs and our runnable components to OCI registries and are happy with that setup. When it's time to wkg wit fetch we can do that (and we fetch the types-only component), and when it's time to publish something runnable we publish (and @ runtime we refer to the OCI address).

view this post on Zulip Victor Adossi (Feb 05 2025 at 09:23):

Lorenzo said:

If the versioning issue can be resolved in a simple & elegant way, then for use cases such as mine only the implementation could be published to the registry (inherently containing the WIT as well). It would be even better if wkg wit build & other commands that only need WIT could then download only the WIT information, to not waste bandwidth on the implementation.

I think this could definitely work -- a few new flags on wkg wit publish (ex. --wit-only) could probably make this happen.

Speaking of which, did you try wkg publish --package <your package name> ? I'm probably a bit late in asking, but usually when you wkg publish a WASM file, you can choose which package you want to send along., and actually wkg will only send *that* package.

Contribute to bytecodealliance/wasm-pkg-tools development by creating an account on GitHub.

view this post on Zulip Victor Adossi (Feb 05 2025 at 09:24):

You can see in that code the delineation between a component and a WIT package (which I've been calling a "types only component")


Last updated: Feb 28 2025 at 03:10 UTC