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

@rubenciveira/opr-kit

v0.3.0

Published

Logica y vistas de ejercitos de One Page Rules (constructor, reglas, cartas, impresion e importacion de Army Forge), independientes del backend.

Readme

@rubenciveira/opr-kit

Logica y vistas de ejercitos de One Page Rules sin depender de ningun backend: constructor de listas, desglose de mejoras, reglas y auras, composicion, hechizos, importacion de listas de Army Forge y cartas e impresion en React.

Nace de Warhost, que la usa sobre Appwrite, pero no sabe nada de Appwrite: cada aplicacion trae sus datos.

Version 0.x: la API puede cambiar entre versiones menores.

Instalar

pnpm add @rubenciveira/opr-kit

Solo ESM, con tipos incluidos.

Uso

Cada modulo se importa por separado:

import { sectionsForUnit, buildArmy } from "@rubenciveira/opr-kit/core/builder";
import { reglasUsadasEnEjercito } from "@rubenciveira/opr-kit/core/faccion";
import { parseSpells } from "@rubenciveira/opr-kit/core/spells";

| Modulo | Para que | |---|---| | builder | Componer unidades desde el catalogo: secciones de mejora, costes, limites, ejercito resultante | | loadout | Armas y equipo de una unidad tras aplicar reemplazos | | opciones | Desglosar una opcion de mejora en lo que concede | | armyForgeResolve, armyForgeGains | Leer listas compartidas de Army Forge | | glosario | Glosario de reglas a partir de los libros de Army Forge | | reglas, auras, faccion | Reglas con valor, auras, reglas propias y generales de una faccion | | composicion | Avisos de composicion y puntos | | spells | Hechizos de un libro | | unidades | Agrupar unidades y emparejar heroes | | print | Cuadricula de impresion en A4 | | gameSystems | Sistemas de juego y sus particularidades | | questHero, questShop | Heroes y tienda de Star Quest / Fantasy Quest | | model | Tipos de entrada |

Vistas en React

react (18 o 19) es peerDependency: usa la de tu aplicacion.

import UnitCard from "@rubenciveira/opr-kit/react/UnitCard";
import ArmyPrintView from "@rubenciveira/opr-kit/react/ArmyPrintView";

| Componente | Que dibuja | |---|---| | UnitCard | Carta de unidad de 120 x 70 mm (o de personaje, 120 x 140) | | RuleCard, SpellCard, HeroSkillCard | Cartas Mini Euro de 44 x 68 mm | | ArmyPrintView | Impresion de un ejercito: modo libro o tarjetas con dorso | | FactionPrintView | Impresion de una faccion entera como libro | | LoreText, TextoConReferencias, IconoArma | Piezas que usan las anteriores |

Las imagenes llegan ya resueltas, como URL o como funcion (avatarDe, miniaturaDe, coverUrl): el paquete no sabe donde se guardan.

Los componentes llevan "use client": en Next se pueden importar desde un componente de servidor, pero se pintan en el cliente.

Estilos

import "@rubenciveira/opr-kit/styles.css";

Importalo antes que el CSS de tu aplicacion, para que tus reglas ganen en los empates. Las clases son propias (ucard-*, scard-*, print-*, libro-*) y no pisan las de Tailwind; el reset de Tailwind tampoco rompe las cartas.

Hay dos ambientaciones: grimdark por defecto y fantasy con <html data-setting="fantasy">. Los colores salen de variables --opr-* con especificidad cero, asi que se cambian desde tu :root:

:root {
  --opr-accent: #635bff;
  --opr-surface: #ffffff;
  --opr-text: #1a1a1a;
}

| Variable | Para que | |---|---| | --opr-accent, --opr-accent-2 | Color de acento: valores del perfil, bordes activos | | --opr-surface, --opr-text | Fondo y texto de los paneles de las vistas de impresion | | --opr-border, --opr-border-strong | Bordes | | --opr-muted | Texto secundario | | --opr-raise | Sombra de las cartas | | --opr-band-letter, --opr-band-transform, --opr-band-variant | Tipografia de las bandas de titulo |

Lo que no pone el paquete: el fondo de la pagina, las tipografias ("Saira Condensed" para rotulos e "IBM Plex Sans" para el texto; sin ellas se usa la sans-serif del sistema) y el aspecto de los botones de la barra de impresion, que llevan la clase primary para que los estiles tu.

Textos

Las cartas salen en espanol. Para otro idioma, envuelvelas en un TextosProvider; el paquete trae ingles:

import { TextosProvider, en } from "@rubenciveira/opr-kit/react/textos";

<TextosProvider textos={en}>
  <ArmyPrintView … />
</TextosProvider>

textos admite un objeto parcial: lo que no pases sale en espanol. Lo que viene de los datos —nombres de unidades, reglas, hechizos— no se traduce, y el sustantivo del ejercito (noun de ArmyPrintView) lo pasas tu.

De una lista de Army Forge a las cartas

Con los JSON de Army Forge que ya tengas —la lista, sus libros y las reglas comunes del sistema— no hace falta nada mas. El paquete no hace peticiones: los datos los traes tu.

import { gameSystemOf, libroDesdeArmyForge, resolveList } from "@rubenciveira/opr-kit/core/armyForgeResolve";
import { armyNounFor, getGameSystem } from "@rubenciveira/opr-kit/core/gameSystems";
import { glosarioDesdeLibros } from "@rubenciveira/opr-kit/core/glosario";
import ArmyPrintView from "@rubenciveira/opr-kit/react/ArmyPrintView";

// lista: /api/community-lists/:id · libros: uid → /api/army-books/:uid · comunes: /api/rules/common/:sistema
function ImprimirLista({ lista, libros, comunes }) {
  const { name, units } = resolveList(lista, libros, lista.id ?? "");
  return (
    <ArmyPrintView
      nombre={name}
      noun={armyNounFor(getGameSystem(gameSystemOf(lista)))}
      quest={false}
      units={units}
      entradasAttachedTo={units.map(() => undefined)}
      glosario={glosarioDesdeLibros(libros.values(), comunes)}
      librosConocidos={[...libros.values()].map(libroDesdeArmyForge)}
      onCerrar={() => history.back()}
    />
  );
}

glosarioDesdeLibros junta las reglas que describe cada libro con las comunes: los libros solos dejan sin texto las reglas del reglamento que solo salen en mejoras. Si tienes tu propio catalogo de reglas, pasa en glosario un Map de nombre en minusculas a { name, description, coreType }.

Dos limites de momento:

  • En el modo tarjetas el heroe no se empareja con la unidad a la que va unido: sale en su propia carta.
  • En listas con aliados, resolveList no anota a que libro pertenece cada unidad, asi que se agrupan bajo "Sin faccion".

Tus datos

Los tipos de core/model solo declaran los campos que la logica lee. Cualquier objeto que los lleve encaja tal cual, aunque tenga mas: una fila de base de datos, el JSON de un army book, lo que sea.

Las funciones que devuelven reglas son genericas: devuelven tu mismo tipo de regla, con todos sus campos.

Desarrollo

pnpm install
pnpm typecheck
pnpm build

Para probar cambios en una aplicacion sin publicar, enlazalo desde ella:

cd ../mi-app
pnpm link ../opr-kit

pnpm build --watch recompila al guardar. Con el paquete enlazado, el bundler puede acabar con dos copias de React —la de la app y la de desarrollo del paquete— y los hooks fallan; en Vite se evita con resolve: { dedupe: ["react", "react-dom"] }.

Licencia

MIT