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

@moishy/algsets

v0.3.1

Published

Algorithm case data for Rubik's cube speedsolving methods (ZBLL, PLL, OLL, COLL and more), with case recognition derived from the algorithms themselves.

Readme

@moishy/algsets

Algorithm case data for moishy-cubing, authored as typed TypeScript modules.

The distinguishing idea: a case stores only its algorithms. Recognition is derived by applying the primary alg to a solved cube and inverting — never hand-written, so it cannot drift out of sync with the algs, and authoring a set means transcribing algs and nothing else.

deno add jsr:@moishy/algsets    # Deno — https://jsr.io/@moishy/algsets
npm  install @moishy/algsets    # Node — https://www.npmjs.com/package/@moishy/algsets

Use

Every set is its own subpath export, so you only pull in the data you need:

import { pll } from "@moishy/algsets/pll";

pll.cases.length; // 21
const c = pll.byId("t-perm");
c?.algs[0].moves; // primary alg, parsed
c?.algs.length; // interchangeable alternatives

// AlgSet implements CaseLookup, so it drops straight into an AlgorithmicPhase
pll.find(someCubeState); // the matching case, or null

Each case carries one or more interchangeable algs, primary first. That matters: the solver tries every variant and keeps whichever leaves the cheapest continuation, which is what makes lookahead worth having.

Sets

| Import | Cases | Set | | ------------------------------- | ----- | ------------------------- | | @moishy/algsets/zbll | 472 | ZBLL | | @moishy/algsets/dfdb | 527 | DF/DB pair (APB block223) | | @moishy/algsets/zbls | 301 | ZBLS | | @moishy/algsets/eo-pair | 148 | EO Pair | | @moishy/algsets/lxs | 116 | Last Extended Slot | | @moishy/algsets/lxs-back-slot | 116 | Last Extended Slot (back) | | @moishy/algsets/br-pair | 89 | BR Pair | | @moishy/algsets/fr-pair | 89 | FR Pair | | @moishy/algsets/oll | 57 | OLL | | @moishy/algsets/eodr | 55 | EODR | | @moishy/algsets/coll-epll | 40 | COLL + EPLL | | @moishy/algsets/sv | 27 | Summer Variation | | @moishy/algsets/wv | 27 | Winter Variation | | @moishy/algsets/pll | 21 | PLL |

Notes:

  • There is no ocll-pll set. OCLL + PLL needs no data of its own: OCLL is the seven oll cases 21-27 and PLL is the pll set, which is how APB's ocllPll replacement builds it. An empty placeholder export existed until 0.2.0 and was removed.
  • zbls cases are authored for the front-right slot. 32 of them were originally expressed against the BR or FL slot and have been conjugated onto FR; a consumer recognizing on a different slot must rotate accordingly. The set is 301 rather than the nominal 302 because two entries were the same case (differing only in last-layer corner state, which ZBLS does not touch); they are merged, both algs kept as variants.

Authoring a Set

import { type AlgSet, defineAlgSet } from "@moishy/algsets";

export const mySet: AlgSet = defineAlgSet({
  id: "my-set",
  name: "My Set",
  cases: [
    { id: "sune", name: "Sune", algs: ["R U R' U R U2 R'", "L' U2 L U L' U L"] },
    { id: "case-2", algs: ["F R U R' U' F'"] },
  ],
});

That is the entire contract — ids and algs. No recognition state, no AUF, no cost: all three are computed. defineAlgSet enforces unique ids, parses every alg, and derives each case's recognition state.

Then validate. The harness re-derives each case and checks its algs actually solve it, and that no two cases collide under the recognition signature:

import { assertValidAlgSet } from "@moishy/algsets";

Deno.test("my set is valid", () => assertValidAlgSet(mySet));

Signature collisions are the failure mode that matters — two cases projecting to the same key means one of them will be silently mis-recognized at solve time. The harness catches it; don't skip it.

Full brief, including per-set conventions and sourcing notes: AUTHORING.md.

Changelog

CHANGELOG.md — release history for all three packages.

License

MIT © Moshe Rosenberg. Algorithms themselves are community knowledge; where a source is known it is recorded on the individual alg variant.