npm package: @seaverse/track-sdk
Description: Unified analytics SDK for Firebase and Sensors Analytics
Author: SeaVerse Team
Latest version: 0.1.13

# @seaverse/track-sdk

Unified tracking SDK with token-based configuration. All platform configurations are built-in for simplicity.

## Features

- 🎯 **Token-based Configuration**: Just provide a token, no need for complex setup
- 🔒 **Code Obfuscation**: Production builds automatically obfuscated to protect configuration
- 🚀 **Smart Collection**: Automatic user behavior tracking plus manual event tracking
- 🔌 **Multi-platform Support**: Simultaneously supports multiple analytics platforms
- 📦 **TypeScript Support**: Complete type definitions
- 🎨 **Lazy Loading**: Dynamic imports reduce initial load
- 🐛 **Error Monitoring**: Optional Sentry integration for real-time error tracking and performance monitoring

## Installation

```bash
npm install @seaverse/track-sdk
```

Required dependencies are automatically installed with the SDK.

## Quick Start

### Method 1: npm Package Import (Recommended)

```typescript
import { TrackClient } from '@seaverse/track-sdk';

// Create client (using production token)
const trackClient = new TrackClient({
  token: 'prod_2f8a9c1b4e3d',
  platform: 'web', // h5
  version: '1.0.0',
  env: 'production', // local, develop, or production
  app_id: 'my-app-001', // Application ID (max 36 characters)
});

// Initialize (automatically injects GTM if GTM ID is configured)
await trackClient.initialize();

// Manual tracking
await trackClient.track('button_click', {
  button_name: 'Purchase Button',
  page: 'Product Details',
});
```

### Method 2: Browser Script Tag

```html
<!DOCTYPE html>
<html>
<head>
  <!-- Include SDK -->
  <script src="https://unpkg.com/@seaverse/track-sdk/dist/track-sdk.umd.js"></script>
</head>
<body>
  <div id="root"></div>

  <script>
    (function() {
      // Access SDK via global variable SeaVerseTrack
      var TrackClient = SeaVerseTrack.TrackClient;

      // Create client
      var trackClient = new TrackClient({
        token: 'prod_2f8a9c1b4e3d',
        platform: 'web',
        version: '1.0.0',
        env: 'production',
        app_id: 'my-app-001',
        debug: true
      });

      // Initialize
      trackClient.initialize().then(function() {
        console.log('Track SDK initialized');

        // Manual tracking
        trackClient.track('page_view', {
          page: 'home',
          title: 'Home'
        });
      });

      // Export to global for later use
      window.trackClient = trackClient;
    })();
  </script>
</body>
</html>
```

## API Documentation

### TrackClient

#### Constructor

```typescript
new TrackClient(config: TrackConfig)
```

**Parameters:**

```typescript
interface TrackConfig {
  token: string;                             // Application token (required)
  platform: string;                          // Platform type (required, e.g., web, h5, ios, android)
  version: string;                           // Application version (required)
  env: 'local' | 'develop' | 'production';   // Environment type (required)
  app_id: string;                            // Application ID (required, max 36 characters)
  debug?: boolean;                           // Enable debug mode, default false
  enableSentry?: boolean;                    // Enable Sentry error monitoring, default false
  sentryDsn?: string;                        // Sentry DSN (optional, override token config)
  sentryOptions?: {                          // Sentry custom options
    tracesSampleRate?: number;               // Performance tracing sample rate (0-1), default 1.0
    replaysSessionSampleRate?: number;       // Session replay sample rate, default 0.1
    replaysOnErrorSampleRate?: number;       // Error replay sample rate, default 1.0
    environment?: string;                    // Override environment (defaults to config.env)
  };
}
```

#### Methods

##### `initialize(): Promise<void>`

Initialize SDK. Must be called before use.

```typescript
await trackClient.initialize();
```

##### `track(eventName: string, properties?: EventProperties): Promise<void>`

Track events.

```typescript
await trackClient.track('purchase', {
  product_id: '12345',
  price: 99.99,
  currency: 'CNY',
});
```

##### `setUserId(userId: string): Promise<void>`

Set user ID (call on user login).

```typescript
await trackClient.setUserId('user_123456');
```

##### `setUserProperties(properties: UserProperties): Promise<void>`

