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

@dotrino/topbar

v0.14.1

Published

Web Component <dotrino-topbar>: la barra superior estándar del ecosistema Dotrino (marca + volver + acciones + idioma + perfil + moneda de support) en un solo componente. Autohosteado, sin JS de terceros ni cookies.

Readme

@dotrino/topbar

Parte del ecosistema Dotrino. Sin anuncios, sin cookies, sin rastreo.

La barra superior estándar del ecosistema Dotrino, en un solo Web Component. Deja de reimplementar (y de desviar) el header en cada app.

Empaqueta, en el orden y comportamiento normados (CONVENCIONES §5/§6/§9):

[◀ volver] [icono + nombre]   … acciones de la app …   [ES|EN] [perfil] [🪙 support]

con la segunda fila de acciones en móvil, env(safe-area-inset-*), Shadow DOM (sin JS de terceros ni cookies) y estética oscura tematizable. Reúne las tres piezas compartidas para que la app importe una sola cosa:

  • @dotrino/nav → chevron de volver + captura del botón físico Android / gesto iOS / atrás del navegador.
  • @dotrino/support → moneda de soporte/donación.
  • Botón de perfil (atributo profile), en toda página: también la portada de un servicio o de una extensión. Abre un menú con los enlaces a profile.dotrino.com (abrir, crear, adoptar, iniciar sesión). Si la página le pasa .identity, el menú lista además los perfiles del dispositivo para cambiar, y el botón muestra el avatar del activo. Antes de abrirse emite dotrino-profile (cancelable).

Uso

Vanilla:

<!-- OJO: por CDN va SIEMPRE con `+esm`, no con `/src/index.js`. Este paquete
     importa @dotrino/nav, /support, /profile y /identity por su nombre, y un
     especificador desnudo NO resuelve en el navegador ("Failed to resolve module
     specifier"). `+esm` los reescribe a URLs del CDN. Por npm no aplica: el
     bundler los resuelve solo. -->
<script type="module" src="https://cdn.jsdelivr.net/npm/@dotrino/[email protected]/+esm"></script>

<dotrino-topbar brand="Mi App" icon="/icon.svg"
  support-repo="imdotrino/mi-app"
  support-discord="https://discord.gg/D648uq7cth"
  profile>
  <!-- (opcional) botones de acción de tu app -->
  <button>Nueva</button>
</dotrino-topbar>

Vue 3 / Vite (npm):

import '@dotrino/topbar'
<dotrino-topbar brand="Mi App" icon="/icon.svg" :avatar="avatar" profile
  @dotrino-profile="openMyProfile" @dotrino-lang="e => lang = e.detail.lang">
  <button @click="nueva">Nueva</button>
</dotrino-topbar>

Atributos

| Atributo | Qué hace | |---|---| | brand | nombre de la marca | | icon | URL del icono de marca | | brand-href | destino al pulsar la marca (default ./) | | lang | es | en | auto (default auto); persiste y refleja document.documentElement.lang | | home | fallback de "volver" (default https://dotrino.com) | | no-back | oculta el chevron de volver | | no-lang | oculta el toggle de idioma | | profile | muestra el botón de perfil (§6.1). Funciona sin .identity: el menú sale con los enlaces y sin la lista de perfiles | | profile-href | a dónde lleva «Abrir mi perfil» (default https://profile.dotrino.com/) | | profile-new-href | ídem para «Crear perfil» | | profile-adopt-href | ídem para «Adoptar un perfil» | | profile-login-href | ídem para «Iniciar sesión» (entrar con usuario y contraseña en un equipo prestado; default https://profile.dotrino.com/login) | | profile-vault-href | a dónde lleva «Enlazar a mi bóveda» / «Volver a enlazar» del estado del respaldo (default https://profile.dotrino.com/vault) | | profile-target | _blank para que esas cuatro abran en otra pestaña (popup de extensión) | | avatar | data-URI del avatar del perfil activo (si falta: silueta) | | support-href | URL de support (default https://ko-fi.com/dotrino) | | support-repo | repo para el botón "reportar" del support | | support-discord | invitación de Discord del support | | support-contact | pasa contact a <dotrino-support> | | support-no-count | pasa no-count: la moneda no registra la apertura en el store compartido. Para apps que no hablan con ningún dominio de Dotrino (las que corren en la máquina del usuario) | | no-support | oculta la moneda de support | | no-net | oculta el botón de estadísticas de red |

El estado del respaldo (.store)

Pásale a la barra el almacén de la app (@dotrino/store ≥ 0.11, ya conectado) y el botón de perfil lleva un punto con el estado del respaldo en la bóveda:

| Punto | Qué significa | |---|---| | verde | respaldado, nada pendiente | | ámbar | sincronizando o con cambios subiendo | | gris | solo en este navegador (el perfil no está enlazado a una bóveda) | | rojo | no se respalda: la bóveda rechaza a este aparato, lo echaron, o falla la copia |

Al abrir el menú, arriba sale qué pasa, cuántos cambios faltan y la única acción que lo arregla («Volver a enlazar» o «Reintentar»).

const store = await Store.connect({ identity })
document.querySelector('dotrino-topbar').store = store

Existe porque un navegador pasó 12 días sin respaldar nada (la bóveda lo rechazaba) y el único aviso estaba dentro de los ajustes de una app: se perdieron datos.

Estadísticas de red

Si la página tiene un cliente del transporte conectado (@dotrino/proxy-client ≥ 0.28.0), la barra enseña un botón de red (dos flechas). Abre un modal con:

  • el proxio al que está conectado, su estado y todo lo que pasó por él (↓ recibido / ↑ enviado);
  • cada conexión con otro aparato (identicon si se sabe su llave), por dónde va ahora —Proxy, WebRTC directo, WebRTC por TURN, o Proxy · negociando WebRTC— y sus bytes, desglosados por el camino por el que pasaron de verdad.

Se refresca cada segundo mientras está abierto. La app no cablea nada: el pilar apunta sus clientes en un registro de la página (Symbol.for('dotrino.transports')) y el topbar lo lee de ahí, sin importar el pilar. Sin cliente, no hay botón. Prueba manual: test/net.html (servir /mnt/sda1/Dotrino y abrir /dotrino-topbar/test/net.html).

Eventos (bubbles, composed)

  • dotrino-lang → { lang } al cambiar de idioma
  • dotrino-profile → al pulsar el botón de perfil

Slot

El slot por defecto son los botones de acción de tu app (van al medio, entre la marca y las acciones estándar).

Temas

Variables CSS en el host: --dotrino-topbar-bg, --dotrino-topbar-border, --dotrino-topbar-text, --dotrino-topbar-muted, --dotrino-topbar-accent.

Licencia MIT.