LaihoE / demoparser

Counter-Strike 2 replay parser for Python and JavaScript
MIT License
307 stars 31 forks source link

[Feature Request] Add node WASM example #1

Closed IOExceptional closed 1 year ago

IOExceptional commented 1 year ago

Similar to the browser/wasm implementation, node supports WASM

wasm-pack also supports creating node modules with type defs:

wasm-pack build --out-dir www/pkg --target nodejs 

I've no idea what I'm doing in rust so I've not managed to make this happen, but I think it "just" needs the lib.rs functions' parameters changing from web_sys::File into a buffer and you can skip that step in each function and pass it in from node!

LaihoE commented 1 year ago

The current code in the WASM dir is just some code i played around with, rather than something meant for use :D, anyway the plan is to add it to NPM eventually.

The main problem I had is what the output should be like? The output is a Pandas DataFrame for Python, but what is the most elegant for JS? Json is always an option but I'm also open to other ideas. Do you have any opinion on what the output should be like?

And for the web_sys::file, yeah the function will just take a string (path to the file) and the parser can take care of the reading (like with the python version).

IOExceptional commented 1 year ago

The wasm example was a great learning tool for me, even if it was super early 😄

Most libraries I've used before (notably markus-wa/demoinfocs-golang, saul/demofile) are unopinionated about data querying, instead storing the data into gamestate & tree directories. Your example I guess is in the main.rs file where you expose the events via the game_events field, but I suppose the data in each field is still serialized

LaihoE commented 1 year ago

I've published a first version of a NPM package: npm i @laihoe/demoparser2

Example useage:

var {parseEvents, parseTicks} = require('@laihoe/demoparser2');

let events = parseEvents("demo.dem", "player_death", ["X", "Y"])
let ticks = parseTicks("demo.dem", ["X", "Y"])

console.log(events[0])

Make sure it's version "0.0.5" and im not 100% about the require path. The bindings are done with "napi".

Some stuff is still missing but the parseEvents and parseTicks should work fine. The parseTicks is currently "columnar" and might change.

LaihoE commented 1 year ago

Regarding the output of Markus/Sauls parsers:

Both parsers are "streaming" parsers that let you hook onto events. This parser is fundamentally different. It doesn't even have a proper "state" that could be returned. This is very much a deliberate choice. The main reason is performance. To be able to get good performance in Python/JS we can't constantly be sending objects back and fourth (especially in parseTicks()). The parser can also "ignore" data that it is not interested in.

The other reason is flexibility. This design does not require "supporting" individual events/props. This means that ALL game events are supported and props are very easy to add (could also be dynamic in the future). And lastly this design allows for easy creation of bindings to other languages as the output is relatively simple.

LaihoE commented 1 year ago

Closing this as node has its own bindings now.