Set user properties.

```typescript
await trackClient.setUserProperties({
  age: 25,
  gender: 'male',
  vip_level: 'gold',
});
```

##### `clearUserId(): Promise<void>`

Clear user ID (call on user logout).

```typescript
await trackClient.clearUserId();
```

##### `getInitializedProviders(): TrackProvider[]`

Get list of initialized providers.

```typescript
const providers = trackClient.getInitializedProviders();
console.log(providers); // List of initialized tracking platforms
```

##### `trackGTMEvent(eventName: string, parameters?: Record<string, any>): void`

Track GTM custom events (web platform only).

```typescript
trackClient.trackGTMEvent('log_login_accounts', {
  loginType: 'seaart-auth',
});
```

##### `captureException(error: Error): void`

Manually capture exceptions to Sentry (requires Sentry enabled).

```typescript
try {
  // some code
} catch (error) {
  trackClient.captureException(error);
}
```

##### `captureMessage(message: string, level?: 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug'): void`

Manually capture messages to Sentry (requires Sentry enabled).

```typescript
trackClient.captureMessage('User completed checkout', 'info');
```

##### `getSentryAdapter(): SentryAdapter | undefined`

Get Sentry adapter instance if initialized.

```typescript
const sentryAdapter = trackClient.getSentryAdapter();
if (sentryAdapter) {
  // Use Sentry adapter directly
}
```

## Usage Examples

### React Application

```typescript
import { useEffect } from 'react';
import { TrackClient } from '@seaverse/track-sdk';

// Create global instance
const trackClient = new TrackClient({
  token: process.env.REACT_APP_TRACK_TOKEN || 'dev_9a3b6c2d1e4f',
  platform: 'web',
  version: '1.0.0', // Recommended to read from package.json
  env: process.env.NODE_ENV === 'production' ? 'production' : 'develop',
  app_id: 'my-react-app',
  debug: process.env.NODE_ENV === 'development',
  enableSentry: true, // Enable Sentry error monitoring
  sentryOptions: {
    tracesSampleRate: 0.5, // 50% performance sampling
  },
});

function App() {
  useEffect(() => {
    // Initialize tracking
    trackClient.initialize().then(() => {
      console.log('Track SDK initialized');
    });
  }, []);

  const handleLogin = async (userId: string) => {
    await trackClient.setUserId(userId);
    await trackClient.track('user_login');
  };

  const handlePurchase = async (productId: string, price: number) => {
    try {
      await trackClient.track('purchase', {
        product_id: productId,
        price,
        currency: 'CNY',
      });
    } catch (error) {
      // Capture error to Sentry
      trackClient.captureException(error);
    }
  };

  const handleCustomGTMEvent = () => {
    // Track GTM custom event
    trackClient.trackGTMEvent('custom_button_click', {
      button_id: 'cta_button',
      page_name: 'home',
    });
  };

  return <div>Your App</div>;
}

export default App;
```

### Vue Application

```typescript
// plugins/track.ts
import { TrackClient } from '@seaverse/track-sdk';

export const trackClient = new TrackClient({
  token: import.meta.env.VITE_TRACK_TOKEN || 'dev_9a3b6c2d1e4f',
  platform: 'web',
  version: '1.0.0', // Recommended to read from package.json
  env: import.meta.env.PROD ? 'production' : 'develop',
  app_id: 'my-vue-app',
  debug: import.meta.env.DEV,
});

// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { trackClient } from './plugins/track';

const app = createApp(App);

trackClient.initialize();

app.config.globalProperties.$track = trackClient;

app.mount('#app');
```

### Environment Variables Configuration

**React (.env):**
```bash
# Development environment
REACT_APP_TRACK_TOKEN=dev_9a3b6c2d1e4f

# Testing environment
REACT_APP_TRACK_TOKEN=test_5d7e2a4b8f1c

# Production environment
REACT_APP_TRACK_TOKEN=prod_2f8a9c1b4e3d
```

**Vue (.env):**
```bash
# Development environment
VITE_TRACK_TOKEN=dev_9a3b6c2d1e4f

# Production environment
VITE_TRACK_TOKEN=prod_2f8a9c1b4e3d
```

## Best Practices

### 1. Environment Configuration

