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

data-studio-sdk

v1.0.6

Published

TypeScript SDK for Data Studio

Readme

Data Studio SDK

A TypeScript SDK for tracking user interactions, sessions, and events in your application. The SDK automatically handles client creation, session management, and event tracking with seamless backend synchronization via AWS SQS.

Table of Contents

Installation

npm install data-studio-sdk
# or
yarn add data-studio-sdk

Quick Start

import { DataStudioSDK } from "data-studio-sdk";

// Initialize the SDK with your API key
// Format: "tenantId@apiKey"
const sdk = new DataStudioSDK({
  apiKey: "your-tenant-id@your-api-key",
});

// The SDK automatically creates a client on initialization
// Start a session
await sdk.startSession();

// Track events
await sdk.sendRatingEvent({
  rating: 1,
  max: 5,
  raterId: "user-123",
});

// End session when done
await sdk.endSession();

API Reference

Initialization

new DataStudioSDK(config: DataStudioSDKConfig)

Creates a new instance of the Data Studio SDK.

Parameters:

  • config.apiKey (string, required): API key in the format "apiKey" (e.g., "123@1234-567-890")

Note: Your API key is available to copy from the Data Studio console.

Example:

const sdk = new DataStudioSDK({
  apiKey: "your-api-key",
});

Note: The SDK automatically:

  • Fetches credentials from the API
  • Initializes sync services (Client, Session, Event)
  • Creates a client on initialization

Client Management

createClient(input?: ClientInput): Promise<Client>

Creates a new client. This is automatically called during SDK initialization, but you can call it manually if needed.

Parameters:

  • input (ClientInput, optional): Manual client configuration. If not provided, the SDK auto-detects browser information in browser environments.

Returns: Promise<Client>

Example:

// Browser environment - auto-detects info
const client = await sdk.createClient();

// Node.js/server environment - manual input
const client = await sdk.createClient({
  clientType: "server",
  ip: "192.168.1.1",
  region: "us-east-1",
  city: "New York",
  timezone: "America/New_York",
});

getClient(): Client | null

Returns the current client instance.

Returns: Client | null

Example:

const client = sdk.getClient();
if (client) {
  console.log(`Client ID: ${client.id}`);
}

closeClient(): Promise<void>

Closes the current client. This automatically ends any active session and syncs the updated client to the backend.

Example:

await sdk.closeClient();

Session Management

startSession(input?: SessionInput): Promise<Session>

Starts a new session. A client must be created before starting a session.

Parameters:

  • input (SessionInput, optional): Session configuration
    • userId?: string - Optional user identifier
    • country?: string - Country code
    • deviceType?: string - Device type
    • referrer?: string - Referrer URL

Returns: Promise<Session>

Example:

const session = await sdk.startSession({
  userId: "user-123",
  country: "US",
  deviceType: "desktop",
  referrer: "https://example.com",
});

endSession(): Promise<void>

Ends the current active session. Calculates session duration and syncs to backend.

Example:

await sdk.endSession();

getCurrentSession(): Session | null

Returns the current active session.

Returns: Session | null

Example:

const session = sdk.getCurrentSession();
if (session) {
  console.log(`Session ID: ${session.id}, Status: ${session.status}`);
}

Event Tracking

The SDK provides methods for tracking various types of events. All event methods require an active session.

Feedback & Quality Events

Helpful for experience analytics.

Rating Submitted

sendRatingEvent(event: RatingEvent): Promise<void>

Sends a rating submitted event.

Parameters:

  • event.rating (number, required): rating value
  • event.max (number, required): Maximum rating value
  • event.source (string, optional): Source of the rating
  • event.raterId (string, optional): ID of the user providing the rating

Example:

await sdk.sendRatingEvent({
  rating: 1,
  max: 5,
  source: "product-page",
  raterId: "user-123",
});

Feedback Submitted

sendFeedbackEvent(event: FeedbackEvent): Promise<void>

Sends a feedback submitted event.

