npm package: @lytics/sdk-kit-plugins
Description: Essential plugins for SDK Kit: storage, consent, context, logging, polling, queuing, and transport
Author: Lytics
Latest version: 1.0.0

# @lytics/sdk-kit-plugins

[![npm version](https://img.shields.io/npm/v/@lytics/sdk-kit-plugins.svg)](https://www.npmjs.com/package/@lytics/sdk-kit-plugins)
[![npm downloads](https://img.shields.io/npm/dm/@lytics/sdk-kit-plugins.svg)](https://www.npmjs.com/package/@lytics/sdk-kit-plugins)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENSE)

Essential plugins for SDK Kit providing battle-tested functionality for modern web SDKs.

## Overview

This package contains 6 essential plugins that cover common SDK needs:

- **Storage** - Multi-backend storage (localStorage, sessionStorage, cookies, memory)
- **Consent** - GDPR/CCPA consent management with platform adapters
- **Context** - Automatic page, device, screen, and environment context collection
- **Poll** - Promise-based async polling utilities
- **Queue** - Event batching and queuing with persistence
- **Transport** - HTTP transport abstraction with retry logic

## Installation

```bash
npm install @lytics/sdk-kit @lytics/sdk-kit-plugins
```

## Quick Start

```typescript
import { SDK } from '@lytics/sdk-kit';
import { 
  storagePlugin,
  consentPlugin,
  contextPlugin,
  pollPlugin,
  queuePlugin,
  transportPlugin
} from '@lytics/sdk-kit-plugins';

const sdk = new SDK();

// Use all plugins
sdk.use(storagePlugin);
sdk.use(consentPlugin);
sdk.use(contextPlugin);
sdk.use(pollPlugin);
sdk.use(queuePlugin);
sdk.use(transportPlugin);

// Initialize
await sdk.init({
  storage: {
    namespace: 'myapp',
    defaultBackend: 'localStorage'
  },
  consent: {
    categories: {
      analytics: 'pending',
      marketing: 'pending'
    },
    persist: true
  },
  queue: {
    maxSize: 50,
    flushInterval: 5000
  },
  transport: {
    retries: 3,
    timeout: 5000
  }
});
```

## Individual Plugin Imports

You can also import plugins individually for better tree-shaking:

```typescript
// Import specific plugins
import { storagePlugin } from '@lytics/sdk-kit-plugins/storage';
import { consentPlugin } from '@lytics/sdk-kit-plugins/consent';
import { contextPlugin } from '@lytics/sdk-kit-plugins/context';
import { pollPlugin } from '@lytics/sdk-kit-plugins/poll';
import { queuePlugin } from '@lytics/sdk-kit-plugins/queue';
import { transportPlugin } from '@lytics/sdk-kit-plugins/transport';
```

## Plugins

### Storage Plugin

Multi-backend storage with TTL, namespacing, and JSON serialization.

```typescript
import { storagePlugin } from '@lytics/sdk-kit-plugins';

sdk.use(storagePlugin);

// Use storage
sdk.storage.set('key', 'value', { backend: 'localStorage', ttl: 3600 });
const value = sdk.storage.get('key');
sdk.storage.remove('key');
```

**Features:**
- Multiple backends (localStorage, sessionStorage, cookies, memory)
- Automatic TTL expiration
- Namespace isolation
- JSON serialization
- Graceful degradation

[Full Documentation](./src/storage/README.md)

### Consent Plugin

State-based consent management with platform adapters for OneTrust, Cookiebot, and Usercentrics.

```typescript
import { consentPlugin } from '@lytics/sdk-kit-plugins';

sdk.use(consentPlugin);

// Check consent
if (sdk.consent.isGranted('analytics')) {
  // Track analytics
}

// Wait for consent
const granted = await sdk.consent.waitForConsent('marketing', { timeout: 5000 });

// Update consent
sdk.consent.grant(['analytics', 'marketing']);
sdk.consent.deny('social');
```

**Features:**
- Category-based consent (necessary, functional, analytics, marketing, social)
- Inferred consent (reduces banner fatigue)
- Platform adapters (OneTrust, Cookiebot, Usercentrics)
- Promise-based `waitForConsent()` API
- Cookie/localStorage persistence
- Nuclear opt-out with `revoke()`
- Metadata tracking and policy versioning

[Full Documentation](./src/consent/README.md)

### Context Plugin

Automatic collection of page, device, screen, and environment context.

```typescript
import { contextPlugin } from '@lytics/sdk-kit-plugins';

sdk.use(contextPlugin);

// Collect all context
const context = sdk.context.collect();
// { page, device, screen, environment }

// Individual collectors
const page = sdk.context.getPage();
const device = sdk.context.getDevice();
const screen = sdk.context.getScreen();
const env = sdk.context.getEnvironment();
```

**Features:**
- Page context (URL, path, query params, referrer, title, session)
- Device context (type, user agent)
- Screen context (dimensions)
- Environment context (timezone, language, cookies, DNT, storage)
- Privacy-first query parameter handling (UTM-only by default)
- External referrer filtering
- Cookie-based session detection
- Caching with manual refresh

[Full Documentation](./src/context/README.md)

### Poll Plugin

Promise-based async polling for DOM elements, globals, or custom conditions.

```typescript
import { pollPlugin } from '@lytics/sdk-kit-plugins';

sdk.use(pollPlugin);

// Poll for DOM element
await sdk.poll.element('#my-element');

// Poll for global variable
await sdk.poll.global('myLib');

// Custom condition
await sdk.poll.waitFor(
  () => document.readyState === 'complete',
  { interval: 100, timeout: 5000 }
);
```

**Features:**
- Promise-based API (modern async/await)
- Immediate check (no delay on first attempt)
- Configurable interval and timeout
- Event emission (`poll:start`, `poll:success`, `poll:timeout`)
- Lifecycle integration (cleanup on destroy)
- Convenience methods for DOM and globals

[Full Documentation](./src/poll/README.md)

### Queue Plugin

Event batching and queuing with automatic flushing, persistence, and retry support.

```typescript
import { queuePlugin } from '@lytics/sdk-kit-plugins';

sdk.use(queuePlugin);

// Add items to queue
sdk.queue.add({ event: 'click', target: 'button' });

// Manual flush
sdk.queue.flush();

// Queue auto-flushes when maxSize or flushInterval reached
sdk.on('queue:flush', (items) => {
  // Send items via transport
  sdk.transport.fetch('/events', {
    method: 'POST',
    body: JSON.stringify(items)
  });
});
```

**Features:**
- Auto-flush based on size or interval
- Persistence to storage (survives page reloads)
- FIFO limiting when maxQueueSize reached
- Lifecycle integration (flush on destroy)
- Event emission (`queue:add`, `queue:flush`, `queue:error`)
- `beforeunload` handling (flush before page unload)

[Full Documentation](./src/queue/README.md)

### Transport Plugin

HTTP transport abstraction with automatic transport selection, retry logic, and hooks.

```typescript
import { transportPlugin } from '@lytics/sdk-kit-plugins';

sdk.use(transportPlugin);

// Fetch transport (modern, default)
await sdk.transport.fetch('/api/events', {
  method: 'POST',
  body: JSON.stringify({ event: 'pageview' })
});

// Beacon transport (for unload events)
sdk.transport.beacon('/api/events', {
  event: 'page_exit'
});

// XHR transport (fallback for older browsers)
await sdk.transport.xhr('/api/events', {
  method: 'POST',
  body: JSON.stringify({ event: 'click' })
});

// Pixel transport (ultimate fallback)
sdk.transport.pixel('/api/track.gif?event=pageview');
```

**Features:**
- Multiple transports (fetch, beacon, XHR, pixel)
- Automatic transport selection
- Retry logic with exponential backoff
- Request/response hooks (`beforeSend`, `afterSend`)
- Event emission (`transport:success`, `transport:error`, `transport:retry`)
- Timeout handling

[Full Documentation](./src/transport/README.md)

## Plugin Combinations

Plugins work together seamlessly:

### Consent + Queue

```typescript
// Queue events until consent is granted
sdk.queue.add({ event: 'pageview' });

sdk.on('queue:flush', async (items) => {
  // Only send if analytics consent granted
  if (sdk.consent.isGranted('analytics')) {
    await sdk.transport.fetch('/events', {
      method: 'POST',
      body: JSON.stringify(items)
    });
  }
});
```

### Context + Transport

```typescript
// Auto-attach context to every request
sdk.transport.configure({
  beforeSend: (request) => {
    const context = sdk.context.collect();
    return {
      ...request,
      body: JSON.stringify({
        ...JSON.parse(request.body || '{}'),
        context
      })
    };
  }
});
```

### Poll + Queue

```typescript
// Wait for third-party library, then initialize queue
await sdk.poll.global('AnalyticsLib');
sdk.use(queuePlugin); // Safe to use now
```

## Browser Compatibility

All plugins support:
- Modern browsers (Chrome, Firefox, Safari, Edge)
- ES2015+ (transpile for older browsers if needed)
- jsdom for testing

Individual plugin compatibility:
- **Storage**: Graceful fallback to memory when storage unavailable
- **Consent**: Cookie and localStorage fallback
- **Context**: Works without browser APIs (returns defaults)
- **Poll**: Requires setTimeout/DOM APIs
- **Queue**: Requires storage for persistence
- **Transport**: Fetch → Beacon → XHR → Pixel fallback

## TypeScript

All plugins are fully typed. Import types alongside plugins:

```typescript
import type { 
  StoragePlugin,
  ConsentPlugin,
  ContextPlugin,
  PollPlugin,
  QueuePlugin,
  TransportPlugin
} from '@lytics/sdk-kit-plugins';

// Extended SDK interface
interface MySDK extends SDK {
  storage: StoragePlugin;
  consent: ConsentPlugin;
  context: ContextPlugin;
  poll: PollPlugin;
  queue: QueuePlugin;
  transport: TransportPlugin;
}

const sdk = new SDK() as MySDK;
```

## Testing

All plugins include comprehensive unit tests. To run tests:

```bash
# Run all tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run with coverage
pnpm test:coverage
```

## License

MIT

## Contributing

See [CONTRIBUTING.md](../../CONTRIBUTING.md) for guidelines.

## Links

- [SDK Kit Core](../core/README.md)
- [Plugin Development Guide](./GUIDE.md)
- [Examples](../../examples/)
- [Roadmap](../../ROADMAP.md)