npm package: @sessionlens/sdk
Description: SessionLens SDK for analytics and event tracking
Author: SessionLens
Latest version: 0.2.1

# SessionLens SDK

A lightweight TypeScript SDK for analytics and user tracking.

## Installation

```bash
npm install @sessionlens/sdk
```

## Quick Start

### Basic Usage

```javascript
import sessionLens from '@sessionlens/sdk';

// Initialize the SDK with your credentials
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key-here',
  user_id: 'user123',
  org_id: 'org456',
  debug: true // Optional: enable debug logging
});

// Track events
sessionLens.sessionLensTrack({
  event_name: 'button_click',
  properties: {
    button_id: 'signup',
    page: 'landing'
  }
});

// Identify users
sessionLens.sessionLensIdentify({
  user_id: 'user123',
  properties: {
    email: 'user@example.com',
    plan: 'premium'
  }
});

// Reset tracking (e.g., on logout)
sessionLens.sessionLensReset();
```

### Advanced Usage with Custom Configuration

```javascript
import sessionLens from '@sessionlens/sdk';

// Initialize with custom API configuration
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key-here',
  user_id: 'user123',
  org_id: 'org456',
  api_base_url: 'https://dev-api.sessionlens.com/v1', // Custom API base URL
  endpoints: {
    events: '/custom/events/ingest',     // Custom events endpoint
    identify: '/custom/user/identify',   // Custom identify endpoint
    reset: '/custom/session/reset',      // Custom reset endpoint
    validate: '/custom/org/validate'     // Custom validation endpoint
  },
  debug: true
});

// Track events with rich properties
sessionLens.sessionLensTrack({
  event_name: 'user_action',
  properties: {
    action_type: 'form_submit',
    form_name: 'contact_form',
    fields_completed: 5,
    time_spent: 120, // seconds
    user_segment: 'premium',
    referrer: document.referrer,
    user_agent: navigator.userAgent
  },
  timestamp: Date.now() // Optional: auto-generated if not provided
});

// Identify user with comprehensive properties
sessionLens.sessionLensIdentify({
  user_id: 'user123',
  properties: {
    email: 'user@example.com',
    name: 'John Doe',
    plan: 'premium',
    company: 'Acme Corp',
    signup_date: '2024-01-15',
    last_login: new Date().toISOString(),
    preferences: {
      theme: 'dark',
      language: 'en',
      notifications: true
    }
  }
});
```

### Environment-Specific Configuration

```javascript
import sessionLens from '@sessionlens/sdk';

// Determine environment
const environment = process.env.NODE_ENV || 'development';

// Environment-specific configuration
const configs = {
  development: {
    api_base_url: 'https://dev-api.sessionlens.com/v1',
    debug: true
  },
  staging: {
    api_base_url: 'https://staging-api.sessionlens.com/v1',
    debug: true
  },
  production: {
    api_base_url: 'https://api.sessionlens.com/v1',
    debug: false
  }
};

// Initialize with environment-specific config
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key-here',
  user_id: 'user123',
  org_id: 'org456',
  ...configs[environment]
});

// Track environment info
sessionLens.sessionLensTrack({
  event_name: 'app_initialized',
  properties: {
    environment: environment,
    version: '1.0.0',
    timestamp: Date.now()
  }
});
```

### React Integration

```jsx
import React from 'react';
import { useSessionLens, useSessionLensTrack, useSessionLensIdentify } from '@sessionlens/sdk';

function App() {
  // Initialize SDK
  useSessionLens({
    sdk_key: 'your-sdk-key-here',
    user_id: 'user123',
    org_id: 'org456',
    debug: true
  });

  const track = useSessionLensTrack();
  const identify = useSessionLensIdentify();

  const handleClick = () => {
    track({
      event_name: 'button_click',
      properties: { button: 'header_cta' }
    });
  };

  const handleLogin = () => {
    identify({
      user_id: 'user123',
      properties: { email: 'user@example.com' }
    });
  };

  return (
    <div>
      <button onClick={handleClick}>Track Event</button>
      <button onClick={handleLogin}>Identify User</button>
    </div>
  );
}
```