Parameters:

  • event.text (string, required): Feedback text
  • event.category (string, optional): Feedback category
  • event.rating (number, optional): Associated rating value
  • event.source (string, optional): Source of the feedback

Example:

await sdk.sendFeedbackEvent({
  text: "Great product! Very satisfied with the quality.",
  category: "product-quality",
  rating: 5,
  source: "feedback-form",
});

Bug Reported

sendBugReportEvent(event: BugReportEvent): Promise<void>

Sends a bug reported event.

Parameters:

  • event.description (string, required): Bug description
  • event.severity (string, optional): Bug severity level (e.g., "low", "medium", "high", "critical")
  • event.stepsToReproduce (string, optional): Steps to reproduce the bug
  • event.component (string, optional): Affected component or area

Example:

await sdk.sendBugReportEvent({
  description: "Button not responding on mobile devices",
  severity: "high",
  stepsToReproduce:
    "1. Open app on mobile 2. Click submit button 3. Nothing happens",
  component: "checkout-form",
});

Survey Started / Completed

sendSurveyEvent(event: SurveyEvent): Promise<void>

Sends a survey started or completed event.

Parameters:

  • event.surveyId (string, required): Unique survey identifier
  • event.status ("started" | "completed", required): Survey status
  • event.questionCount (number, optional): Number of questions in the survey
  • event.duration (number, optional): Duration in milliseconds

Example:

// Survey started
await sdk.sendSurveyEvent({
  surveyId: "survey-123",
  status: "started",
  questionCount: 10,
});

// Survey completed
await sdk.sendSurveyEvent({
  surveyId: "survey-123",
  status: "completed",
  questionCount: 10,
  duration: 120000, // 2 minutes in milliseconds
});

User Complaint Received

sendComplaintEvent(event: ComplaintEvent): Promise<void>

Sends a user complaint received event.

Parameters:

  • event.text (string, required): Complaint text
  • event.category (string, optional): Complaint category
  • event.priority (string, optional): Priority level (e.g., "low", "medium", "high", "urgent")
  • event.status (string, optional): Complaint status (e.g., "new", "in-progress", "resolved")

Example:

await sdk.sendComplaintEvent({
  text: "Unable to access my account after password reset",
  category: "account-access",
  priority: "high",
  status: "new",
});

Workflow & Business Process Events

Perfect for automation and internal tools.

sendWorkflowStartedEvent(event: WorkflowStartedEvent): Promise<void>

Sends a workflow started event.

Parameters:

  • event.workflowId (string, required): Unique workflow identifier
  • event.workflowName (string, optional): Name of the workflow
  • event.workflowType (string, optional): Type or category of the workflow
  • event.initiatorId (string, optional): ID of the user or system that initiated the workflow

Example:

await sdk.sendWorkflowStartedEvent({
  workflowId: "workflow-123",
  workflowName: "Order Processing",
  workflowType: "e-commerce",
  initiatorId: "user-456",
});
sendWorkflowStepCompletedEvent(event: WorkflowStepCompletedEvent): Promise<void>

Sends a workflow step completed event.

Parameters:

  • event.workflowId (string, required): Unique workflow identifier
  • event.stepId (string, required): Unique step identifier
  • event.stepName (string, optional): Name of the completed step
  • event.duration (number, optional): Duration of the step in milliseconds
  • event.status (string, optional): Status of the step completion

Example:

await sdk.sendWorkflowStepCompletedEvent({
  workflowId: "workflow-123",
  stepId: "step-456",
  stepName: "Payment Processing",
  duration: 2500,
  status: "success",
});
sendWorkflowErrorEvent(event: WorkflowErrorEvent): Promise<void>

Sends a workflow error event.

Parameters:

  • event.workflowId (string, required): Unique workflow identifier
  • event.stepId (string, optional): Step identifier where the error occurred
  • event.errorType (string, optional): Type or category of the error
  • event.errorMessage (string, optional): Detailed error message
  • event.errorCode (string, optional): Error code or identifier
  • event.severity (string, optional): Error severity level (e.g., "low", "medium", "high", "critical")

Example:

