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

@infrasamurai/sdk-js

v0.0.1

Published

TypeScript SDK for InfraSamurai metrics, alerting, and APM tracing

Readme

@infrasamurai/sdk-js

TypeScript SDK for InfraSamurai metrics, alerting, and APM tracing.

Installation

npm install @infrasamurai/sdk-js

Features

| Entry Point | Purpose | Runtime | |-------------|---------|---------| | @infrasamurai/sdk-js | Core client (metrics & alerts) | Node.js, Browser, Deno, Bun | | @infrasamurai/sdk-js/node | APM auto-instrumentation | Node.js only | | @infrasamurai/sdk-js/browser | Browser APM tracing | Browser only | | @infrasamurai/sdk-js/queues | Queue metrics | Node.js, Deno, Bun |


Quick Start

Metrics & Alerts

import { InfraSamuraiClient } from "@infrasamurai/sdk-js";

const client = new InfraSamuraiClient({
  dsn: "your-project-dsn",
  environment: "production",
});

// Send a metric
await client.sendMetric({
  metricType: "photo_upload_speed",
  value: 2.5,
  unit: "MB/s",
});

// Send alerts
await client.critical("Server down!");
await client.error("Failed to process payment");
await client.warning("High memory usage");
await client.info("User signed in");

Node.js APM (Auto-Instrumentation)

// tracing.ts - Create this file and import it FIRST in your entry point
import { InfraSamuraiNode } from "@infrasamurai/sdk-js/node";

InfraSamuraiNode.init({
  dsn: process.env.ALERTSAMURAI_DSN!,
  serviceName: "my-api",
  serviceVersion: "1.0.0",
  environment: process.env.NODE_ENV,
});

// main.ts
import "./tracing"; // MUST be first import!
import { NestFactory } from "@nestjs/core";
// ... rest of your app

Browser APM

import { InfraSamuraiBrowser } from "@infrasamurai/sdk-js/browser";

InfraSamuraiBrowser.init({
  dsn: "your-project-dsn",
  serviceName: "my-frontend",
  environment: "production",
});

// Set user context for all traces
InfraSamuraiBrowser.setUser({
  id: "user-123",
  email: "[email protected]",
});

Queue Metrics

import { InfraSamuraiQueues } from "@infrasamurai/sdk-js/queues";

const queues = InfraSamuraiQueues.init({
  dsn: process.env.ALERTSAMURAI_DSN!,
  environment: "production",
});

// Record queue metrics periodically
setInterval(async () => {
  const stats = await getQueueStats();
  await queues.recordMetrics("orders-queue", {
    depth: stats.pending,
    consumerLag: stats.lag,
    processedCount: stats.processed,
    failedCount: stats.failed,
  });
}, 60000);

Core Client

Configuration

const client = new InfraSamuraiClient({
  dsn: "your-dsn",           // Required - found in project settings
  environment: "production", // Optional - default environment
  baseUrl: "https://...",    // Optional - API endpoint
  timeout: 30000,            // Optional - request timeout (ms)
  retries: 3,                // Optional - retry attempts
  silent: true,              // Optional - suppress console warnings
});

Metrics API

await client.sendMetric({
  metricType: "photo_upload_speed", // Required - metric name (max 100 chars)
  value: 2.5,                       // Required - numeric value
  unit: "MB/s",                     // Optional - unit (max 50 chars)
  environment: "production",        // Optional - overrides default
  metadata: { userId: "123" },      // Optional - additional context
  timestamp: new Date(),            // Optional - defaults to now
});

Alerts API

await client.sendAlert({
  message: "Database connection failed", // Required (max 4000 chars)
  priority: "critical",                  // critical|error|warning|info|debug
  environment: "production",             // Optional
  data: { errorCode: "ECONNREFUSED" },   // Optional context
});

// Convenience methods
await client.critical("Server down!");
await client.error("Payment failed", { orderId: "123" });
await client.warning("High memory usage");
await client.info("User signed in");
await client.debug("Cache miss");

Error Handling

The client is fault-tolerant - it never throws errors that could crash your application:

