Skip to main content
Version: 0.1.0

Connection & Authentication

Connect, authenticate, and manage client lifecycle.

RaisinClient

Constructor

new RaisinClient(url: string, options?: ClientOptions)
ParameterTypeDescription
urlstringWebSocket URL (e.g. ws://localhost:8080)
optionsClientOptionsOptional 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:

ClassStorageUse case
MemoryTokenStorageIn-memoryDefault, server-side
LocalStorageTokenStoragelocalStorageBrowser persistence

Types

interface IdentityUser {
id: string;
email: string;
displayName?: string;
avatarUrl?: string;
emailVerified?: boolean;
home?: string;
}