# Variably JavaScript/TypeScript SDK

Official JavaScript/TypeScript SDK for Variably feature flags and experimentation platform.

## Installation

```bash
npm install @variably/sdk
# or
yarn add @variably/sdk
```

## Quick Start

```typescript
import { VariablyClient } from '@variably/sdk';

// Initialize the client
const client = new VariablyClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://graphql.variably.tech', // optional, defaults to production GraphQL endpoint
  environment: 'production' // optional
});

// Evaluate a boolean feature flag
const userContext = {
  userId: 'user-123',
  email: 'user@example.com',
  country: 'US'
};

const isFeatureEnabled = await client.evaluateFlagBool(
  'new-checkout-flow',
  false, // default value
  userContext
);

if (isFeatureEnabled) {
  // Show new checkout flow
}

// Evaluate a feature gate
const hasAccess = await client.evaluateGate('premium-features', userContext);

// Track events
await client.track({
  name: 'button_clicked',
  userId: 'user-123',
  properties: {
    button_name: 'checkout',
    page: 'product-detail'
  }
});
```

## Configuration

```typescript
interface VariablyConfig {
  /** API key for authentication */
  apiKey: string;
  /** Base URL for the GraphQL API (default: https://graphql.variably.tech) */
  baseUrl?: string;
  /** Environment (development, staging, production) */
  environment?: string;
  /** Request timeout in milliseconds (default: 5000) */
  timeout?: number;
  /** Number of retry attempts (default: 3) */
  retryAttempts?: number;
  /** Enable analytics tracking (default: true) */
  enableAnalytics?: boolean;
  /** Cache configuration */
  cache?: {
    /** Cache TTL in milliseconds (default: 300000 = 5 minutes) */
    ttl?: number;
    /** Maximum cache size (default: 1000) */
    maxSize?: number;
    /** Enable cache (default: true) */
    enabled?: boolean;
  };
}
```

## Advanced Usage

### Environment Variables

You can create a client using environment variables:

```typescript
import { createClientFromEnv } from '@variably/sdk';

// Uses these environment variables:
// VARIABLY_API_KEY
// VARIABLY_BASE_URL
// VARIABLY_ENVIRONMENT
// VARIABLY_TIMEOUT
// VARIABLY_ENABLE_ANALYTICS

const client = createClientFromEnv();
```

### Different Flag Types

```typescript
// Boolean flags
const boolValue = await client.evaluateFlagBool('feature-enabled', false, userContext);

// String flags
const stringValue = await client.evaluateFlagString('theme', 'light', userContext);

// Number flags
const numberValue = await client.evaluateFlagNumber('max-items', 10, userContext);

// JSON flags
const jsonValue = await client.evaluateFlagJSON('config', { timeout: 5000 }, userContext);

// Get full evaluation details
const result = await client.evaluateFlag('feature-flag', 'default', userContext);
console.log(result); // { key, value, reason, cacheHit, evaluatedAt, error? }
```

### Batch Evaluation

```typescript
const flags = await client.evaluateFlags([
  'feature-a',
  'feature-b', 
  'feature-c'
], userContext);

console.log(flags['feature-a'].value);
```

### Event Tracking

```typescript
// Single event
await client.track({
  name: 'purchase_completed',
  userId: 'user-123',
  properties: {
    amount: 99.99,
    currency: 'USD',
    items: ['item-1', 'item-2']
  }
});

// Batch events
await client.trackBatch([
  { name: 'page_view', userId: 'user-123', properties: { page: '/home' } },
  { name: 'button_click', userId: 'user-123', properties: { button: 'cta' } }
]);
```

### Cache Management

```typescript
// Clear cache
client.clearCache();

// Get cache stats
const stats = client.cache.getStats();
console.log(stats); // { size, maxSize, hitRate, enabled }
```

### Metrics

```typescript
// Get SDK metrics
const metrics = client.getMetrics();
console.log(metrics);
// {
//   apiCalls: number,
//   cacheHits: number,
//   cacheMisses: number,
//   errors: number,
//   averageLatency: number,
//   cacheHitRate: number,
//   errorRate: number,
//   flagsEvaluated: number,
//   gatesEvaluated: number,
//   eventsTracked: number,
//   startTime: Date
// }
```

### Custom Logger

```typescript
import { VariablyClient, createLogger } from '@variably/sdk';

const logger = createLogger({
  level: 'debug',
  type: 'structured' // 'console', 'silent', 'structured'
});

// Or use a custom logging function
const customLogger = createLogger({
  level: 'info',
  custom: (level, message, meta) => {
    // Send to your logging service
    console.log(`${level}: ${message}`, meta);
  }
});
```

## Browser Usage

The SDK works in both Node.js and browser environments:

```html
<script type="module">
import { VariablyClient } from 'https://unpkg.com/@variably/sdk@latest/dist/index.esm.js';

const client = new VariablyClient({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.variably.com'
});

// Use the client...
</script>
```

## Error Handling

```typescript
import { 
  VariablyError, 
  NetworkError, 
  AuthenticationError, 
  ValidationError 
} from '@variably/sdk';

try {
  const result = await client.evaluateFlag('my-flag', false, userContext);
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.statusCode);
  } else if (error instanceof ValidationError) {
    console.error('Validation error:', error.field);
  } else {
    console.error('Unknown error:', error.message);
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and includes full type definitions:

```typescript
import { VariablyClient, UserContext, FlagResult } from '@variably/sdk';

const userContext: UserContext = {
  userId: 'user-123',
  email: 'user@example.com',
  attributes: {
    plan: 'premium',
    signupDate: '2023-01-01'
  }
};

const result: FlagResult = await client.evaluateFlag('feature', false, userContext);
```

## Development

### Building

```bash
npm run build
```

### Testing

```bash
npm test
```

### Linting

```bash
npm run lint
```

## License

MIT License - see LICENSE file for details.