await sdk.sendWorkflowErrorEvent({
  workflowId: "workflow-123",
  stepId: "step-456",
  errorType: "validation_error",
  errorMessage: "Invalid payment method",
  errorCode: "PAYMENT_001",
  severity: "high",
});
sendWorkflowAbortedEvent(event: WorkflowAbortedEvent): Promise<void>

Sends a workflow aborted event.

Parameters:

  • event.workflowId (string, required): Unique workflow identifier
  • event.reason (string, optional): Reason for aborting the workflow
  • event.abortedBy (string, optional): ID of the user or system that aborted the workflow

Example:

await sdk.sendWorkflowAbortedEvent({
  workflowId: "workflow-123",
  reason: "User cancelled operation",
  abortedBy: "user-456",
});
sendDocumentCreatedEvent(event: DocumentCreatedEvent): Promise<void>

Sends a document created event.

Parameters:

  • event.documentId (string, required): Unique document identifier
  • event.documentType (string, optional): Type of document (e.g., "invoice", "contract", "report")
  • event.documentName (string, optional): Name of the document
  • event.creatorId (string, optional): ID of the user who created the document
  • event.templateId (string, optional): Template identifier if document was created from a template

Example:

await sdk.sendDocumentCreatedEvent({
  documentId: "doc-123",
  documentType: "invoice",
  documentName: "Invoice #2024-001",
  creatorId: "user-456",
  templateId: "template-invoice-v2",
});
sendDocumentApprovedEvent(event: DocumentApprovedEvent): Promise<void>

Sends a document approved event.

Parameters:

  • event.documentId (string, required): Unique document identifier
  • event.approverId (string, optional): ID of the user who approved the document
  • event.reason (string, optional): Reason for approval
  • event.comment (string, optional): Additional comments

Example:

await sdk.sendDocumentApprovedEvent({
  documentId: "doc-123",
  approverId: "user-789",
  reason: "All requirements met",
  comment: "Approved for production",
});
sendDocumentRejectedEvent(event: DocumentRejectedEvent): Promise<void>

Sends a document rejected event.

Parameters:

  • event.documentId (string, required): Unique document identifier
  • event.approverId (string, optional): ID of the user who rejected the document
  • event.reason (string, optional): Reason for rejection
  • event.comment (string, optional): Additional comments or feedback

Example:

await sdk.sendDocumentRejectedEvent({
  documentId: "doc-123",
  approverId: "user-789",
  reason: "Missing required information",
  comment: "Please add customer signature before resubmission",
});
sendTaskAssignedEvent(event: TaskAssignedEvent): Promise<void>

Sends a task assigned event.

Parameters:

  • event.taskId (string, required): Unique task identifier
  • event.taskName (string, optional): Name of the task
  • event.assigneeId (string, optional): ID of the user assigned to the task
  • event.assignerId (string, optional): ID of the user who assigned the task
  • event.priority (number, optional): Task priority level (higher numbers indicate higher priority)
  • event.dueDate (number, optional): Due date timestamp in milliseconds

Example:

await sdk.sendTaskAssignedEvent({
  taskId: "task-123",
  taskName: "Review quarterly report",
  assigneeId: "user-456",
  assignerId: "user-789",
  priority: 5,
  dueDate: Date.now() + 7 * 24 * 60 * 60 * 1000, // 7 days from now
});
sendTaskCompletedEvent(event: TaskCompletedEvent): Promise<void>

Sends a task completed event.

Parameters:

  • event.taskId (string, required): Unique task identifier
  • event.completedBy (string, optional): ID of the user who completed the task
  • event.duration (number, optional): Duration to complete the task in milliseconds
  • event.status (string, optional): Completion status (e.g., "completed", "cancelled", "failed")
  • event.outcome (string, optional): Outcome or result of the task

Example:

await sdk.sendTaskCompletedEvent({
  taskId: "task-123",
  completedBy: "user-456",
  duration: 3600000, // 1 hour in milliseconds
  status: "completed",
  outcome: "All items reviewed and approved",
});

