talksphere-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/MIGRATION_EXAMPLE.md +164 -0
- package/README.md +241 -0
- package/dist/config-fetcher.d.ts +11 -0
- package/dist/config-fetcher.d.ts.map +1 -0
- package/dist/config-fetcher.js +23 -0
- package/dist/config-fetcher.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/room.d.ts +79 -0
- package/dist/room.d.ts.map +1 -0
- package/dist/room.js +227 -0
- package/dist/room.js.map +1 -0
- package/dist/signaling/socket-client.d.ts +88 -0
- package/dist/signaling/socket-client.d.ts.map +1 -0
- package/dist/signaling/socket-client.js +136 -0
- package/dist/signaling/socket-client.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/webrtc/media.d.ts +45 -0
- package/dist/webrtc/media.d.ts.map +1 -0
- package/dist/webrtc/media.js +87 -0
- package/dist/webrtc/media.js.map +1 -0
- package/dist/webrtc/peer.d.ts +65 -0
- package/dist/webrtc/peer.d.ts.map +1 -0
- package/dist/webrtc/peer.js +137 -0
- package/dist/webrtc/peer.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// Migration Example: useWebRTC.ts → @talksphere/sdk-client
|
|
2
|
+
// This shows how to replace the useWebRTC hook with the SDK
|
|
3
|
+
|
|
4
|
+
// ===== BEFORE (useWebRTC hook) =====
|
|
5
|
+
/*
|
|
6
|
+
import { useWebRTC } from '@/hooks/useWebRTC';
|
|
7
|
+
|
|
8
|
+
function RoomPage({ roomId, user }) {
|
|
9
|
+
const {
|
|
10
|
+
localVideoRef,
|
|
11
|
+
remoteVideoRef,
|
|
12
|
+
connectionState,
|
|
13
|
+
messages,
|
|
14
|
+
sendMessage,
|
|
15
|
+
toggleAudio,
|
|
16
|
+
toggleVideo,
|
|
17
|
+
endCall,
|
|
18
|
+
remoteStream
|
|
19
|
+
} = useWebRTC(roomId, user);
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div>
|
|
23
|
+
<video ref={localVideoRef} autoPlay muted />
|
|
24
|
+
<video ref={remoteVideoRef} autoPlay />
|
|
25
|
+
<button onClick={() => toggleAudio(false)}>Mute</button>
|
|
26
|
+
<button onClick={() => toggleVideo(false)}>Camera Off</button>
|
|
27
|
+
<button onClick={endCall}>Leave</button>
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
// ===== AFTER (SDK) =====
|
|
34
|
+
|
|
35
|
+
import { useEffect, useRef, useState } from 'react';
|
|
36
|
+
import { TalksphereSDK, Room } from '@talksphere/sdk-client';
|
|
37
|
+
|
|
38
|
+
function RoomPage({ roomId, user }: { roomId: string; user: { id: number; username: string } }) {
|
|
39
|
+
const [room, setRoom] = useState<Room | null>(null);
|
|
40
|
+
const [messages, setMessages] = useState<any[]>([]);
|
|
41
|
+
const [connectionState, setConnectionState] = useState<string>('new');
|
|
42
|
+
|
|
43
|
+
const localVideoRef = useRef<HTMLVideoElement>(null);
|
|
44
|
+
const remoteVideoRef = useRef<HTMLVideoElement>(null);
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!user || !roomId) return;
|
|
48
|
+
|
|
49
|
+
// Initialize SDK
|
|
50
|
+
const sdk = new TalksphereSDK({
|
|
51
|
+
apiKey: process.env.NEXT_PUBLIC_API_KEY || 'pk_dev_xxx',
|
|
52
|
+
// In development, point to local backend
|
|
53
|
+
backendUrl: process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:4000'
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Join room
|
|
57
|
+
sdk.join(roomId, {
|
|
58
|
+
audio: true,
|
|
59
|
+
video: true,
|
|
60
|
+
displayName: user.username
|
|
61
|
+
}).then(room => {
|
|
62
|
+
setRoom(room);
|
|
63
|
+
|
|
64
|
+
// Attach local video
|
|
65
|
+
const localStream = room.getLocalStream();
|
|
66
|
+
if (localVideoRef.current && localStream) {
|
|
67
|
+
localVideoRef.current.srcObject = localStream;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Listen for remote track
|
|
71
|
+
room.on('track', (track) => {
|
|
72
|
+
if (remoteVideoRef.current) {
|
|
73
|
+
const stream = new MediaStream([track]);
|
|
74
|
+
remoteVideoRef.current.srcObject = stream;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Listen for chat messages
|
|
79
|
+
room.on('message', (message) => {
|
|
80
|
+
setMessages(prev => [...prev, message]);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Listen for connection state changes
|
|
84
|
+
room.on('connection-state', (state) => {
|
|
85
|
+
setConnectionState(state);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Listen for peer events
|
|
89
|
+
room.on('peer-joined', (peer) => {
|
|
90
|
+
console.log('Peer joined:', peer.id);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
room.on('peer-left', (peer) => {
|
|
94
|
+
console.log('Peer left:', peer.id);
|
|
95
|
+
});
|
|
96
|
+
}).catch(error => {
|
|
97
|
+
console.error('Failed to join room:', error);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Cleanup on unmount
|
|
101
|
+
return () => {
|
|
102
|
+
room?.leave();
|
|
103
|
+
};
|
|
104
|
+
}, [roomId, user]);
|
|
105
|
+
|
|
106
|
+
const handleSendMessage = (text: string) => {
|
|
107
|
+
room?.sendMessage(text);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const handleToggleAudio = () => {
|
|
111
|
+
room?.toggleAudio(false);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const handleToggleVideo = () => {
|
|
115
|
+
room?.toggleVideo(false);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const handleLeave = async () => {
|
|
119
|
+
await room?.leave();
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div>
|
|
124
|
+
<video ref={localVideoRef} autoPlay muted />
|
|
125
|
+
<video ref={remoteVideoRef} autoPlay />
|
|
126
|
+
<p>Connection: {connectionState}</p>
|
|
127
|
+
|
|
128
|
+
<button onClick={handleToggleAudio}>Mute</button>
|
|
129
|
+
<button onClick={handleToggleVideo}>Camera Off</button>
|
|
130
|
+
<button onClick={handleLeave}>Leave</button>
|
|
131
|
+
|
|
132
|
+
<div>
|
|
133
|
+
{messages.map((msg, i) => (
|
|
134
|
+
<div key={i}>{msg.userId}: {msg.message}</div>
|
|
135
|
+
))}
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default RoomPage;
|
|
142
|
+
|
|
143
|
+
// ===== KEY DIFFERENCES =====
|
|
144
|
+
/*
|
|
145
|
+
1. SDK is initialized once with API key (no hardcoded TURN credentials)
|
|
146
|
+
2. TURN credentials are fetched dynamically from backend (short-lived, secure)
|
|
147
|
+
3. Room is created via sdk.join() instead of hook initialization
|
|
148
|
+
4. Event listeners use room.on() instead of React state
|
|
149
|
+
5. Cleanup is done via room.leave() instead of hook cleanup
|
|
150
|
+
6. No direct access to RTCPeerConnection, Socket.io, or ICE servers
|
|
151
|
+
7. Framework-agnostic - same SDK works in Vue, vanilla JS, etc.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
// ===== ENVIRONMENT VARIABLES =====
|
|
155
|
+
/*
|
|
156
|
+
Add to .env.local:
|
|
157
|
+
|
|
158
|
+
NEXT_PUBLIC_API_KEY=pk_dev_your_api_key_here
|
|
159
|
+
NEXT_PUBLIC_BACKEND_URL=http://localhost:4000
|
|
160
|
+
|
|
161
|
+
In production:
|
|
162
|
+
NEXT_PUBLIC_API_KEY=pk_live_your_production_key
|
|
163
|
+
NEXT_PUBLIC_BACKEND_URL=https://api.talksphere.in
|
|
164
|
+
*/
|
package/README.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# @talksphere/sdk-client
|
|
2
|
+
|
|
3
|
+
Official browser SDK for Talksphere WebRTC platform.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎥 **WebRTC Video/Audio Calls** - Crystal clear 1-to-1 calls
|
|
8
|
+
- 💬 **Real-time Chat** - Send messages during calls
|
|
9
|
+
- 🔒 **Secure** - Short-lived TURN credentials, no secrets in browser
|
|
10
|
+
- 🎯 **Simple API** - Hide WebRTC complexity
|
|
11
|
+
- 📦 **Framework Agnostic** - Works with React, Vue, vanilla JS, etc.
|
|
12
|
+
- 🚀 **Zero Configuration** - Fetch config dynamically from backend
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @talksphere/sdk-client
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { TalksphereSDK } from '@talksphere/sdk-client';
|
|
24
|
+
|
|
25
|
+
// Initialize SDK with your API key
|
|
26
|
+
const sdk = new TalksphereSDK({
|
|
27
|
+
apiKey: 'pk_live_xxx',
|
|
28
|
+
backendUrl: 'https://api.talksphere.in' // optional
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Join a room
|
|
32
|
+
const room = await sdk.join('room-123', {
|
|
33
|
+
audio: true,
|
|
34
|
+
video: true,
|
|
35
|
+
displayName: 'John Doe'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Listen for events
|
|
39
|
+
room.on('peer-joined', (peer) => {
|
|
40
|
+
console.log('Peer joined:', peer.id);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
room.on('track', (track, peer) => {
|
|
44
|
+
// Attach remote video/audio to DOM
|
|
45
|
+
const videoElement = document.getElementById('remote-video');
|
|
46
|
+
if (videoElement instanceof HTMLVideoElement) {
|
|
47
|
+
videoElement.srcObject = new MediaStream([track]);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
room.on('message', (message) => {
|
|
52
|
+
console.log('Chat:', message.message);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Controls
|
|
56
|
+
room.toggleAudio(false); // Mute
|
|
57
|
+
room.toggleVideo(false); // Camera off
|
|
58
|
+
room.sendMessage('Hello!');
|
|
59
|
+
|
|
60
|
+
// Get streams
|
|
61
|
+
const localStream = room.getLocalStream();
|
|
62
|
+
const remoteStream = room.getRemoteStream();
|
|
63
|
+
|
|
64
|
+
// Leave room
|
|
65
|
+
await room.leave();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## API Reference
|
|
69
|
+
|
|
70
|
+
### TalksphereSDK
|
|
71
|
+
|
|
72
|
+
#### Constructor
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
new TalksphereSDK(options: SDKConfig)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Options:**
|
|
79
|
+
- `apiKey` (required): Your project API key
|
|
80
|
+
- `backendUrl` (optional): Backend URL (defaults to production)
|
|
81
|
+
|
|
82
|
+
#### Methods
|
|
83
|
+
|
|
84
|
+
##### `join(roomId, options)`
|
|
85
|
+
|
|
86
|
+
Join a WebRTC room.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const room = await sdk.join('room-123', {
|
|
90
|
+
audio: true,
|
|
91
|
+
video: true,
|
|
92
|
+
displayName: 'John Doe'
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Parameters:**
|
|
97
|
+
- `roomId`: Room identifier
|
|
98
|
+
- `options.audio`: Enable audio (default: true)
|
|
99
|
+
- `options.video`: Enable video (default: true)
|
|
100
|
+
- `options.displayName`: User display name (required)
|
|
101
|
+
|
|
102
|
+
**Returns:** `Promise<Room>`
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Room
|
|
107
|
+
|
|
108
|
+
#### Events
|
|
109
|
+
|
|
110
|
+
Listen to events using `room.on(event, callback)`:
|
|
111
|
+
|
|
112
|
+
##### `peer-joined`
|
|
113
|
+
Fired when a peer joins the room.
|
|
114
|
+
```typescript
|
|
115
|
+
room.on('peer-joined', (peer: Peer) => {
|
|
116
|
+
console.log('Peer joined:', peer.id);
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
##### `peer-left`
|
|
121
|
+
Fired when a peer leaves the room.
|
|
122
|
+
```typescript
|
|
123
|
+
room.on('peer-left', (peer: Peer) => {
|
|
124
|
+
console.log('Peer left:', peer.id);
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
##### `track`
|
|
129
|
+
Fired when a remote track is received.
|
|
130
|
+
```typescript
|
|
131
|
+
room.on('track', (track: MediaStreamTrack, peer: Peer) => {
|
|
132
|
+
// Attach to video element
|
|
133
|
+
videoElement.srcObject = new MediaStream([track]);
|
|
134
|
+
});
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
##### `message`
|
|
138
|
+
Fired when a chat message is received.
|
|
139
|
+
```typescript
|
|
140
|
+
room.on('message', (message: ChatMessage) => {
|
|
141
|
+
console.log(message.userId, ':', message.message);
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
##### `connection-state`
|
|
146
|
+
Fired when WebRTC connection state changes.
|
|
147
|
+
```typescript
|
|
148
|
+
room.on('connection-state', (state: RTCPeerConnectionState) => {
|
|
149
|
+
console.log('Connection state:', state);
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
##### `error`
|
|
154
|
+
Fired when an error occurs.
|
|
155
|
+
```typescript
|
|
156
|
+
room.on('error', (error: Error) => {
|
|
157
|
+
console.error('Room error:', error);
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### Methods
|
|
162
|
+
|
|
163
|
+
##### `toggleAudio(enabled: boolean)`
|
|
164
|
+
Enable/disable microphone.
|
|
165
|
+
|
|
166
|
+
##### `toggleVideo(enabled: boolean)`
|
|
167
|
+
Enable/disable camera.
|
|
168
|
+
|
|
169
|
+
##### `sendMessage(text: string)`
|
|
170
|
+
Send a chat message.
|
|
171
|
+
|
|
172
|
+
##### `getLocalStream(): MediaStream | null`
|
|
173
|
+
Get local media stream.
|
|
174
|
+
|
|
175
|
+
##### `getRemoteStream(): MediaStream | null`
|
|
176
|
+
Get remote media stream.
|
|
177
|
+
|
|
178
|
+
##### `getConnectionState(): RTCPeerConnectionState | null`
|
|
179
|
+
Get WebRTC connection state.
|
|
180
|
+
|
|
181
|
+
##### `leave(): Promise<void>`
|
|
182
|
+
Leave room and cleanup resources.
|
|
183
|
+
|
|
184
|
+
## React Example
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import { useEffect, useRef, useState } from 'react';
|
|
188
|
+
import { TalksphereSDK, Room } from '@talksphere/sdk-client';
|
|
189
|
+
|
|
190
|
+
function VideoCall({ roomId, apiKey }) {
|
|
191
|
+
const [room, setRoom] = useState<Room | null>(null);
|
|
192
|
+
const localVideoRef = useRef<HTMLVideoElement>(null);
|
|
193
|
+
const remoteVideoRef = useRef<HTMLVideoElement>(null);
|
|
194
|
+
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
const sdk = new TalksphereSDK({ apiKey });
|
|
197
|
+
|
|
198
|
+
sdk.join(roomId, {
|
|
199
|
+
audio: true,
|
|
200
|
+
video: true,
|
|
201
|
+
displayName: 'User'
|
|
202
|
+
}).then(room => {
|
|
203
|
+
setRoom(room);
|
|
204
|
+
|
|
205
|
+
// Attach local video
|
|
206
|
+
const localStream = room.getLocalStream();
|
|
207
|
+
if (localVideoRef.current && localStream) {
|
|
208
|
+
localVideoRef.current.srcObject = localStream;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Listen for remote track
|
|
212
|
+
room.on('track', (track) => {
|
|
213
|
+
if (remoteVideoRef.current) {
|
|
214
|
+
remoteVideoRef.current.srcObject = new MediaStream([track]);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return () => {
|
|
220
|
+
room?.leave();
|
|
221
|
+
};
|
|
222
|
+
}, [roomId, apiKey]);
|
|
223
|
+
|
|
224
|
+
return (
|
|
225
|
+
<div>
|
|
226
|
+
<video ref={localVideoRef} autoPlay muted />
|
|
227
|
+
<video ref={remoteVideoRef} autoPlay />
|
|
228
|
+
<button onClick={() => room?.toggleAudio(false)}>Mute</button>
|
|
229
|
+
<button onClick={() => room?.leave()}>Leave</button>
|
|
230
|
+
</div>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## TypeScript Support
|
|
236
|
+
|
|
237
|
+
The SDK is written in TypeScript and includes full type definitions.
|
|
238
|
+
|
|
239
|
+
## License
|
|
240
|
+
|
|
241
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BackendConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fetch SDK configuration from backend
|
|
4
|
+
* This retrieves short-lived TURN credentials and signaling URL
|
|
5
|
+
*
|
|
6
|
+
* @param apiKey - Project API key
|
|
7
|
+
* @param backendUrl - Backend URL (defaults to production)
|
|
8
|
+
* @returns Backend configuration with ICE servers
|
|
9
|
+
*/
|
|
10
|
+
export declare function fetchConfig(apiKey: string, backendUrl?: string): Promise<BackendConfig>;
|
|
11
|
+
//# sourceMappingURL=config-fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-fetcher.d.ts","sourceRoot":"","sources":["../src/config-fetcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC7B,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAAoC,GACjD,OAAO,CAAC,aAAa,CAAC,CAkBxB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch SDK configuration from backend
|
|
3
|
+
* This retrieves short-lived TURN credentials and signaling URL
|
|
4
|
+
*
|
|
5
|
+
* @param apiKey - Project API key
|
|
6
|
+
* @param backendUrl - Backend URL (defaults to production)
|
|
7
|
+
* @returns Backend configuration with ICE servers
|
|
8
|
+
*/
|
|
9
|
+
export async function fetchConfig(apiKey, backendUrl = 'https://api.talksphere.in') {
|
|
10
|
+
const url = `${backendUrl}/v1/sdk/config?apiKey=${encodeURIComponent(apiKey)}`;
|
|
11
|
+
const response = await fetch(url);
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
14
|
+
throw new Error(`Failed to fetch SDK config: ${error.error || response.statusText}`);
|
|
15
|
+
}
|
|
16
|
+
const config = await response.json();
|
|
17
|
+
// Validate config
|
|
18
|
+
if (!config.signalingUrl || !config.iceServers) {
|
|
19
|
+
throw new Error('Invalid SDK configuration received from backend');
|
|
20
|
+
}
|
|
21
|
+
return config;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=config-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-fetcher.js","sourceRoot":"","sources":["../src/config-fetcher.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,MAAc,EACd,aAAqB,2BAA2B;IAEhD,MAAM,GAAG,GAAG,GAAG,UAAU,yBAAyB,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAE/E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,MAAM,MAAM,GAAkB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEpD,kBAAkB;IAClB,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Room } from './room.js';
|
|
2
|
+
import type { SDKConfig, JoinOptions, BackendConfig } from './types.js';
|
|
3
|
+
export { Room };
|
|
4
|
+
export type { SDKConfig, JoinOptions, BackendConfig, Peer, ChatMessage } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* TalksphereSDK
|
|
7
|
+
* Main SDK class for Talksphere WebRTC platform
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const sdk = new TalksphereSDK({
|
|
12
|
+
* apiKey: 'pk_live_xxx',
|
|
13
|
+
* backendUrl: 'https://api.talksphere.in'
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* const room = await sdk.join('room-123', {
|
|
17
|
+
* audio: true,
|
|
18
|
+
* video: true,
|
|
19
|
+
* displayName: 'John Doe'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* room.on('track', (track, peer) => {
|
|
23
|
+
* // Attach remote video/audio
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class TalksphereSDK {
|
|
28
|
+
private apiKey;
|
|
29
|
+
private backendUrl;
|
|
30
|
+
private config;
|
|
31
|
+
constructor(options: SDKConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Join a room
|
|
34
|
+
* Fetches config from backend and initializes WebRTC connection
|
|
35
|
+
*
|
|
36
|
+
* @param roomId - Room identifier
|
|
37
|
+
* @param options - Join options (audio, video, displayName)
|
|
38
|
+
* @returns Room instance
|
|
39
|
+
*/
|
|
40
|
+
join(roomId: string, options: JoinOptions): Promise<Room>;
|
|
41
|
+
/**
|
|
42
|
+
* Refresh config (e.g., when TURN credentials expire)
|
|
43
|
+
* TURN credentials are valid for 24 hours
|
|
44
|
+
*/
|
|
45
|
+
refreshConfig(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Get current config (for debugging)
|
|
48
|
+
*/
|
|
49
|
+
getConfig(): BackendConfig | null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGxE,OAAO,EAAE,IAAI,EAAE,CAAC;AAChB,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3F;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAA8B;gBAEhC,OAAO,EAAE,SAAS;IAS9B;;;;;;;OAOG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B/D;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;OAEG;IACH,SAAS,IAAI,aAAa,GAAG,IAAI;CAGpC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Talksphere SDK
|
|
2
|
+
// Main entry point for the SDK
|
|
3
|
+
// Framework-agnostic WebRTC client library
|
|
4
|
+
import { fetchConfig } from './config-fetcher.js';
|
|
5
|
+
import { Room } from './room.js';
|
|
6
|
+
// Re-export Room for consumers
|
|
7
|
+
export { Room };
|
|
8
|
+
/**
|
|
9
|
+
* TalksphereSDK
|
|
10
|
+
* Main SDK class for Talksphere WebRTC platform
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const sdk = new TalksphereSDK({
|
|
15
|
+
* apiKey: 'pk_live_xxx',
|
|
16
|
+
* backendUrl: 'https://api.talksphere.in'
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const room = await sdk.join('room-123', {
|
|
20
|
+
* audio: true,
|
|
21
|
+
* video: true,
|
|
22
|
+
* displayName: 'John Doe'
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* room.on('track', (track, peer) => {
|
|
26
|
+
* // Attach remote video/audio
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class TalksphereSDK {
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.config = null;
|
|
33
|
+
if (!options.apiKey) {
|
|
34
|
+
throw new Error('API key is required');
|
|
35
|
+
}
|
|
36
|
+
this.apiKey = options.apiKey;
|
|
37
|
+
this.backendUrl = options.backendUrl || 'https://api.talksphere.in';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Join a room
|
|
41
|
+
* Fetches config from backend and initializes WebRTC connection
|
|
42
|
+
*
|
|
43
|
+
* @param roomId - Room identifier
|
|
44
|
+
* @param options - Join options (audio, video, displayName)
|
|
45
|
+
* @returns Room instance
|
|
46
|
+
*/
|
|
47
|
+
async join(roomId, options) {
|
|
48
|
+
if (!roomId) {
|
|
49
|
+
throw new Error('Room ID is required');
|
|
50
|
+
}
|
|
51
|
+
if (!options.displayName) {
|
|
52
|
+
throw new Error('Display name is required');
|
|
53
|
+
}
|
|
54
|
+
// Fetch config from backend (includes short-lived TURN credentials)
|
|
55
|
+
if (!this.config) {
|
|
56
|
+
this.config = await fetchConfig(this.apiKey, this.backendUrl);
|
|
57
|
+
}
|
|
58
|
+
// Create room instance
|
|
59
|
+
const room = new Room(roomId, options.displayName, this.config);
|
|
60
|
+
// Initialize room (get media + connect signaling)
|
|
61
|
+
await room.initialize(options.audio ?? true, options.video ?? true);
|
|
62
|
+
return room;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Refresh config (e.g., when TURN credentials expire)
|
|
66
|
+
* TURN credentials are valid for 24 hours
|
|
67
|
+
*/
|
|
68
|
+
async refreshConfig() {
|
|
69
|
+
this.config = await fetchConfig(this.apiKey, this.backendUrl);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get current config (for debugging)
|
|
73
|
+
*/
|
|
74
|
+
getConfig() {
|
|
75
|
+
return this.config;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,+BAA+B;AAC/B,2CAA2C;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,+BAA+B;AAC/B,OAAO,EAAE,IAAI,EAAE,CAAC;AAGhB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,OAAO,aAAa;IAKtB,YAAY,OAAkB;QAFtB,WAAM,GAAyB,IAAI,CAAC;QAGxC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,2BAA2B,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,MAAc,EAAE,OAAoB;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAChD,CAAC;QAED,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAClE,CAAC;QAED,uBAAuB;QACvB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhE,kDAAkD;QAClD,MAAM,IAAI,CAAC,UAAU,CACjB,OAAO,CAAC,KAAK,IAAI,IAAI,EACrB,OAAO,CAAC,KAAK,IAAI,IAAI,CACxB,CAAC;QAEF,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa;QACf,IAAI,CAAC,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;CACJ"}
|
package/dist/room.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { RoomEventMap, BackendConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Room
|
|
4
|
+
* Public API for WebRTC room interactions
|
|
5
|
+
* Hides all WebRTC complexity from consumers
|
|
6
|
+
*/
|
|
7
|
+
export declare class Room {
|
|
8
|
+
private roomId;
|
|
9
|
+
private userId;
|
|
10
|
+
private config;
|
|
11
|
+
private mediaManager;
|
|
12
|
+
private peerManager;
|
|
13
|
+
private signalingClient;
|
|
14
|
+
private eventListeners;
|
|
15
|
+
private remotePeer;
|
|
16
|
+
private remoteStream;
|
|
17
|
+
constructor(roomId: string, userId: string, config: BackendConfig);
|
|
18
|
+
/**
|
|
19
|
+
* Initialize room connection
|
|
20
|
+
* @param audio - Enable audio
|
|
21
|
+
* @param video - Enable video
|
|
22
|
+
*/
|
|
23
|
+
initialize(audio: boolean, video: boolean): Promise<MediaStream>;
|
|
24
|
+
/**
|
|
25
|
+
* Event listener registration
|
|
26
|
+
* MIGRATED pattern from useWebRTC.ts event handling
|
|
27
|
+
*/
|
|
28
|
+
on<K extends keyof RoomEventMap>(event: K, callback: RoomEventMap[K]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Remove event listener
|
|
31
|
+
*/
|
|
32
|
+
off<K extends keyof RoomEventMap>(event: K, callback: RoomEventMap[K]): void;
|
|
33
|
+
/**
|
|
34
|
+
* Emit event to listeners
|
|
35
|
+
*/
|
|
36
|
+
private emit;
|
|
37
|
+
private handleJoinedRoom;
|
|
38
|
+
private handleUserConnected;
|
|
39
|
+
private handleOffer;
|
|
40
|
+
private handleAnswer;
|
|
41
|
+
private handleIceCandidate;
|
|
42
|
+
private handleChatMessage;
|
|
43
|
+
private handleUserDisconnected;
|
|
44
|
+
private handleError;
|
|
45
|
+
private createPeerConnection;
|
|
46
|
+
/**
|
|
47
|
+
* Toggle audio on/off
|
|
48
|
+
* MIGRATED from useWebRTC.ts lines 166-168
|
|
49
|
+
*/
|
|
50
|
+
toggleAudio(enabled: boolean): void;
|
|
51
|
+
/**
|
|
52
|
+
* Toggle video on/off
|
|
53
|
+
* MIGRATED from useWebRTC.ts lines 170-172
|
|
54
|
+
*/
|
|
55
|
+
toggleVideo(enabled: boolean): void;
|
|
56
|
+
/**
|
|
57
|
+
* Send chat message
|
|
58
|
+
* MIGRATED from useWebRTC.ts lines 160-164
|
|
59
|
+
*/
|
|
60
|
+
sendMessage(text: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get local media stream
|
|
63
|
+
*/
|
|
64
|
+
getLocalStream(): MediaStream | null;
|
|
65
|
+
/**
|
|
66
|
+
* Get remote media stream
|
|
67
|
+
*/
|
|
68
|
+
getRemoteStream(): MediaStream | null;
|
|
69
|
+
/**
|
|
70
|
+
* Get connection state
|
|
71
|
+
*/
|
|
72
|
+
getConnectionState(): RTCPeerConnectionState | null;
|
|
73
|
+
/**
|
|
74
|
+
* Leave room and cleanup
|
|
75
|
+
* MIGRATED from useWebRTC.ts lines 174-178
|
|
76
|
+
*/
|
|
77
|
+
leave(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=room.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAqB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjF;;;;GAIG;AACH,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAgB;IAE9B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,cAAc,CAAqD;IAC3E,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,YAAY,CAA4B;gBAEpC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAkBjE;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAatE;;;OAGG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAO3E;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI;IAO5E;;OAEG;IACH,OAAO,CAAC,IAAI;IAmBZ,OAAO,CAAC,gBAAgB;YAIV,mBAAmB;YAmBnB,WAAW;YAiBX,YAAY;YAOZ,kBAAkB;IAOhC,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,oBAAoB;IA0B5B;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAInC;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAInC;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC;;OAEG;IACH,eAAe,IAAI,WAAW,GAAG,IAAI;IAIrC;;OAEG;IACH,kBAAkB,IAAI,sBAAsB,GAAG,IAAI;IAInD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB/B"}
|