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

@lattestream/client

v1.2.0

Published

LatteStream client SDK for browsers and frontend frameworks

Readme

@lattestream/client

npm version License: MIT

LatteStream client SDK for browsers and frontend frameworks. Real-time messaging with WebSocket support, Pusher-style API, and TypeScript-first design.

Features

  • Framework Agnostic - Works with React, Vue, Angular, Svelte, or vanilla JS
  • TypeScript First - Full type safety with comprehensive type definitions
  • Auto-reconnection - Robust connection handling with exponential backoff
  • Channel Authentication - Built-in support for private and presence channels
  • Presence Channels - Track who's online with user presence
  • Performance Optimized - Event batching, object pooling, and lazy loading
  • Tiny Bundle Size - Optimized for modern bundlers

Installation

npm install @lattestream/client

Or with yarn/pnpm:

yarn add @lattestream/client
# or
pnpm add @lattestream/client

Quick Start

import LatteStream from '@lattestream/client';

// Initialize with public key
const client = new LatteStream('lspk_your_public_key', {
  cluster: 'eu1',
  authEndpoint: '/auth', // Required for private/presence channels
});

// Connect
client.connect();

// Subscribe to a channel (must subscribe within 30 seconds)
const channel = client.subscribe('private-channel-name');

// Listen for events
channel.bind('client-example-event', (data) => {
  console.log('Received:', data);
});

// Trigger client events (private/presence channels only)
channel.trigger('client-example-event', { message: 'Hello!' });

Channel Types

Public Channels

No authentication required. Anyone can subscribe.

const channel = client.subscribe('public-updates');
channel.bind('announcement', (data) => {
  console.log('Announcement:', data);
});

Private Channels

Require authentication via your auth endpoint. Channel names must start with private-.

const channel = client.subscribe('private-user-123');
channel.bind('message', (data) => {
  console.log('Private message:', data);
});

Presence Channels

Track online users. Channel names must start with presence-.

Note: Webhooks are currently in development. Presence channels currently function as private channels with extra metadata.

const channel = client.subscribe('presence-chat');

// Listen for members joining
channel.bind('lattestream:member_added', (member) => {
  console.log('User joined:', member);
});

// Listen for members leaving
channel.bind('lattestream:member_removed', (member) => {
  console.log('User left:', member);
});

// Get current members
const members = channel.getMembers();
console.log('Online users:', members);

API Reference

LatteStream

Constructor

new LatteStream(appKey: string, options?: LatteStreamOptions)

Methods

  • connect() - Connect to LatteStream
  • disconnect() - Disconnect from LatteStream
  • subscribe(channelName: string, authOptions?: AuthOptions) - Subscribe to a channel
  • unsubscribe(channelName: string) - Unsubscribe from a channel
  • bind(eventName: string, callback: EventCallback) - Listen for global events
  • unbind(eventName?: string, callback?: EventCallback) - Remove global event listeners
  • getSocketId() - Get current socket ID
  • getConnectionState() - Get connection state
  • getReconnectionAttempts() - Get number of reconnection attempts
  • forceReconnect() - Force immediate reconnection

Channel

Methods

  • bind(eventName: string, callback: EventCallback) - Listen for channel events
  • unbind(eventName?: string, callback?: EventCallback) - Stop listening for events
  • trigger(eventName: string, data?: any) - Trigger client event (private/presence only)
  • isSubscribed() - Check if subscribed
  • getType() - Get channel type ('public', 'private', or 'presence')

PresenceChannel

Extends Channel with presence-specific methods:

  • getMembers() - Get all online members
  • getMember(id: string) - Get specific member
  • getMyId() - Get your user ID
  • getMemberCount() - Get member count

Configuration Options

