@onchaindb/sdk 0.0.6

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 (66) hide show
  1. package/README.md +475 -0
  2. package/dist/batch.d.ts +42 -0
  3. package/dist/batch.d.ts.map +1 -0
  4. package/dist/batch.js +124 -0
  5. package/dist/batch.js.map +1 -0
  6. package/dist/client.d.ts +93 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +679 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/database.d.ts +194 -0
  11. package/dist/database.d.ts.map +1 -0
  12. package/dist/database.js +211 -0
  13. package/dist/database.js.map +1 -0
  14. package/dist/index.d.ts +15 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +37 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/query-sdk/ConditionBuilder.d.ts +23 -0
  19. package/dist/query-sdk/ConditionBuilder.d.ts.map +1 -0
  20. package/dist/query-sdk/ConditionBuilder.js +76 -0
  21. package/dist/query-sdk/ConditionBuilder.js.map +1 -0
  22. package/dist/query-sdk/FieldConditionBuilder.d.ts +2 -0
  23. package/dist/query-sdk/FieldConditionBuilder.d.ts.map +1 -0
  24. package/dist/query-sdk/FieldConditionBuilder.js +6 -0
  25. package/dist/query-sdk/FieldConditionBuilder.js.map +1 -0
  26. package/dist/query-sdk/NestedBuilders.d.ts +44 -0
  27. package/dist/query-sdk/NestedBuilders.d.ts.map +1 -0
  28. package/dist/query-sdk/NestedBuilders.js +131 -0
  29. package/dist/query-sdk/NestedBuilders.js.map +1 -0
  30. package/dist/query-sdk/OnChainDB.d.ts +27 -0
  31. package/dist/query-sdk/OnChainDB.d.ts.map +1 -0
  32. package/dist/query-sdk/OnChainDB.js +191 -0
  33. package/dist/query-sdk/OnChainDB.js.map +1 -0
  34. package/dist/query-sdk/PrismaLikeClient.d.ts +41 -0
  35. package/dist/query-sdk/PrismaLikeClient.d.ts.map +1 -0
  36. package/dist/query-sdk/PrismaLikeClient.js +202 -0
  37. package/dist/query-sdk/PrismaLikeClient.js.map +1 -0
  38. package/dist/query-sdk/QueryBuilder.d.ts +155 -0
  39. package/dist/query-sdk/QueryBuilder.d.ts.map +1 -0
  40. package/dist/query-sdk/QueryBuilder.js +757 -0
  41. package/dist/query-sdk/QueryBuilder.js.map +1 -0
  42. package/dist/query-sdk/QueryResult.d.ts +53 -0
  43. package/dist/query-sdk/QueryResult.d.ts.map +1 -0
  44. package/dist/query-sdk/QueryResult.js +267 -0
  45. package/dist/query-sdk/QueryResult.js.map +1 -0
  46. package/dist/query-sdk/SelectionBuilder.d.ts +21 -0
  47. package/dist/query-sdk/SelectionBuilder.d.ts.map +1 -0
  48. package/dist/query-sdk/SelectionBuilder.js +67 -0
  49. package/dist/query-sdk/SelectionBuilder.js.map +1 -0
  50. package/dist/query-sdk/adapters/HttpClientAdapter.d.ts +28 -0
  51. package/dist/query-sdk/adapters/HttpClientAdapter.d.ts.map +1 -0
  52. package/dist/query-sdk/adapters/HttpClientAdapter.js +206 -0
  53. package/dist/query-sdk/adapters/HttpClientAdapter.js.map +1 -0
  54. package/dist/query-sdk/index.d.ts +38 -0
  55. package/dist/query-sdk/index.d.ts.map +1 -0
  56. package/dist/query-sdk/index.js +28 -0
  57. package/dist/query-sdk/index.js.map +1 -0
  58. package/dist/query-sdk/operators.d.ts +57 -0
  59. package/dist/query-sdk/operators.d.ts.map +1 -0
  60. package/dist/query-sdk/operators.js +275 -0
  61. package/dist/query-sdk/operators.js.map +1 -0
  62. package/dist/types.d.ts +263 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +46 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,475 @@
