# WASM API reference

> wasm_bindgen exports decompile, unpack, and ruleNames; parameter types, WakaruDecompileResult and WakaruUnpackResult JSON shapes, and warning kind strings.

- Repository: pionxzh/wakaru
- GitHub: https://github.com/pionxzh/wakaru
- Human docs: https://grok-wiki.com/public/docs/pionxzh-wakaru-77a438a6cc6b
- Complete Markdown: https://grok-wiki.com/public/docs/pionxzh-wakaru-77a438a6cc6b/llms-full.txt

## Source Files

- `crates/wasm/src/lib.rs`
- `crates/core/src/driver/types.rs`
- `crates/formatter/src/lib.rs`

---

---
title: "WASM API reference"
description: "wasm_bindgen exports decompile, unpack, and ruleNames; parameter types, WakaruDecompileResult and WakaruUnpackResult JSON shapes, and warning kind strings."
---

The `wakaru-wasm` crate (`crates/wasm`) compiles to a `cdylib` and exposes three JavaScript-callable functions — `decompile`, `unpack`, and `ruleNames` — via `#[wasm_bindgen]`. Successful calls return plain objects serialized with `serde_wasm_bindgen`; fatal failures throw a string error. A `#[wasm_bindgen(start)]` initializer installs `console_error_panic_hook` so Rust panics surface in the browser console. The playground builds the artifact with `wasm-pack build --target web` into `crates/wasm/pkg`.

## Initialization

`wasm-pack` emits a default `init` function that must run before any API call. It accepts an optional `RequestInfo`, `URL`, `Response`, `BufferSource`, or `WebAssembly.Module` and returns `Promise<void>`.

```typescript
import init, { decompile, unpack, ruleNames } from "wakaru-wasm";

await init();
```

Vite resolves `wakaru-wasm` to `crates/wasm/pkg` and excludes it from dependency pre-bundling so the `.wasm` binary loads correctly.

## Exported functions

| Function | Rust symbol | Returns on success |
|----------|-------------|-------------------|
| `decompile` | `decompile` | `WakaruDecompileResult` object |
| `unpack` | `unpack` | `WakaruUnpackResult` object |
| `ruleNames` | `rule_names` (js_name `ruleNames`) | `string[]` |

`ruleNames` cannot fail under normal conditions; it returns `wakaru_core::rule_names()` — the ordered pipeline rule identifiers — or `null` if serialization fails.

Neither `unpack_files`, `unpack_raw`, nor `trace_rules` from `wakaru-core` are exposed on the WASM surface.

## `decompile`

Runs the single-file decompile pipeline on one source string.

### Parameters

| Position | JS name | Type | Default | Effect |
|----------|---------|------|---------|--------|
| 1 | `source` | `string` | — | Input JavaScript source |
| 2 | `level` | `"minimal" \| "standard" \| "aggressive"` or omitted | `"standard"` | Maps to `RewriteLevel::from_str_or_default`; unrecognized values fall back to `standard` |
| 3 | `sourcemap` | `Uint8Array` or omitted | none | Raw v3 source-map bytes; enables import dedup and source-map-driven identifier rename |
| 4 | `diagnostics` | `boolean` | `false` | Enables post-transform checks (TDZ, duplicate declarations, output parse verification) |
| 5 | `formatter` | `boolean` | `false` | When `true`, runs the Oxc formatter on output; failures become `formatter_failed` warnings |
| 6 | `emitSourceMap` | `boolean` | `false` | Emits a v3 source map mapping decompiled output back to input |

### Fixed internal options

The WASM binding sets options not exposed as parameters:

| Field | Value |
|-------|-------|
| `filename` | `"input.js"` |
| `dce_mode` | `DceMode::TransformOnly` |
| `heuristic_split` | `false` |

### Example

```typescript
const result = decompile(
  bundledSource,
  "standard",
  undefined,
  true,
  true,
  false
);
console.log(result.code);
for (const w of result.warnings) {
  console.warn(`${w.filename} [${w.kind}]: ${w.message}`);
}
```

## `unpack`

Detects bundle format, extracts modules, and runs the decompile pipeline on each module.

### Parameters

