Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f598529
feat(p2-shim): improve browser support
vados-cosmonic Aug 3, 2026
409831c
fix(p2-shim): close browser io and clock gaps
vados-cosmonic Aug 22, 2026
f72da38
docs: mark browser support as supported
vados-cosmonic Aug 22, 2026
d3322c3
test(transpile): consolidate browser harness
vados-cosmonic Aug 24, 2026
d2659c3
fix(p2-shim): create only final filesystem paths
vados-cosmonic Aug 24, 2026
1b48b62
fix(p2-shim): preserve filesystem rename invariants
vados-cosmonic Aug 24, 2026
04b4ac8
fix(p2-shim): share browser filesystem identity
vados-cosmonic Aug 24, 2026
7c8e0ad
fix(p2-shim): wake invalidated browser pollables
vados-cosmonic Aug 24, 2026
498342f
fix(p2-shim): await browser HTTP request bodies
vados-cosmonic Aug 24, 2026
6b6294e
fix(p2-shim): align browser HTTP request options
vados-cosmonic Aug 24, 2026
d6c3f18
fix(p2-shim): expose browser incoming HTTP handlers
vados-cosmonic Aug 24, 2026
d98c768
fix(p2-shim): isolate sandbox network capabilities
vados-cosmonic Aug 24, 2026
a3554c8
fix(p2-shim): delegate preopens to filesystem factories
vados-cosmonic Aug 24, 2026
57f0ff2
docs(p2-shim): detail browser capability support
vados-cosmonic Aug 24, 2026
3fd64a7
fix(p2-shim): yield browser tasks from ready polls
vados-cosmonic Aug 24, 2026
dc022d2
test(p2-shim): release browser harness resources
vados-cosmonic Aug 24, 2026
0046521
fix(p2-shim): remove obsolete body helper
vados-cosmonic Aug 24, 2026
bfd01f6
feat(p2-shim): allow browser request streaming
vados-cosmonic Aug 24, 2026
8d28cc5
refactor(p2-shim): name HTTP authority patterns
vados-cosmonic Aug 24, 2026
685f0e8
test(p2-shim): exercise Chromium request streaming
vados-cosmonic Aug 24, 2026
040b19b
feat(p2-shim): delegate custom filesystem preopens
vados-cosmonic Aug 24, 2026
86f1adc
test(p2-shim): add Map filesystem example
vados-cosmonic Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Features

