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

@infinitech.maps/st-map

v1.0.20

Published

SDK de React para renderizar mapas interactivos de SmartTicket con selección de asientos, mesas y secciones.

Readme

@infinitech.maps/st-map

SDK de React para renderizar mapas interactivos de SmartTicket con selección de asientos, mesas y secciones.

Instalación

npm install @infinitech.maps/st-map

Peer dependencies: react >=18 y react-dom >=18.

Inicio rápido

Modo self-contained (recomendado)

El componente carga el mapa automáticamente desde la API usando apiKey y cacheKey:

import { STMap } from "@infinitech.maps/st-map";

function App() {
  return (
    <STMap
      apiKey="tu-api-key"
      cacheKey="uuid-del-mapa"
      onSeatClick={(seat, shape, event, meta) => {
        console.log(seat.id, seat.price);
      }}
      loadingFallback={<p>Cargando mapa...</p>}
      errorFallback={(error) => <p>Error: {error.message}</p>}
    />
  );
}

Modo legacy (datos directos)

Para pasar el JSON del mapa directamente:

import { STMap } from "@infinitech.maps/st-map";

function App() {
  return (
    <STMap
      map={mapData}
      onSeatClick={(seat, shape, event, meta) => {
        console.log(seat.id, seat.price);
      }}
    />
  );
}

Props

Modo self-contained

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | apiKey | string | — | Requerido. API key de autenticación. | | cacheKey | string | — | Requerido. UUID del mapa en caché. | | baseUrl | string | "http://localhost:3001" | URL base del Gateway. | | loadingFallback | ReactNode | null | Componente a mostrar mientras carga el mapa. | | errorFallback | ReactNode \| (error) => ReactNode | null | Componente o función a mostrar en caso de error. |

Modo legacy

| Prop | Tipo | Descripción | |------|------|-------------| | map | object | Objeto JSON del mapa (formato v2 o legacy). |

Callbacks

| Prop | Firma | Descripción | |------|-------|-------------| | onSeatClick | (seat, shape, event, meta) => void | Clic en un asiento, silla o mesa. | | onSectionClick | (shape, event) => void | Clic en una sección/categoría completa. | | onEmptyAreaClick | () => void | Clic en el área vacía del canvas. | | onReady | () => void | El mapa terminó de renderizar. |

Personalización visual

| Prop | Tipo | Default | Descripción | |------|------|---------|-------------| | prices | Record<string, number> | — | Mapa de precios por UUID (ver Resolución de precios). | | selectedSeats | string[] | — | Lista de UUIDs seleccionados (modo controlado). | | reservedSeats | string[] | — | Lista de UUIDs de asientos reservados. | | selectedSeatColor | string | "#01FFFF" | Color de asientos seleccionados. | | reservedSeatColor | string | "#FF0000" | Color de asientos reservados. | | purchasedSeatColor | string | "#000000" | Color de asientos comprados. | | hoverColor | string | "#444" | Color al pasar el cursor. | | hoverTransition | number | 0 | Duración de la transición hover en ms. |


Callbacks

onSeatClick(seat, shape, event, meta)

Se invoca al hacer clic en cualquier elemento reservable (asiento, silla o mesa).

| Argumento | Descripción | |-----------|-------------| | seat | Objeto del asiento/mesa seleccionado. Contiene id (UUID), price, status, etc. | | shape | Objeto de la forma padre (fila, mesa, sector). Contiene category, section, sectorName, etc. | | event | Evento de Konva (canvas). | | meta | Metadatos adicionales. Contiene screenPosition para posicionar popups. |

Propiedades de seat

| Propiedad | Tipo | Descripción | |-----------|------|-------------| | seat.id | string | UUID único del elemento seleccionado. | | seat.price | number \| undefined | Precio resuelto. Presente solo si se pasó prices y existe un precio. | | seat.name | string | Nombre visible del asiento (ej. "A01"). | | seat.row | string \| number | Fila del asiento. | | seat.column | number | Columna del asiento. | | seat.status | string | Estado: "vacant", "reserved", "purchased". | | seat.type | string | Tipo de elemento: "seat" o "table". |

Propiedades exclusivas de mesas (seat.type === "table")

