@onchaindb/sdk 0.4.0 → 0.4.2

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 (98) hide show
  1. package/.DS_Store +0 -0
  2. package/.claude/settings.local.json +8 -0
  3. package/.gitignore +5 -0
  4. package/.idea/.gitignore +5 -0
  5. package/.idea/compiler.xml +6 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/jsLinters/eslint.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/prettier.xml +7 -0
  10. package/.idea/sdk.iml +12 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/.idea/workspace.xml +257 -0
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +11 -3
  15. package/dist/client.js.map +1 -1
  16. package/dist/database.d.ts +0 -20
  17. package/dist/database.d.ts.map +1 -1
  18. package/dist/database.js +0 -40
  19. package/dist/database.js.map +1 -1
  20. package/dist/query-sdk/tests/setup.d.ts +16 -0
  21. package/dist/query-sdk/tests/setup.d.ts.map +1 -0
  22. package/dist/query-sdk/tests/setup.js +49 -0
  23. package/dist/query-sdk/tests/setup.js.map +1 -0
  24. package/examples/basic-usage.ts +136 -0
  25. package/examples/blob-upload-example.ts +140 -0
  26. package/examples/collection-schema-example.ts +304 -0
  27. package/examples/server-side-joins.ts +201 -0
  28. package/examples/tweet-self-joins-example.ts +352 -0
  29. package/package-lock.json +3823 -0
  30. package/package.json +1 -1
  31. package/skills.md +1096 -0
  32. package/src/.env +1 -0
  33. package/src/batch.d.ts +121 -0
  34. package/src/batch.js +205 -0
  35. package/src/batch.ts +257 -0
  36. package/src/client.ts +1856 -0
  37. package/src/database.d.ts +268 -0
  38. package/src/database.js +294 -0
  39. package/src/database.ts +695 -0
  40. package/src/index.d.ts +160 -0
  41. package/src/index.js +186 -0
  42. package/src/index.ts +253 -0
  43. package/src/query-sdk/ConditionBuilder.ts +103 -0
  44. package/src/query-sdk/FieldConditionBuilder.ts +2 -0
  45. package/src/query-sdk/NestedBuilders.ts +186 -0
  46. package/src/query-sdk/OnChainDB.ts +294 -0
  47. package/src/query-sdk/QueryBuilder.ts +1191 -0
  48. package/src/query-sdk/QueryResult.ts +375 -0
  49. package/src/query-sdk/README.md +866 -0
  50. package/src/query-sdk/SelectionBuilder.ts +94 -0
  51. package/src/query-sdk/adapters/HttpClientAdapter.ts +249 -0
  52. package/src/query-sdk/dist/ConditionBuilder.d.ts +22 -0
  53. package/src/query-sdk/dist/ConditionBuilder.js +90 -0
  54. package/src/query-sdk/dist/FieldConditionBuilder.d.ts +1 -0
  55. package/src/query-sdk/dist/FieldConditionBuilder.js +6 -0
  56. package/src/query-sdk/dist/NestedBuilders.d.ts +43 -0
  57. package/src/query-sdk/dist/NestedBuilders.js +144 -0
  58. package/src/query-sdk/dist/OnChainDB.d.ts +19 -0
  59. package/src/query-sdk/dist/OnChainDB.js +123 -0
  60. package/src/query-sdk/dist/QueryBuilder.d.ts +70 -0
  61. package/src/query-sdk/dist/QueryBuilder.js +295 -0
  62. package/src/query-sdk/dist/QueryResult.d.ts +52 -0
  63. package/src/query-sdk/dist/QueryResult.js +293 -0
  64. package/src/query-sdk/dist/SelectionBuilder.d.ts +20 -0
  65. package/src/query-sdk/dist/SelectionBuilder.js +80 -0
  66. package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +27 -0
  67. package/src/query-sdk/dist/adapters/HttpClientAdapter.js +170 -0
  68. package/src/query-sdk/dist/index.d.ts +36 -0
  69. package/src/query-sdk/dist/index.js +27 -0
  70. package/src/query-sdk/dist/operators.d.ts +56 -0
  71. package/src/query-sdk/dist/operators.js +289 -0
  72. package/src/query-sdk/dist/tests/setup.d.ts +15 -0
  73. package/src/query-sdk/dist/tests/setup.js +46 -0
  74. package/src/query-sdk/index.ts +59 -0
  75. package/src/query-sdk/jest.config.js +25 -0
  76. package/src/query-sdk/operators.ts +335 -0
  77. package/src/query-sdk/package.json +46 -0
  78. package/src/query-sdk/tests/FieldConditionBuilder.test.ts +84 -0
  79. package/src/query-sdk/tests/LogicalOperator.test.ts +85 -0
  80. package/src/query-sdk/tests/NestedBuilders.test.ts +321 -0
  81. package/src/query-sdk/tests/QueryBuilder.test.ts +348 -0
  82. package/src/query-sdk/tests/QueryResult.test.ts +464 -0
  83. package/src/query-sdk/tests/aggregations.test.ts +653 -0
  84. package/src/query-sdk/tests/comprehensive.test.ts +279 -0
  85. package/src/query-sdk/tests/integration.test.ts +608 -0
  86. package/src/query-sdk/tests/operators.test.ts +327 -0
  87. package/src/query-sdk/tests/setup.ts +59 -0
  88. package/src/query-sdk/tests/unit.test.ts +794 -0
  89. package/src/query-sdk/tsconfig.json +26 -0
  90. package/src/query-sdk/yarn.lock +3092 -0
  91. package/src/types.d.ts +131 -0
  92. package/src/types.js +46 -0
  93. package/src/types.ts +534 -0
  94. package/src/x402/index.ts +12 -0
  95. package/src/x402/types.ts +250 -0
  96. package/src/x402/utils.ts +332 -0
  97. package/tsconfig.json +20 -0
  98. package/yarn.lock +2309 -0
@@ -0,0 +1,375 @@
1
+ // Query result utilities class matching Rust SDK functionality
2
+ export class QueryResult<T = any> {
3
+ public data: T[];
4
+
5
+ constructor(data: T[]) {
6
+ this.data = Array.isArray(data) ? data : [data];
7
+ }
8
+
9
+ // ===== BASIC UTILITIES =====
10
+
11
+ len(): number {
12
+ return this.data.length;
13
+ }
14
+
15
+ length(): number {
16
+ return this.len();
17
+ }
18
+
19
+ isEmpty(): boolean {
20
+ return this.data.length === 0;
21
+ }
22
+
23
+ first(): T | undefined {
24
+ return this.data[0];
25
+ }
26
+
27
+ last(): T | undefined {
28
+ return this.data[this.data.length - 1];
29
+ }
30
+
31
+ get(index: number): T | undefined {
32
+ return this.data[index];
33
+ }
34
+
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
+ toArray(): T[] {
260
+ return [...this.data];
261
+ }
262
+
263
+ toJSON(): string {
264
+ return JSON.stringify(this.data);
265
+ }
266
+
267
+ // Convert to QueryResult with different type
268
+ cast<U>(): QueryResult<U> {
269
+ return new QueryResult(this.data as unknown as U[]);
270
+ }
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
+ }
359
+
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
+ export function createQueryResult<T>(data: T[]): QueryResult<T> {
374
+ return new QueryResult(data);
375
+ }