jco

repository·main·Indexed 21 days ago

https://github.com/bytecodealliance/jco

A JavaScript-native toolchain for the WebAssembly Component Model. jco allows developers to build WebAssembly components from JavaScript or TypeScript using `jco componentize`, transpile WebAssembly components into JavaScript modules with `jco transpile`, and serve components for local development via `jco serve`. The toolchain includes `js-component-bindgen` for transpiling components into JavaScript and supports WebAssembly Interface Types (WIT) to define component contracts.

Tokens
80.4K
Snippets
310
Records
390
Agent score
75%

What's inside jco

  1. Overview of Jco capabilities

    main

    Jco is a JavaScript-native toolchain for working with WebAssembly Components. Its primary functions include:

    • Building WebAssembly components from JavaScript/TypeScript using componentize-js or componentize-qjs.
    • Transpiling WebAssembly components into ES modules for use in environments like NodeJS and browsers.
    • Running WebAssembly components as single-shot applications or web servers (similar to wasmtime run or wasmtime serve).
    • Reusing WebAssembly component workflows within your own JavaScript projects.
    • Utilizing wasm-tools as a library from within JavaScript.
  2. Overview of jco features

    main

    jco is a native tool designed for working with WebAssembly Components in JavaScript environments. Its primary capabilities include:

    • Transpiling: Converts Wasm Component binaries into ECMAScript modules (ESM) compatible with any JavaScript environment.
    • WASI Support: Provides experimental WASI Preview2 support for Node.js and browsers.
    • Wasm Tools Helpers: Offers component builds of Wasm Tools helpers as both a library and CLI commands for native JS environments.
    • Optimization: Includes an optimization helper for Components using Binaryen.
    • Componentization: Provides the componentize command to create WebAssembly components from JavaScript code (this is a wrapper around ComponentizeJS).

    Note: This project is experimental. Stability, security, and support are not guaranteed, and breaking changes may occur without notice.

  3. What is @bytecodealliance/jco-std?

    main

    @bytecodealliance/jco-std is a sub-project of @bytecodealliance/jco that contains shared functionality and reusable libraries for building WebAssembly Components in JavaScript.

    It provides helpers for both server-side and browser environments.

    WARNING

    Browser support is considered experimental and is not currently suitable for production applications.

  4. Overview of JCO Example Components

    main
    The examples/components directory contains various JavaScript projects that demonstrate different ways to use JCO for componentization. These examples cover a range of use cases from simple function exports to complex multi-file TypeScript projects, HTTP servers, and WASI interface implementations. Most examples are standard JavaScript projects compatible with Node.js or the browser.
  5. Explore JCO usage guides

    main

    The jco repository provides a series of guided walkthroughs to help you navigate the JS ecosystem WebAssembly tooling (including jco and componentize-js). These guides cover everything from initial environment setup to advanced component composition.

    Available guides include:

    • Tooling setup: Getting started with the necessary JS WebAssembly tools.
    • Building a Component with jco: A walkthrough for building simple components (e.g., add.wasm).
    • Running components in Javascript: Instructions on how to execute WebAssembly components from within existing JavaScript code.
    • Exporting functionality with rich types: How to export functionality using complex types (e.g., string-reverse.wasm).
    • Importing and reusing components: Advanced patterns for importing and exporting functionality between components (e.g., string-reverse-upper.wasm).
  6. Handle WIT results in JavaScript

    main

    WIT result<T, E> types are handled differently depending on whether they are used in function signatures or stored in containers:

    1. Function Return Values: Jco uses JavaScript exceptions. A successful return is a direct return value, while an error is handled by throw-ing.
      • If a function returns result<string, string>, throwing an error in JS satisfies the err case.
    2. Container Types (Records, Options, etc.): If a result is stored inside another type, it is represented as a variant object: { tag: 'ok', val: T } | { tag: 'err', val: E }.
    3. Host Implementation Tip: When a JS host throws an Error object, Jco can extract the error type if the error has a .payload property. This allows you to throw idiomatic JS errors while still satisfying WIT error types.
    // Function return (Result as exception)
    // WIT: f: func(n: u32) -> result<string, string>;
    function f(n: number): string {
        if (n == 42) {
            return 'correct';
        }
        throw 'not correct';
    }
    
    // Result in a container (Result as variant)
    // WIT: r: func(r: result<string, string>) -> string;
    type Result<T,E> = { tag: 'ok', val: T } | { tag: 'err', val: E };
    
    function f(input: Result<string, string>): string {
      switch (input.tag) {
        case 'ok': return `SUCCESS, returned: [${input.val}]`;
        case 'err': return `ERROR, returned: [${input.val}]`;
        default: throw Error("something has gone seriously wrong");
      }
    }
    
    // Host implementation using Error.payload
    function justThrow() {
        const plainError = new Error('Error for JS users');
        const errorWithPayload = Object.assign(plainError, { payload: 1111 });
        throw errorWithPayload;
    }
  7. Implement ResourceTable for optimized bindgen

    main

    In optimized bindgen, resource handles are managed via ResourceTable, which is implemented as a JS array of integers. This table maps handles to resource IDs (reps).

    Data Structure Details:

    • Storage: Uses a JS array of integers. Each entry is a pair of u32 values.
    • Bit Layout:
      • The lowest 29 bits are used for the value.
      • The bit 1 << 30 is the flag bit for all data values.
      • The highest bit is unused to avoid SMI deoptimization.
    • Free List Entries: The high bit (bit 30) is set to indicate the pair is part of the free list. The first pair (indices 0 and 1) is the head. A value of 0 (after removing the flag) indicates the end of the list.
    • Data Entries: The high bit is NOT set. The first value is the scope (ref count or scope ID) and the second is the rep (resource ID). The second value's high bit indicates if it is an 'own' handle.
    • Indexing: To access handle n, read the pair at n * 2 and n * 2 + 1.
  8. How Hono works with WebAssembly components

    main

    This project demonstrates how to use the Hono web framework within a WebAssembly component. The architecture relies on the following principles:

    1. WASI HTTP Support: Web requests are handled via the wasi:http/incoming-handler interface. When using jco componentize, the StarlingMonkey runtime is used to provide this capability.
    2. Standards Compliance: Hono is highly standards-compliant (following WinterCG/WinterTC), allowing it to run on WASI-compatible runtimes like StarlingMonkey without major changes.
    3. NodeJS Integration: To run a component in a NodeJS environment, jco transpile is used. This creates a "virtual" WebAssembly + WASI host using @bytecodealliance/preview2-shim to handle incoming HTTP requests.
    4. Enhanced Capabilities: By using @bytecodealliance/jco-std, the component can access wasi:cli/environment (for environment variables) and wasi:config/store (for custom configuration) on the WebAssembly platform.
  9. Jco project organization and subprojects

    main

    The Jco repository is organized into several specialized subprojects:

    SubprojectDescription
    jcoThe jco CLI
    jco-transpileWebAssembly Component Transpilation functionality
    jco-stdA "standard library" providing integrations for popular JS frameworks/paradigms
    preview2-shimProvides a mapping of WASI Preview 2 for NodeJS and Browsers
    preview3-shimProvides a mapping of WASI Preview 3 for NodeJS
    rolldown-plugin-jcoRolldown and Rollup plugin for importing WebAssembly Components through Jco
    js-component-bindgenEnables jco transpile and other features by reusing the Rust WebAssembly ecosystem
    js-component-bindgen-componentA WebAssembly component that makes js-component-bindgen available in JS jco when transpiled
    wasm-tools-componentA WebAssembly component containing pieces of wasm-tools used by jco