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

@appspro-dev/sdk-js

v0.1.9

Published

AppsPro Analytics SDK for browser and Node.js — zero dependencies

Readme

@appspro-dev/sdk-js

Zero-dependency analytics SDK for the AppsPro platform.
Works in browsers and Node.js (18+).


Installation

npm install @appspro-dev/sdk-js
# or
yarn add @appspro-dev/sdk-js
# or
pnpm add @appspro-dev/sdk-js

Quick Start

import { AppsPro } from '@appspro-dev/sdk-js';

const analytics = new AppsPro({
  apiKey: 'ws_abc123.your-secret-key',
});

// Track a custom event
analytics.track('button_clicked', { label: 'Sign Up' });

// Track a page view
analytics.page('Home');

// Identify a user
analytics.identify('user_42', {
  email: '[email protected]',
  plan: 'pro',
});

Configuration

| Option | Type | Default | Description | | --------------- | -------- | ---------------------------------------- | --------------------------------------------- | | apiKey | string | (required) | Your AppsPro API key | | endpoint | string | https://collector.appspro.credpal.co | Collector endpoint URL | | flushInterval | number | 10000 | Auto-flush interval in milliseconds | | flushSize | number | 20 | Number of queued events that triggers a flush | | maxRetries | number | 3 | Max retry attempts on network failure | | workspaceId | string | Extracted from apiKey prefix | Override the workspace ID |

const analytics = new AppsPro({
  apiKey: 'ws_abc123.your-secret-key',
  endpoint: 'https://your-collector.example.com',
  flushInterval: 5000,
  flushSize: 10,
  maxRetries: 5,
});

API Reference

new AppsPro(config)

Creates a new SDK instance. An anonymous ID is generated automatically.

analytics.track(event, properties?)

Track a custom event.

analytics.track('purchase', {
  amount: 49.99,
  currency: 'USD',
  item_id: 'sku_001',
});

analytics.identify(userId, traits?)

Identify a user and merge the anonymous session with a known user ID. Sends an identify call to POST /v1/identify immediately and sets the user_id for all subsequent events.

analytics.identify('user_42', {
  email: '[email protected]',
  name: 'Jane Doe',
  plan: 'pro',
});

analytics.page(name?, properties?)

Track a page view. Automatically captures page_url and referrer.

analytics.page('Pricing', { experiment: 'variant_b' });

analytics.setAnonymousId(id)

Override the auto-generated anonymous ID (e.g. restore from a cookie).

analytics.setAnonymousId('anon_from_cookie_abc');

analytics.flush()

Flush all pending events to the collector immediately. Returns a Promise.

await analytics.flush();

analytics.shutdown()

Stop the automatic flush timer and send remaining events. Call this when your application is shutting down.

await analytics.shutdown();

analytics.reset()

Reset identity state (e.g. on user logout). Generates a new anonymous ID and clears the known user ID.

analytics.reset();

Server-Side Usage (Node.js)

The SDK works in Node.js 18+ (which ships with global fetch). Browser-only context fields (page URL, referrer, user agent, screen size, UTM params) are gracefully skipped in server environments.

import { AppsPro } from '@appspro-dev/sdk-js';

const analytics = new AppsPro({
  apiKey: 'ws_abc123.your-secret-key',
  endpoint: 'https://collect.appspro-dev.io',
});

// Server-side tracking
analytics.track('api_request', {
  path: '/api/users',
  method: 'GET',
  status: 200,
  duration_ms: 42,
});

// Important: flush before process exits
process.on('SIGTERM', async () => {
  await analytics.shutdown();
  process.exit(0);
});

Event Payload

Each event sent to the collector follows this shape:

{
  "event_id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "button_clicked",
  "anonymous_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "user_id": "user_42", // present after identify()
  "properties": { "label": "Sign Up" },
  "context": {
    "page_url": "https://example.com/pricing",
    "referrer": "https://google.com",
    "user_agent": "Mozilla/5.0 ...",
    "locale": "en-US",
    "timezone": "America/New_York",
    "screen_width": 1920,
    "screen_height": 1080,
    "utm_source": "google",
    "utm_medium": "cpc",
  },
  "timestamp": "2026-02-06T12:00:00.000Z",
  "workspace_id": "ws_abc123",
}

How It Works

  1. Queueing — Events are queued in memory.
  2. Auto-flush — The queue flushes when it reaches flushSize events or every flushInterval milliseconds, whichever comes first.
  3. Batching — Flushed events are sent as a single POST /v1/events/batch request with Authorization: Bearer <apiKey>.
  4. Retry — Failed requests are retried with exponential backoff (up to maxRetries times). Events are re-queued on failure.
  5. Identifyidentify() sends to POST /v1/identify immediately with its own retry logic.

License

MIT