CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-langfuse--core

Core functions and utilities for Langfuse packages including API client, logging, media handling, and OpenTelemetry tracing attributes

Overview
Eval results
Files

utils.mddocs/

Utilities

Cross-platform utility functions for UUID generation, base64 encoding/decoding, environment variable access, and safe timeouts. All utilities work in both Node.js and browser environments.

Capabilities

UUID Generation

/**
 * Generates a UUID v4 string
 * @param globalThis - Optional global object (for testing/customization)
 * @returns A UUID v4 string in the format "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
 */
function generateUUID(globalThis?: any): string;

Import:

import { generateUUID } from '@langfuse/core';

Description: Generates a random UUID v4 compliant with RFC 4122. Uses a timestamp-based random number generation algorithm for cross-platform compatibility in both Node.js and browser environments.

Usage Examples:

import { generateUUID } from '@langfuse/core';

// Generate a UUID
const id = generateUUID();
console.log(id);  // "a3bb189e-8bf9-3888-9912-ace4e6543002"

// Use for trace IDs
const traceId = generateUUID();
await client.ingestion.batch({
  batch: [{
    type: 'trace-create',
    id: generateUUID(),  // Event ID
    timestamp: new Date().toISOString(),
    body: {
      id: traceId,
      name: 'My Trace'
    }
  }]
});

// Generate multiple unique IDs
const ids = Array.from({ length: 10 }, () => generateUUID());
console.log(ids);  // Array of 10 unique UUIDs

Environment Variables

/**
 * Gets environment variable values from process.env or globalThis
 * @param key - The environment variable name
 * @returns The environment variable value or undefined
 */
function getEnv(key: LangfuseEnvVar): string | undefined;

type LangfuseEnvVar =
  | "LANGFUSE_PUBLIC_KEY"
  | "LANGFUSE_SECRET_KEY"
  | "LANGFUSE_BASE_URL"
  | "LANGFUSE_BASEURL"              // Legacy v2
  | "LANGFUSE_TIMEOUT"
  | "LANGFUSE_FLUSH_AT"
  | "LANGFUSE_FLUSH_INTERVAL"
  | "LANGFUSE_LOG_LEVEL"
  | "LANGFUSE_RELEASE"
  | "LANGFUSE_TRACING_ENVIRONMENT";

Import:

import { getEnv } from '@langfuse/core';

Description: Safely retrieves Langfuse environment variables from either process.env (Node.js) or globalThis (browser). Returns undefined if the variable is not set.

Supported Environment Variables:

  • LANGFUSE_PUBLIC_KEY - Public API key for authentication
  • LANGFUSE_SECRET_KEY - Secret API key for authentication
  • LANGFUSE_BASE_URL - Base API URL (e.g., "https://cloud.langfuse.com")
  • LANGFUSE_BASEURL - Legacy base URL (v2 compatibility)
  • LANGFUSE_TIMEOUT - Request timeout in milliseconds
  • LANGFUSE_FLUSH_AT - Batch size for flushing operations
  • LANGFUSE_FLUSH_INTERVAL - Flush interval in milliseconds
  • LANGFUSE_LOG_LEVEL - Logging level (DEBUG, INFO, WARN, ERROR)
  • LANGFUSE_RELEASE - Release identifier for traces
  • LANGFUSE_TRACING_ENVIRONMENT - Environment identifier for traces

Usage Examples:

import { getEnv, LangfuseAPIClient } from '@langfuse/core';

// Get API keys from environment
const publicKey = getEnv('LANGFUSE_PUBLIC_KEY');
const secretKey = getEnv('LANGFUSE_SECRET_KEY');

if (!publicKey || !secretKey) {
  throw new Error('Missing Langfuse API keys');
}

// Initialize client with environment variables
const client = new LangfuseAPIClient({
  environment: getEnv('LANGFUSE_BASE_URL') || 'https://cloud.langfuse.com',
  username: publicKey,
  password: secretKey
});

// Get configuration values
const timeout = parseInt(getEnv('LANGFUSE_TIMEOUT') || '60000');
const logLevel = getEnv('LANGFUSE_LOG_LEVEL') || 'INFO';
const release = getEnv('LANGFUSE_RELEASE');

console.log(`Using timeout: ${timeout}ms, log level: ${logLevel}`);

Base64 Encoding/Decoding

Cross-platform base64 utilities that work in Node.js, browsers, and edge runtimes.

/**
 * Encodes a UTF-8 string to base64
 * @param input - UTF-8 string to encode
 * @returns Base64 encoded string
 */
