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

@pixels-online/pixels-client-js-sdk

v1.21.0

Published

Pixels Client JS SDK

Readme

Pixels BuildOn Client JS SDK

A powerful TypeScript SDK for integrating Pixels BuildOn offerwall functionality into web applications and games. This SDK provides real-time offer management, player progression tracking, and reward handling capabilities.

🚀 Features

  • Real-time Offer Management - Live updates via Server-Sent Events (SSE)
  • Player Progression Tracking - Monitor player stats, achievements, and conditions
  • Reward System Integration - Handle various reward types (coins, items, exp, etc.)
  • Event-Driven Architecture - React to offer events and player actions
  • TypeScript Support - Full type safety and IntelliSense support
  • Flexible Configuration - Customizable asset resolution and hooks
  • Multi-Environment Support - Local, Test, staging, and production environments
  • Auto-Reconnection - Robust connection management with retry logic

📦 Installation

npm install @pixels-online/pixels-client-js-sdk

🔧 Quick Start

1. Basic Setup

import { OfferwallClient } from '@pixels-online/pixels-client-js-sdk';

const client = new OfferwallClient({
  env: 'test', // or 'live' for production
  tokenProvider: async () => {
    // Fetch JWT token from your server. We recommend using our server-side SDK on your server for JWT creation
    const response = await fetch('/api/auth/pixels-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
    });
    const data = await response.json();
    return data.token;
  },
  assetResolver: (_, id: string) => {
    return {
      name: exampleGameLib[id]?.name || 'Unknown2',
      image: exampleGameLib[id]?.image,
    };
  },
  fallbackRewardImage: 'https://example.com/default-reward.png',
  hooks: {
    onOfferSurfaced: (offer) => {
      var random = Math.random() < 0.5;
      return random; // 50% chance to show the offer
    },
  },
  autoConnect: true,
});

2. Initialize and Connect

// Initialize the client
await client.initialize();

// Listen for offers
client.on('offersUpdated', (offers) => {
  console.log('Available offers:', offers);
  displayOffersInUI(offers);
});

// Listen for player updates
client.on('playerUpdated', (player) => {
  console.log('Player snapshot updated:', player.snapshot);
  console.log('Player data updated:', player.data);
  updatePlayerStatsUI(player);
});

3. Claim Offers

// Claim an offer
try {
  const result = await client.claimOffer(offerId);
  console.log('Offer claimed successfully:', result);
} catch (error) {
  console.error('Failed to claim offer:', error);
}

📊 Player Data Structure

The SDK provides player information through the IClientPlayer interface:

interface IClientPlayer {
  snapshot: IPlayerSnapshot; // Core player data (levels, currencies, achievements, etc.)
  data?: IPlayerData | null; // Additional game-specific data
}

Accessing Player Information

// Get the current player
const player = client.getPlayer();

if (player) {
  // Access core player data
  console.log('Player ID:', player.snapshot.playerId);
  console.log('Player level:', player.snapshot.levels?.combat?.level);
  console.log('Currency balance:', player.snapshot.currencies?.gold?.balance);

  // Access additional player data (if available)
  if (player.data) {
    console.log('Additional currencies:', player.data.currencies);
  }
}

🎯 Configuration Options

OfferwallConfig

interface OfferwallConfig {
  /** Environment: 'test' | 'live' | custom endpoint */
  env: 'test' | 'live' | (string & {});

  /** Auto-connect on initialization (default: false) */
  autoConnect?: boolean;

  /** Enable auto-reconnection (default: true) */
  reconnect?: boolean;

  /** Reconnection delay in ms (default: 1000) */
  reconnectDelay?: number;

  /** Max reconnection attempts (default: 5) */
  maxReconnectAttempts?: number;

  /** Enable debug logging (default: false) */
  debug?: boolean;

  /** Event hooks for custom logic */
  hooks?: Partial<OfferwallHooks>;

  /** Custom asset resolver for rewards */
  assetResolver?: AssetResolver;

  /** Fallback image for unknown rewards */
  fallbackRewardImage: string;

  /** JWT token provider function */
  tokenProvider: TokenProvider;
}

🎨 Asset Resolution

Customize how rewards are displayed in your game:

const gameAssets = {
  gems: { name: 'Gems', image: '/assets/gems.png' },
  gold: { name: 'Gold Coins', image: '/assets/gold.png' },
  sword_1: { name: 'Iron Sword', image: '/assets/sword_iron.png' },
};

const client = new OfferwallClient({
  // ... other config
  assetResolver: (reward, assetId) => {
    const asset = gameAssets[assetId];
    if (asset) {
      return { name: asset.name, image: asset.image };
    }
    return { name: `Unknown Item (${assetId})`, image: null };
  },
});

