diff --git a/design/mvp/WIT.md b/design/mvp/WIT.md index 43a1c1e7..7ee0df20 100644 --- a/design/mvp/WIT.md +++ b/design/mvp/WIT.md @@ -661,6 +661,80 @@ world w2 { > configure that a `use`'d interface is a particular import or a particular > export. +## Unlocked Dependency Imports + +When working with a registry, the keyword `unlocked-dep` is available to specify dependencies with package name and version requirements. For example: + +```wit +world w { + unlocked-dep foo:bar@{>=x.x.x =1.2.0}; +} +``` + +Now say that `foo:bar@1.2.0` implements the following `exports` interface: +```wit +package foo:bar@1.2.0; +interface exports { + calc: func(x: u64) -> u64; +} +``` + +The next step is to expand `generated-world` with nested packages fetched from all the relevant registries, producing an all-in-one WIT file with no external references: +```wit +package my:component; + +package wasi:http@0.2.0 { + ... + world proxy { ... } +} + +package foo:bar@1.2.0 { + interface exports { + calc: func(x: u64) -> u64; + } +} + +world generated-world { + include wasi:http/proxy@0.2.0; + unlocked-dep foo:bar/exports@{>=1.2.0}; +} +``` +Note that `exports` is an arbitrary name and can be anything because the WIT bindings generation will always strip off the final interface name, leaving only the package name. In particular, the Component Model type for this world is: +```wat +(component + (import "wasi:http/types@0.2.0" (instance ...)) + (import "wasi:http/outgoing-handler@0.2.0" (instance ...)) + (import "unlocked-dep==1.2.0}>" (instance + (export "calc" (func (param "x" u64) (result u64))) + )) + (export "wasi:http/incoming-handler@0.2.0" (instance ...)) +) +``` + +A wasm component that contains `unlocked-dep` imports is referred to as an "unlocked component". Unlocked components are what you normally would want to publish to a registry, since it allows users of the unlocked component to perform the final dependency solving across a DAG of components. ## WIT Functions [functions]: #wit-functions