Are multiple identical imports with different aliases possible / a goal?
I came across the use case in the wasmCloud runtime linking docs.
Excerpt:
For example, a component may use the
wasi:keyvalueinterface to link to both a local key-value cache for ephemeral storage and a cloud-based store for more resilient storage. In this example, you're using the same key-value interface and the same operations, but the interface needs to be configured differently. These different configurations of the interface can be differentiated with a link name.
Wouldn't this be better standardized as native component model functionality, avoiding different vendor solutions? Perhaps by giving imports names or aliases somehow? One must be able to determine which storage import (local or cloud-based) is used in the language bindings/source code.
Using the LEGO brick terminology which is popular for illustrating wasm component imports/exports: when giving imports names or aliases, each aliased import get its own tube/socket that must be filled separately.
Did this make sense? Perhaps it could be done another way, but I think solving the use case in wit/wasm components is reasonable..?
Hi, great question, and agreed! IIUC, the root issue you're rasising is that it's only possible to import a given interface name (like wasi:keyvalue/store) once in a given world (due to the requirements of name-uniqueness). This was raised earlier in #287 and my current best proposal on the WIT- and WAT-level generalization to support this use case is in https://github.com/WebAssembly/component-model/issues/287#issuecomment-2738173706. I think this is a practical necessity so I'd like to push to include it before declaring a 1.0-rc. If anyone wants to work on tooling support for this, I'm happy to work up a PR to support.
@lukewagner thanks - yes, that's the issue (and this can be closed as a duplicate- perhaps #287's title could be changed to reflect the use case)
One thing I'd really like to keep with this feature, is how targeting wasm+wasi for e.g. a .NET project will transparently use the wasi interfaces and not require code changes.
Assume a project today use two volumes/disks: one local temp disk and another remote cloud disk. They both would be rewritten by the .NET compiler(i think?) to use wasi:filesystem, there is only one import in the component so one can not easily have two different disks.
For this use case to work in the same automatic way when targeting wasm, some annotation in the source code is required to point to the right name (one or two in your example). .NET/c# could for example require a wasm/wit-specific attribute with the name.
I just hope naming interfaces (when it is added to the component model) will (still) make it easy to target wasm with no or minimal source code changes. Ideally, any source code changes should be annotations and not affect non-wasm builds.
perhaps https://github.com/WebAssembly/component-model/issues/287's title could be changed to reflect the use case)
Yes, good idea, done.
They both would be rewritten by the .NET compiler(i think?) to use wasi:filesystem, there is only one import in the component so one can not easily have two different disks.
Filesystems are a somewhat special case since, as you said, they are used ubiquitously and there is an ambient assumption that there is only one. In your example where there are two disk imports, probably the best way to achieve source compatibility is to virtualize a single filesystem with the two disks mounted at different directories using a tool like wasi-virt (which can't do exactly this today, but I think should be extended over time so that many different kinds of WASI interfaces can be "mounted").
@lukewagner Yes, you're right, that's more natural for filesystem.
I tried to find a use case where annotating with the alias/name in source code would be helpful, but so far I can't think of any.
Perhaps it is only used when linking /composing components?
Going back to the kv-store example, where you have:
world w {
import redis: wasi:keyvalue/store;
import cosmos: wasi:keyvalue/store;
...
}
it seems useful to have redis.open("my-bucket") vs. cosmos.open("other-bucket") where redis and cosmos are generated bindings and validated to exist by statically-typed languages.