function base64Encode(input: string): string;

/**
 * Decodes a base64 string to UTF-8
 * @param input - Base64 encoded string
 * @returns Decoded UTF-8 string
 */
function base64Decode(input: string): string;

/**
 * Converts a base64 string to a Uint8Array of bytes
 * @param base64 - Base64 encoded string
 * @returns Uint8Array of decoded bytes
 */
function base64ToBytes(base64: string): Uint8Array;

/**
 * Converts a Uint8Array of bytes to a base64 string
 * @param bytes - Byte array to encode
 * @returns Base64 encoded string
 */
function bytesToBase64(bytes: Uint8Array): string;

Import:

import {
  base64Encode,
  base64Decode,
  base64ToBytes,
  bytesToBase64
} from '@langfuse/core';

base64Encode()

Encodes a UTF-8 string to base64. Works in both Node.js and browser environments.

Usage Examples:

import { base64Encode } from '@langfuse/core';

// Encode simple string
const encoded = base64Encode('Hello, World!');
console.log(encoded);  // "SGVsbG8sIFdvcmxkIQ=="

// Encode JSON
const data = { name: 'Alice', age: 30 };
const encodedJson = base64Encode(JSON.stringify(data));
console.log(encodedJson);  // "eyJuYW1lIjoiQWxpY2UiLCJhZ2UiOjMwfQ=="

// Encode Unicode
const unicode = base64Encode('Hello 世界 🌍');
console.log(unicode);  // Properly encoded UTF-8

base64Decode()

Decodes a base64 string to UTF-8.

Usage Examples:

import { base64Decode } from '@langfuse/core';

// Decode simple string
const decoded = base64Decode('SGVsbG8sIFdvcmxkIQ==');
console.log(decoded);  // "Hello, World!"

// Decode JSON
const encodedJson = 'eyJuYW1lIjoiQWxpY2UiLCJhZ2UiOjMwfQ==';
const decodedJson = base64Decode(encodedJson);
const data = JSON.parse(decodedJson);
console.log(data);  // { name: 'Alice', age: 30 }

// Decode Unicode
const unicode = base64Decode('SGVsbG8g5LiW55WMIPCfjI0=');
console.log(unicode);  // "Hello 世界 🌍"

base64ToBytes()

Converts a base64 string to a Uint8Array of bytes.

Usage Examples:

import { base64ToBytes } from '@langfuse/core';

// Decode to bytes
const base64 = 'SGVsbG8=';
const bytes = base64ToBytes(base64);
console.log(bytes);  // Uint8Array(5) [72, 101, 108, 108, 111]

// Convert to string
const text = new TextDecoder().decode(bytes);
console.log(text);  // "Hello"

// Use with binary data
const imageBase64 = 'iVBORw0KGgoAAAA...';
const imageBytes = base64ToBytes(imageBase64);
console.log(`Image size: ${imageBytes.length} bytes`);

bytesToBase64()

Converts a Uint8Array of bytes to a base64 string.

Usage Examples:

import { bytesToBase64 } from '@langfuse/core';

// Encode bytes
const bytes = new Uint8Array([72, 101, 108, 108, 111]);
const base64 = bytesToBase64(bytes);
console.log(base64);  // "SGVsbG8="

// Encode binary data
const binaryData = new Uint8Array([0xFF, 0xD8, 0xFF, 0xE0]);
const encoded = bytesToBase64(binaryData);
console.log(encoded);  // "/9j/4A=="

// Round-trip conversion
const original = new Uint8Array([1, 2, 3, 4, 5]);
const encoded2 = bytesToBase64(original);
const decoded = base64ToBytes(encoded2);
console.log(decoded);  // Uint8Array(5) [1, 2, 3, 4, 5]

Safe Timeout

/**
 * Sets a timeout that unref's itself in Node.js environments to prevent hanging on exit
 * @param fn - Function to execute after timeout
 * @param timeout - Timeout duration in milliseconds
 * @returns The timeout handle
 */
function safeSetTimeout(fn: () => void, timeout: number): any;

Import:

import { safeSetTimeout } from '@langfuse/core';

Description: Creates a timeout that automatically unref's itself in Node.js environments. This prevents the timeout from keeping the process alive if it's the only pending operation, allowing for clean process exits.

Usage Examples:

import { safeSetTimeout } from '@langfuse/core';

// Schedule a delayed operation
safeSetTimeout(() => {
  console.log('This runs after 5 seconds');
}, 5000);

