diff --git a/component-model/book.toml b/component-model/book.toml index 74f0eaf2..047ccfbf 100644 --- a/component-model/book.toml +++ b/component-model/book.toml @@ -8,7 +8,8 @@ title = "The WebAssembly Component Model" [output.html] git-repository-url = "https://github.com/bytecodealliance/component-docs/tree/main/component-model" edit-url-template = "https://github.com/bytecodealliance/component-docs/tree/main/component-model/{path}" -additional-css = ["theme/head.hbs"] +additional-css = ["theme/head.hbs", "theme/tabs.css", "theme/version-notice.css"] +additional-js = ["theme/tabs.js"] [output.html.fold] enable = true @@ -34,4 +35,6 @@ level = 1 [preprocessor.alerts] +[preprocessor.tabs] + [output.linkcheck] diff --git a/component-model/src/running-components/wasmtime.md b/component-model/src/running-components/wasmtime.md index 4272725c..79bb781d 100644 --- a/component-model/src/running-components/wasmtime.md +++ b/component-model/src/running-components/wasmtime.md @@ -1,9 +1,25 @@ # Wasmtime +
+ +This page has content for both **WASI P2** and **WASI P3**. Use the tabs below to switch between versions where they differ. + +
+ +{{#tabs global="wasi-version" }} +{{#tab name="WASI P2" }} [Wasmtime](https://github.com/bytecodealliance/wasmtime/) is the reference implementation of the Component Model. -It supports running components that implement the [`wasi:cli/command` world](https://github.com/WebAssembly/wasi-cli/blob/main/wit/command.wit) -and serving components that implement the [`wasi:http/proxy` world](https://github.com/WebAssembly/wasi-http/blob/main/wit/proxy.wit). +It supports running components that implement the [`wasi:cli/command` world](https://github.com/WebAssembly/WASI/blob/main/proposals/cli/wit/command.wit) +and serving components that implement the [`wasi:http/proxy` world](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit/proxy.wit). Wasmtime can also invoke functions exported from a component. +{{#endtab }} +{{#tab name="WASI P3" }} +[Wasmtime](https://github.com/bytecodealliance/wasmtime/) is the reference implementation of the Component Model. WASI P3 runtime support is available in Wasmtime 43 and later, which implements the WASI 0.3 ABI (`async func`, `stream`, `future`). + +It supports running components that implement the [`wasi:cli/command` world](https://github.com/WebAssembly/WASI/blob/main/proposals/cli/wit-0.3.0-draft/command.wit). Support for serving components in the [`wasi:http/service` world](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit-0.3.0-draft/worlds.wit) and the new [`wasi:http/middleware` world](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit-0.3.0-draft/worlds.wit), which both imports and exports the HTTP handler interface, is in development. See [the tracking issue](https://github.com/bytecodealliance/wit-bindgen/issues/1554) for current status. +Wasmtime can also invoke functions exported from a component. +{{#endtab }} +{{#endtabs }} ## Running command components with Wasmtime To run a command component with Wasmtime, execute: @@ -21,8 +37,10 @@ See the [Wasmtime guide](https://docs.wasmtime.dev/) for information on granting ## Running HTTP components with Wasmtime -You can execute components that implement the [HTTP proxy world](https://github.com/WebAssembly/wasi-http/blob/main/wit/proxy.wit) with the `wasmtime serve` subcommand. -[The Wasmtime CLI](https://github.com/bytecodealliance/wasmtime) supports serving these components as of `v14.0.3`. +{{#tabs global="wasi-version" }} +{{#tab name="WASI P2" }} +You can execute components that implement the [HTTP proxy world](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit/proxy.wit) with the `wasmtime serve` subcommand. +[The Wasmtime CLI](https://github.com/bytecodealliance/wasmtime) supports serving these components as of `v18.0.0`. To run a HTTP component with Wasmtime, execute: ```sh @@ -34,6 +52,13 @@ Try out building and running HTTP components with one of these tutorials 1. [Hello WASI HTTP tutorial](https://github.com/sunfishcode/hello-wasi-http) - build and serve a simple Rust-based HTTP component 2. [HTTP Auth Middleware tutorial](https://github.com/fermyon/http-auth-middleware#running-with-wasmtime) - compose a HTTP authentication middleware component with a business logic component +{{#endtab }} +{{#tab name="WASI P3" }} +Wasmtime 43 and later provide runtime support for the WASI P3 ABI. The `wasmtime serve` subcommand currently targets the [`wasi:http/proxy` world](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit/proxy.wit) from WASI P2; support for serving components in the WASI P3 [`wasi:http/service`](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit-0.3.0-draft/worlds.wit) and [`wasi:http/middleware`](https://github.com/WebAssembly/WASI/blob/main/proposals/http/wit-0.3.0-draft/worlds.wit) worlds is in progress. See [the tracking issue](https://github.com/bytecodealliance/wit-bindgen/issues/1554) for current status. + +For an overview of the WASI P3 HTTP interfaces, see [WASI 0.3](https://wasi.dev/releases/wasi-p3) on WASI.dev. +{{#endtab }} +{{#endtabs }} ## Running components with custom exports diff --git a/component-model/theme/tabs.css b/component-model/theme/tabs.css new file mode 100644 index 00000000..61cda923 --- /dev/null +++ b/component-model/theme/tabs.css @@ -0,0 +1,52 @@ +.mdbook-tabs { + display: flex; + border-bottom: 1px solid var(--table-border-color); +} + +.mdbook-tab { + background-color: var(--table-alternate-bg); + color: var(--fg); + padding: 0.5rem 1rem; + cursor: pointer; + border: none; + border-bottom: 2px solid transparent; + font-size: 1.6rem; + line-height: 1.45em; +} + +@media (prefers-reduced-motion: no-preference) { + .mdbook-tab { + transition: color 120ms ease, border-color 120ms ease; + } +} + +.mdbook-tab:hover:not(.active) { + color: var(--sidebar-active, var(--fg)); +} + +.mdbook-tab.active { + background-color: var(--table-header-bg); + color: var(--sidebar-active, var(--fg)); + border-bottom-color: var(--sidebar-active, var(--fg)); + font-weight: bold; +} + +/* Rust theme: --sidebar-active (#e69f67) has low contrast against the warm + tan tab backgrounds. Fall back to --fg for the label text; the accent + color still carries the active signal via the bottom border. */ +.rust .mdbook-tab.active { + color: var(--fg); +} + +.rust .mdbook-tab:hover:not(.active) { + color: var(--fg); + border-bottom-color: var(--sidebar-active, var(--fg)); +} + +.mdbook-tab-content { + padding: 1rem 0rem; +} + +.mdbook-tab-content table { + margin: unset; +} diff --git a/component-model/theme/tabs.js b/component-model/theme/tabs.js new file mode 100644 index 00000000..8d335667 --- /dev/null +++ b/component-model/theme/tabs.js @@ -0,0 +1,75 @@ +/** + * Change active tab of tabs. + * + * @param {Element} container + * @param {string} name + */ +const changeTab = (container, name) => { + for (const child of container.children) { + if (!(child instanceof HTMLElement)) { + continue; + } + + if (child.classList.contains('mdbook-tabs')) { + for (const tab of child.children) { + if (!(tab instanceof HTMLElement)) { + continue; + } + + if (tab.dataset.tabname === name) { + tab.classList.add('active'); + } else { + tab.classList.remove('active'); + } + } + } else if (child.classList.contains('mdbook-tab-content')) { + if (child.dataset.tabname === name) { + child.classList.remove('hidden'); + } else { + child.classList.add('hidden'); + } + } + } +}; + +document.addEventListener('DOMContentLoaded', () => { + const tabs = document.querySelectorAll('.mdbook-tab'); + for (const tab of tabs) { + tab.addEventListener('click', () => { + if (!(tab instanceof HTMLElement)) { + return; + } + + if (!tab.parentElement || !tab.parentElement.parentElement) { + return; + } + + const container = tab.parentElement.parentElement; + const name = tab.dataset.tabname; + const global = container.dataset.tabglobal; + + changeTab(container, name); + + if (global) { + localStorage.setItem(`mdbook-tabs-${global}`, name); + + const globalContainers = document.querySelectorAll( + `.mdbook-tabs-container[data-tabglobal="${global}"]` + ); + for (const globalContainer of globalContainers) { + changeTab(globalContainer, name); + } + } + }); + } + + const containers = document.querySelectorAll('.mdbook-tabs-container[data-tabglobal]'); + for (const container of containers) { + const global = container.dataset.tabglobal; + + const name = localStorage.getItem(`mdbook-tabs-${global}`); + if (name && document.querySelector(`.mdbook-tab[data-tabname="${name}"]`)) { + changeTab(container, name); + } + } +}); diff --git a/component-model/theme/version-notice.css b/component-model/theme/version-notice.css new file mode 100644 index 00000000..5ae986dd --- /dev/null +++ b/component-model/theme/version-notice.css @@ -0,0 +1,37 @@ +.version-notice { + display: flex; + align-items: flex-start; + gap: 0.75rem; + padding: 0.75rem 1rem 0.75rem 1.25rem; + margin: 0 0 1.5rem 0; + background-color: var(--quote-bg); + border-left: 4px solid var(--sidebar-active, var(--fg)); + border-radius: 0 4px 4px 0; + font-size: 0.95em; + line-height: 1.5; +} + +.version-notice::before { + content: ""; + flex-shrink: 0; + width: 1.15em; + height: 1.15em; + margin-top: 0.15em; + background-color: var(--sidebar-active, var(--fg)); + -webkit-mask-image: url("data:image/svg+xml;utf8,"); + mask-image: url("data:image/svg+xml;utf8,"); + -webkit-mask-size: contain; + mask-size: contain; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; +} + +.version-notice > *:first-child { + margin-top: 0; +} + +.version-notice > *:last-child { + margin-bottom: 0; +}