| Propiedad | Tipo | Descripción | |-----------|------|-------------| | seat.isTable | boolean | true cuando es una mesa. | | seat.tableName | string | Nombre de la mesa. | | seat.chairs | array | Lista de sillas de la mesa. | | seat.totalChairs | number | Total de sillas en la mesa. | | seat.vacantCount | number | Cantidad de sillas vacantes. | | seat.reservedCount | number | Cantidad de sillas reservadas. | | seat.purchasedCount | number | Cantidad de sillas compradas. | | seat.available | number | Alias de vacantCount. |

Propiedad meta.screenPosition

Contiene las coordenadas CSS del centro del elemento clicado, útil para posicionar tooltips o popups:

const handleSeatClick = (seat, shape, event, meta) => {
  // Posicionar un popup sobre el asiento
  setPopupPosition({
    x: meta.screenPosition.x,
    y: meta.screenPosition.y,
  });
};

Ejemplo completo: obtener UUID y precio

import { STMap } from "@infinitech.maps/st-map";

function MapView() {
  const prices = {
    "d5195a0a-2e6f-4167-a930-b26440d1e072": 150,  // Categoría "VIP"
    "702fdfc0-3a10-48a5-861c-0ddddac1bf7f": 50,   // Categoría "General"
    "58a5497e-eb75-445a-a89c-dc0fbe652d38": 500,   // Asiento específico
  };

  const handleSeatClick = (seat, shape, event, meta) => {
    console.log("UUID:", seat.id);
    console.log("Precio:", seat.price ?? "Sin precio asignado");

    if (seat.type === "table") {
      console.log(`Mesa "${seat.tableName}" — ${seat.vacantCount}/${seat.totalChairs} disponibles`);
    } else {
      console.log(`Asiento ${seat.name}, fila ${seat.row}`);
    }
  };

  return (
    <STMap
      apiKey="tu-api-key"
      cacheKey="uuid-del-mapa"
      prices={prices}
      onSeatClick={handleSeatClick}
    />
  );
}

onSectionClick(shape, event)

Se invoca al hacer clic en una sección/categoría completa (formas geométricas sin asientos individuales).

| Propiedad | Tipo | Descripción | |-----------|------|-------------| | shape.id | string | UUID de la sección. | | shape.price | number \| undefined | Precio resuelto (si existe). | | shape.category | string | ID de la categoría. | | shape.categoryName | string | Nombre de la categoría. | | shape.section | string | ID del sector. | | shape.sectorName | string | Nombre del sector. |

<STMap
  apiKey="tu-api-key"
  cacheKey="uuid-del-mapa"
  prices={prices}
  onSeatClick={handleSeatClick}
  onSectionClick={(shape, event) => {
    console.log("UUID sección:", shape.id);
    console.log("Precio:", shape.price ?? "Sin precio");
  }}
/>

Resolución jerárquica de precios

Cuando se pasa la prop prices, el SDK resuelve el precio de forma jerárquica buscando en este orden:

  1. Asiento individualprices[seat.id]
  2. Sectorprices[shape.section]
  3. Categoríaprices[shape.category]

El primer match encontrado se asigna como seat.price (o shape.price en secciones).

Si se proporcionan prices pero no se encuentra precio en ningún nivel, el SDK muestra una alerta y no permite la selección del elemento.

Si no se pasa la prop prices, no hay validación de precio y todos los elementos son seleccionables.


Métodos imperativos (ref)

Usa ref para acceder a métodos imperativos del componente:

import { useRef } from "react";
import { STMap } from "@infinitech.maps/st-map";

function App() {
  const mapRef = useRef();

  return <STMap ref={mapRef} apiKey="tu-api-key" cacheKey="uuid-del-mapa" />;
}

resolveReservationIds(selections)

Convierte los elementos clicados en IDs de asientos/sillas individuales listos para la API. Para mesas, extrae los IDs de las sillas vacantes; para asientos, devuelve [id].

const seatIds = mapRef.current.resolveReservationIds([
  { id: "uuid-mesa", quantity: 3 },   // extrae 3 sillas vacantes
  { id: "uuid-asiento" },             // devuelve [uuid-asiento]
]);
// → ["silla-1", "silla-2", "silla-3", "uuid-asiento"]

| Parámetro | Tipo | Descripción | |-----------|------|-------------| | selections | Array<{ id: string, quantity?: number }> | Elementos a resolver. quantity solo aplica a mesas. |

reserveSelected({ selections, ttlSeconds })

Resuelve IDs y reserva en una sola llamada. Requiere apiKey y cacheKey.

const { seatIds } = await mapRef.current.reserveSelected({
  selections: [{ id: "uuid-mesa", quantity: 2 }],
  ttlSeconds: 300, // 5 minutos (default)
});