// In a long-running service
class BatchProcessor {
  private timeoutHandle: any;

  scheduleNextFlush() {
    // Clear existing timeout
    if (this.timeoutHandle) {
      clearTimeout(this.timeoutHandle);
    }

    // Schedule next flush (won't prevent process exit)
    this.timeoutHandle = safeSetTimeout(() => {
      this.flush();
      this.scheduleNextFlush();
    }, 30000);  // 30 seconds
  }

  flush() {
    console.log('Flushing batch...');
    // Flush logic
  }

  shutdown() {
    if (this.timeoutHandle) {
      clearTimeout(this.timeoutHandle);
    }
  }
}

// Retry logic with safe timeout
async function retryWithBackoff<T>(
  fn: () => Promise<T>,
  maxRetries: number = 3
): Promise<T> {
  let lastError: Error | undefined;

  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error as Error;

      if (i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000;  // Exponential backoff
        await new Promise(resolve => safeSetTimeout(resolve, delay));
      }
    }
  }

  throw lastError;
}

Usage Patterns

Complete Client Initialization

import {
  LangfuseAPIClient,
  getEnv,
  configureGlobalLogger,
  LogLevel
} from '@langfuse/core';

// Configure logger from environment
const logLevelMap: Record<string, LogLevel> = {
  'DEBUG': LogLevel.DEBUG,
  'INFO': LogLevel.INFO,
  'WARN': LogLevel.WARN,
  'ERROR': LogLevel.ERROR
};

const logLevel = logLevelMap[getEnv('LANGFUSE_LOG_LEVEL') || 'INFO'];
configureGlobalLogger({
  level: logLevel,
  prefix: 'Langfuse',
  enableTimestamp: true
});

// Initialize client with environment variables
const client = new LangfuseAPIClient({
  environment: getEnv('LANGFUSE_BASE_URL') || 'https://cloud.langfuse.com',
  username: getEnv('LANGFUSE_PUBLIC_KEY'),
  password: getEnv('LANGFUSE_SECRET_KEY')
});

Data URI Construction

import { bytesToBase64 } from '@langfuse/core';

function createDataUri(bytes: Uint8Array, mimeType: string): string {
  const base64 = bytesToBase64(bytes);
  return `data:${mimeType};base64,${base64}`;
}

// Usage
const imageBytes = new Uint8Array([/* ... */]);
const dataUri = createDataUri(imageBytes, 'image/png');
console.log(dataUri);  // "data:image/png;base64,..."

Secure Token Encoding

import { base64Encode, base64Decode } from '@langfuse/core';

interface Token {
  userId: string;
  sessionId: string;
  expires: number;
}

function encodeToken(token: Token): string {
  const json = JSON.stringify(token);
  return base64Encode(json);
}

function decodeToken(encoded: string): Token {
  const json = base64Decode(encoded);
  return JSON.parse(json);
}

// Usage
const token = {
  userId: 'user-123',
  sessionId: 'session-456',
  expires: Date.now() + 3600000
};

const encoded = encodeToken(token);
console.log(encoded);  // Base64 encoded token

const decoded = decodeToken(encoded);
console.log(decoded);  // Original token object

Batch Processing with Safe Timeouts

import { safeSetTimeout, generateUUID } from '@langfuse/core';

class EventBatcher<T> {
  private batch: Array<{ id: string; data: T }> = [];
  private flushHandle: any;

  constructor(
    private onFlush: (batch: Array<{ id: string; data: T }>) => Promise<void>,
    private flushInterval: number = 5000,
    private maxBatchSize: number = 100
  ) {
    this.scheduleFlush();
  }

  add(data: T) {
    this.batch.push({
      id: generateUUID(),
      data
    });

    if (this.batch.length >= this.maxBatchSize) {
      this.flush();
    }
  }

  private scheduleFlush() {
    this.flushHandle = safeSetTimeout(() => {
      this.flush();
    }, this.flushInterval);
  }

  private async flush() {
    if (this.flushHandle) {
      clearTimeout(this.flushHandle);
    }

    if (this.batch.length === 0) {
      this.scheduleFlush();
      return;
    }

    const toFlush = this.batch;
    this.batch = [];

    try {
      await this.onFlush(toFlush);
    } catch (error) {
      console.error('Flush failed', error);
      // Re-add to batch or handle error
    }

    this.scheduleFlush();
  }

  async shutdown() {
    if (this.flushHandle) {
      clearTimeout(this.flushHandle);
    }
    await this.flush();
  }
}