const result = await client.sendMetric({ metricType: "test", value: 123 });

if (!result.success) {
  console.error("Failed:", result.error);
  // result.disabled === true if DSN is missing
}

For explicit error handling:

import {
  InfraSamuraiError,
  AuthenticationError,  // 401 - Invalid DSN
  ValidationError,      // 400 - Invalid request
  NetworkError,         // Timeout, connection failure
} from "@infrasamurai/sdk-js";

Retry Logic

  • Default: 3 retries with exponential backoff (1s → 2s → 4s, max 10s)
  • Does NOT retry on 401 (auth) or 400 (validation) errors

Node.js APM

Configuration

import { InfraSamuraiNode } from "@infrasamurai/sdk-js/node";

InfraSamuraiNode.init({
  // Required
  dsn: process.env.ALERTSAMURAI_DSN!,
  serviceName: "my-api",

  // Optional
  serviceVersion: "1.0.0",
  environment: "production",
  baseUrl: "https://monitor.infrasamurai.com",

  // Sampling (0.0 to 1.0, default: 1.0)
  sampleRate: 0.1,         // Trace 10% of requests
  errorsSampleRate: 1.0,   // Capture 100% of errors
  sessionSampleRate: 1.0,  // Sample by instance

  // Auto-instrumentation toggles
  instrumentations: {
    http: true,      // HTTP incoming/outgoing (default: true)
    express: true,   // Express.js (default: true)
    nestjs: true,    // NestJS (default: true)
    prisma: true,    // Prisma ORM (default: true)
    redis: true,     // Redis/ioredis (default: true)
    pg: true,        // PostgreSQL (default: true)
    grpc: true,      // gRPC (default: true)
    fs: false,       // Filesystem (default: false - noisy)
    dns: false,      // DNS lookups (default: false - noisy)
  },

  // Custom attributes for all spans
  resourceAttributes: {
    "deployment.region": "us-east-1",
  },

  silent: false,  // Suppress warnings
  debug: true,    // Verbose logging
});

Auto-Instrumented Libraries

The Node.js SDK automatically traces:

| Library | What's Captured | |---------|-----------------| | HTTP/HTTPS | All incoming requests, outgoing calls | | Express | Routes, middleware, errors | | NestJS | Controllers, guards, interceptors | | Prisma | All database queries with statements | | PostgreSQL (pg) | Raw SQL queries | | Redis/ioredis | All Redis commands | | gRPC | Client and server calls | | MySQL | Database queries | | MongoDB | Database operations |

Manual Error Capture

try {
  await riskyOperation();
} catch (error) {
  InfraSamuraiNode.captureError(error, {
    component: "PaymentService",
    action: "processPayment",
  });
}

Shutdown

// Flush pending spans before exit (for serverless)
await InfraSamuraiNode.flush();

// Full shutdown
await InfraSamuraiNode.shutdown();

Browser APM

Configuration

import { InfraSamuraiBrowser } from "@infrasamurai/sdk-js/browser";

InfraSamuraiBrowser.init({
  // Required
  dsn: "your-project-dsn",
  serviceName: "my-frontend",

  // Optional
  serviceVersion: "1.0.0",
  environment: "production",

  // Sampling
  sampleRate: 0.1,        // Trace 10% of sessions
  errorsSampleRate: 1.0,  // Capture all errors

  // Auto-instrumentation
  instrumentations: {
    documentLoad: true,      // Page load metrics (LCP, FCP, TTFB)
    fetch: true,             // Fetch/XHR requests
    userInteraction: false,  // Clicks, form submissions (noisy)
    errors: true,            // Uncaught errors, unhandled rejections
  },

  // Distributed tracing - add trace headers to these URLs
  propagateTraceHeaderUrls: [
    /^https:\/\/api\.example\.com/,
    window.location.origin,
  ],

  // URLs to ignore
  ignoreUrls: [
    /\/health$/,
    /google-analytics\.com/,
  ],
});

User Context