| Position | JS name | Type | Default | Effect |
|----------|---------|------|---------|--------|
| 1 | `source` | `string` | — | Bundle source |
| 2 | `level` | rewrite level string | `"standard"` | Same parsing as `decompile` |
| 3 | `heuristicSplit` | `boolean` | `true` | Enables scope-hoisted bundle splitting when no structural bundle is detected |
| 4 | `diagnostics` | `boolean` | `false` | Per-module diagnostic checks |
| 5 | `formatter` | `boolean` | `false` | Oxc formatting per extracted module |
| 6 | `emitSourceMap` | `boolean` | `false` | Per-module emitted source maps |

### Fixed internal options

| Field | Value |
|-------|-------|
| `filename` | `"input.js"` |
| `dce_mode` | `DceMode::Off` (from `DecompileOptions::default`) |
| `sourcemap` | none |

### Example

```typescript
const result = unpack(bundleSource, "aggressive", true, true, true, false);
for (const mod of result.modules) {
  console.log(mod.filename, mod.code.length);
}
```

## `ruleNames`

Returns the ordered list of transformation rule identifiers from the core pipeline registry. Use it to populate UI pickers or to align browser-side tooling with `RuleDescriptor` order documented on the rule pipeline reference page.

```typescript
const names: string[] = ruleNames();
```

## Result shapes

Serde serializes Rust struct fields using **snake_case** JSON keys. Optional fields are omitted when empty.

### `WakaruDecompileResult`

| Field | Type | Presence |
|-------|------|----------|
| `code` | `string` | always |
| `source_map` | `string` | only when `emitSourceMap` is `true`; v3 source-map JSON |
| `warnings` | `WakaruWarning[]` | always (may be empty) |

```json
{
  "code": "export function greet() {\n  return \"hello\";\n}\n",
  "warnings": []
}
```

With diagnostics and source-map emission:

```json
{
  "code": "...",
  "source_map": "{\"version\":3,\"sources\":[\"input.js\"],...}",
  "warnings": [
    {
      "filename": "input.js",
      "kind": "tdz_violation",
      "message": "..."
    }
  ]
}
```

### `WakaruUnpackResult`

| Field | Type | Presence |
|-------|------|----------|
| `modules` | `WakaruModule[]` | always |
| `source_maps` | `WakaruSourceMap[]` | only when non-empty (`emitSourceMap` produced maps) |
| `warnings` | `WakaruWarning[]` | always (may be empty) |

#### `WakaruModule`

| Field | Type |
|-------|------|
| `filename` | `string` — virtual path for the extracted module |
| `code` | `string` — decompiled (and optionally formatted) source |

#### `WakaruSourceMap`

| Field | Type |
|-------|------|
| `filename` | `string` — module filename the map belongs to |
| `map` | `string` — v3 source-map JSON |

```json
{
  "modules": [
    { "filename": "src/index.js", "code": "..." },
    { "filename": "src/utils.js", "code": "..." }
  ],
  "warnings": [
    {
      "filename": "src/legacy.js",
      "kind": "decompile_failed",
      "message": "..."
    }
  ]
}
```

Unlike CLI `--json` output, WASM results do **not** include `elapsed_ms`, `detected_formats`, `total`, or `failed` counters.

## `WakaruWarning`

Every warning carries three fields:

| Field | Type | Description |
|-------|------|-------------|
| `filename` | `string` | Module or input file the warning refers to |
| `kind` | `string` | Machine-readable warning category (see table below) |
| `message` | `string` | Human-readable detail |

WASM results omit the CLI JSON `is_error` flag. Classify warnings client-side using the kind strings below.

### Warning kind strings

| `kind` | Origin | Treat as error? |
|--------|--------|-----------------|
| `raw_normalization_failed` | core `UnpackWarningKind` | yes |
| `fact_collection_parse_failed` | core | yes |
| `decompile_failed` | core | yes |
| `duplicate_declaration` | core | yes |
| `output_parse_recovered` | core | yes |
| `output_parse_failed` | core | yes |
| `formatter_failed` | WASM formatter layer only | yes |
| `input_parse_recovered` | core | no — diagnostic |
| `tdz_violation` | core | no — diagnostic |
| `import_cycle` | core | no — diagnostic |

