@onchaindb/sdk 0.4.5 → 1.0.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.
Files changed (97) hide show
  1. package/.claude/settings.local.json +10 -2
  2. package/README.md +422 -355
  3. package/dist/batch.d.ts +1 -10
  4. package/dist/batch.d.ts.map +1 -1
  5. package/dist/batch.js +4 -26
  6. package/dist/batch.js.map +1 -1
  7. package/dist/client.d.ts +29 -43
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +198 -323
  10. package/dist/client.js.map +1 -1
  11. package/dist/database.d.ts +14 -131
  12. package/dist/database.d.ts.map +1 -1
  13. package/dist/database.js +35 -131
  14. package/dist/database.js.map +1 -1
  15. package/dist/index.d.ts +6 -9
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -15
  18. package/dist/index.js.map +1 -1
  19. package/dist/query-sdk/ConditionBuilder.d.ts +3 -11
  20. package/dist/query-sdk/ConditionBuilder.d.ts.map +1 -1
  21. package/dist/query-sdk/ConditionBuilder.js +10 -48
  22. package/dist/query-sdk/ConditionBuilder.js.map +1 -1
  23. package/dist/query-sdk/NestedBuilders.d.ts +33 -30
  24. package/dist/query-sdk/NestedBuilders.d.ts.map +1 -1
  25. package/dist/query-sdk/NestedBuilders.js +46 -43
  26. package/dist/query-sdk/NestedBuilders.js.map +1 -1
  27. package/dist/query-sdk/QueryBuilder.d.ts +4 -2
  28. package/dist/query-sdk/QueryBuilder.d.ts.map +1 -1
  29. package/dist/query-sdk/QueryBuilder.js +47 -169
  30. package/dist/query-sdk/QueryBuilder.js.map +1 -1
  31. package/dist/query-sdk/QueryResult.d.ts +0 -38
  32. package/dist/query-sdk/QueryResult.d.ts.map +1 -1
  33. package/dist/query-sdk/QueryResult.js +1 -227
  34. package/dist/query-sdk/QueryResult.js.map +1 -1
  35. package/dist/query-sdk/index.d.ts +1 -1
  36. package/dist/query-sdk/index.d.ts.map +1 -1
  37. package/dist/query-sdk/index.js.map +1 -1
  38. package/dist/query-sdk/operators.d.ts +32 -28
  39. package/dist/query-sdk/operators.d.ts.map +1 -1
  40. package/dist/query-sdk/operators.js +45 -155
  41. package/dist/query-sdk/operators.js.map +1 -1
  42. package/dist/types.d.ts +153 -1
  43. package/dist/types.d.ts.map +1 -1
  44. package/dist/types.js.map +1 -1
  45. package/jest.config.js +4 -0
  46. package/package.json +1 -1
  47. package/skills.md +0 -1
  48. package/src/client.ts +242 -745
  49. package/src/database.ts +70 -493
  50. package/src/index.ts +40 -193
  51. package/src/query-sdk/ConditionBuilder.ts +37 -89
  52. package/src/query-sdk/NestedBuilders.ts +90 -92
  53. package/src/query-sdk/QueryBuilder.ts +59 -218
  54. package/src/query-sdk/QueryResult.ts +4 -330
  55. package/src/query-sdk/README.md +214 -583
  56. package/src/query-sdk/index.ts +1 -1
  57. package/src/query-sdk/operators.ts +91 -200
  58. package/src/query-sdk/tests/FieldConditionBuilder.test.ts +70 -71
  59. package/src/query-sdk/tests/LogicalOperator.test.ts +43 -82
  60. package/src/query-sdk/tests/NestedBuilders.test.ts +229 -309
  61. package/src/query-sdk/tests/QueryBuilder.test.ts +5 -5
  62. package/src/query-sdk/tests/QueryResult.test.ts +41 -435
  63. package/src/query-sdk/tests/comprehensive.test.ts +4 -185
  64. package/src/tests/client-requests.test.ts +280 -0
  65. package/src/tests/client-validation.test.ts +80 -0
  66. package/src/types.ts +229 -8
  67. package/src/batch.ts +0 -257
  68. package/src/query-sdk/dist/ConditionBuilder.d.ts +0 -22
  69. package/src/query-sdk/dist/ConditionBuilder.js +0 -90
  70. package/src/query-sdk/dist/FieldConditionBuilder.d.ts +0 -1
  71. package/src/query-sdk/dist/FieldConditionBuilder.js +0 -6
  72. package/src/query-sdk/dist/NestedBuilders.d.ts +0 -43
  73. package/src/query-sdk/dist/NestedBuilders.js +0 -144
  74. package/src/query-sdk/dist/OnChainDB.d.ts +0 -19
  75. package/src/query-sdk/dist/OnChainDB.js +0 -123
  76. package/src/query-sdk/dist/QueryBuilder.d.ts +0 -70
  77. package/src/query-sdk/dist/QueryBuilder.js +0 -295
  78. package/src/query-sdk/dist/QueryResult.d.ts +0 -52
  79. package/src/query-sdk/dist/QueryResult.js +0 -293
  80. package/src/query-sdk/dist/SelectionBuilder.d.ts +0 -20
  81. package/src/query-sdk/dist/SelectionBuilder.js +0 -80
  82. package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +0 -27
  83. package/src/query-sdk/dist/adapters/HttpClientAdapter.js +0 -170
  84. package/src/query-sdk/dist/index.d.ts +0 -36
  85. package/src/query-sdk/dist/index.js +0 -27
  86. package/src/query-sdk/dist/operators.d.ts +0 -56
  87. package/src/query-sdk/dist/operators.js +0 -289
  88. package/src/query-sdk/dist/tests/setup.d.ts +0 -15
  89. package/src/query-sdk/dist/tests/setup.js +0 -46
  90. package/src/query-sdk/jest.config.js +0 -25
  91. package/src/query-sdk/package.json +0 -46
  92. package/src/query-sdk/tests/aggregations.test.ts +0 -653
  93. package/src/query-sdk/tests/integration.test.ts +0 -608
  94. package/src/query-sdk/tests/operators.test.ts +0 -327
  95. package/src/query-sdk/tests/unit.test.ts +0 -794
  96. package/src/query-sdk/tsconfig.json +0 -26
  97. package/src/query-sdk/yarn.lock +0 -3092
