@ekodb/ekodb-client 0.20.0 → 0.22.0

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.
package/README.md CHANGED
@@ -254,6 +254,7 @@ const joinResults = await client.find("users", multiQuery);
254
254
  - `kvSet(key: string, value: any): Promise<void>`
255
255
  - `kvGet(key: string): Promise<any>`
256
256
  - `kvDelete(key: string): Promise<void>`
257
+ - `kvClear(): Promise<void>` - Clear the entire KV store
257
258
 
258
259
  #### Query Builder
259
260
 
@@ -297,6 +298,8 @@ const joinResults = await client.find("users", multiQuery);
297
298
  #### Collection Management
298
299
 
299
300
  - `listCollections(): Promise<string[]>`
301
+ - `listUserCollections(): Promise<string[]>` - List collections excluding
302
+ internal chat/system collections
300
303
  - `deleteCollection(collection: string): Promise<void>`
301
304
  - `collectionExists(collection: string): Promise<boolean>` - Check if collection
302
305
  exists
@@ -346,6 +349,14 @@ const joinResults = await client.find("users", multiQuery);
346
349
  - `deleteCollection(name): Promise<void>`
347
350
  - `close(): void`
348
351
 
352
+ **Subscriptions & chat:**
353
+
354
+ - `subscribe(collection, options?): Promise<EventStream<MutationNotification>>`
355
+ - Subscribe to a collection's mutation notifications
356
+ - `unsubscribe(collection): void` - Tear down a subscription (not replayed on
357
+ reconnect)
358
+ - `cancelChat(chatId): Promise<void>` - Cancel an in-flight streaming chat
359
+
349
360
  **Schema Cache:**
350
361
 
351
362
  ```typescript
@@ -359,6 +370,23 @@ const id = extractRecordId(record); // tries "id", "_id"
359
370
  const id2 = ws.extractId("users", record); // uses cache
360
371
  ```
361
372
 
373
+ ### Transactions
374
+
375
+ Buffered, read-your-writes transactions. Statements issued with a
376
+ `transactionId` are staged and applied atomically at commit.
377
+
378
+ - `beginTransaction(isolationLevel?): Promise<string>` - Start a transaction and
379
+ return its id
380
+ - `commitTransaction(transactionId): Promise<void>` - Apply staged writes. May
381
+ reject with a retryable conflict (HTTP 409)
382
+ - `rollbackTransaction(transactionId): Promise<void>` - Discard staged writes
383
+ - `createSavepoint(transactionId, name): Promise<void>`
384
+ - `rollbackToSavepoint(transactionId, name): Promise<void>`
385
+ - `releaseSavepoint(transactionId, name): Promise<void>`
386
+
387
+ Pass `transactionId` in the options of `insert` / `update` / `delete` / `find` /
388
+ `findById` to read and write within the transaction (read-your-writes).
389
+
362
390
  ## Examples
363
391
 
364
392
  See the
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * ekoDB TypeScript Client
3
3
  */
4
- import { QueryBuilder } from "./query-builder";
4
+ import { QueryBuilder, Query } from "./query-builder";
5
5
  import { SearchQuery, SearchResponse } from "./search";
6
6
  import { Schema, SchemaBuilder, CollectionMetadata } from "./schema";
7
7
  import { UserFunction, FunctionResult } from "./functions";
@@ -50,11 +50,7 @@ export declare class RateLimitError extends Error {
50
50
  retryAfterSecs: number;
51
51
  constructor(retryAfterSecs: number, message?: string);
52
52
  }
