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

@luceosports/play-rendering

v2.11.2

Published

Core canvas rendering library for the LuceoSports platform. Renders play JSON (players, lines, shapes, animations) onto an HTML5 canvas. Published as a UMD bundle via webpack. Consumed by the `animation-playback` and `drawing-animation` frontend submodule

Readme

@luceosports/play-rendering

Core canvas rendering library for the LuceoSports platform. Renders play JSON (players, lines, shapes, animations) onto an HTML5 canvas. Published as a UMD bundle via webpack. Consumed by the animation-playback and drawing-animation frontend submodules.


Install

npm install @luceosports/play-rendering

Usage

import { PlayModel, AnimationModel, PlayConstructData } from '@luceosports/play-rendering';

await PlayModel.init();                         // load shared assets once
const play = new PlayModel(data, { width: 800 });
const ctx = canvas.getContext('2d')!;
const anim = new AnimationModel(ctx, play);
anim.start(onFinish, onProgress);

The complete public type surface lives in src/play-rendering.ts (source) and dist/types/play-rendering.d.ts (emitted). Anything not exported there is internal — do not deep-import from dist/types/... subpaths.


Development

npm install                  # install deps
npm run build                # webpack -> dist/play-rendering.js
npm run build:dev            # webpack --mode=development
npm run build:types          # rimraf dist/types && tsc && node scripts/prune-types.js
npm run check:types-fresh    # verify committed dist/types matches a fresh emit
npm run lint                 # eslint
npm run lint:fix             # eslint --fix
npm run verify:pack          # build everything + npm pack, prints next steps

There are no automated tests. Verification is via:

  1. npx tsc --noEmit --emitDeclarationOnly false — type-check source
  2. npm run lint
  3. Building both consumer repos (drawing-animation, animation-playback) against an npm link-ed copy of this lib

The Husky pre-commit hook runs lint-staged plus check:types-fresh. It will reject any commit where dist/types/ would differ from a fresh build:types emit — i.e. source changes that didn't regenerate the published types are caught before they land.


Release process

Releases go directly from master to npm. The library is published as @luceosports/play-rendering and the dist/ folder is the only thing shipped in the tarball (controlled by "files": ["dist"] in package.json).

Step 1 — Merge work to master

If you've been working on a feature branch, fast-forward merge to master:

git checkout master
git pull
git merge --ff-only <feature-branch>

Confirm working tree is clean before continuing.

Step 2 — Smoke-test the actual publishable tarball

npm run verify:pack

That runs npm run build, npm run build:types, then npm pack. It prints the absolute path to the produced .tgz plus copy-paste commands for installing into the consumer repos. Run those commands and build each consumer:

cd ../drawing-animation
npm install --no-save "<path-to-tgz>"
npm run build

cd ../animation-playback
npm install --no-save "<path-to-tgz>"
npm run build

If both build clean, the tarball is safe to publish. The point of this step over npm link is that npm pack builds the exact tarball npm publish would ship (respecting "files" and .npmignore), so it catches missing-dist regressions that a symlinked dev install would mask.

After the smoke-test you can either re-link to keep editing locally:

cd ../drawing-animation && npm link @luceosports/play-rendering
cd ../animation-playback && npm link @luceosports/play-rendering

…or leave them on the tarball install until you bump and publish.

Step 3 — Bump version

npm version <patch|minor|major>

That edits package.json, creates a commit (default message is the new version, e.g. 2.9.0), and creates an annotated git tag (v2.9.0).

Semver guidance for this library:

  • patch — internal fixes, no public-API change. Bug fixes inside model methods, performance improvements, comment-only docs changes.
  • minor — additive public-API change (new exported class/method) or cleanup that's transparent for the known consumers but technically shifts the type surface (e.g. a stricter return type on an existing method).
  • major — breaking change to the exports from src/play-rendering.ts: removed identifier, removed method, changed required parameter, return type widened in a way consumers can't handle. Per .claude/CLAUDE.md's rule: treat src/play-rendering.ts as a public contract.

Step 4 — Push commit + tag

git push --follow-tags

--follow-tags pushes the v<version> tag along with the version-bump commit.

Step 5 — Publish to npm

You need an authenticated npm session with publish access to the @luceosports scope. Check first:

npm whoami

If that returns 401 your token in ~/.npmrc is expired. Re-authenticate via npm login (browser flow) or by setting a fresh automation token from npmjs.com/settings → Access Tokens.

A dry-run is cheap and surfaces what would upload:

npm publish --dry-run

The output lists every file going into the tarball plus the final shasum. When you're satisfied, do the real publish:

npm publish

That uploads to https://registry.npmjs.org/@luceosports/play-rendering/-/play-rendering-<version>.tgz and updates the latest dist-tag. Published versions are effectively permanentnpm unpublish only works for the first 72 hours and gets increasingly restricted. Treat publish as irreversible.

Step 6 — Verify the publish landed

npm view @luceosports/play-rendering version
npm view @luceosports/play-rendering@<version> dist.shasum

The shasum should match what npm publish --dry-run reported in Step 5 — if it does, what landed on npm is byte-identical to what you tested.

Step 7 — Update consumers

Bump the version range in each consumer's package.json and reinstall. For a clean install (not symlinked), make sure any prior npm link is gone first.

# in each consumer repo:
npm install --save '@luceosports/play-rendering@^<new-version>'
npm run build      # smoke-test against the published version

If a consumer still has a leftover npm link symlink, npm install --save of a real version replaces the symlink with the published tarball. The package.json and package-lock.json diffs there should be:

  • package.json: bumped semver range (^2.8.0^2.9.0)
  • package-lock.json: new integrity hash + resolved URL pointing at registry.npmjs.org

Commit those in the consumer repo per its own convention.

Optional — pre-release / RC channel

For a soak period before promoting to latest, use the next dist-tag:

npm version prerelease --preid=rc      # 2.9.0 -> 2.10.0-rc.0
git push --follow-tags
npm publish --tag next
# consumers opt in: npm install @luceosports/play-rendering@next
# after the soak:
npm dist-tag add @luceosports/play-rendering@<version> latest

This is overkill for the current scale (~2 known consumers, both maintained in this workspace). Skip unless you're shipping something risky enough to want a multi-day bake-in window.


Architecture pointers

  • Source layout: src/index.ts is the runtime entry (webpack reads it for the JS bundle); src/play-rendering.ts is the type entry (tsc reads it for the published declarations). Both files must export the same identifier set — the consumer build (Phase 2 verification) catches drift; long-term the structural const X: { new (...): I } = XImpl assignment inside play-rendering.ts catches impl-vs-interface drift at compile time.
  • Pruning: scripts/prune-types.js runs after tsc and deletes any dist/types/*.d.ts file the public entry can't reach. Without it, tsc ships ~200 internal layer/sport/trait declaration files that no consumer can ever import.
  • Curated classes: PlayerModel, LineModel, ShapeModel, NoteModel, FrameModel, AnimationModel, PlayModel, Bezier — each has an explicit interface in src/play-rendering.ts that the impl class must satisfy. Adding a method to one of these requires updating the interface, rebuilding dist/types/, and committing both together.

License

ISC. See package.json.