Use environment variables to manage tokens:

```typescript
const trackClient = new TrackClient({
  token: process.env.REACT_APP_TRACK_TOKEN || 'dev_9a3b6c2d1e4f',
  platform: 'web',
  version: '1.0.0',
  env: process.env.NODE_ENV === 'production' ? 'production' : 'develop',
  app_id: 'my-app-001',
  debug: process.env.NODE_ENV !== 'production',
});
```

### 2. User Lifecycle

```typescript
// Login
async function onLogin(userId: string) {
  await trackClient.setUserId(userId);
  await trackClient.setUserProperties({
    login_time: Date.now(),
  });
  await trackClient.track('user_login');
}

// Logout
async function onLogout() {
  await trackClient.track('user_logout');
  await trackClient.clearUserId();
}
```

### 3. Error Handling

```typescript
try {
  await trackClient.initialize();
} catch (error) {
  console.error('Tracking initialization failed:', error);
  // Continue running, don't block main flow
}
```

### 4. Sentry Integration

Enable Sentry to automatically capture errors and monitor performance:

```typescript
const trackClient = new TrackClient({
  token: 'your_token',
  platform: 'web',
  version: '1.0.0',
  env: 'production',
  app_id: 'my-app-001',
  enableSentry: true, // Enable Sentry
  sentryOptions: {
    tracesSampleRate: 1.0,        // 100% performance monitoring
    replaysSessionSampleRate: 0.1, // 10% session replay
    replaysOnErrorSampleRate: 1.0, // 100% error replay
  },
});

// Manually capture exceptions
try {
  someDangerousOperation();
} catch (error) {
  trackClient.captureException(error);
}

// Manually capture messages
trackClient.captureMessage('Important event occurred', 'warning');
```

## FAQ

**Q: How to apply for a new token?**

Contact administrator to add new configuration to `src/config.ts`.

**Q: How to verify tracking is working properly?**

Enable debug mode:
```typescript
const trackClient = new TrackClient({
  token: 'your_token',
  platform: 'web',
  version: '1.0.0',
  env: 'develop',
  app_id: 'my-app-001',
  debug: true,  // Will output logs to console
});
```

**Q: Is Google Tag Manager automatically injected?**

Yes, if the platform configuration includes `gtmId`, the SDK will automatically inject GTM code during Firebase initialization:
- Automatically inserts GTM script in `<head>`
- Automatically inserts noscript fallback at the beginning of `<body>`
- Supports duplicate detection to avoid re-injection

GTM ID is set in platform configuration in `src/config.ts`, no need for users to pass it manually.

**Q: How to track GTM custom events?**

Use the `trackGTMEvent` method:

```typescript
// Track login event
trackClient.trackGTMEvent('log_login_accounts', {
  loginType: 'seaart-auth',
});

// Track button click
trackClient.trackGTMEvent('custom_button_click', {
  button_id: 'purchase_btn',
  page: 'product_detail',
});
```

Note:
- This method is only effective on web platform, will output log but not execute on non-web platforms
- Events are pushed to GTM dataLayer, can configure triggers and tags in GTM dashboard
- Event name must be a valid string

**Q: How to enable Sentry error monitoring?**

Set `enableSentry: true` in the configuration:

```typescript
const trackClient = new TrackClient({
  token: 'your_token',
  platform: 'web',
  version: '1.0.0',
  env: 'production',
  app_id: 'my-app-001',
  enableSentry: true, // Enable Sentry
});
```

Sentry will automatically:
- Capture unhandled errors and promise rejections
- Monitor performance (page load, API calls, user interactions)
- Record user actions as breadcrumbs
- Sync user information (ID and properties)

You can also manually capture exceptions or messages:

```typescript
trackClient.captureException(new Error('Something went wrong'));
trackClient.captureMessage('Custom log message', 'info');
```

**Q: Can I use a custom Sentry DSN?**

Yes, you can override the DSN from token configuration:

```typescript
const trackClient = new TrackClient({
  token: 'your_token',
  platform: 'web',
  version: '1.0.0',
  env: 'production',
  app_id: 'my-app-001',
  enableSentry: true,
  sentryDsn: 'https://your-custom-dsn@sentry.io/project-id',
});
```

## License

MIT