### React Integration with Custom Configuration

```jsx
import React from 'react';
import { useSessionLens, useSessionLensTrack, useSessionLensIdentify } from '@sessionlens/sdk';

function App() {
  // Environment-specific configuration
  const environment = process.env.NODE_ENV || 'development';
  
  const configs = {
    development: {
      api_base_url: 'https://dev-api.sessionlens.com/v1',
      debug: true
    },
    staging: {
      api_base_url: 'https://staging-api.sessionlens.com/v1',
      debug: true
    },
    production: {
      api_base_url: 'https://api.sessionlens.com/v1',
      debug: false
    }
  };

  // Initialize SDK with environment-specific config
  useSessionLens({
    sdk_key: 'your-sdk-key-here',
    user_id: 'user123',
    org_id: 'org456',
    ...configs[environment]
  });

  const track = useSessionLensTrack();
  const identify = useSessionLensIdentify();

  const handlePageView = () => {
    track({
      event_name: 'page_view',
      properties: {
        page: window.location.pathname,
        referrer: document.referrer,
        environment: environment,
        timestamp: Date.now()
      }
    });
  };

  const handleUserAction = (action, details) => {
    track({
      event_name: 'user_action',
      properties: {
        action_type: action,
        ...details,
        user_agent: navigator.userAgent,
        screen_resolution: `${screen.width}x${screen.height}`
      }
    });
  };

  const handleUserLogin = (userData) => {
    identify({
      user_id: userData.id,
      properties: {
        email: userData.email,
        name: userData.name,
        login_method: userData.loginMethod,
        last_login: new Date().toISOString(),
        preferences: userData.preferences
      }
    });
  };

  // Track page view on component mount
  React.useEffect(() => {
    handlePageView();
  }, []);

  return (
    <div>
      <button onClick={() => handleUserAction('button_click', { button: 'header_cta' })}>
        Track Event
      </button>
      <button onClick={() => handleUserLogin({ 
        id: 'user123', 
        email: 'user@example.com',
        name: 'John Doe',
        loginMethod: 'email',
        preferences: { theme: 'dark' }
      })}>
        Identify User
      </button>
    </div>
  );
}
```

## Configuration

### Runtime Configuration

The SDK supports flexible runtime configuration through the `SessionLensConfig` interface:

```typescript
interface SessionLensConfig {
  sdk_key: string;      // Your SessionLens SDK key
  user_id: string;      // Unique identifier for the user
  org_id: string;       // Your organization ID
  project_id?: string;  // Optional: extracted from SDK key if not provided
  debug?: boolean;      // Optional: enable debug logging
  // API configuration options
  api_base_url?: string; // Optional: override API base URL
  endpoints?: {
    events?: string;    // Optional: override events endpoint (default: /events/ingest)
    identify?: string;  // Optional: override identify endpoint (default: /identify)
    reset?: string;     // Optional: override reset endpoint (default: /reset)
    validate?: string;  // Optional: override validation endpoint (default: /org/validate)
  };
}
```

#### API Base URL Configuration

Configure the API base URL for different environments:

```javascript
// Development
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key',
  user_id: 'user123',
  org_id: 'org456',
  api_base_url: 'https://dev-api.sessionlens.com/v1',
  debug: true
});

// Staging
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key',
  user_id: 'user123',
  org_id: 'org456',
  api_base_url: 'https://staging-api.sessionlens.com/v1'
});

// Production
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key',
  user_id: 'user123',
  org_id: 'org456',
  api_base_url: 'https://api.sessionlens.com/v1'
});
```

#### Custom Endpoints

Override specific API endpoints if needed:

```javascript
await sessionLens.sessionLensInit({
  sdk_key: 'your-sdk-key',
  user_id: 'user123',
  org_id: 'org456',
  api_base_url: 'https://api.sessionlens.com/v1',
  endpoints: {
    events: '/custom/events/endpoint',
    identify: '/custom/identify/endpoint',
    reset: '/custom/reset/endpoint',
    validate: '/custom/validate/endpoint'
  }
});
```

### Environment Variables

The SDK also supports configuration through environment variables (fallback):

