npm package: @lightswitch-sdk/lightswitch-sdk-js
Description: A two-layer JavaScript SDK for the Lightswitch monetization platform, providing both vanilla JavaScript and React implementations.
Latest version: 0.1.7

# Lightswitch JavaScript SDK

A two-layer JavaScript SDK for the Lightswitch monetization platform, providing both vanilla JavaScript and React implementations.

## Architecture

The SDK is built with a **two-layer architecture**:

### Layer 1: Vanilla JS Core (`core/`)
- **Pure JavaScript** implementation with no framework dependencies
- Handles authentication, entitlement checks, paywall display, and API communication
- Can be used in any JavaScript environment (vanilla JS, Vue, Angular, etc.)
- Lightweight and framework-agnostic

### Layer 2: React Adapter (`react/`)
- **React-specific** components and hooks that wrap the vanilla JS core
- Provides React context, state management, and component abstractions
- Uses React and react-dom as peer dependencies
- All business logic delegated to the core layer

## Installation

```bash
npm install lightswitch-js-sdk
```

## Quick Start

### Vanilla JavaScript

```javascript
import Lightswitch from 'lightswitch-js-sdk/core';

// Initialize the SDK
await Lightswitch.init({
  publishableKey: 'your-publishable-key',
  appSlug: 'your-app-slug'
});

// Check if user is authenticated
if (Lightswitch.isAuthenticated()) {
  console.log('User:', Lightswitch.getUser());
}

// Check entitlement
const isEntitled = await Lightswitch.isEntitled('premium-feature');
if (!isEntitled) {
  // Show paywall
  Lightswitch.showPaywall({ feature: 'premium-feature' });
}

// Login redirect
Lightswitch.login();
```

### React

```jsx
import React from 'react';
import { 
  LightswitchProvider, 
  useLightswitch, 
  EntitlementGate,
  LoginButton 
} from 'lightswitch-js-sdk/react';

function App() {
  return (
    <LightswitchProvider 
      publishableKey="your-publishable-key"
      appSlug="your-app-slug"
    >
      <MyComponent />
    </LightswitchProvider>
  );
}

function MyComponent() {
  const {
    // Auth state
    isAuthenticated,
    user,
    isLoading,
    error,
    
    // Methods
    login,
    logout,
    checkEntitlement,
    showPaywall,
    
    // Tracking method (anonymous)
    trackEvent,
    
    // Direct core access
    core
  } = useLightswitch();

  return (
    <div>
      <LoginButton />
      
      {isAuthenticated && (
        <EntitlementGate feature="premium-feature">
          <button onClick={() => console.log('Premium action!')}>
            Premium Feature
          </button>
        </EntitlementGate>
      )}
    </div>
  );
}
```

## Core API Reference

### Initialization

```javascript
import Lightswitch from 'lightswitch-js-sdk/core';

await Lightswitch.init({
  publishableKey: 'your-publishable-key',
  appSlug: 'your-app-slug',
  autoAuth: true // automatically check for stored tokens
});
```

### Authentication

```javascript
// Check authentication status
const isAuth = Lightswitch.isAuthenticated();
const user = Lightswitch.getUser();
const token = Lightswitch.getAuthToken();

// Login/logout
Lightswitch.login(); // redirects to hosted login
Lightswitch.logout();

// Listen to auth changes
const unsubscribe = Lightswitch.onAuthChange((authState) => {
  console.log('Auth state changed:', authState);
});
```

### Entitlements

```javascript
// Check single entitlement
const result = await Lightswitch.checkEntitlement('premium-feature');
console.log(result.entitled); // true/false
```

### Paywall

```javascript
// Show paywall modal
const paywall = Lightswitch.showPaywall({
  feature: 'premium-feature',
  onPaymentSuccess: (data) => {
    console.log('Payment successful!', data);
  },
  onClose: () => {
    console.log('Paywall closed');
  }
});

// Close paywall
Lightswitch.closePaywall();

// Listen to paywall events
const unsubscribe = Lightswitch.onPaywallEvent((event, data) => {
  if (event === 'payment_success') {
    console.log('Payment completed!');
  }
});
```

### Tracking

Anonymous usage tracking for analytics (no authentication required):

```javascript
// Track any event with custom parameters
await Lightswitch.trackEvent('button_click', '/dashboard', {
  button_name: 'signup',
  user_type: 'premium'
});

// Track page views
await Lightswitch.trackEvent('page_view', '/dashboard', {
  source: 'navigation',
  user_type: 'premium'
});

// Track feature usage
await Lightswitch.trackEvent('feature_usage', null, {
  feature: 'ai_completion',
  input_length: 150,
  model: 'gpt-4'
});

// Track custom events
await Lightswitch.trackEvent('video_watched', null, {
  duration: 120,
  quality: '1080p'
});
```