releaseAll({ seatIds })

Libera asientos (vuelven a estado "vacant"). Requiere apiKey y cacheKey.

await mapRef.current.releaseAll({
  seatIds: ["silla-1", "silla-2"],
});

Selección controlada

Por defecto el SDK gestiona la selección internamente. Para controlarla externamente, pasa selectedSeats:

const [selected, setSelected] = useState([]);

const handleSeatClick = (seat) => {
  setSelected((prev) =>
    prev.includes(seat.id)
      ? prev.filter((id) => id !== seat.id)
      : [...prev, seat.id]
  );
};

<STMap
  apiKey="tu-api-key"
  cacheKey="uuid-del-mapa"
  selectedSeats={selected}
  onSeatClick={handleSeatClick}
/>

Console log integrado

El SDK incluye un log automático en la consola del navegador cada vez que se hace clic en un elemento reservable:

// Asientos/mesas
[ST-Map] Seat click {
  uuid: "58a5497e-eb75-445a-a89c-dc0fbe652d38",
  price: 500,
  row: "A",
  column: 1,
  category: "VIP",
  section: "Sector 1"
}

// Secciones
[ST-Map] Section click {
  uuid: "3b1633c9-57d0-4438-b952-95c213f98e29",
  price: 200,
  category: "General",
  section: "Sector 2"
}

Si un campo no existe (ej. fila/columna en mesas), se muestra "N/A". Sin precio se muestra "sin precio".


STMapClient

Cliente HTTP para interactuar con la API de gestión de asientos. Funciona de forma independiente, sin necesidad del componente React.

import { STMapClient } from "@infinitech.maps/st-map";

const client = new STMapClient({ apiKey: "tu-api-key" });

// O con URL personalizada:
const client = new STMapClient({
  apiKey: "tu-api-key",
  baseUrl: "https://gateway.example.com",
});

getMap(cacheKey, options?)

Carga el mapa desde la API.

const map = await client.getMap("uuid-del-mapa");
// Con versión específica:
const map = await client.getMap("uuid-del-mapa", { version: "v1" });

reserve({ cacheKey, seatIds, ttlSeconds?, version? })

Reserva asientos. Estado → "reserved" con expiración.

const reserved = await client.reserve({
  cacheKey: "uuid-del-mapa",
  seatIds: ["seat-1", "seat-2"],
  ttlSeconds: 300, // 5 minutos (default)
});
// → [{ id: "seat-1", status: "reserved", expiredAt: "..." }, ...]

purchase({ cacheKey, seatIds, version? })

Compra asientos. Estado → "purchased" (permanente). Funciona sobre asientos vacantes o previamente reservados.

const purchased = await client.purchase({
  cacheKey: "uuid-del-mapa",
  seatIds: ["seat-1"],
});
// → [{ id: "seat-1", status: "purchased" }]

release({ cacheKey, seatIds, version? })

Libera asientos. Estado → "vacant". Idempotente: liberar un asiento ya vacante no genera error.

await client.release({
  cacheKey: "uuid-del-mapa",
  seatIds: ["seat-2"],
});
// → [{ id: "seat-2", status: "vacant" }]

getSeatStatus({ cacheKey, seatIds?, version? })

Consulta el estado de asientos. Omitir seatIds devuelve todos los asientos del mapa.

// Estado de asientos específicos
const status = await client.getSeatStatus({
  cacheKey: "uuid-del-mapa",
  seatIds: ["seat-1", "seat-2"],
});
// → [{ id: "seat-1", status: "reserved", expiredAt: "..." }, ...]

// Estado de todos los asientos
const allStatus = await client.getSeatStatus({
  cacheKey: "uuid-del-mapa",
});

Métodos estáticos

STMapClient.resolveReservationIds(element, quantity?)

Resuelve los IDs individuales de un elemento devuelto por onSeatClick. Para mesas, extrae los IDs de las sillas vacantes; para asientos, devuelve [id].

const ids = STMapClient.resolveReservationIds(clickedElement, 3);
await client.reserve({ cacheKey: "uuid-del-mapa", seatIds: ids });

STMapClient.vacantCount(element)

Devuelve la cantidad de asientos vacantes para un elemento. Asientos individuales devuelven 0 o 1; mesas devuelven la cantidad de sillas vacantes.

const available = STMapClient.vacantCount(clickedElement);
console.log(`${available} lugares disponibles`);