@ekodb/ekodb-client 0.2.1 → 0.3.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/dist/client.d.ts +22 -3
- package/dist/client.js +103 -39
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/package.json +2 -1
- package/src/client.ts +185 -25
- package/src/index.ts +1 -0
package/dist/client.d.ts
CHANGED
|
@@ -7,6 +7,15 @@ import { Schema, SchemaBuilder, CollectionMetadata } from "./schema";
|
|
|
7
7
|
export interface Record {
|
|
8
8
|
[key: string]: any;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Serialization format for client-server communication
|
|
12
|
+
*/
|
|
13
|
+
export declare enum SerializationFormat {
|
|
14
|
+
/** JSON format (default, human-readable) */
|
|
15
|
+
Json = "Json",
|
|
16
|
+
/** MessagePack format (binary, 2-3x faster) */
|
|
17
|
+
MessagePack = "MessagePack"
|
|
18
|
+
}
|
|
10
19
|
/**
|
|
11
20
|
* Rate limit information from the server
|
|
12
21
|
*/
|
|
@@ -32,6 +41,8 @@ export interface ClientConfig {
|
|
|
32
41
|
maxRetries?: number;
|
|
33
42
|
/** Request timeout in milliseconds (default: 30000) */
|
|
34
43
|
timeout?: number;
|
|
44
|
+
/** Serialization format (default: MessagePack for best performance, use Json for debugging) */
|
|
45
|
+
format?: SerializationFormat;
|
|
35
46
|
}
|
|
36
47
|
/**
|
|
37
48
|
* Rate limit error
|
|
@@ -155,6 +166,7 @@ export declare class EkoDBClient {
|
|
|
155
166
|
private shouldRetry;
|
|
156
167
|
private maxRetries;
|
|
157
168
|
private timeout;
|
|
169
|
+
private format;
|
|
158
170
|
private rateLimitInfo;
|
|
159
171
|
constructor(config: string | ClientConfig, apiKey?: string);
|
|
160
172
|
/**
|
|
@@ -181,6 +193,12 @@ export declare class EkoDBClient {
|
|
|
181
193
|
* Sleep for a specified number of seconds
|
|
182
194
|
*/
|
|
183
195
|
private sleep;
|
|
196
|
+
/**
|
|
197
|
+
* Helper to determine if a path should use JSON
|
|
198
|
+
* Only CRUD operations (insert/update/delete/batch) use MessagePack
|
|
199
|
+
* Everything else uses JSON for compatibility
|
|
200
|
+
*/
|
|
201
|
+
private shouldUseJSON;
|
|
184
202
|
/**
|
|
185
203
|
* Make an HTTP request to the ekoDB API with retry logic
|
|
186
204
|
*/
|
|
@@ -227,18 +245,19 @@ export declare class EkoDBClient {
|
|
|
227
245
|
/**
|
|
228
246
|
* Batch insert multiple documents
|
|
229
247
|
*/
|
|
230
|
-
batchInsert(collection: string, records: Record[]): Promise<
|
|
248
|
+
batchInsert(collection: string, records: Record[], bypassRipple?: boolean): Promise<BatchOperationResult>;
|
|
231
249
|
/**
|
|
232
250
|
* Batch update multiple documents
|
|
233
251
|
*/
|
|
234
252
|
batchUpdate(collection: string, updates: Array<{
|
|
235
253
|
id: string;
|
|
236
254
|
data: Record;
|
|
237
|
-
|
|
255
|
+
bypassRipple?: boolean;
|
|
256
|
+
}>): Promise<BatchOperationResult>;
|
|
238
257
|
/**
|
|
239
258
|
* Batch delete multiple documents
|
|
240
259
|
*/
|
|
241
|
-
batchDelete(collection: string, ids: string[]): Promise<
|
|
260
|
+
batchDelete(collection: string, ids: string[], bypassRipple?: boolean): Promise<BatchOperationResult>;
|
|
242
261
|
/**
|
|
243
262
|
* Set a key-value pair
|
|
244
263
|
*/
|
package/dist/client.js
CHANGED
|
@@ -36,10 +36,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.WebSocketClient = exports.EkoDBClient = exports.MergeStrategy = exports.RateLimitError = void 0;
|
|
39
|
+
exports.WebSocketClient = exports.EkoDBClient = exports.MergeStrategy = exports.RateLimitError = exports.SerializationFormat = void 0;
|
|
40
|
+
const msgpack_1 = require("@msgpack/msgpack");
|
|
40
41
|
const query_builder_1 = require("./query-builder");
|
|
41
42
|
const search_1 = require("./search");
|
|
42
43
|
const schema_1 = require("./schema");
|
|
44
|
+
/**
|
|
45
|
+
* Serialization format for client-server communication
|
|
46
|
+
*/
|
|
47
|
+
var SerializationFormat;
|
|
48
|
+
(function (SerializationFormat) {
|
|
49
|
+
/** JSON format (default, human-readable) */
|
|
50
|
+
SerializationFormat["Json"] = "Json";
|
|
51
|
+
/** MessagePack format (binary, 2-3x faster) */
|
|
52
|
+
SerializationFormat["MessagePack"] = "MessagePack";
|
|
53
|
+
})(SerializationFormat || (exports.SerializationFormat = SerializationFormat = {}));
|
|
43
54
|
/**
|
|
44
55
|
* Rate limit error
|
|
45
56
|
*/
|
|
@@ -68,6 +79,7 @@ class EkoDBClient {
|
|
|
68
79
|
this.shouldRetry = true;
|
|
69
80
|
this.maxRetries = 3;
|
|
70
81
|
this.timeout = 30000;
|
|
82
|
+
this.format = SerializationFormat.MessagePack; // Default to MessagePack for 2-3x performance
|
|
71
83
|
}
|
|
72
84
|
else {
|
|
73
85
|
this.baseURL = config.baseURL;
|
|
@@ -75,6 +87,7 @@ class EkoDBClient {
|
|
|
75
87
|
this.shouldRetry = config.shouldRetry ?? true;
|
|
76
88
|
this.maxRetries = config.maxRetries ?? 3;
|
|
77
89
|
this.timeout = config.timeout ?? 30000;
|
|
90
|
+
this.format = config.format ?? SerializationFormat.MessagePack; // Default to MessagePack for 2-3x performance
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
/**
|
|
@@ -138,29 +151,72 @@ class EkoDBClient {
|
|
|
138
151
|
sleep(seconds) {
|
|
139
152
|
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
140
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Helper to determine if a path should use JSON
|
|
156
|
+
* Only CRUD operations (insert/update/delete/batch) use MessagePack
|
|
157
|
+
* Everything else uses JSON for compatibility
|
|
158
|
+
*/
|
|
159
|
+
shouldUseJSON(path) {
|
|
160
|
+
// ONLY these operations support MessagePack
|
|
161
|
+
const msgpackPaths = [
|
|
162
|
+
"/api/insert/",
|
|
163
|
+
"/api/batch_insert/",
|
|
164
|
+
"/api/update/",
|
|
165
|
+
"/api/batch_update/",
|
|
166
|
+
"/api/delete/",
|
|
167
|
+
"/api/batch_delete/",
|
|
168
|
+
];
|
|
169
|
+
// Check if path starts with any MessagePack-supported operation
|
|
170
|
+
for (const prefix of msgpackPaths) {
|
|
171
|
+
if (path.startsWith(prefix)) {
|
|
172
|
+
return false; // Use MessagePack
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Everything else uses JSON
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
141
178
|
/**
|
|
142
179
|
* Make an HTTP request to the ekoDB API with retry logic
|
|
143
180
|
*/
|
|
144
|
-
async makeRequest(method, path, data, attempt = 0) {
|
|
181
|
+
async makeRequest(method, path, data, attempt = 0, forceJson = false) {
|
|
145
182
|
if (!this.token) {
|
|
146
183
|
await this.refreshToken();
|
|
147
184
|
}
|
|
185
|
+
// Determine content type and serialization based on path
|
|
186
|
+
// Only CRUD operations support MessagePack, everything else uses JSON
|
|
187
|
+
const shouldForceJson = forceJson || this.shouldUseJSON(path);
|
|
188
|
+
const isMessagePack = !shouldForceJson && this.format === SerializationFormat.MessagePack;
|
|
189
|
+
const contentType = isMessagePack
|
|
190
|
+
? "application/msgpack"
|
|
191
|
+
: "application/json";
|
|
192
|
+
// Note: Modern fetch API automatically handles gzip/deflate decompression
|
|
193
|
+
// when server sends Content-Encoding header. No additional configuration needed.
|
|
148
194
|
const options = {
|
|
149
195
|
method,
|
|
150
196
|
headers: {
|
|
151
197
|
Authorization: `Bearer ${this.token}`,
|
|
152
|
-
"Content-Type":
|
|
198
|
+
"Content-Type": contentType,
|
|
199
|
+
Accept: contentType,
|
|
153
200
|
},
|
|
154
201
|
};
|
|
155
202
|
if (data) {
|
|
156
|
-
options.body =
|
|
203
|
+
options.body = isMessagePack
|
|
204
|
+
? (0, msgpack_1.encode)(data)
|
|
205
|
+
: JSON.stringify(data);
|
|
157
206
|
}
|
|
158
207
|
try {
|
|
159
208
|
const response = await fetch(`${this.baseURL}${path}`, options);
|
|
160
209
|
// Extract rate limit info from successful responses
|
|
161
210
|
if (response.ok) {
|
|
162
211
|
this.extractRateLimitInfo(response);
|
|
163
|
-
|
|
212
|
+
// Deserialize based on format
|
|
213
|
+
if (isMessagePack) {
|
|
214
|
+
const buffer = await response.arrayBuffer();
|
|
215
|
+
return (0, msgpack_1.decode)(new Uint8Array(buffer));
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
return response.json();
|
|
219
|
+
}
|
|
164
220
|
}
|
|
165
221
|
// Handle rate limiting (429)
|
|
166
222
|
if (response.status === 429) {
|
|
@@ -168,7 +224,7 @@ class EkoDBClient {
|
|
|
168
224
|
if (this.shouldRetry && attempt < this.maxRetries) {
|
|
169
225
|
console.log(`Rate limited. Retrying after ${retryAfter} seconds...`);
|
|
170
226
|
await this.sleep(retryAfter);
|
|
171
|
-
return this.makeRequest(method, path, data, attempt + 1);
|
|
227
|
+
return this.makeRequest(method, path, data, attempt + 1, forceJson);
|
|
172
228
|
}
|
|
173
229
|
throw new RateLimitError(retryAfter);
|
|
174
230
|
}
|
|
@@ -179,7 +235,7 @@ class EkoDBClient {
|
|
|
179
235
|
const retryDelay = 10;
|
|
180
236
|
console.log(`Service unavailable. Retrying after ${retryDelay} seconds...`);
|
|
181
237
|
await this.sleep(retryDelay);
|
|
182
|
-
return this.makeRequest(method, path, data, attempt + 1);
|
|
238
|
+
return this.makeRequest(method, path, data, attempt + 1, forceJson);
|
|
183
239
|
}
|
|
184
240
|
// Handle other errors
|
|
185
241
|
const text = await response.text();
|
|
@@ -193,7 +249,7 @@ class EkoDBClient {
|
|
|
193
249
|
const retryDelay = 3;
|
|
194
250
|
console.log(`Network error. Retrying after ${retryDelay} seconds...`);
|
|
195
251
|
await this.sleep(retryDelay);
|
|
196
|
-
return this.makeRequest(method, path, data, attempt + 1);
|
|
252
|
+
return this.makeRequest(method, path, data, attempt + 1, forceJson);
|
|
197
253
|
}
|
|
198
254
|
throw error;
|
|
199
255
|
}
|
|
@@ -255,57 +311,65 @@ class EkoDBClient {
|
|
|
255
311
|
/**
|
|
256
312
|
* Batch insert multiple documents
|
|
257
313
|
*/
|
|
258
|
-
async batchInsert(collection, records) {
|
|
259
|
-
const inserts = records.map((data) => ({
|
|
260
|
-
|
|
261
|
-
|
|
314
|
+
async batchInsert(collection, records, bypassRipple) {
|
|
315
|
+
const inserts = records.map((data) => ({
|
|
316
|
+
data,
|
|
317
|
+
bypass_ripple: bypassRipple,
|
|
318
|
+
}));
|
|
319
|
+
return this.makeRequest("POST", `/api/batch/insert/${collection}`, { inserts });
|
|
262
320
|
}
|
|
263
321
|
/**
|
|
264
322
|
* Batch update multiple documents
|
|
265
323
|
*/
|
|
266
324
|
async batchUpdate(collection, updates) {
|
|
267
|
-
const
|
|
268
|
-
|
|
325
|
+
const formattedUpdates = updates.map((u) => ({
|
|
326
|
+
id: u.id,
|
|
327
|
+
data: u.data,
|
|
328
|
+
bypass_ripple: u.bypassRipple,
|
|
329
|
+
}));
|
|
330
|
+
return this.makeRequest("PUT", `/api/batch/update/${collection}`, { updates: formattedUpdates });
|
|
269
331
|
}
|
|
270
332
|
/**
|
|
271
333
|
* Batch delete multiple documents
|
|
272
334
|
*/
|
|
273
|
-
async batchDelete(collection, ids) {
|
|
274
|
-
const deletes = ids.map((id) => ({
|
|
275
|
-
|
|
276
|
-
|
|
335
|
+
async batchDelete(collection, ids, bypassRipple) {
|
|
336
|
+
const deletes = ids.map((id) => ({
|
|
337
|
+
id: id,
|
|
338
|
+
bypass_ripple: bypassRipple,
|
|
339
|
+
}));
|
|
340
|
+
return this.makeRequest("DELETE", `/api/batch/delete/${collection}`, { deletes });
|
|
277
341
|
}
|
|
278
342
|
/**
|
|
279
343
|
* Set a key-value pair
|
|
280
344
|
*/
|
|
281
345
|
async kvSet(key, value) {
|
|
282
|
-
await this.makeRequest("POST", `/api/kv/set/${encodeURIComponent(key)}`, { value });
|
|
346
|
+
await this.makeRequest("POST", `/api/kv/set/${encodeURIComponent(key)}`, { value }, 0, true);
|
|
283
347
|
}
|
|
284
348
|
/**
|
|
285
349
|
* Get a value by key
|
|
286
350
|
*/
|
|
287
351
|
async kvGet(key) {
|
|
288
|
-
const result = await this.makeRequest("GET", `/api/kv/get/${encodeURIComponent(key)}
|
|
352
|
+
const result = await this.makeRequest("GET", `/api/kv/get/${encodeURIComponent(key)}`, undefined, 0, true);
|
|
289
353
|
return result.value;
|
|
290
354
|
}
|
|
291
355
|
/**
|
|
292
356
|
* Delete a key
|
|
293
357
|
*/
|
|
294
358
|
async kvDelete(key) {
|
|
295
|
-
await this.makeRequest("DELETE", `/api/kv/delete/${encodeURIComponent(key)}
|
|
359
|
+
await this.makeRequest("DELETE", `/api/kv/delete/${encodeURIComponent(key)}`, undefined, 0, true);
|
|
296
360
|
}
|
|
297
361
|
/**
|
|
298
362
|
* List all collections
|
|
299
363
|
*/
|
|
300
364
|
async listCollections() {
|
|
301
|
-
const result = await this.makeRequest("GET", "/api/collections");
|
|
365
|
+
const result = await this.makeRequest("GET", "/api/collections", undefined, 0, true);
|
|
302
366
|
return result.collections;
|
|
303
367
|
}
|
|
304
368
|
/**
|
|
305
369
|
* Delete a collection
|
|
306
370
|
*/
|
|
307
371
|
async deleteCollection(collection) {
|
|
308
|
-
await this.makeRequest("DELETE", `/api/collections/${collection}
|
|
372
|
+
await this.makeRequest("DELETE", `/api/collections/${collection}`, undefined, 0, true);
|
|
309
373
|
}
|
|
310
374
|
/**
|
|
311
375
|
* Create a collection with schema
|
|
@@ -325,7 +389,7 @@ class EkoDBClient {
|
|
|
325
389
|
*/
|
|
326
390
|
async createCollection(collection, schema) {
|
|
327
391
|
const schemaObj = schema instanceof schema_1.SchemaBuilder ? schema.build() : schema;
|
|
328
|
-
await this.makeRequest("POST", `/api/collections/${collection}`, schemaObj);
|
|
392
|
+
await this.makeRequest("POST", `/api/collections/${collection}`, schemaObj, 0, true);
|
|
329
393
|
}
|
|
330
394
|
/**
|
|
331
395
|
* Get collection metadata and schema
|
|
@@ -334,7 +398,7 @@ class EkoDBClient {
|
|
|
334
398
|
* @returns Collection metadata including schema and analytics
|
|
335
399
|
*/
|
|
336
400
|
async getCollection(collection) {
|
|
337
|
-
return this.makeRequest("GET", `/api/collections/${collection}
|
|
401
|
+
return this.makeRequest("GET", `/api/collections/${collection}`, undefined, 0, true);
|
|
338
402
|
}
|
|
339
403
|
/**
|
|
340
404
|
* Get collection schema
|
|
@@ -383,26 +447,26 @@ class EkoDBClient {
|
|
|
383
447
|
const queryObj = searchQuery instanceof search_1.SearchQueryBuilder
|
|
384
448
|
? searchQuery.build()
|
|
385
449
|
: searchQuery;
|
|
386
|
-
return this.makeRequest("POST", `/api/search/${collection}`, queryObj);
|
|
450
|
+
return this.makeRequest("POST", `/api/search/${collection}`, queryObj, 0, true);
|
|
387
451
|
}
|
|
388
452
|
// ========== Chat Methods ==========
|
|
389
453
|
/**
|
|
390
454
|
* Create a new chat session
|
|
391
455
|
*/
|
|
392
456
|
async createChatSession(request) {
|
|
393
|
-
return this.makeRequest("POST", "/api/chat", request);
|
|
457
|
+
return this.makeRequest("POST", "/api/chat", request, 0, true);
|
|
394
458
|
}
|
|
395
459
|
/**
|
|
396
460
|
* Send a message in an existing chat session
|
|
397
461
|
*/
|
|
398
462
|
async chatMessage(sessionId, request) {
|
|
399
|
-
return this.makeRequest("POST", `/api/chat/${sessionId}/messages`, request);
|
|
463
|
+
return this.makeRequest("POST", `/api/chat/${sessionId}/messages`, request, 0, true);
|
|
400
464
|
}
|
|
401
465
|
/**
|
|
402
466
|
* Get a chat session by ID
|
|
403
467
|
*/
|
|
404
468
|
async getChatSession(sessionId) {
|
|
405
|
-
return this.makeRequest("GET", `/api/chat/${sessionId}
|
|
469
|
+
return this.makeRequest("GET", `/api/chat/${sessionId}`, undefined, 0, true);
|
|
406
470
|
}
|
|
407
471
|
/**
|
|
408
472
|
* List all chat sessions
|
|
@@ -417,7 +481,7 @@ class EkoDBClient {
|
|
|
417
481
|
params.append("sort", query.sort);
|
|
418
482
|
const queryString = params.toString();
|
|
419
483
|
const path = queryString ? `/api/chat?${queryString}` : "/api/chat";
|
|
420
|
-
return this.makeRequest("GET", path);
|
|
484
|
+
return this.makeRequest("GET", path, undefined, 0, true);
|
|
421
485
|
}
|
|
422
486
|
/**
|
|
423
487
|
* Get messages from a chat session
|
|
@@ -434,55 +498,55 @@ class EkoDBClient {
|
|
|
434
498
|
const path = queryString
|
|
435
499
|
? `/api/chat/${sessionId}/messages?${queryString}`
|
|
436
500
|
: `/api/chat/${sessionId}/messages`;
|
|
437
|
-
return this.makeRequest("GET", path);
|
|
501
|
+
return this.makeRequest("GET", path, undefined, 0, true);
|
|
438
502
|
}
|
|
439
503
|
/**
|
|
440
504
|
* Update a chat session
|
|
441
505
|
*/
|
|
442
506
|
async updateChatSession(sessionId, request) {
|
|
443
|
-
return this.makeRequest("PUT", `/api/chat/${sessionId}`, request);
|
|
507
|
+
return this.makeRequest("PUT", `/api/chat/${sessionId}`, request, 0, true);
|
|
444
508
|
}
|
|
445
509
|
/**
|
|
446
510
|
* Branch a chat session
|
|
447
511
|
*/
|
|
448
512
|
async branchChatSession(request) {
|
|
449
|
-
return this.makeRequest("POST", "/api/chat/branch", request);
|
|
513
|
+
return this.makeRequest("POST", "/api/chat/branch", request, 0, true);
|
|
450
514
|
}
|
|
451
515
|
/**
|
|
452
516
|
* Delete a chat session
|
|
453
517
|
*/
|
|
454
518
|
async deleteChatSession(sessionId) {
|
|
455
|
-
await this.makeRequest("DELETE", `/api/chat/${sessionId}
|
|
519
|
+
await this.makeRequest("DELETE", `/api/chat/${sessionId}`, undefined, 0, true);
|
|
456
520
|
}
|
|
457
521
|
/**
|
|
458
522
|
* Regenerate an AI response message
|
|
459
523
|
*/
|
|
460
524
|
async regenerateMessage(sessionId, messageId) {
|
|
461
|
-
return this.makeRequest("POST", `/api/chat/${sessionId}/messages/${messageId}/regenerate
|
|
525
|
+
return this.makeRequest("POST", `/api/chat/${sessionId}/messages/${messageId}/regenerate`, undefined, 0, true);
|
|
462
526
|
}
|
|
463
527
|
/**
|
|
464
528
|
* Update a specific message
|
|
465
529
|
*/
|
|
466
530
|
async updateChatMessage(sessionId, messageId, content) {
|
|
467
|
-
await this.makeRequest("PUT", `/api/chat/${sessionId}/messages/${messageId}`, { content });
|
|
531
|
+
await this.makeRequest("PUT", `/api/chat/${sessionId}/messages/${messageId}`, { content }, 0, true);
|
|
468
532
|
}
|
|
469
533
|
/**
|
|
470
534
|
* Delete a specific message
|
|
471
535
|
*/
|
|
472
536
|
async deleteChatMessage(sessionId, messageId) {
|
|
473
|
-
await this.makeRequest("DELETE", `/api/chat/${sessionId}/messages/${messageId}
|
|
537
|
+
await this.makeRequest("DELETE", `/api/chat/${sessionId}/messages/${messageId}`, undefined, 0, true);
|
|
474
538
|
}
|
|
475
539
|
/**
|
|
476
540
|
* Toggle the "forgotten" status of a message
|
|
477
541
|
*/
|
|
478
542
|
async toggleForgottenMessage(sessionId, messageId, forgotten) {
|
|
479
|
-
await this.makeRequest("PATCH", `/api/chat/${sessionId}/messages/${messageId}/forgotten`, { forgotten });
|
|
543
|
+
await this.makeRequest("PATCH", `/api/chat/${sessionId}/messages/${messageId}/forgotten`, { forgotten }, 0, true);
|
|
480
544
|
}
|
|
481
545
|
/**
|
|
482
546
|
* Merge multiple chat sessions into one
|
|
483
547
|
*/
|
|
484
548
|
async mergeChatSessions(request) {
|
|
485
|
-
return this.makeRequest("POST", "/api/chat/merge", request);
|
|
549
|
+
return this.makeRequest("POST", "/api/chat/merge", request, 0, true);
|
|
486
550
|
}
|
|
487
551
|
/**
|
|
488
552
|
* Create a WebSocket client
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { EkoDBClient, WebSocketClient, MergeStrategy, RateLimitError, } from "./client";
|
|
1
|
+
export { EkoDBClient, WebSocketClient, SerializationFormat, MergeStrategy, RateLimitError, } from "./client";
|
|
2
2
|
export { QueryBuilder, SortOrder } from "./query-builder";
|
|
3
3
|
export { SearchQueryBuilder } from "./search";
|
|
4
4
|
export { SchemaBuilder, FieldTypeSchemaBuilder, VectorIndexAlgorithm, DistanceMetric, } from "./schema";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JoinBuilder = exports.DistanceMetric = exports.VectorIndexAlgorithm = exports.FieldTypeSchemaBuilder = exports.SchemaBuilder = exports.SearchQueryBuilder = exports.SortOrder = exports.QueryBuilder = exports.RateLimitError = exports.MergeStrategy = exports.WebSocketClient = exports.EkoDBClient = void 0;
|
|
3
|
+
exports.JoinBuilder = exports.DistanceMetric = exports.VectorIndexAlgorithm = exports.FieldTypeSchemaBuilder = exports.SchemaBuilder = exports.SearchQueryBuilder = exports.SortOrder = exports.QueryBuilder = exports.RateLimitError = exports.MergeStrategy = exports.SerializationFormat = exports.WebSocketClient = exports.EkoDBClient = void 0;
|
|
4
4
|
var client_1 = require("./client");
|
|
5
5
|
Object.defineProperty(exports, "EkoDBClient", { enumerable: true, get: function () { return client_1.EkoDBClient; } });
|
|
6
6
|
Object.defineProperty(exports, "WebSocketClient", { enumerable: true, get: function () { return client_1.WebSocketClient; } });
|
|
7
|
+
Object.defineProperty(exports, "SerializationFormat", { enumerable: true, get: function () { return client_1.SerializationFormat; } });
|
|
7
8
|
Object.defineProperty(exports, "MergeStrategy", { enumerable: true, get: function () { return client_1.MergeStrategy; } });
|
|
8
9
|
Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return client_1.RateLimitError; } });
|
|
9
10
|
var query_builder_1 = require("./query-builder");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekodb/ekodb-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Official TypeScript/JavaScript client for ekoDB",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"typescript": "^5.3.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
+
"@msgpack/msgpack": "^3.0.0",
|
|
25
26
|
"ws": "^8.16.0"
|
|
26
27
|
}
|
|
27
28
|
}
|
package/src/client.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* ekoDB TypeScript Client
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { encode, decode } from "@msgpack/msgpack";
|
|
5
6
|
import { QueryBuilder, Query as QueryBuilderQuery } from "./query-builder";
|
|
6
7
|
import { SearchQuery, SearchQueryBuilder, SearchResponse } from "./search";
|
|
7
8
|
import { Schema, SchemaBuilder, CollectionMetadata } from "./schema";
|
|
@@ -10,6 +11,16 @@ export interface Record {
|
|
|
10
11
|
[key: string]: any;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Serialization format for client-server communication
|
|
16
|
+
*/
|
|
17
|
+
export enum SerializationFormat {
|
|
18
|
+
/** JSON format (default, human-readable) */
|
|
19
|
+
Json = "Json",
|
|
20
|
+
/** MessagePack format (binary, 2-3x faster) */
|
|
21
|
+
MessagePack = "MessagePack",
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
/**
|
|
14
25
|
* Rate limit information from the server
|
|
15
26
|
*/
|
|
@@ -36,6 +47,8 @@ export interface ClientConfig {
|
|
|
36
47
|
maxRetries?: number;
|
|
37
48
|
/** Request timeout in milliseconds (default: 30000) */
|
|
38
49
|
timeout?: number;
|
|
50
|
+
/** Serialization format (default: MessagePack for best performance, use Json for debugging) */
|
|
51
|
+
format?: SerializationFormat;
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
/**
|
|
@@ -184,6 +197,7 @@ export class EkoDBClient {
|
|
|
184
197
|
private shouldRetry: boolean;
|
|
185
198
|
private maxRetries: number;
|
|
186
199
|
private timeout: number;
|
|
200
|
+
private format: SerializationFormat;
|
|
187
201
|
private rateLimitInfo: RateLimitInfo | null = null;
|
|
188
202
|
|
|
189
203
|
constructor(config: string | ClientConfig, apiKey?: string) {
|
|
@@ -194,12 +208,14 @@ export class EkoDBClient {
|
|
|
194
208
|
this.shouldRetry = true;
|
|
195
209
|
this.maxRetries = 3;
|
|
196
210
|
this.timeout = 30000;
|
|
211
|
+
this.format = SerializationFormat.MessagePack; // Default to MessagePack for 2-3x performance
|
|
197
212
|
} else {
|
|
198
213
|
this.baseURL = config.baseURL;
|
|
199
214
|
this.apiKey = config.apiKey;
|
|
200
215
|
this.shouldRetry = config.shouldRetry ?? true;
|
|
201
216
|
this.maxRetries = config.maxRetries ?? 3;
|
|
202
217
|
this.timeout = config.timeout ?? 30000;
|
|
218
|
+
this.format = config.format ?? SerializationFormat.MessagePack; // Default to MessagePack for 2-3x performance
|
|
203
219
|
}
|
|
204
220
|
}
|
|
205
221
|
|
|
@@ -275,6 +291,33 @@ export class EkoDBClient {
|
|
|
275
291
|
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
276
292
|
}
|
|
277
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Helper to determine if a path should use JSON
|
|
296
|
+
* Only CRUD operations (insert/update/delete/batch) use MessagePack
|
|
297
|
+
* Everything else uses JSON for compatibility
|
|
298
|
+
*/
|
|
299
|
+
private shouldUseJSON(path: string): boolean {
|
|
300
|
+
// ONLY these operations support MessagePack
|
|
301
|
+
const msgpackPaths = [
|
|
302
|
+
"/api/insert/",
|
|
303
|
+
"/api/batch_insert/",
|
|
304
|
+
"/api/update/",
|
|
305
|
+
"/api/batch_update/",
|
|
306
|
+
"/api/delete/",
|
|
307
|
+
"/api/batch_delete/",
|
|
308
|
+
];
|
|
309
|
+
|
|
310
|
+
// Check if path starts with any MessagePack-supported operation
|
|
311
|
+
for (const prefix of msgpackPaths) {
|
|
312
|
+
if (path.startsWith(prefix)) {
|
|
313
|
+
return false; // Use MessagePack
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Everything else uses JSON
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
|
|
278
321
|
/**
|
|
279
322
|
* Make an HTTP request to the ekoDB API with retry logic
|
|
280
323
|
*/
|
|
@@ -283,21 +326,36 @@ export class EkoDBClient {
|
|
|
283
326
|
path: string,
|
|
284
327
|
data?: any,
|
|
285
328
|
attempt: number = 0,
|
|
329
|
+
forceJson: boolean = false,
|
|
286
330
|
): Promise<T> {
|
|
287
331
|
if (!this.token) {
|
|
288
332
|
await this.refreshToken();
|
|
289
333
|
}
|
|
290
334
|
|
|
335
|
+
// Determine content type and serialization based on path
|
|
336
|
+
// Only CRUD operations support MessagePack, everything else uses JSON
|
|
337
|
+
const shouldForceJson = forceJson || this.shouldUseJSON(path);
|
|
338
|
+
const isMessagePack =
|
|
339
|
+
!shouldForceJson && this.format === SerializationFormat.MessagePack;
|
|
340
|
+
const contentType = isMessagePack
|
|
341
|
+
? "application/msgpack"
|
|
342
|
+
: "application/json";
|
|
343
|
+
|
|
344
|
+
// Note: Modern fetch API automatically handles gzip/deflate decompression
|
|
345
|
+
// when server sends Content-Encoding header. No additional configuration needed.
|
|
291
346
|
const options: RequestInit = {
|
|
292
347
|
method,
|
|
293
348
|
headers: {
|
|
294
349
|
Authorization: `Bearer ${this.token}`,
|
|
295
|
-
"Content-Type":
|
|
350
|
+
"Content-Type": contentType,
|
|
351
|
+
Accept: contentType,
|
|
296
352
|
},
|
|
297
353
|
};
|
|
298
354
|
|
|
299
355
|
if (data) {
|
|
300
|
-
options.body =
|
|
356
|
+
options.body = isMessagePack
|
|
357
|
+
? (encode(data) as any)
|
|
358
|
+
: JSON.stringify(data);
|
|
301
359
|
}
|
|
302
360
|
|
|
303
361
|
try {
|
|
@@ -306,7 +364,14 @@ export class EkoDBClient {
|
|
|
306
364
|
// Extract rate limit info from successful responses
|
|
307
365
|
if (response.ok) {
|
|
308
366
|
this.extractRateLimitInfo(response);
|
|
309
|
-
|
|
367
|
+
|
|
368
|
+
// Deserialize based on format
|
|
369
|
+
if (isMessagePack) {
|
|
370
|
+
const buffer = await response.arrayBuffer();
|
|
371
|
+
return decode(new Uint8Array(buffer)) as T;
|
|
372
|
+
} else {
|
|
373
|
+
return response.json() as Promise<T>;
|
|
374
|
+
}
|
|
310
375
|
}
|
|
311
376
|
|
|
312
377
|
// Handle rate limiting (429)
|
|
@@ -319,7 +384,13 @@ export class EkoDBClient {
|
|
|
319
384
|
if (this.shouldRetry && attempt < this.maxRetries) {
|
|
320
385
|
console.log(`Rate limited. Retrying after ${retryAfter} seconds...`);
|
|
321
386
|
await this.sleep(retryAfter);
|
|
322
|
-
return this.makeRequest<T>(
|
|
387
|
+
return this.makeRequest<T>(
|
|
388
|
+
method,
|
|
389
|
+
path,
|
|
390
|
+
data,
|
|
391
|
+
attempt + 1,
|
|
392
|
+
forceJson,
|
|
393
|
+
);
|
|
323
394
|
}
|
|
324
395
|
|
|
325
396
|
throw new RateLimitError(retryAfter);
|
|
@@ -336,7 +407,7 @@ export class EkoDBClient {
|
|
|
336
407
|
`Service unavailable. Retrying after ${retryDelay} seconds...`,
|
|
337
408
|
);
|
|
338
409
|
await this.sleep(retryDelay);
|
|
339
|
-
return this.makeRequest<T>(method, path, data, attempt + 1);
|
|
410
|
+
return this.makeRequest<T>(method, path, data, attempt + 1, forceJson);
|
|
340
411
|
}
|
|
341
412
|
|
|
342
413
|
// Handle other errors
|
|
@@ -352,7 +423,7 @@ export class EkoDBClient {
|
|
|
352
423
|
const retryDelay = 3;
|
|
353
424
|
console.log(`Network error. Retrying after ${retryDelay} seconds...`);
|
|
354
425
|
await this.sleep(retryDelay);
|
|
355
|
-
return this.makeRequest<T>(method, path, data, attempt + 1);
|
|
426
|
+
return this.makeRequest<T>(method, path, data, attempt + 1, forceJson);
|
|
356
427
|
}
|
|
357
428
|
|
|
358
429
|
throw error;
|
|
@@ -440,14 +511,20 @@ export class EkoDBClient {
|
|
|
440
511
|
/**
|
|
441
512
|
* Batch insert multiple documents
|
|
442
513
|
*/
|
|
443
|
-
async batchInsert(
|
|
444
|
-
|
|
445
|
-
|
|
514
|
+
async batchInsert(
|
|
515
|
+
collection: string,
|
|
516
|
+
records: Record[],
|
|
517
|
+
bypassRipple?: boolean,
|
|
518
|
+
): Promise<BatchOperationResult> {
|
|
519
|
+
const inserts = records.map((data) => ({
|
|
520
|
+
data,
|
|
521
|
+
bypass_ripple: bypassRipple,
|
|
522
|
+
}));
|
|
523
|
+
return this.makeRequest<BatchOperationResult>(
|
|
446
524
|
"POST",
|
|
447
525
|
`/api/batch/insert/${collection}`,
|
|
448
526
|
{ inserts },
|
|
449
527
|
);
|
|
450
|
-
return result.successful.map((id) => ({ id }));
|
|
451
528
|
}
|
|
452
529
|
|
|
453
530
|
/**
|
|
@@ -455,27 +532,37 @@ export class EkoDBClient {
|
|
|
455
532
|
*/
|
|
456
533
|
async batchUpdate(
|
|
457
534
|
collection: string,
|
|
458
|
-
updates: Array<{ id: string; data: Record }>,
|
|
459
|
-
): Promise<
|
|
460
|
-
const
|
|
535
|
+
updates: Array<{ id: string; data: Record; bypassRipple?: boolean }>,
|
|
536
|
+
): Promise<BatchOperationResult> {
|
|
537
|
+
const formattedUpdates = updates.map((u) => ({
|
|
538
|
+
id: u.id,
|
|
539
|
+
data: u.data,
|
|
540
|
+
bypass_ripple: u.bypassRipple,
|
|
541
|
+
}));
|
|
542
|
+
return this.makeRequest<BatchOperationResult>(
|
|
461
543
|
"PUT",
|
|
462
544
|
`/api/batch/update/${collection}`,
|
|
463
|
-
{ updates },
|
|
545
|
+
{ updates: formattedUpdates },
|
|
464
546
|
);
|
|
465
|
-
return result.successful.map((id) => ({ id }));
|
|
466
547
|
}
|
|
467
548
|
|
|
468
549
|
/**
|
|
469
550
|
* Batch delete multiple documents
|
|
470
551
|
*/
|
|
471
|
-
async batchDelete(
|
|
472
|
-
|
|
473
|
-
|
|
552
|
+
async batchDelete(
|
|
553
|
+
collection: string,
|
|
554
|
+
ids: string[],
|
|
555
|
+
bypassRipple?: boolean,
|
|
556
|
+
): Promise<BatchOperationResult> {
|
|
557
|
+
const deletes = ids.map((id) => ({
|
|
558
|
+
id: id,
|
|
559
|
+
bypass_ripple: bypassRipple,
|
|
560
|
+
}));
|
|
561
|
+
return this.makeRequest<BatchOperationResult>(
|
|
474
562
|
"DELETE",
|
|
475
563
|
`/api/batch/delete/${collection}`,
|
|
476
564
|
{ deletes },
|
|
477
565
|
);
|
|
478
|
-
return result.successful.length;
|
|
479
566
|
}
|
|
480
567
|
|
|
481
568
|
/**
|
|
@@ -486,6 +573,8 @@ export class EkoDBClient {
|
|
|
486
573
|
"POST",
|
|
487
574
|
`/api/kv/set/${encodeURIComponent(key)}`,
|
|
488
575
|
{ value },
|
|
576
|
+
0,
|
|
577
|
+
true, // Force JSON for KV operations
|
|
489
578
|
);
|
|
490
579
|
}
|
|
491
580
|
|
|
@@ -496,6 +585,9 @@ export class EkoDBClient {
|
|
|
496
585
|
const result = await this.makeRequest<{ value: any }>(
|
|
497
586
|
"GET",
|
|
498
587
|
`/api/kv/get/${encodeURIComponent(key)}`,
|
|
588
|
+
undefined,
|
|
589
|
+
0,
|
|
590
|
+
true, // Force JSON for KV operations
|
|
499
591
|
);
|
|
500
592
|
return result.value;
|
|
501
593
|
}
|
|
@@ -507,6 +599,9 @@ export class EkoDBClient {
|
|
|
507
599
|
await this.makeRequest<void>(
|
|
508
600
|
"DELETE",
|
|
509
601
|
`/api/kv/delete/${encodeURIComponent(key)}`,
|
|
602
|
+
undefined,
|
|
603
|
+
0,
|
|
604
|
+
true, // Force JSON for KV operations
|
|
510
605
|
);
|
|
511
606
|
}
|
|
512
607
|
|
|
@@ -517,6 +612,9 @@ export class EkoDBClient {
|
|
|
517
612
|
const result = await this.makeRequest<{ collections: string[] }>(
|
|
518
613
|
"GET",
|
|
519
614
|
"/api/collections",
|
|
615
|
+
undefined,
|
|
616
|
+
0,
|
|
617
|
+
true, // Force JSON for metadata operations
|
|
520
618
|
);
|
|
521
619
|
return result.collections;
|
|
522
620
|
}
|
|
@@ -525,7 +623,13 @@ export class EkoDBClient {
|
|
|
525
623
|
* Delete a collection
|
|
526
624
|
*/
|
|
527
625
|
async deleteCollection(collection: string): Promise<void> {
|
|
528
|
-
await this.makeRequest<void>(
|
|
626
|
+
await this.makeRequest<void>(
|
|
627
|
+
"DELETE",
|
|
628
|
+
`/api/collections/${collection}`,
|
|
629
|
+
undefined,
|
|
630
|
+
0,
|
|
631
|
+
true, // Force JSON for metadata operations
|
|
632
|
+
);
|
|
529
633
|
}
|
|
530
634
|
|
|
531
635
|
/**
|
|
@@ -553,6 +657,8 @@ export class EkoDBClient {
|
|
|
553
657
|
"POST",
|
|
554
658
|
`/api/collections/${collection}`,
|
|
555
659
|
schemaObj,
|
|
660
|
+
0,
|
|
661
|
+
true, // Force JSON for metadata operations
|
|
556
662
|
);
|
|
557
663
|
}
|
|
558
664
|
|
|
@@ -566,6 +672,9 @@ export class EkoDBClient {
|
|
|
566
672
|
return this.makeRequest<CollectionMetadata>(
|
|
567
673
|
"GET",
|
|
568
674
|
`/api/collections/${collection}`,
|
|
675
|
+
undefined,
|
|
676
|
+
0,
|
|
677
|
+
true, // Force JSON for metadata operations
|
|
569
678
|
);
|
|
570
679
|
}
|
|
571
680
|
|
|
@@ -625,6 +734,8 @@ export class EkoDBClient {
|
|
|
625
734
|
"POST",
|
|
626
735
|
`/api/search/${collection}`,
|
|
627
736
|
queryObj,
|
|
737
|
+
0,
|
|
738
|
+
true, // Force JSON for search operations
|
|
628
739
|
);
|
|
629
740
|
}
|
|
630
741
|
|
|
@@ -636,7 +747,13 @@ export class EkoDBClient {
|
|
|
636
747
|
async createChatSession(
|
|
637
748
|
request: CreateChatSessionRequest,
|
|
638
749
|
): Promise<ChatResponse> {
|
|
639
|
-
return this.makeRequest<ChatResponse>(
|
|
750
|
+
return this.makeRequest<ChatResponse>(
|
|
751
|
+
"POST",
|
|
752
|
+
"/api/chat",
|
|
753
|
+
request,
|
|
754
|
+
0,
|
|
755
|
+
true, // Force JSON for chat operations
|
|
756
|
+
);
|
|
640
757
|
}
|
|
641
758
|
|
|
642
759
|
/**
|
|
@@ -650,6 +767,8 @@ export class EkoDBClient {
|
|
|
650
767
|
"POST",
|
|
651
768
|
`/api/chat/${sessionId}/messages`,
|
|
652
769
|
request,
|
|
770
|
+
0,
|
|
771
|
+
true, // Force JSON for chat operations
|
|
653
772
|
);
|
|
654
773
|
}
|
|
655
774
|
|
|
@@ -660,6 +779,9 @@ export class EkoDBClient {
|
|
|
660
779
|
return this.makeRequest<ChatSessionResponse>(
|
|
661
780
|
"GET",
|
|
662
781
|
`/api/chat/${sessionId}`,
|
|
782
|
+
undefined,
|
|
783
|
+
0,
|
|
784
|
+
true, // Force JSON for chat operations
|
|
663
785
|
);
|
|
664
786
|
}
|
|
665
787
|
|
|
@@ -676,7 +798,13 @@ export class EkoDBClient {
|
|
|
676
798
|
|
|
677
799
|
const queryString = params.toString();
|
|
678
800
|
const path = queryString ? `/api/chat?${queryString}` : "/api/chat";
|
|
679
|
-
return this.makeRequest<ListSessionsResponse>(
|
|
801
|
+
return this.makeRequest<ListSessionsResponse>(
|
|
802
|
+
"GET",
|
|
803
|
+
path,
|
|
804
|
+
undefined,
|
|
805
|
+
0,
|
|
806
|
+
true, // Force JSON for chat operations
|
|
807
|
+
);
|
|
680
808
|
}
|
|
681
809
|
|
|
682
810
|
/**
|
|
@@ -695,7 +823,13 @@ export class EkoDBClient {
|
|
|
695
823
|
const path = queryString
|
|
696
824
|
? `/api/chat/${sessionId}/messages?${queryString}`
|
|
697
825
|
: `/api/chat/${sessionId}/messages`;
|
|
698
|
-
return this.makeRequest<GetMessagesResponse>(
|
|
826
|
+
return this.makeRequest<GetMessagesResponse>(
|
|
827
|
+
"GET",
|
|
828
|
+
path,
|
|
829
|
+
undefined,
|
|
830
|
+
0,
|
|
831
|
+
true, // Force JSON for chat operations
|
|
832
|
+
);
|
|
699
833
|
}
|
|
700
834
|
|
|
701
835
|
/**
|
|
@@ -709,6 +843,8 @@ export class EkoDBClient {
|
|
|
709
843
|
"PUT",
|
|
710
844
|
`/api/chat/${sessionId}`,
|
|
711
845
|
request,
|
|
846
|
+
0,
|
|
847
|
+
true, // Force JSON for chat operations
|
|
712
848
|
);
|
|
713
849
|
}
|
|
714
850
|
|
|
@@ -718,14 +854,26 @@ export class EkoDBClient {
|
|
|
718
854
|
async branchChatSession(
|
|
719
855
|
request: CreateChatSessionRequest,
|
|
720
856
|
): Promise<ChatResponse> {
|
|
721
|
-
return this.makeRequest<ChatResponse>(
|
|
857
|
+
return this.makeRequest<ChatResponse>(
|
|
858
|
+
"POST",
|
|
859
|
+
"/api/chat/branch",
|
|
860
|
+
request,
|
|
861
|
+
0,
|
|
862
|
+
true, // Force JSON for chat operations
|
|
863
|
+
);
|
|
722
864
|
}
|
|
723
865
|
|
|
724
866
|
/**
|
|
725
867
|
* Delete a chat session
|
|
726
868
|
*/
|
|
727
869
|
async deleteChatSession(sessionId: string): Promise<void> {
|
|
728
|
-
await this.makeRequest<void>(
|
|
870
|
+
await this.makeRequest<void>(
|
|
871
|
+
"DELETE",
|
|
872
|
+
`/api/chat/${sessionId}`,
|
|
873
|
+
undefined,
|
|
874
|
+
0,
|
|
875
|
+
true, // Force JSON for chat operations
|
|
876
|
+
);
|
|
729
877
|
}
|
|
730
878
|
|
|
731
879
|
/**
|
|
@@ -738,6 +886,9 @@ export class EkoDBClient {
|
|
|
738
886
|
return this.makeRequest<ChatResponse>(
|
|
739
887
|
"POST",
|
|
740
888
|
`/api/chat/${sessionId}/messages/${messageId}/regenerate`,
|
|
889
|
+
undefined,
|
|
890
|
+
0,
|
|
891
|
+
true, // Force JSON for chat operations
|
|
741
892
|
);
|
|
742
893
|
}
|
|
743
894
|
|
|
@@ -753,6 +904,8 @@ export class EkoDBClient {
|
|
|
753
904
|
"PUT",
|
|
754
905
|
`/api/chat/${sessionId}/messages/${messageId}`,
|
|
755
906
|
{ content },
|
|
907
|
+
0,
|
|
908
|
+
true, // Force JSON for chat operations
|
|
756
909
|
);
|
|
757
910
|
}
|
|
758
911
|
|
|
@@ -763,6 +916,9 @@ export class EkoDBClient {
|
|
|
763
916
|
await this.makeRequest<void>(
|
|
764
917
|
"DELETE",
|
|
765
918
|
`/api/chat/${sessionId}/messages/${messageId}`,
|
|
919
|
+
undefined,
|
|
920
|
+
0,
|
|
921
|
+
true, // Force JSON for chat operations
|
|
766
922
|
);
|
|
767
923
|
}
|
|
768
924
|
|
|
@@ -778,6 +934,8 @@ export class EkoDBClient {
|
|
|
778
934
|
"PATCH",
|
|
779
935
|
`/api/chat/${sessionId}/messages/${messageId}/forgotten`,
|
|
780
936
|
{ forgotten },
|
|
937
|
+
0,
|
|
938
|
+
true, // Force JSON for chat operations
|
|
781
939
|
);
|
|
782
940
|
}
|
|
783
941
|
|
|
@@ -791,6 +949,8 @@ export class EkoDBClient {
|
|
|
791
949
|
"POST",
|
|
792
950
|
"/api/chat/merge",
|
|
793
951
|
request,
|
|
952
|
+
0,
|
|
953
|
+
true, // Force JSON for chat operations
|
|
794
954
|
);
|
|
795
955
|
}
|
|
796
956
|
|