@ekodb/ekodb-client 0.1.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 +329 -0
- package/dist/client.d.ts +404 -0
- package/dist/client.js +553 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +20 -0
- package/dist/join.d.ts +68 -0
- package/dist/join.js +71 -0
- package/dist/query-builder.d.ts +141 -0
- package/dist/query-builder.js +370 -0
- package/dist/schema.d.ts +189 -0
- package/dist/schema.js +186 -0
- package/dist/search.d.ts +172 -0
- package/dist/search.js +183 -0
- package/package.json +27 -0
- package/src/client.ts +757 -0
- package/src/index.ts +29 -0
- package/src/join.ts +102 -0
- package/src/query-builder.ts +419 -0
- package/src/schema.ts +285 -0
- package/src/search.ts +275 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# ekoDB TypeScript Client
|
|
2
|
+
|
|
3
|
+
Official TypeScript/JavaScript client library for ekoDB.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @ekodb/ekodb-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### TypeScript
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { EkoDBClient, RateLimitError } from "@ekodb/ekodb-client";
|
|
17
|
+
|
|
18
|
+
async function main() {
|
|
19
|
+
// Create and initialize client with configuration
|
|
20
|
+
const client = new EkoDBClient({
|
|
21
|
+
baseURL: "http://localhost:8080",
|
|
22
|
+
apiKey: "your-api-key",
|
|
23
|
+
shouldRetry: true, // Enable automatic retries (default: true)
|
|
24
|
+
maxRetries: 3, // Maximum retry attempts (default: 3)
|
|
25
|
+
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
26
|
+
});
|
|
27
|
+
await client.init();
|
|
28
|
+
|
|
29
|
+
// Or use the simple constructor (backward compatible)
|
|
30
|
+
// const client = new EkoDBClient("http://localhost:8080", "your-api-key");
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Insert a document
|
|
34
|
+
const record = {
|
|
35
|
+
name: "John Doe",
|
|
36
|
+
email: "john@example.com",
|
|
37
|
+
age: 30,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const inserted = await client.insert("users", record);
|
|
41
|
+
console.log("Inserted:", inserted);
|
|
42
|
+
|
|
43
|
+
// Check rate limit status
|
|
44
|
+
const rateLimitInfo = client.getRateLimitInfo();
|
|
45
|
+
if (rateLimitInfo) {
|
|
46
|
+
console.log(
|
|
47
|
+
`Rate limit: ${rateLimitInfo.remaining}/${rateLimitInfo.limit} remaining`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Find documents
|
|
52
|
+
const results = await client.find("users", { limit: 10 });
|
|
53
|
+
console.log(`Found ${results.length} documents`);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error instanceof RateLimitError) {
|
|
56
|
+
console.log(`Rate limited! Retry after ${error.retryAfterSecs} seconds`);
|
|
57
|
+
// Handle rate limiting manually if needed
|
|
58
|
+
} else {
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### JavaScript
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
const { EkoDBClient } = require("@ekodb/ekodb-client");
|
|
71
|
+
|
|
72
|
+
async function main() {
|
|
73
|
+
const client = new EkoDBClient("http://localhost:8080", "your-api-key");
|
|
74
|
+
await client.init();
|
|
75
|
+
|
|
76
|
+
const record = {
|
|
77
|
+
name: "John Doe",
|
|
78
|
+
email: "john@example.com",
|
|
79
|
+
age: 30,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const inserted = await client.insert("users", record);
|
|
83
|
+
console.log("Inserted:", inserted);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
main();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage Examples
|
|
90
|
+
|
|
91
|
+
### Query Builder
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { EkoDBClient, QueryBuilder } from "@ekodb/ekodb-client";
|
|
95
|
+
|
|
96
|
+
const client = new EkoDBClient("http://localhost:8080", "your-api-key");
|
|
97
|
+
await client.init();
|
|
98
|
+
|
|
99
|
+
// Simple query with operators
|
|
100
|
+
const query = new QueryBuilder()
|
|
101
|
+
.eq("status", "active")
|
|
102
|
+
.gte("age", 18)
|
|
103
|
+
.lt("age", 65)
|
|
104
|
+
.limit(10)
|
|
105
|
+
.build();
|
|
106
|
+
|
|
107
|
+
const results = await client.find("users", query);
|
|
108
|
+
|
|
109
|
+
// Complex query with sorting and pagination
|
|
110
|
+
const complexQuery = new QueryBuilder()
|
|
111
|
+
.in("status", ["active", "pending"])
|
|
112
|
+
.contains("email", "@example.com")
|
|
113
|
+
.sortDesc("created_at")
|
|
114
|
+
.skip(20)
|
|
115
|
+
.limit(10)
|
|
116
|
+
.build();
|
|
117
|
+
|
|
118
|
+
const users = await client.find("users", complexQuery);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Search Operations
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { SearchQuery } from "@ekodb/ekodb-client";
|
|
125
|
+
|
|
126
|
+
// Basic text search
|
|
127
|
+
const searchQuery: SearchQuery = {
|
|
128
|
+
query: "programming",
|
|
129
|
+
minScore: 0.1,
|
|
130
|
+
limit: 10,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const results = await client.search("articles", searchQuery);
|
|
134
|
+
for (const result of results.results) {
|
|
135
|
+
console.log(`Score: ${result.score.toFixed(4)} - ${result.record.title}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Search with field weights
|
|
139
|
+
const weightedSearch: SearchQuery = {
|
|
140
|
+
query: "rust database",
|
|
141
|
+
fields: ["title", "description"],
|
|
142
|
+
weights: { title: 2.0 },
|
|
143
|
+
limit: 5,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const searchResults = await client.search("articles", weightedSearch);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Schema Management
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { SchemaBuilder, FieldTypeSchemaBuilder } from "@ekodb/ekodb-client";
|
|
153
|
+
|
|
154
|
+
// Create a collection with schema
|
|
155
|
+
const schema = new SchemaBuilder()
|
|
156
|
+
.addField(
|
|
157
|
+
"name",
|
|
158
|
+
new FieldTypeSchemaBuilder("String").required().pattern("^[a-zA-Z ]+$"),
|
|
159
|
+
)
|
|
160
|
+
.addField("email", new FieldTypeSchemaBuilder("String").required().unique())
|
|
161
|
+
.addField("age", new FieldTypeSchemaBuilder("Integer").range(0, 150))
|
|
162
|
+
.build();
|
|
163
|
+
|
|
164
|
+
await client.createCollection("users", schema);
|
|
165
|
+
|
|
166
|
+
// Get collection schema
|
|
167
|
+
const retrievedSchema = await client.getSchema("users");
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Join Operations
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { JoinBuilder } from "@ekodb/ekodb-client";
|
|
174
|
+
|
|
175
|
+
// Single collection join
|
|
176
|
+
const join = JoinBuilder.single(
|
|
177
|
+
"departments",
|
|
178
|
+
"department_id",
|
|
179
|
+
"id",
|
|
180
|
+
"department",
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const query = new QueryBuilder().join(join).limit(10).build();
|
|
184
|
+
|
|
185
|
+
const results = await client.find("users", query);
|
|
186
|
+
|
|
187
|
+
// Multi-collection join
|
|
188
|
+
const multiJoin = JoinBuilder.multi(
|
|
189
|
+
["departments", "profiles"],
|
|
190
|
+
"department_id",
|
|
191
|
+
"id",
|
|
192
|
+
"related_data",
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const multiQuery = new QueryBuilder().join(multiJoin).build();
|
|
196
|
+
|
|
197
|
+
const joinResults = await client.find("users", multiQuery);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Features
|
|
201
|
+
|
|
202
|
+
- ✅ Full TypeScript support with type definitions
|
|
203
|
+
- ✅ CRUD operations
|
|
204
|
+
- ✅ Batch operations
|
|
205
|
+
- ✅ Key-value operations
|
|
206
|
+
- ✅ Collection management
|
|
207
|
+
- ✅ WebSocket support
|
|
208
|
+
- ✅ TTL support
|
|
209
|
+
- ✅ Automatic token management
|
|
210
|
+
- ✅ **Query Builder** - Fluent API for complex queries with operators, sorting,
|
|
211
|
+
and pagination
|
|
212
|
+
- ✅ **Search** - Full-text search, fuzzy search, and field-specific search with
|
|
213
|
+
scoring
|
|
214
|
+
- ✅ **Schema Management** - Define and enforce data schemas with validation
|
|
215
|
+
- ✅ **Join Operations** - Single and multi-collection joins with queries
|
|
216
|
+
- ✅ **Rate limiting with automatic retry** (429, 503, network errors)
|
|
217
|
+
- ✅ **Rate limit tracking** (`X-RateLimit-*` headers)
|
|
218
|
+
- ✅ **Configurable retry behavior**
|
|
219
|
+
- ✅ **Retry-After header support**
|
|
220
|
+
|
|
221
|
+
## API Reference
|
|
222
|
+
|
|
223
|
+
### Client Methods
|
|
224
|
+
|
|
225
|
+
#### Constructor
|
|
226
|
+
|
|
227
|
+
- `new EkoDBClient(config: ClientConfig | string, apiKey?: string)` - Create
|
|
228
|
+
client with config object or legacy (baseURL, apiKey) signature
|
|
229
|
+
|
|
230
|
+
#### Configuration
|
|
231
|
+
|
|
232
|
+
- `init(): Promise<void>` - Initialize and get auth token
|
|
233
|
+
- `getRateLimitInfo(): RateLimitInfo | null` - Get current rate limit
|
|
234
|
+
information
|
|
235
|
+
- `isNearRateLimit(): boolean` - Check if approaching rate limit (<10%
|
|
236
|
+
remaining)
|
|
237
|
+
|
|
238
|
+
#### CRUD Operations
|
|
239
|
+
|
|
240
|
+
- `insert(collection: string, record: Record, ttl?: string): Promise<Record>`
|
|
241
|
+
- `find(collection: string, query?: Query): Promise<Record[]>`
|
|
242
|
+
- `findByID(collection: string, id: string): Promise<Record>`
|
|
243
|
+
- `update(collection: string, id: string, record: Record): Promise<Record>`
|
|
244
|
+
- `delete(collection: string, id: string): Promise<void>`
|
|
245
|
+
|
|
246
|
+
#### Batch Operations
|
|
247
|
+
|
|
248
|
+
- `batchInsert(collection: string, records: Record[]): Promise<Record[]>`
|
|
249
|
+
- `batchUpdate(collection: string, updates: Array<{id: string, data: Record}>): Promise<Record[]>`
|
|
250
|
+
- `batchDelete(collection: string, ids: string[]): Promise<number>`
|
|
251
|
+
|
|
252
|
+
#### Key-Value Operations
|
|
253
|
+
|
|
254
|
+
- `kvSet(key: string, value: any): Promise<void>`
|
|
255
|
+
- `kvGet(key: string): Promise<any>`
|
|
256
|
+
- `kvDelete(key: string): Promise<void>`
|
|
257
|
+
|
|
258
|
+
#### Query Builder
|
|
259
|
+
|
|
260
|
+
- `new QueryBuilder()` - Create a new query builder
|
|
261
|
+
- `.eq(field, value)` - Equal to
|
|
262
|
+
- `.ne(field, value)` - Not equal to
|
|
263
|
+
- `.gt(field, value)` - Greater than
|
|
264
|
+
- `.gte(field, value)` - Greater than or equal
|
|
265
|
+
- `.lt(field, value)` - Less than
|
|
266
|
+
- `.lte(field, value)` - Less than or equal
|
|
267
|
+
- `.in(field, values)` - In array
|
|
268
|
+
- `.nin(field, values)` - Not in array
|
|
269
|
+
- `.contains(field, value)` - String contains
|
|
270
|
+
- `.startsWith(field, value)` - String starts with
|
|
271
|
+
- `.endsWith(field, value)` - String ends with
|
|
272
|
+
- `.regex(field, pattern)` - Regex match
|
|
273
|
+
- `.sortAsc(field)` / `.sortDesc(field)` - Sorting
|
|
274
|
+
- `.limit(n)` / `.skip(n)` - Pagination
|
|
275
|
+
- `.join(joinConfig)` - Add join configuration
|
|
276
|
+
- `.build()` - Build the query
|
|
277
|
+
|
|
278
|
+
#### Search Operations
|
|
279
|
+
|
|
280
|
+
- `search(collection: string, query: SearchQuery): Promise<SearchResults>` -
|
|
281
|
+
Full-text search
|
|
282
|
+
|
|
283
|
+
#### Schema Management
|
|
284
|
+
|
|
285
|
+
- `createCollection(collection: string, schema: Schema): Promise<void>` - Create
|
|
286
|
+
collection with schema
|
|
287
|
+
- `getSchema(collection: string): Promise<Schema>` - Get collection schema
|
|
288
|
+
- `getCollection(collection: string): Promise<CollectionMetadata>` - Get
|
|
289
|
+
collection metadata
|
|
290
|
+
|
|
291
|
+
#### Join Operations
|
|
292
|
+
|
|
293
|
+
- `JoinBuilder.single(collection, localField, foreignField, as)` - Single
|
|
294
|
+
collection join
|
|
295
|
+
- `JoinBuilder.multi(collections, localField, foreignField, as)` -
|
|
296
|
+
Multi-collection join
|
|
297
|
+
|
|
298
|
+
#### Collection Management
|
|
299
|
+
|
|
300
|
+
- `listCollections(): Promise<string[]>`
|
|
301
|
+
- `deleteCollection(collection: string): Promise<void>`
|
|
302
|
+
|
|
303
|
+
#### WebSocket
|
|
304
|
+
|
|
305
|
+
- `websocket(wsURL: string): WebSocketClient`
|
|
306
|
+
|
|
307
|
+
### WebSocket Methods
|
|
308
|
+
|
|
309
|
+
- `findAll(collection: string): Promise<Record[]>`
|
|
310
|
+
- `close(): void`
|
|
311
|
+
|
|
312
|
+
## Examples
|
|
313
|
+
|
|
314
|
+
See the
|
|
315
|
+
[examples directory](https://github.com/ekoDB/ekodb/tree/main/examples/typescript)
|
|
316
|
+
for complete working examples:
|
|
317
|
+
|
|
318
|
+
- `client_simple_crud.ts` - Basic CRUD operations
|
|
319
|
+
- `client_query_builder.ts` - Complex queries with QueryBuilder
|
|
320
|
+
- `client_search.ts` - Full-text search operations
|
|
321
|
+
- `client_schema.ts` - Schema management
|
|
322
|
+
- `client_joins.ts` - Join operations
|
|
323
|
+
- `client_batch_operations.ts` - Batch operations
|
|
324
|
+
- `client_kv_operations.ts` - Key-value operations
|
|
325
|
+
- And more...
|
|
326
|
+
|
|
327
|
+
## License
|
|
328
|
+
|
|
329
|
+
MIT
|