We have made the choice to use existing package managers for distributing WESL code.
One currently unanswered question is how exactly such a WESL project on npm or cargo (or another package manager) should look like.
The first observation is that pre-compiling everything to WGSL would not not, because we want to be able to share dependencies. (e.g. An "assert" library can be a dependency of multiple libraries that we are using)
The second observation is that we need to compile
Our own code
The WESL code of direct dependencies (imported libraries)
The WESL code of indirect dependencies (when a library imports another library)
How do we figure out what these indirect dependencies are? Do we inspect the libraries and re-implement the Cargo/npm/... resolution algorithms?
Or do we let the languages do the job for us? For example, a typical Rust project would use Cargo and a WESL-compiler that can be called from Rust. The Rust project would start the WESL-compilation from a build script or proc macro.
So we could make the build script do the following
use bevy_pbr::wesl_code;
use wesl_compiler::compile;
fn main() {
let code = wesl_code();
let generated = compile(code);
}
And in turn, bevy_pbr would have
use wesl_assert::wesl_code;
fn wesl_code() -> &'static ... {
// Expose the code
// Expose the dependencies! <===
// Expose an ID for deduplication purposes
// Expose the config (no need for a TOML parser, we could just directly expose an object that has the config settings)
}
With that setup, we solve the problem of finding indirect dependencies, and very nicely integate into our host languages (Rust, Typescript, ...).
The big catch is that a language server essentially needs to run the code of the host languages. But the alternative of correctly doing package resolution is also nontrivial.
We have made the choice to use existing package managers for distributing WESL code.
One currently unanswered question is how exactly such a WESL project on npm or cargo (or another package manager) should look like.
The first observation is that pre-compiling everything to WGSL would not not, because we want to be able to share dependencies. (e.g. An "assert" library can be a dependency of multiple libraries that we are using)
The second observation is that we need to compile
How do we figure out what these indirect dependencies are? Do we inspect the libraries and re-implement the Cargo/npm/... resolution algorithms? Or do we let the languages do the job for us? For example, a typical Rust project would use Cargo and a WESL-compiler that can be called from Rust. The Rust project would start the WESL-compilation from a build script or proc macro.
So we could make the build script do the following
And in turn, bevy_pbr would have
With that setup, we solve the problem of finding indirect dependencies, and very nicely integate into our host languages (Rust, Typescript, ...).
The big catch is that a language server essentially needs to run the code of the host languages. But the alternative of correctly doing package resolution is also nontrivial.