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

@reachysdk/sdk

v1.0.0

Published

SDK JavaScript moderno para tracking de contatos inspirado nas melhores práticas do mercado

Readme

Reachy SDK

SDK JavaScript para tracking de contatos, eventos e e-commerce da plataforma Reachy. Roda no browser do usuario final, coleta dados de comportamento e envia para o backend Reachy via AWS Lambda.

Funcionalidades

  • Multiplas estrategias de envio (sendBeacon, fetch, XHR, image pixel, iframe) com fallback automatico
  • Fila offline com retry e exponential backoff
  • Sessoes inteligentes (30min timeout, auto-extend, nova sessao por UTM change)
  • Identidade persistente (reachyID via localStorage + cookie + fingerprint)
  • Auto-tracking (page views, cliques, scroll, formularios, outbound links, tempo na pagina)
  • E-commerce tracking com schema estruturado (7 eventos padronizados)
  • Deduplicacao de eventos via eventId (UUID v4)
  • Batching de eventos com compressao de payload
  • Middleware/hooks para interceptar eventos antes do envio
  • Consent mode com bloqueio de auto-tracking quando privacidade nao permitida
  • Cross-domain identity via cookieDomain
  • TypeScript declarations (.d.ts) incluidas
  • 243 testes unitarios

Instalacao

Via CDN (recomendado)

<script type="text/javascript">
var reachy = {event:[], config:[], session:[], privacy:[], identify:[]};

reachy.config.push({
    "passcode": "seu-passcode-aqui",
    "debug": false
});

(function () {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = 'https://d3t0ntrdvgmzst.cloudfront.net/reachy.js';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(script, s);
})();
</script>

Via NPM

npm install @reachysdk/sdk
import { createSDK } from '@reachysdk/sdk';

const sdk = createSDK({
    passcode: 'seu-passcode-aqui',
    debug: true
});

Uso

Criar contato

// Via API de fila (funciona antes do SDK carregar)
reachy.login.push({
    first_name: 'Joao Silva',
    email: '[email protected]',
    phone: '+55 11 99999-9999',
    properties: {
        utm_source: 'google',
        plan: 'pro'
    },
    is_subscribed: true
});

// Via API direta (apos SDK carregar)
await sdk.createContact({
    first_name: 'Joao Silva',
    email: '[email protected]',
    phone: '+55 11 99999-9999',
    properties: { utm_source: 'google' },
    is_subscribed: true
});

Eventos customizados

// Via fila
reachy.event.push('Button Clicked', {
    button_id: 'cta_hero',
    page: 'landing'
});

// Via API direta
await sdk.trackEvent('Form Submitted', {
    form_name: 'contact',
    fields: 5
});

Identify

Vincula o reachyID a um ID externo (CRM, sistema interno) sem criar contato:

// Via fila
reachy.identify.push('crm-user-42', { company: 'Acme Corp', plan: 'enterprise' });

// Via API direta
await sdk.identify('crm-user-42', { company: 'Acme Corp', plan: 'enterprise' });

E-commerce

API estruturada com schema padronizado para cada tipo de evento:

// Produto visualizado
await sdk.ecommerce.productViewed({
    product_id: 'SKU-1001',
    name: 'Camiseta Preta P',
    price: 79.90,
    currency: 'BRL',
    category: 'roupas',
    brand: 'Reachy Wear'
});

// Adicionado ao carrinho
await sdk.ecommerce.addedToCart({
    product_id: 'SKU-1001',
    name: 'Camiseta Preta P',
    price: 79.90,
    quantity: 2
});

// Checkout iniciado
await sdk.ecommerce.checkoutStarted({
    order_id: 'ORD-789',
    total: 159.80,
    payment_method: 'pix',
    items: [
        { product_id: 'SKU-1001', name: 'Camiseta Preta P', price: 79.90, quantity: 2 }
    ]
});

// Pedido finalizado
await sdk.ecommerce.orderCompleted({
    order_id: 'ORD-789',
    total: 159.80,
    shipping: 15.00,
    tax: 0,
    currency: 'BRL',
    payment_method: 'pix',
    coupon: 'BLACKFRIDAY',
    items: [
        { product_id: 'SKU-1001', name: 'Camiseta Preta P', price: 79.90, quantity: 2 }
    ]
});

// Outros
await sdk.ecommerce.removedFromCart({ product_id: 'SKU-1001', quantity: 1 });
await sdk.ecommerce.cartViewed({ cart_id: 'abc', items: [...], total: 159.80 });
await sdk.ecommerce.couponApplied({ coupon: 'BLACKFRIDAY', discount: 50.00 });

Middleware

Intercepta eventos antes do envio. Retornar null bloqueia o evento:

// Adicionar metadata em todos os eventos
sdk.use((payload) => {
    payload.event.data.app_version = '2.1.0';
    payload.event.data.environment = 'production';
    return payload;
});