- [Transpiling](./transpiling.md) Wasm Component binaries into [ECMAScript modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules) that can run in any JavaScript environment.
- WASI Preview2 support in Node.js & browsers (experimental).
- WASI Preview2 support in Node.js & browsers.
- Component builds of Wasm Tools helpers, available for use as a library or CLI commands for use in native JS environments
- Optimization helper for Components via Binaryen.
- `componentize` command to easily create components written in JavaScript (wrapper of [ComponentizeJS](https://github.com/bytecodealliance/ComponentizeJS)).
Expand Down
3 changes: 2 additions & 1 deletion docs/src/transpiling.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ For all subsystems - `cli`, `clocks`, `filesystem`, `http`, `io`, `random` and `

To disable this automatic WASI handling the `--no-wasi-shim` flag can be provided and WASI will be treated like any other import without special handling.

Note that browser support for WASI is currently experimental.
Browser WASI support is subject to web-platform capability limitations; some interfaces require
application-provided adapters.

### Interface Implementation Example

Expand Down
2 changes: 1 addition & 1 deletion examples/components/fs-write-file/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pnpm install
At this point, since this project is *just* NodeJS, you could use the module from any NodeJS project or browser project where appropriate.

That said, we'll be focusing on building the JS code we've written so far into a WebAssembly binary, which can run *anywhere*
WebAssembly runtimes are supported, including in other languages, and the browser (experimental support).
WebAssembly runtimes are supported, including in other languages and the browser.

## Building the WebAssembly component

Expand Down
3 changes: 0 additions & 3 deletions examples/transpile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ This folder contains examples of how to use `@bytecodealliance/jco-transpile` di
converting a WebAssembly component into a Javascript ES module that can be run from JS
runtimes like [NodeJS][nodejs] and the browser.

> [!WARNING]
> Browser support is still experimental

Most (if not all) individual example projects are standard Javascript projects, and since we are focused on
transpiling existing components, they may contain a pre-built WebAssembly binary that is transpiled.

Expand Down
3 changes: 0 additions & 3 deletions packages/jco-std/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ an evolving architecture for interoperabl WebAssembly libraries, aplications and
WebAssembly components can be used from server side applications _and_ in the browser, and
`@bytecodealliance/jco-std` contains shared functionality and helpers for both environments.

> [!WARNING]
> Browser support is considered experimental, and not currently suitable for production applications.

[cm-book]: https://component-model.bytecodealliance.org/
[jco]: https://www.npmjs.com/package/@bytecodealliance/jco

Expand Down
5 changes: 1 addition & 4 deletions packages/jco-transpile/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# `@bytecodealliance/jco-transpile`

This [`@bytecodealliance/jco`][jco] sub-project enables transpilation of [WebAssembly Components][cm-book] into ES modules
that can be run in Javascript environments like NodeJS and the browser (experimental).
that can be run in Javascript environments like NodeJS and the browser.

`@bytecodealliance/jco-transpile` is used primarily when only transpilation functionality of `jco` is needed,
and `jco` derives it's use of transpilation from this library.

> [!WARNING]
> Browser support is considered experimental, and not currently suitable for production applications.

[cm-book]: https://component-model.bytecodealliance.org/
[jco]: https://www.npmjs.com/package/@bytecodealliance/jco

Expand Down
59 changes: 59 additions & 0 deletions packages/jco-transpile/test/browser/cases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { $init, generate as _generate } from '../../vendor/js-component-bindgen-component.js';

await $init;

const wasiMap = [
['wasi:cli/*', '@bytecodealliance/preview2-shim/cli#*'],
['wasi:clocks/*', '@bytecodealliance/preview2-shim/clocks#*'],
['wasi:filesystem/*', '@bytecodealliance/preview2-shim/filesystem#*'],
['wasi:http/*', '@bytecodealliance/preview2-shim/http#*'],
['wasi:io/*', '@bytecodealliance/preview2-shim/io#*'],
['wasi:random/*', '@bytecodealliance/preview2-shim/random#*'],
['wasi:sockets/*', '@bytecodealliance/preview2-shim/sockets#*'],
];

export async function transpile() {
const componentUrl = new URL('../fixtures/components/runtime/lists.component.wasm', import.meta.url);
const component = await (await fetch(componentUrl)).arrayBuffer();
const output = await _generate(component, {
name: 'test',
noTypescript: true,
noNodejsCompat: true,
instantiation: { tag: 'async' },
base64Cutoff: 1_000_000,
map: wasiMap,
});
const source = output.files.find(([name]) => name === 'test.js')?.[1];
if (!source) {
throw new Error(`transpile output did not contain test.js: ${output.files.map(([name]) => name)}`);
}

const url = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
try {
await import(url);
} finally {
URL.revokeObjectURL(url);
}
}

export async function jspi(modulePath) {
const module = await import(modulePath);
const instance = await module.instantiate(undefined, {
'something:test/test-interface': {
callAsync: () => new Promise((resolve) => setTimeout(() => resolve('callAsync'), 50)),
callSync: () => 'callSync',
},
});

let ticks = 0;
const interval = setInterval(() => ticks++, 5);
try {
const responseText = await instance.runAsync();
if (ticks < 2) {
throw new Error(`event loop was blocked during JSPI call; observed only ${ticks} ticks`);
}
return { responseText };
} finally {
clearInterval(interval);
}
}
179 changes: 0 additions & 179 deletions packages/jco-transpile/test/browser/general.ts

This file was deleted.

52 changes: 52 additions & 0 deletions packages/jco-transpile/test/browser/harness.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!doctype html>
<meta charset="utf-8" />
<title>jco browser test</title>
<script type="importmap">
{
"imports": {
"@bytecodealliance/preview2-shim/cli": "../../../preview2-shim/dist/browser/cli.js",
"@bytecodealliance/preview2-shim/clocks": "../../../preview2-shim/dist/browser/clocks.js",
"@bytecodealliance/preview2-shim/filesystem": "../../../preview2-shim/dist/browser/filesystem.js",
"@bytecodealliance/preview2-shim/http": "../../../preview2-shim/dist/browser/http.js",
"@bytecodealliance/preview2-shim/io": "../../../preview2-shim/dist/browser/io.js",
"@bytecodealliance/preview2-shim/random": "../../../preview2-shim/dist/browser/random.js",
"@bytecodealliance/preview2-shim/sockets": "../../../preview2-shim/dist/browser/sockets.js"
}
}
</script>
<body>
<h1>Running</h1>
<script type="module">
const params = new URLSearchParams(location.hash.slice(1));

window.__jcoTest = (async () => {
try {
const modulePath = params.get('module');
const exportName = params.get('export') ?? 'test';
const args = JSON.parse(params.get('args') ?? '[]');
if (!modulePath) throw new Error('missing browser test module');

const module = await import(modulePath);
const test = module[exportName];
if (typeof test !== 'function') {
throw new Error(
`Expected ${JSON.stringify(modulePath)} to export ${JSON.stringify(exportName)}; found [${Object.keys(module)}]`,
);
}

return { ok: true, value: await test(...args) };
} catch (error) {
return {
ok: false,
error: {
name: error?.name ?? 'Error',
message: error?.message ?? String(error),
stack: error?.stack,
},
};
}
})();

document.body.textContent = JSON.stringify(await window.__jcoTest);
</script>
</body>
Loading
Loading