@ekodb/ekodb-client 0.6.1 → 0.7.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 +55 -2
- package/dist/client.js +77 -4
- package/dist/functions.d.ts +25 -0
- package/dist/functions.js +26 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/utils.d.ts +85 -0
- package/dist/utils.js +127 -0
- package/package.json +1 -1
- package/src/client.ts +124 -4
- package/src/functions.ts +59 -0
- package/src/index.ts +2 -0
- package/src/utils.ts +162 -0
package/dist/client.d.ts
CHANGED
|
@@ -206,6 +206,9 @@ export declare class EkoDBClient {
|
|
|
206
206
|
private makeRequest;
|
|
207
207
|
/**
|
|
208
208
|
* Insert a document into a collection
|
|
209
|
+
* @param collection - Collection name
|
|
210
|
+
* @param record - Document to insert
|
|
211
|
+
* @param ttl - Optional TTL: duration string ("1h", "30m"), seconds ("3600"), or ISO8601 timestamp
|
|
209
212
|
*/
|
|
210
213
|
insert(collection: string, record: Record, ttl?: string): Promise<Record>;
|
|
211
214
|
/**
|
|
@@ -260,9 +263,12 @@ export declare class EkoDBClient {
|
|
|
260
263
|
*/
|
|
261
264
|
batchDelete(collection: string, ids: string[], bypassRipple?: boolean): Promise<BatchOperationResult>;
|
|
262
265
|
/**
|
|
263
|
-
* Set a key-value pair
|
|
266
|
+
* Set a key-value pair with optional TTL
|
|
267
|
+
* @param key - The key to set
|
|
268
|
+
* @param value - The value to store
|
|
269
|
+
* @param ttl - Optional TTL in seconds
|
|
264
270
|
*/
|
|
265
|
-
kvSet(key: string, value: any): Promise<void>;
|
|
271
|
+
kvSet(key: string, value: any, ttl?: number): Promise<void>;
|
|
266
272
|
/**
|
|
267
273
|
* Get a value by key
|
|
268
274
|
*/
|
|
@@ -271,6 +277,53 @@ export declare class EkoDBClient {
|
|
|
271
277
|
* Delete a key
|
|
272
278
|
*/
|
|
273
279
|
kvDelete(key: string): Promise<void>;
|
|
280
|
+
/**
|
|
281
|
+
* Check if a key exists
|
|
282
|
+
* @param key - The key to check
|
|
283
|
+
* @returns true if the key exists, false otherwise
|
|
284
|
+
*/
|
|
285
|
+
kvExists(key: string): Promise<boolean>;
|
|
286
|
+
/**
|
|
287
|
+
* Query/find KV entries with pattern matching
|
|
288
|
+
* @param options - Query options including pattern and include_expired
|
|
289
|
+
* @returns Array of matching records
|
|
290
|
+
*/
|
|
291
|
+
kvFind(options?: {
|
|
292
|
+
pattern?: string;
|
|
293
|
+
include_expired?: boolean;
|
|
294
|
+
}): Promise<any[]>;
|
|
295
|
+
/**
|
|
296
|
+
* Alias for kvFind - query KV store with pattern
|
|
297
|
+
*/
|
|
298
|
+
kvQuery(options?: {
|
|
299
|
+
pattern?: string;
|
|
300
|
+
include_expired?: boolean;
|
|
301
|
+
}): Promise<any[]>;
|
|
302
|
+
/**
|
|
303
|
+
* Begin a new transaction
|
|
304
|
+
* @param isolationLevel - Transaction isolation level (default: "ReadCommitted")
|
|
305
|
+
* @returns Transaction ID
|
|
306
|
+
*/
|
|
307
|
+
beginTransaction(isolationLevel?: string): Promise<string>;
|
|
308
|
+
/**
|
|
309
|
+
* Get transaction status
|
|
310
|
+
* @param transactionId - The transaction ID
|
|
311
|
+
* @returns Transaction status object
|
|
312
|
+
*/
|
|
313
|
+
getTransactionStatus(transactionId: string): Promise<{
|
|
314
|
+
state: string;
|
|
315
|
+
operations_count: number;
|
|
316
|
+
}>;
|
|
317
|
+
/**
|
|
318
|
+
* Commit a transaction
|
|
319
|
+
* @param transactionId - The transaction ID to commit
|
|
320
|
+
*/
|
|
321
|
+
commitTransaction(transactionId: string): Promise<void>;
|
|
322
|
+
/**
|
|
323
|
+
* Rollback a transaction
|
|
324
|
+
* @param transactionId - The transaction ID to rollback
|
|
325
|
+
*/
|
|
326
|
+
rollbackTransaction(transactionId: string): Promise<void>;
|
|
274
327
|
/**
|
|
275
328
|
* List all collections
|
|
276
329
|
*/
|
package/dist/client.js
CHANGED
|
@@ -263,11 +263,14 @@ class EkoDBClient {
|
|
|
263
263
|
}
|
|
264
264
|
/**
|
|
265
265
|
* Insert a document into a collection
|
|
266
|
+
* @param collection - Collection name
|
|
267
|
+
* @param record - Document to insert
|
|
268
|
+
* @param ttl - Optional TTL: duration string ("1h", "30m"), seconds ("3600"), or ISO8601 timestamp
|
|
266
269
|
*/
|
|
267
270
|
async insert(collection, record, ttl) {
|
|
268
271
|
const data = { ...record };
|
|
269
272
|
if (ttl) {
|
|
270
|
-
data.
|
|
273
|
+
data.ttl = ttl;
|
|
271
274
|
}
|
|
272
275
|
return this.makeRequest("POST", `/api/insert/${collection}`, data);
|
|
273
276
|
}
|
|
@@ -347,10 +350,17 @@ class EkoDBClient {
|
|
|
347
350
|
return this.makeRequest("DELETE", `/api/batch/delete/${collection}`, { deletes });
|
|
348
351
|
}
|
|
349
352
|
/**
|
|
350
|
-
* Set a key-value pair
|
|
353
|
+
* Set a key-value pair with optional TTL
|
|
354
|
+
* @param key - The key to set
|
|
355
|
+
* @param value - The value to store
|
|
356
|
+
* @param ttl - Optional TTL in seconds
|
|
351
357
|
*/
|
|
352
|
-
async kvSet(key, value) {
|
|
353
|
-
|
|
358
|
+
async kvSet(key, value, ttl) {
|
|
359
|
+
const body = { value };
|
|
360
|
+
if (ttl !== undefined) {
|
|
361
|
+
body.ttl = ttl;
|
|
362
|
+
}
|
|
363
|
+
await this.makeRequest("POST", `/api/kv/set/${encodeURIComponent(key)}`, body, 0, true);
|
|
354
364
|
}
|
|
355
365
|
/**
|
|
356
366
|
* Get a value by key
|
|
@@ -365,6 +375,69 @@ class EkoDBClient {
|
|
|
365
375
|
async kvDelete(key) {
|
|
366
376
|
await this.makeRequest("DELETE", `/api/kv/delete/${encodeURIComponent(key)}`, undefined, 0, true);
|
|
367
377
|
}
|
|
378
|
+
/**
|
|
379
|
+
* Check if a key exists
|
|
380
|
+
* @param key - The key to check
|
|
381
|
+
* @returns true if the key exists, false otherwise
|
|
382
|
+
*/
|
|
383
|
+
async kvExists(key) {
|
|
384
|
+
try {
|
|
385
|
+
const result = await this.kvGet(key);
|
|
386
|
+
return result !== null && result !== undefined;
|
|
387
|
+
}
|
|
388
|
+
catch {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Query/find KV entries with pattern matching
|
|
394
|
+
* @param options - Query options including pattern and include_expired
|
|
395
|
+
* @returns Array of matching records
|
|
396
|
+
*/
|
|
397
|
+
async kvFind(options) {
|
|
398
|
+
const result = await this.makeRequest("POST", "/api/kv/find", options || {}, 0, true);
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Alias for kvFind - query KV store with pattern
|
|
403
|
+
*/
|
|
404
|
+
async kvQuery(options) {
|
|
405
|
+
return this.kvFind(options);
|
|
406
|
+
}
|
|
407
|
+
// ============================================================================
|
|
408
|
+
// Transaction Operations
|
|
409
|
+
// ============================================================================
|
|
410
|
+
/**
|
|
411
|
+
* Begin a new transaction
|
|
412
|
+
* @param isolationLevel - Transaction isolation level (default: "ReadCommitted")
|
|
413
|
+
* @returns Transaction ID
|
|
414
|
+
*/
|
|
415
|
+
async beginTransaction(isolationLevel = "ReadCommitted") {
|
|
416
|
+
const result = await this.makeRequest("POST", "/api/transactions", { isolation_level: isolationLevel }, 0, true);
|
|
417
|
+
return result.transaction_id;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Get transaction status
|
|
421
|
+
* @param transactionId - The transaction ID
|
|
422
|
+
* @returns Transaction status object
|
|
423
|
+
*/
|
|
424
|
+
async getTransactionStatus(transactionId) {
|
|
425
|
+
return this.makeRequest("GET", `/api/transactions/${encodeURIComponent(transactionId)}`, undefined, 0, true);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Commit a transaction
|
|
429
|
+
* @param transactionId - The transaction ID to commit
|
|
430
|
+
*/
|
|
431
|
+
async commitTransaction(transactionId) {
|
|
432
|
+
await this.makeRequest("POST", `/api/transactions/${encodeURIComponent(transactionId)}/commit`, undefined, 0, true);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Rollback a transaction
|
|
436
|
+
* @param transactionId - The transaction ID to rollback
|
|
437
|
+
*/
|
|
438
|
+
async rollbackTransaction(transactionId) {
|
|
439
|
+
await this.makeRequest("POST", `/api/transactions/${encodeURIComponent(transactionId)}/rollback`, undefined, 0, true);
|
|
440
|
+
}
|
|
368
441
|
/**
|
|
369
442
|
* List all collections
|
|
370
443
|
*/
|
package/dist/functions.d.ts
CHANGED
|
@@ -174,6 +174,26 @@ export type FunctionStageConfig = {
|
|
|
174
174
|
} | {
|
|
175
175
|
type: "ReleaseSavepoint";
|
|
176
176
|
name: string;
|
|
177
|
+
} | {
|
|
178
|
+
type: "KvGet";
|
|
179
|
+
key: string;
|
|
180
|
+
output_field?: string;
|
|
181
|
+
} | {
|
|
182
|
+
type: "KvSet";
|
|
183
|
+
key: string;
|
|
184
|
+
value: any;
|
|
185
|
+
ttl?: number;
|
|
186
|
+
} | {
|
|
187
|
+
type: "KvDelete";
|
|
188
|
+
key: string;
|
|
189
|
+
} | {
|
|
190
|
+
type: "KvExists";
|
|
191
|
+
key: string;
|
|
192
|
+
output_field?: string;
|
|
193
|
+
} | {
|
|
194
|
+
type: "KvQuery";
|
|
195
|
+
pattern?: string;
|
|
196
|
+
include_expired?: boolean;
|
|
177
197
|
};
|
|
178
198
|
export interface ChatMessage {
|
|
179
199
|
role: string;
|
|
@@ -275,4 +295,9 @@ export declare const Stage: {
|
|
|
275
295
|
createSavepoint: (name: string) => FunctionStageConfig;
|
|
276
296
|
rollbackToSavepoint: (name: string) => FunctionStageConfig;
|
|
277
297
|
releaseSavepoint: (name: string) => FunctionStageConfig;
|
|
298
|
+
kvGet: (key: string, output_field?: string) => FunctionStageConfig;
|
|
299
|
+
kvSet: (key: string, value: any, ttl?: number) => FunctionStageConfig;
|
|
300
|
+
kvDelete: (key: string) => FunctionStageConfig;
|
|
301
|
+
kvExists: (key: string, output_field?: string) => FunctionStageConfig;
|
|
302
|
+
kvQuery: (pattern?: string, include_expired?: boolean) => FunctionStageConfig;
|
|
278
303
|
};
|
package/dist/functions.js
CHANGED
|
@@ -206,4 +206,30 @@ exports.Stage = {
|
|
|
206
206
|
type: "ReleaseSavepoint",
|
|
207
207
|
name,
|
|
208
208
|
}),
|
|
209
|
+
// KV Store operations - faster than collection lookups for simple key-value data
|
|
210
|
+
kvGet: (key, output_field) => ({
|
|
211
|
+
type: "KvGet",
|
|
212
|
+
key,
|
|
213
|
+
output_field,
|
|
214
|
+
}),
|
|
215
|
+
kvSet: (key, value, ttl) => ({
|
|
216
|
+
type: "KvSet",
|
|
217
|
+
key,
|
|
218
|
+
value,
|
|
219
|
+
ttl,
|
|
220
|
+
}),
|
|
221
|
+
kvDelete: (key) => ({
|
|
222
|
+
type: "KvDelete",
|
|
223
|
+
key,
|
|
224
|
+
}),
|
|
225
|
+
kvExists: (key, output_field) => ({
|
|
226
|
+
type: "KvExists",
|
|
227
|
+
key,
|
|
228
|
+
output_field,
|
|
229
|
+
}),
|
|
230
|
+
kvQuery: (pattern, include_expired) => ({
|
|
231
|
+
type: "KvQuery",
|
|
232
|
+
pattern,
|
|
233
|
+
include_expired,
|
|
234
|
+
}),
|
|
209
235
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ export { SearchQueryBuilder } from "./search";
|
|
|
4
4
|
export { SchemaBuilder, FieldTypeSchemaBuilder, VectorIndexAlgorithm, DistanceMetric, } from "./schema";
|
|
5
5
|
export { JoinBuilder } from "./join";
|
|
6
6
|
export { Stage, ChatMessage } from "./functions";
|
|
7
|
-
export { getValue, getValues, extractRecord, getDateTimeValue, getUUIDValue, getDecimalValue, getDurationValue, getBytesValue, getBinaryValue, getArrayValue, getSetValue, getVectorValue, getObjectValue, } from "./utils";
|
|
7
|
+
export { getValue, getValues, extractRecord, getDateTimeValue, getUUIDValue, getDecimalValue, getDurationValue, getBytesValue, getBinaryValue, getArrayValue, getSetValue, getVectorValue, getObjectValue, Field, } from "./utils";
|
|
8
|
+
export type { WrappedFieldValue } from "./utils";
|
|
8
9
|
export type { SearchQuery, SearchResult, SearchResponse } from "./search";
|
|
9
10
|
export type { Schema, FieldTypeSchema, IndexConfig, CollectionMetadata, } from "./schema";
|
|
10
11
|
export type { JoinConfig } from "./join";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getObjectValue = exports.getVectorValue = exports.getSetValue = exports.getArrayValue = exports.getBinaryValue = exports.getBytesValue = exports.getDurationValue = exports.getDecimalValue = exports.getUUIDValue = exports.getDateTimeValue = exports.extractRecord = exports.getValues = exports.getValue = exports.ChatMessage = exports.Stage = 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;
|
|
3
|
+
exports.Field = exports.getObjectValue = exports.getVectorValue = exports.getSetValue = exports.getArrayValue = exports.getBinaryValue = exports.getBytesValue = exports.getDurationValue = exports.getDecimalValue = exports.getUUIDValue = exports.getDateTimeValue = exports.extractRecord = exports.getValues = exports.getValue = exports.ChatMessage = exports.Stage = 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; } });
|
|
@@ -36,3 +36,4 @@ Object.defineProperty(exports, "getArrayValue", { enumerable: true, get: functio
|
|
|
36
36
|
Object.defineProperty(exports, "getSetValue", { enumerable: true, get: function () { return utils_1.getSetValue; } });
|
|
37
37
|
Object.defineProperty(exports, "getVectorValue", { enumerable: true, get: function () { return utils_1.getVectorValue; } });
|
|
38
38
|
Object.defineProperty(exports, "getObjectValue", { enumerable: true, get: function () { return utils_1.getObjectValue; } });
|
|
39
|
+
Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return utils_1.Field; } });
|
package/dist/utils.d.ts
CHANGED
|
@@ -87,3 +87,88 @@ export declare function getObjectValue<T = any>(field: any): T | null;
|
|
|
87
87
|
* ```
|
|
88
88
|
*/
|
|
89
89
|
export declare function extractRecord<T extends Record<string, any>>(record: any): T;
|
|
90
|
+
export interface WrappedFieldValue {
|
|
91
|
+
type: string;
|
|
92
|
+
value: unknown;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Field builders for creating wrapped type values to send to ekoDB.
|
|
96
|
+
* These are the inverse of the getValue* extraction functions.
|
|
97
|
+
*/
|
|
98
|
+
export declare const Field: {
|
|
99
|
+
/**
|
|
100
|
+
* Create a UUID field value
|
|
101
|
+
* @param value - UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000")
|
|
102
|
+
*/
|
|
103
|
+
uuid: (value: string) => WrappedFieldValue;
|
|
104
|
+
/**
|
|
105
|
+
* Create a Decimal field value for precise numeric values
|
|
106
|
+
* @param value - Decimal as string (e.g., "99.99") to preserve precision
|
|
107
|
+
*/
|
|
108
|
+
decimal: (value: string) => WrappedFieldValue;
|
|
109
|
+
/**
|
|
110
|
+
* Create a DateTime field value
|
|
111
|
+
* @param value - Date object or RFC3339 string
|
|
112
|
+
*/
|
|
113
|
+
dateTime: (value: Date | string) => WrappedFieldValue;
|
|
114
|
+
/**
|
|
115
|
+
* Create a Duration field value
|
|
116
|
+
* @param milliseconds - Duration in milliseconds
|
|
117
|
+
*/
|
|
118
|
+
duration: (milliseconds: number) => WrappedFieldValue;
|
|
119
|
+
/**
|
|
120
|
+
* Create a Number field value (flexible numeric type)
|
|
121
|
+
* @param value - Integer or float
|
|
122
|
+
*/
|
|
123
|
+
number: (value: number) => WrappedFieldValue;
|
|
124
|
+
/**
|
|
125
|
+
* Create a Set field value (unique elements)
|
|
126
|
+
* @param values - Array of values (duplicates will be removed by server)
|
|
127
|
+
*/
|
|
128
|
+
set: <T>(values: T[]) => WrappedFieldValue;
|
|
129
|
+
/**
|
|
130
|
+
* Create a Vector field value (for embeddings/similarity search)
|
|
131
|
+
* @param values - Array of numbers representing the vector
|
|
132
|
+
*/
|
|
133
|
+
vector: (values: number[]) => WrappedFieldValue;
|
|
134
|
+
/**
|
|
135
|
+
* Create a Binary field value
|
|
136
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
137
|
+
*/
|
|
138
|
+
binary: (value: string | Uint8Array) => WrappedFieldValue;
|
|
139
|
+
/**
|
|
140
|
+
* Create a Bytes field value
|
|
141
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
142
|
+
*/
|
|
143
|
+
bytes: (value: string | Uint8Array) => WrappedFieldValue;
|
|
144
|
+
/**
|
|
145
|
+
* Create an Array field value
|
|
146
|
+
* @param values - Array of values
|
|
147
|
+
*/
|
|
148
|
+
array: <T>(values: T[]) => WrappedFieldValue;
|
|
149
|
+
/**
|
|
150
|
+
* Create an Object field value
|
|
151
|
+
* @param value - Object/map of key-value pairs
|
|
152
|
+
*/
|
|
153
|
+
object: (value: Record<string, unknown>) => WrappedFieldValue;
|
|
154
|
+
/**
|
|
155
|
+
* Create a String field value (explicit wrapping)
|
|
156
|
+
* @param value - String value
|
|
157
|
+
*/
|
|
158
|
+
string: (value: string) => WrappedFieldValue;
|
|
159
|
+
/**
|
|
160
|
+
* Create an Integer field value (explicit wrapping)
|
|
161
|
+
* @param value - Integer value
|
|
162
|
+
*/
|
|
163
|
+
integer: (value: number) => WrappedFieldValue;
|
|
164
|
+
/**
|
|
165
|
+
* Create a Float field value (explicit wrapping)
|
|
166
|
+
* @param value - Float value
|
|
167
|
+
*/
|
|
168
|
+
float: (value: number) => WrappedFieldValue;
|
|
169
|
+
/**
|
|
170
|
+
* Create a Boolean field value (explicit wrapping)
|
|
171
|
+
* @param value - Boolean value
|
|
172
|
+
*/
|
|
173
|
+
boolean: (value: boolean) => WrappedFieldValue;
|
|
174
|
+
};
|
package/dist/utils.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Utility functions for working with ekoDB records
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Field = void 0;
|
|
6
7
|
exports.getValue = getValue;
|
|
7
8
|
exports.getValues = getValues;
|
|
8
9
|
exports.getDateTimeValue = getDateTimeValue;
|
|
@@ -196,3 +197,129 @@ function extractRecord(record) {
|
|
|
196
197
|
}
|
|
197
198
|
return result;
|
|
198
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Field builders for creating wrapped type values to send to ekoDB.
|
|
202
|
+
* These are the inverse of the getValue* extraction functions.
|
|
203
|
+
*/
|
|
204
|
+
exports.Field = {
|
|
205
|
+
/**
|
|
206
|
+
* Create a UUID field value
|
|
207
|
+
* @param value - UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000")
|
|
208
|
+
*/
|
|
209
|
+
uuid: (value) => ({
|
|
210
|
+
type: "UUID",
|
|
211
|
+
value,
|
|
212
|
+
}),
|
|
213
|
+
/**
|
|
214
|
+
* Create a Decimal field value for precise numeric values
|
|
215
|
+
* @param value - Decimal as string (e.g., "99.99") to preserve precision
|
|
216
|
+
*/
|
|
217
|
+
decimal: (value) => ({
|
|
218
|
+
type: "Decimal",
|
|
219
|
+
value,
|
|
220
|
+
}),
|
|
221
|
+
/**
|
|
222
|
+
* Create a DateTime field value
|
|
223
|
+
* @param value - Date object or RFC3339 string
|
|
224
|
+
*/
|
|
225
|
+
dateTime: (value) => ({
|
|
226
|
+
type: "DateTime",
|
|
227
|
+
value: value instanceof Date ? value.toISOString() : value,
|
|
228
|
+
}),
|
|
229
|
+
/**
|
|
230
|
+
* Create a Duration field value
|
|
231
|
+
* @param milliseconds - Duration in milliseconds
|
|
232
|
+
*/
|
|
233
|
+
duration: (milliseconds) => ({
|
|
234
|
+
type: "Duration",
|
|
235
|
+
value: milliseconds,
|
|
236
|
+
}),
|
|
237
|
+
/**
|
|
238
|
+
* Create a Number field value (flexible numeric type)
|
|
239
|
+
* @param value - Integer or float
|
|
240
|
+
*/
|
|
241
|
+
number: (value) => ({
|
|
242
|
+
type: "Number",
|
|
243
|
+
value,
|
|
244
|
+
}),
|
|
245
|
+
/**
|
|
246
|
+
* Create a Set field value (unique elements)
|
|
247
|
+
* @param values - Array of values (duplicates will be removed by server)
|
|
248
|
+
*/
|
|
249
|
+
set: (values) => ({
|
|
250
|
+
type: "Set",
|
|
251
|
+
value: values,
|
|
252
|
+
}),
|
|
253
|
+
/**
|
|
254
|
+
* Create a Vector field value (for embeddings/similarity search)
|
|
255
|
+
* @param values - Array of numbers representing the vector
|
|
256
|
+
*/
|
|
257
|
+
vector: (values) => ({
|
|
258
|
+
type: "Vector",
|
|
259
|
+
value: values,
|
|
260
|
+
}),
|
|
261
|
+
/**
|
|
262
|
+
* Create a Binary field value
|
|
263
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
264
|
+
*/
|
|
265
|
+
binary: (value) => ({
|
|
266
|
+
type: "Binary",
|
|
267
|
+
value: value instanceof Uint8Array ? btoa(String.fromCharCode(...value)) : value,
|
|
268
|
+
}),
|
|
269
|
+
/**
|
|
270
|
+
* Create a Bytes field value
|
|
271
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
272
|
+
*/
|
|
273
|
+
bytes: (value) => ({
|
|
274
|
+
type: "Bytes",
|
|
275
|
+
value: value instanceof Uint8Array ? btoa(String.fromCharCode(...value)) : value,
|
|
276
|
+
}),
|
|
277
|
+
/**
|
|
278
|
+
* Create an Array field value
|
|
279
|
+
* @param values - Array of values
|
|
280
|
+
*/
|
|
281
|
+
array: (values) => ({
|
|
282
|
+
type: "Array",
|
|
283
|
+
value: values,
|
|
284
|
+
}),
|
|
285
|
+
/**
|
|
286
|
+
* Create an Object field value
|
|
287
|
+
* @param value - Object/map of key-value pairs
|
|
288
|
+
*/
|
|
289
|
+
object: (value) => ({
|
|
290
|
+
type: "Object",
|
|
291
|
+
value,
|
|
292
|
+
}),
|
|
293
|
+
/**
|
|
294
|
+
* Create a String field value (explicit wrapping)
|
|
295
|
+
* @param value - String value
|
|
296
|
+
*/
|
|
297
|
+
string: (value) => ({
|
|
298
|
+
type: "String",
|
|
299
|
+
value,
|
|
300
|
+
}),
|
|
301
|
+
/**
|
|
302
|
+
* Create an Integer field value (explicit wrapping)
|
|
303
|
+
* @param value - Integer value
|
|
304
|
+
*/
|
|
305
|
+
integer: (value) => ({
|
|
306
|
+
type: "Integer",
|
|
307
|
+
value: Math.floor(value),
|
|
308
|
+
}),
|
|
309
|
+
/**
|
|
310
|
+
* Create a Float field value (explicit wrapping)
|
|
311
|
+
* @param value - Float value
|
|
312
|
+
*/
|
|
313
|
+
float: (value) => ({
|
|
314
|
+
type: "Float",
|
|
315
|
+
value,
|
|
316
|
+
}),
|
|
317
|
+
/**
|
|
318
|
+
* Create a Boolean field value (explicit wrapping)
|
|
319
|
+
* @param value - Boolean value
|
|
320
|
+
*/
|
|
321
|
+
boolean: (value) => ({
|
|
322
|
+
type: "Boolean",
|
|
323
|
+
value,
|
|
324
|
+
}),
|
|
325
|
+
};
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -441,6 +441,9 @@ export class EkoDBClient {
|
|
|
441
441
|
|
|
442
442
|
/**
|
|
443
443
|
* Insert a document into a collection
|
|
444
|
+
* @param collection - Collection name
|
|
445
|
+
* @param record - Document to insert
|
|
446
|
+
* @param ttl - Optional TTL: duration string ("1h", "30m"), seconds ("3600"), or ISO8601 timestamp
|
|
444
447
|
*/
|
|
445
448
|
async insert(
|
|
446
449
|
collection: string,
|
|
@@ -449,7 +452,7 @@ export class EkoDBClient {
|
|
|
449
452
|
): Promise<Record> {
|
|
450
453
|
const data = { ...record };
|
|
451
454
|
if (ttl) {
|
|
452
|
-
data.
|
|
455
|
+
data.ttl = ttl;
|
|
453
456
|
}
|
|
454
457
|
return this.makeRequest<Record>("POST", `/api/insert/${collection}`, data);
|
|
455
458
|
}
|
|
@@ -575,13 +578,20 @@ export class EkoDBClient {
|
|
|
575
578
|
}
|
|
576
579
|
|
|
577
580
|
/**
|
|
578
|
-
* Set a key-value pair
|
|
581
|
+
* Set a key-value pair with optional TTL
|
|
582
|
+
* @param key - The key to set
|
|
583
|
+
* @param value - The value to store
|
|
584
|
+
* @param ttl - Optional TTL in seconds
|
|
579
585
|
*/
|
|
580
|
-
async kvSet(key: string, value: any): Promise<void> {
|
|
586
|
+
async kvSet(key: string, value: any, ttl?: number): Promise<void> {
|
|
587
|
+
const body: any = { value };
|
|
588
|
+
if (ttl !== undefined) {
|
|
589
|
+
body.ttl = ttl;
|
|
590
|
+
}
|
|
581
591
|
await this.makeRequest<void>(
|
|
582
592
|
"POST",
|
|
583
593
|
`/api/kv/set/${encodeURIComponent(key)}`,
|
|
584
|
-
|
|
594
|
+
body,
|
|
585
595
|
0,
|
|
586
596
|
true, // Force JSON for KV operations
|
|
587
597
|
);
|
|
@@ -614,6 +624,116 @@ export class EkoDBClient {
|
|
|
614
624
|
);
|
|
615
625
|
}
|
|
616
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Check if a key exists
|
|
629
|
+
* @param key - The key to check
|
|
630
|
+
* @returns true if the key exists, false otherwise
|
|
631
|
+
*/
|
|
632
|
+
async kvExists(key: string): Promise<boolean> {
|
|
633
|
+
try {
|
|
634
|
+
const result = await this.kvGet(key);
|
|
635
|
+
return result !== null && result !== undefined;
|
|
636
|
+
} catch {
|
|
637
|
+
return false;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Query/find KV entries with pattern matching
|
|
643
|
+
* @param options - Query options including pattern and include_expired
|
|
644
|
+
* @returns Array of matching records
|
|
645
|
+
*/
|
|
646
|
+
async kvFind(options?: {
|
|
647
|
+
pattern?: string;
|
|
648
|
+
include_expired?: boolean;
|
|
649
|
+
}): Promise<any[]> {
|
|
650
|
+
const result = await this.makeRequest<any[]>(
|
|
651
|
+
"POST",
|
|
652
|
+
"/api/kv/find",
|
|
653
|
+
options || {},
|
|
654
|
+
0,
|
|
655
|
+
true, // Force JSON for KV operations
|
|
656
|
+
);
|
|
657
|
+
return result;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Alias for kvFind - query KV store with pattern
|
|
662
|
+
*/
|
|
663
|
+
async kvQuery(options?: {
|
|
664
|
+
pattern?: string;
|
|
665
|
+
include_expired?: boolean;
|
|
666
|
+
}): Promise<any[]> {
|
|
667
|
+
return this.kvFind(options);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// ============================================================================
|
|
671
|
+
// Transaction Operations
|
|
672
|
+
// ============================================================================
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Begin a new transaction
|
|
676
|
+
* @param isolationLevel - Transaction isolation level (default: "ReadCommitted")
|
|
677
|
+
* @returns Transaction ID
|
|
678
|
+
*/
|
|
679
|
+
async beginTransaction(
|
|
680
|
+
isolationLevel: string = "ReadCommitted",
|
|
681
|
+
): Promise<string> {
|
|
682
|
+
const result = await this.makeRequest<{ transaction_id: string }>(
|
|
683
|
+
"POST",
|
|
684
|
+
"/api/transactions",
|
|
685
|
+
{ isolation_level: isolationLevel },
|
|
686
|
+
0,
|
|
687
|
+
true,
|
|
688
|
+
);
|
|
689
|
+
return result.transaction_id;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Get transaction status
|
|
694
|
+
* @param transactionId - The transaction ID
|
|
695
|
+
* @returns Transaction status object
|
|
696
|
+
*/
|
|
697
|
+
async getTransactionStatus(
|
|
698
|
+
transactionId: string,
|
|
699
|
+
): Promise<{ state: string; operations_count: number }> {
|
|
700
|
+
return this.makeRequest<{ state: string; operations_count: number }>(
|
|
701
|
+
"GET",
|
|
702
|
+
`/api/transactions/${encodeURIComponent(transactionId)}`,
|
|
703
|
+
undefined,
|
|
704
|
+
0,
|
|
705
|
+
true,
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Commit a transaction
|
|
711
|
+
* @param transactionId - The transaction ID to commit
|
|
712
|
+
*/
|
|
713
|
+
async commitTransaction(transactionId: string): Promise<void> {
|
|
714
|
+
await this.makeRequest<void>(
|
|
715
|
+
"POST",
|
|
716
|
+
`/api/transactions/${encodeURIComponent(transactionId)}/commit`,
|
|
717
|
+
undefined,
|
|
718
|
+
0,
|
|
719
|
+
true,
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Rollback a transaction
|
|
725
|
+
* @param transactionId - The transaction ID to rollback
|
|
726
|
+
*/
|
|
727
|
+
async rollbackTransaction(transactionId: string): Promise<void> {
|
|
728
|
+
await this.makeRequest<void>(
|
|
729
|
+
"POST",
|
|
730
|
+
`/api/transactions/${encodeURIComponent(transactionId)}/rollback`,
|
|
731
|
+
undefined,
|
|
732
|
+
0,
|
|
733
|
+
true,
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
|
|
617
737
|
/**
|
|
618
738
|
* List all collections
|
|
619
739
|
*/
|
package/src/functions.ts
CHANGED
|
@@ -187,6 +187,31 @@ export type FunctionStageConfig =
|
|
|
187
187
|
| {
|
|
188
188
|
type: "ReleaseSavepoint";
|
|
189
189
|
name: string;
|
|
190
|
+
}
|
|
191
|
+
| {
|
|
192
|
+
type: "KvGet";
|
|
193
|
+
key: string;
|
|
194
|
+
output_field?: string;
|
|
195
|
+
}
|
|
196
|
+
| {
|
|
197
|
+
type: "KvSet";
|
|
198
|
+
key: string;
|
|
199
|
+
value: any;
|
|
200
|
+
ttl?: number;
|
|
201
|
+
}
|
|
202
|
+
| {
|
|
203
|
+
type: "KvDelete";
|
|
204
|
+
key: string;
|
|
205
|
+
}
|
|
206
|
+
| {
|
|
207
|
+
type: "KvExists";
|
|
208
|
+
key: string;
|
|
209
|
+
output_field?: string;
|
|
210
|
+
}
|
|
211
|
+
| {
|
|
212
|
+
type: "KvQuery";
|
|
213
|
+
pattern?: string;
|
|
214
|
+
include_expired?: boolean;
|
|
190
215
|
};
|
|
191
216
|
|
|
192
217
|
export interface ChatMessage {
|
|
@@ -572,4 +597,38 @@ export const Stage = {
|
|
|
572
597
|
type: "ReleaseSavepoint",
|
|
573
598
|
name,
|
|
574
599
|
}),
|
|
600
|
+
|
|
601
|
+
// KV Store operations - faster than collection lookups for simple key-value data
|
|
602
|
+
kvGet: (key: string, output_field?: string): FunctionStageConfig => ({
|
|
603
|
+
type: "KvGet",
|
|
604
|
+
key,
|
|
605
|
+
output_field,
|
|
606
|
+
}),
|
|
607
|
+
|
|
608
|
+
kvSet: (key: string, value: any, ttl?: number): FunctionStageConfig => ({
|
|
609
|
+
type: "KvSet",
|
|
610
|
+
key,
|
|
611
|
+
value,
|
|
612
|
+
ttl,
|
|
613
|
+
}),
|
|
614
|
+
|
|
615
|
+
kvDelete: (key: string): FunctionStageConfig => ({
|
|
616
|
+
type: "KvDelete",
|
|
617
|
+
key,
|
|
618
|
+
}),
|
|
619
|
+
|
|
620
|
+
kvExists: (key: string, output_field?: string): FunctionStageConfig => ({
|
|
621
|
+
type: "KvExists",
|
|
622
|
+
key,
|
|
623
|
+
output_field,
|
|
624
|
+
}),
|
|
625
|
+
|
|
626
|
+
kvQuery: (
|
|
627
|
+
pattern?: string,
|
|
628
|
+
include_expired?: boolean,
|
|
629
|
+
): FunctionStageConfig => ({
|
|
630
|
+
type: "KvQuery",
|
|
631
|
+
pattern,
|
|
632
|
+
include_expired,
|
|
633
|
+
}),
|
|
575
634
|
};
|
package/src/index.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -191,3 +191,165 @@ export function extractRecord<T extends Record<string, any>>(record: any): T {
|
|
|
191
191
|
}
|
|
192
192
|
return result as T;
|
|
193
193
|
}
|
|
194
|
+
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// Wrapped Type Builders
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// These functions create wrapped type objects for sending to ekoDB.
|
|
199
|
+
// Use these when inserting/updating records with special field types.
|
|
200
|
+
//
|
|
201
|
+
// Example:
|
|
202
|
+
// await client.insert("orders", {
|
|
203
|
+
// id: Field.uuid("550e8400-e29b-41d4-a716-446655440000"),
|
|
204
|
+
// total: Field.decimal("99.99"),
|
|
205
|
+
// created_at: Field.dateTime(new Date()),
|
|
206
|
+
// tags: Field.set(["sale", "featured"]),
|
|
207
|
+
// });
|
|
208
|
+
|
|
209
|
+
export interface WrappedFieldValue {
|
|
210
|
+
type: string;
|
|
211
|
+
value: unknown;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Field builders for creating wrapped type values to send to ekoDB.
|
|
216
|
+
* These are the inverse of the getValue* extraction functions.
|
|
217
|
+
*/
|
|
218
|
+
export const Field = {
|
|
219
|
+
/**
|
|
220
|
+
* Create a UUID field value
|
|
221
|
+
* @param value - UUID string (e.g., "550e8400-e29b-41d4-a716-446655440000")
|
|
222
|
+
*/
|
|
223
|
+
uuid: (value: string): WrappedFieldValue => ({
|
|
224
|
+
type: "UUID",
|
|
225
|
+
value,
|
|
226
|
+
}),
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Create a Decimal field value for precise numeric values
|
|
230
|
+
* @param value - Decimal as string (e.g., "99.99") to preserve precision
|
|
231
|
+
*/
|
|
232
|
+
decimal: (value: string): WrappedFieldValue => ({
|
|
233
|
+
type: "Decimal",
|
|
234
|
+
value,
|
|
235
|
+
}),
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Create a DateTime field value
|
|
239
|
+
* @param value - Date object or RFC3339 string
|
|
240
|
+
*/
|
|
241
|
+
dateTime: (value: Date | string): WrappedFieldValue => ({
|
|
242
|
+
type: "DateTime",
|
|
243
|
+
value: value instanceof Date ? value.toISOString() : value,
|
|
244
|
+
}),
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Create a Duration field value
|
|
248
|
+
* @param milliseconds - Duration in milliseconds
|
|
249
|
+
*/
|
|
250
|
+
duration: (milliseconds: number): WrappedFieldValue => ({
|
|
251
|
+
type: "Duration",
|
|
252
|
+
value: milliseconds,
|
|
253
|
+
}),
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Create a Number field value (flexible numeric type)
|
|
257
|
+
* @param value - Integer or float
|
|
258
|
+
*/
|
|
259
|
+
number: (value: number): WrappedFieldValue => ({
|
|
260
|
+
type: "Number",
|
|
261
|
+
value,
|
|
262
|
+
}),
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Create a Set field value (unique elements)
|
|
266
|
+
* @param values - Array of values (duplicates will be removed by server)
|
|
267
|
+
*/
|
|
268
|
+
set: <T>(values: T[]): WrappedFieldValue => ({
|
|
269
|
+
type: "Set",
|
|
270
|
+
value: values,
|
|
271
|
+
}),
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Create a Vector field value (for embeddings/similarity search)
|
|
275
|
+
* @param values - Array of numbers representing the vector
|
|
276
|
+
*/
|
|
277
|
+
vector: (values: number[]): WrappedFieldValue => ({
|
|
278
|
+
type: "Vector",
|
|
279
|
+
value: values,
|
|
280
|
+
}),
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Create a Binary field value
|
|
284
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
285
|
+
*/
|
|
286
|
+
binary: (value: string | Uint8Array): WrappedFieldValue => ({
|
|
287
|
+
type: "Binary",
|
|
288
|
+
value:
|
|
289
|
+
value instanceof Uint8Array ? btoa(String.fromCharCode(...value)) : value,
|
|
290
|
+
}),
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Create a Bytes field value
|
|
294
|
+
* @param value - Base64 encoded string or Uint8Array
|
|
295
|
+
*/
|
|
296
|
+
bytes: (value: string | Uint8Array): WrappedFieldValue => ({
|
|
297
|
+
type: "Bytes",
|
|
298
|
+
value:
|
|
299
|
+
value instanceof Uint8Array ? btoa(String.fromCharCode(...value)) : value,
|
|
300
|
+
}),
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Create an Array field value
|
|
304
|
+
* @param values - Array of values
|
|
305
|
+
*/
|
|
306
|
+
array: <T>(values: T[]): WrappedFieldValue => ({
|
|
307
|
+
type: "Array",
|
|
308
|
+
value: values,
|
|
309
|
+
}),
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Create an Object field value
|
|
313
|
+
* @param value - Object/map of key-value pairs
|
|
314
|
+
*/
|
|
315
|
+
object: (value: Record<string, unknown>): WrappedFieldValue => ({
|
|
316
|
+
type: "Object",
|
|
317
|
+
value,
|
|
318
|
+
}),
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Create a String field value (explicit wrapping)
|
|
322
|
+
* @param value - String value
|
|
323
|
+
*/
|
|
324
|
+
string: (value: string): WrappedFieldValue => ({
|
|
325
|
+
type: "String",
|
|
326
|
+
value,
|
|
327
|
+
}),
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Create an Integer field value (explicit wrapping)
|
|
331
|
+
* @param value - Integer value
|
|
332
|
+
*/
|
|
333
|
+
integer: (value: number): WrappedFieldValue => ({
|
|
334
|
+
type: "Integer",
|
|
335
|
+
value: Math.floor(value),
|
|
336
|
+
}),
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Create a Float field value (explicit wrapping)
|
|
340
|
+
* @param value - Float value
|
|
341
|
+
*/
|
|
342
|
+
float: (value: number): WrappedFieldValue => ({
|
|
343
|
+
type: "Float",
|
|
344
|
+
value,
|
|
345
|
+
}),
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Create a Boolean field value (explicit wrapping)
|
|
349
|
+
* @param value - Boolean value
|
|
350
|
+
*/
|
|
351
|
+
boolean: (value: boolean): WrappedFieldValue => ({
|
|
352
|
+
type: "Boolean",
|
|
353
|
+
value,
|
|
354
|
+
}),
|
|
355
|
+
};
|