// Filtrar usuarios internos
sdk.use((payload) => {
    if (payload.event.data.email?.endsWith('@reachy.io')) return null;
    return payload;
});

Configuracao

const sdk = createSDK({
    // Autenticacao (obrigatorio)
    passcode: 'seu-passcode',

    // Endpoint (ja configurado por padrao)
    endpoint: 'https://...',

    // Debug
    debug: false,                      // ou ?reachy_debug=true na URL

    // Identidade
    autoIdentityManagement: true,
    cookieDomain: '',                  // ex: 'example.com' para cross-subdomain
    sessionTimeout: 30 * 60 * 1000,   // 30 min

    // Auto tracking
    autoTracking: true,
    trackPageViews: true,
    trackUtmVisited: true,
    trackClicks: true,
    trackOutboundLinks: true,
    trackFormSubmits: true,
    trackFormFieldChanges: true,
    captureFieldValues: true,
    trackScrollDepth: false,
    trackTimeOnPage: true,
    trackPageLeave: false,
    trackVisibility: false,
    scrollThresholds: [25, 50, 75, 100],

    // Campos sensiseis (nunca capturados)
    deniedFieldPatterns: ['password', 'pass', 'token', 'secret', 'credit', 'card', 'cvv', 'email', 'phone', 'cpf', 'cnpj', 'ssn'],
    allowedFieldPatterns: [],          // whitelist (vazio = tudo exceto denied)

    // Activity tracking
    activityTracking: true,
    idleTimeout: 30 * 60 * 1000,
    heartbeatInterval: 5 * 60 * 1000,

    // Live users (page_enter/page_leave)
    liveUsersEnabled: true,

    // Batching (requer suporte no backend)
    batchEvents: false,
    batchSize: 10,
    batchTimeout: 5000,

    // Fila offline
    queueEnabled: true,

    // Privacy / Consent
    respectPrivacy: false,             // quando true, bloqueia auto-tracking sem consent
});

API Reference

Contatos e Identidade

| Metodo | Descricao | |--------|-----------| | createContact(data) | Cria contato com email e/ou telefone. Gera novo reachyID se email muda. | | identify(userId, traits) | Vincula reachyID a ID externo sem criar contato. | | getReachyID() | Retorna o reachyID atual. | | setReachyID(id) | Define reachyID manualmente. | | generateNewReachyID() | Forca geracao de novo reachyID. | | getUserData() | Retorna dados do usuario armazenados localmente. | | getUserInfo() | Retorna informacoes completas (reachyId, userData, isRegistered, fingerprint). | | updateUserData(data) | Merge com dados existentes. | | isUserRegistered() | Verifica se usuario ja tem cadastro local. | | clearUserData() | Limpa dados do usuario (mantem reachyID). | | clearUserIdentity() | Limpa tudo (reachyID + dados + fingerprint). |

Eventos

| Metodo | Descricao | |--------|-----------| | trackEvent(name, data) | Envia evento customizado. | | ecommerce.productViewed(data) | Evento product_viewed. | | ecommerce.addedToCart(data) | Evento product_added_to_cart. | | ecommerce.removedFromCart(data) | Evento product_removed_from_cart. | | ecommerce.cartViewed(data) | Evento cart_viewed. | | ecommerce.checkoutStarted(data) | Evento checkout_started. | | ecommerce.orderCompleted(data) | Evento order_completed. | | ecommerce.couponApplied(data) | Evento coupon_applied. |

Sessao

| Metodo | Descricao | |--------|-----------| | renewSession() | Forca criacao de nova sessao. | | clearSession() | Remove sessao do storage. |

Controles

| Metodo | Descricao | |--------|-----------| | setDebug(enabled) | Liga/desliga logs no console. | | setAutoTracking(enabled) | Liga/desliga auto-tracking de eventos. | | setActivityTracking(enabled) | Liga/desliga deteccao de atividade/idle. | | setLiveUsersEnabled(enabled) | Liga/desliga page_enter/page_leave automaticos. | | updateConfig(config) | Atualiza configuracao em runtime. | | updateTrackingConfig(config) | Atualiza configs de tracking e activity. |

Middleware e Privacy

| Metodo | Descricao | |--------|-----------| | use(fn) | Registra middleware: (payload) => payload \| null. | | isTrackingPermitted() | Verifica se tracking esta permitido pelo consent mode. |

Informacao e Debug

| Metodo | Descricao | |--------|-----------| | getInfo() | Retorna estado completo do SDK (version, session, reachyID, config, features). | | getTrackingStats() | Retorna estatisticas de tracking e activity. | | clearQueue() | Limpa fila de eventos pendentes. |

Lifecycle

| Metodo | Descricao | |--------|-----------| | destroy() | Destroi a instancia: para tracking, cancela timers, remove listeners, flush batcher. |

Unsubscribe

