@kelnishi/tropelang-wasm
v0.23.1
Published
WASM bindings for the TropeLang analysis core (the LSP/IDE backend).
Readme
@kelnishi/tropelang-wasm
The TropeLang recognition & analysis engine, compiled to WebAssembly — the backend that powers the
browser editor / IDE. A wasm-bindgen module over the (closed-source) Rust core: it parses TropeLang
.trl, recognizes tropes against a loaded corpus, runs the evaluator, and serves the IDE features
(completion, hover, diagnostics, symbols, inlays). Ships as a compiled binary — no source included.
Install
npm install @kelnishi/tropelang-wasmBuilt for bundlers (wasm-pack --target bundler): import and call — your bundler (Vite, webpack, Rollup,
esbuild) wires up the .wasm automatically, no manual init step.
Quick start
Every function is string in → JSON string out (parse the result with JSON.parse). Load a corpus once,
then analyze buffers against it.
import { load_corpus, suggest, validate, engine_version } from "@kelnishi/tropelang-wasm";
// 1. Load a corpus — an array of { path, source } (a corpus.json "bag").
const corpus = [
{ path: "trl/prelude.trl", source: "prop Hero\nverb Strikes" },
{ path: "trl/tropes/rescue/the_rescue.trl", source: "/* … */" },
];
const loaded = JSON.parse(load_corpus(JSON.stringify(corpus))); // { ok, count, errors }
// 2. Recognize tropes in a buffer.
const hits = JSON.parse(suggest("char h [+Hero]\nevt e [&Strikes(agent=h)]")); // { recognitions: [...] }
// 3. Validate / version.
JSON.parse(validate("char h [+Hero]")); // diagnostics
engine_version(); // e.g. "0.13.1"Fast corpus load (.trlb)
For a large corpus, load the post-parse AST binary (corpus.trlb) instead of text — it skips lexing
and parsing at load. Pass the bytes as a Uint8Array; decompress a .trlb.gz first (e.g. via
DecompressionStream).
import { load_corpus_trlb, layer_corpus_trlb } from "@kelnishi/tropelang-wasm";
const bytes = new Uint8Array(await (await fetch("/corpus.trlb")).arrayBuffer());
JSON.parse(load_corpus_trlb(bytes)); // replace the active corpus
JSON.parse(layer_corpus_trlb(packBytes, '["struck_stem"]')); // layer + redact on topAPI
Full signatures are in the bundled tropelang_wasm.d.ts. Grouped:
- Corpus:
load_corpus(files_json),load_corpus_trlb(bytes),layer_corpus_trlb(bytes, strikes_json),corpus(),corpus_path(name),corpus_source(name),glossary(). - Recognition:
suggest(src),suggest_local(src, include_local),explain(src),explain_local(src, include_local). - Language / eval:
validate(src),format(src),eval_buffer(src),drams(src),epistemics(src),story(src),state_at(src, name, offset). - IDE:
complete(src, off),describe(src, name),define(name),signature(src, off),links(src),inlays(src),symbols(src),expand_param(src, off). - Meta:
engine_version(),version().
Every export carries a doc comment in tropelang_wasm.d.ts (JSDoc), so your editor shows each
function's purpose and exact JSON shape on hover — no need to run it to learn the output.
Return conventions
Every function returns a JSON string (JSON.parse it); offsets are char offsets. Failure/empty
is uniform, so you don't have to probe for it:
- Corpus-backed views (
suggest,explain,eval_buffer,drams,state_at,corpus,glossary,describe, …) run against the active corpus and return empty results ({recognitions:[]},"", …) before anyload_corpus*, never an error. - Parse-dependent (
format,story) return{ok:true, …}or{ok:false, error};load_corpus*return{ok, count, errors}. - Lookups (
define,corpus_source,corpus_path,signature,expand_param) return""when there's no result. - Offsets in
complete/inlays/links/signature/state_atare character offsets (CodeMirror positions for BMP text), not byte offsets.
Versioning
The package version tracks the engine version (engine_version()); gate a corpus's engineMin against it.
License
Proprietary. You may use and redistribute the unmodified compiled module for any purpose, including commercially; reverse-engineering, decompilation, and modification are not permitted. See LICENSE. The engine source is private; TropeLang the language is an open standard. © 2026 Kelvin Nishikawa.
