@ekodb/ekodb-client 0.20.0 → 0.21.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
  */
@@ -1335,6 +1386,13 @@ export declare class WebSocketClient {
1335
1386
  private ws;
1336
1387
  private dispatcherRunning;
1337
1388
  private schemaCache;
1389
+ /**
1390
+ * Per-connection wire format, set by negotiateFormat() on every (re)connect:
1391
+ * true once the server has Welcomed msgpack, so frames are sent/received as
1392
+ * binary msgpack; false (JSON text) otherwise, including against an older
1393
+ * server that never Welcomes. Keeps the transport fully back-compatible.
1394
+ */
1395
+ private binary;
1338
1396
  private autoReconnect;
1339
1397
  private reconnectInitialDelayMs;
1340
1398
  private reconnectMaxDelayMs;
@@ -1373,6 +1431,21 @@ export declare class WebSocketClient {
1373
1431
  */
1374
1432
  private ensureConnected;
1375
1433
  private openSocket;
1434
+ /**
1435
+ * Additive capability handshake: offer msgpack and, if the server Welcomes
1436
+ * it, switch this connection to binary msgpack frames; otherwise stay on JSON
1437
+ * text. The Welcome (a text frame) is read with a one-shot listener and a
1438
+ * timeout so an older server that never answers — or answers with an Error —
1439
+ * simply leaves the connection on JSON. Best-effort and never throws: JSON
1440
+ * always works.
1441
+ */
1442
+ private negotiateFormat;
1443
+ /**
1444
+ * Send a request object on the active socket using the negotiated format:
1445
+ * binary msgpack when the server Welcomed it, JSON text otherwise. The single
1446
+ * write point so every request honors the negotiated transport.
1447
+ */
1448
+ private sendFrame;
1376
1449
  private spawnDispatcher;
1377
1450
  /**
1378
1451
  * Reject in-flight requests and tear down the dead socket. If the close was
@@ -1419,6 +1492,11 @@ export declare class WebSocketClient {
1419
1492
  * Send a tool result back to the server during a chat stream.
1420
1493
  */
1421
1494
  sendToolResult(chatId: string, callId: string, success: boolean, result?: any, error?: string): Promise<void>;
1495
+ /**
1496
+ * Cancel an in-flight streaming chat. Fire-and-forget: tells the server to
1497
+ * stop generating tokens for the given chat.
1498
+ */
1499
+ cancelChat(chatId: string): Promise<void>;
1422
1500
  /**
1423
1501
  * Stateless raw LLM completion via WebSocket.
1424
1502
  *