A lightweight TypeScript client library for smooth-server with authentication, conversation management, and WebSocket support
npm install smooth-clientsmooth-client is a lightweight TypeScript helper for working with the parent smooth-server project. It ships typed helpers for authentication, user configuration, conversation management, and message creation on top of the server's /api/v1 endpoints.
- Node.js ≥ 18 (or any runtime that provides fetch)
- A running instance of smooth-server (default http://localhost:8000/api/v1)
Install dependencies once:
``bash`
npm install
First, you need to get a token and user ID. Use SmoothClient.login() to authenticate:
`ts
import { SmoothClient } from "smooth-client";
// Create a client instance for login (token can be empty for login only)
const tempClient = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: "", // Empty token is acceptable for login
});
// Perform login to get token and user_id
const { token, user_id } = await tempClient.login();
console.log({ token, user_id });
// Now create a client with the token for API operations
const client = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: token, // Use the token from login
});
`
Alternatively, you can also use the deprecated SmoothAuthClient for backward compatibility:
`ts
import { SmoothAuthClient } from "smooth-client";
const authClient = new SmoothAuthClient({ baseUrl: "http://localhost:8000/api/v1" });
const { token, user_id } = await authClient.login();
`
Note: If you omit baseUrl, the helper will look for SMOOTH_SERVER_URL (for example via a .env file) and fall back to http://localhost:8000/api/v1.
`ts
import { SmoothClient } from "smooth-client";
const client = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: "your_token",
});
// Note: updateNativeLanguage takes userId as first parameter
await client.updateNativeLanguage("user_123", "zh-CN");
`
`ts
import { SmoothClient } from "smooth-client";
const client = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: "your_token",
});
const conversation = await client.createConversation({
participants: ["user_123"],
title: "Demo conversation",
});
await client.sendTextMessage({
conversationId: conversation.id,
content: "Hello from smooth-client!",
});
`
`ts
import { SmoothClient } from "smooth-client";
const client = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: "your_token",
});
// Set your language preference for a conversation
await client.updateParticipantLanguage({
conversationId: conversation.id,
language: "zh-CN",
});
`
The SmoothClient includes integrated WebSocket functionality:
`ts
import {
SmoothClient,
WebSocketStatus,
type WebSocketMessage,
type NewMessageEvent,
type MessageTranslationCompleteEvent,
} from "smooth-client";
const client = new SmoothClient({
baseUrl: "http://localhost:8000/api/v1",
token: "your_token",
// Optional WebSocket callbacks (you can also use event listeners)
onConnect: () => {
console.log("WebSocket connected");
},
onMessage: (message: WebSocketMessage) => {
switch (message.type) {
case "new_message":
console.log("New message:", message.message?.content);
break;
case "message_translation_complete":
console.log("Translation complete:", message.translated_text);
break;
case "message_translating":
console.log("Translation in progress...");
break;
}
},
onError: (error) => {
console.error("WebSocket error:", error);
},
onClose: () => {
console.log("WebSocket closed");
},
});
// Connect to the WebSocket server
await client.connect();
// Subscribe to a conversation
await client.subscribe("conversation_id");
// Register event listeners for specific message types with strong typing
// TypeScript will automatically infer the correct event type
client.on("new_message", (message: NewMessageEvent) => {
// TypeScript knows message.message is guaranteed to exist
console.log("New message:", message.message.content);
console.log("From:", message.message.sender_id);
console.log("Conversation:", message.conversation_id);
});
client.on("message_translation_complete", (message: MessageTranslationCompleteEvent) => {
// TypeScript knows all required fields exist
console.log("Translation complete:", message.translated_text);
console.log("Original:", message.original_text);
console.log("Source:", message.source_language, "→ Target:", message.target_language);
});
client.on("message_translating", (message) => {
// TypeScript infers MessageTranslatingEvent type automatically
console.log("Translation in progress for message:", message.message_id);
});
// Listen to all messages
client.on("message", (message) => {
// TypeScript infers WebSocketMessage type
console.log("Any message received:", message.type);
});
// Remove an event listener (need to store the handler reference first)
const messageHandler = (message: NewMessageEvent) => {
console.log("Message received:", message.message.content);
};
client.on("new_message", messageHandler);
// Later, remove it
client.off("new_message", messageHandler);
// Listen to an event only once
client.once("connect", () => {
console.log("First connection established");
});
// Later, unsubscribe if needed
await client.unsubscribe("conversation_id");
// Disconnect
client.disconnect();
`
Compile the library to dist/:
`bash`
npm run build
`bash`
npm run lint
`bash`
npm run test:e2e # Node + fetch (basic auth and messaging)
npm run test:e2e:audio # Audio translation test (Chinese to Japanese/Korean)
npm run test:e2e:browser # Playwright (headless browser)
Both suites call the real Smooth Server. Ensure the server is running locally (default http://localhost:8000/api/v1) or set SMOOTH_SERVER_E2E_URL to point to a reachable instance before running the tests. The browser suite requires Playwright browsers (install with npx playwright install if needed).
The test:e2e:audio` test demonstrates:
- Creating multiple users with different language preferences (Chinese, Japanese, Korean)
- Generating Chinese audio using TTS API
- Sending audio via WebSocket for real-time transcription
- Receiving transcription results and translations to multiple target languages
Prerequisites:
- Smooth server must be running with TTS and translation services configured
- Google API credentials must be available for TTS and translation