Custom Events

sendCustomEvent(event: Event): Promise<void>

Sends a custom event with full control over the event structure.

Parameters:

  • event (Event, required): Custom event object conforming to the Event interface

Example:

await sdk.sendCustomEvent({
  id: "custom-event-123",
  tenantId: "tenant-123",
  sessionId: "session-123",
  timestamp: Date.now(),
  eventType: "custom",
  properties: {
    string1: "custom-value",
    num1: 42,
    bool1: true,
  },
});

Event Types

The SDK supports the following event types:

| Event Type | Constant | Description | | ----------------------- | ------------------------- | -------------------------------------- | | Rating | RATING | User rating events | | Custom | CUSTOM | Custom events with flexible properties | | Feedback Submitted | FEEDBACK_SUBMITTED | User feedback submission | | Bug Reported | BUG_REPORTED | Bug report events | | Survey | SURVEY | Survey started/completed events | | Complaint Received | COMPLAINT_RECEIVED | User complaint events | | Workflow Started | WORKFLOW_STARTED | Workflow initiation events | | Workflow Step Completed | WORKFLOW_STEP_COMPLETED | Workflow step completion events | | Workflow Error | WORKFLOW_ERROR | Workflow error events | | Workflow Aborted | WORKFLOW_ABORTED | Workflow abortion events | | Document Created | DOCUMENT_CREATED | Document creation events | | Document Approved | DOCUMENT_APPROVED | Document approval events | | Document Rejected | DOCUMENT_REJECTED | Document rejection events | | Task Assigned | TASK_ASSIGNED | Task assignment events | | Task Completed | TASK_COMPLETED | Task completion events |


Type Definitions

ClientInput

interface ClientInput {
  clientType: "browser" | "server";
  ip?: string;
  region?: string;
  city?: string;
  timezone?: string;
  os?: string;
  osVersion?: string;
  browser?: string;
  browserVersion?: string;
  screenResolution?: string;
  utmSource?: string;
  utmMedium?: string;
  utmCampaign?: string;
}

SessionInput

interface SessionInput {
  userId?: string;
  country?: string;
  deviceType?: string;
  referrer?: string;
}

RatingEvent

interface RatingEvent {
  min: number;
  max: number;
  source?: string;
  raterId?: string;
}

FeedbackEvent

interface FeedbackEvent {
  text: string;
  category?: string;
  rating?: number;
  source?: string;
}

BugReportEvent

interface BugReportEvent {
  description: string;
  severity?: string;
  stepsToReproduce?: string;
  component?: string;
}

SurveyEvent

interface SurveyEvent {
  surveyId: string;
  status: "started" | "completed";
  questionCount?: number;
  duration?: number;
}

ComplaintEvent

interface ComplaintEvent {
  text: string;
  category?: string;
  priority?: string;
  status?: string;
}

WorkflowStartedEvent

interface WorkflowStartedEvent {
  workflowId: string;
  workflowName?: string;
  workflowType?: string;
  initiatorId?: string;
}

WorkflowStepCompletedEvent

interface WorkflowStepCompletedEvent {
  workflowId: string;
  stepId: string;
  stepName?: string;
  duration?: number;
  status?: string;
}

WorkflowErrorEvent

interface WorkflowErrorEvent {
  workflowId: string;
  stepId?: string;
  errorType?: string;
  errorMessage?: string;
  errorCode?: string;
  severity?: string;
}

WorkflowAbortedEvent

interface WorkflowAbortedEvent {
  workflowId: string;
  reason?: string;
  abortedBy?: string;
}

DocumentCreatedEvent

interface DocumentCreatedEvent {
  documentId: string;
  documentType?: string;
  documentName?: string;
  creatorId?: string;
  templateId?: string;
}

DocumentApprovedEvent

interface DocumentApprovedEvent {
  documentId: string;
  approverId?: string;
  reason?: string;
  comment?: string;
}

DocumentRejectedEvent

interface DocumentRejectedEvent {
  documentId: string;
  approverId?: string;
  reason?: string;
  comment?: string;
}

