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

@postacksolutions/flux-relay-sdk

v1.2.0

Published

Official JavaScript/TypeScript SDK for Flux Relay - Real-time messaging platform

Readme

Flux Relay SDK

Official JavaScript/TypeScript SDK for Flux Relay - Real-time messaging platform.

npm version License

Installation

npm install @postacksolutions/flux-relay-sdk
# or
yarn add @postacksolutions/flux-relay-sdk
# or
bun add @postacksolutions/flux-relay-sdk

Quick Start

import { FluxRelay } from '@postacksolutions/flux-relay-sdk';

// Initialize the client
const client = new FluxRelay({
  apiUrl: 'https://flux.postacksolutions.com',
  serverId: 'YOUR_SERVER_ID',
  apiKey: 'YOUR_API_KEY',
});

// Authenticate a user
const auth = await client.authenticateUser({
  externalUserId: 'user_123', // Your app's user ID
  username: 'john_doe',
  metadata: {
    email: '[email protected]',
  },
});

// Store the access token
client.setAccessToken(auth.accessToken);

// Now you can use the SDK
const conversations = await client.getConversations();

Configuration

Basic Configuration

const client = new FluxRelay({
  apiUrl: 'https://flux.postacksolutions.com', // Required
  serverId: 'YOUR_SERVER_ID',                  // Optional when using access tokens
  apiKey: 'YOUR_API_KEY',                      // Optional when using access tokens
  timeout: 30000,                              // Optional: Request timeout in ms (default: 30000)
  enforceHttps: true,                          // Optional: Enforce HTTPS in production (default: true)
});

Using Access Tokens

Once you have an access token (from authenticateUser), you can use it for all subsequent requests:

// After authentication
client.setAccessToken(auth.accessToken);

// Now serverId and apiKey are optional
// The SDK will use the access token for authentication

API Reference

Authentication

authenticateUser(params)

Authenticate or create a user. If the user doesn't exist, it will be created automatically.

const auth = await client.authenticateUser({
  externalUserId: 'user_123',        // Required: Your app's unique user ID
  username: 'john_doe',               // Required: Display name
  metadata: {                         // Optional: Additional user data
    email: '[email protected]',
    phoneNumber: '+1234567890',
    avatar: 'https://example.com/avatar.jpg',
  },
});

// Returns:
// {
//   userId: string;
//   accessToken: string;
//   refreshToken: string;
//   user: {
//     id: string;
//     username: string;
//     metadata?: Record<string, any>;
//   };
// }

Contacts

getContacts()

Get all contacts (users in the same project/server).

const contacts = await client.getContacts();

// Returns: Contact[]
// [
//   {
//     userId: string;
//     username: string;
//     externalUserId: string;
//     metadata?: Record<string, any>;
//     createdAt: string;
//   },
//   ...
// ]

Conversations

getConversations()

List all conversations for the authenticated user.

const conversations = await client.getConversations();

// Returns: Conversation[]
// [
//   {
//     id: string;
//     name?: string;
//     isGroup: boolean;
//     participantIds: string[];
//     createdAt: string;
//     updatedAt: string;
//     lastMessage?: Message | null;
//     unreadCount?: number;
//   },
//   ...
// ]

createConversation(params)

Create a new conversation.

const conversation = await client.createConversation({
  participantIds: ['user_456'],  // Required: Array of user IDs
  name: 'Chat with Jane',        // Optional: Conversation name (for groups)
  isGroup: false,                // Optional: Whether it's a group chat (default: false)
});

// Returns: Conversation

getConversationDetails(conversationId)

Get details of a specific conversation.

const conversation = await client.getConversationDetails('conv_123');

// Returns: Conversation

updateConversationName(conversationId, name)

Update the name of a conversation (typically for group chats).

const conversation = await client.updateConversationName('conv_123', 'New Group Name');

// Returns: Conversation

deleteConversation(conversationId)

Delete a conversation.

await client.deleteConversation('conv_123');

Messages

getMessages(conversationId, options?)

Get messages from a conversation.

const messages = await client.getMessages('conv_123', {
  limit: 50,                      // Optional: Number of messages (1-100, default: 50)
  before: '2024-01-01T00:00:00Z', // Optional: Get messages before this timestamp
});

// Returns: Message[]
// [
//   {
//     id: string;
//     conversationId: string;
//     senderId: string;
//     content: string;
//     type: string;
//     attachments?: Array<{
//       id: string;
//       filename: string;
//       mimeType: string;
//       size: number;
//     }>;
//     createdAt: string;
//   },
//   ...
// ]

sendMessage(conversationId, params)

Send a message to a conversation.

const message = await client.sendMessage('conv_123', {
  content: 'Hello, world!',       // Required: Message content
  type: 'text',                    // Optional: Message type (default: 'text')
  attachments: [                   // Optional: File attachments
    {
      id: 'file_123',
      filename: 'document.pdf',
      mimeType: 'application/pdf',
      size: 1024,
    },
  ],
});

// Returns: Message

File Uploads

uploadFile(file)

Upload a file and get a file ID for use in messages.

const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const uploadResult = await client.uploadFile(file);

// Returns: { fileId: string; url: string }

// Use the fileId in message attachments
await client.sendMessage('conv_123', {
  content: 'Check out this file!',
  type: 'text',
  attachments: [{
    id: uploadResult.fileId,
    filename: file.name,
    mimeType: file.type,
    size: file.size,
  }],
});