Core classification follows `UnpackWarningKind::is_diagnostic()`: diagnostic kinds are `input_parse_recovered`, `tdz_violation`, and `import_cycle`. All other kinds, including `formatter_failed`, are errors (`is_error()` returns true for them).

`formatter_failed` messages follow the pattern `{formatter} formatter failed, preserving output: {detail}` where `formatter` is `oxc` when Oxc formatting was requested.

### Filtering example

```typescript
const DIAGNOSTIC_KINDS = new Set([
  "input_parse_recovered",
  "tdz_violation",
  "import_cycle",
]);

function isErrorWarning(kind: string): boolean {
  return !DIAGNOSTIC_KINDS.has(kind);
}

const errors = result.warnings.filter((w) => isErrorWarning(w.kind));
```

## Error handling

| Outcome | JS behavior |
|---------|-------------|
| Success | Plain object return value |
| Fatal error (parse failure, unpack failure, serialization error) | Thrown `string` (from `JsValue::from_str`) |

The playground worker pattern catches thrown strings and forwards them as `decompile-error` messages. Always wrap calls in `try/catch` when integrating outside the demo.

```typescript
try {
  const result = decompile(source);
} catch (err) {
  // err is a string, e.g. "failed to parse input.js"
  console.error(err);
}
```

## TypeScript bindings

`#[wasm_bindgen(typescript_custom_section)]` in `crates/wasm/src/lib.rs` injects interface definitions into the generated `.d.ts`. Parameter names use **camelCase** (`emitSourceMap`, `heuristicSplit`); result field names use **snake_case** (`source_map`, `source_maps`).

The injected `WakaruWarningKind` union is a **subset** of runtime kinds — it lists `raw_normalization_failed`, `fact_collection_parse_failed`, `decompile_failed`, `tdz_violation`, `output_parse_failed`, and `formatter_failed` but omits `input_parse_recovered`, `duplicate_declaration`, `import_cycle`, and `output_parse_recovered`. Treat `kind` as `string` at runtime or extend local types to cover the full table above.

The playground's `playground/src/vite-env.d.ts` declares `kind: string` on `WakaruWarning`, which matches full runtime behavior.

## WASM vs CLI surface

| Capability | WASM | CLI |
|------------|------|-----|
| Single-file decompile | `decompile` | default mode |
| Bundle unpack | `unpack` (single string) | `--unpack` |
| Multi-file / directory unpack | not exposed | `--unpack` with multiple paths |
| Raw extraction | not exposed | `--unpack --raw` |
| Rule trace | not exposed | `wakaru debug trace` |
| Machine-readable timing/metadata | not in result | `--json` |
| DCE mode control | fixed per function | `--dce` flag |
| stdin input | not applicable | supported |

For automation pipelines that need `elapsed_ms`, `detected_formats`, or `is_error` on every warning, use the CLI `--json` schema instead of WASM bindings.

## Build

From the repository root:

```bash
wasm-pack build crates/wasm --target web --out-dir crates/wasm/pkg --release
```

Or via the playground helper:

```bash
node playground/scripts/build-wasm.mjs
```

Release builds disable `wasm-opt` in `Cargo.toml` metadata to avoid over-aggressive size optimization that can break debugging.

## Related pages

<Card href="/wasm-and-playground" title="WASM and playground" description="Vite integration, worker bridge pattern, and online demo setup." />

<Card href="/core-api-reference" title="Core API reference" description="Full Rust API including unpack_files, unpack_raw, DecompileOptions, and DceMode." />

<Card href="/json-output-and-ci" title="JSON output and CI integration" description="CLI --json schema with is_error, elapsed_ms, and detected_formats for automation." />

<Card href="/rewrite-levels-and-assumptions" title="Rewrite levels and assumptions" description="What minimal, standard, and aggressive levels change in the pipeline." />

<Card href="/use-source-maps" title="Use source maps" description="Source-map bytes for rename recovery and emit_source_map output semantics." />

<Card href="/rule-pipeline-reference" title="Rule pipeline reference" description="Ordered rule registry that ruleNames() mirrors." />
