@ekodb/ekodb-client 0.18.2 → 0.20.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 +0 -1
- package/dist/client.d.ts +135 -5
- package/dist/client.js +418 -64
- package/dist/client.test.js +152 -0
- package/dist/functions.test.d.ts +1 -2
- package/dist/functions.test.js +1 -2
- package/dist/index.d.ts +1 -1
- package/dist/query-builder.d.ts +0 -4
- package/dist/query-builder.js +2 -14
- package/dist/query-builder.test.js +0 -5
- package/dist/utils.js +7 -1
- package/dist/utils.test.js +4 -0
- package/dist/websocket.test.js +180 -0
- package/package.json +2 -2
- package/src/client.test.ts +195 -1
- package/src/client.ts +525 -66
- package/src/functions.test.ts +1 -2
- package/src/index.ts +2 -0
- package/src/query-builder.test.ts +0 -7
- package/src/query-builder.ts +2 -14
- package/src/utils.test.ts +5 -0
- package/src/utils.ts +9 -1
- package/src/websocket.test.ts +273 -0
package/README.md
CHANGED
|
@@ -269,7 +269,6 @@ const joinResults = await client.find("users", multiQuery);
|
|
|
269
269
|
- `.contains(field, value)` - String contains
|
|
270
270
|
- `.startsWith(field, value)` - String starts with
|
|
271
271
|
- `.endsWith(field, value)` - String ends with
|
|
272
|
-
- `.regex(field, pattern)` - Regex match
|
|
273
272
|
- `.sortAsc(field)` / `.sortDesc(field)` - Sorting
|
|
274
273
|
- `.limit(n)` / `.skip(n)` - Pagination
|
|
275
274
|
- `.join(joinConfig)` - Add join configuration
|
package/dist/client.d.ts
CHANGED
|
@@ -258,6 +258,22 @@ export interface ChatModels {
|
|
|
258
258
|
anthropic: string[];
|
|
259
259
|
perplexity: string[];
|
|
260
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Request to compact a chat session's history on demand.
|
|
263
|
+
*/
|
|
264
|
+
export interface CompactChatRequest {
|
|
265
|
+
keep_recent?: number;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Result of an on-demand chat history compaction.
|
|
269
|
+
*/
|
|
270
|
+
export interface CompactChatResponse {
|
|
271
|
+
folded: number;
|
|
272
|
+
kept_recent: number;
|
|
273
|
+
summary_chars: number;
|
|
274
|
+
summary_message_id: string | null;
|
|
275
|
+
already_compact: boolean;
|
|
276
|
+
}
|
|
261
277
|
/**
|
|
262
278
|
* Request to generate embeddings
|
|
263
279
|
*/
|
|
@@ -358,6 +374,20 @@ export declare class EkoDBClient {
|
|
|
358
374
|
* Sleep for a specified number of seconds
|
|
359
375
|
*/
|
|
360
376
|
private sleep;
|
|
377
|
+
/**
|
|
378
|
+
* Parse a `Retry-After` header into a non-negative delay in seconds.
|
|
379
|
+
*
|
|
380
|
+
* Per RFC 9110 the value is either delay-seconds (an integer) or an
|
|
381
|
+
* HTTP-date. Anything that doesn't resolve to a finite, non-negative number
|
|
382
|
+
* (missing header, garbage, a past date) falls back to `defaultSecs`.
|
|
383
|
+
*/
|
|
384
|
+
private parseRetryAfter;
|
|
385
|
+
/**
|
|
386
|
+
* Backoff delay (in seconds) for a 0-indexed retry attempt: a capped
|
|
387
|
+
* exponential schedule (0.2s → 5s) with full jitter, so concurrent clients
|
|
388
|
+
* don't retry in lockstep. Returns a value in [d/2, d].
|
|
389
|
+
*/
|
|
390
|
+
private backoffSeconds;
|
|
361
391
|
/**
|
|
362
392
|
* Helper to determine if a path should use JSON
|
|
363
393
|
* Only CRUD operations (insert/update/delete/batch) use MessagePack
|
|
@@ -866,6 +896,17 @@ export declare class EkoDBClient {
|
|
|
866
896
|
* Toggle the "forgotten" status of a message
|
|
867
897
|
*/
|
|
868
898
|
toggleForgottenMessage(sessionId: string, messageId: string, forgotten: boolean): Promise<void>;
|
|
899
|
+
/**
|
|
900
|
+
* Compact a chat session's history on demand.
|
|
901
|
+
*
|
|
902
|
+
* Folds older messages into a summary while preserving the most recent
|
|
903
|
+
* messages verbatim, reducing context size for long-running sessions.
|
|
904
|
+
*
|
|
905
|
+
* @param chatId - Chat session ID
|
|
906
|
+
* @param keepRecent - Number of recent messages to preserve verbatim (optional)
|
|
907
|
+
* @returns Compaction result with counts and the summary message ID
|
|
908
|
+
*/
|
|
909
|
+
compactChat(chatId: string, keepRecent?: number): Promise<CompactChatResponse>;
|
|
869
910
|
/**
|
|
870
911
|
* Merge multiple chat sessions into one
|
|
871
912
|
*/
|
|
@@ -1063,9 +1104,17 @@ export declare class EkoDBClient {
|
|
|
1063
1104
|
filterValue?: string;
|
|
1064
1105
|
}): EventStream<MutationNotification>;
|
|
1065
1106
|
/**
|
|
1066
|
-
* Create a WebSocket client
|
|
1107
|
+
* Create a WebSocket client.
|
|
1108
|
+
*
|
|
1109
|
+
* The token is supplied as a provider bound to this client's
|
|
1110
|
+
* {@link getToken}, so every (re)connect re-evaluates (and proactively
|
|
1111
|
+
* refreshes) the auth token instead of snapshotting it once. This means a
|
|
1112
|
+
* reconnect after a token rotation uses the current token.
|
|
1113
|
+
*
|
|
1114
|
+
* @param wsURL - The WebSocket URL (e.g. `wss://host`); `/api/ws` is appended if absent.
|
|
1115
|
+
* @param options - Optional reconnect/timeout tunables.
|
|
1067
1116
|
*/
|
|
1068
|
-
websocket(wsURL: string): WebSocketClient;
|
|
1117
|
+
websocket(wsURL: string, options?: WebSocketClientOptions): WebSocketClient;
|
|
1069
1118
|
/**
|
|
1070
1119
|
* Generate embeddings for a single text
|
|
1071
1120
|
*
|
|
@@ -1209,6 +1258,35 @@ export interface SubscribeOptions {
|
|
|
1209
1258
|
filterField?: string;
|
|
1210
1259
|
filterValue?: string;
|
|
1211
1260
|
}
|
|
1261
|
+
/**
|
|
1262
|
+
* A token provider: either a static token string, or a (possibly async)
|
|
1263
|
+
* function that returns a fresh token. When a function is supplied it is
|
|
1264
|
+
* re-invoked on every (re)connect, so a rotated/refreshed token is always
|
|
1265
|
+
* used for the new socket instead of a stale snapshot captured once.
|
|
1266
|
+
*/
|
|
1267
|
+
export type TokenProvider = string | (() => string | null | Promise<string | null>);
|
|
1268
|
+
/** Tunables for the WebSocket client's reconnect + request-timeout behavior. */
|
|
1269
|
+
export interface WebSocketClientOptions {
|
|
1270
|
+
/**
|
|
1271
|
+
* Auto-reconnect after an unexpected socket close/error (not an explicit
|
|
1272
|
+
* `close()`/unsubscribe). Defaults to true.
|
|
1273
|
+
*/
|
|
1274
|
+
autoReconnect?: boolean;
|
|
1275
|
+
/** Initial backoff delay in ms before the first reconnect attempt. Default 200. */
|
|
1276
|
+
reconnectInitialDelayMs?: number;
|
|
1277
|
+
/** Maximum backoff delay in ms (the cap for exponential growth). Default 5000. */
|
|
1278
|
+
reconnectMaxDelayMs?: number;
|
|
1279
|
+
/**
|
|
1280
|
+
* Maximum number of consecutive reconnect attempts before giving up.
|
|
1281
|
+
* 0 or undefined means unlimited. Default unlimited.
|
|
1282
|
+
*/
|
|
1283
|
+
reconnectMaxAttempts?: number;
|
|
1284
|
+
/**
|
|
1285
|
+
* Per-request timeout in ms for request/response WS calls. If no response
|
|
1286
|
+
* arrives in this window the pending promise rejects. Default 30000.
|
|
1287
|
+
*/
|
|
1288
|
+
requestTimeoutMs?: number;
|
|
1289
|
+
}
|
|
1212
1290
|
/** EventEmitter-like interface for subscriptions and chat streams. */
|
|
1213
1291
|
export declare class EventStream<_T = unknown> {
|
|
1214
1292
|
private listeners;
|
|
@@ -1253,24 +1331,67 @@ export declare class SchemaCache {
|
|
|
1253
1331
|
export declare function extractRecordId(record: Record, extraCandidates?: string[]): string | undefined;
|
|
1254
1332
|
export declare class WebSocketClient {
|
|
1255
1333
|
private wsURL;
|
|
1256
|
-
private
|
|
1334
|
+
private tokenProvider;
|
|
1257
1335
|
private ws;
|
|
1258
1336
|
private dispatcherRunning;
|
|
1259
1337
|
private schemaCache;
|
|
1338
|
+
private autoReconnect;
|
|
1339
|
+
private reconnectInitialDelayMs;
|
|
1340
|
+
private reconnectMaxDelayMs;
|
|
1341
|
+
private reconnectMaxAttempts;
|
|
1342
|
+
private requestTimeoutMs;
|
|
1343
|
+
/** Set while close() is in progress so the close handler doesn't reconnect. */
|
|
1344
|
+
private closed;
|
|
1345
|
+
private reconnectAttempts;
|
|
1346
|
+
private reconnecting;
|
|
1347
|
+
private connectPromise;
|
|
1260
1348
|
private pendingRequests;
|
|
1261
1349
|
private subscriptions;
|
|
1350
|
+
/** Bookkeeping so subscriptions can be replayed on reconnect. */
|
|
1351
|
+
private subscriptionParams;
|
|
1262
1352
|
private chatStreams;
|
|
1263
1353
|
private registerToolsAck;
|
|
1264
|
-
|
|
1354
|
+
/**
|
|
1355
|
+
* @param wsURL - WebSocket URL; `/api/ws` is appended if absent.
|
|
1356
|
+
* @param token - A static token string OR a {@link TokenProvider} function
|
|
1357
|
+
* re-evaluated on every (re)connect (so a refreshed token is used after a drop).
|
|
1358
|
+
* @param options - Optional reconnect/timeout tunables.
|
|
1359
|
+
*/
|
|
1360
|
+
constructor(wsURL: string, token: TokenProvider, options?: WebSocketClientOptions);
|
|
1265
1361
|
private messageCounter;
|
|
1266
1362
|
private genMessageId;
|
|
1267
1363
|
/**
|
|
1268
|
-
*
|
|
1364
|
+
* Compute the capped exponential backoff (with jitter) for a reconnect
|
|
1365
|
+
* attempt. attempt 0 -> ~initial, growing x2 each time up to the max cap.
|
|
1366
|
+
* Jitter is +/-25% to avoid thundering-herd reconnect storms.
|
|
1367
|
+
* @internal exposed for testing
|
|
1368
|
+
*/
|
|
1369
|
+
computeBackoff(attempt: number): number;
|
|
1370
|
+
/**
|
|
1371
|
+
* Connect and start the dispatcher. Re-evaluates the token provider so the
|
|
1372
|
+
* current/refreshed token is used for this socket.
|
|
1269
1373
|
*/
|
|
1270
1374
|
private ensureConnected;
|
|
1375
|
+
private openSocket;
|
|
1271
1376
|
private spawnDispatcher;
|
|
1377
|
+
/**
|
|
1378
|
+
* Reject in-flight requests and tear down the dead socket. If the close was
|
|
1379
|
+
* unexpected (not an explicit `close()`) and auto-reconnect is enabled,
|
|
1380
|
+
* schedule a reconnect that re-sends the active subscriptions.
|
|
1381
|
+
*/
|
|
1382
|
+
private handleDisconnect;
|
|
1383
|
+
/**
|
|
1384
|
+
* Reconnect with capped exponential backoff + jitter, then re-send the
|
|
1385
|
+
* subscribe messages for every active subscription so the SAME EventStream
|
|
1386
|
+
* keeps delivering mutations after a transient drop.
|
|
1387
|
+
*/
|
|
1388
|
+
private scheduleReconnect;
|
|
1389
|
+
/** Re-send Subscribe frames for every tracked subscription after a reconnect. */
|
|
1390
|
+
private resubscribeAll;
|
|
1272
1391
|
private routeMessage;
|
|
1273
1392
|
private sendRequest;
|
|
1393
|
+
/** Resolve/reject a pending request, clearing its timeout timer. */
|
|
1394
|
+
private settlePending;
|
|
1274
1395
|
/**
|
|
1275
1396
|
* Find all records in a collection via WebSocket.
|
|
1276
1397
|
*/
|
|
@@ -1280,6 +1401,11 @@ export declare class WebSocketClient {
|
|
|
1280
1401
|
* Returns an EventStream that emits "mutation" events.
|
|
1281
1402
|
*/
|
|
1282
1403
|
subscribe(collection: string, options?: SubscribeOptions): Promise<EventStream<MutationNotification>>;
|
|
1404
|
+
/**
|
|
1405
|
+
* Unsubscribe from a collection's mutation notifications. This is an
|
|
1406
|
+
* intentional teardown, so the subscription is NOT replayed on reconnect.
|
|
1407
|
+
*/
|
|
1408
|
+
unsubscribe(collection: string): void;
|
|
1283
1409
|
/**
|
|
1284
1410
|
* Send a chat message and receive a streaming response.
|
|
1285
1411
|
* Returns an EventStream that emits "event" with ChatStreamEvent objects.
|
|
@@ -1342,6 +1468,10 @@ export declare class WebSocketClient {
|
|
|
1342
1468
|
deleteCollection(name: string): Promise<void>;
|
|
1343
1469
|
/**
|
|
1344
1470
|
* Close the WebSocket connection.
|
|
1471
|
+
*
|
|
1472
|
+
* This is an INTENTIONAL close: it disables auto-reconnect, rejects any
|
|
1473
|
+
* in-flight requests, and tears down all subscriptions/chat streams so
|
|
1474
|
+
* nothing is replayed afterward.
|
|
1345
1475
|
*/
|
|
1346
1476
|
close(): void;
|
|
1347
1477
|
}
|