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

@jamunlabs/gameu-session-test

v0.2.0

Published

Cross-language full-stack session test harness for gameu — spawns the real Rust host as a child process, opens real WebSocket clients per controller, drives the real game reducer in-process. Mocks live only at OS-level boundaries. Symmetric companion to t

Readme

@jamunlabs/gameu-session-test

Cross-language full-stack session test harness for gameu. Symmetric companion to the Rust crate gameu-session-test — same mental model, exposed for tests written in TypeScript / Node.

What it does

  • Spawns the real gameu-desktop host as a child process (random port).
  • Opens real WebSocket clients per controller against /ws/controller.
  • Loads the real game reducer module in this Node process and bridges Bootstrap / Input / PeerJoined / … through /ws/tv.
  • Asserts on the reducer's in-memory model directly — no DOM, no rendering layer, no mocked transports.

The only seams that are mocked are OS-level boundaries: TCP loopback, HTTP catalog responses, filesystem paths for the per-test data dir. Everything else — LobbyEngine, LobbyDriver, codec, bridge schema, the SDK, the published reducer — is the same code that ships.

Install

npm install --save-dev @jamunlabs/gameu-session-test

The harness needs to find a gameu-desktop binary. It searches in this order:

  1. process.env.GAMEU_HOST_BINARY — explicit override.
  2. <repo>/target/release/gameu-desktop walking up from cwd.
  3. @jamunlabs/gameu-host-<platform>/bin/gameu-desktop (npm package).

For local development inside the gameu workspace, run cargo build --release -p gameu-desktop once and tier 2 picks the binary up. External game repos add the right host-binary npm package as a dev-dependency and tier 3 resolves it.

Minimal example

import { test, before, after } from "node:test";
import { SessionFixture } from "@jamunlabs/gameu-session-test";
import assert from "node:assert/strict";

let fix;
before(async () => {
  fix = await SessionFixture.boot({
    preInstalledGame: { id: "my-game", dir: "/abs/path/to/my-game" },
  });
});
after(() => fix?.teardown());

test("game flow", async () => {
  const alice = await fix.pairPhone("alice"); // first paired = master
  const bob = await fix.pairPhone("bob");
  await alice.awaitLobby((s) => s.peers.length === 2);

  const game = await fix.startGame({
    reducerPath: "/abs/path/to/my-game/reducer.js",
    reducerExportName: "MyReducer",
  });

  alice.pickerNavigate("right");
  alice.pickerSelect();
  await alice.awaitLobby((s) => s.screen?.kind === "in_game");

  await game.awaitModel((m) => m.board !== undefined);
  alice.send({ kind: "input", event: "button_down", button: "cell-0", t_ms: 0 });
  const after = await game.awaitModel((m) => m.board[0] !== "");
  assert.equal(after.board[0], "x");

  await game.close();
});

Why plain node --test, not tsx

The harness's own sources are .ts, but tests written by consumers (game repos) should be plain .mjs (or .test.ts compiled separately). tsx --test misresolves the SDK's package.json exports field — it treats ESM as CJS and flattens named exports to a default-only shape, which breaks the reducers' import { Reducer, msg, EFFECT_KINDS, ... } from "@jamunlabs/gameu-sdk". Plain node --test honors ESM correctly.

For tests inside this workspace, see crates/gameu-runtime/tests-js-session/ — those run via plain node --test from cargo xtask test behavior.

API surface

  • SessionFixture.boot(opts) — spawn host, wait for bound port.
    • catalogUrl?: catalog URL the host fetches at boot. Empty string = empty catalog.
    • hostBinary?: tier-1 override.
    • preInstalledGame?: {id, dir} — recursively copies the game directory into <dataDir>/games/<id>/ so it appears in the picker as a regular Installed tile (skips the install pipeline; gameplay tests get straight to the action).
  • fix.pairPhone(name)PairedController — fresh credential.
  • fix.reconnectWithSessionToken(name, token) — reconnect path.
  • fix.startGame({reducerPath, reducerExportName?})RunningGame — connects to /ws/tv and bridges Bootstrap / Input / PeerJoined / PeerReconnected / RequestEnd to the reducer.
  • fix.teardown() — kill child + remove temp data dir.
  • RunningGame.awaitModel(pred, timeoutMs?) — block until predicate matches the latest reducer model, or throw on timeout.
  • RunningGame.eventLog / effectLog — every event the bridge fed the reducer / every effect the reducer emitted. Useful for asserting on dispatch patterns rather than just final state.