Get up and running with kSync v0.2 in under 2 minutes
npm install @klastra/ksync
import { createKSync } from '@klastra/ksync';
// Works instantly with smart defaults
const ksync = createKSync();
// Listen for events
ksync.on('message', (data, event) => {
console.log(`${event.userId}: ${data.text}`);
});
// Send events (instant local, auto-synced if server configured)
await ksync.send('message', {
text: 'Hello world!',
timestamp: Date.now()
});
// Get current state
const state = ksync.getState();
import { createChat } from '@klastra/ksync';
// Chat with presence and optimized batching
const chat = createChat('my-room', {
serverUrl: 'ws://localhost:8080'
});
// Set user presence
await chat.setPresence({
status: 'online',
metadata: { name: 'Alice', avatar: 'avatar-url' }
});
// Send messages
await chat.send('message', {
text: 'Hello everyone!',
author: 'Alice',
timestamp: Date.now()
});
// Listen for messages and presence
chat.on('message', (data) => {
console.log(`${data.author}: ${data.text}`);
});
chat.on('presence-update', (data) => {
console.log(`${data.metadata?.name} is ${data.status}`);
});
import { createChat } from '@klastra/ksync';
// Create chat instance
const chat = createChat('general', {
serverUrl: 'ws://localhost:8080', // Optional - works offline without server
features: { presence: true }
});
// Set user info
await chat.setPresence({
status: 'online',
metadata: {
name: 'Alice',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Alice'
}
});
// UI Elements (assuming HTML exists)
const messagesDiv = document.getElementById('messages');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const presenceDiv = document.getElementById('presence');
// Send message function
async function sendMessage() {
const text = messageInput.value.trim();
if (!text) return;
await chat.send('message', {
text,
author: 'Alice',
timestamp: Date.now(),
id: `msg-${Date.now()}`
});
messageInput.value = '';
}
// Listen for messages
chat.on('message', (data) => {
const messageEl = document.createElement('div');
messageEl.innerHTML = `
<strong>${data.author}</strong>: ${data.text}
<small>(${new Date(data.timestamp).toLocaleTimeString()})</small>
`;
messagesDiv.appendChild(messageEl);
messagesDiv.scrollTop = messagesDiv.scrollHeight;
});
// Listen for presence updates
chat.on('presence-update', (data) => {
updatePresenceUI();
});
function updatePresenceUI() {
const presence = chat.getPresence();
presenceDiv.innerHTML = presence
.map(p => `<span class="user ${p.status}">${p.metadata?.name || p.userId}</span>`)
.join('');
}
// Event listeners
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
// Initial presence update
updatePresenceUI();
import React, { useState, useEffect } from 'react';
import { createChat } from '@klastra/ksync';
function ChatApp() {
const [chat] = useState(() => createChat('my-room'));
const [messages, setMessages] = useState([]);
const [presence, setPresence] = useState([]);
useEffect(() => {
// Listen for messages
chat.on('message', (data) => {
setMessages(prev => [...prev, data]);
});
// Listen for presence
chat.on('presence-update', () => {
setPresence(chat.getPresence());
});
// Set initial presence
chat.setPresence({
status: 'online',
metadata: { name: 'React User' }
});
return () => {
chat.disconnect();
};
}, [chat]);
const sendMessage = async (text: string) => {
await chat.send('message', {
text,
author: 'React User',
timestamp: Date.now(),
id: `msg-${Date.now()}`
});
};
return (
<div>
<div>
<h3>Online ({presence.length})</h3>
{presence.map(p => (
<div key={p.userId}>{p.metadata?.name || p.userId}</div>
))}
</div>
<div>
<h3>Messages</h3>
{messages.map(msg => (
<div key={msg.id}>
<strong>{msg.author}</strong>: {msg.text}
</div>
))}
</div>
<input
onKeyPress={e => e.key === 'Enter' && sendMessage(e.target.value)}
placeholder="Type a message..."
/>
</div>
);
}
import { createAI } from '@klastra/ksync';
const ai = createAI('gpt-assistant', {
features: { streaming: true }
});
// Simple streaming chat interface
class AIChat {
private currentResponse = '';
private responseElement: HTMLElement;
constructor(responseElementId: string) {
this.responseElement = document.getElementById(responseElementId);
this.setupListeners();
}
private setupListeners() {
// Listen for streaming chunks
ai.on('stream-chunk', (data) => {
this.currentResponse += data.data;
this.responseElement.textContent = this.currentResponse;
});
// Response complete
ai.on('stream-end', (data) => {
console.log('AI response complete');
// Save to message history, etc.
});
}
async askQuestion(question: string) {
// Clear previous response
this.currentResponse = '';
this.responseElement.textContent = 'AI is thinking...';
// Simulate AI response stream
const responseId = `response-${Date.now()}`;
await ai.startStream(responseId);
// Simulate streaming response (replace with real AI API)
const words = [
'I understand your question. ',
'Let me think about this carefully. ',
'Based on my knowledge, ',
'I would recommend the following approach...'
];
for (const word of words) {
await new Promise(resolve => setTimeout(resolve, 500));
await ai.streamChunk(responseId, { data: word });
}
await ai.endStream(responseId);
}
}
// Usage
const chat = new AIChat('ai-response');
document.getElementById('ask-button').onclick = () => {
const question = document.getElementById('question-input').value;
chat.askQuestion(question);
};
import { createKSync } from '@klastra/ksync';
const ksync = createKSync({
// Connection
serverUrl: 'wss://your-server.com/ws',
room: 'my-app',
userId: 'user-123',
// Authentication
auth: {
token: 'your-jwt-token',
type: 'bearer'
},
// Performance tuning
performance: {
batchSize: 200, // Higher for throughput
batchDelay: 5, // Lower for real-time
materializationCaching: true,
compressionThreshold: 1024
},
// Offline support
offline: {
enabled: true,
queueSize: 10000,
persistence: true,
syncOnReconnect: true
},
// Features
features: {
presence: true,
streaming: true,
encryption: false
},
// Production debugging
debug: {
events: false, // Disable in production
performance: true // Monitor performance
}
});