// Usage
const batcher = new EventBatcher(
  async (batch) => {
    console.log(`Flushing ${batch.length} events`);
    // Send to API
  },
  5000,  // Flush every 5 seconds
  100    // Or when 100 events
);

batcher.add({ type: 'trace', data: { /* ... */ } });

Environment-Based Configuration

import { getEnv } from '@langfuse/core';

interface Config {
  apiUrl: string;
  publicKey: string;
  secretKey: string;
  timeout: number;
  flushInterval: number;
  flushAt: number;
  release?: string;
  environment?: string;
  logLevel: string;
}

function loadConfig(): Config {
  const publicKey = getEnv('LANGFUSE_PUBLIC_KEY');
  const secretKey = getEnv('LANGFUSE_SECRET_KEY');

  if (!publicKey || !secretKey) {
    throw new Error(
      'Missing required environment variables: LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY'
    );
  }

  return {
    apiUrl: getEnv('LANGFUSE_BASE_URL') || 'https://cloud.langfuse.com',
    publicKey,
    secretKey,
    timeout: parseInt(getEnv('LANGFUSE_TIMEOUT') || '60000'),
    flushInterval: parseInt(getEnv('LANGFUSE_FLUSH_INTERVAL') || '5000'),
    flushAt: parseInt(getEnv('LANGFUSE_FLUSH_AT') || '100'),
    release: getEnv('LANGFUSE_RELEASE'),
    environment: getEnv('LANGFUSE_TRACING_ENVIRONMENT'),
    logLevel: getEnv('LANGFUSE_LOG_LEVEL') || 'INFO'
  };
}

// Usage
const config = loadConfig();
console.log(`Connecting to ${config.apiUrl}`);
console.log(`Flush interval: ${config.flushInterval}ms`);

Binary Data Handling

import { base64ToBytes, bytesToBase64 } from '@langfuse/core';

async function downloadAndEncode(url: string): Promise<string> {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  const bytes = new Uint8Array(arrayBuffer);
  return bytesToBase64(bytes);
}

async function decodeAndDisplay(base64: string, mimeType: string) {
  const bytes = base64ToBytes(base64);
  const blob = new Blob([bytes], { type: mimeType });
  const url = URL.createObjectURL(blob);

  const img = document.createElement('img');
  img.src = url;
  document.body.appendChild(img);
}

// Usage
const encoded = await downloadAndEncode('https://example.com/image.png');
await decodeAndDisplay(encoded, 'image/png');

Type Definitions

function generateUUID(globalThis?: any): string;

function getEnv(key: LangfuseEnvVar): string | undefined;

type LangfuseEnvVar =
  | "LANGFUSE_PUBLIC_KEY"
  | "LANGFUSE_SECRET_KEY"
  | "LANGFUSE_BASE_URL"
  | "LANGFUSE_BASEURL"
  | "LANGFUSE_TIMEOUT"
  | "LANGFUSE_FLUSH_AT"
  | "LANGFUSE_FLUSH_INTERVAL"
  | "LANGFUSE_LOG_LEVEL"
  | "LANGFUSE_RELEASE"
  | "LANGFUSE_TRACING_ENVIRONMENT";

function base64Encode(input: string): string;
function base64Decode(input: string): string;
function base64ToBytes(base64: string): Uint8Array;
function bytesToBase64(bytes: Uint8Array): string;

function safeSetTimeout(fn: () => void, timeout: number): any;

Best Practices

  1. Environment Variables: Always validate required environment variables at startup
  2. UUID Generation: Use generateUUID() for all ID generation to ensure RFC 4122 compliance
  3. Base64 Encoding: Prefer base64Encode/base64Decode over direct Buffer/btoa/atob for cross-platform compatibility
  4. Binary Data: Use base64ToBytes/bytesToBase64 when working with raw binary data
  5. Safe Timeouts: Always use safeSetTimeout for background operations to prevent process hanging
  6. Error Handling: Wrap base64 operations in try-catch blocks for malformed input
  7. Memory Management: For large binary data, process in chunks rather than loading entirely
  8. Configuration: Centralize environment variable reading in a config module
  9. Type Safety: Use the LangfuseEnvVar type for environment variable keys
  10. Cleanup: Always clear timeouts in cleanup/shutdown handlers

Install with Tessl CLI

npx tessl i tessl/npm-langfuse--core

docs

api-client.md

api-resources.md

constants.md

errors.md

index.md

logger.md

media.md

utils.md

tile.json