| Metodo | Descricao | |--------|-----------| | resolveUnsubscribeFromUrl(options?) | Le ?u=token ou ?rid=id da URL e resolve dados do contato. | | confirmUnsubscribeFromUrl(options?) | Confirma unsubscribe lendo parametros da URL. | | resolveUnsubscribeByReachyId(id) | Resolve dados de unsubscribe por reachyId. | | unsubscribeByReachyId(id, campaignId?) | Confirma unsubscribe por reachyId. | | resolveUnsubscribeByToken(token) | Resolve dados de unsubscribe por token JWT. | | unsubscribeByToken(token) | Confirma unsubscribe por token JWT. |

Payload

Cada evento enviado tem a seguinte estrutura:

{
    "eventId": "uuid-v4",
    "reachyID": "uuid-usuario",
    "sdkVersion": "1.1.0",
    "event": {
        "name": "product_viewed",
        "data": { ... }
    },
    "session": {
        "id": "session-id",
        "createdAt": 1703123456789,
        "expires": 1703125256789,
        "isNew": false
    },
    "browser": {
        "userAgent": "Mozilla/5.0...",
        "platform": { ... },
        "screen": { ... },
        "window": { ... }
    },
    "url": {
        "current": "https://exemplo.com/pagina",
        "domain": "exemplo.com",
        "path": "/pagina",
        "referrer": "https://google.com"
    },
    "utms": {
        "utm_source": "google",
        "utm_medium": "cpc",
        "utm_campaign": "black_friday"
    },
    "timestamp": 1703123456789
}

No modo batch, payloads sao comprimidos: campos comuns (browser, url, session, utms) vao no context e cada evento carrega apenas eventId, event e timestamp.

Sistema de transporte

O SDK tenta enviar por multiplas estrategias em ordem de prioridade:

  1. sendBeacon() — nao bloqueia a pagina
  2. Image pixel — via GET, estilo Facebook Pixel
  3. Fetch API — POST com no-cors
  4. XMLHttpRequest — fallback para browsers antigos
  5. iframe invisivel — ultimo recurso

Nada e enviado sem um passcode configurado. Se todas as estrategias falham, o evento vai para a fila offline com retry automatico (exponential backoff de 1s a 30s, max 5 tentativas por evento).

Regras de sessao

  • Nova sessao: primeira visita, 30 minutos de inatividade, ou mudanca de utm_source
  • Auto-extend: se restam menos de 5 minutos, a sessao e estendida automaticamente
  • Persistencia: localStorage (dados completos) + cookie (payload minimo para evitar 431 Request Header Too Large)

Regras de identidade

  • reachyID e um UUID persistido em localStorage + cookie (TTL de 1 ano)
  • createContact() com email diferente do armazenado gera novo reachyID (dedup por email)
  • Contatos phone-only sempre geram novo reachyID
  • cookieDomain habilita compartilhamento cross-subdomain (cookie vira source of truth)

Desenvolvimento

npm install          # Instalar dependencias
npm run dev          # Watch mode (Rollup)
npm run build        # Build de producao (UMD + ESM + loader)
npm test             # Testes (243 testes, 8 suites)
npm run lint         # ESLint

Rodar um arquivo de teste especifico:

npx jest --testPathPattern='session.test'
npx jest --testPathPattern='ecommerce'

Debug via URL: adicione ?reachy_debug=true a qualquer pagina com o SDK.

Build outputs

| Arquivo | Formato | Uso | |---------|---------|-----| | dist/sdk.js | UMD (minificado) | CDN, tag <script>. Global ReachySDK. | | dist/sdk.esm.js | ESM | import via bundler. | | dist/loader.js | IIFE (minificado) | Script de carregamento assincrono. | | dist/sdk.d.ts | TypeScript declarations | Autocomplete e tipagem para consumidores NPM. |

Estrutura

src/
  sdk.js                  # Classe principal ReachySDK
  loader.js               # Script de carregamento assincrono (CleverTap-style)
  transport/
    index.js              # Estrategias de envio (beacon, fetch, XHR, image, iframe)
  utils/
    session.js            # Ciclo de vida da sessao
    user-identity.js      # reachyID persistente + fingerprint
    auto-tracking.js      # Listeners de DOM (clicks, scroll, forms, etc)
    activity-tracker.js   # Deteccao de idle/atividade
    queue.js              # Fila offline com retry + backoff
    batcher.js            # Batching de eventos com compressao
    cookie.js             # Utilitarios compartilhados de cookie
    logger.js             # Logger centralizado (respeita debug flag)
    url.js                # Extracao de UTM + sessionStorage
    pageview.js           # SPA page view detection (History API)
    privacy.js            # Consent, DNT, opt-in/opt-out
    browser.js            # Deteccao de capabilities do browser
    uuid.js               # Geracao de UUID v4
    debug.js              # Debug dashboard (floating panel)

Compatibilidade

| Browser | Versao | Status | |---------|--------|--------| | Chrome | 60+ | Completo | | Firefox | 55+ | Completo | | Safari | 12+ | Completo | | Edge | 79+ | Completo | | IE | 11 | Limitado |

Licenca

MIT