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

@masivo/core

v1.0.1

Published

Masivo core SDK — shared logic for all Masivo SDK packages

Readme

@masivo/core

Official Masivo core SDK — shared logic for all Masivo SDK packages.

This is an internal package. It is consumed by @masivo/client and @masivo/rn. You can also use it directly if you are building your own Masivo SDK wrapper or running in a Node.js backend context.

Important: This SDK requires a CLIENT API key. Do not use SERVER API keys — they will be rejected and the SDK will warn you about exposed server credentials. Create a CLIENT key in the Masivo dashboard.

Installation

npm install @masivo/core
pnpm add @masivo/core
yarn add @masivo/core

Quick Start

import { createClient } from "@masivo/core";

const masivo = createClient({ apiKey: "your-client-api-key" });

await masivo.sendAnalyticsEvent({
  type: "ADD_TO_CART",
  customer_id: "customer-123",
  brand_id: "brand-456",
  product: {
    sku: "SKU-001",
    amount: 1,
    value: 29.99
  }
});

// Clean up when the user logs out or the process ends
masivo.destroy();

Events are sent on the analytics path: they feed tracking, journeys, and related flows without applying behavioral or punch-card loyalty rewards from the client. Use your backend with a SERVER key when you need full loyalty campaign execution.

Allowed Event Types

This SDK uses CLIENT API keys, which can only emit:

  • Tracking eventsADD_TO_CART, EMPTY_CART, and other tracking types.
  • Custom event types — Any custom event type you have created in the Masivo platform.

Default event types like PURCHASE, ABANDONED_CART, BIRTHDAY, REGISTRATION, and TIER_ADJUSTMENT are not allowed from the client SDK. These must be sent from your backend using a SERVER API key directly via the Masivo REST API.

API

createClient(config)

Creates a Masivo client instance. Multiple calls with the same apiKey share a single AuthManager singleton — one bearer token, one background refresh timer — no matter how many client instances are created. The client handles authorization automatically: it exchanges your CLIENT API key for a bearer token on the first event, then refreshes it proactively every 5 minutes in the background.

| Parameter | Type | Required | Description | | --- | --- | --- | --- | | config.apiKey | string | Yes | Your Masivo CLIENT API key | | config.brandId | string \| null | No | Default brand ID injected into events that have a platform but no explicit brand_id |

Returns a MasivoClient with the following methods:

client.sendAnalyticsEvent(event)

Sends an event to Masivo on the analytics path. Events are buffered internally and sent in batches for efficiency.

| Field | Type | Required | Description | | --- | --- | --- | --- | | type | string | Yes | Event type (e.g. ADD_TO_CART, custom type) | | customer_id | string | Yes | External customer identifier | | brand_id | string \| null | Yes | Brand identifier, null if not applicable | | ...rest | unknown | No | Any additional event data |

Returns Promise<SendEventResult>:

{
  success: boolean;
  status: number; // HTTP status code
  data: unknown;  // Response payload
}

client.flush()

Forces an immediate send of all buffered events. Useful before navigating away or logging out.

await masivo.flush();

client.destroy()

Stops the background token refresh interval, clears all internal state, and removes the AuthManager instance from the singleton registry. Call this on logout to avoid memory leaks. After calling destroy(), the next createClient call with the same apiKey will start fresh.

masivo.destroy();

client.getToken()

Returns the current Bearer token, waiting for the initial authorization if necessary. Intended for sibling SDK packages (@masivo/rn) that need to make authenticated HTTP requests using the same credentials.

const token = await masivo.getToken();

Error Handling

import { createClient, MasivoError, MasivoServerKeyError, MasivoAuthError, MasivoNetworkError } from "@masivo/core";

const masivo = createClient({ apiKey: "your-client-api-key" });

try {
  await masivo.sendAnalyticsEvent({
    type: "ADD_TO_CART",
    customer_id: "customer-123",
    brand_id: null
  });
} catch (error) {
  if (error instanceof MasivoServerKeyError) {
    // You used a SERVER key instead of a CLIENT key
    console.error(error.message);
  } else if (error instanceof MasivoNetworkError) {
    // Network failure (no connectivity, DNS, timeout)
    console.error("Network error:", error.message);
  } else if (error instanceof MasivoAuthError) {
    // Invalid API key or authorization failure
    console.error("Auth error:", error.message, error.details);
  } else if (error instanceof MasivoError) {
    // API returned an error (400, 422, etc.)
    console.error("API error:", error.status, error.message);
  }
}

| Error class | When | Properties | | --- | --- | --- | | MasivoServerKeyError | SERVER API key used instead of CLIENT | message | | MasivoNetworkError | Fetch fails (no connectivity, DNS, etc.) | message | | MasivoAuthError | Authorization fails (invalid/expired key) | message, status, details | | MasivoError | API returns an error response | message, status, details |

Token Management

The SDK manages authentication transparently via the AuthManager singleton:

  1. On the first event, it exchanges your CLIENT API key for a bearer token via the authorize endpoint, sending an x-masivo-sdk: client header so the server verifies the key type.
  2. If you use a SERVER key, the server rejects the request and the SDK throws a MasivoServerKeyError with clear instructions.
  3. The token is proactively refreshed every 5 minutes in the background, so requests never fail due to expiry.
  4. If a request returns 401, the SDK invalidates the cached token and retries once with a fresh token.
  5. Concurrent requests share the same boot promise to avoid redundant authorization calls.
  6. Singleton per apiKey — multiple createClient calls with the same key share one AuthManager instance (one token state, one refresh timer). Calling destroy() removes the instance from the registry so the next client creation starts clean.

Batching Behavior

Events are queued and sent in bulk for efficiency:

| Trigger | Condition | | --- | --- | | Queue size | Flush when 100 events are queued | | Idle | Flush after 30 seconds with no new events | | Max wait | Flush after 60 seconds regardless of activity | | Manual | Call client.flush() to send immediately |

Compatibility

  • Node.js >= 18 (native fetch)
  • React Native (built-in fetch)
  • Browsers (built-in fetch)
  • Deno, Bun, or any runtime with global fetch

Zero external dependencies.

Links

License

MIT