@ardrive/turbo-sdk 1.25.0 → 1.26.0-alpha.1

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 (49) hide show
  1. package/README.md +162 -61
  2. package/bundles/web.bundle.min.js +1584 -730
  3. package/lib/cjs/common/events.js +256 -0
  4. package/lib/cjs/common/events.test.js +470 -0
  5. package/lib/cjs/common/http.js +4 -13
  6. package/lib/cjs/common/turbo.js +6 -4
  7. package/lib/cjs/common/upload.js +65 -37
  8. package/lib/cjs/node/signer.js +31 -11
  9. package/lib/cjs/node/upload.js +7 -1
  10. package/lib/cjs/utils/axiosClient.js +3 -0
  11. package/lib/cjs/utils/readableStream.js +15 -0
  12. package/lib/cjs/version.js +1 -1
  13. package/lib/cjs/web/signer.js +55 -28
  14. package/lib/esm/common/events.js +249 -0
  15. package/lib/esm/common/events.test.js +468 -0
  16. package/lib/esm/common/http.js +4 -13
  17. package/lib/esm/common/turbo.js +6 -4
  18. package/lib/esm/common/upload.js +66 -38
  19. package/lib/esm/node/signer.js +31 -11
  20. package/lib/esm/node/upload.js +7 -1
  21. package/lib/esm/utils/axiosClient.js +3 -0
  22. package/lib/esm/utils/readableStream.js +15 -0
  23. package/lib/esm/version.js +1 -1
  24. package/lib/esm/web/signer.js +55 -28
  25. package/lib/types/common/events.d.ts +56 -0
  26. package/lib/types/common/events.d.ts.map +1 -0
  27. package/lib/types/common/events.test.d.ts +2 -0
  28. package/lib/types/common/events.test.d.ts.map +1 -0
  29. package/lib/types/common/http.d.ts +1 -2
  30. package/lib/types/common/http.d.ts.map +1 -1
  31. package/lib/types/common/signer.d.ts +1 -1
  32. package/lib/types/common/signer.d.ts.map +1 -1
  33. package/lib/types/common/turbo.d.ts +4 -4
  34. package/lib/types/common/turbo.d.ts.map +1 -1
  35. package/lib/types/common/upload.d.ts +13 -5
  36. package/lib/types/common/upload.d.ts.map +1 -1
  37. package/lib/types/node/signer.d.ts +1 -1
  38. package/lib/types/node/signer.d.ts.map +1 -1
  39. package/lib/types/node/upload.d.ts.map +1 -1
  40. package/lib/types/types.d.ts +60 -6
  41. package/lib/types/types.d.ts.map +1 -1
  42. package/lib/types/utils/axiosClient.d.ts.map +1 -1
  43. package/lib/types/utils/readableStream.d.ts +0 -1
  44. package/lib/types/utils/readableStream.d.ts.map +1 -1
  45. package/lib/types/version.d.ts +1 -1
  46. package/lib/types/version.d.ts.map +1 -1
  47. package/lib/types/web/signer.d.ts +1 -1
  48. package/lib/types/web/signer.d.ts.map +1 -1
  49. package/package.json +9 -5
