Skip to content

Latest commit

 

History

History
208 lines (148 loc) · 6.01 KB

File metadata and controls

208 lines (148 loc) · 6.01 KB

unluac-js

unluac-js is the published JavaScript / TypeScript wrapper for unluac-rs.

It consumes the WebAssembly build produced by packages/unluac-wasm and exposes a small JS-friendly API for decompiling Lua bytecode in Node.js and bundler-based browser environments.

Installation

npm install unluac-js

Requirements:

  • Node.js >= 18 for Node usage
  • A bundler that can emit package-relative wasm assets for browser usage

What This Package Provides

  • init(input?): initialize the wasm module explicitly
  • decompile(bytes, options?): decompile a compiled Lua chunk and return the final source string
  • decompileRich(bytes, options?): decompile and return structured analysis result (source + proto metadata + CFGs)
  • supportedOptionValues(): inspect supported enum-like option values

This package ships a slim wasm build for npm. In particular:

  • decompile() returns the final generated source string directly
  • debug dumps and timing reports are not exposed in the published npm build
  • if you need the full debug surface, use the Rust crate or unluac-cli

Node.js Usage

In Node.js, the default initialization path automatically reads the packaged unluac_wasm_bg.wasm file, so you usually do not need to pass a wasm path manually.

import { decompile, supportedOptionValues } from "unluac-js";
import { readFile } from "node:fs/promises";

const chunkBytes = await readFile("./sample.luac");

const values = await supportedOptionValues();
console.log(values.dialects);

const source = await decompile(chunkBytes, {
  dialect: "auto",
});

console.log(source);

If you want to initialize earlier in your startup path, you can also call:

import { init } from "unluac-js";

await init();

Browser Usage

In the browser, the recommended setup is to use this package through a modern bundler and make sure both unluac_wasm.js and unluac_wasm_bg.wasm are emitted as runtime assets.

If your bundler can resolve the package's relative wasm asset automatically, calling init() is enough:

import { decompile, init } from "unluac-js";

await init();

const source = await decompile(chunkBytes, {
  dialect: "luau",
  generate: {
    luauVectorConstructor: { library: "Vector3", constructor: "new", size: 3 },
  },
});

console.log(source);

If you need to provide the wasm location explicitly, pass a URL:

import { decompile, init } from "unluac-js";

await init(new URL("./unluac_wasm_bg.wasm", import.meta.url));

const source = await decompile(chunkBytes, {
  dialect: "lua5.4",
});

console.log(source);

API Notes

decompile(bytes, options?)

  • bytes accepts BufferSource or any ArrayLike<number>
  • the input must already be a compiled chunk; this package does not compile Lua source for you
  • the return value is always the final generated source string

decompileRich(bytes, options?)

Returns a structured analysis result instead of a plain source string:

import { decompileRich } from "unluac-js";

const result = await decompileRich(chunkBytes, { dialect: "auto" });

console.log(result.source);    // source or Error-marked diagnostic pseudocode
console.log(result.kind);      // "source" or "diagnostic-pseudocode"
console.log(result.protos);    // proto metadata (DFS order)
console.log(result.cfgs);      // per-proto CFG with blocks and edges

The result includes:

  • source: generated source or Error-marked diagnostic pseudocode
  • kind: source or diagnostic-pseudocode
  • protos: array of UnluacProtoMeta with function metadata (name, line range, params, upvalues, constants, instructions, children)
  • cfgs: array of UnluacProtoCfg with control flow graph data (blocks with Low-IR and raw bytecode instructions, edges with type labels)

Supported top-level options:

  • dialect
  • parse
  • readability
  • naming
  • generate

Unsupported in the published npm build:

  • debug
  • timing-report style output

supportedOptionValues()

Returns the currently supported enum-like values for:

  • dialects
  • parseModes
  • stringEncodings
  • stringDecodeModes
  • namingModes
  • generateModes
  • quoteStyles
  • numberFormats
  • tableStyles

Option Reference

Common decompile() options:

  • dialect: target chunk dialect such as auto, lua5.1, lua5.4, luajit, or luau
  • parse.mode: parser mode, strict or permissive
  • parse.stringEncoding: string decoding encoding; accepts auto or any Encoding Standard label (e.g. utf-8, gbk, shift_jis, euc-kr, big5)
  • parse.stringDecodeMode: string decode failure strategy, strict or lossy
  • naming.mode: naming strategy, debug-like, simple, or heuristic
  • naming.debugLikeIncludeFunction: whether debug-like naming should include function-shaped names

readability sub-options:

  • returnInlineMaxComplexity
  • indexInlineMaxComplexity
  • argsInlineMaxComplexity
  • accessBaseInlineMaxComplexity

generate sub-options:

  • mode: strict requires target-compatible source; permissive may return clearly marked diagnostic pseudocode
  • indentWidth
  • maxLineLength
  • numberFormat
  • quoteStyle
  • tableStyle
  • luauVectorConstructor: optional object with an optional library, required constructor, and required size (3 or 4); required when rendering Luau vector constants
  • comment

Current library defaults used by this package:

  • dialect = auto
  • parse.mode = permissive
  • parse.stringEncoding = auto
  • parse.stringDecodeMode = strict
  • naming.mode = debug-like
  • naming.debugLikeIncludeFunction = true
  • generate.mode = permissive
  • generate.indentWidth = 4
  • generate.maxLineLength = 100
  • generate.numberFormat = decimal
  • generate.quoteStyle = min-escape
  • generate.tableStyle = balanced
  • generate.comment = true

Related Packages