libwasmWhat libwasm is

What libwasm is

libwasm is the browser cell. It is a D-to-wasm SPA framework — a fork of spasm — plus generated WebIDL bindings and a replacement runtime so LDC can emit wasm32-unknown-wasi without linking stock druntime or Phobos. svelte-d does not wrap it. svelte-d pretty-prints your .svelte files into the D that libwasm already knows how to compile!(). If you have just finished Getting Started and opened svelte-engine-ws in VS Code with code-d, the identifiers that complete under import libwasm; are the subject of this section.

A representative journey starts at _start(uint heap_base), injected by mixin Spa!App. That C export initialises a bump allocator from the wasm linear-memory heap base, initialises memutils PoolStack, asks JavaScript for the DOM root, injects compile-time CSS, walks the annotated structs, and renders them. JavaScript holds every live DOM object in an integer handle table that begins {1: document, 2: window}. D never stores a JavaScript pointer. A Handle is a uint. That single fact organises the rest of the API: typed bindings are methods on a Handle, Lodash is a command buffer that ships through ldexec_* imports, events re-enter wasm as domEvent(ctx, fun, handle), and this.update.field = v writes a D field and then pushes the new value onto the handle that render created.

Release wasm is small because that graph is the UI. On the kit-admin tree a debug module is 12.64 MiB (name section + DWARF so code-d and DevTools still say ClickField.go); svelte-d wasm / svelte-d build pass lflags -strip-all and then Binaryen ≥123 wasm-opt -Oz, and the same IR is 0.93 MiB (224 KB gzipped). There is no React bundle next to it. See Wasm and host sizes.

There is no garbage collector on this cell. -fno-moduleinfo is required. Stock LDC -Iimport must not win, or the wasm object.d is the wrong one. Language new bumps WasmAllocator and is never recycled. Transient work belongs in a ScopedPool; survivors are copied onto the NodeDef graph. Promises are not native wasm async. The default cell is still LDC 1.43 + --wasm-enable-eh. Official Binaryen ≥123 parses try_table and -Ozs it. The etcimon Flatten-try_table fork also --asyncifys that module so {#await} can print .await. Stock 123/132 cannot; wireAwait then keeps JsPromise.then. Do not put a landing pad around the import.

import libwasm; is the barrel (source/libwasm/package.d). It public-imports the whole product:

ModuleWhat it is
libwasm.bindings~680 WebIDL structs (Document, Window, MouseEvent, HTMLInputElement, fetch, …)
libwasm.spamixin Spa!App, _start, log_info / log_error
libwasm.nodeNodeDef, NamedNode, TagHtmlElementMap, getChildren
libwasm.domcompile!, render, this.update, setVisible, document(), window()
libwasm.eventdomEvent, EventEmitter, Slot, emit, typed listeners
libwasm.arrayHTMLArray, List, UnorderedList, assignEventListeners
libwasm.cssGetCss, addCss, @style
libwasm.routerURLRouter, @entering / @leaving, navigateTo
libwasm.lodashLodash command buffer, execute!T, Eval
libwasm.momentmoment(...) as a Lodash wrapper of window.moment
libwasm.promiseD Promise!(T, E) (CyberShadow / ae)
libwasm.typesHandle, UDAs, JsPromise, JsHandle
libwasm.hmrdumpApp / loadApp
libwasm.intrinsicswasmMemorySize / wasmMemoryGrow
libwasm.rt.allocatorWasmAllocator
libwasm.rt.memoryalloc_init, wasm_malloc, _d_newclass
libwasm.rt.ehwasm-eh personality, _d_throw_exception
memutils.all, fast.json, optional, diet.htmlsupporting graph

Printed client D starts with import libwasm; and then uses those names. It does not import TypeScript, lodash npm, or moment npm — those stay in the workspace JS glue (src-ts/modules/bindings.ts installs window._ and window.moment). It does not import vibe.*. A <script lang="d"> that does is in the wrong cell.

The rest of this section is the runtime in the order you will meet it when you open a printed file. Spa, _start, lifetime is the boot. NodeDef graph is how a .svelte file becomes structs. Handle, bindings, Lodash is how those structs talk to the browser. JsPromise, memory and exceptions, and URLRouter finish the API. lang=“d” on the wasm cell puts the same identifiers back next to the script you actually write.

svelte-d’s Svelte → D IR pages teach the printer. This section teaches the library the printer is targeting. Read both. A construct that cannot be compile!()’d is a diagnostic, not a JavaScript fallback; the place to add the missing idiom is libwasm, then the engine, then the printer.