Connection & Authentication
Connect, authenticate, and manage client lifecycle.
RaisinClient
Constructor
new RaisinClient(url: string, options?: ClientOptions)
| Parameter | Type | Description |
|---|---|---|
url | string | WebSocket URL (e.g. ws://localhost:8080) |
options | ClientOptions | Optional configuration |
interface ClientOptions {
tenantId?: string;
defaultBranch?: string;
requestTimeout?: number;
logLevel?: 'debug' | 'info' | 'warn' | 'error';
tokenStorage?: TokenStorage;
mode?: 'websocket' | 'http' | 'hybrid';
httpBaseUrl?: string;
}
connect()
Establish the WebSocket connection.
await client.connect(): Promise<void>
disconnect()
Close the WebSocket connection.
client.disconnect(): void
database()
Get a database interface for the given repository.
client.database(name: string): Database
The returned Database comes pre-configured with access to the Chat and Flow APIs:
const db = client.database('myapp');
// Chat — conversational AI
const convo = await db.chat.createConversation({ agent: '/agents/support' });
// Flow — workflow execution
const result = await db.flow.runAndWait('/flows/process-order', { orderId: '123' });
db.chat
Returns a pre-configured ChatClient scoped to this repository. The client is lazily created and cached.
get chat: ChatClient
db.flow
Returns a pre-configured FlowClient scoped to this repository. The client is lazily created and cached.
get flow: FlowClient
Authentication
authenticate()
Authenticate with admin credentials or a JWT token.
await client.authenticate(credentials: Credentials): Promise<void>
Admin credentials:
await client.authenticate({
username: 'admin',
password: 'your-password'
});
JWT token:
await client.authenticate({
type: 'jwt',
token: 'eyJhbGciOiJIUzI...'
});
loginWithEmail()
Log in an existing user with email and password.
await client.loginWithEmail(
email: string,
password: string,
repository: string
): Promise<IdentityUser>
Returns an IdentityUser with id, email, displayName, and home path.
registerWithEmail()
Register a new user account.
await client.registerWithEmail(
email: string,
password: string,
repository: string,
displayName?: string
): Promise<IdentityUser>
initSession()
Restore a session from a previously stored token.
await client.initSession(
repository: string
): Promise<IdentityUser | null>
Returns the user if a valid stored token exists, or null otherwise.
refreshToken()
Manually refresh the access token.
await client.refreshToken(): Promise<IdentityUser | null>
logout()
Sign out and optionally disconnect.
await client.logout(options?: {
disconnect?: boolean;
reconnect?: boolean;
}): Promise<void>
Session & User Info
isAuthenticated()
client.isAuthenticated(): boolean
isReady()
Returns true when the client is both connected and authenticated.
client.isReady(): boolean
getCurrentUser()
client.getCurrentUser(): CurrentUser | null
interface CurrentUser {
userId: string;
roles?: string[];
anonymous: boolean;
node?: UserNode;
}
getCurrentUserId()
client.getCurrentUserId(): string | null
getCurrentUserPath()
client.getCurrentUserPath(): string | null
getSession()
client.getSession(): {
user: IdentityUser | null;
accessToken: string | null;
} | null
getUser()
Alias for getSession()?.user. Compatible with Supabase patterns.
client.getUser(): IdentityUser | null
State Listeners
onAuthStateChange()
Listen for authentication lifecycle events.
const unsubscribe = client.onAuthStateChange(
callback: (change: AuthStateChange) => void
): () => void
interface AuthStateChange {
event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'
| 'SESSION_EXPIRED' | 'USER_UPDATED';
session: {
user: IdentityUser | null;
accessToken: string | null;
};
}
onConnectionStateChange()
const unsubscribe = client.onConnectionStateChange(
callback: (state: ConnectionState) => void
): () => void
ConnectionState is one of: 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'closed'.
onReadyStateChange()
Fires when the combined connected + authenticated state changes.
const unsubscribe = client.onReadyStateChange(
callback: (ready: boolean) => void
): () => void
onReconnected()
Fires after the client automatically reconnects.
const unsubscribe = client.onReconnected(
callback: () => void
): () => void
onUserChange()
Fires when the user's home node is updated.
const unsubscribe = client.onUserChange(
callback: (event: UserChangeEvent) => void
): () => void
Connection Info
isConnected()
client.isConnected(): boolean
getConnectionState()
client.getConnectionState(): ConnectionState
getBranch() / setBranch()
client.getBranch(): string
client.setBranch(branch: string): void
getTenantId()
client.getTenantId(): string
HTTP Client (SSR)
For server-side rendering where WebSocket is not available:
const client = RaisinClient.forSSR('http://localhost:8080', {
tenantId: 'default'
});
// Also available as:
const client = RaisinClient.createHttpClient('http://localhost:8080', options);
The HTTP client supports the same authentication and database methods but communicates over REST instead of WebSocket. Real-time events and flows over WebSocket are not available.
Token Storage
interface TokenStorage {
getAccessToken(): string | null;
setAccessToken(token: string): void;
getRefreshToken(): string | null;
setRefreshToken(token: string): void;
clear(): void;
}
Built-in implementations:
| Class | Storage | Use case |
|---|---|---|
MemoryTokenStorage | In-memory | Default, server-side |
LocalStorageTokenStorage | localStorage | Browser persistence |
Types
interface IdentityUser {
id: string;
email: string;
displayName?: string;
avatarUrl?: string;
emailVerified?: boolean;
home?: string;
}