kalam-link 0.2.0-alpha1

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,781 @@
1
+ /**
2
+ * kalam-link - Official TypeScript/JavaScript client for KalamDB
3
+ *
4
+ * This package provides a type-safe wrapper around the KalamDB WASM bindings
5
+ * for use in Node.js and browser environments.
6
+ *
7
+ * Features:
8
+ * - SQL query execution via HTTP
9
+ * - Real-time subscriptions via WebSocket (single connection, multiple subscriptions)
10
+ * - Subscription management with modern patterns (unsubscribe functions)
11
+ * - Cross-platform support (Node.js & Browser)
12
+ * - Type-safe authentication with multiple providers (Basic Auth, JWT, Anonymous)
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createClient, Auth } from 'kalam-link';
17
+ *
18
+ * // Basic Auth (username/password)
19
+ * const client = createClient({
20
+ * url: 'http://localhost:8080',
21
+ * auth: Auth.basic('admin', 'admin')
22
+ * });
23
+ *
24
+ * // JWT Token Auth
25
+ * const jwtClient = createClient({
26
+ * url: 'http://localhost:8080',
27
+ * auth: Auth.jwt('eyJhbGciOiJIUzI1NiIs...')
28
+ * });
29
+ *
30
+ * // Anonymous (localhost bypass)
31
+ * const anonClient = createClient({
32
+ * url: 'http://localhost:8080',
33
+ * auth: Auth.none()
34
+ * });
35
+ *
36
+ * await client.connect();
37
+ *
38
+ * // Subscribe to changes (returns unsubscribe function - Firebase/Supabase style)
39
+ * const unsubscribe = await client.subscribe('messages', (event) => {
40
+ * console.log('Change:', event);
41
+ * });
42
+ *
43
+ * // Check subscription count
44
+ * console.log(`Active subscriptions: ${client.getSubscriptionCount()}`);
45
+ *
46
+ * // Later: unsubscribe when done
47
+ * await unsubscribe();
48
+ * ```
49
+ */
50
+ export { Auth, AuthCredentials, BasicAuthCredentials, JwtAuthCredentials, NoAuthCredentials, buildAuthHeader, encodeBasicAuth, isAuthenticated, isBasicAuth, isJwtAuth, isNoAuth } from './auth.js';
51
+ import type { AuthCredentials } from './auth.js';
52
+ export type { KalamClient as WasmKalamClient } from './wasm/kalam_link.js';
53
+ /**
54
+ * Schema field describing a column in the result set
55
+ */
56
+ export interface SchemaField {
57
+ /** Column name */
58
+ name: string;
59
+ /** Data type (e.g., 'BigInt', 'Text', 'Timestamp') */
60
+ data_type: string;
61
+ /** Column index in the row array */
62
+ index: number;
63
+ }
64
+ /**
65
+ * Query result structure matching KalamDB server response
66
+ */
67
+ export interface QueryResult {
68
+ /** Schema describing the columns in the result set */
69
+ schema: SchemaField[];
70
+ /** Result rows as arrays of values (ordered by schema index) */
71
+ rows?: unknown[][];
72
+ /** Number of rows affected or returned */
73
+ row_count: number;
74
+ /** Optional message for non-query statements */
75
+ message?: string;
76
+ }
77
+ /**
78
+ * Full query response from the server
79
+ */
80
+ export interface QueryResponse {
81
+ /** Query execution status */
82
+ status: 'success' | 'error';
83
+ /** Array of result sets, one per executed statement */
84
+ results: QueryResult[];
85
+ /** Query execution time in milliseconds */
86
+ took?: number;
87
+ /** Error details if status is "error" */
88
+ error?: ErrorDetail;
89
+ }
90
+ /**
91
+ * Error detail structure
92
+ */
93
+ export interface ErrorDetail {
94
+ /** Error code */
95
+ code: string;
96
+ /** Error message */
97
+ message: string;
98
+ /** Optional error details */
99
+ details?: any;
100
+ }
101
+ /**
102
+ * Message type enum for WebSocket subscription events
103
+ */
104
+ export declare enum MessageType {
105
+ SubscriptionAck = "subscription_ack",
106
+ InitialDataBatch = "initial_data_batch",
107
+ Change = "change",
108
+ Error = "error"
109
+ }
110
+ /**
111
+ * Change type enum for live subscription change events
112
+ */
113
+ export declare enum ChangeType {
114
+ Insert = "insert",
115
+ Update = "update",
116
+ Delete = "delete"
117
+ }
118
+ /**
119
+ * Batch loading status enum
120
+ */
121
+ export declare enum BatchStatus {
122
+ Loading = "loading",
123
+ LoadingBatch = "loading_batch",
124
+ Ready = "ready"
125
+ }
126
+ /**
127
+ * Server message types for WebSocket subscriptions
128
+ */
129
+ export type ServerMessage = {
130
+ type: MessageType.SubscriptionAck | 'subscription_ack';
131
+ subscription_id: string;
132
+ total_rows: number;
133
+ batch_control: BatchControl;
134
+ schema: SchemaField[];
135
+ } | {
136
+ type: MessageType.InitialDataBatch | 'initial_data_batch';
137
+ subscription_id: string;
138
+ rows: Record<string, any>[];
139
+ batch_control: BatchControl;
140
+ } | {
141
+ type: MessageType.Change | 'change';
142
+ subscription_id: string;
143
+ change_type: ChangeType | 'insert' | 'update' | 'delete';
144
+ rows?: Record<string, any>[];
145
+ old_values?: Record<string, any>[];
146
+ } | {
147
+ type: MessageType.Error | 'error';
148
+ subscription_id: string;
149
+ code: string;
150
+ message: string;
151
+ };
152
+ /**
153
+ * Batch control metadata for paginated data loading
154
+ *
155
+ * Note: We don't include total_batches because we can't know it upfront
156
+ * without counting all rows first (expensive). The `has_more` field is
157
+ * sufficient for clients to know whether to request more batches.
158
+ */
159
+ export interface BatchControl {
160
+ /** Current batch number (0-indexed) */
161
+ batch_num: number;
162
+ /** Whether more batches are available */
163
+ has_more: boolean;
164
+ /** Loading status */
165
+ status: BatchStatus | 'loading' | 'loading_batch' | 'ready';
166
+ /** Last sequence ID in this batch */
167
+ last_seq_id?: string;
168
+ /** Snapshot boundary sequence ID */
169
+ snapshot_end_seq?: string;
170
+ }
171
+ /**
172
+ * Subscription callback function type
173
+ */
174
+ export type SubscriptionCallback = (event: ServerMessage) => void;
175
+ /**
176
+ * Function to unsubscribe from a subscription (Firebase/Supabase style)
177
+ * @returns Promise that resolves when unsubscription is complete
178
+ */
179
+ export type Unsubscribe = () => Promise<void>;
180
+ /**
181
+ * Information about an active subscription
182
+ */
183
+ export interface SubscriptionInfo {
184
+ /** Unique subscription ID */
185
+ id: string;
186
+ /** Table name or SQL query being subscribed to */
187
+ tableName: string;
188
+ /** Timestamp when subscription was created */
189
+ createdAt: Date;
190
+ }
191
+ /**
192
+ * Connection-level options for WebSocket connection behavior
193
+ *
194
+ * These options control the overall WebSocket connection, including:
195
+ * - Automatic reconnection on connection loss
196
+ * - Reconnection timing and retry limits
197
+ *
198
+ * Separate from SubscriptionOptions which control individual subscriptions.
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * const client = new KalamDBClient('http://localhost:8080', 'user', 'pass');
203
+ *
204
+ * // Configure connection options before connecting
205
+ * client.setAutoReconnect(true);
206
+ * client.setReconnectDelay(2000, 60000);
207
+ * client.setMaxReconnectAttempts(10);
208
+ *
209
+ * await client.connect();
210
+ * ```
211
+ */
212
+ export interface ConnectionOptions {
213
+ /**
214
+ * Enable automatic reconnection on connection loss
215
+ * Default: true - automatically attempts to reconnect
216
+ */
217
+ auto_reconnect?: boolean;
218
+ /**
219
+ * Initial delay in milliseconds between reconnection attempts
220
+ * Default: 1000ms (1 second)
221
+ * Uses exponential backoff up to max_reconnect_delay_ms
222
+ */
223
+ reconnect_delay_ms?: number;
224
+ /**
225
+ * Maximum delay between reconnection attempts (for exponential backoff)
226
+ * Default: 30000ms (30 seconds)
227
+ */
228
+ max_reconnect_delay_ms?: number;
229
+ /**
230
+ * Maximum number of reconnection attempts before giving up
231
+ * Default: undefined (infinite retries)
232
+ * Set to 0 to disable reconnection entirely
233
+ */
234
+ max_reconnect_attempts?: number;
235
+ }
236
+ /**
237
+ * Subscription options for controlling individual subscription behavior
238
+ *
239
+ * These options control subscription behavior including:
240
+ * - Initial data loading (batch_size, last_rows)
241
+ * - Data resumption after reconnection (from_seq_id)
242
+ *
243
+ * Aligned with backend's SubscriptionOptions.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * // Fetch last 100 rows with batch size of 50
248
+ * const options: SubscriptionOptions = {
249
+ * batch_size: 50,
250
+ * last_rows: 100
251
+ * };
252
+ *
253
+ * const unsubscribe = await client.subscribe('messages', callback, options);
254
+ * ```
255
+ */
256
+ export interface SubscriptionOptions {
257
+ /**
258
+ * Hint for server-side batch sizing during initial data load
259
+ * Default: server-configured (typically 1000 rows per batch)
260
+ */
261
+ batch_size?: number;
262
+ /**
263
+ * Number of last (newest) rows to fetch for initial data
264
+ * Default: undefined (fetch all matching rows)
265
+ */
266
+ last_rows?: number;
267
+ /**
268
+ * Resume subscription from a specific sequence ID
269
+ * When set, the server will only send changes after this seq_id
270
+ * Typically set automatically during reconnection to resume from last received event
271
+ */
272
+ from_seq_id?: string;
273
+ }
274
+ /**
275
+ * @deprecated Use SubscriptionOptions instead. This type alias is for backwards compatibility.
276
+ */
277
+ export type SubscribeOptions = SubscriptionOptions;
278
+ /**
279
+ * Configuration options for KalamDB client (new type-safe API)
280
+ *
281
+ * Uses discriminated unions for type-safe authentication.
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * // Type-safe auth options
286
+ * const client = createClient({
287
+ * url: 'http://localhost:8080',
288
+ * auth: Auth.basic('admin', 'admin')
289
+ * });
290
+ *
291
+ * // JWT authentication
292
+ * const jwtClient = createClient({
293
+ * url: 'http://localhost:8080',
294
+ * auth: Auth.jwt('eyJhbGciOiJIUzI1NiIs...')
295
+ * });
296
+ * ```
297
+ */
298
+ export interface ClientOptionsWithAuth {
299
+ /** Server URL (e.g., 'http://localhost:8080') */
300
+ url: string;
301
+ /** Authentication credentials (type-safe) */
302
+ auth: AuthCredentials;
303
+ }
304
+ /**
305
+ * Configuration options for KalamDB client (legacy API)
306
+ *
307
+ * @deprecated Use ClientOptionsWithAuth with Auth.basic() instead
308
+ */
309
+ export interface ClientOptionsLegacy {
310
+ /** Server URL (e.g., 'http://localhost:8080') */
311
+ url: string;
312
+ /** Username for authentication */
313
+ username: string;
314
+ /** Password for authentication */
315
+ password: string;
316
+ }
317
+ /**
318
+ * Configuration options for KalamDB client
319
+ *
320
+ * Supports both new type-safe auth API and legacy username/password API.
321
+ */
322
+ export type ClientOptions = ClientOptionsWithAuth | ClientOptionsLegacy;
323
+ /**
324
+ * KalamDB Client - TypeScript wrapper around WASM bindings
325
+ *
326
+ * Provides a type-safe interface to KalamDB with support for:
327
+ * - SQL query execution
328
+ * - Real-time WebSocket subscriptions
329
+ * - Multiple authentication methods (Basic Auth, JWT, Anonymous)
330
+ * - Cross-platform (Node.js & Browser)
331
+ * - Subscription tracking and management
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * // New API with type-safe auth (recommended)
336
+ * import { createClient, Auth } from 'kalam-link';
337
+ *
338
+ * const client = createClient({
339
+ * url: 'http://localhost:8080',
340
+ * auth: Auth.basic('alice', 'password123')
341
+ * });
342
+ *
343
+ * // JWT authentication
344
+ * const jwtClient = createClient({
345
+ * url: 'http://localhost:8080',
346
+ * auth: Auth.jwt('eyJhbGciOiJIUzI1NiIs...')
347
+ * });
348
+ *
349
+ * // Anonymous (no auth - localhost bypass)
350
+ * const anonClient = createClient({
351
+ * url: 'http://localhost:8080',
352
+ * auth: Auth.none()
353
+ * });
354
+ *
355
+ * await client.connect();
356
+ *
357
+ * // Execute queries
358
+ * const users = await client.query('SELECT * FROM users WHERE active = true');
359
+ * console.log(users.results[0].rows);
360
+ *
361
+ * // Subscribe to changes (returns unsubscribe function)
362
+ * const unsubscribe = await client.subscribe('messages', (event) => {
363
+ * if (event.type === 'change') {
364
+ * console.log('New message:', event.rows);
365
+ * }
366
+ * });
367
+ *
368
+ * // Check subscription count
369
+ * console.log(`Active: ${client.getSubscriptionCount()}`);
370
+ *
371
+ * // Cleanup
372
+ * await unsubscribe();
373
+ * await client.disconnect();
374
+ * ```
375
+ */
376
+ export declare class KalamDBClient {
377
+ private wasmClient;
378
+ private initialized;
379
+ private url;
380
+ private auth;
381
+ /** Track active subscriptions for management */
382
+ private subscriptions;
383
+ /**
384
+ * Create a new KalamDB client with type-safe auth options
385
+ *
386
+ * @param options - Client options with URL and auth credentials
387
+ *
388
+ * @throws Error if url is empty
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * import { KalamDBClient, Auth } from 'kalam-link';
393
+ *
394
+ * const client = new KalamDBClient({
395
+ * url: 'http://localhost:8080',
396
+ * auth: Auth.basic('admin', 'secret')
397
+ * });
398
+ * ```
399
+ */
400
+ constructor(options: ClientOptionsWithAuth);
401
+ /**
402
+ * Create a new KalamDB client with username/password (legacy API)
403
+ *
404
+ * @param url - Server URL (e.g., 'http://localhost:8080')
405
+ * @param username - Username for authentication
406
+ * @param password - Password for authentication
407
+ *
408
+ * @throws Error if url, username, or password is empty
409
+ *
410
+ * @deprecated Use constructor with ClientOptionsWithAuth and Auth.basic() instead
411
+ */
412
+ constructor(url: string, username: string, password: string);
413
+ /**
414
+ * Get the current authentication type
415
+ *
416
+ * @returns 'basic', 'jwt', or 'none'
417
+ */
418
+ getAuthType(): 'basic' | 'jwt' | 'none';
419
+ /**
420
+ * Initialize WASM module and create client instance
421
+ *
422
+ * Must be called before any other operations. Automatically called by connect()
423
+ * if not already initialized.
424
+ *
425
+ * @throws Error if WASM initialization fails
426
+ */
427
+ initialize(): Promise<void>;
428
+ /**
429
+ * Connect to KalamDB server via WebSocket
430
+ *
431
+ * Establishes a persistent WebSocket connection for real-time subscriptions.
432
+ * Also initializes the WASM module if not already done.
433
+ *
434
+ * @throws Error if connection fails
435
+ */
436
+ connect(): Promise<void>;
437
+ /**
438
+ * Enable or disable automatic reconnection
439
+ *
440
+ * When enabled, the client will automatically attempt to reconnect
441
+ * if the WebSocket connection is lost, and will re-subscribe to all
442
+ * active subscriptions with resume_from_seq_id to catch up on missed events.
443
+ *
444
+ * @param enabled - Whether to automatically reconnect on connection loss
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * client.setAutoReconnect(true); // Enable (default)
449
+ * client.setAutoReconnect(false); // Disable for manual control
450
+ * ```
451
+ */
452
+ setAutoReconnect(enabled: boolean): void;
453
+ /**
454
+ * Configure reconnection delay parameters
455
+ *
456
+ * The client uses exponential backoff starting from initialDelayMs,
457
+ * doubling each attempt up to maxDelayMs.
458
+ *
459
+ * @param initialDelayMs - Initial delay between reconnection attempts (default: 1000ms)
460
+ * @param maxDelayMs - Maximum delay for exponential backoff (default: 30000ms)
461
+ *
462
+ * @example
463
+ * ```typescript
464
+ * // Start with 500ms delay, max out at 10 seconds
465
+ * client.setReconnectDelay(500, 10000);
466
+ * ```
467
+ */
468
+ setReconnectDelay(initialDelayMs: number, maxDelayMs: number): void;
469
+ /**
470
+ * Set maximum number of reconnection attempts
471
+ *
472
+ * @param maxAttempts - Maximum attempts before giving up (0 = infinite)
473
+ *
474
+ * @example
475
+ * ```typescript
476
+ * client.setMaxReconnectAttempts(5); // Give up after 5 attempts
477
+ * client.setMaxReconnectAttempts(0); // Never give up (default)
478
+ * ```
479
+ */
480
+ setMaxReconnectAttempts(maxAttempts: number): void;
481
+ /**
482
+ * Get the current number of reconnection attempts
483
+ *
484
+ * Resets to 0 after a successful reconnection.
485
+ *
486
+ * @returns Current reconnection attempt count
487
+ */
488
+ getReconnectAttempts(): number;
489
+ /**
490
+ * Check if the client is currently attempting to reconnect
491
+ *
492
+ * @returns true if a reconnection is in progress
493
+ */
494
+ isReconnecting(): boolean;
495
+ /**
496
+ * Get the last received sequence ID for a subscription
497
+ *
498
+ * Useful for debugging or manual tracking of subscription progress.
499
+ * This seq_id is automatically used during reconnection to resume
500
+ * from where the subscription left off.
501
+ *
502
+ * @param subscriptionId - The subscription ID to query
503
+ * @returns The last seq_id as a string, or undefined if not set
504
+ *
505
+ * @example
506
+ * ```typescript
507
+ * const lastSeq = client.getLastSeqId(subscriptionId);
508
+ * console.log(`Last received seq: ${lastSeq}`);
509
+ * ```
510
+ */
511
+ getLastSeqId(subscriptionId: string): string | undefined;
512
+ /**
513
+ * Helper to ensure WASM client is initialized
514
+ * @private
515
+ */
516
+ private ensureInitialized;
517
+ /**
518
+ * Disconnect from KalamDB server
519
+ *
520
+ * Closes the WebSocket connection and cleans up all active subscriptions.
521
+ */
522
+ disconnect(): Promise<void>;
523
+ /**
524
+ * Check if client is currently connected
525
+ *
526
+ * @returns true if WebSocket connection is active, false otherwise
527
+ */
528
+ isConnected(): boolean;
529
+ /**
530
+ * Execute a SQL query with optional parameters
531
+ *
532
+ * Supports all SQL statements: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, etc.
533
+ * Use parameterized queries to prevent SQL injection.
534
+ *
535
+ * @param sql - SQL query string (may contain $1, $2, ... placeholders)
536
+ * @param params - Optional array of parameter values for placeholders
537
+ * @returns Parsed query response with results
538
+ *
539
+ * @throws Error if query execution fails
540
+ *
541
+ * @example
542
+ * ```typescript
543
+ * // Simple query
544
+ * const result = await client.query('SELECT * FROM users');
545
+ *
546
+ * // Parameterized query (recommended for user input)
547
+ * const users = await client.query(
548
+ * 'SELECT * FROM users WHERE id = $1 AND age > $2',
549
+ * [42, 18]
550
+ * );
551
+ * console.log(users.results[0].rows);
552
+ *
553
+ * // INSERT with parameters
554
+ * await client.query(
555
+ * "INSERT INTO users (name, email) VALUES ($1, $2)",
556
+ * ['Alice', 'alice@example.com']
557
+ * );
558
+ *
559
+ * // DDL statements (no params)
560
+ * await client.query('CREATE TABLE products (id BIGINT PRIMARY KEY, name TEXT)');
561
+ * ```
562
+ */
563
+ query(sql: string, params?: any[]): Promise<QueryResponse>;
564
+ /**
565
+ * Insert data into a table (convenience method)
566
+ *
567
+ * @param tableName - Name of the table (can include namespace, e.g., 'app.users')
568
+ * @param data - Object containing column values
569
+ * @returns Query response
570
+ *
571
+ * @throws Error if insert fails
572
+ *
573
+ * @example
574
+ * ```typescript
575
+ * await client.insert('todos', {
576
+ * title: 'Buy groceries',
577
+ * completed: false
578
+ * });
579
+ * ```
580
+ */
581
+ insert(tableName: string, data: Record<string, any>): Promise<QueryResponse>;
582
+ /**
583
+ * Delete a row from a table (convenience method)
584
+ *
585
+ * @param tableName - Name of the table
586
+ * @param rowId - ID of the row to delete
587
+ *
588
+ * @throws Error if delete fails
589
+ *
590
+ * @example
591
+ * ```typescript
592
+ * await client.delete('todos', '123456789');
593
+ * ```
594
+ */
595
+ delete(tableName: string, rowId: string | number): Promise<void>;
596
+ /**
597
+ * Subscribe to real-time changes in a table
598
+ *
599
+ * The callback will be invoked for:
600
+ * - Initial data batches (type: 'initial_data_batch')
601
+ * - Live changes (type: 'change')
602
+ * - Errors (type: 'error')
603
+ *
604
+ * Returns an unsubscribe function (Firebase/Supabase style) for easy cleanup.
605
+ *
606
+ * @param tableName - Name of the table to subscribe to
607
+ * @param callback - Function called when changes occur
608
+ * @param options - Optional subscription options (batch_size, last_rows, from_seq_id)
609
+ * @returns Unsubscribe function to stop receiving updates
610
+ *
611
+ * @throws Error if subscription fails or not connected
612
+ *
613
+ * @example
614
+ * ```typescript
615
+ * // Simple subscription
616
+ * const unsubscribe = await client.subscribe('messages', (event) => {
617
+ * if (event.type === 'change') {
618
+ * console.log('New data:', event.rows);
619
+ * }
620
+ * });
621
+ *
622
+ * // With options
623
+ * const unsubscribe = await client.subscribe('messages', callback, {
624
+ * batch_size: 100, // Load initial data in batches of 100
625
+ * last_rows: 50 // Only fetch last 50 rows initially
626
+ * });
627
+ *
628
+ * // Later: unsubscribe when done
629
+ * await unsubscribe();
630
+ * ```
631
+ */
632
+ subscribe(tableName: string, callback: SubscriptionCallback, options?: SubscriptionOptions): Promise<Unsubscribe>;
633
+ /**
634
+ * Subscribe to a SQL query with real-time updates
635
+ *
636
+ * More flexible than subscribe() - allows custom SQL queries with WHERE clauses,
637
+ * JOINs, and other SQL features.
638
+ *
639
+ * @param sql - SQL SELECT query to subscribe to
640
+ * @param callback - Function called when changes occur
641
+ * @param options - Optional subscription options (batch_size, last_rows, from_seq_id)
642
+ * @returns Unsubscribe function to stop receiving updates
643
+ *
644
+ * @throws Error if subscription fails or not connected
645
+ *
646
+ * @example
647
+ * ```typescript
648
+ * // Subscribe to filtered query
649
+ * const unsubscribe = await client.subscribeWithSql(
650
+ * 'SELECT * FROM chat.messages WHERE conversation_id = 1',
651
+ * (event) => {
652
+ * if (event.type === 'change') {
653
+ * console.log('New message:', event.rows);
654
+ * }
655
+ * },
656
+ * { batch_size: 50, last_rows: 100 }
657
+ * );
658
+ *
659
+ * // Later: unsubscribe when done
660
+ * await unsubscribe();
661
+ * ```
662
+ */
663
+ subscribeWithSql(sql: string, callback: SubscriptionCallback, options?: SubscriptionOptions): Promise<Unsubscribe>;
664
+ /**
665
+ * Unsubscribe from table changes
666
+ *
667
+ * @param subscriptionId - ID returned from subscribe()
668
+ *
669
+ * @throws Error if unsubscribe fails or not connected
670
+ *
671
+ * @example
672
+ * ```typescript
673
+ * // Using the returned unsubscribe function (preferred)
674
+ * const unsubscribe = await client.subscribe('messages', handleChange);
675
+ * await unsubscribe();
676
+ *
677
+ * // Or manually with subscription ID
678
+ * const unsubscribe = await client.subscribe('messages', handleChange);
679
+ * const subs = client.getSubscriptions();
680
+ * await client.unsubscribe(subs[0].id);
681
+ * ```
682
+ */
683
+ unsubscribe(subscriptionId: string): Promise<void>;
684
+ /**
685
+ * Get the number of active subscriptions
686
+ *
687
+ * @returns Number of active subscriptions
688
+ *
689
+ * @example
690
+ * ```typescript
691
+ * console.log(`Active subscriptions: ${client.getSubscriptionCount()}`);
692
+ *
693
+ * // Prevent too many subscriptions
694
+ * if (client.getSubscriptionCount() >= 10) {
695
+ * console.warn('Too many subscriptions!');
696
+ * }
697
+ * ```
698
+ */
699
+ getSubscriptionCount(): number;
700
+ /**
701
+ * Get information about all active subscriptions
702
+ *
703
+ * @returns Array of subscription info objects
704
+ *
705
+ * @example
706
+ * ```typescript
707
+ * const subs = client.getSubscriptions();
708
+ * for (const sub of subs) {
709
+ * console.log(`Subscribed to ${sub.tableName} since ${sub.createdAt}`);
710
+ * }
711
+ * ```
712
+ */
713
+ getSubscriptions(): SubscriptionInfo[];
714
+ /**
715
+ * Check if subscribed to a specific table
716
+ *
717
+ * @param tableName - Name of the table to check
718
+ * @returns true if there's an active subscription to this table
719
+ *
720
+ * @example
721
+ * ```typescript
722
+ * if (!client.isSubscribedTo('messages')) {
723
+ * await client.subscribe('messages', handleChange);
724
+ * }
725
+ * ```
726
+ */
727
+ isSubscribedTo(tableName: string): boolean;
728
+ /**
729
+ * Unsubscribe from all active subscriptions
730
+ *
731
+ * Useful for cleanup before disconnecting or switching contexts.
732
+ *
733
+ * @example
734
+ * ```typescript
735
+ * // Cleanup all subscriptions
736
+ * await client.unsubscribeAll();
737
+ * console.log(`Subscriptions remaining: ${client.getSubscriptionCount()}`); // 0
738
+ * ```
739
+ */
740
+ unsubscribeAll(): Promise<void>;
741
+ }
742
+ /**
743
+ * Create a KalamDB client with the given configuration
744
+ *
745
+ * Factory function that supports both the new type-safe auth API and legacy API.
746
+ *
747
+ * @param options - Client configuration with URL and authentication
748
+ * @returns Configured KalamDB client
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * import { createClient, Auth } from 'kalam-link';
753
+ *
754
+ * // New type-safe API (recommended)
755
+ * const client = createClient({
756
+ * url: 'http://localhost:8080',
757
+ * auth: Auth.basic('admin', 'admin')
758
+ * });
759
+ *
760
+ * // JWT authentication
761
+ * const jwtClient = createClient({
762
+ * url: 'http://localhost:8080',
763
+ * auth: Auth.jwt('eyJhbGciOiJIUzI1NiIs...')
764
+ * });
765
+ *
766
+ * // Anonymous (no authentication)
767
+ * const anonClient = createClient({
768
+ * url: 'http://localhost:8080',
769
+ * auth: Auth.none()
770
+ * });
771
+ *
772
+ * // Legacy API (deprecated but still works)
773
+ * const legacyClient = createClient({
774
+ * url: 'http://localhost:8080',
775
+ * username: 'admin',
776
+ * password: 'admin'
777
+ * });
778
+ * ```
779
+ */
780
+ export declare function createClient(options: ClientOptions): KalamDBClient;
781
+ export default KalamDBClient;