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

@v1ct0rbr/waze-web

v0.3.2

Published

Módulo independente de visualização de alertas do Waze (wazedatafeedintegrator). Consumível como pacote npm em qualquer app React ou standalone.

Readme

@v1ct0rbr/waze-web

Módulo independente de visualização de alertas do wazedatafeedintegrator (Waze Partner Hub).

  • Standalone — roda como app de exemplo próprio (README de mapeamento de dados).
  • Biblioteca — consumível em qualquer app React (Siga+/Seguir e outros) via npm, com isolamento arquitetural, versionamento próprio e sem acoplar no host.

Arquitetura

wazedatafeedintegrator (Java - pipeline + API REST)
      ▲  Bearer <token estático> (server-side)
      │
      │  No Seguir: proxy autenticado  →  GET /waze/alerts/filter (Keycloak JWT)
      │  Standalone: acesso direto     →  http://localhost:8081/alerts/filter
      │
@v1ct0rbr/waze-web (este pacote: React 19 + Vite + Leaflet + TanStack Query)

O token do Waze nunca vai para o browser no fluxo Seguir — o proxy WazeProxyController guarda app.waze.token no servidor.

Escopo de CSS

Todo o CSS da biblioteca (style.css) é escopado sob .waze-module (gerado com postcss-prefix-selector apenas no build da lib). Isso garante que o Bootstrap embutido no pacote não vaze para o host: seletores globais como .btn, .card e :root viram .waze-module .btn, .waze-module .card etc. O layout raiz do módulo usa estilos inline (independe de CSS global/escopado), então o mesmo bundle funciona igual em app embutida e standalone.

O host não precisa importar leaflet/dist/leaflet.css — as folhas do Leaflet já entram no waze-web.css escopadas. Se importar a global também, não há conflito, mas é redundante.

UI

Layout mapa-first com abas Alertas / Métricas / Sobre:

  • Mapa OpenStreetMap/CARTO à esquerda, com alternância Mapa / Satélite, modos Pontos / Clusters / Calor e controles de zoom recentralização.
  • Sidebar direita retrátil com abas Filtros / Lista / Camadas; a listagem usa @tanstack/react-virtual (linhas virtualizadas) com paginação "Ver mais".
  • Clicar em um marcador/linha seleciona a ocorrência e busca o detalhe completo (GET /alerts/{uuid}) sob demanda.
  • Tema light/dark alternável na interface (atributos data-waze-theme e data-bs-theme no root do módulo).
  • Camadas GeoJSON opcionais (URL ou upload), com visibilidade/cor por camada.

Mapeamento de dados (importante)

| Campo da API | Tipo | Observação | |---|---|---| | uuid | string | chave primária (dedup do feed) | | type | JAM / HAZARD / ACCIDENT / … | tipo do alerta | | subtype | string | subtipo | | pubMillis | number | epoch em msnew Date(pubMillis) | | location.x | number | longitude | | location.y | number | latitude | | confidence, reliability, reportRating | int | 0–100 (rating 0–5) — apenas no DTO completo (detalhe) | | street, city, country | string | localização textual — apenas no DTO completo (detalhe) |

A listagem (/alerts/filter) retorna o DTO mínimo WazeAlertSummaryDTO (WazeAlertSummary no TS) com apenas uuid, type, subtype, pubMillis e location; o WazeAlertDTO completo (WazeAlert) é usado apenas na ingestão e no detalhe (/alerts/{uuid}).

O Leaflet espera [latitude, longitude]; use o helper exportado toLatLng().

Endpoints mapeados no WazeApi (espelham o controller Java):

  • Alertas: GET /alerts/filter?type=HAZARD&minReliability=5&… (máx. 1000, paginação por limit/offset), GET /alerts/{uuid} (DTO completo)
  • Métricas: GET /alerts/metrics, /alerts/metrics/top-cities, /alerts/metrics/by-type, /alerts/metrics/by-subtype
  • Catálogo (exige admin-token): /types, /subtypes, /types/{id}/subtypes
  • Auxiliares: /cities?q=…, /countries, /road-types