**Parameters:**
- `eventType` (string): Type of event being tracked
- `path` (string, optional): Path where event occurred (auto-detected if not provided)  
- `params` (object, optional): Additional parameters to track
- `options` (object, optional): Request options

All tracking automatically includes:
- Timestamp (current time)
- User agent (auto-detected)
- Current path (auto-detected if not provided)
- Anonymous hash ID (generated server-side)

### Automatic Tracking Features

The React SDK includes built-in automatic tracking that can be enabled/disabled:

**Page View Tracking** (`autoPageTracking={true}`)
- Automatically tracks `'page_view'` events when users navigate between pages
- Includes current path and referrer information
- Works with React Router and programmatic navigation

**Click Tracking** (`autoClickTracking={true}`)
- Automatically tracks `'click'` events on interactive elements
- Captures element details: tag, ID, class, text content, link targets
- Filters out irrelevant clicks (document, body) for clean data
- Includes page context where clicks occurred

```jsx
<LightswitchProvider 
  autoPageTracking={true}  // Default: true
  autoClickTracking={true} // Default: true
>
  <App />
</LightswitchProvider>
```

## React API Reference

### Provider

```jsx
import { LightswitchProvider } from 'lightswitch-js-sdk/react';

<LightswitchProvider 
  publishableKey="your-key"
  appSlug="your-app"
  autoAuth={true}
  autoPageTracking={true}
  autoClickTracking={true}
>
  <App />
</LightswitchProvider>
```

### Hooks

#### `useLightswitch()`

```jsx
import { useLightswitch } from 'lightswitch-js-sdk/react';

function MyComponent() {
  const {
    // Auth state
    isAuthenticated,
    user,
    isLoading,
    error,
    
    // Methods
    login,
    logout,
    checkEntitlement,
    showPaywall,
    
    // Tracking method (anonymous)
    trackEvent,
    
    // Direct core access
    core
  } = useLightswitch();
}
```

#### `useEntitlement(feature)`

```jsx
import { useEntitlement } from 'lightswitch-js-sdk/react';

function PremiumFeature() {
  const {
    entitled,
    loading,
    error,
    check,
    refresh
  } = useEntitlement('premium-feature');

  if (loading) return <div>Checking access...</div>;
  if (!entitled) return <div>Upgrade required</div>;
  
  return <div>Premium content!</div>;
}
```

### Components

#### `<EntitlementGate>`

```jsx
import { EntitlementGate } from 'lightswitch-js-sdk/react';

<EntitlementGate 
  feature="premium-feature"
  onPaymentSuccess={() => console.log('Paid!')}
>
  <button onClick={handlePremiumAction}>
    Premium Action
  </button>
</EntitlementGate>
```

#### `<LoginButton>`

```jsx
import { LoginButton } from 'lightswitch-js-sdk/react';

<LoginButton 
  className="btn btn-primary"
  loginText="Sign In"
  logoutText="Sign Out"
  onLogin={() => console.log('Login initiated')}
  onLogout={() => console.log('Logged out')}
/>
```

### Higher-Order Components

#### `withEntitlement(feature)`

```jsx
import { withEntitlement } from 'lightswitch-js-sdk/react';

const PremiumComponent = () => <div>Premium content!</div>;

const EntitledComponent = withEntitlement('premium-feature', {
  showPaywallOnNotEntitled: true
})(PremiumComponent);
```

## Migration from React-only SDK

If you're migrating from the previous React-only SDK:

### Before (React-only)
```jsx
import { LightswitchProvider, useLightswitch } from '@lightswitch-sdk';
```

### After (New two-layer SDK)
```jsx
import { LightswitchProvider, useLightswitch } from 'lightswitch-js-sdk/react';
// OR for vanilla JS
import Lightswitch from 'lightswitch-js-sdk/core';
```

The React API remains largely the same, but now you have the option to use the vanilla JS core directly.

## Browser Support

- **Core SDK**: Works in all modern browsers (ES2018+)
- **React SDK**: Requires React 16.8+ (hooks support)

## Bundle Size

- **Core only**: ~15KB gzipped
- **React adapter**: +5KB gzipped
- **Tree-shakable**: Import only what you need

## Development

```bash
# Install dependencies
npm install

# Run tests
npm test

# Build for production
npm run build

# Publish to npm
npm publish
```

## License

MIT License - see LICENSE file for details.