// Set user after login
InfraSamuraiBrowser.setUser({
  id: "user-123",
  email: "[email protected]",
  username: "john_doe",
  plan: "premium",  // Custom attributes
});

// Clear on logout
InfraSamuraiBrowser.clearUser();

// Get current user
const user = InfraSamuraiBrowser.getUser();

Manual Tracing

// Wrap async operations
const result = await InfraSamuraiBrowser.trace(
  "checkout.process",
  async (span) => {
    span.setAttribute("cart.items", 5);
    return await processCheckout();
  }
);

Manual Error Capture

InfraSamuraiBrowser.captureError(error, {
  component: "CheckoutForm",
  action: "submit",
});

Queue Metrics

For monitoring Kafka, RabbitMQ, SQS, BullMQ, or any message queue.

Configuration

import { InfraSamuraiQueues } from "@infrasamurai/sdk-js/queues";

const queues = InfraSamuraiQueues.init({
  dsn: process.env.ALERTSAMURAI_DSN!,
  environment: "production",
  timeout: 10000,  // Request timeout (ms)
  silent: false,
});

Recording Metrics

// Full metrics
await queues.recordMetrics("orders-queue", {
  depth: 150,                    // Messages waiting
  consumerLag: 50,               // Messages behind
  dlqCount: 3,                   // Dead letter queue count
  oldestMessageAgeSeconds: 120,  // Age of oldest message
  processedCount: 1000,          // Successfully processed
  failedCount: 5,                // Failed messages
  avgProcessingTimeMs: 45,       // Average processing time
  enqueueRate: 10.5,             // Messages/sec enqueued
  dequeueRate: 9.8,              // Messages/sec dequeued
});

// Convenience methods
await queues.recordDepth("orders-queue", 150);
await queues.recordConsumerLag("orders-queue", 50);
await queues.recordDlq("orders-queue", 3);
await queues.recordProcessing("orders-queue", 1000, 5, 45);

BullMQ Example

import { Queue } from "bullmq";

const queue = new Queue("orders");

setInterval(async () => {
  const [waiting, active, failed, delayed] = await Promise.all([
    queue.getWaitingCount(),
    queue.getActiveCount(),
    queue.getFailedCount(),
    queue.getDelayedCount(),
  ]);

  await queues.recordMetrics("orders", {
    depth: waiting + delayed,
    processedCount: active,
    failedCount: failed,
  });
}, 60000);

TypeScript Types

import type {
  // Core client
  InfraSamuraiConfig,
  SendMetricOptions,
  SendMetricResponse,
  SendAlertOptions,
  SendAlertResponse,
  AlertPriority,

  // Queue metrics
  QueueConfig,
  QueueMetrics,
  QueueMetricsResponse,
} from "@infrasamurai/sdk-js";

// APM types (re-exported from OpenTelemetry)
import type { Span, Tracer, SpanContext } from "@infrasamurai/sdk-js/node";

Runtime Compatibility

| Entry Point | Node.js | Browser | Deno | Bun | |-------------|---------|---------|------|-----| | @infrasamurai/sdk-js | ✅ | ✅ | ✅ | ✅ | | @infrasamurai/sdk-js/node | ✅ | ❌ | ❌ | ⚠️ | | @infrasamurai/sdk-js/browser | ❌ | ✅ | ❌ | ❌ | | @infrasamurai/sdk-js/queues | ✅ | ❌ | ✅ | ✅ |

Note: Node.js APM auto-instrumentation uses monkey-patching via require-in-the-middle, which doesn't work in Deno and has limited support in Bun.


Requirements

  • Node.js 18+ (for native fetch) or browser environment
  • TypeScript 5.0+ (for type definitions)

Dependencies

The SDK uses OpenTelemetry for APM tracing:

Required:

  • @opentelemetry/api
  • @opentelemetry/core
  • @opentelemetry/resources
  • @opentelemetry/sdk-trace-base
  • @opentelemetry/exporter-trace-otlp-http

Optional (for auto-instrumentation):

  • @opentelemetry/sdk-node
  • @opentelemetry/auto-instrumentations-node
  • @prisma/instrumentation

License

MIT