@onchaindb/sdk 0.4.5 → 2.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.
- package/.claude/settings.local.json +10 -2
- package/README.md +422 -355
- package/dist/batch.d.ts +1 -10
- package/dist/batch.d.ts.map +1 -1
- package/dist/batch.js +4 -26
- package/dist/batch.js.map +1 -1
- package/dist/client.d.ts +31 -46
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +222 -357
- package/dist/client.js.map +1 -1
- package/dist/database.d.ts +14 -131
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +35 -131
- package/dist/database.js.map +1 -1
- package/dist/index.d.ts +10 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -18
- package/dist/index.js.map +1 -1
- package/dist/query-sdk/ConditionBuilder.d.ts +3 -11
- package/dist/query-sdk/ConditionBuilder.d.ts.map +1 -1
- package/dist/query-sdk/ConditionBuilder.js +10 -48
- package/dist/query-sdk/ConditionBuilder.js.map +1 -1
- package/dist/query-sdk/NestedBuilders.d.ts +33 -30
- package/dist/query-sdk/NestedBuilders.d.ts.map +1 -1
- package/dist/query-sdk/NestedBuilders.js +46 -43
- package/dist/query-sdk/NestedBuilders.js.map +1 -1
- package/{src/query-sdk/dist/OnChainDB.d.ts → dist/query-sdk/OnDB.d.ts} +10 -2
- package/dist/query-sdk/OnDB.d.ts.map +1 -0
- package/{src/query-sdk/dist/OnChainDB.js → dist/query-sdk/OnDB.js} +86 -18
- package/dist/query-sdk/OnDB.js.map +1 -0
- package/dist/query-sdk/QueryBuilder.d.ts +4 -2
- package/dist/query-sdk/QueryBuilder.d.ts.map +1 -1
- package/dist/query-sdk/QueryBuilder.js +47 -169
- package/dist/query-sdk/QueryBuilder.js.map +1 -1
- package/dist/query-sdk/QueryResult.d.ts +0 -38
- package/dist/query-sdk/QueryResult.d.ts.map +1 -1
- package/dist/query-sdk/QueryResult.js +1 -227
- package/dist/query-sdk/QueryResult.js.map +1 -1
- package/dist/query-sdk/index.d.ts +2 -2
- package/dist/query-sdk/index.d.ts.map +1 -1
- package/dist/query-sdk/index.js +3 -3
- package/dist/query-sdk/index.js.map +1 -1
- package/dist/query-sdk/operators.d.ts +32 -28
- package/dist/query-sdk/operators.d.ts.map +1 -1
- package/dist/query-sdk/operators.js +45 -155
- package/dist/query-sdk/operators.js.map +1 -1
- package/dist/types.d.ts +159 -36
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -8
- package/dist/types.js.map +1 -1
- package/dist/x402/types.d.ts +1 -1
- package/dist/x402/types.d.ts.map +1 -1
- package/dist/x402/utils.js +2 -2
- package/dist/x402/utils.js.map +1 -1
- package/jest.config.js +4 -0
- package/package.json +1 -1
- package/skills.md +0 -1
- package/src/batch.d.ts +3 -3
- package/src/batch.js +1 -1
- package/src/client.ts +287 -823
- package/src/database.d.ts +1 -1
- package/src/database.js +4 -4
- package/src/database.ts +71 -494
- package/src/index.d.ts +18 -18
- package/src/index.js +16 -16
- package/src/index.ts +44 -198
- package/src/query-sdk/ConditionBuilder.ts +37 -89
- package/src/query-sdk/NestedBuilders.ts +90 -92
- package/src/query-sdk/{OnChainDB.ts → OnDB.ts} +1 -1
- package/src/query-sdk/QueryBuilder.ts +59 -218
- package/src/query-sdk/QueryResult.ts +4 -330
- package/src/query-sdk/README.md +218 -587
- package/src/query-sdk/index.ts +2 -2
- package/src/query-sdk/operators.ts +91 -200
- package/src/query-sdk/tests/FieldConditionBuilder.test.ts +70 -71
- package/src/query-sdk/tests/LogicalOperator.test.ts +43 -82
- package/src/query-sdk/tests/NestedBuilders.test.ts +229 -309
- package/src/query-sdk/tests/QueryBuilder.test.ts +5 -5
- package/src/query-sdk/tests/QueryResult.test.ts +41 -435
- package/src/query-sdk/tests/comprehensive.test.ts +4 -185
- package/src/tests/client-requests.test.ts +280 -0
- package/src/tests/client-validation.test.ts +80 -0
- package/src/types.d.ts +6 -6
- package/src/types.js +8 -8
- package/src/types.ts +239 -54
- package/src/x402/types.ts +3 -3
- package/src/x402/utils.ts +3 -3
- package/examples/blob-upload-example.ts +0 -140
- package/src/batch.ts +0 -257
- package/src/query-sdk/dist/ConditionBuilder.d.ts +0 -22
- package/src/query-sdk/dist/ConditionBuilder.js +0 -90
- package/src/query-sdk/dist/FieldConditionBuilder.d.ts +0 -1
- package/src/query-sdk/dist/FieldConditionBuilder.js +0 -6
- package/src/query-sdk/dist/NestedBuilders.d.ts +0 -43
- package/src/query-sdk/dist/NestedBuilders.js +0 -144
- package/src/query-sdk/dist/QueryBuilder.d.ts +0 -70
- package/src/query-sdk/dist/QueryBuilder.js +0 -295
- package/src/query-sdk/dist/QueryResult.d.ts +0 -52
- package/src/query-sdk/dist/QueryResult.js +0 -293
- package/src/query-sdk/dist/SelectionBuilder.d.ts +0 -20
- package/src/query-sdk/dist/SelectionBuilder.js +0 -80
- package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +0 -27
- package/src/query-sdk/dist/adapters/HttpClientAdapter.js +0 -170
- package/src/query-sdk/dist/index.d.ts +0 -36
- package/src/query-sdk/dist/index.js +0 -27
- package/src/query-sdk/dist/operators.d.ts +0 -56
- package/src/query-sdk/dist/operators.js +0 -289
- package/src/query-sdk/dist/tests/setup.d.ts +0 -15
- package/src/query-sdk/dist/tests/setup.js +0 -46
- package/src/query-sdk/jest.config.js +0 -25
- package/src/query-sdk/package.json +0 -46
- package/src/query-sdk/tests/aggregations.test.ts +0 -653
- package/src/query-sdk/tests/integration.test.ts +0 -608
- package/src/query-sdk/tests/operators.test.ts +0 -327
- package/src/query-sdk/tests/unit.test.ts +0 -794
- package/src/query-sdk/tsconfig.json +0 -26
- package/src/query-sdk/yarn.lock +0 -3092
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
//
|
|
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.
|
|
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
|
+
}
|