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

billdogeng-node

v1.0.0-beta.1

Published

Official BilldogEng server SDK for Node.js — Analytics, Feature Flags (remote + local eval), Surveys, Messaging, and LLM observability.

Readme

billdogeng-node

Official BilldogEng server SDK for Node.js / TypeScript — the engagement suite for server-side use: Analytics, Feature Flags (remote + local evaluation), Surveys (data API), Messaging dispatch, and LLM observability.

This is the canonical reference implementation that the other billdogeng-{python,go,php,ruby,java,rust,dotnet,elixir} SDKs mirror.

Install

npm install billdogeng-node

Requires Node.js ≥ 18 (uses the built-in global fetch).

Quickstart

import { BilldogEng } from 'billdogeng-node';

const bd = new BilldogEng('bd_test_xxx', {
  // host: 'https://api.billdog.io/v1',  // default
  flushAt: 20,            // batch size that triggers a flush
  flushInterval: 10_000,  // ms background flush cadence
  localEvaluation: true,  // server-only: evaluate flags locally
});

// ─ Analytics ─ (batched + flushed automatically)
bd.capture('user-123', 'order_completed', { revenue: 49.99 }, { company: 'acme' });
bd.identify('user-123', { email: '[email protected]', plan: 'pro' });
bd.groupIdentify('company', 'acme', { seats: 50 });
bd.alias('user-123', 'anon-abc');

// ─ Feature flags ─
const on = await bd.isFeatureEnabled('new_checkout', 'user-123');
const variant = await bd.getFeatureFlag('paywall_test', 'user-123');       // boolean | variant key | null
const payload = await bd.getFeatureFlagPayload('paywall_test', 'user-123'); // variant config
const all = await bd.getAllFlags('user-123');

// ─ Surveys (data API) ─
const surveys = await bd.surveys.list('user-123');
const config = await bd.surveys.fetch(surveys[0].id, 'user-123');
const { respondent_id } = await bd.surveys.start(config.id, { customerId: 'user-123', idempotencyKey: 'k1' });
await bd.surveys.submit(config.id, [{ question_id: 'q1', answer_number: 9 }], { respondentId: respondent_id });

// ─ Messaging dispatch ─ (Bearer JWT auth, not the API key)
await bd.messaging.dispatch({
  projectId: 'project-uuid',
  channel: 'push',
  content: { title: 'Hi', body: 'There' },
  targeting: { type: 'all' },
  scheduling: { deliveryType: 'immediate' },
  accessToken: '<supabase-session-jwt>',
});

// ─ LLM observability ─
await bd.captureTrace({
  traceId: 't-1', spanId: 's-1', model: 'gpt-4o',
  inputText: 'prompt', outputText: 'completion',
  promptTokens: 100, completionTokens: 50, durationMs: 820, costUsd: 0.003,
});

// Flush remaining events + stop the background timer before exit.
await bd.shutdown();

Configuration

| Option | Default | Description | | ----------------- | ------------------------------ | ----------- | | host | https://api.billdog.io/v1 | API base URL | | flushAt | 20 | Batch size that triggers a flush | | flushInterval | 10000 | Background flush cadence (ms) | | maxQueueSize | 1000 | Drop oldest events past this many queued | | gzip | true | Gzip large request bodies | | localEvaluation | false | Evaluate feature flags locally (server-only) | | requestTimeout | 10000 | Per-request timeout (ms) | | maxRetries | 3 | Retry attempts for 5xx / 429 / network errors | | groupTypeIndex | — | Stable group-type → $group_0..4 index map | | enableLogging | false | Verbose diagnostics to console |

Authentication uses the x-api-key: <apiKey> header (bd_test_* sandbox / bd_live_* live) on every request, except messaging dispatch, which authenticates with a Supabase session Bearer JWT + project membership.

Analytics batching & delivery

  • Events accumulate in an in-memory queue and ship as a single batched POST to /ingest-events.
  • A flush happens on flushAt, every flushInterval, or on flush() / shutdown().
  • Failed flushes re-queue their batch (never lose events on a transient failure); the transport also retries with exponential backoff (1s, 2s, 4s).
  • Bodies are gzip-compressed when large enough to benefit.

Feature flags — local evaluation

With localEvaluation: true, the SDK fetches flag definitions once (POST /feature-flag-definitions), caches them for 5 minutes, and evaluates deterministically on-process:

  1. missing/inactive → false
  2. ALL targeting_rules must match personProperties, else false
  3. bucket = murmurhash3("{key}.{distinctId}") % 100; ON iff bucket < rollout_percentage
  4. multivariate: walk variants by cumulative rollout within the ON bucket → variant key

The murmurhash3 (32-bit, seed 0) implementation is byte-identical across web / iOS / Android / all server SDKs, so a user buckets the same everywhere.

Build & test

npm install
npm run build   # tsc → dist/
npm test        # vitest

License

MIT