```bash
# For Node.js applications
SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1

# For React applications (Create React App)
REACT_APP_SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1

# For development/staging environments
SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
REACT_APP_SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
```

**Configuration Priority:**
1. Runtime config (`api_base_url` in `sessionLensInit`)
2. Environment variables (`SESSIONLENS_API_BASE_URL` or `REACT_APP_SESSIONLENS_API_BASE_URL`)
3. Default (`https://api.sessionlens.com/v1`)

**Default:** `https://api.sessionlens.com/v1`

### Environment Setup Examples

#### Development (.env.development)
```bash
REACT_APP_SESSIONLENS_API_BASE_URL=https://dev-api.sessionlens.com/v1
REACT_APP_SESSIONLENS_SDK_KEY=sk_dev_your_development_key
```

#### Staging (.env.staging)
```bash
REACT_APP_SESSIONLENS_API_BASE_URL=https://staging-api.sessionlens.com/v1
REACT_APP_SESSIONLENS_SDK_KEY=sk_staging_your_staging_key
```

#### Production (.env.production)
```bash
REACT_APP_SESSIONLENS_API_BASE_URL=https://api.sessionlens.com/v1
REACT_APP_SESSIONLENS_SDK_KEY=sk_live_your_production_key
```

## API Reference

### Configuration

The SDK requires initialization with your credentials:

```typescript
interface SessionLensConfig {
  sdk_key: string;      // Your SessionLens SDK key
  user_id: string;      // Unique identifier for the user
  org_id: string;       // Your organization ID
  debug?: boolean;      // Optional: enable debug logging
}
```

### Methods

#### `sessionLensInit(config: SessionLensConfig): Promise<void>`

Initialize the SDK with your configuration. This method validates your credentials with the SessionLens backend using a RESTful GET request.

**API Call:** `GET /validate?org_id={org_id}&user_id={user_id}` with `Authorization: Bearer {sdk_key}` header

**Error Handling:**
- `401`: Invalid SDK key
- `403`: Access denied - check organization permissions
- `404`: Organization not found
- `429`: Rate limit exceeded
- Network errors: SDK runs in offline mode

#### `sessionLensTrack(event: SessionLensEvent): void`

Track custom events.

```typescript
interface SessionLensEvent {
  event_name: string;
  properties?: Record<string, any>;
  timestamp?: number; // Optional: will be auto-generated if not provided
}
```

#### `sessionLensIdentify(user: SessionLensUser): void`

Identify and update user properties.

```typescript
interface SessionLensUser {
  user_id: string;
  properties?: Record<string, any>;
}
```

#### `sessionLensReset(): void`

Reset tracking state. Useful when users log out.

## API Design

The SDK follows RESTful principles:

- **GET /validate**: Validates SDK key and organization/user access (idempotent)
- **POST /events**: Creates new tracking events
- **POST /identify**: Creates/updates user identification
- **POST /reset**: Resets user tracking state

This design ensures:
- Proper HTTP semantics (GET for reads, POST for writes)
- Better caching behavior for validation requests
- Cleaner server logs (sensitive data in headers, not URLs)

## Security

The SDK key is used for:
- Backend validation during initialization
- Authentication for all API requests
- Secure event transmission

**Best Practices:**
- Store SDK keys securely (environment variables, secure storage)
- Use different SDK keys for different environments
- Rotate SDK keys regularly
- Never expose SDK keys in client-side code for production
- Use environment-specific API base URLs for development/staging

## Error Handling

The SDK includes comprehensive error handling:

```javascript
try {
  await sessionLens.sessionLensInit({
    sdk_key: 'your-sdk-key',
    user_id: 'user123',
    org_id: 'org456'
  });
  console.log('SDK initialized successfully');
} catch (error) {
  console.error('Initialization failed:', error.message);
  // Handle specific errors:
  // - Invalid SDK key
  // - Network issues
  // - Organization access issues
}
```

## Examples

Check the `/examples` directory for complete implementation examples:
- Basic JavaScript usage
- React integration
- Error handling patterns
- Offline mode handling
- Environment configuration

## Development

```bash
# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test

# Run linting
npm run lint
```

## License

MIT