Rodar standalone

npm install
cp .env.example .env   # ajuste VITE_WAZE_API_URL e token
npm run dev            # http://localhost:5174

Variáveis de ambiente (.env):

| Variável | Padrão | Descrição | |---|---|---| | VITE_WAZE_API_URL | http://localhost:8081 | URL base da API (ou /waze via proxy do Seguir) | | VITE_WAZE_API_TOKEN | — | token estático (acesso direto) | | VITE_WAZE_INITIAL_DEFAULT_LATITUDE/LONGITUDE/ZOOM | — | centro/zoom inicial do mapa | | VITE_WAZE_COMPANY_ACRONYM / VITE_WAZE_COMPANY_NAME | — | identidade na barra | | VITE_WAZE_THEME | light | tema inicial (light | dark) |

Usar como pacote

npm run build:lib      # gera dist/ (ESM + .d.ts + waze-web.css)

No host React (ex.: sigamais-admin):

import '@v1ct0rbr/waze-web/style.css'
import { WazeAlertsModule } from '@v1ct0rbr/waze-web'

// Em uma rota do host, ex.: <Route path="/waze" />
<WazeAlertsModule
  baseUrl="/waze"                                    // proxy do backend do Seguir
  getToken={() => localStorage.getItem('access_token')}  // JWT Keycloak do host
/>

No modo acesso direto à API do Waze (outros sistemas):

<WazeAlertsModule baseUrl="https://waze-api.derpb.com.br" token={process.env.WAZE_TOKEN} />

Acesso a dados sem UI (@v1ct0rbr/waze-web/data)

Para integrar as ocorrências externamente sem re-mapear DTOs nem puxar a camada de UI (React/Leaflet/TanStack), consuma o subpath data:

import { WazeApi, WazeApiError } from '@v1ct0rbr/waze-web/data'
import type { WazeAlertSummary, AlertFilter } from '@v1ct0rbr/waze-web/data'

const api = new WazeApi({ baseUrl: '/waze', getToken: () => localStorage.getItem('access_token') })
// ou acesso direto: new WazeApi({ baseUrl: 'https://waze-api.derpb.com.br', token: '...' })

const filter: AlertFilter = { startDate, endDate, type: 'HAZARD', limit: 100 }
const alerts: WazeAlertSummary[] = await api.filterAlerts(filter)
const detail = await api.getByUuid(uuid)

O bundle waze-data é framework-agnóstico e expõe o WazeApi (client tipado) e todos os DTOs (WazeAlert, WazeAlertSummary, AlertFilter, métricas, catálogos). Filtros e detalhes usam exatamente os mesmos DTOs da UI, eliminando mapeamentos duplicados e acoplamento de integração nas aplicações consumidoras.

Props de WazeAlertsModule

| Prop | Tipo | Padrão | Descrição | |---|---|---|---| | baseUrl | string | — | URL base da API (proxy /waze ou API direta) | | token | string? | — | token estático (acesso direto) | | getToken | () => string \| null \| Promise<...>? | — | resolvedor dinâmico de token (Keycloak do host) | | fetch | typeof fetch? | global | transporte injetável | | timeoutMs | number? | 15000 | timeout das requisições | | center | [lat, lng]? | [-7.1, -35.9] | centro inicial do mapa | | zoom | number? | 7 | zoom inicial | | refetchIntervalMs | number? | 60000 | auto-refresh dos alertas | | layers | WazeLayer[]? | — | camadas GeoJSON opcionais exibidas no mapa. Pode ser por url (fetch autenticado com getToken quando fornecido) ou por data já carregado pelo host | | theme | 'light' \| 'dark' | 'light' | tema visual inicial | | syncThemeToBody | boolean | false | aplica o tema também ao <body> (só em uso standalone) |

Scripts

npm run dev         # app standalone (exemplo)
npm run build       # build standalone
npm run build:lib   # build da biblioteca (dist/)
npm run typecheck   # tsc --noEmit
npm run test        # vitest
npm run lint        # eslint