Crate modularity

Source
Expand description

modularity is a bare-bones library for loading and linking WebAssembly components. It serves as a foundation for WASM-based plugin and modding systems by providing the following functionality:

  • Resolving dependency graphs of WASM packages from arbitrary sources
  • Instantiating WASM packages with imports from other components and the host
  • Allowing the host to inspect and call package exports

§Usage

The example below illustrates how to use this crate. A complete version may be found in the examples folder. It first creates a PackageResolver, specifying the list of packages that the application desires to load. Then, it repeatedly calls PackageResolver::resolve, supplying new components whenever the resolver reports that it needs them. Once the resolver has finished building the dependency graph, it produces a PackageContextImage. The image is subsequently applied to the PackageContext, where all of the components are linked and instantiated. After this, the package exports may be accessed through the context.

// Create the WASM engine and store
let engine = Engine::new(wasmi::Engine::default());
let mut store = Store::new(&engine, ());

// Create a context to hold packages
let mut ctx = PackageContext::default();

// Create a resolver with the list of top-level dependencies
let mut resolver = Some(PackageResolver::new(package_ids), Linker::default());

while let Some(r) = take(&mut resolver) {
    match r.resolve() {
        Ok(x) => {
            // Create a transition to move the context to the new set of packages
            // The linking process can be customized here
            let transition = PackageContextTransitionBuilder::new(&x, &ctx)
                .build(&mut store, &ctx)
                .unwrap();

            // Apply the transition to the package context
            transition.apply(&mut store);

            println!("Loaded packages are {:?}", ctx.packages().collect::<Vec<_>>());
        }
        Err(PackageResolverError::MissingPackages(mut r)) => {
            for u in r.unresolved() {
                // Gets the component with the specified ID from a source
                u.resolve(u.id(), get_package(&u));
            }
            resolver = Some(r);
        }
        x => panic!("Error occurred: {x:?}"),
    }
}

modularity relies on the wasm_component_layer crate for creating loaded WASM modules. It is the responsibility of the consumer to supply parsed wasm_component_layer::Component instances from a source.

Structs§

LoadedPackage
Represents an instantiated WebAssembly component that is owned by a PackageContext.
PackageBuildOptions
Determines how a package’s component should be instantiated and linked.
PackageContext
Manages a set of loaded WebAssembly components. PackageContexts are responsible for loading, linking, and unloading packages to match the state described by a PackageContextImage. Contexts also provide access to the exports of loaded packages.
PackageContextImage
Describes a target state which can be applied to a PackageContext. Each PackageContextImage is an instantaneous “snapshot” of what a context should look like after loading and unloading the requisite packages.
PackageContextTransition
Describes how to move a context between two PackageContextImages.
PackageContextTransitionBuilder
Facilitates the creation of new PackageContextTransitions, which switch the PackageContextImage upon which a context is based.
PackageInstantiationError
Provides information about a package that could not be instantiated.
PackageResolver
Builds a package dependency graph which can be converted to a PackageContextImage.
UnresolvedPackage
Denotes a package that must be supplied for resolution to continue.

Enums§

PackageResolverError
Describes an issue with package dependency resolution.