1
+ # OnChainDB TypeScript SDK
2
+
3
+ A TypeScript SDK for OnChainDB - the decentralized database built on Celestia blockchain with x402 payment protocol integration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @onchaindb/sdk
9
+ # or
10
+ yarn add @onchaindb/sdk
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { createClient } from '@onchaindb/sdk';
17
+
18
+ const db = createClient({
19
+ endpoint: 'https://api.onchaindb.io',
20
+ appId: 'my_app',
21
+ apiKey: 'your_api_key'
22
+ });
23
+
24
+ // Store data
25
+ await db.store({
26
+ collection: 'messages',
27
+ data: [{ message: 'Hello OnChainDB!', author: 'alice' }]
28
+ });
29
+
30
+ // Query data
31
+ const result = await db.queryBuilder()
32
+ .collection('messages')
33
+ .whereField('author').equals('alice')
34
+ .selectAll()
35
+ .limit(10)
36
+ .execute();
37
+
38
+ console.log(result.records);
39
+ ```
40
+
41
+ ## Configuration
42
+
43
+ ```typescript
44
+ interface OnChainDBConfig {
45
+ endpoint: string; // OnChainDB server endpoint
46
+ appId?: string; // Application ID
47
+ apiKey?: string; // API key for authentication
48
+ timeout?: number; // Request timeout (default: 30000ms)
49
+ retryCount?: number; // Retry attempts (default: 3)
50
+ retryDelay?: number; // Retry delay (default: 1000ms)
51
+ }
52
+ ```
53
+
54
+ ## Storing Data
55
+
56
+ ```typescript
57
+ // Basic store
58
+ const result = await db.store({
59
+ collection: 'tweets',
60
+ data: [
61
+ { id: 'tweet_1', content: 'Hello!', author: 'alice' },
62
+ { id: 'tweet_2', content: 'World!', author: 'bob' }
63
+ ]
64
+ });
65
+
66
+ // Store with payment (x402 protocol)
67
+ const result = await db.store(
68
+ { collection: 'tweets', data: [{ content: 'Paid tweet' }] },
69
+ async (quote) => {
70
+ // Pay via wallet (e.g., Keplr)
71
+ const txHash = await wallet.signAndBroadcast(
72
+ quote.broker_address,
73
+ `${quote.total_cost_utia}utia`,
74
+ 'OnChainDB storage'
75
+ );
76
+ return { txHash, network: 'mocha-4' };
77
+ }
78
+ );
79
+ ```
80
+
81
+ ## Query Builder
82
+
83
+ The SDK provides a fluent query builder for constructing queries. For comprehensive query documentation including all operators, nested queries, and advanced patterns, see the [Query SDK Reference](./src/query-sdk/README.md).
84
+
85
+ ### Basic Queries
86
+
87
+ ```typescript
88
+ const result = await db.queryBuilder()
89
+ .collection('users')
90
+ .whereField('status').equals('active')
91
+ .selectFields(['id', 'name', 'email'])
92
+ .limit(50)
93
+ .execute();
94
+
95
+ // Access results - records have flat structure
96
+ result.records.forEach(user => {
97
+ console.log(user.name, user.email);
98
+ });
99
+ ```
100
+
101
+ ### Query Operators
102
+
103
+ ```typescript
104
+ .equals(value)
105
+ .notEquals(value)
106
+ .greaterThan(value)
107
+ .lessThan(value)
108
+ .contains(value)
109
+ .startsWith(value)
110
+ .isNull()
111
+ .isNotNull()
112
+ .in(values)
113
+ .notIn(values)
114
+ ```
115
+
116
+ ### Complex Queries with Logical Operators
117
+
118
+ ```typescript
119
+ import { LogicalOperator } from '@onchaindb/sdk';
120
+
121
+ const result = await db.queryBuilder()
122
+ .collection('posts')
123
+ .find(builder =>
124
+ LogicalOperator.And([
125
+ LogicalOperator.Condition(builder.field('published').equals(true)),
126
+ LogicalOperator.Or([
127
+ LogicalOperator.Condition(builder.field('category').equals('tech')),
128
+ LogicalOperator.Condition(builder.field('views').greaterThan(1000))
129
+ ])
130
+ ])
131
+ )
132
+ .selectFields(['title', 'content', 'author'])
133
+ .limit(20)
134
+ .execute();
135
+ ```
136
+
137
+ ## Server-Side JOINs
138
+
139
+ Server-side JOINs execute on the backend for optimal performance. Use `$data.fieldname` to reference parent record fields.
140
+
141
+ ### One-to-One JOIN (joinOne)
142
+
143
+ Returns a single object or null.
144
+
145
+ ```typescript
146
+ // Get tweets with author profile
147
+ const result = await db.queryBuilder()
148
+ .collection('tweets')
149
+ .joinOne('author_info', 'users')
150
+ .onField('address').equals('$data.author')
151
+ .selectFields(['address', 'display_name', 'avatar_url', 'verified'])
152
+ .build()
153
+ .selectAll()
154
+ .limit(20)
155
+ .execute();
156
+
157
+ // Result structure:
158
+ // {
159
+ // id: 'tweet_123',
160
+ // content: 'Hello world!',
161
+ // author: 'celestia1abc...',
162
+ // author_info: {
163
+ // address: 'celestia1abc...',
164
+ // display_name: 'Alice',
165
+ // avatar_url: 'https://...',
166
+ // verified: true
167
+ // }
168
+ // }
169
+ ```
170
+
171
+ ### One-to-Many JOIN (joinMany)
172
+
173
+ Returns an array of related records.
174
+
175
+ ```typescript
176
+ // Get users with their tweets
177
+ const result = await db.queryBuilder()
178
+ .collection('users')
179
+ .whereField('address').equals(userAddress)
180
+ .joinMany('user_tweets', 'tweets')
181
+ .onField('author').equals('$data.address')
182
+ .selectFields(['id', 'content', 'created_at'])
183
+ .build()
184
+ .selectAll()
185
+ .execute();
186
+
187
+ // Result structure:
188
+ // {
189
+ // address: 'celestia1abc...',
190
+ // display_name: 'Alice',
191
+ // user_tweets: [
192
+ // { id: 'tweet_1', content: 'Hello!', created_at: '...' },
193
+ // { id: 'tweet_2', content: 'World!', created_at: '...' }
194
+ // ]
195
+ // }
196
+ ```
197
+
198
+ ### Multiple JOINs
199
+
200
+ ```typescript
201
+ // Timeline with likes, replies, and author info
202
+ const result = await db.queryBuilder()
203
+ .collection('tweets')
204
+ .whereField('reply_to_id').isNull()
205
+ .joinOne('author_info', 'users')
206
+ .onField('address').equals('$data.author')
207
+ .selectFields(['display_name', 'avatar_url', 'verified'])
208
+ .build()
209
+ .joinMany('likes', 'likes')
210
+ .onField('tweet_id').equals('$data.id')
211
+ .selectFields(['user', 'created_at'])
212
+ .build()
213
+ .joinMany('replies', 'tweets')
214
+ .onField('reply_to_id').equals('$data.id')
215
+ .selectFields(['id', 'author', 'content'])
216
+ .build()
217
+ .selectAll()
218
+ .offset(offset)
219
+ .limit(limit)
220
+ .execute();
221
+ ```
222
+
223
+ ### Nested JOINs
224
+
225
+ ```typescript
226
+ // Get tweet with replies, each reply includes author info
227
+ const result = await db.queryBuilder()
228
+ .collection('tweets')
229
+ .whereField('id').equals(tweetId)
230
+ .joinMany('replies', 'tweets')
231
+ .onField('reply_to_id').equals('$data.id')
232
+ .selectAll()
233
+ // Nested: get author for each reply
234
+ .joinOne('author_info', 'users')
235
+ .onField('address').equals('$data.author')
236
+ .selectFields(['display_name', 'avatar_url', 'verified'])
237
+ .build()
238
+ .build()
239
+ .selectAll()
240
+ .limit(1)
241
+ .execute();
242
+ ```
243
+
244
+ ### Self-Referential JOINs
245
+
246
+ ```typescript
247
+ // Get tweets with quoted tweet info
248
+ const result = await db.queryBuilder()
249
+ .collection('tweets')
250
+ .whereField('quote_tweet_id').isNotNull()
251
+ .joinOne('quote_tweet', 'tweets')
252
+ .onField('id').equals('$data.quote_tweet_id')
253
+ .selectFields(['id', 'content', 'author', 'created_at'])
254
+ // Nested: get quoted tweet's author
255
+ .joinOne('author_info', 'users')
256
+ .onField('address').equals('$data.author')
257
+ .selectFields(['display_name', 'avatar_url'])
258
+ .build()
259
+ .build()
260
+ .selectAll()
261
+ .execute();
262
+ ```
263
+
264
+ ## Blob Storage
265
+
266
+ ```typescript
267
+ // Get pricing quote
268
+ const quote = await db.getPricingQuote({
269
+ app_id: 'my_app',
270
+ operation_type: 'write',
271
+ size_kb: Math.ceil(file.size / 1024),
272
+ collection: 'images'
273
+ });
274
+
275
+ const costInUtia = Math.ceil(quote.total_cost * 1_000_000);
276
+
277
+ // Pay for storage
278
+ const txHash = await wallet.signAndBroadcast(
279
+ brokerAddress,
280
+ `${costInUtia}utia`,
281
+ 'Image upload'
282
+ );
283
+
284
+ // Upload blob
285
+ const upload = await db.uploadBlob({
286
+ collection: 'images',
287
+ blob: file,
288
+ metadata: { user_address: userAddress },
289
+ payment_tx_hash: txHash,
290
+ user_address: userAddress,
291
+ broker_address: brokerAddress,
292
+ amount_utia: costInUtia
293
+ });
294
+
295
+ // Wait for completion
296
+ const task = await db.waitForTaskCompletion(upload.ticket_id);
297
+
298
+ if (task.status === 'Completed') {
299
+ console.log('Blob ID:', upload.blob_id);
300
+ }
301
+
302
+ // Retrieve blob
303
+ const blob = await db.retrieveBlob({
304
+ collection: 'images',
305
+ blob_id: upload.blob_id
306
+ });
307
+ ```
308
+
309
+ ## Task Tracking
310
+
311
+ ```typescript
312
+ // Check task status
313
+ const task = await db.getTaskStatus(ticket_id);
314
+ console.log('Status:', task.status);
315
+ // Pending, PaymentBroadcast, PaymentConfirming, Completed, Failed
316
+
317
+ // Wait with polling
318
+ const completed = await db.waitForTaskCompletion(
319
+ ticket_id,
320
+ 2000, // Poll interval (ms)
321
+ 600000 // Max wait (ms)
322
+ );
323
+ ```
324
+
325
+ ## Cost Estimation
326
+
327
+ ```typescript
328
+ const quote = await db.getPricingQuote({
329
+ app_id: 'my_app',
330
+ operation_type: 'write',
331
+ size_kb: 50,
332
+ collection: 'tweets'
333
+ });
334
+
335
+ console.log('Total cost:', quote.total_cost, 'TIA');
336
+ console.log('In utia:', Math.ceil(quote.total_cost * 1_000_000));
337
+ ```
338
+
339
+ ## Real-World Example: Social App
340
+
341
+ ```typescript
342
+ import { createClient, OnChainDBClient } from '@onchaindb/sdk';
343
+
344
+ class SocialService {
345
+ private client: OnChainDBClient;
346
+
347
+ constructor(endpoint: string, appId: string, apiKey?: string) {
348
+ this.client = createClient({ endpoint, appId, apiKey });
349
+ }
350
+
351
+ async getTimeline(limit = 20, offset = 0) {
352
+ const result = await this.client.queryBuilder()
353
+ .collection('tweets')
354
+ .whereField('reply_to_id').isNull()
355
+ .joinOne('author_info', 'users')
356
+ .onField('address').equals('$data.author')
357
+ .selectFields(['display_name', 'avatar_url', 'verified'])
358
+ .build()
359
+ .joinMany('likes', 'likes')
360
+ .onField('tweet_id').equals('$data.id')
361
+ .selectFields(['user'])
362
+ .build()
363
+ .joinMany('replies', 'tweets')
364
+ .onField('reply_to_id').equals('$data.id')
365
+ .selectFields(['id'])
366
+ .build()
367
+ .selectAll()
368
+ .offset(offset)
369
+ .limit(limit)
370
+ .execute();
371
+
372
+ return result.records.map(tweet => ({
373
+ ...tweet,
374
+ like_count: tweet.likes?.length || 0,
375
+ reply_count: tweet.replies?.length || 0
376
+ }));
377
+ }
378
+
379
+ async createTweet(content: string, author: string, paymentCallback: Function) {
380
+ const tweet = {
381
+ id: `tweet_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
382
+ content,
383
+ author,
384
+ created_at: new Date().toISOString()
385
+ };
386
+
387
+ await this.client.store(
388
+ { collection: 'tweets', data: [tweet] },
389
+ paymentCallback
390
+ );
391
+
392
+ return tweet;
393
+ }
394
+
395
+ async getUserProfile(address: string) {
396
+ const result = await this.client.queryBuilder()
397
+ .collection('users')
398
+ .whereField('address').equals(address)
399
+ .joinMany('tweets', 'tweets')
400
+ .onField('author').equals('$data.address')
401
+ .selectAll()
402
+ .build()
403
+ .joinMany('followers', 'follows')
404
+ .onField('following').equals('$data.address')
405
+ .selectFields(['follower'])
406
+ .build()
407
+ .joinMany('following', 'follows')
408
+ .onField('follower').equals('$data.address')
409
+ .selectFields(['following'])
410
+ .build()
411
+ .selectAll()
412
+ .limit(1)
413
+ .execute();
414
+
415
+ if (!result.records.length) return null;
416
+
417
+ const user = result.records[0];
418
+ return {
419
+ ...user,
420
+ follower_count: user.followers?.length || 0,
421
+ following_count: user.following?.length || 0
422
+ };
423
+ }
424
+ }
425
+ ```
426
+
427
+ ## Error Handling
428
+
429
+ ```typescript
430
+ import { OnChainDBError, ValidationError } from '@onchaindb/sdk';
431
+
432
+ try {
433
+ await db.store({ collection: 'test', data: [{ test: 'data' }] });
434
+ } catch (error) {
435
+ if (error instanceof ValidationError) {
436
+ console.log('Validation failed:', error.message);
437
+ } else if (error instanceof OnChainDBError) {
438
+ console.log('Error:', error.code, error.message);
439
+ }
440
+ }
441
+ ```
442
+
443
+ ## API Reference
444
+
445
+ ### OnChainDBClient
446
+
447
+ | Method | Description |
448
+ |--------|-------------|
449
+ | `store(request, paymentCallback?, wait?)` | Store data |
450
+ | `queryBuilder()` | Create query builder |
451
+ | `uploadBlob(request)` | Upload binary file |
452
+ | `retrieveBlob(request)` | Download binary file |
453
+ | `getTaskStatus(ticketId)` | Get task status |
454
+ | `waitForTaskCompletion(ticketId)` | Poll until complete |
455
+ | `getPricingQuote(request)` | Get pricing quote |
456
+ | `health()` | Health check |
457
+
458
+ ### QueryBuilder
459
+
460
+ | Method | Description |
461
+ |--------|-------------|
462
+ | `collection(name)` | Set collection |
463
+ | `whereField(name)` | Start field condition |
464
+ | `find(builderFn)` | Complex conditions |
465
+ | `selectFields(fields)` | Select specific fields |
466
+ | `selectAll()` | Select all fields |
467
+ | `joinOne(alias, model)` | One-to-one JOIN |
468
+ | `joinMany(alias, model)` | One-to-many JOIN |
469
+ | `limit(n)` | Limit results |
470
+ | `offset(n)` | Skip results |
471
+ | `execute()` | Execute query |
472
+
473
+ ## License
474
+
475
+ MIT License
@@ -0,0 +1,42 @@
1
+ import { OnChainDBClient } from './client';
2
+ import { StoreRequest, StoreResponse, TransactionStatus } from './types';
3
+ import { EventEmitter } from 'eventemitter3';
4
+ export declare class BatchOperations extends EventEmitter {
5
+ private client;
6
+ constructor(client: OnChainDBClient);
7
+ store(requests: StoreRequest[], options?: {
8
+ concurrency?: number;
9
+ waitForConfirmation?: boolean;
10
+ onProgress?: (completed: number, total: number) => void;
11
+ paymentOptions?: {
12
+ userWallet?: any;
13
+ brokerAddress?: string;
14
+ };
15
+ }): Promise<StoreResponse[]>;
16
+ storeWithRetry(requests: StoreRequest[], options?: {
17
+ concurrency?: number;
18
+ waitForConfirmation?: boolean;
19
+ maxRetries?: number;
20
+ retryDelay?: number;
21
+ onProgress?: (completed: number, total: number) => void;
22
+ paymentOptions?: {
23
+ userWallet?: any;
24
+ brokerAddress?: string;
25
+ };
26
+ }): Promise<StoreResponse[]>;
27
+ waitForBatchConfirmation(transactionIds: string[], maxWaitTime?: number): Promise<TransactionStatus[]>;
28
+ private sleep;
29
+ }
30
+ export declare class BulkBuilder {
31
+ private requests;
32
+ private defaultCollection?;
33
+ private defaultApp?;
34
+ collection(name: string): this;
35
+ app(name: string): this;
36
+ add(data: Record<string, any>, collection?: string, app?: string): this;
37
+ addMany(records: Record<string, any>[], collection?: string, app?: string): this;
38
+ build(): StoreRequest[];
39
+ count(): number;
40
+ clear(): this;
41
+ }
42
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAQ7C,qBAAa,eAAgB,SAAQ,YAAY;IACnC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,eAAe;IA6BrC,KAAK,CACT,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,GAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,cAAc,CAAC,EAAE;YACf,UAAU,CAAC,EAAE,GAAG,CAAC;YACjB,aAAa,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;KACE,GACL,OAAO,CAAC,aAAa,EAAE,CAAC;IAqDrB,cAAc,CAClB,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,GAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QACxD,cAAc,CAAC,EAAE;YACf,UAAU,CAAC,EAAE,GAAG,CAAC;YACjB,aAAa,CAAC,EAAE,MAAM,CAAC;SACxB,CAAC;KACE,GACL,OAAO,CAAC,aAAa,EAAE,CAAC;IAkCrB,wBAAwB,CAC5B,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,GAAE,MAAe,GAC3B,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAyB/B,OAAO,CAAC,KAAK;CAGd;AAgBD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,UAAU,CAAC,CAAS;IAK5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ9B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQvB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAQhF,KAAK,IAAI,YAAY,EAAE;IAOvB,KAAK,IAAI,MAAM;IAOf,KAAK,IAAI,IAAI;CAId"}
package/dist/batch.js ADDED
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BulkBuilder = exports.BatchOperations = void 0;
4
+ const eventemitter3_1 = require("eventemitter3");
5
+ class BatchOperations extends eventemitter3_1.EventEmitter {
6
+ constructor(client) {
7
+ super();
8
+ this.client = client;
9
+ }
10
+ async store(requests, options = {}) {
11
+ const { concurrency = 10, waitForConfirmation = false, onProgress, paymentOptions } = options;
12
+ const results = [];
13
+ const errors = [];
14
+ let completed = 0;
15
+ for (let i = 0; i < requests.length; i += concurrency) {
16
+ const batch = requests.slice(i, i + concurrency);
17
+ const batchPromises = batch.map(async (request, batchIndex) => {
18
+ const globalIndex = i + batchIndex;
19
+ try {
20
+ const result = await this.client.store(request, undefined, waitForConfirmation);
21
+ results[globalIndex] = result;
22
+ completed++;
23
+ onProgress?.(completed, requests.length);
24
+ this.emit('progress', { completed, total: requests.length, success: true });
25
+ return result;
26
+ }
27
+ catch (error) {
28
+ errors.push({ index: globalIndex, error: error });
29
+ completed++;
30
+ onProgress?.(completed, requests.length);
31
+ this.emit('progress', { completed, total: requests.length, success: false, error });
32
+ throw error;
33
+ }
34
+ });
35
+ await Promise.allSettled(batchPromises);
36
+ }
37
+ if (errors.length > 0) {
38
+ this.emit('batchComplete', { results, errors });
39
+ throw new Error(`Batch operation failed: ${errors.length}/${requests.length} requests failed`);
40
+ }
41
+ this.emit('batchComplete', { results, errors: [] });
42
+ return results;
43
+ }
44
+ async storeWithRetry(requests, options = {}) {
45
+ const { maxRetries = 3, retryDelay = 1000, ...batchOptions } = options;
46
+ let attempt = 0;
47
+ let lastError;
48
+ while (attempt <= maxRetries) {
49
+ try {
50
+ return await this.store(requests, batchOptions);
51
+ }
52
+ catch (error) {
53
+ lastError = error;
54
+ attempt++;
55
+ if (attempt <= maxRetries) {
56
+ this.emit('retryAttempt', { attempt, maxRetries, error });
57
+ await this.sleep(retryDelay * attempt);
58
+ }
59
+ }
60
+ }
61
+ throw lastError;
62
+ }
63
+ async waitForBatchConfirmation(transactionIds, maxWaitTime = 300000) {
64
+ const confirmationPromises = transactionIds.map(async (id, index) => {
65
+ try {
66
+ const result = await this.client.waitForConfirmation(id, maxWaitTime);
67
+ this.emit('transactionConfirmed', { id, index, result });
68
+ return {
69
+ id,
70
+ status: 'confirmed',
71
+ block_height: result.block_height,
72
+ transaction_hash: result.transaction_hash,
73
+ celestia_height: result.celestia_height
74
+ };
75
+ }
76
+ catch (error) {
77
+ this.emit('transactionFailed', { id, index, error });
78
+ return {
79
+ id,
80
+ status: 'failed',
81
+ error: error.message
82
+ };
83
+ }
84
+ });
85
+ return Promise.all(confirmationPromises);
86
+ }
87
+ sleep(ms) {
88
+ return new Promise(resolve => setTimeout(resolve, ms));
89
+ }
90
+ }
91
+ exports.BatchOperations = BatchOperations;
92
+ class BulkBuilder {
93
+ constructor() {
94
+ this.requests = [];
95
+ }
96
+ collection(name) {
97
+ this.defaultCollection = name;
98
+ return this;
99
+ }
100
+ app(name) {
101
+ this.defaultApp = name;
102
+ return this;
103
+ }
104
+ add(data, collection, app) {
105
+ this.requests.push({ data: [data], root: `${app}::${collection}` });
106
+ return this;
107
+ }
108
+ addMany(records, collection, app) {
109
+ records.forEach(data => this.add(data, collection, app));
110
+ return this;
111
+ }
112
+ build() {
113
+ return [...this.requests];
114
+ }
115
+ count() {
116
+ return this.requests.length;
117
+ }
118
+ clear() {
119
+ this.requests = [];
120
+ return this;
121
+ }
122
+ }
123
+ exports.BulkBuilder = BulkBuilder;
124
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../src/batch.ts"],"names":[],"mappings":"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"}