@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 +28 -0
- package/dist/client.d.ts +101 -12
- package/dist/client.js +269 -56
- package/dist/client.test.js +206 -0
- package/dist/search.d.ts +12 -0
- package/dist/search.js +9 -0
- package/dist/websocket.test.js +159 -5
- package/package.json +1 -1
- package/src/client.test.ts +287 -0
- package/src/client.ts +367 -65
- package/src/search.ts +18 -0
- package/src/websocket.test.ts +225 -5
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
|
|
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
|
|
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
|
*
|