lightstream-sdk 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LightStream
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/QUICKSTART.md ADDED
@@ -0,0 +1,150 @@
1
+ # LightStream SDK Quickstart Guide
2
+
3
+ This guide walks you through setting up and running your first LightStream integration in 5 minutes.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ 1. Node.js 18+, Bun, or Deno installed.
10
+ 2. A LightStream API Key.
11
+ 3. LightStream Gateway Base URL: `https://gateway.lightstream.lat`
12
+
13
+ ---
14
+
15
+ ## 1. Project Setup
16
+
17
+ Create a new directory and install dependencies:
18
+
19
+ ```bash
20
+ mkdir my-lightstream-bot
21
+ cd my-lightstream-bot
22
+ npm init -y
23
+ npm install lightstream-sdk
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 2. Hello World: Realtime Chat Listener
29
+
30
+ Create `bot.js` (or `bot.ts`):
31
+
32
+ ```javascript
33
+ import { createLightStreamClient } from 'lightstream-sdk';
34
+
35
+ const client = createLightStreamClient({
36
+ baseUrl: 'https://gateway.lightstream.lat',
37
+ wsUrl: 'wss://gateway.lightstream.lat/ws',
38
+ apiKey: process.env.LIGHTSTREAM_API_KEY || 'YOUR_API_KEY'
39
+ });
40
+
41
+ client.stream.on('status', (status) => {
42
+ console.log(`[Status] ${status}`);
43
+ });
44
+
45
+ client.stream.on('connected', (evt) => {
46
+ console.log(`[Connected] Live on ${evt.platform} - ${evt.channel} (${evt.viewerCount} viewers)`);
47
+ });
48
+
49
+ client.stream.on('stream:offline', (evt) => {
50
+ console.log(`[Offline] Channel ${evt.channel} is not streaming right now.`);
51
+ });
52
+
53
+ client.stream.on('chat', (msg) => {
54
+ console.log(`💬 ${msg.user.displayName}: ${msg.content}`);
55
+ });
56
+
57
+ client.stream.on('gift', (gift) => {
58
+ console.log(`🎁 ${gift.user.displayName} sent ${gift.gift.name} x${gift.gift.repeatCount}`);
59
+ });
60
+
61
+ // Connect to TikTok, Kick, or Twitch
62
+ client.stream.connect('kick', 'xqc');
63
+ ```
64
+
65
+ Run the bot:
66
+
67
+ ```bash
68
+ node bot.js
69
+ ```
70
+
71
+ ---
72
+
73
+ ## 3. Frontend Integration (Next.js / React)
74
+
75
+ When building client-facing web applications or OBS overlays, **never** bundle your master API key in the client!
76
+
77
+ ### Step A: Backend API Route (`/api/get-stream-token`)
78
+ ```typescript
79
+ import { createLightStreamClient } from 'lightstream-sdk'
80
+
81
+ const serverClient = createLightStreamClient({
82
+ baseUrl: 'https://gateway.lightstream.lat',
83
+ apiKey: process.env.LIGHTSTREAM_MASTER_KEY!
84
+ })
85
+
86
+ export async function POST(req: Request) {
87
+ const { channel, platform } = await req.json()
88
+
89
+ // Issue a 5-minute scoped token for this viewer/channel only
90
+ const { token, expiresAt } = await serverClient.rest.issueToken({
91
+ allowedPlatforms: [platform],
92
+ allowedChannels: [channel],
93
+ expireAfterSeconds: 300,
94
+ maxWebSockets: 1
95
+ })
96
+
97
+ return Response.json({ token, expiresAt })
98
+ }
99
+ ```
100
+
101
+ ### Step B: React Component
102
+ ```tsx
103
+ 'use client'
104
+ import { useEffect, useState } from 'react'
105
+ import { createLightStreamClient, type ConnectionStatus } from 'lightstream-sdk'
106
+
107
+ export function LiveChatWidget({ platform, channel }) {
108
+ const [messages, setMessages] = useState<string[]>([])
109
+ const [status, setStatus] = useState<ConnectionStatus>('idle')
110
+
111
+ useEffect(() => {
112
+ let client: any
113
+
114
+ async function init() {
115
+ // 1. Fetch ephemeral token from our secure server route
116
+ const res = await fetch('/api/get-stream-token', {
117
+ method: 'POST',
118
+ headers: { 'Content-Type': 'application/json' },
119
+ body: JSON.stringify({ platform, channel })
120
+ })
121
+ const { token } = await res.json()
122
+
123
+ // 2. Connect client with ephemeral token
124
+ client = createLightStreamClient({ token })
125
+
126
+ client.stream.on('status', setStatus)
127
+ client.stream.on('chat', (msg) => {
128
+ setMessages((prev) => [...prev.slice(-49), `${msg.user.displayName}: ${msg.content}`])
129
+ })
130
+
131
+ await client.stream.connect(platform, channel)
132
+ }
133
+
134
+ init()
135
+
136
+ return () => {
137
+ client?.stream.disconnect()
138
+ }
139
+ }, [platform, channel])
140
+
141
+ return (
142
+ <div className="chat-container">
143
+ <div className="badge">Status: {status}</div>
144
+ <ul>
145
+ {messages.map((m, i) => <li key={i}>{m}</li>)}
146
+ </ul>
147
+ </div>
148
+ )
149
+ }
150
+ ```
package/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # lightstream-sdk
2
+
3
+ Official TypeScript & JavaScript SDK for the **LightStream Developer Platform**.
4
+
5
+ Interact with **TikTok LIVE**, **Kick**, and **Twitch** using a single, unified client. LightStream provides real-time WebSockets, verified stream lifecycle management, rich metadata APIs, leaderboards, and unified cross-platform chat moderation.
6
+
7
+ ---
8
+
9
+ ## ✨ Features
10
+
11
+ - **🌐 Unified Real-time WebSockets**: Connect to TikTok, Kick, and Twitch with one common interface and protocol.
12
+ - **🛡️ Zero False Positives**: Connection state is strictly backed by upstream verification. The client emits `stream:offline` with `STREAMER_OFFLINE` when the channel is not live, guaranteeing that `connected` only fires when live data is flowing.
13
+ - **⚡ Fast REST APIs**:
14
+ - **Bulk Live Check**: Check live status and viewer counts for up to 100 streamers in a single call.
15
+ - **Playback & Stream Info**: Retrieve HLS (`.m3u8`) playback streams and stream titles.
16
+ - **Monetization & Earnings**: Track gifts, bits, kicks, and estimated USD earnings.
17
+ - **Rankings & Leaderboards**: Query hourly, daily, and weekly creator leaderboards.
18
+ - **Cross-Platform Moderation**: Mute, ban, delete chat messages, and toggle comments across platforms.
19
+ - **🔑 Scoped Ephemeral Tokens**: Generate secure, short-lived JWTs to embed directly in frontend applications or widgets without leaking master API keys.
20
+ - **🔄 Resilient State Machine**: Built-in heartbeat (`ping`/`pong`), auto-reconnection with exponential backoff, and strict lifecycle states.
21
+ - **📦 Isomorphic**: Works out of the box in Node.js, Bun, Deno, and modern web browsers.
22
+
23
+ ---
24
+
25
+ ## 🚀 Installation
26
+
27
+ ```bash
28
+ # Using npm
29
+ npm install lightstream-sdk
30
+
31
+ # Using pnpm
32
+ pnpm add lightstream-sdk
33
+
34
+ # Using bun
35
+ bun add lightstream-sdk
36
+ ```
37
+
38
+ *(If consuming as a local package, you can also link it via `"file:../lightstream-sdk"`)*
39
+
40
+ ---
41
+
42
+ ## ⚡ Quick Start
43
+
44
+ ### 1. Connecting to a Live Stream (WebSocket)
45
+
46
+ ```typescript
47
+ import { createLightStreamClient } from 'lightstream-sdk'
48
+
49
+ const client = createLightStreamClient({
50
+ baseUrl: 'https://gateway.lightstream.lat',
51
+ wsUrl: 'wss://gateway.lightstream.lat/ws',
52
+ apiKey: 'your_api_key_here' // Or use ephemeral token: token: 'eyJ...'
53
+ })
54
+
55
+ // Track connection state machine
56
+ client.stream.on('status', (status) => {
57
+ console.log('Connection status:', status)
58
+ // 'idle' | 'connecting' | 'connected' | 'offline' | 'reconnecting' | 'disconnected' | 'error'
59
+ })
60
+
61
+ // Guaranteed: Only fires when the channel is 100% verified LIVE
62
+ client.stream.on('connected', (event) => {
63
+ console.log(`✅ Connected to ${event.platform} channel: ${event.channel}`)
64
+ console.log(`Viewers: ${event.viewerCount}, Title: ${event.title}`)
65
+ })
66
+
67
+ // Streamer is not streaming (Zero false positives)
68
+ client.stream.on('stream:offline', (event) => {
69
+ console.warn(`⚠️ Channel ${event.channel} is currently offline. Code: ${event.code}`)
70
+ })
71
+
72
+ // Real-time Chat
73
+ client.stream.on('chat', (msg) => {
74
+ console.log(`[${msg.platform}] ${msg.user.displayName}: ${msg.content}`)
75
+ })
76
+
77
+ // Real-time Gifts / Monetization
78
+ client.stream.on('gift', (gift) => {
79
+ console.log(`🎁 ${gift.user.displayName} sent ${gift.gift.name} x${gift.gift.repeatCount} (${gift.gift.value} diamonds/coins)`)
80
+ })
81
+
82
+ // Handle errors
83
+ client.stream.on('error', (err) => {
84
+ console.error(`❌ Error [${err.code}]: ${err.message}`)
85
+ })
86
+
87
+ // Connect to a channel
88
+ await client.stream.connect('twitch', 'ninja')
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 🛠️ REST API Usage
94
+
95
+ ### Bulk Check Live Status
96
+
97
+ Check the status of multiple streamers simultaneously across different platforms:
98
+
99
+ ```typescript
100
+ const results = await client.rest.bulkCheckStreams([
101
+ { platform: 'tiktok', channel: 'charlidamelio' },
102
+ { platform: 'kick', channel: 'xqc' },
103
+ { platform: 'twitch', channel: 'shroud' },
104
+ ])
105
+
106
+ for (const stream of results) {
107
+ console.log(`${stream.platform}/@${stream.channel}: ${stream.isLive ? '🔴 LIVE' : '⚪ OFFLINE'} (${stream.viewerCount} viewers)`)
108
+ }
109
+ ```
110
+
111
+ ### Issue Scoped Ephemeral Tokens (for Frontend / Overlays)
112
+
113
+ Do not expose your master API key in client-side code! Issue a short-lived token instead:
114
+
115
+ ```typescript
116
+ const { token, expiresAt } = await client.rest.issueToken({
117
+ allowedPlatforms: ['kick', 'twitch'],
118
+ allowedChannels: ['my_channel'],
119
+ expireAfterSeconds: 300, // 5 minutes
120
+ maxWebSockets: 2,
121
+ })
122
+
123
+ // The frontend can now safely connect:
124
+ // const client = createLightStreamClient({ token })
125
+ ```
126
+
127
+ ### Unified Chat Moderation
128
+
129
+ Perform moderation actions regardless of the platform:
130
+
131
+ ```typescript
132
+ // Mute user for 60 seconds
133
+ await client.rest.moderation.mute('tiktok', 'my_channel', 'spammer_username', 60)
134
+
135
+ // Ban user
136
+ await client.rest.moderation.ban('kick', 'my_channel', 'bad_actor', 'Violated rules')
137
+
138
+ // Delete a message
139
+ await client.rest.moderation.deleteMessage('twitch', 'my_channel', 'msg-uuid-123')
140
+
141
+ // Disable chat comments
142
+ await client.rest.moderation.toggleComments('tiktok', 'my_channel', false)
143
+ ```
144
+
145
+ ### Rankings & Leaderboards
146
+
147
+ ```typescript
148
+ // Top streamers on TikTok today
149
+ const topDaily = await client.rest.getLeaderboard('tiktok', 'daily', 20)
150
+ console.log('Top Streamer:', topDaily[0])
151
+
152
+ // Search streamer ranking
153
+ const rank = await client.rest.searchRankings('my_streamer', 'tiktok', 'daily')
154
+ console.log(`Position: #${rank.rank} with ${rank.score} points`)
155
+ ```
156
+
157
+ ---
158
+
159
+ ## 📖 Canonical Error Codes
160
+
161
+ The SDK and Gateway use canonical, strongly typed error codes:
162
+
163
+ | Code | Meaning | Action / Handling |
164
+ | :--- | :--- | :--- |
165
+ | `STREAMER_OFFLINE` | The channel exists but is not broadcasting live. | Display offline banner in UI. Do not expect stream data. |
166
+ | `ROOM_NOT_FOUND` | The requested username/channel was not found. | Check spelling or channel username. |
167
+ | `AUTHENTICATION_FAILED` | Invalid API key or expired token. | Refresh credentials. |
168
+ | `FORBIDDEN_CHANNEL` | The ephemeral token is not authorized for this channel. | Generate a token with correct `allowedChannels`. |
169
+ | `RATE_LIMITED` | Too many requests or concurrent connections. | Backoff and retry later. |
170
+ | `UPSTREAM_ERROR` | Error from TikTok, Kick, or Twitch API. | Client will auto-reconnect if retryable. |
171
+ | `TIMEOUT` | Connection attempt timed out. | Retry with exponential backoff. |
172
+ | `INTERNAL_ERROR` | Unhandled gateway server error. | Contact support or check gateway status. |
173
+
174
+ ---
175
+
176
+ ## 📄 License
177
+
178
+ MIT © 2026 LightStream
@@ -0,0 +1,26 @@
1
+ export declare const LIGHTSTREAM_ERROR_CODES: {
2
+ readonly STREAMER_OFFLINE: "STREAMER_OFFLINE";
3
+ readonly ROOM_NOT_FOUND: "ROOM_NOT_FOUND";
4
+ readonly AUTHENTICATION_FAILED: "AUTHENTICATION_FAILED";
5
+ readonly FORBIDDEN_CHANNEL: "FORBIDDEN_CHANNEL";
6
+ readonly RATE_LIMITED: "RATE_LIMITED";
7
+ readonly UPSTREAM_ERROR: "UPSTREAM_ERROR";
8
+ readonly TIMEOUT: "TIMEOUT";
9
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
10
+ };
11
+ export type LightStreamErrorCode = keyof typeof LIGHTSTREAM_ERROR_CODES;
12
+ export interface LightStreamErrorPayload {
13
+ code: LightStreamErrorCode;
14
+ message: string;
15
+ details?: unknown;
16
+ retryable?: boolean;
17
+ timestamp: string;
18
+ }
19
+ export declare class LightStreamError extends Error {
20
+ readonly code: LightStreamErrorCode;
21
+ readonly details?: unknown;
22
+ readonly retryable: boolean;
23
+ readonly timestamp: string;
24
+ constructor(payload: LightStreamErrorPayload);
25
+ toJSON(): LightStreamErrorPayload;
26
+ }