npm package: @purplesquirrel/psm-sdk
Description: Purple Squirrel Media SDK - A unified toolkit for media-rich web applications with 20+ modules
Author: Purple Squirrel Media
Latest version: 1.2.1

# PSM SDK

[![npm version](https://img.shields.io/npm/v/@purplesquirrel/psm-sdk?color=%239b30ff)](https://www.npmjs.com/package/@purplesquirrel/psm-sdk)
[![npm downloads](https://img.shields.io/npm/dt/@purplesquirrel/psm-sdk?color=%237a1fe8)](https://www.npmjs.com/package/@purplesquirrel/psm-sdk)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue)](https://www.npmjs.com/package/@purplesquirrel/psm-sdk)
[![License](https://img.shields.io/github/license/PurpleSquirrelMedia/psm-sdk?color=%233b0b7d)](LICENSE)

Purple Squirrel Media SDK - A unified toolkit for media-rich web applications.

## Installation

### CDN (Recommended)

```html
<script src="https://purplesquirrel.media/sdk/psm.js"></script>
```

### npm

```bash
npm install @purplesquirrel/psm-sdk
```

### yarn

```bash
yarn add @purplesquirrel/psm-sdk
```

## Quick Start

```html
<script src="https://purplesquirrel.media/sdk/psm.js"></script>
<script>
  // Video player
  const player = await PSM.createPlayer('#video');

  // HLS streaming
  const stream = await PSM.createStream();
  await stream.attach(videoElement, 'https://example.com/live.m3u8');

  // Audio waveform
  const audio = await PSM.createAudio('#waveform', 'audio.mp3');

  // Canvas editor
  const canvas = await PSM.createCanvas('myCanvas');
  canvas.addRect({ fill: '#9b30ff' });

  // Markdown parser
  const md = await PSM.createMarkdown();
  const html = md.parse('# Hello World');
</script>
```

## Modules

### Core Media
| Module | Description | Based On |
|--------|-------------|----------|
| `squirrel-player.js` | Video player with PSM branding | Plyr |
| `stream.js` | HLS adaptive streaming | HLS.js |
| `sync.js` | Real-time WebSocket sync | Socket.io |
| `audio.js` | Audio waveform visualization | Wavesurfer.js |
| `peer.js` | WebRTC video/audio calls | PeerJS |

### Creative Tools
| Module | Description | Based On |
|--------|-------------|----------|
| `canvas.js` | Canvas editor with history | Fabric.js |
| `charts.js` | Data visualization | Chart.js |
| `three.js` | 3D graphics | Three.js |
| `play.js` | Retro game emulator | EmulatorJS |

### Document & Code
| Module | Description | Based On |
|--------|-------------|----------|
| `markdown.js` | Markdown parser | Marked |
| `code.js` | Syntax highlighting | Prism.js |
| `docs.js` | PDF document viewer | PDF.js |

### New in v1.2.0
| Module | Description | Based On |
|--------|-------------|----------|
| `animation.js` | Animation library | GSAP |
| `forms.js` | Form validation | Custom |
| `storage.js` | Unified storage API | Custom |
| `toast.js` | Notification toasts | Custom |
| `theme.js` | Theme customization | Custom |
| `plugins.js` | Plugin system | Custom |
| `vue.js` | Vue 3 composables | Vue |
| `react.js` | React hooks | React |

## API Reference

### PSM.createPlayer(selector, options)

Creates a video player instance.

```javascript
const player = await PSM.createPlayer('#video', {
  autoplay: false,
  muted: false
});

player.play();
player.pause();
player.seekTo(30); // seconds
player.setVolume(0.8);
player.setSpeed(1.5);
player.enterFullscreen();

player.on('play', () => console.log('Playing'));
player.on('pause', () => console.log('Paused'));
player.on('timeupdate', (time) => console.log(time));
```

### PSM.createStream(config)

Creates an HLS streaming instance.

```javascript
const stream = await PSM.createStream({
  lowLatency: true
});

await stream.attach(videoElement, 'https://example.com/live.m3u8');

// Quality control
stream.setQuality(2); // specific level
stream.setAutoQuality(true); // auto

// Get levels
console.log(stream.levels);
console.log(stream.currentLevel);
```

### PSM.createAudio(container, url, options)

Creates an audio waveform player.

```javascript
const audio = await PSM.createAudio('#waveform', 'audio.mp3', {
  waveColor: '#7a1fe8',
  progressColor: '#9b30ff',
  height: 128
});

audio.play();
audio.pause();
audio.seekTo(0.5); // 0-1 position
audio.setVolume(0.8);

audio.on('ready', () => console.log('Duration:', audio.duration));
audio.on('timeupdate', (time) => console.log(time));
```

### PSM.createCanvas(canvasId, options)

Creates a canvas editor instance.

```javascript
const canvas = await PSM.createCanvas('myCanvas', {
  backgroundColor: '#0c0a12'
});

// Shapes
canvas.addRect({ fill: '#9b30ff', width: 100, height: 100 });
canvas.addCircle({ radius: 50 });
canvas.addText('Hello', { fontSize: 24 });
await canvas.addImage('image.png');

// Drawing mode
canvas.enableDrawing({ color: '#9b30ff', width: 3 });
canvas.disableDrawing();

// History
canvas.undo();
canvas.redo();

// Export
const dataUrl = canvas.toDataURL('png');
const json = canvas.toJSON();
await canvas.loadFromJSON(json);
```

### PSM.createMarkdown(options)

Creates a markdown parser.

```javascript
const md = await PSM.createMarkdown({
  sanitize: true,
  breaks: true
});

// Parse to string
const html = md.parse('# Hello **World**');

// Render to element
md.render('# Hello', document.getElementById('output'));
```

### PSM.createCode(options)

Creates a syntax highlighter.

```javascript
const code = await PSM.createCode();

// Highlight string
const html = code.highlight('const x = 1;', 'javascript');

// Highlight element
code.highlightElement(document.querySelector('pre'));

// Highlight all code blocks
code.highlightAll();
```

### PSM.createDocs(container, url, options)

Creates a PDF document viewer.

```javascript
const docs = await PSM.createDocs('#viewer', 'document.pdf', {
  scale: 1.5,
  showToolbar: true
});

// Navigation
docs.goToPage(5);
docs.nextPage();
docs.prevPage();

// Zoom
docs.setScale(2);
docs.zoomIn();
docs.zoomOut();

docs.on('pagechange', ({ page }) => console.log('Page:', page));
```

### PSM.createPeer(id, options)

Creates a WebRTC peer connection.

```javascript
const peer = await PSM.createPeer('my-unique-id');

// Get local camera/mic
const stream = await peer.getLocalStream({ video: true, audio: true });

// Call another peer
const call = await peer.call('other-peer-id', stream);

// Handle incoming calls
peer.on('incomingcall', async ({ answer, reject, peerId }) => {
  const accept = confirm(`Call from ${peerId}?`);
  if (accept) {
    await answer(); // Uses local stream
  } else {
    reject();
  }
});

// Receive remote stream
peer.on('stream', ({ stream, peerId }) => {
  remoteVideo.srcObject = stream;
});

// Data channels
peer.connect('other-peer-id');
peer.send('other-peer-id', { message: 'Hello!' });
peer.on('data', ({ data, peerId }) => console.log(data));

// Controls
peer.toggleVideo(false); // Mute video
peer.toggleAudio(false); // Mute audio
peer.endCall('other-peer-id');
```

### PSM.createAnimation() (v1.2.0)

Creates a GSAP-powered animation instance.

```javascript
const animation = await PSM.createAnimation();

// Basic tweens
animation.to('.box', { x: 100, opacity: 1, duration: 0.5 });
animation.from('.box', { y: -50, opacity: 0 });
animation.fromTo('.box', { scale: 0 }, { scale: 1, ease: 'elastic.out' });

// Presets
animation.fadeIn('.element');
animation.fadeOut('.element');
animation.slideIn('.element', 'left');
animation.bounce('.element');
animation.shake('.element');

// Timeline
const tl = animation.timeline()
  .to('.box1', { x: 100 })
  .to('.box2', { rotation: 360 })
  .to('.box3', { scale: 1.5 });

tl.play();
tl.reverse();

// Stagger
animation.stagger('.items', { opacity: 1, y: 0 }, 0.1);
```

### PSM.createForms(form, options) (v1.2.0)

Creates a form validation instance.

```javascript
const forms = PSM.createForms('#myForm', {
  validateOnBlur: true,
  validateOnInput: true,
  showErrors: true
});

// Define fields and validators
forms
  .field('email', { required: true, email: true })
  .field('password', { required: true, minLength: 8 })
  .field('age', { required: true, min: 18, max: 100 })
  .field('card', { creditCard: true })
  .field('phone', { phone: true })
  .field('custom', {
    custom: (value) => value.startsWith('PSM') || 'Must start with PSM'
  });

// Validate
const result = forms.validate();
// { valid: true, errors: {}, data: { email: '...', password: '...' } }

// Events
forms.on('valid', () => console.log('Form is valid'));
forms.on('invalid', () => console.log('Form has errors'));
```

### PSM.createStorage(options) (v1.2.0)

Creates a unified storage instance with localStorage/IndexedDB.

```javascript
const storage = await PSM.createStorage({
  prefix: 'myapp',
  driver: 'auto',  // 'localStorage', 'indexedDB', or 'auto'
  encrypt: true,
  encryptionKey: 'secret'
});

// Basic operations
await storage.set('user', { name: 'John', age: 30 });
const user = await storage.get('user');
await storage.remove('user');
await storage.clear();

// TTL (time to live)
await storage.set('token', 'abc123', { ttl: 3600000 }); // expires in 1 hour

// Batch operations
await storage.setMany({ key1: 'val1', key2: 'val2' });
const values = await storage.getMany(['key1', 'key2']);

// Watch for changes
const unwatch = storage.watch('theme', (newVal, oldVal) => {
  console.log('Theme changed:', oldVal, '->', newVal);
});
```

### PSM.createToast(options) (v1.2.0)

Creates a toast notification system.

```javascript
const toast = await PSM.createToast({
  position: 'top-right',  // top-left, top-center, bottom-right, etc.
  duration: 4000,
  showProgress: true,
  pauseOnHover: true
});

// Basic notifications
toast.show('Hello!');
toast.success('Saved successfully');
toast.error('Something went wrong');
toast.warning('Low disk space');
toast.info('New update available');

// With options
toast.show('Custom toast', {
  title: 'Notification',
  duration: 6000,
  icon: '🚀',
  actions: [
    { label: 'Undo', onClick: () => undoAction() },
    { label: 'View', onClick: () => viewDetails() }
  ]
});

// Promise toast (loading -> success/error)
toast.promise(fetch('/api/data'), {
  loading: 'Loading...',
  success: 'Data loaded!',
  error: 'Failed to load data'
});

// Dismiss
const id = toast.show('Message');
toast.dismiss(id);
toast.dismissAll();
```

### PSMTheme (v1.2.0)

Theme customization module.

```javascript
// Create with preset
const theme = PSMTheme.create({ preset: 'midnight' });

// Available presets: default, light, midnight, forest, sunset, ocean, rose

// Apply preset
theme.apply('forest');

// Custom colors
theme.set({
  colors: {
    primary: '#ff6b9d',
    background: '#1a1a2e',
    text: '#ffffff'
  }
});

// Get current theme
const current = theme.get();
console.log(current.colors.primary);

// Generate CSS variables
const css = theme.generateCSS();

// Listen for changes
theme.onChange(({ theme, preset }) => {
  console.log('Theme changed:', preset);
});

// Color utilities
PSMTheme.lighten('#9b30ff', 0.2);
PSMTheme.darken('#9b30ff', 0.2);
PSMTheme.alpha('#9b30ff', 0.5);
```

### PSMPlugins (v1.2.0)

Plugin system for extending PSM SDK.

```javascript
// Create and register a plugin
const myPlugin = PSMPlugins.createPlugin({
  name: 'my-plugin',
  version: '1.0.0',
  description: 'My custom functionality',

  install(PSM, config) {
    PSM.myFeature = {
      doSomething: () => console.log('Doing something!')
    };
  },

  uninstall(PSM) {
    delete PSM.myFeature;
  },

  hooks: {
    afterCreate: (ctx) => {
      console.log('Module created:', ctx.module);
    }
  }
});

PSMPlugins.register(myPlugin);

// Built-in plugins
PSMPlugins.register(PSMPlugins.builtIn.Analytics);
PSMPlugins.register(PSMPlugins.builtIn.Debug);
PSMPlugins.register(PSMPlugins.builtIn.Performance);

// Use analytics
PSM.analytics.track('button:click', { id: 'submit' });

// Use debug
PSM.debug.log('Loading module...');
PSM.debug.warn('Deprecated feature');

// Use performance
PSM.performance.mark('start');
// ... do work ...
PSM.performance.measure('operation', 'start');
```

### Vue Composables (v1.2.0)

Vue 3 Composition API hooks.

```javascript
import { PSMVue } from '@purplesquirrel/psm-sdk/dist/vue.js';

// Install as Vue plugin
app.use(PSMVue);

// Or use composables directly
const { player, isPlaying, play, pause, toggle } = PSMVue.usePlayer();
const { toast, success, error } = PSMVue.useToast();
const { animation, fadeIn, slideIn } = PSMVue.useAnimation();
const { data, isLoading } = PSMVue.useStorage('key', defaultValue);
const { errors, isValid, validate } = PSMVue.useForms(formRef);
```

### PSM.utils

Utility functions.

```javascript
PSM.utils.formatTime(125);        // "2:05"
PSM.utils.formatBytes(1536000);   // "1.46 MB"
PSM.utils.generateId();           // "psm_abc123..."
PSM.utils.isMobile();             // true/false
PSM.utils.hasTouch();             // true/false
PSM.utils.debounce(fn, 300);
PSM.utils.throttle(fn, 100);
PSM.utils.sleep(1000);            // async delay
PSM.utils.clamp(value, min, max);
PSM.utils.lerp(start, end, t);
await PSM.utils.copyToClipboard('text');

// Fullscreen
PSM.utils.fullscreen.enter(element);
PSM.utils.fullscreen.exit();
PSM.utils.fullscreen.toggle(element);
```

## CDN Links

```
# Full SDK
https://purplesquirrel.media/sdk/psm.js
https://purplesquirrel.media/sdk/psm.min.js

# Core Media
https://purplesquirrel.media/sdk/squirrel-player.js
https://purplesquirrel.media/sdk/stream.js
https://purplesquirrel.media/sdk/sync.js
https://purplesquirrel.media/sdk/audio.js
https://purplesquirrel.media/sdk/peer.js

# Creative Tools
https://purplesquirrel.media/sdk/canvas.js
https://purplesquirrel.media/sdk/charts.js
https://purplesquirrel.media/sdk/three.js
https://purplesquirrel.media/sdk/play.js

# Document & Code
https://purplesquirrel.media/sdk/markdown.js
https://purplesquirrel.media/sdk/code.js
https://purplesquirrel.media/sdk/docs.js

# New in v1.2.0
https://purplesquirrel.media/sdk/animation.js
https://purplesquirrel.media/sdk/forms.js
https://purplesquirrel.media/sdk/storage.js
https://purplesquirrel.media/sdk/toast.js
https://purplesquirrel.media/sdk/theme.js
https://purplesquirrel.media/sdk/plugins.js
https://purplesquirrel.media/sdk/vue.js
https://purplesquirrel.media/sdk/react.js

# Alternative CDNs
https://unpkg.com/@purplesquirrel/psm-sdk/dist/psm.js
https://cdn.jsdelivr.net/npm/@purplesquirrel/psm-sdk/dist/psm.js
```

## TypeScript

PSM SDK includes full TypeScript definitions.

```typescript
import PSM from '@purplesquirrel/psm-sdk';

const player: PSM.Player = await PSM.createPlayer('#video');
const canvas: PSM.Canvas = await PSM.createCanvas('myCanvas');

player.on('play', () => console.log('Playing'));
canvas.addRect({ fill: '#9b30ff', width: 100, height: 100 });
```

## Live Examples

### Core Examples
- [Examples Index](https://purplesquirrel.media/sdk/examples/index.html)
- [Tutorial](https://purplesquirrel.media/sdk/examples/tutorial.html)
- [Playground](https://purplesquirrel.media/sdk/examples/playground.html)
- [API Explorer](https://purplesquirrel.media/sdk/examples/api-explorer.html)

### v1.2.0 Demos
- [Animation Demo](https://purplesquirrel.media/sdk/examples/animation-demo.html)
- [Forms Demo](https://purplesquirrel.media/sdk/examples/forms-demo.html)
- [Storage Demo](https://purplesquirrel.media/sdk/examples/storage-demo.html)
- [Toast Demo](https://purplesquirrel.media/sdk/examples/toast-demo.html)
- [Theme Demo](https://purplesquirrel.media/sdk/examples/theme-demo.html)
- [Plugins Demo](https://purplesquirrel.media/sdk/examples/plugins-demo.html)

### Media Examples
- [Streaming Dashboard](https://purplesquirrel.media/sdk/examples/streaming-dashboard.html)
- [Watch Party Sync](https://purplesquirrel.media/sdk/examples/sync-demo.html)

## Documentation

https://purplesquirrel.media/sdk/

## License

MIT