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

@game-hub/game-labyrinth

v0.1.3

Published

Labyrinth (Ravensburger, The aMAZEing Labyrinth) as a Game Hub game package — the first game built OUTSIDE the platform monorepo, against the published @game-hub/kernel and @game-hub/ui-kit. Four subpath exports over TypeScript source: ./engine (pure rule

Readme

@game-hub/game-labyrinth

Ravensburger's The aMAZEing Labyrinth as a Game Hub game package: a 7×7 sliding maze where you push the walls around to reach your treasures, and where your push can carry another player's pawn off one edge and back on at the other.

And it is the platform's out-of-repo pilot. Every other Game Hub game lives inside the platform's monorepo. This one does not: it is a standalone repository that depends on @game-hub/kernel and @game-hub/ui-kit from the public npm registry, like any third-party consumer would. If the published contract has a hole in it, this repo's CI is where it shows up.

Why the pilot exists

Game Hub's whole design bet is that a game is additive — four subpath exports (./engine, ./module, ./client, ./bot) behind game-agnostic hosts, so adding one touches no shared core. That bet had been proven five times in-workspace, where a lot of things quietly work for the wrong reasons: TypeScript source is consumed directly, Vite aliases stand in for a real build, the Tailwind content globs happen to cover every game folder, and workspace:* resolves everything.

None of that survives node_modules. So the platform published its two shareable pieces — @game-hub/[email protected] (the contracts + primitives; its major version is the host↔game contract version) and @game-hub/[email protected] (the shared board chrome + the game-facing REST calls) — and this repo is the first real consumer of them. Everywhere the documented recipe assumed a workspace and broke out here is written down, unvarnished, in docs/d2c-findings.md. That file is the point of the exercise as much as the game is.

There are zero references to the platform repository in this one: no path, no link, no file: dep. The lockfile resolves @game-hub/* to registry tarballs with integrity hashes, and CI installs with --frozen-lockfile so it cannot silently start doing anything else.

Status

D2d shipped — the Game Hub hosts this package, and the pilot's question is answered. The hub installs @game-hub/game-labyrinth like any other dependency (its exports resolving to the compiled dist/ below), registers it with one config entry, and ships it in its production Docker image as the sixth playable game — with no alias, path mapping or build shim reaching back into this repo. pnpm pack:smoke is the check that keeps that true: it packs the tarball, installs it plus its peers from the public registry into a throwaway project outside this repo, and plays a game through all four subpaths under plain node.

L4 (functional stage) shipped — the game is playable. L0 laid the data spine (rules types, tile/treasure data, the fixed board transcribed from the rulebook's board photo, and createGame with an injected-rng shuffle, orientations and deal); L1 added the slide (the 12 arrows, the no-reverse rule, pawns carried along a pushed line and wrapped round the edge); L2 added the other half of a turn — flood-fill reachability, the pawn move, the treasure flip, the turn hand-off and the immediate win; L3 added ./module — the real GameModule, a shape-only parseAction, the error→HTTP map, and viewFor, the projection that redacts each player's face-down stack from its own owner down to the top card he is allowed to look at (pg. 2); L4 added ./client — a board you can actually play: the maze drawn from the engine's own connectivity, the 12 arrows with the banned one visibly dead and saying why, the extra tile with a rotation control, the flood-fill highlighted and clickable, "stay put" as a real button, and the move log in plain English.

L4b shipped — the board is illustrated. The direction is Hedgeglow: the labyrinth as an enchanted hedge garden at dusk, corridors of lantern-lit sandstone cut through moss-dark clipped foliage, all 24 treasures redrawn as original gold-leaf medallions hung like lanterns in the hedge, and the "you are hunting" card showing its medallion large so the 24 are tellable apart in play. The pass touched only the three art files: the board's structure, its testids and describe.ts did not move, and the maze is still legible at a 35px phone tile. ./bot is still an honest typed placeholder (L5). 355 tests, 100% engine coverage. The slice plan, the rules digest and every ruling live in ROADMAP.md.

Layout

src/
  engine/     the pure rules core — no I/O, no Date, no Math.random. 100% coverage gate.
    core/       constants, types, errors, and the rulebook-transcribed tile/treasure data
    internal/   shared helpers (geometry, setup randomness, the kernel record()/seating bindings)
    tests/      one file per concern
  module/     the backend seam — the GameModule: createGame wiring, parseAction, the error map, summarize
  client/     the UI seam — the GameClient + the board
    Board.tsx     the 7×7 maze, the 12 arrows, the extra tile, the panels
    palette.ts    the Hedgeglow colours (L4b)                        ← the art lives in these three
    TileFace.tsx  one tile, drawn from the engine's own openings()   ←
    treasures.tsx the 24 original treasure medallions                ←
    describe.ts   the move log in plain English, from the payloads alone
  bot/        the AI (L5). 90% coverage gate, enabled with it.
docs/
  d2c-findings.md   what building out-of-repo actually cost

Running it

Requires Node 22 (.nvmrc) and pnpm (the version is pinned in packageManager).

pnpm install         # resolves @game-hub/* from the public registry
pnpm test            # vitest + the coverage gates (engine 100%; bot 90% from L5)
pnpm test:watch
pnpm typecheck       # strict TS across all four subpaths
pnpm lint            # ESLint 9 flat config — real hazards, not a second typecheck
pnpm format:check    # Prettier (hand-wrap Markdown; *.md is Prettier-ignored)
pnpm build           # tsc → dist/ (JS + .d.ts + inline-source maps), what publishConfig points at
pnpm pack:smoke      # pack, install outside this repo, play a game under plain node, typecheck a consumer

⚠️ Relative imports in the shipped sources carry an explicit .js extension ('../engine/index.js') — tsc emits them verbatim and Node ESM resolves neither extensions nor directories, so extensionless ones would produce a tarball that throws on a host's first import while every command above stayed green. pack:smoke is what catches it.

CI (.github/workflows/ci.yml) runs exactly those, in that order, on a runner with no access to the platform monorepo.

Using this package in a host, before it is published: pnpm pack here, then depend on the tarball. The hub does exactly that from a committed vendor/ directory, with a one-command refresh loop (pnpm labyrinth:refresh over there) — see its vendor/README.md.

Rules, and what's original

The rulebook PDF is not in this repository — it is copyrighted, so it stays local (gitignored) and the code cites page numbers instead. Mechanics and a list of treasure names aren't copyrightable; the illustrations are, so every asset here is drawn fresh in the house style and nothing is traced. The tiles are drawn from the engine's own geometry, and each of the 24 treasure medallions (L4b) is an original silhouette written as SVG path data in src/client/treasures.tsx — from the plain English word, not from the card.

Licence

BSD-3-Clause (see LICENSE). Not affiliated with or endorsed by Ravensburger.