Web Assembly

The Ad Astra crate supports WebAssembly (Wasm) build targets, specifically the wasm32-unknown-unknown target.

The compiled Wasm module can be loaded and run in browsers, including the script language static analyzer, runner, and language server. However, this setup requires additional preparations.

The WebAssembly Example provides a full-featured setup of these components for the browser environment. You can see it in action in the Ad Astra Playground.

Exports

For desktop build targets, the Export macro automatically exports introspection metadata by linking the generated exporting functions in a special link section.

However, the Wasm build target does not have a fully-featured linker. Therefore, you must call these functions manually after the Wasm module is loaded and before the module is actually used.

// Loading a WebAssembly file.
const assembly = fetch('./wasm.wasm');

// Compiling the file in the browser.
WebAssembly.instantiateStreaming(assembly, IMPORTS).then(({instance}) => {
    // Calling each module-exported function that starts with the special
    // `__ADASTRA_EXPORT_` prefix.
    //
    // These functions are generated by the Export macro.
    // By invoking them manually, you register the corresponding item's
    // introspection metadata in the Ad Astra script engine's exports registry.
    for (const property in instance.exports) {
        if (property.startsWith('__ADASTRA_EXPORT_')) {
            instance.exports[property]();
        }
    }

    // The module is now ready for use.
});

LSP Server

The built-in LSP server that you would normally run using the LspServer::startup function spawns additional threads for the communication channel and the actual LSP server instance.

Common LSP communication transports such as STDIO and TCP are unavailable in the Wasm environment. Additionally, the browser's Wasm environment does not support multi-threading.

To organize the LSP server in this environment, you would typically instantiate the LSP server manually using the LspServer::new function and manually manage communication between the language server and the language client.

The WebAssembly Example example demonstrates running the Wasm module in a separate web worker, establishing communication through a system of serialized post-messages passed between the worker and the browser environment.

The LspServer::handle function processes deserialized incoming LSP messages, synchronously yielding outgoing messages. The corresponding implementation reads these messages on the Rust side, serializes them into strings, and sends these strings back to the browser environment.