@wave-av/sdk 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@wave/sdk` are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.0.0] - 2026-04-01
11
+
12
+ ### Added
13
+
14
+ - **CloudSwitcherAPI** — Cloud video switcher control (instances, inputs, outputs, transitions, program/preview bus)
15
+ - **ReplayAPI** — Replay engine management (sessions, points of interest, clip export to social)
16
+ - **CameraControlAPI** — Multi-manufacturer camera control (PTZ, focus, iris, presets, discovery)
17
+ - **GraphicsAPI** — Lower-thirds, overlays, and animated graphics layer management
18
+ - **SportsDataAPI** — Live sports data integration (scoreboards, clocks, stats, player cards)
19
+ - **AutomationAPI** — Rule-based production automation (triggers, actions, schedules, rundowns)
20
+ - **StorefrontAPI** — Creator commerce (products, purchases, entitlement checks, storefronts)
21
+
22
+ ### Changed
23
+
24
+ - Client HTTP methods replaced `client.request()` with dedicated `client.get()`, `client.post()`, and `client.delete()` for clearer intent and improved TypeScript inference. Migration:
25
+
26
+ ```typescript
27
+ // Before (v1.x)
28
+ const stream = await client.request<Stream>('/v1/streams/abc', {
29
+ method: 'GET',
30
+ });
31
+
32
+ // After (v2.0)
33
+ const stream = await client.get<Stream>('/v1/streams/abc');
34
+ ```
35
+
36
+ - `Wave` convenience class expanded from 12 to 34 API module properties
37
+ - `PipelineAPI`, `StudioAPI`, `FleetAPI`, `GhostAPI`, `MeshAPI`, `EdgeAPI`, `PulseAPI`, and `ClipsAPI` promoted from beta to stable
38
+
39
+ ## [1.0.0] - 2025-10-15
40
+
41
+ ### Added
42
+
43
+ - Initial public release
44
+ - **PipelineAPI** — Live stream management (create, start, stop, recordings, viewer metrics, protocol switching)
45
+ - **StudioAPI** — Multi-camera production (sources, scenes, transitions, graphics, audio mixing)
46
+ - **FleetAPI** — Desktop Node fleet management (register, health, commands, metrics)
47
+ - **GhostAPI** — AI automatic directing (autonomous/assisted modes, suggestions, overrides)
48
+ - **MeshAPI** — Multi-region failover (regions, peers, policies, replication, topology)
49
+ - **EdgeAPI** — CDN and edge workers (deploy, routing, cache purge, latency map)
50
+ - **PulseAPI** — Analytics and BI (stream, viewer, quality, engagement, revenue metrics; dashboards; reports)
51
+ - **ClipsAPI** — Clip creation from live or VOD sources (export, highlights, AI detection)
52
+ - Base `WaveClient` with API key authentication, configurable retry logic (default 3 attempts), rate limit handling, and optional OpenTelemetry integration
53
+ - `Wave` convenience class bundling all 12 API modules under a single import
54
+ - TypeScript strict mode throughout; ESM and CJS dual output via `tsup`
55
+
56
+ [Unreleased]: https://github.com/wave-av/wave-surfer-connect/compare/sdk-v2.0.0...HEAD
57
+ [2.0.0]: https://github.com/wave-av/wave-surfer-connect/compare/sdk-v1.0.0...sdk-v2.0.0
58
+ [1.0.0]: https://github.com/wave-av/wave-surfer-connect/releases/tag/sdk-v1.0.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 WAVE Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,406 @@
1
+ # WAVE SDK for TypeScript
2
+
3
+ Official TypeScript SDK for the WAVE API by WAVE Inc.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @wave/sdk
9
+ # or
10
+ npm install @wave/sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { Wave } from "@wave/sdk";
17
+
18
+ const wave = new Wave({
19
+ apiKey: process.env.WAVE_API_KEY!,
20
+ organizationId: "org_123",
21
+ });
22
+
23
+ // Create and start a live stream
24
+ const stream = await wave.pipeline.create({
25
+ title: "My Live Stream",
26
+ protocol: "webrtc",
27
+ recording_enabled: true,
28
+ });
29
+ await wave.pipeline.start(stream.id);
30
+
31
+ // Create a virtual camera from NDI
32
+ const device = await wave.prism.createDevice({
33
+ name: "PTZ Camera 1",
34
+ type: "camera",
35
+ source_protocol: "ndi",
36
+ source_endpoint: "NDI-CAM-1",
37
+ node_id: "node_abc",
38
+ ptz_enabled: true,
39
+ });
40
+
41
+ // Get analytics
42
+ const viewers = await wave.pulse.getViewerAnalytics({ time_range: "24h" });
43
+ console.log(`Peak concurrent: ${viewers.peak_concurrent}`);
44
+ ```
45
+
46
+ ## All 34 APIs
47
+
48
+ ### P1 - Core Streaming
49
+
50
+ | API | Access | Description |
51
+ | --------------- | ------------- | -------------------------------------------------------------------- |
52
+ | `wave.pipeline` | `PipelineAPI` | Live stream lifecycle, protocols, recordings, viewer metrics |
53
+ | `wave.studio` | `StudioAPI` | Multi-camera production, scenes, transitions, graphics, audio mixing |
54
+
55
+ ### P2 - Enterprise
56
+
57
+ | API | Access | Description |
58
+ | ------------ | ---------- | ------------------------------------------------------------ |
59
+ | `wave.fleet` | `FleetAPI` | Desktop Node fleet management, health, commands |
60
+ | `wave.ghost` | `GhostAPI` | AI auto-directing (Autopilot), suggestions, overrides |
61
+ | `wave.mesh` | `MeshAPI` | Multi-region failover, replication, topology |
62
+ | `wave.edge` | `EdgeAPI` | CDN, edge workers, cache, routing rules |
63
+ | `wave.pulse` | `PulseAPI` | Analytics, BI dashboards, revenue metrics |
64
+ | `wave.prism` | `PrismAPI` | Virtual Device Bridge (NDI/ONVIF/VISCA/Dante to USB UVC/UAC) |
65
+ | `wave.zoom` | `ZoomAPI` | Zoom meetings, rooms, recordings, RTMS |
66
+
67
+ ### P3 - Content & Commerce
68
+
69
+ | API | Access | Description |
70
+ | ------------------- | ----------------- | ------------------------------------------- |
71
+ | `wave.clips` | `ClipsAPI` | Video clips, exports, AI highlights |
72
+ | `wave.editor` | `EditorAPI` | Video editing, tracks, transitions, effects |
73
+ | `wave.voice` | `VoiceAPI` | Text-to-speech, voice cloning |
74
+ | `wave.phone` | `PhoneAPI` | Voice calling, conferences, numbers |
75
+ | `wave.collab` | `CollabAPI` | Real-time collaboration rooms |
76
+ | `wave.captions` | `CaptionsAPI` | Auto-captions, translation, burn-in |
77
+ | `wave.chapters` | `ChaptersAPI` | Video chapters and markers |
78
+ | `wave.studioAI` | `StudioAIAPI` | AI production assistant, suggestions |
79
+ | `wave.transcribe` | `TranscribeAPI` | Transcription with speaker diarization |
80
+ | `wave.sentiment` | `SentimentAPI` | Sentiment and emotion analysis |
81
+ | `wave.search` | `SearchAPI` | Full-text, visual, and audio search |
82
+ | `wave.scene` | `SceneAPI` | AI scene detection and shot classification |
83
+ | `wave.vault` | `VaultAPI` | Recording storage, VOD, archive policies |
84
+ | `wave.marketplace` | `MarketplaceAPI` | Templates, plugins, graphics marketplace |
85
+ | `wave.connect` | `ConnectAPI` | Third-party integrations, webhooks |
86
+ | `wave.distribution` | `DistributionAPI` | Social simulcasting, scheduled posts |
87
+ | `wave.desktop` | `DesktopAPI` | Desktop Node app management |
88
+ | `wave.signage` | `SignageAPI` | Digital signage displays, playlists |
89
+ | `wave.qr` | `QrAPI` | Dynamic QR codes, analytics |
90
+ | `wave.audience` | `AudienceAPI` | Polls, Q&A, reactions, engagement |
91
+ | `wave.creator` | `CreatorAPI` | Monetization, subscriptions, tips, payouts |
92
+
93
+ ### P4 - Specialized
94
+
95
+ | API | Access | Description |
96
+ | -------------- | ------------ | ----------------------------------- |
97
+ | `wave.podcast` | `PodcastAPI` | Podcast episodes, RSS, distribution |
98
+ | `wave.slides` | `SlidesAPI` | Presentation-to-video conversion |
99
+ | `wave.usb` | `UsbAPI` | USB device relay and management |
100
+
101
+ ## Product Examples
102
+
103
+ - [Streams (Pipeline)](#streams-pipeline)
104
+ - [Clips](#clips)
105
+ - [Captions](#captions)
106
+ - [Chapters](#chapters)
107
+ - [Voice](#voice)
108
+ - [Transcription](#transcription)
109
+ - [Editor](#editor)
110
+ - [Phone](#phone)
111
+ - [Podcast](#podcast)
112
+ - [Collab](#collab)
113
+ - [Analytics (Pulse)](#analytics-pulse)
114
+ - [VOD (Vault)](#vod-vault)
115
+ - [Studio AI](#studio-ai)
116
+
117
+ ---
118
+
119
+ ### Streams (Pipeline)
120
+
121
+ ```typescript
122
+ import { Wave } from "@wave/sdk";
123
+
124
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
125
+
126
+ const stream = await wave.pipeline.create({
127
+ title: "My Live Stream",
128
+ protocol: "webrtc",
129
+ recording_enabled: true,
130
+ });
131
+ await wave.pipeline.start(stream.id);
132
+ const live = await wave.pipeline.waitForLive(stream.id);
133
+ console.log(`Playback: ${live.playback_url}`);
134
+ await wave.pipeline.stop(stream.id);
135
+ ```
136
+
137
+ ### Clips
138
+
139
+ ```typescript
140
+ import { Wave } from "@wave/sdk";
141
+
142
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
143
+
144
+ const clip = await wave.clips.create({
145
+ title: "Best Moment",
146
+ source: { type: "stream", id: "stream_123", start_time: 120, end_time: 150 },
147
+ });
148
+ const ready = await wave.clips.waitForReady(clip.id);
149
+ console.log(`Clip URL: ${ready.playback_url}`);
150
+ ```
151
+
152
+ ### Captions
153
+
154
+ ```typescript
155
+ import { Wave } from "@wave/sdk";
156
+
157
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
158
+
159
+ const track = await wave.captions.generate({
160
+ media_id: "video_123",
161
+ media_type: "video",
162
+ language: "en",
163
+ speaker_diarization: true,
164
+ });
165
+ const ready = await wave.captions.waitForReady(track.id);
166
+ await wave.captions.translate(ready.id, { target_language: "es" });
167
+ ```
168
+
169
+ ### Chapters
170
+
171
+ ```typescript
172
+ import { Wave } from "@wave/sdk";
173
+
174
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
175
+
176
+ const chapterSet = await wave.chapters.generate({
177
+ media_id: "video_123",
178
+ media_type: "video",
179
+ method: "combined",
180
+ generate_thumbnails: true,
181
+ });
182
+ const ready = await wave.chapters.waitForReady(chapterSet.id);
183
+ console.log(`Found ${ready.chapter_count} chapters`);
184
+ ```
185
+
186
+ ### Voice
187
+
188
+ ```typescript
189
+ import { Wave } from "@wave/sdk";
190
+
191
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
192
+
193
+ const voices = await wave.voice.listVoices({ language: "en" });
194
+ const result = await wave.voice.synthesize({
195
+ text: "Welcome to WAVE live streaming.",
196
+ voice_id: voices.data[0].id,
197
+ format: "mp3",
198
+ });
199
+ const audio = await wave.voice.waitForSynthesis(result.id);
200
+ console.log(`Audio: ${audio.audio_url}`);
201
+ ```
202
+
203
+ ### Transcription
204
+
205
+ ```typescript
206
+ import { Wave } from "@wave/sdk";
207
+
208
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
209
+
210
+ const job = await wave.transcribe.create({
211
+ source_type: "recording",
212
+ source_id: "rec_456",
213
+ language: "en",
214
+ speaker_diarization: true,
215
+ });
216
+ const result = await wave.transcribe.waitForReady(job.id);
217
+ const text = await wave.transcribe.getText(result.id, { include_speakers: true });
218
+ console.log(text);
219
+ ```
220
+
221
+ ### Editor
222
+
223
+ ```typescript
224
+ import { Wave } from "@wave/sdk";
225
+
226
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
227
+
228
+ const project = await wave.editor.createProject({
229
+ name: "Highlight Reel",
230
+ width: 1920,
231
+ height: 1080,
232
+ frame_rate: 30,
233
+ });
234
+ const track = await wave.editor.addTrack(project.id, { name: "Main", type: "video" });
235
+ await wave.editor.addElement(project.id, {
236
+ track_id: track.id,
237
+ type: "clip",
238
+ source_id: "clip_789",
239
+ start_time: 0,
240
+ });
241
+ const job = await wave.editor.render(project.id, { format: "mp4", quality: "high" });
242
+ const rendered = await wave.editor.waitForRender(project.id, job.id);
243
+ console.log(`Output: ${rendered.output_url}`);
244
+ ```
245
+
246
+ ### Phone
247
+
248
+ ```typescript
249
+ import { Wave } from "@wave/sdk";
250
+
251
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
252
+
253
+ const call = await wave.phone.makeCall({
254
+ from: "+15551234567",
255
+ to: "+15559876543",
256
+ timeout: 30,
257
+ });
258
+ console.log(`Call ${call.id} status: ${call.status}`);
259
+ ```
260
+
261
+ ### Podcast
262
+
263
+ ```typescript
264
+ import { Wave } from "@wave/sdk";
265
+
266
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
267
+
268
+ const show = await wave.podcast.create({
269
+ title: "The WAVE Podcast",
270
+ description: "Weekly streaming industry news",
271
+ category: "Technology",
272
+ });
273
+ const episode = await wave.podcast.createEpisode({
274
+ podcast_id: show.id,
275
+ title: "Episode 1: Getting Started",
276
+ description: "An introduction to live streaming.",
277
+ });
278
+ await wave.podcast.publishEpisode(episode.id);
279
+ ```
280
+
281
+ ### Collab
282
+
283
+ ```typescript
284
+ import { Wave } from "@wave/sdk";
285
+
286
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
287
+
288
+ const room = await wave.collab.createRoom({
289
+ name: "Project Review",
290
+ resource_type: "project",
291
+ resource_id: "proj_123",
292
+ settings: { voice_enabled: true, annotations_enabled: true },
293
+ });
294
+ console.log(`Room: ${room.id} (${room.participant_count} participants)`);
295
+ ```
296
+
297
+ ### Analytics (Pulse)
298
+
299
+ ```typescript
300
+ import { Wave } from "@wave/sdk";
301
+
302
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
303
+
304
+ const viewers = await wave.pulse.getViewerAnalytics({ time_range: "24h" });
305
+ console.log(`Peak concurrent: ${viewers.peak_concurrent}`);
306
+ console.log(`Unique viewers: ${viewers.unique_viewers}`);
307
+
308
+ const stream = await wave.pulse.getStreamAnalytics("stream_123", { time_range: "7d" });
309
+ console.log(`Quality score: ${stream.quality_score}`);
310
+ ```
311
+
312
+ ### VOD (Vault)
313
+
314
+ ```typescript
315
+ import { Wave } from "@wave/sdk";
316
+
317
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
318
+
319
+ const upload = await wave.vault.createUpload({
320
+ title: "Conference Keynote",
321
+ format: "mp4",
322
+ file_size_bytes: 524288000,
323
+ });
324
+ console.log(`Upload to: ${upload.upload_url}`);
325
+
326
+ const usage = await wave.vault.getStorageUsage();
327
+ console.log(`Storage: ${usage.usage_percent}% used`);
328
+ ```
329
+
330
+ ### Studio AI
331
+
332
+ ```typescript
333
+ import { Wave } from "@wave/sdk";
334
+
335
+ const wave = new Wave({ apiKey: process.env.WAVE_API_KEY! });
336
+
337
+ const assistant = await wave.studioAI.startAssistant({
338
+ stream_id: "stream_123",
339
+ mode: "auto_director",
340
+ config: { automation_level: 75, auto_apply: false, confidence_threshold: 0.8, settings: {} },
341
+ });
342
+ const suggestions = await wave.studioAI.getSuggestion(assistant.id);
343
+ console.log(`AI suggestion: ${suggestions.title} (${suggestions.confidence * 100}% confidence)`);
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Configuration
349
+
350
+ ```typescript
351
+ const wave = new Wave({
352
+ apiKey: "your-api-key", // Required
353
+ organizationId: "org_123", // Multi-tenant isolation
354
+ baseUrl: "https://api.wave.online", // Default
355
+ timeout: 30000, // Request timeout (ms)
356
+ maxRetries: 3, // Retry attempts
357
+ debug: false, // Debug logging
358
+ });
359
+ ```
360
+
361
+ ## Individual API Imports
362
+
363
+ ```typescript
364
+ import { WaveClient, PipelineAPI, PrismAPI } from "@wave/sdk";
365
+
366
+ const client = new WaveClient({ apiKey: "key" });
367
+ const pipeline = new PipelineAPI(client);
368
+ const prism = new PrismAPI(client);
369
+ ```
370
+
371
+ ## Error Handling
372
+
373
+ ```typescript
374
+ import { WaveError, RateLimitError } from "@wave/sdk";
375
+
376
+ try {
377
+ await wave.pipeline.get("invalid-id");
378
+ } catch (error) {
379
+ if (error instanceof RateLimitError) {
380
+ console.log(`Rate limited. Retry after ${error.retryAfter}ms`);
381
+ } else if (error instanceof WaveError) {
382
+ console.log(`${error.code}: ${error.message} (${error.statusCode})`);
383
+ }
384
+ }
385
+ ```
386
+
387
+ ## Events
388
+
389
+ ```typescript
390
+ wave.client.on("request.start", (url, method) => {
391
+ console.log(`${method} ${url}`);
392
+ });
393
+
394
+ wave.client.on("rate_limit.hit", (retryAfter) => {
395
+ console.log(`Rate limited. Waiting ${retryAfter}ms`);
396
+ });
397
+ ```
398
+
399
+ ## Requirements
400
+
401
+ - Node.js 18+
402
+ - TypeScript 5.0+ (for TypeScript users)
403
+
404
+ ## License
405
+
406
+ MIT - WAVE Inc.