TaskAssignedEvent

interface TaskAssignedEvent {
  taskId: string;
  taskName?: string;
  assigneeId?: string;
  assignerId?: string;
  priority?: number;
  dueDate?: number;
}

TaskCompletedEvent

interface TaskCompletedEvent {
  taskId: string;
  completedBy?: string;
  duration?: number;
  status?: string;
  outcome?: string;
}

Examples

Complete Workflow Example

import { DataStudioSDK } from "data-studio-sdk";

async function trackUserJourney() {
  // Initialize SDK
  const sdk = new DataStudioSDK({
    apiKey: "your-tenant-id@your-api-key",
  });

  try {
    // Client is automatically created on initialization
    // Start a session
    await sdk.startSession({
      userId: "user-123",
      country: "US",
    });

    // Track various events
    await sdk.sendRatingEvent({
      rating: 1,
      max: 5,
      raterId: "user-123",
    });

    await sdk.sendFeedbackEvent({
      text: "Love the new design!",
      category: "ui-feedback",
      rating: 5,
    });

    await sdk.sendSurveyEvent({
      surveyId: "satisfaction-survey-2024",
      status: "started",
      questionCount: 5,
    });

    // ... user completes survey ...

    await sdk.sendSurveyEvent({
      surveyId: "satisfaction-survey-2024",
      status: "completed",
      questionCount: 5,
      duration: 45000, // 45 seconds
    });

    // End session
    await sdk.endSession();

    // Close client
    await sdk.closeClient();
  } catch (error) {
    console.error("Error tracking events:", error);
  }
}

Browser Integration Example

// In your React/Vue/Angular component
import { DataStudioSDK } from "data-studio-sdk";

// Initialize once (e.g., in app initialization)
const sdk = new DataStudioSDK({
  apiKey: process.env.REACT_APP_DATA_STUDIO_API_KEY!,
});

// Start session when user lands on page
useEffect(() => {
  sdk.startSession({
    userId: currentUser?.id,
    referrer: document.referrer,
  });

  return () => {
    // End session on component unmount
    sdk.endSession();
  };
}, []);

// Track events on user interactions
const handleRatingSubmit = async (rating: number) => {
  await sdk.sendRatingEvent({
    rating: 1,
    max: 5,
    raterId: currentUser?.id,
  });
};

const handleFeedbackSubmit = async (feedback: string) => {
  await sdk.sendFeedbackEvent({
    text: feedback,
    category: "general",
    source: "contact-form",
  });
};

Node.js/Server Example

import { DataStudioSDK } from "data-studio-sdk";

// Initialize with server-specific configuration
const sdk = new DataStudioSDK({
  apiKey: process.env.DATA_STUDIO_API_KEY!,
});

// Create client with server info
await sdk.createClient({
  clientType: "server",
  ip: req.ip,
  region: "us-east-1",
  city: "New York",
  timezone: "America/New_York",
});

// Start session
await sdk.startSession({
  userId: req.user.id,
  country: req.headers["cf-ipcountry"] as string,
});

// Track server-side events
await sdk.sendBugReportEvent({
  description: "API endpoint returning 500 error",
  severity: "critical",
  component: "payment-api",
});

Best Practices

  1. Initialize Once: Create a single SDK instance and reuse it throughout your application lifecycle.

  2. Session Management:

    • Start a session when a user begins their journey
    • End the session when they leave or after a period of inactivity
    • Don't create multiple concurrent sessions
  3. Error Handling: Always wrap SDK calls in try-catch blocks to handle potential errors gracefully.

  4. Async/Await: All SDK methods are asynchronous. Always use await or handle promises appropriately.

  5. Event Context: The SDK automatically adds context (sessionId, clientId, tenantId, timestamp) to all events. You don't need to provide this manually.

  6. Browser vs Server:

    • In browser environments, the SDK auto-detects device and browser information
    • In server environments, provide client information manually via createClient()
  7. Cleanup: Always call endSession() and closeClient() when appropriate to ensure data is properly synced.