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

glue-fumen

v1.0.2

Published

A npm package with CLI to glue/unglue fumens optimized for speed.

Readme

GluingFumens

A npm package with CLI to glue/unglue fumens optimized for speed.

What is a glued fumen?

A fumen is a standard, easily sharable encoding of Tetris board states as a string. Fumens support several features such as multiple pages to allow storing related information of several Tetris boards and piece information per page. The act of gluing a fumen is extracting the information of the pieces that are drawn on the board and outputing a fumen with a piece per page, and ungluing a fumen is the inverse operation of a fumen with a piece on each page into one page of all the pieces drawn.

| Unglued PCO | Glued PCO | | :----------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------: | | PCO with LSZ solve | PCO with LSZ solve with separate frame per piece placement |

Features

  • Uniqueness - Guarantees to output unique gluing up to order of piece placements
  • Order - Specifiable string of pieces that must be place in corresponding order up to allowing n-hold
  • SRS - Allow for pieces to be checked if can be placed using SRS 180 kicktable
  • Optimized Classes
    • EncodedField is a faster, minimal implementation compared to tetris-fumen Field
    • MinosEncoder is an abstract static class for obtaining piece positions quickly
    • OperationEncoder is an abstract static class for packing an operation into a number

Installation

To use this library in your project:

npm i glue-fumen

To get globally for CLI:

npm i glue-fumen -g

Usage

Library

The main glueFumen and unglueFumen functions

import { glueFumen, unglueFumen } from 'glue-fumen';

const glued = glueFumen(
  'v115@9gDtQ4glwhi0wwBtilwhRpg0xwT4whRpglwwR4BtQ4?whilJeAgH',
  1,
  false,
  'TSLOJZILSZ',
  0,
  true
);
const unglued = unglueFumen('v115@vhJNJJXqBJnBSyBznB0fBSmBGjBvrB0qB');

console.log(glued);
console.log(unglued);

The EncodedField, MinosEncoder, and OperationEncoder classes

import { EncodedField, MinosEncoder as mi, OperationEncoder as op } from 'glue-fumen';
import { Mino, Rotation } from 'glue-fumen'; // enums
import { TETROMINO } from 'glue-fumen'; // constant
import type { EncodedOperation, EncodedMinos } from 'glue-fumen';
import { Field } from 'tetris-fumen';

// basic field operations
const field = new EncodedField(Field.create());
console.log('Before setting:', Mino[field.at(0, 0)]);
field.set(0, 0, 'I');
console.log('After setting:', Mino[field.at(0, 0)]);
field.unset(0, 0);
console.log('After unsetting:', Mino[field.at(0, 0)]);

// packing of operation into number
const operation: EncodedOperation = op.encode({ x: 1, y: 0, type: 'T', rotation: 'spawn' });
console.log('Encoded Operation:', operation);
console.log('Operation:', op.decode(operation));
console.log(
  op.getX(operation),
  op.getY(operation),
  Mino[op.getPiece(operation)],
  Rotation[op.getRotation(operation)]
);

// get individual minos of a piece
let minos: EncodedMinos = mi.positions(1, 0, Mino.T, Rotation.spawn);
console.log('Encoded Minos:', minos, op.positions(operation)); // same value
for (let i = 0; i < TETROMINO; i++) {
  console.log(mi.getMino(minos));
  minos = mi.nextMino(minos);
}

CLI

Locally in a NPM project

npx glue-fumen 'v115@9gDtQ4glwhi0wwBtilwhRpg0xwT4whRpglwwR4BtQ4?whilJeAgH' -s -o 'TSLOJZILSZ'

Installed globally

glue-fumen 'v115@9gDtQ4glwhi0wwBtilwhRpg0xwT4whRpglwwR4BtQ4?whilJeAgH' -s -o 'TSLOJZILSZ'

Options

| Option | Type | Default | Description | | :----- | :-------- | :------ | :----------------------------------------------------------------------------------------------------- | | -l | number | 1 | Maximum number of solutions to find for each page of the fumens. Nonpositive values for all solutions. | | -o | string | '' | Order of pieces to be placed. | | -d | number | 0 | Number of hold for handling order. Requires order to apply. | | -s | boolean | false | Check if pieces are reachable through SRS 180 kicktable. | | -f | boolean | false | Allow for pieces to be placed in the air. | | -x | boolean | false | Unglues glued fumens. All other options are ignored if this is set. |