Recompia
Pokémon Pokopia (Switch 2) recompiled to run natively on Windows with Linux/Handheld support. Multiplayer included, modding, feature enhancements and more! Join the discord community as well
翻訳待ち
MTG Arena log file parser — Rust library crate
翻訳待ち
Loading the full README. The saved excerpt is shown below.
This project is in active development. APIs may change without notice.
manasight-parser is the log parsing engine behind Manasight, an MTG Arena companion app.
MTG Arena log file parser — a Rust library crate that reads Arena's Player.log and emits typed game events. It runs natively — tailing a live log through an async event bus — or compiles to WebAssembly to parse a whole log in the browser or in Node.
Requires Rust 1.93.0 or later.Read the full README ↗This project is in active development. APIs may change without notice.
manasight-parser is the log parsing engine behind Manasight, an MTG Arena companion app.
MTG Arena log file parser — a Rust library crate that reads Arena's Player.log and emits typed game events. It runs natively — tailing a live log through an async event bus — or compiles to WebAssembly to parse a whole log in the browser or in Node.
cargo add manasight-parser
Or in Cargo.toml:
[dependencies]
manasight-parser = "0.7"
Requires Rust 1.93.0 or later.
Player.log → File Tailer → Entry Buffer → Router → Parsers → Subscriber
log — file discovery, polling tailer, entry accumulation, timestampsrouter — dispatches raw entries to the correct category parserparsers — one sub-module per event categoryevents — public event type enums/structs (the parser's output contract)event_bus — tokio::broadcast channel for fan-out to subscribers, and the Subscriber type; the stream's own Subscriber reads a bounded, lossless queue insteadstream — public entry point (MtgaEventStream)sanitize — privacy scrubber for redacting PII from raw log textutil — pipeline utilities (gzip compression, content hashing)wasm — wasm-bindgen export of the synchronous parser (enabled by the wasm feature)The async pipeline above powers the live desktop overlay. The synchronous parse_whole_log entry point — and its wasm export — reuse the same Router → Parsers core directly, bypassing the tailer and subscriber queue (no tokio, no filesystem).
manasight-parser has two entry points: a streaming tailer for live logs, and a synchronous whole-log parser (the basis for the WASM build).
Player.log)MtgaEventStream (the default tailer feature) tails a live log and delivers every event, in log order, to its subscriber as it arrives. When the subscriber falls behind, the pipeline waits for it instead of dropping events:
use std::path::Path;
use manasight_parser::MtgaEventStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (stream, mut subscriber) = MtgaEventStream::start(Path::new("Player.log")).await?;
while let Some(event) = subscriber.recv().await {
println!("got event: {event:?}");
}
Ok(())
}
parse_whole_log parses an entire Player.log string in one synchronous call — no async runtime, no filesystem. It is always available (independent of the tailer feature) and is the exact entry point the WASM build exposes to JavaScript:
use manasight_parser::parse_whole_log;
fn main() -> std::io::Result<()> {
let text = std::fs::read_to_string("Player.log")?;
let events = parse_whole_log(&text);
println!("parsed {} events", events.len());
Ok(())
}
| Feature | Default | Description |
|---|---|---|
brace_depth_flush | ✓ | Flush multi-line entries on JSON brace-balance instead of waiting for the next header. Disable as a rollback mechanism if a regression is detected. |
tailer | ✓ | File tailer, log discovery, async event stream (MtgaEventStream), and event bus. Pulls in tokio and known-folders. Disable to build the pure-sync WASM-compatible subset. |
wasm | wasm-bindgen export of parseWholeLog and StreamingParser for use in a browser or Node Parse Worker. Implies brace_depth_flush and lean (omits raw_bytes + heavy payload fields such as annotations, timers, zones, and deck lists to reduce WASM memory pressure). Does not pull in tailer (no tokio/known-folders). |
The wasm feature wraps the synchronous parse_whole_log in a wasm-bindgen export, producing a loadable .wasm artifact plus JS/TypeScript bindings via wasm-pack. The same parser core then runs in a browser or in Node — no tokio, no filesystem, no async runtime.
# Install wasm-pack (once) — pin the version for reproducible builds
cargo install wasm-pack --locked --version 0.15.0
# Build for a bundler (webpack / Vite) — PRIMARY/recommended target:
wasm-pack build --target bundler --no-default-features --features wasm
# For a Node.js consumer:
wasm-pack build --target nodejs --no-default-features --features wasm
# For direct <script type="module"> usage (no bundler):
wasm-pack build --target web --no-default-features --features wasm
Consume the generated bindings from JavaScript / TypeScript:
import init, { parseWholeLog } from "./pkg/manasight_parser.js";
await init(); // instantiate the .wasm module (web / bundler targets)
const text = await readPlayerLog(); // the full Player.log contents, as a string
let events;
try {
events = parseWholeLog(text); // GameEvent[] — see "Event Types" below
} catch (err) {
// parseWholeLog throws only if serialisation to JS fails (extremely unlikely)
console.error("parse failed:", err);
}
Return type: at runtime parseWholeLog returns a GameEvent[] — a live JS object graph (via serde-wasm-bindgen), not a JSON string, so there's no second JSON.parse. Each element is an externally-tagged enum, e.g. { "GameState": { … } } (see Event Types). Because the wrapper hands back a JsValue, the generated .d.ts types the return as any and the call can throw — TypeScript consumers will likely want to layer their own types and a try/catch.
This is the beginning of the README. Read the rest at the original. Read the full README ↗