npm.io
0.4.0 • Published 20h ago

@gdscript-analyzer/wasm

Licence
MIT OR Apache-2.0
Version
0.4.0
Deps
0
Size
909 kB
Vulns
0
Weekly
0

@gdscript-analyzer/wasm

Browser/WebAssembly binding for gdscript-analyzer — a fast, embeddable GDScript (Godot 4.x) static-analysis library. "Roslyn for Godot."

npm License: MIT OR Apache-2.0

Run a full GDScript analyzer entirely in the browser — no server, no Godot, no network: diagnostics, type-aware hover, completion, symbols, and navigation. This is the wasm-bindgen (--target web, ESM) build; for Node use the native @gdscript-analyzer/core.

︎ See it running: the playground.

npm i @gdscript-analyzer/wasm

Quick start

import init, { Analyzer } from "@gdscript-analyzer/wasm";

await init();                       // instantiate the .wasm (required, once)
const az = new Analyzer();

const uri = "inmemory://main.gd";
az.openDocument(uri, "extends Node\nfunc _ready():\n\tvar x = 5 / 2\n", null);

console.log(az.diagnostics(uri));  // → INTEGER_DIVISION warning (a native JS array, no JSON.parse)

Bundlers and native ESM both work. With Vite/webpack, import init resolves the .wasm automatically; for a no-bundler setup, serve the package and import init from "/node_modules/@gdscript-analyzer/wasm/gdscript.js".


Engine-class completion (optional)

Parse + type diagnostics work out of the box. To get completion/hover for Godot engine classes (Node, Button, …), load the engine model once — a binary blob you host alongside your app:

const bytes = new Uint8Array(await (await fetch("/data/extension_api.bin")).arrayBuffer());
az.loadEngineApi(bytes);            //true on success

The blob is the analyzer's compiled Godot 4.x API model. The playground ships one at playground/data/extension_api.bin you can copy, or generate it from the repo.


API

Same URI-keyed session model as the native package. Construct once, push documents, query by UTF-8 byte offset; queries return native JS values (no JSON.parse). Navigation/edit results (gotoDefinition, findReferences, rename) carry a uri per target, so you need no FileId→URI mapping of your own.

az.openDocument(uri, text, resPath);   // resPath ("res://…") enables cross-file resolution
az.changeDocument(uri, newText);
az.closeDocument(uri);
az.setProjectConfig(projectGodotText); // enables [autoload] resolution
az.loadEngineApi(bytes);               // optional engine model

az.diagnostics(uri);                   // array
az.documentSymbols(uri);               // array
az.completions(uri, byteOffset);       // array
const hover = az.hover(uri, byteOffset);          // object | null
az.gotoDefinition(uri, byteOffset);    // array, each target has a `uri`
az.inlayHints(uri);                    // array
az.foldingRanges(uri);                 // array
Positions (byte offsets)

The analyzer speaks UTF-8 byte offsets; the browser's strings/editors are UTF-16. Convert at the boundary — the playground source has a complete, copy-pasteable utf16 ⇄ byte helper plus an editor wiring you can lift directly.

const enc = new TextEncoder();
const byteOffset = enc.encode(text.slice(0, utf16Index)).length;

Keywords