53
- export interface Query {
54
- limit?: number;
55
- offset?: number;
56
- filter?: Record;
57
- }
53
+ export type { Query };
58
54
  export interface BatchOperationResult {
59
55
  successful: string[];
60
56
  failed: Array<{
@@ -95,6 +91,23 @@ export interface FindOptions {
95
91
  bypassCache?: boolean;
96
92
  selectFields?: string[];
97
93
  excludeFields?: string[];
94
+ /**
95
+ * Read within a transaction (read-your-writes). When set, the read is served
96
+ * from the transaction's own view — its uncommitted staged writes, else the
97
+ * committed store — and recorded in the transaction's read set for
98
+ * commit-time conflict detection. Omit for an ordinary committed read.
99
+ */
100
+ transactionId?: string;
101
+ }
102
+ /**
103
+ * Options for a point read by id. `transactionId` enables read-your-writes
104
+ * within a transaction (see {@link FindOptions.transactionId}).
105
+ */
106
+ export interface FindByIdOptions {
107
+ selectFields?: string[];
108
+ excludeFields?: string[];
109
+ bypassRipple?: boolean;
110
+ transactionId?: string;
98
111
  }
99
112
  export interface BatchInsertOptions {
100
113
  bypassRipple?: boolean;
@@ -427,19 +440,25 @@ export declare class EkoDBClient {
427
440
  * const results = await client.find("users", { limit: 10 });
428
441
  * ```
429
442
  */
430
- find(collection: string, query?: Query | QueryBuilder): Promise<Record[]>;
443
+ find(collection: string, query?: Query | QueryBuilder, options?: {
444
+ bypassRipple?: boolean;
445
+ transactionId?: string;
446
+ }): Promise<Record[]>;
431
447
  /**
432
- * Find a document by ID
448
+ * Find a document by ID.
449
+ * @param options - Optional read options. `transactionId` reads within a
450
+ * transaction (read-your-writes); see {@link FindByIdOptions}.
433
451
  */
434
- findById(collection: string, id: string): Promise<Record>;
452
+ findById(collection: string, id: string, options?: FindByIdOptions): Promise<Record>;
435
453
  /**
436
454
  * Find a document by ID with field projection
437
455
  * @param collection - Collection name
438
456
  * @param id - Document ID
439
457
  * @param selectFields - Fields to include in the result
440
458
  * @param excludeFields - Fields to exclude from the result
459
+ * @param transactionId - Read within a transaction (read-your-writes)
441
460
  */
442
- findByIdWithProjection(collection: string, id: string, selectFields?: string[], excludeFields?: string[]): Promise<Record>;
461
+ findByIdWithProjection(collection: string, id: string, selectFields?: string[], excludeFields?: string[], transactionId?: string): Promise<Record>;
443
462
  /**
444
463
  * Update a document
445
464
  * @param collection - Collection name
@@ -514,6 +533,10 @@ export declare class EkoDBClient {
514
533
  * Delete a key
515
534
  */
516
535
  kvDelete(key: string): Promise<void>;
536
+ /**
537
+ * Clear the entire KV store (all keys in the namespace).
538
+ */
539
+ kvClear(): Promise<void>;
517
540
  /**
518
541
  * Batch get multiple keys
519
542
  * @param keys - Array of keys to retrieve
@@ -560,7 +583,18 @@ export declare class EkoDBClient {
560
583
  include_expired?: boolean;
561
584
  }): Promise<any[]>;
562
585
  /**
563
- * Begin a new transaction
586
+ * Begin a new transaction.
587
+ *
588
+ * Transactions are buffered: statements issued with this `transactionId`
589
+ * (passed via the `transactionId` option on insert/update/delete/find/…) are
590
+ * staged and applied atomically only at {@link commitTransaction}. They are
591
+ * invisible to everyone else until commit, and visible to this transaction's
592
+ * own reads (read-your-writes) only when those reads also carry the
593
+ * `transactionId`. {@link rollbackTransaction} discards the staged writes.
594
+ * `commitTransaction` may reject with a conflict (HTTP 409) if a record this
595
+ * transaction read or wrote was changed by another committed transaction —
596
+ * retry the transaction in that case.
597
+ *
564
598
  * @param isolationLevel - Transaction isolation level (default: "ReadCommitted")
565
599
  * @returns Transaction ID
566
600
  */
@@ -580,10 +614,23 @@ export declare class EkoDBClient {
580
614
  */
581
615
  commitTransaction(transactionId: string): Promise<void>;
582
616
  /**
583
- * Rollback a transaction
617
+ * Rollback a transaction (discards all staged writes; nothing was applied).
584
618
  * @param transactionId - The transaction ID to rollback
585
619
  */
586
620
  rollbackTransaction(transactionId: string): Promise<void>;
621
+ /**
622
+ * Create a savepoint within a transaction. A later
623
+ * {@link rollbackToSavepoint} discards everything staged after it.
624
+ */
625
+ createSavepoint(transactionId: string, name: string): Promise<void>;
626
+ /**
627
+ * Roll the transaction back to a savepoint, discarding writes staged after it.
628
+ */
629
+ rollbackToSavepoint(transactionId: string, name: string): Promise<void>;
630
+ /**
631
+ * Release (forget) a savepoint. Staged work is unaffected.
632
+ */
633
+ releaseSavepoint(transactionId: string, name: string): Promise<void>;
587
634
  /**
588
635
  * Insert or update a record (upsert operation)
589
636
  *
@@ -672,6 +719,10 @@ export declare class EkoDBClient {
672
719
  * List all collections
673
720
  */
674
721
  listCollections(): Promise<string[]>;
722
+ /**
723
+ * List collections, excluding internal chat/system collections.
724
+ */
725
+ listUserCollections(): Promise<string[]>;
675
726
  /**
676
727
  * Delete a collection
677
728
  */
@@ -844,6 +895,17 @@ export declare class EkoDBClient {
844
895
  * Unblocks ekoDB's tool loop so it can feed the result to the LLM.
845
896
  */
846
897
  submitChatToolResult(chatId: string, callId: string, success: boolean, result?: any, error?: string): Promise<void>;
898
+ /**
899
+ * Send a client tool keepalive (liveness ping) for an in-flight SSE chat stream.
900
+ *
901
+ * This is NOT a result: it does not unblock the tool loop or feed anything to the
902
+ * LLM. It simply resets the server's per-tool wait deadline (governed by
903
+ * `client_tool_timeout_secs`, default 60s) so that slow user confirmations or
904
+ * long-running client tools don't get the turn timed out before
905
+ * {@link submitChatToolResult} arrives. Send it periodically while a client tool
906
+ * is still working. See ekoDB#530.
907
+ */
908
+ submitChatToolKeepalive(chatId: string, callId: string): Promise<void>;
847
909
  /**
848
910
  * Send a message in an existing chat session via SSE streaming.
849
911
  *
@@ -1335,6 +1397,13 @@ export declare class WebSocketClient {
1335
1397
  private ws;
1336
1398
  private dispatcherRunning;
1337
1399
  private schemaCache;
1400
+ /**
1401
+ * Per-connection wire format, set by negotiateFormat() on every (re)connect:
1402
+ * true once the server has Welcomed msgpack, so frames are sent/received as
1403
+ * binary msgpack; false (JSON text) otherwise, including against an older
1404
+ * server that never Welcomes. Keeps the transport fully back-compatible.
1405
+ */
1406
+ private binary;
1338
1407
  private autoReconnect;
1339
1408
  private reconnectInitialDelayMs;
1340
1409
  private reconnectMaxDelayMs;
@@ -1373,6 +1442,21 @@ export declare class WebSocketClient {
1373
1442
  */
1374
1443
  private ensureConnected;
1375
1444
  private openSocket;
1445
+ /**
1446
+ * Additive capability handshake: offer msgpack and, if the server Welcomes
1447
+ * it, switch this connection to binary msgpack frames; otherwise stay on JSON
1448
+ * text. The Welcome (a text frame) is read with a one-shot listener and a
1449
+ * timeout so an older server that never answers — or answers with an Error —
1450
+ * simply leaves the connection on JSON. Best-effort and never throws: JSON
1451
+ * always works.
1452
+ */
1453
+ private negotiateFormat;
1454
+ /**
1455
+ * Send a request object on the active socket using the negotiated format:
1456
+ * binary msgpack when the server Welcomed it, JSON text otherwise. The single
1457
+ * write point so every request honors the negotiated transport.
1458
+ */
1459
+ private sendFrame;
1376
1460
  private spawnDispatcher;
1377
1461
  /**
1378
1462
  * Reject in-flight requests and tear down the dead socket. If the close was
@@ -1419,6 +1503,11 @@ export declare class WebSocketClient {
1419
1503
  * Send a tool result back to the server during a chat stream.
1420
1504
  */
1421
1505
  sendToolResult(chatId: string, callId: string, success: boolean, result?: any, error?: string): Promise<void>;
1506
+ /**
1507
+ * Cancel an in-flight streaming chat. Fire-and-forget: tells the server to
1508
+ * stop generating tokens for the given chat.
1509
+ */
1510
+ cancelChat(chatId: string): Promise<void>;
1422
1511
  /**
1423
1512
  * Stateless raw LLM completion via WebSocket.
1424
1513
  *