@sayna-ai/node-sdk 0.0.2

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.
@@ -0,0 +1,303 @@
1
+ import type { STTConfig, TTSConfig, LiveKitConfig, STTResultMessage, ErrorMessage, SaynaMessage, Participant, VoicesResponse, HealthResponse, LiveKitTokenResponse } from "./types";
2
+ /**
3
+ * Event handler for speech-to-text results.
4
+ */
5
+ export type STTResultHandler = (result: STTResultMessage) => void | Promise<void>;
6
+ /**
7
+ * Event handler for text-to-speech audio data.
8
+ */
9
+ export type TTSAudioHandler = (audio: ArrayBuffer) => void | Promise<void>;
10
+ /**
11
+ * Event handler for error messages.
12
+ */
13
+ export type ErrorHandler = (error: ErrorMessage) => void | Promise<void>;
14
+ /**
15
+ * Event handler for participant messages.
16
+ */
17
+ export type MessageHandler = (message: SaynaMessage) => void | Promise<void>;
18
+ /**
19
+ * Event handler for participant disconnections.
20
+ */
21
+ export type ParticipantDisconnectedHandler = (participant: Participant) => void | Promise<void>;
22
+ /**
23
+ * Event handler for TTS playback completion.
24
+ */
25
+ export type TTSPlaybackCompleteHandler = (timestamp: number) => void | Promise<void>;
26
+ /**
27
+ * Client for connecting to Sayna WebSocket server for real-time voice interactions.
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const client = await saynaConnect(
32
+ * "https://api.sayna.ai",
33
+ * sttConfig,
34
+ * ttsConfig
35
+ * );
36
+ *
37
+ * client.registerOnSttResult((result) => {
38
+ * console.log("Transcription:", result.transcript);
39
+ * });
40
+ *
41
+ * await client.speak("Hello, world!");
42
+ * ```
43
+ */
44
+ export declare class SaynaClient {
45
+ private url;
46
+ private sttConfig;
47
+ private ttsConfig;
48
+ private livekitConfig?;
49
+ private withoutAudio;
50
+ private websocket?;
51
+ private isConnected;
52
+ private isReady;
53
+ private _livekitRoomName?;
54
+ private _livekitUrl?;
55
+ private _saynaParticipantIdentity?;
56
+ private _saynaParticipantName?;
57
+ private sttCallback?;
58
+ private ttsCallback?;
59
+ private errorCallback?;
60
+ private messageCallback?;
61
+ private participantDisconnectedCallback?;
62
+ private ttsPlaybackCompleteCallback?;
63
+ private readyPromiseResolve?;
64
+ private readyPromiseReject?;
65
+ /**
66
+ * Creates a new SaynaClient instance.
67
+ *
68
+ * @param url - The Sayna server URL (e.g., "https://api.sayna.ai")
69
+ * @param sttConfig - Speech-to-text configuration
70
+ * @param ttsConfig - Text-to-speech configuration
71
+ * @param livekitConfig - Optional LiveKit room configuration
72
+ * @param withoutAudio - If true, disables audio streaming (default: false)
73
+ *
74
+ * @throws {SaynaValidationError} If URL or configurations are invalid
75
+ */
76
+ constructor(url: string, sttConfig: STTConfig, ttsConfig: TTSConfig, livekitConfig?: LiveKitConfig, withoutAudio?: boolean);
77
+ /**
78
+ * Establishes connection to the Sayna WebSocket server.
79
+ *
80
+ * @throws {SaynaConnectionError} If connection fails
81
+ * @returns Promise that resolves when the connection is ready
82
+ */
83
+ connect(): Promise<void>;
84
+ /**
85
+ * Handles incoming JSON messages from the WebSocket.
86
+ * @internal
87
+ */
88
+ private handleJsonMessage;
89
+ /**
90
+ * Cleans up internal state.
91
+ * @internal
92
+ */
93
+ private cleanup;
94
+ /**
95
+ * Converts WebSocket URL to HTTP URL for REST API calls.
96
+ * @internal
97
+ */
98
+ private getHttpUrl;
99
+ /**
100
+ * Generic fetch helper for making REST API calls to Sayna server.
101
+ * Handles URL construction, headers, error responses, and type conversion.
102
+ * @internal
103
+ *
104
+ * @param endpoint - API endpoint path (e.g., "/voices", "/speak")
105
+ * @param options - Fetch options including method, body, headers, etc.
106
+ * @param responseType - Expected response type: "json" or "arrayBuffer"
107
+ * @returns Promise resolving to the parsed response
108
+ * @throws {SaynaConnectionError} If the network request fails
109
+ * @throws {SaynaServerError} If the server returns an error response
110
+ */
111
+ private fetchFromSayna;
112
+ /**
113
+ * Disconnects from the Sayna WebSocket server and cleans up resources.
114
+ */
115
+ disconnect(): Promise<void>;
116
+ /**
117
+ * Sends audio data to the server for speech recognition.
118
+ *
119
+ * @param audioData - Raw audio data as ArrayBuffer
120
+ * @throws {SaynaNotConnectedError} If not connected
121
+ * @throws {SaynaNotReadyError} If connection is not ready
122
+ */
123
+ onAudioInput(audioData: ArrayBuffer): Promise<void>;
124
+ /**
125
+ * Registers a callback for speech-to-text results.
126
+ *
127
+ * @param callback - Function to call when STT results are received
128
+ */
129
+ registerOnSttResult(callback: STTResultHandler): void;
130
+ /**
131
+ * Registers a callback for text-to-speech audio data.
132
+ *
133
+ * @param callback - Function to call when TTS audio is received
134
+ */
135
+ registerOnTtsAudio(callback: TTSAudioHandler): void;
136
+ /**
137
+ * Registers a callback for error messages.
138
+ *
139
+ * @param callback - Function to call when errors occur
140
+ */
141
+ registerOnError(callback: ErrorHandler): void;
142
+ /**
143
+ * Registers a callback for participant messages.
144
+ *
145
+ * @param callback - Function to call when messages are received
146
+ */
147
+ registerOnMessage(callback: MessageHandler): void;
148
+ /**
149
+ * Registers a callback for participant disconnection events.
150
+ *
151
+ * @param callback - Function to call when a participant disconnects
152
+ */
153
+ registerOnParticipantDisconnected(callback: ParticipantDisconnectedHandler): void;
154
+ /**
155
+ * Registers a callback for TTS playback completion.
156
+ *
157
+ * @param callback - Function to call when TTS playback is complete
158
+ */
159
+ registerOnTtsPlaybackComplete(callback: TTSPlaybackCompleteHandler): void;
160
+ /**
161
+ * Sends text to be synthesized as speech.
162
+ *
163
+ * @param text - Text to synthesize
164
+ * @param flush - Whether to flush the TTS queue before speaking (default: true)
165
+ * @param allowInterruption - Whether this speech can be interrupted (default: true)
166
+ * @throws {SaynaNotConnectedError} If not connected
167
+ * @throws {SaynaNotReadyError} If connection is not ready
168
+ * @throws {SaynaValidationError} If text is not a string
169
+ */
170
+ speak(text: string, flush?: boolean, allowInterruption?: boolean): Promise<void>;
171
+ /**
172
+ * Clears the text-to-speech queue.
173
+ *
174
+ * @throws {SaynaNotConnectedError} If not connected
175
+ * @throws {SaynaNotReadyError} If connection is not ready
176
+ */
177
+ clear(): Promise<void>;
178
+ /**
179
+ * Flushes the TTS queue by sending an empty speak command.
180
+ *
181
+ * @param allowInterruption - Whether the flush can be interrupted (default: true)
182
+ * @throws {SaynaNotConnectedError} If not connected
183
+ * @throws {SaynaNotReadyError} If connection is not ready
184
+ */
185
+ ttsFlush(allowInterruption?: boolean): Promise<void>;
186
+ /**
187
+ * Sends a message to the Sayna session.
188
+ *
189
+ * @param message - Message content
190
+ * @param role - Message role (e.g., "user", "assistant")
191
+ * @param topic - Optional topic identifier
192
+ * @param debug - Optional debug metadata
193
+ * @throws {SaynaNotConnectedError} If not connected
194
+ * @throws {SaynaNotReadyError} If connection is not ready
195
+ * @throws {SaynaValidationError} If parameters are invalid
196
+ */
197
+ sendMessage(message: string, role: string, topic?: string, debug?: Record<string, unknown>): Promise<void>;
198
+ /**
199
+ * Performs a health check on the Sayna server.
200
+ *
201
+ * @returns Promise that resolves with the health status
202
+ * @throws {SaynaConnectionError} If the request fails
203
+ * @throws {SaynaServerError} If server returns an error
204
+ *
205
+ * @example
206
+ * ```typescript
207
+ * const health = await client.health();
208
+ * console.log(health.status); // "OK"
209
+ * ```
210
+ */
211
+ health(): Promise<HealthResponse>;
212
+ /**
213
+ * Retrieves the catalogue of text-to-speech voices grouped by provider.
214
+ *
215
+ * @returns Promise that resolves with voices organized by provider
216
+ * @throws {SaynaConnectionError} If the request fails
217
+ * @throws {SaynaServerError} If server returns an error
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const voices = await client.getVoices();
222
+ * for (const [provider, voiceList] of Object.entries(voices)) {
223
+ * console.log(`${provider}:`, voiceList.map(v => v.name));
224
+ * }
225
+ * ```
226
+ */
227
+ getVoices(): Promise<VoicesResponse>;
228
+ /**
229
+ * Synthesizes text into audio using the REST API endpoint.
230
+ * This is a standalone synthesis method that doesn't require an active WebSocket connection.
231
+ *
232
+ * @param text - Text to synthesize
233
+ * @param ttsConfig - Text-to-speech configuration
234
+ * @returns Promise that resolves with the audio data as ArrayBuffer
235
+ * @throws {SaynaValidationError} If text is empty
236
+ * @throws {SaynaConnectionError} If the request fails
237
+ * @throws {SaynaServerError} If server returns an error
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * const audioBuffer = await client.speakRest("Hello, world!", {
242
+ * provider: "elevenlabs",
243
+ * voice_id: "21m00Tcm4TlvDq8ikWAM",
244
+ * model: "eleven_turbo_v2",
245
+ * speaking_rate: 1.0,
246
+ * audio_format: "mp3",
247
+ * sample_rate: 24000,
248
+ * connection_timeout: 30,
249
+ * request_timeout: 60,
250
+ * pronunciations: []
251
+ * });
252
+ * ```
253
+ */
254
+ speakRest(text: string, ttsConfig: TTSConfig): Promise<ArrayBuffer>;
255
+ /**
256
+ * Issues a LiveKit access token for a participant.
257
+ *
258
+ * @param roomName - LiveKit room to join or create
259
+ * @param participantName - Display name assigned to the participant
260
+ * @param participantIdentity - Unique identifier for the participant
261
+ * @returns Promise that resolves with the LiveKit token and connection details
262
+ * @throws {SaynaValidationError} If any parameter is empty
263
+ * @throws {SaynaConnectionError} If the request fails
264
+ * @throws {SaynaServerError} If server returns an error
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * const tokenInfo = await client.getLiveKitToken(
269
+ * "my-room",
270
+ * "John Doe",
271
+ * "user-123"
272
+ * );
273
+ * console.log("Token:", tokenInfo.token);
274
+ * console.log("LiveKit URL:", tokenInfo.livekit_url);
275
+ * ```
276
+ */
277
+ getLiveKitToken(roomName: string, participantName: string, participantIdentity: string): Promise<LiveKitTokenResponse>;
278
+ /**
279
+ * Whether the client is ready to send/receive data.
280
+ */
281
+ get ready(): boolean;
282
+ /**
283
+ * Whether the client is connected to the WebSocket.
284
+ */
285
+ get connected(): boolean;
286
+ /**
287
+ * LiveKit room name acknowledged by the server, if available.
288
+ */
289
+ get livekitRoomName(): string | undefined;
290
+ /**
291
+ * LiveKit WebSocket URL configured on the server, if available.
292
+ */
293
+ get livekitUrl(): string | undefined;
294
+ /**
295
+ * Identity assigned to the agent participant when LiveKit is enabled, if available.
296
+ */
297
+ get saynaParticipantIdentity(): string | undefined;
298
+ /**
299
+ * Display name assigned to the agent participant when LiveKit is enabled, if available.
300
+ */
301
+ get saynaParticipantName(): string | undefined;
302
+ }
303
+ //# sourceMappingURL=sayna-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sayna-client.d.ts","sourceRoot":"","sources":["../src/sayna-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Speech-to-Text (STT) configuration options.
3
+ */
4
+ export interface STTConfig {
5
+ /** The STT provider to use (e.g., "deepgram", "google") */
6
+ provider: string;
7
+ /** Language code for speech recognition (e.g., "en-US", "es-ES") */
8
+ language: string;
9
+ /** Audio sample rate in Hz (e.g., 16000, 44100) */
10
+ sample_rate: number;
11
+ /** Number of audio channels (1 for mono, 2 for stereo) */
12
+ channels: number;
13
+ /** Whether to include punctuation in transcriptions */
14
+ punctuation: boolean;
15
+ /** Audio encoding format (e.g., "linear16", "opus") */
16
+ encoding: string;
17
+ /** STT model identifier to use */
18
+ model: string;
19
+ }
20
+ /**
21
+ * Word pronunciation override for text-to-speech.
22
+ */
23
+ export interface Pronunciation {
24
+ /** The word to be pronounced differently */
25
+ word: string;
26
+ /** Phonetic pronunciation or alternative spelling */
27
+ pronunciation: string;
28
+ }
29
+ /**
30
+ * Text-to-Speech (TTS) configuration options.
31
+ */
32
+ export interface TTSConfig {
33
+ /** The TTS provider to use (e.g., "elevenlabs", "google") */
34
+ provider: string;
35
+ /** Voice identifier for the selected provider */
36
+ voice_id: string;
37
+ /** Speech rate multiplier (e.g., 1.0 for normal, 1.5 for faster) */
38
+ speaking_rate: number;
39
+ /** Audio format for TTS output (e.g., "mp3", "pcm") */
40
+ audio_format: string;
41
+ /** Audio sample rate in Hz (e.g., 16000, 44100) */
42
+ sample_rate: number;
43
+ /** Connection timeout in milliseconds */
44
+ connection_timeout: number;
45
+ /** Request timeout in milliseconds */
46
+ request_timeout: number;
47
+ /** TTS model identifier to use */
48
+ model: string;
49
+ /** Custom pronunciation overrides */
50
+ pronunciations: Pronunciation[];
51
+ }
52
+ /**
53
+ * LiveKit room configuration for real-time communication.
54
+ */
55
+ export interface LiveKitConfig {
56
+ /** LiveKit room name to join */
57
+ room_name: string;
58
+ /** Whether to enable session recording */
59
+ enable_recording?: boolean;
60
+ /** Storage key for the recording file (required when enable_recording is true) */
61
+ recording_file_key?: string;
62
+ /** Identity assigned to the agent participant (defaults to "sayna-ai") */
63
+ sayna_participant_identity?: string;
64
+ /** Display name for the agent participant (defaults to "Sayna AI") */
65
+ sayna_participant_name?: string;
66
+ /** Optional list of participant identities to monitor; empty list means "all participants" */
67
+ listen_participants?: string[];
68
+ }
69
+ /**
70
+ * Configuration message sent to initialize the Sayna WebSocket connection.
71
+ * @internal
72
+ */
73
+ export interface ConfigMessage {
74
+ type: "config";
75
+ /** Whether audio streaming is enabled */
76
+ audio?: boolean;
77
+ /** Speech-to-text configuration */
78
+ stt_config: STTConfig;
79
+ /** Text-to-speech configuration */
80
+ tts_config: TTSConfig;
81
+ /** Optional LiveKit room configuration */
82
+ livekit?: LiveKitConfig;
83
+ }
84
+ /**
85
+ * Message to request text-to-speech synthesis.
86
+ * @internal
87
+ */
88
+ export interface SpeakMessage {
89
+ type: "speak";
90
+ /** Text to synthesize */
91
+ text: string;
92
+ /** Whether to flush the TTS queue before speaking */
93
+ flush?: boolean;
94
+ /** Whether this speech can be interrupted */
95
+ allow_interruption?: boolean;
96
+ }
97
+ /**
98
+ * Message to clear the TTS queue.
99
+ * @internal
100
+ */
101
+ export interface ClearMessage {
102
+ type: "clear";
103
+ }
104
+ /**
105
+ * Message to send data to the Sayna session.
106
+ * @internal
107
+ */
108
+ export interface SendMessageMessage {
109
+ type: "send_message";
110
+ /** Message content */
111
+ message: string;
112
+ /** Message role (e.g., "user", "assistant") */
113
+ role: string;
114
+ /** Optional topic identifier */
115
+ topic?: string;
116
+ /** Optional debug metadata */
117
+ debug?: Record<string, unknown>;
118
+ }
119
+ /**
120
+ * Message received when the Sayna connection is ready.
121
+ */
122
+ export interface ReadyMessage {
123
+ type: "ready";
124
+ /** LiveKit room name acknowledged by the server (present only when LiveKit is enabled) */
125
+ livekit_room_name?: string;
126
+ /** LiveKit WebSocket URL configured on the server */
127
+ livekit_url: string;
128
+ /** Identity assigned to the agent participant when LiveKit is enabled */
129
+ sayna_participant_identity?: string;
130
+ /** Display name assigned to the agent participant when LiveKit is enabled */
131
+ sayna_participant_name?: string;
132
+ }
133
+ /**
134
+ * Speech-to-text transcription result.
135
+ */
136
+ export interface STTResultMessage {
137
+ type: "stt_result";
138
+ /** Transcribed text */
139
+ transcript: string;
140
+ /** Whether this is a final transcription */
141
+ is_final: boolean;
142
+ /** Whether speech has concluded */
143
+ is_speech_final: boolean;
144
+ /** Transcription confidence score (0-1) */
145
+ confidence: number;
146
+ }
147
+ /**
148
+ * Error message from the Sayna server.
149
+ */
150
+ export interface ErrorMessage {
151
+ type: "error";
152
+ /** Error description */
153
+ message: string;
154
+ }
155
+ /**
156
+ * Message data from a Sayna session participant.
157
+ */
158
+ export interface SaynaMessage {
159
+ /** Message content */
160
+ message?: string;
161
+ /** Additional data payload */
162
+ data?: string;
163
+ /** Participant identity */
164
+ identity: string;
165
+ /** Message topic */
166
+ topic: string;
167
+ /** Room identifier */
168
+ room: string;
169
+ /** Unix timestamp in milliseconds */
170
+ timestamp: number;
171
+ }
172
+ /**
173
+ * Wrapper for participant messages.
174
+ */
175
+ export interface MessageMessage {
176
+ type: "message";
177
+ /** The message data */
178
+ message: SaynaMessage;
179
+ }
180
+ /**
181
+ * Information about a session participant.
182
+ */
183
+ export interface Participant {
184
+ /** Unique participant identity */
185
+ identity: string;
186
+ /** Optional display name */
187
+ name?: string;
188
+ /** Room identifier */
189
+ room: string;
190
+ /** Unix timestamp in milliseconds */
191
+ timestamp: number;
192
+ }
193
+ /**
194
+ * Message received when a participant disconnects.
195
+ */
196
+ export interface ParticipantDisconnectedMessage {
197
+ type: "participant_disconnected";
198
+ /** The disconnected participant */
199
+ participant: Participant;
200
+ }
201
+ /**
202
+ * Message received when the TTS playback is complete.
203
+ */
204
+ export interface TTSPlaybackCompleteMessage {
205
+ type: "tts_playback_complete";
206
+ /** Unix timestamp in milliseconds */
207
+ timestamp: number;
208
+ }
209
+ /**
210
+ * Union type of all possible messages received from the Sayna server.
211
+ */
212
+ export type OutgoingMessage = ReadyMessage | STTResultMessage | ErrorMessage | MessageMessage | ParticipantDisconnectedMessage | TTSPlaybackCompleteMessage;
213
+ /**
214
+ * Voice descriptor returned by the GET /voices endpoint.
215
+ */
216
+ export interface Voice {
217
+ /** Provider-specific identifier for the voice profile */
218
+ id: string;
219
+ /** URL to a preview audio sample (may be empty) */
220
+ sample: string;
221
+ /** Human-readable name supplied by the provider */
222
+ name: string;
223
+ /** Detected accent associated with the voice */
224
+ accent: string;
225
+ /** Inferred gender label from provider metadata */
226
+ gender: string;
227
+ /** Primary language for synthesis */
228
+ language: string;
229
+ }
230
+ /**
231
+ * Response from the GET /voices endpoint.
232
+ * Keys are provider identifiers, values are arrays of voice descriptors.
233
+ */
234
+ export type VoicesResponse = Record<string, Voice[]>;
235
+ /**
236
+ * Response from the GET / health check endpoint.
237
+ */
238
+ export interface HealthResponse {
239
+ /** Status indicator, always "OK" when successful */
240
+ status: string;
241
+ }
242
+ /**
243
+ * Response from the POST /livekit/token endpoint.
244
+ */
245
+ export interface LiveKitTokenResponse {
246
+ /** JWT granting LiveKit permissions for the specified participant */
247
+ token: string;
248
+ /** Echo of the requested room */
249
+ room_name: string;
250
+ /** Echo of the requested identity */
251
+ participant_identity: string;
252
+ /** WebSocket endpoint for the LiveKit server */
253
+ livekit_url: string;
254
+ }
255
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,WAAW,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,kFAAkF;IAClF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0EAA0E;IAC1E,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sEAAsE;IACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,8FAA8F;IAC9F,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,UAAU,EAAE,SAAS,CAAC;IACtB,mCAAmC;IACnC,UAAU,EAAE,SAAS,CAAC;IACtB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6CAA6C;IAC7C,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,cAAc,CAAC;IACrB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,uBAAuB;IACvB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,0BAA0B,CAAC;IACjC,mCAAmC;IACnC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,gBAAgB,GAChB,YAAY,GACZ,cAAc,GACd,8BAA8B,GAC9B,0BAA0B,CAAC;AAE/B;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;CACrB"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@sayna-ai/node-sdk",
3
+ "version": "0.0.2",
4
+ "description": "Node.js SDK for Sayna.ai server-side WebSocket connections",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "scripts": {
21
+ "build": "bun run build.ts",
22
+ "typecheck": "tsc --noEmit",
23
+ "lint": "eslint .",
24
+ "lint:fix": "eslint . --fix",
25
+ "format": "prettier --write .",
26
+ "format:check": "prettier --check .",
27
+ "prepublishOnly": "bun run typecheck && bun run lint && bun run build",
28
+ "prepack": "bun run build"
29
+ },
30
+ "keywords": [
31
+ "sayna",
32
+ "websocket",
33
+ "sdk",
34
+ "server"
35
+ ],
36
+ "author": "",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": ""
41
+ },
42
+ "bugs": {
43
+ "url": ""
44
+ },
45
+ "homepage": "",
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "devDependencies": {
50
+ "@types/bun": "latest",
51
+ "@typescript-eslint/eslint-plugin": "^8.46.0",
52
+ "@typescript-eslint/parser": "^8.46.0",
53
+ "eslint": "^9.37.0",
54
+ "prettier": "^3.6.2"
55
+ },
56
+ "peerDependencies": {
57
+ "typescript": "^5.9.3"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
62
+ }