File Upload Limits:

  • Maximum file size: 10MB
  • Allowed types: Images, documents, videos, audio files

getFile(fileId)

Retrieve file data by file ID. Returns the file with base64-encoded data.

const file = await client.getFile('file_123');

// Returns:
// {
//   id: string;
//   filename: string;
//   mimeType: string;
//   size: number;
//   data: string; // Base64 encoded
//   uploadedAt: string;
// }

// Example: Download file
const file = await client.getFile('file_123');
const byteCharacters = atob(file.data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
  byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: file.mimeType });

// Create download link
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = file.filename;
a.click();
URL.revokeObjectURL(url);

Token Management

setAccessToken(token)

Set the access token manually (useful for token refresh or restoring sessions).

client.setAccessToken('your-access-token');

getAccessToken()

Get the current access token.

const token = client.getAccessToken();
// Returns: string | null

⚠️ Security Warning: Only use this for token refresh or secure server-side operations. Never expose tokens in client-side code, logs, or error messages.

clearAccessToken()

Clear the access token (useful for logout).

client.clearAccessToken();

Error Handling

The SDK throws FluxRelayError for all errors. Always wrap SDK calls in try-catch blocks:

import { FluxRelay, FluxRelayError } from '@postacksolutions/flux-relay-sdk';

try {
  const conversations = await client.getConversations();
} catch (error) {
  if (error instanceof FluxRelayError) {
    console.error('Flux Relay error:', error.message);
    console.error('Status code:', error.statusCode);
    console.error('Error code:', error.errorCode);
  } else {
    console.error('Unexpected error:', error);
  }
}

Common Error Codes

  • MISSING_API_URL - API URL is required
  • MISSING_CREDENTIALS - Server ID and API Key are required
  • INVALID_TOKEN - Invalid access token format
  • NOT_AUTHENTICATED - User is not authenticated
  • INVALID_ID - Invalid ID format
  • REQUEST_TIMEOUT - Request timed out
  • HTTPS_REQUIRED - HTTPS is required in production

Real-time Updates with WebSocket

For real-time message delivery, use Socket.io alongside the SDK:

import { io } from 'socket.io-client';

// Connect to WebSocket
const socket = io('https://flux.postacksolutions.com', {
  auth: {
    token: auth.accessToken, // From authenticateUser
  },
  path: '/socket.io',
});

// Listen for new messages
socket.on('new_message', (message) => {
  console.log('New message:', message);
  // Update your UI
});

// Join a conversation room
socket.emit('join_conversation', {
  conversationId: 'conv_123',
});

// Send message via WebSocket (optional, can also use REST API)
socket.emit('send_message', {
  conversationId: 'conv_123',
  content: 'Hello!',
  type: 'text',
});

Install Socket.io client:

npm install socket.io-client

TypeScript Support

The SDK is written in TypeScript and includes full type definitions:

import { FluxRelay, User, Conversation, Message, Contact } from '@postacksolutions/flux-relay-sdk';

const client: FluxRelay = new FluxRelay({ ... });
const user: User = auth.user;
const conversations: Conversation[] = await client.getConversations();

Security Features

  • ✅ HTTPS enforcement in production
  • ✅ Input validation and sanitization
  • ✅ Path injection prevention
  • ✅ Request timeouts
  • ✅ Secure token handling
  • ✅ XSS prevention

Examples

Complete Integration Example

import { FluxRelay } from '@postacksolutions/flux-relay-sdk';
import { io } from 'socket.io-client';

// Initialize client
const client = new FluxRelay({
  apiUrl: 'https://flux.postacksolutions.com',
  serverId: 'YOUR_SERVER_ID',
  apiKey: 'YOUR_API_KEY',
});

// Authenticate user
async function initializeMessaging(userId: string, username: string) {
  // Authenticate
  const auth = await client.authenticateUser({
    externalUserId: userId,
    username: username,
  });

  // Set access token
  client.setAccessToken(auth.accessToken);

  // Connect WebSocket
  const socket = io('https://flux.postacksolutions.com', {
    auth: { token: auth.accessToken },
    path: '/socket.io',
  });

  // Load conversations
  const conversations = await client.getConversations();

  // Listen for new messages
  socket.on('new_message', (message) => {
    console.log('New message:', message);
  });

  return { client, socket, conversations };
}

// Usage
const { client, socket, conversations } = await initializeMessaging(
  'user_123',
  'john_doe'
);

React Hook Example

import { useState, useEffect } from 'react';
import { FluxRelay } from '@postacksolutions/flux-relay-sdk';

function useFluxRelay(serverId: string, apiKey: string) {
  const [client, setClient] = useState<FluxRelay | null>(null);
  const [conversations, setConversations] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fluxClient = new FluxRelay({
      apiUrl: 'https://flux.postacksolutions.com',
      serverId,
      apiKey,
    });
    setClient(fluxClient);
    setLoading(false);
  }, [serverId, apiKey]);

  const authenticate = async (userId: string, username: string) => {
    if (!client) return;
    const auth = await client.authenticateUser({ externalUserId: userId, username });
    client.setAccessToken(auth.accessToken);
    const convs = await client.getConversations();
    setConversations(convs);
    return auth;
  };

  return { client, conversations, authenticate, loading };
}

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Node.js Support

  • Node.js 16.0.0 or higher

Resources

License

MIT

Support

For support, email [email protected] or visit flux.postacksolutions.com.