npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@open-rgs/core

v1.7.0

Published

Open-RGS core: orchestrator, session, promo free-rounds, Lua/WASM math loader, binary-msgpack transport, admin endpoints. Bun-native.

Readme

@open-rgs/core

The orchestrator and runtime for open-rgs - the round lifecycle, money-movement choreography, math runtimes, secure RNG, binary-msgpack transport, admin endpoints, and metrics. With @open-rgs/contract it is the only required package.

Bun is required. This package publishes raw TypeScript (no dist/) and leans on Bun-specific APIs; run it under Bun, not Node.

Install

bun add @open-rgs/core @open-rgs/contract @open-rgs/platform-mock

Boot

import { createServer, binaryTransport, loadLuaMath } from "@open-rgs/core";
import { defineGame } from "@open-rgs/contract";
import { MockPlatform } from "@open-rgs/platform-mock";

await createServer({
  manifest: defineGame({
    id: "hello", declaredRtp: 0.95, defaultMode: "default",
    modes: { default: { math: await loadLuaMath("./maths/spin.lua"), stakeMultiplier: 1 } },
  }),
  platform:  new MockPlatform({ startingBalance: 100_000 }),
  transport: binaryTransport({ port: 80 }),
});

Math runtimes

A game's math is a MathModule (@open-rgs/contract). Core loads it from one of three source forms - same contract, swappable by a manifest entry:

| Loader | Source | Use case | |--------|--------|----------| | loadLuaMath(path, opts?) | .lua via wasmoon (Lua 5.4 -> WASM) | Default. Cheap to write, hot-reloadable. Per-call watchdog (debug.sethook). | | loadWasmMath(path, opts?) | .wasm kernel (typically Zig or Rust) | Production-grade, certification-friendly, ~14x faster than Lua (measured - examples/twin-slot/src/bench.ts). Simple or complex. | | createMathPool(opts) | the same .wasm kernel, in a Worker pool | Off the I/O thread; fails the round closed on a per-call timeout. Worker-kill is best-effort/platform-dependent (see below). |

Compiled (WASM / Zig) math

Author a kernel (exports play / alloc / free, imports host.rng_next; see examples/hold-and-win/maths/play.zig for a worked one) and build it to WASM with zig:

zig build-exe play.zig -target wasm32-freestanding -fno-entry -rdynamic \
  -OReleaseSmall -femit-bin=play.wasm

Then load it:

import { loadWasmMath, cryptoRng } from "@open-rgs/core";

// Direct, synchronous calls - the fast path.
const math = await loadWasmMath("./maths/play.wasm", { rng: cryptoRng });

A WASM call cannot be interrupted from JS, so loadWasmMath has no execution watchdog - a runaway kernel would block the event loop. It logs a warning at load to keep that visible. Use it only for trusted, bounded kernels.

To run WASM math off the I/O thread (concurrency) with a per-call budget, use the worker pool:

import { createMathPool } from "@open-rgs/core";

const math = await createMathPool({
  wasmPath:  "./maths/play.wasm",
  size:      4,      // worker threads (default 4)
  timeoutMs: 1000,   // per-call budget; an overrun fails the ROUND (MATH_TIMEOUT)
});
// ...later: math.shutdown();

On a budget overrun the pool fails the round closed (rejects with MATH_TIMEOUT - no bad payout, the connection isn't left hung) and replaces the worker. That's the portable guarantee (the outcome-integrity half of Guarantee 5). It is not a portable no-DoS sandbox, though: whether worker.terminate() can kill a tight synchronous runaway is platform-dependent (it did on Linux, not on Bun+macOS in our testing), so a runaway thread may leak. Treat WASM kernels as trusted and bounded regardless; a hard cross-platform no-DoS kill needs process isolation (SIGKILL), not implemented. The pool's win over bare loadWasmMath is off-thread concurrency + round-level failure. v1 is simple (single play) math. (Only the Lua loader's in-VM watchdog preempts a tight loop on any platform.)

Complex rounds. A kernel with kind=1 and open / step / is_terminal / close (+ optional autoclose) exports loads as complex math. Core threads the kernel's serialized state (base64) back into each call; the kernel keeps nothing between calls. See examples/cash-ladder for a worked Zig kernel and specs/03-math-runtime.md for the ABI. (The pool is simple-only today; and even for simple math its worker-kill is platform-dependent — it fails the round on timeout but isn't a portable no-DoS sandbox — so keep all WASM kernels trusted.)

Why Zig for kernels: comptime RTP invariants, no GC pauses, no JIT warmup, tiny hashable output, and one source that compiles to both WASM (server) and a native binary (simulator) - byte-for-byte identical. See specs/06-performance.md and the worked examples/hold-and-win (a 3x3 hold-&-win on a Zig kernel).

Secure RNG

Outcome randomness is injected by the host; the math never ships its own PRNG.

  • Default is a secure CSPRNG. cryptoRng (exported) draws from WebCrypto getRandomValues (-> BoringSSL/OpenSSL, the same source Bun's crypto uses). Math.random is never used for outcomes.
  • Production fails closed. Under NODE_ENV=production, a loader with no rng injected throws - even though a secure default exists - so the operator chooses the source deliberately. Pass { rng: cryptoRng } for the system CSPRNG, or inject a jurisdiction-certified source.
  • A seeded PRNG (e.g. mulberry32 from @open-rgs/simulator) is for simulation only; it is tagged and refused in production.
import { loadLuaMath, cryptoRng } from "@open-rgs/core";

// Production: choose the RNG explicitly.
const math = await loadLuaMath("./maths/spin.lua", { rng: cryptoRng });

Also exported

createOrchestrator (drive rounds without a transport), binaryTransport, startAdmin + admin/probe handlers, createAuditLog / verifyChain (hash- chained audit log), createRgsMetrics + a Prometheus-style Registry, settleAmount / roundHalfEven (integer minor-unit money), uuidV4 / deriveIdempotencyKey, cryptoRng, and the session / promo namespaces.

Specs

The contracts and guarantees this package enforces: 00-guarantees, 02-orchestrator, 03-math-runtime, 06-performance.

License

MIT.