package/README.md CHANGED
@@ -16,11 +16,12 @@ Welcome to the `@ardrive/turbo-sdk`! This SDK provides functionality for interac
16
16
  - [NodeJS](#nodejs)
17
17
  - [Typescript](#typescript)
18
18
  - [Examples](#examples)
19
- - [Logging](#logging)
20
19
  - [APIs](#apis)
21
20
  - [TurboFactory](#turbofactory)
22
21
  - [TurboUnauthenticatedClient](#turbounauthenticatedclient)
23
22
  - [TurboAuthenticatedClient](#turboauthenticatedclient)
23
+ - [Events](#events)
24
+ - [Logging](#logging)
24
25
  - [CLI](#cli)
25
26
  - [Installation](#installation-1)
26
27
  - [Usage](#usage-1)
@@ -56,57 +57,62 @@ import open from 'open';
56
57
  import path from 'path';
57
58
 
58
59
  async function uploadWithTurbo() {
59
- // load your JWK directly to authenticate
60
- const arweave = Arweave.init({});
61
60
  const jwk = JSON.parse(fs.readFileSync('./my-jwk.json', 'utf-8'));
62
- const address = await arweave.wallets.jwkToAddress(jwk);
63
- const turbo = TurboFactory.authenticated({ privateKey: jwk });
64
-
65
- // or provide your own signer
66
- // const signer = new ArweaveSigner(jwk);
67
- // const turbo = TurboFactory.authenticated({ signer });
68
-
69
- // get the wallet balance
70
- const { winc: balance } = await turbo.getBalance();
61
+ const signer = new ArweaveSigner(jwk);
62
+ const turbo = TurboFactory.authenticated({ signer });
71
63
 
72
- // prep file for upload
73
- const filePath = path.join(__dirname, './my-image.png');
74
- const fileSize = fs.statSync(filePath).size;
75
-
76
- // get the cost of uploading the file
77
- const [{ winc: fileSizeCost }] = await turbo.getUploadCosts({
78
- bytes: [fileSize],
79
- });
80
-
81
- // check if balance greater than upload cost, and if in browser
82
- if (balance < fileSizeCost && window !== undefined) {
83
- const { url } = await turbo.createCheckoutSession({
84
- amount: fileSizeCost,
85
- owner: address,
86
- // add a promo code if you have one
87
- });
88
-
89
- // open the URL to top-up if in browser
90
- window.open(url, '_blank');
91
- } else {
92
- // otherwise, print the URL to the console
93
- console.log('Please top up your balance via the CLI before uploading', {
94
- balance,
95
- fileSizeCost,
64
+ try {
65
+ // upload some simple data - log upload progress events
66
+ const { id, owner, dataCaches, fastFinalityIndexes } = await turbo.upload({
67
+ data: 'Hello, world!',
68
+ events: {
69
+ // overall events (includes signing and upload events)
70
+ onProgress: ({ totalBytes, processedBytes, step }) => {
71
+ console.log('Overall progress:', { totalBytes, processedBytes, step });
72
+ },
73
+ onError: ({ error, step }) => {
74
+ console.log('Overall error:', { error, step });
75
+ },
76
+ },
96
77
  });
97
- }
98
78
 
99
- // upload the file
100
- try {
79
+ // upload a file - log signing and upload progress events
80
+ const filePath = path.join(__dirname, './my-image.png');
81
+ const fileSize = fs.statSync(filePath).size;
101
82
  const { id, owner, dataCaches, fastFinalityIndexes } =
102
- // Have data in memory already? Just use it!
103
- haveDataInMemory
104
- ? await turbo.upload({ data: 'The contents of my file!' })
105
- : // Or perhaps you have a larger file that you don't want in memory? Stream it!
106
- await turbo.uploadFile({
107
- fileStreamFactory: () => fs.createReadStream(filePath),
108
- fileSizeFactory: () => fileSize,
109
- });
83
+ await turbo.uploadFile({
84
+ fileStreamFactory: () => fs.createReadStream(filePath),
85
+ fileSizeFactory: () => fileSize,
86
+ events: {
87
+ // overall events (includes signing and upload events)
88
+ onProgress: ({ totalBytes, processedBytes, step }) => {
89
+ console.log('Overall progress:', { totalBytes, processedBytes, step });
90
+ },
91
+ onError: ({ error, step }) => {
92
+ console.log('Overall error:', { error, step });
93
+ },
94
+ // signing events
95
+ onSigningProgress: ({ totalBytes, processedBytes }) => {
96
+ console.log('Signing progress:', { totalBytes, processedBytes });
97
+ },
98
+ onSigningError: ({ error }) => {
99
+ console.log('Signing error:', { error });
100
+ },
101
+ onSigningSuccess: () => {
102
+ console.log('Signing success!');
103
+ },
104
+ // upload events
105
+ onUploadProgress: ({ totalBytes, processedBytes }) => {
106
+ console.log('Upload progress:', { totalBytes, processedBytes });
107
+ },
108
+ onUploadError: (error) => {
109
+ console.log('Upload error:', { error });
110
+ },
111
+ onUploadSuccess: () => {
112
+ console.log('Upload success!');
113
+ },
114
+ },
115
+ });
110
116
  // upload complete!
111
117
  console.log('Successfully upload data item!', {
112
118
  id,
@@ -117,9 +123,6 @@ async function uploadWithTurbo() {
117
123
  } catch (error) {
118
124
  // upload failed
119
125
  console.error('Failed to upload data item!', error);
120
- } finally {
121
- const { winc: newBalance } = await turbo.getBalance();
122
- console.log('New balance:', newBalance);
123
126
  }
124
127
  }
125
128
  ```
@@ -195,14 +198,6 @@ Examples are available in the [examples] directory. To run examples:
195
198
  - `yarn example:cjs` - runs example CJS node script
196
199
  - `yarn example:esm` - runs example ESM node script
197
200
 
198
- ## Logging
199
-
200
- The SDK uses winston for logging. You can set the log level using the `setLogLevel` method.
201
-
202
- ```typescript
203
- TurboFactory.setLogLevel('debug');
204
- ```
205
-
206
201
  ## APIs
207
202
 
208
203
  ### TurboFactory
@@ -379,9 +374,9 @@ const [uploadCostForFile] = await turbo.getUploadCosts({ bytes: [1024] });
379
374
  const { winc, adjustments } = uploadCostForFile;
380
375
  ```
381
376
 
382
- #### `uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal })`
377
+ #### `uploadSignedDataItem({ dataItemStreamFactory, dataItemSizeFactory, signal, events })`
383
378
 
384
- Uploads a signed data item. The provided `dataItemStreamFactory` should produce a NEW signed data item stream each time is it invoked. The `dataItemSizeFactory` is a function that returns the size of the file. The `signal` is an optional [AbortSignal] that can be used to cancel the upload or timeout the request.
379
+ Uploads a signed data item. The provided `dataItemStreamFactory` should produce a NEW signed data item stream each time is it invoked. The `dataItemSizeFactory` is a function that returns the size of the file. The `signal` is an optional [AbortSignal] that can be used to cancel the upload or timeout the request. The `events` parameter is an optional object that can be used to listen to upload progress, errors, and success (refer to the [Events] section for more details).
385
380
 
386
381
  ```typescript
387
382
  const filePath = path.join(__dirname, './my-signed-data-item');
@@ -390,6 +385,17 @@ const uploadResponse = await turbo.uploadSignedDataItem({
390
385
  dataItemStreamFactory: () => fs.createReadStream(filePath),
391
386
  dataItemSizeFactory: () => dataItemSize,
392
387
  signal: AbortSignal.timeout(10_000), // cancel the upload after 10 seconds
388
+ events: {
389
+ onUploadProgress: ({ totalBytes, processedBytes }) => {
390
+ console.log('Upload progress:', { totalBytes, processedBytes });
391
+ },
392
+ onUploadError: (error) => {
393
+ console.log('Upload error:', { error });
394
+ },
395
+ onUploadSuccess: () => {
396
+ console.log('Upload success!');
397
+ },
398
+ },
393
399
  });
394
400
  ```
395
401
 
@@ -515,7 +521,24 @@ const { url, winc, paymentAmount, quotedPaymentAmount, adjustments } =
515
521
  window.open(url, '_blank');
516
522
  ```
517
523
 
518
- #### `uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts })`
524
+ #### `upload({ data, signal, dataItemOpts, events })`
525
+
526
+ The easiest way to upload data to Turbo. The `signal` is an optional [AbortSignal] that can be used to cancel the upload or timeout the request. `dataItemOpts` is an optional object that can be used to configure tags, target, and anchor for the data item upload.
527
+
528
+ ```typescript
529
+ const uploadResult = await turbo.upload({
530
+ data: 'The contents of my file!',
531
+ signal: AbortSignal.timeout(10_000), // cancel the upload after 10 seconds
532
+ dataItemOpts: {
533
+ // optional
534
+ },
535
+ events: {
536
+ // optional
537
+ },
538
+ });
539
+ ```
540
+
541
+ #### `uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts, events })`
519
542
 
520
543
  Signs and uploads a raw file. The provided `fileStreamFactory` should produce a NEW file data stream each time is it invoked. The `fileSizeFactory` is a function that returns the size of the file. The `signal` is an optional [AbortSignal] that can be used to cancel the upload or timeout the request. `dataItemOpts` is an optional object that can be used to configure tags, target, and anchor for the data item upload.
521
544
 
@@ -539,6 +562,18 @@ const uploadResult = await turbo.uploadFile({
539
562
  ],
540
563
  // no timeout or AbortSignal provided
541
564
  },
565
+ events: {
566
+ onUploadProgress: ({ totalBytes, processedBytes }) => {
567
+ console.log('Upload progress:', { totalBytes, processedBytes });
568
+ },
569
+ onUploadError: (error) => {
570
+ console.log('Upload error:', { error });
571
+ },
572
+ onUploadSuccess: () => {
573
+ console.log('Upload success!');
574
+ },
575
+ // add any other events you want to listen to (see `Events` section for more details)
576
+ },
542
577
  });
543
578
  ```
544
579
 
@@ -708,6 +743,71 @@ const { givenApprovals, receivedApprovals } =
708
743
  });
709
744
  ```
710
745
 
746
+ ## Events
747
+
748
+ The SDK provides events for uploading and signing data. You can listen to these events by providing a callback function to the `events` parameter of the `upload` and `uploadFile` and `uploadSignedDataItem` methods.
749
+
750
+ - `onProgress` - emitted when the overall progress changes (includes both upload and signing). Each event includes the total bytes, processed bytes, and the step (upload or signing)
751
+ - `onError` - emitted when the overall upload or signing fails (includes both upload and signing). Each event includes the error and the step (upload or signing)
752
+ - `onSuccess` - emitted when the overall upload or signing succeeds (includes both upload and signing) - this is the last event emitted for the upload or signing process
753
+ - `onSigningProgress` - emitted when the signing progress changes.
754
+ - `onSigningError` - emitted when the signing fails.
755
+ - `onSigningSuccess` - emitted when the signing succeeds
756
+ - `onUploadProgress` - emitted when the upload progress changes
757
+ - `onUploadError` - emitted when the upload fails
758
+ - `onUploadSuccess` - emitted when the upload succeeds
759
+
760
+ ```typescript
761
+ const uploadResult = await turbo.upload({
762
+ data: 'The contents of my file!',
763
+ signal: AbortSignal.timeout(10_000), // cancel the upload after 10 seconds
764
+ dataItemOpts: {
765
+ // optional
766
+ },
767
+ events: {
768
+ // overall progress
769
+ onProgress: ({ totalBytes, processedBytes, step }) => {
770
+ const percentComplete = (processedBytes / totalBytes) * 100;
771
+ console.log('Overall progress:', {
772
+ totalBytes,
773
+ processedBytes,
774
+ step,
775
+ percentComplete: percentComplete.toFixed(2) + '%', // eg 50.68%
776
+ });
777
+ },
778
+ onError: (error) => {
779
+ console.log('Overall error:', { error });
780
+ },
781
+ onUploadProgress: ({ totalBytes, processedBytes }) => {
782
+ console.log('Upload progress:', { totalBytes, processedBytes });
783
+ },
784
+ onUploadError: (error) => {
785
+ console.log('Upload error:', { error });
786
+ },
787
+ onUploadSuccess: () => {
788
+ console.log('Upload success!');
789
+ },
790
+ onSigningProgress: ({ totalBytes, processedBytes }) => {
791
+ console.log('Signing progress:', { totalBytes, processedBytes });
792
+ },
793
+ onSigningError: (error) => {
794
+ console.log('Signing error:', { error });
795
+ },
796
+ onSigningSuccess: () => {
797
+ console.log('Signing success!');
798
+ },
799
+ },
800
+ });
801
+ ```
802
+
803
+ ## Logging
804
+
805
+ The SDK uses winston for logging. You can set the log level using the `setLogLevel` method.
806
+
807
+ ```typescript
808
+ TurboFactory.setLogLevel('debug');
809
+ ```
810
+
711
811
  ## CLI
712
812
 
713
813
  <!-- markdownlint-disable MD024 -->
@@ -1033,3 +1133,4 @@ For more information on how to contribute, please see [CONTRIBUTING.md].
1033
1133
  [AbortSignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
1034
1134
  [CONTRIBUTING.md]: ./CONTRIBUTING.md
1035
1135
  [docs/native-address]: https://docs.ar.io/glossary.html#native-address
1136
+ [Events]: #events