🎣 Event Hooks

Implement custom logic with event hooks:

const client = new OfferwallClient({
  // ... other config
  hooks: {
    // Control which offers to show
    onOfferSurfaced: (offer) => {
      // Custom logic to determine if offer should be shown
      const currentPlayer = client.getPlayer();
      return currentPlayer?.snapshot.levels?.overall?.level >= offer.minLevel;
    },

    // Handle successful offer claims
    onOfferClaimed: async (offer, rewards) => {
      console.log('Offer completed!', { offer, rewards });
      // Award rewards in your game
      await showConfetti(rewards);
    },

    // Handle connection events
    onConnect: () => {
      console.log('Connected to Pixels BuildOn');
      showConnectionStatus('connected');
    },

    onDisconnect: () => {
      console.log('Disconnected from Pixels BuildOn');
      showConnectionStatus('disconnected');
    },
  },
});

📡 Events

Listen to various events emitted by the client:

// Offer-related events
client.on('offersUpdated', (offers) => {
  /* Handle offers update */
});
client.on('offerAdded', (offer) => {
  /* Handle new offer */
});
client.on('offerRemoved', (offerId) => {
  /* Handle offer removal */
});
client.on('offerUpdated', (offer) => {
  /* Handle offer changes */
});

// Player-related events
client.on('playerUpdated', (player) => {
  /* Handle player data changes */
});

// Connection events
client.on('connected', () => {
  /* Handle connection */
});
client.on('disconnected', () => {
  /* Handle disconnection */
});
client.on('reconnecting', (attempt) => {
  /* Handle reconnection attempts */
});

// Error events
client.on('error', (error) => {
  /* Handle errors */
});

🏗️ API Reference

OfferwallClient Methods

initialize(): Promise<void>

Initialize the client and establish connection.

disconnect(): Promise<void>

Disconnect from the service.

refreshOffersAndPlayer(): { offers: IClientOffer[], player: IClientPlayer }

Refresh and get all current offers.

claimOffer(offerId: string): Promise<ClaimResult>

Claim an offer and receive rewards.

getConnectionState(): ConnectionState

Get current connection status.

Utility Functions

import { meetsConditions, AssetHelper } from '@pixels-online/pixels-client-js-sdk';

// Check if player meets offer conditions
const canClaim = meetsConditions(player.snapshot, offer.surfacingConditions);

// Asset helper utilities
const assetHelper = new AssetHelper(assetResolver, fallbackImage);
const rewardAsset = assetHelper.resolveRewardAsset(reward, assetId);

🧪 Testing

The SDK includes comprehensive test coverage:

# Run all tests
npm test

# Run unit tests
npm run test:unit

# Run integration tests
npm run test:integration

# Run e2e tests
npm run test:e2e

# Run with coverage
npm run test:coverage

# Watch mode
npm run test:watch

🌍 Environments

The SDK supports multiple environments:

  • test - Sandbox environment for development
  • live - Production environment
  • staging - Staging environment
  • preview - Preview environment
  • dev - Development environment
  • Custom URL - Provide your own endpoint

� Migration Guide

v1.0.0+ Breaking Changes

Player Data Structure Update

The player data structure has been updated to provide better separation between core player data and additional game-specific data:

  • Old: IClientPlayerSnapshot (flat structure)
  • New: IClientPlayer (structured with snapshot and data properties)

Migration Steps:

// Before (v0.x)
const player = client.getPlayer(); // IClientPlayerSnapshot
const level = player.levels?.combat?.level;
const gold = player.currencies?.gold?.balance;

// After (v1.0+)
const player = client.getPlayer(); // IClientPlayer
const level = player.snapshot.levels?.combat?.level;
const gold = player.snapshot.currencies?.gold?.balance;

// Access additional data (new feature)
const additionalCurrencies = player.data?.currencies;

Event Handler Updates:

// Before
client.on('playerUpdated', (playerSnapshot) => {
  updateUI(playerSnapshot.currencies);
});

// After
client.on('playerUpdated', (player) => {
  updateUI(player.snapshot.currencies);
  // Also handle additional data if needed
  if (player.data) {
    handleAdditionalData(player.data);
  }
});

�📋 Requirements

  • Node.js 16+
  • TypeScript 4.5+ (if using TypeScript)
  • Modern browser with EventSource support

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the AGPLv3 License - see the LICENSE.md file for details.

🔗 Links

📞 Support

For support and questions:

  • Create an issue on GitLab
  • Contact the Pixels team

Made with ❤️ by the Pixels team