@@ -1,4 +1,5 @@
1
- // Query result utilities class matching Rust SDK functionality
1
+ // Lightweight wrapper around query response data.
2
+ // Aggregation, sorting, filtering, and joining are handled server-side via QueryBuilder.
2
3
  export class QueryResult<T = any> {
3
4
  public data: T[];
4
5
 
@@ -6,14 +7,12 @@ export class QueryResult<T = any> {
6
7
  this.data = Array.isArray(data) ? data : [data];
7
8
  }
8
9
 
9
- // ===== BASIC UTILITIES =====
10
-
11
10
  len(): number {
12
11
  return this.data.length;
13
12
  }
14
13
 
15
14
  length(): number {
16
- return this.len();
15
+ return this.data.length;
17
16
  }
18
17
 
19
18
  isEmpty(): boolean {
@@ -32,230 +31,6 @@ export class QueryResult<T = any> {
32
31
  return this.data[index];
33
32
  }
34
33
 
35
- // ===== ITERATION UTILITIES =====
36
-
37
- any(predicate: (item: T) => boolean): boolean {
38
- return this.data.some(predicate);
39
- }
40
-
41
- all(predicate: (item: T) => boolean): boolean {
42
- return this.data.every(predicate);
43
- }
44
-
45
- find(predicate: (item: T) => boolean): T | undefined {
46
- return this.data.find(predicate);
47
- }
48
-
49
- filter(predicate: (item: T) => boolean): T[] {
50
- return this.data.filter(predicate);
51
- }
52
-
53
- map<U>(transform: (item: T) => U): U[] {
54
- return this.data.map(transform);
55
- }
56
-
57
- forEach(callback: (item: T, index: number) => void): void {
58
- this.data.forEach(callback);
59
- }
60
-
61
- reduce<U>(callback: (accumulator: U, item: T, index: number) => U, initialValue: U): U {
62
- return this.data.reduce(callback, initialValue);
63
- }
64
-
65
- // ===== AGGREGATION UTILITIES =====
66
-
67
- groupBy(field: string): Record<string, T[]> {
68
- const groups: Record<string, T[]> = {};
69
-
70
- this.data.forEach(item => {
71
- const key = this.getNestedValue(item, field);
72
- const keyString = String(key ?? 'null');
73
-
74
- if (!groups[keyString]) {
75
- groups[keyString] = [];
76
- }
77
- groups[keyString].push(item);
78
- });
79
-
80
- return groups;
81
- }
82
-
83
- // Pluck values from a specific field across all records
84
- pluck(field: string): any[] {
85
- return this.data.map(item => this.getNestedValue(item, field));
86
- }
87
-
88
- pluckStrings(field: string): (string | null)[] {
89
- return this.data.map(item => {
90
- const value = this.getNestedValue(item, field);
91
- return typeof value === 'string' ? value : (value != null ? String(value) : null);
92
- });
93
- }
94
-
95
- pluckNumbers(field: string): (number | null)[] {
96
- return this.data.map(item => {
97
- const value = this.getNestedValue(item, field);
98
- if (typeof value === 'number' && !isNaN(value)) {
99
- return value;
100
- }
101
- const parsed = Number(value);
102
- return !isNaN(parsed) ? parsed : null;
103
- });
104
- }
105
-
106
- // ===== NUMERIC SUMMARY =====
107
-
108
- summarizeNumeric(field: string): NumericSummary | null {
109
- const numbers = this.pluckNumbers(field).filter(n => n !== null) as number[];
110
-
111
- if (numbers.length === 0) {
112
- return null;
113
- }
114
-
115
- const sum = numbers.reduce((acc, n) => acc + n, 0);
116
- const mean = sum / numbers.length;
117
- const min = Math.min(...numbers);
118
- const max = Math.max(...numbers);
119
-
120
- // Calculate median
121
- const sortedNumbers = [...numbers].sort((a, b) => a - b);
122
- const mid = Math.floor(sortedNumbers.length / 2);
123
- const median = sortedNumbers.length % 2 !== 0
124
- ? sortedNumbers[mid]
125
- : (sortedNumbers[mid - 1] + sortedNumbers[mid]) / 2;
126
-
127
- // Calculate standard deviation
128
- const variance = numbers.reduce((acc, n) => acc + Math.pow(n - mean, 2), 0) / numbers.length;
129
- const standardDeviation = Math.sqrt(variance);
130
-
131
- return {
132
- count: numbers.length,
133
- sum,
134
- mean,
135
- median,
136
- min,
137
- max,
138
- standardDeviation,
139
- variance
140
- };
141
- }
142
-
143
- // ===== SORTING =====
144
-
145
- sortBy(field: string, ascending: boolean = true): T[] {
146
- const sorted = [...this.data].sort((a, b) => {
147
- const valueA = this.getNestedValue(a, field);
148
- const valueB = this.getNestedValue(b, field);
149
-
150
- // Handle null/undefined values
151
- if (valueA == null && valueB == null) return 0;
152
- if (valueA == null) return ascending ? -1 : 1;
153
- if (valueB == null) return ascending ? 1 : -1;
154
-
155
- // Compare values
156
- let comparison = 0;
157
- if (valueA < valueB) comparison = -1;
158
- else if (valueA > valueB) comparison = 1;
159
-
160
- return ascending ? comparison : -comparison;
161
- });
162
-
163
- return sorted;
164
- }
165
-
166
- // Multiple field sorting
167
- sortByMultiple(fields: Array<{field: string, ascending?: boolean}>): T[] {
168
- const sorted = [...this.data].sort((a, b) => {
169
- for (const {field, ascending = true} of fields) {
170
- const valueA = this.getNestedValue(a, field);
171
- const valueB = this.getNestedValue(b, field);
172
-
173
- // Handle null/undefined values
174
- if (valueA == null && valueB == null) continue;
175
- if (valueA == null) return ascending ? -1 : 1;
176
- if (valueB == null) return ascending ? 1 : -1;
177
-
178
- // Compare values
179
- let comparison = 0;
180
- if (valueA < valueB) comparison = -1;
181
- else if (valueA > valueB) comparison = 1;
182
-
183
- if (comparison !== 0) {
184
- return ascending ? comparison : -comparison;
185
- }
186
- }
187
- return 0;
188
- });
189
-
190
- return sorted;
191
- }
192
-
193
- // ===== PAGINATION =====
194
-
195
- paginate(page: number, pageSize: number): T[] {
196
- const startIndex = (page - 1) * pageSize;
197
- const endIndex = startIndex + pageSize;
198
- return this.data.slice(startIndex, endIndex);
199
- }
200
-
201
- chunk(size: number): T[][] {
202
- const chunks: T[][] = [];
203
- for (let i = 0; i < this.data.length; i += size) {
204
- chunks.push(this.data.slice(i, i + size));
205
- }
206
- return chunks;
207
- }
208
-
209
- // ===== DISTINCT/UNIQUE =====
210
-
211
- distinctBy(field: string): T[] {
212
- const seen = new Set();
213
- return this.data.filter(item => {
214
- const value = this.getNestedValue(item, field);
215
- const key = String(value);
216
- if (seen.has(key)) {
217
- return false;
218
- }
219
- seen.add(key);
220
- return true;
221
- });
222
- }
223
-
224
- unique(): T[] {
225
- return [...new Set(this.data)];
226
- }
227
-
228
- // ===== STATISTICAL FUNCTIONS =====
229
-
230
- count(predicate?: (item: T) => boolean): number {
231
- if (predicate) {
232
- return this.data.filter(predicate).length;
233
- }
234
- return this.data.length;
235
- }
236
-
237
- countBy(field: string): Record<string, number> {
238
- const counts: Record<string, number> = {};
239
-
240
- this.data.forEach(item => {
241
- const key = String(this.getNestedValue(item, field) ?? 'null');
242
- counts[key] = (counts[key] || 0) + 1;
243
- });
244
-
245
- return counts;
246
- }
247
-
248
- // ===== UTILITY METHODS =====
249
-
250
- // Get nested field value using dot notation
251
- private getNestedValue(obj: any, path: string): any {
252
- return path.split('.').reduce((current, key) => {
253
- return current && typeof current === 'object' ? current[key] : undefined;
254
- }, obj);
255
- }
256
-
257
- // ===== TRANSFORMATION =====
258
-
259
34
  toArray(): T[] {
260
35
  return [...this.data];
261
36
  }
@@ -264,112 +39,11 @@ export class QueryResult<T = any> {
264
39
  return JSON.stringify(this.data);
265
40
  }
266
41
 
267
- // Convert to QueryResult with different type
268
42
  cast<U>(): QueryResult<U> {
269
43
  return new QueryResult(this.data as unknown as U[]);
270
44
  }
271
-
272
- // ===== JOINING (similar to SQL joins) =====
273
-
274
- innerJoin<U>(
275
- other: QueryResult<U>,
276
- thisKey: string,
277
- otherKey: string
278
- ): Array<T & U> {
279
- const results: Array<T & U> = [];
280
-
281
- this.data.forEach(thisItem => {
282
- const thisValue = this.getNestedValue(thisItem, thisKey);
283
- other.data.forEach(otherItem => {
284
- const otherValue = this.getNestedValue(otherItem, otherKey);
285
- if (thisValue === otherValue) {
286
- results.push({...thisItem, ...otherItem});
287
- }
288
- });
289
- });
290
-
291
- return results;
292
- }
293
-
294
- leftJoin<U>(
295
- other: QueryResult<U>,
296
- thisKey: string,
297
- otherKey: string
298
- ): Array<T & Partial<U>> {
299
- const results: Array<T & Partial<U>> = [];
300
-
301
- this.data.forEach(thisItem => {
302
- const thisValue = this.getNestedValue(thisItem, thisKey);
303
- const matches = other.data.filter(otherItem =>
304
- this.getNestedValue(otherItem, otherKey) === thisValue
305
- );
306
-
307
- if (matches.length > 0) {
308
- matches.forEach(match => {
309
- results.push({...thisItem, ...match});
310
- });
311
- } else {
312
- results.push({...thisItem} as T & Partial<U>);
313
- }
314
- });
315
-
316
- return results;
317
- }
318
-
319
- // ===== EXPORT/FORMATTING =====
320
-
321
- toCsv(delimiter: string = ','): string {
322
- if (this.data.length === 0) return '';
323
-
324
- // Get all unique keys from all objects
325
- const allKeys = new Set<string>();
326
- this.data.forEach(item => {
327
- if (typeof item === 'object' && item !== null) {
328
- Object.keys(item).forEach(key => allKeys.add(key));
329
- }
330
- });
331
-
332
- const headers = Array.from(allKeys);
333
- const csvRows = [headers.join(delimiter)];
334
-
335
- this.data.forEach(item => {
336
- const row = headers.map(header => {
337
- const value = typeof item === 'object' && item !== null ? (item as any)[header] : '';
338
- // Escape values that contain the delimiter
339
- const stringValue = String(value ?? '');
340
- return stringValue.includes(delimiter) ? `"${stringValue}"` : stringValue;
341
- });
342
- csvRows.push(row.join(delimiter));
343
- });
344
-
345
- return csvRows.join('\n');
346
- }
347
-
348
- // ===== DEBUGGING =====
349
-
350
- inspect(limit?: number): void {
351
- const itemsToShow = limit ? this.data.slice(0, limit) : this.data;
352
- console.log('QueryResult:', {
353
- count: this.data.length,
354
- showing: itemsToShow.length,
355
- data: itemsToShow
356
- });
357
- }
358
45
  }
359
46
 
360
- // Numeric summary interface
361
- export interface NumericSummary {
362
- count: number;
363
- sum: number;
364
- mean: number;
365
- median: number;
366
- min: number;
367
- max: number;
368
- standardDeviation: number;
369
- variance: number;
370
- }
371
-
372
- // Utility function to create QueryResult
373
47
  export function createQueryResult<T>(data: T[]): QueryResult<T> {
374
48
  return new QueryResult(data);
375
- }
49
+ }