interface LatteStreamOptions {
  wsEndpoint?: string; // Custom WebSocket endpoint
  authEndpoint?: string; // Auth endpoint for private/presence channels
  cluster?: string; // Cluster region (default: 'eu1')
  forceTLS?: boolean; // Force TLS connection
  enableLogging?: boolean; // Enable debug logging
  activityTimeout?: number; // Activity timeout in ms
  pongTimeout?: number; // Pong timeout in ms
  unavailableTimeout?: number; // Unavailable timeout in ms
  maxReconnectionAttempts?: number; // Max reconnection attempts
  maxReconnectGapInSeconds?: number; // Max gap between reconnections
  reconnectBaseDelay?: number; // Base delay in ms (default: 1000)
  reconnectBackoffMultiplier?: number; // Backoff multiplier (default: 2)
  reconnectJitter?: boolean; // Add random jitter (default: true)
  enableBatching?: boolean; // Enable event batching
  batchSize?: number; // Max batch size
  batchInterval?: number; // Batch interval in ms
  enablePerformanceMonitoring?: boolean;
}

Connection States

The client can be in one of these states:

  • connecting - Attempting to connect
  • connected - Successfully connected
  • disconnected - Disconnected
  • unavailable - Connection unavailable
  • failed - Connection failed

Listen for state changes:

client.bind('connection_state_change', (event) => {
  console.log(`${event.previous} -> ${event.current}`);
});

Authentication

For private and presence channels, set up an auth endpoint on your server:

// Client side
const client = new LatteStream('lspk_your_public_key', {
  authEndpoint: '/auth',
});

const channel = client.subscribe('private-user-123');

Your server should handle the auth request and use @lattestream/server to authorize:

// Server side (see @lattestream/server docs)
import LatteStreamServer from '@lattestream/server';

const server = new LatteStreamServer('lsk_your_encrypted_secret');

app.post('/auth', async (req, res) => {
  const { socket_id, channel_name } = req.body;

  // Your authorization logic
  const authResponse = await server.authorizeChannel(
    socket_id,
    channel_name,
    userData // For presence channels
  );

  res.json(authResponse);
});

Advanced Features

Lazy Loading

For code splitting and dynamic imports:

import { LazyLatteStream } from '@lattestream/client';

// Lazy load the client
const client = await LazyLatteStream.createClient('lspk_your_key', options);

Performance Utilities

Export performance utilities for advanced use cases:

import {
  MessageQueue,
  ObjectPool,
  FastEventEmitter,
  PerformanceMonitor,
  debounce,
  throttle,
} from '@lattestream/client';

Examples

React Integration

import { useEffect, useState } from 'react';
import LatteStream from '@lattestream/client';

function App() {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const client = new LatteStream('lspk_your_key', {
      authEndpoint: '/auth',
    });

    client.connect();
    const channel = client.subscribe('chat');

    channel.bind('message', (data) => {
      setMessages((prev) => [...prev, data]);
    });

    return () => {
      client.disconnect();
    };
  }, []);

  return (
    <div>
      {messages.map((msg, i) => (
        <div key={i}>{msg.text}</div>
      ))}
    </div>
  );
}

Vue Integration

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import LatteStream from '@lattestream/client';

const messages = ref([]);
let client;

onMounted(() => {
  client = new LatteStream('lspk_your_key', {
    authEndpoint: '/auth',
  });

  client.connect();
  const channel = client.subscribe('private-chat');

  channel.bind('message', (data) => {
    messages.value.push(data);
  });
});

onUnmounted(() => {
  if (client) client.disconnect();
});
</script>

<template>
  <div v-for="(msg, i) in messages" :key="i">
    {{ msg.text }}
  </div>
</template>

Browser Support

  • Chrome/Edge (latest 2 versions)
  • Firefox (latest 2 versions)
  • Safari (latest 2 versions)
  • iOS Safari (latest 2 versions)
  • Chrome for Android (latest 2 versions)

TypeScript

This package includes TypeScript definitions out of the box. No need for @types packages.

import LatteStream, { Channel, PresenceChannel, LatteStreamOptions, ConnectionState } from '@lattestream/client';

const client: LatteStream = new LatteStream('lspk_key', {
  cluster: 'eu1',
});

Related Packages

License

MIT License - see LICENSE for details.

Links