rn-file-toolkit 1.0.1 → 1.0.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.
package/README.md CHANGED
@@ -6,516 +6,166 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square)](https://www.typescriptlang.org/)
7
7
  [![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20Android-lightgrey.svg?style=flat-square)](https://github.com/chavan-labs/rn-file-toolkit)
8
8
 
9
- The easiest way to download **and manage files** in React Nativewith background support, pause/resume, upload, queueing, and built-in filesystem APIs.
10
-
11
- > 100% pure native code (Kotlin + Swift). Zero third-party dependencies.
12
-
13
- **Keywords:** react native download, react native file download, react native background download, react native download manager, react native file upload, react native download progress, react native pause resume download, react native cache manager, react native turbo module, expo download, iOS URLSession, Android DownloadManager, react native checksum validation, base64 converter, url to base64, data uri, share file, open file, file sharing, native share, document viewer, download queue, concurrent downloads, queue concurrency, priority queue, batch download, max concurrent downloads, react native filesystem, read file, write file, copy file, move file, stat file, file exists, useDownload hook, download speed, download eta, download progress bytes
14
-
15
- ⭐ **Star this repo if you found it useful** — it helps others discover the project!
16
-
17
- ## Problems?
18
-
19
- Most React Native file download solutions have one or more of these problems:
20
-
21
- - **Complexity** — require configuring native modules, background tasks, and notification channels separately
22
- - **Dependencies** — rely on heavy third-party libraries that bloat your app size
23
- - **Limited features** — lack pause/resume, checksum validation, or proper background support
24
- - **No queue** — spawn 20 downloads and you'll crash or saturate the network; libraries like `react-native-blob-util` have no queue at all
25
- - **Split libraries** — downloading is in one package, filesystem operations in another (read/write/copy/stat/exists), adding extra dependency and complexity
26
- - **Poor DX** — complicated APIs that require managing multiple IDs, listeners, and cleanup logic
27
-
28
- **rn-file-toolkit** was built to solve these issues. It provides a simple, unified API while leveraging platform-native download managers (URLSession on iOS, DownloadManager on Android) for reliable, battery-efficient downloads. Everything works out of the box — background downloads, progress tracking, pause/resume — without wrestling with native configuration.
29
-
30
- ## ✨ Features
31
-
32
- - **`useDownload()` hook** — drop-in React hook with built-in state: `status`, `progress`, `result`, `pause`, `resume`, `cancel` — no competitors have this
33
- - **Rich progress info** — `onProgress` gives you `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, and `etaSeconds` — not just a plain number
34
- - **Zip & Unzip** — compress files/directories and extract ZIP archives natively with **zero third-party dependencies** (`java.util.zip` on Android, system `zlib` on iOS)
35
- - **Download with progress** — clean `0 → 100` progress natively, no UI freezing
36
- - **Background downloads** — survive app suspension (iOS background URLSession + Android DownloadManager)
37
- - **Download Queue** — built-in concurrency-limited queue with `maxConcurrent` control and `high`/`normal` priority
38
- - **Pause & Resume** — resume mid-download using HTTP Range requests
39
- - **Auto-Retry** — automatic retry on network errors with exponential backoff
40
- - **Cancel** — cancel any active download, partial files are cleaned up automatically
41
- - **Re-attach** — reconnect to background downloads after app restart
42
- - **Custom Headers** — support for Authorization tokens and custom metadata
43
- - **Custom Destinations** — save to `downloads`, `cache`, or `documents` folders
44
- - **Multipart Upload** — simple, native file uploading
45
- - **Checksum Validation** — verify file integrity (MD5, SHA1, SHA256) after download
46
- - **Base64 & Data URI Support** — convert base64 strings and data URIs to files natively
47
- - **URL to Base64** — convert remote URLs (images, videos, gifs) to base64 strings
48
- - **Share Files** — share files with other apps using native share dialog
49
- - **Open Files** — open files with default apps or app chooser
50
- - **Filesystem API (`fs`)** — `exists`, `stat`, `readFile`, `writeFile`, `copyFile`, `moveFile`, `mkdir`, `ls`, `deleteFile`
51
- - **Expo Support** — includes a config plugin for zero-config integration
52
- - **TurboModules** — built on the React Native New Architecture
53
- - **File management** — list, delete individual files, or clear all downloads
9
+ The ultimate, unified file management library for React Native. Download, upload, manage queues, and interact with the filesystemall powered by pure native implementations (Kotlin + Swift) with **zero third-party dependencies**.
54
10
 
55
- ---
56
-
57
- ## Installation
58
-
59
- ```sh
60
- npm install rn-file-toolkit
61
- ```
11
+ ⭐ **Star this repo if you found it useful!**
62
12
 
63
13
  ---
64
14
 
65
- ## API
66
-
67
- ### `download(options)`
68
-
69
- ```javascript
70
- import { download } from 'rn-file-toolkit';
15
+ ## Why rn-file-toolkit?
16
+ Most React Native file solutions are fragmented, bloated, or lack critical features like background queues or stable pause/resume. **rn-file-toolkit** gives you a unified, TurboModule-powered API utilizing OS-native download managers (`URLSession` on iOS, `DownloadManager` on Android) for reliable, battery-efficient file operations.
71
17
 
72
- const result = await download({
73
- url: 'https://example.com/file.pdf',
74
- fileName: 'my_file.pdf',
75
- headers: { Authorization: 'Bearer <token>' },
76
- destination: 'documents', // 'downloads' | 'cache' | 'documents'
77
- checksum: {
78
- hash: 'd41d8cd98f00b204e9800998ecf8427e',
79
- algorithm: 'md5',
80
- },
81
- onProgress: ({
82
- percent,
83
- bytesDownloaded,
84
- totalBytes,
85
- speedBps,
86
- etaSeconds,
87
- }) => {
88
- console.log(
89
- `${percent.toFixed(1)}% — ${(speedBps / 1024).toFixed(
90
- 1
91
- )} KB/s — ETA ${etaSeconds.toFixed(0)}s`
92
- );
93
- },
94
- // Auto-retry on network failure (optional)
95
- retry: {
96
- attempts: 3, // max retry attempts
97
- delay: 1000, // base delay in ms; doubles each attempt: 1s → 2s → 4s (capped at 30s)
98
- onRetry: (attempt, error) => console.log(`Retry #${attempt}: ${error}`),
99
- },
100
- });
101
- ```
102
-
103
- > **Retry behaviour:**
104
- >
105
- > - Only retries on **network errors** (timeouts, connection drops, socket errors).
106
- > - Server errors (`4xx`/`5xx`) and checksum mismatches are **not** retried.
107
- > - Delay doubles each attempt (exponential backoff), capped at 30 seconds.
108
- > - Works on both iOS and Android for foreground downloads.
18
+ ### Key Features
19
+ - **Drop-in `useDownload()` Hook:** Built-in state management (`status`, `progress`, `result`) and controls (`pause`, `resume`, `cancel`).
20
+ - **Background Downloads:** Survives app suspension with automatic re-attachment capabilities.
21
+ - **Smart Queueing:** Cap concurrency and set priorities (`high`/`normal`) without native configuration.
22
+ - **Resilient:** Auto-retries on network errors with exponential backoff and Range-based HTTP resume.
23
+ - **Zero-Dependency Zip/Unzip:** Uses native `java.util.zip` and iOS `zlib` for extracting/compressing files.
24
+ - **Rich File System API:** `readFile`, `writeFile`, `copyFile`, `moveFile`, `mkdir`, `ls`, `stat`, `exists`, and `deleteFile`.
25
+ - **Media Utilities:** Base64 encoding/decoding, URL to Base64 conversions, and native share/open dialogs.
109
26
 
110
27
  ---
111
28
 
112
- ### `setQueueOptions(options)` · `getQueueStatus()` · Queue-aware `download()`
113
-
114
- Avoid crashing your app (or saturating the network) when kicking off many simultaneous downloads. The built-in queue lets you cap concurrency and prioritise individual items — all in pure JavaScript, with zero native changes required.
115
-
116
- ```javascript
117
- import { download, setQueueOptions, getQueueStatus } from 'rn-file-toolkit';
118
-
119
- // 1. Configure the global queue (call once, e.g. at app startup)
120
- setQueueOptions({ maxConcurrent: 3 }); // default is 3
121
-
122
- // 2. Enqueue downloads — at most 3 will run at the same time
123
- const promises = urls.map((url) =>
124
- download({
125
- url,
126
- destination: 'documents',
127
- queue: true, // join the managed queue
128
- priority: 'normal', // 'high' | 'normal' (default)
129
- onProgress: (p) => console.log(`${url}: ${p.percent}%`),
130
- })
131
- );
132
-
133
- const results = await Promise.all(promises);
134
-
135
- // High-priority item jumps ahead of all 'normal' pending items
136
- download({
137
- url: 'https://example.com/urgent.pdf',
138
- queue: true,
139
- priority: 'high',
140
- });
29
+ ## Installation
141
30
 
142
- // 3. Inspect queue state at any time
143
- const { active, pending, maxConcurrent } = getQueueStatus();
144
- console.log(`Running: ${active} Waiting: ${pending} Limit: ${maxConcurrent}`);
31
+ ```sh
32
+ npm install rn-file-toolkit
145
33
  ```
146
34
 
147
- > **Queue behaviour:**
148
- >
149
- > - `queue: false` (default) — download starts immediately, bypassing the queue entirely. All existing behaviour is unchanged.
150
- > - `queue: true` — the download is placed in the JS queue. It starts as soon as an active slot is free.
151
- > - `priority: 'high'` — item is inserted at the **front** of the pending list, so it runs before any `'normal'` items.
152
- > - `priority: 'normal'` (default) — item is appended to the **back**.
153
- > - `setQueueOptions` can be called at any time; if `maxConcurrent` is increased, idle slots are filled immediately.
154
- > - All other `DownloadOptions` (`onProgress`, `retry`, `checksum`, `headers`, etc.) work exactly the same inside the queue.
155
-
156
35
  ---
157
36
 
158
- ### `useDownload()` hook
37
+ ## Quick Start: `useDownload` Hook
159
38
 
160
- The easiest way to manage a download inside a React component. Get status, rich progress (with speed & ETA), and full controls all with zero boilerplate.
39
+ The easiest way to manage a download inside a React component. Get status, rich progress (with speed & ETA), and full controls out of the box.
161
40
 
162
41
  ```tsx
163
42
  import { useDownload } from 'rn-file-toolkit';
164
43
 
165
44
  function DownloadScreen() {
166
- const { start, pause, resume, cancel, status, progress, result } =
167
- useDownload();
45
+ const { start, pause, resume, cancel, status, progress, result } = useDownload();
168
46
 
169
47
  return (
170
48
  <View>
171
- <Button
172
- title="Download"
173
- onPress={() =>
174
- start({
175
- url: 'https://example.com/video.mp4',
176
- destination: 'documents',
177
- })
178
- }
49
+ <Button
50
+ title="Download"
51
+ onPress={() => start({ url: 'https://example.com/video.mp4', destination: 'documents' })}
179
52
  />
180
53
 
181
54
  {status === 'downloading' && progress && (
182
55
  <View>
183
- <Text>{progress.percent.toFixed(1)}%</Text>
184
- <Text>Speed: {(progress.speedBps / 1024).toFixed(1)} KB/s</Text>
56
+ <Text>{progress.percent.toFixed(1)}% ({(progress.speedBps / 1024).toFixed(1)} KB/s)</Text>
185
57
  <Text>ETA: {progress.etaSeconds.toFixed(0)}s</Text>
186
- <Text>
187
- {(progress.bytesDownloaded / 1024 / 1024).toFixed(1)} MB
188
- {' / '}
189
- {(progress.totalBytes / 1024 / 1024).toFixed(1)} MB
190
- </Text>
191
58
  <Button title="Pause" onPress={pause} />
192
59
  <Button title="Cancel" onPress={cancel} />
193
60
  </View>
194
61
  )}
195
62
 
196
63
  {status === 'paused' && <Button title="Resume" onPress={resume} />}
197
-
198
- {status === 'done' && result?.success && (
199
- <Text>✅ Saved to: {result.filePath}</Text>
200
- )}
201
-
64
+ {status === 'done' && <Text>✅ Saved to: {result?.filePath}</Text>}
202
65
  {status === 'error' && <Text>❌ {result?.error}</Text>}
203
66
  </View>
204
67
  );
205
68
  }
206
69
  ```
207
70
 
208
- | Property | Type | Description |
209
- | ---------------- | ---------------------------------------------------------- | ------------------------------- |
210
- | `start(options)` | `(options: DownloadOptions) => Promise<DownloadResult>` | Start a download |
211
- | `pause()` | `() => Promise<void>` | Pause the active download |
212
- | `resume()` | `() => Promise<void>` | Resume a paused download |
213
- | `cancel()` | `() => Promise<void>` | Cancel and discard the download |
214
- | `status` | `'idle' \| 'downloading' \| 'paused' \| 'done' \| 'error'` | Current state |
215
- | `progress` | `ProgressInfo \| null` | Live progress info (see below) |
216
- | `result` | `DownloadResult \| null` | Final result once complete |
217
- | `downloadId` | `string \| null` | Active download ID |
218
-
219
- ---
220
-
221
- ### `upload(options)`
222
-
223
- ```javascript
224
- import { upload } from 'rn-file-toolkit';
225
-
226
- const result = await upload({
227
- url: 'https://example.com/api/upload',
228
- filePath: '/path/to/my_image.jpg',
229
- fieldName: 'avatar', // default: 'file'
230
- parameters: {
231
- userId: '123',
232
- },
233
- headers: { 'X-Custom-Header': 'value' },
234
- onProgress: (p) => console.log(`Uploading: ${p}%`),
235
- });
236
-
237
- if (result.success) {
238
- console.log('Response:', result.data);
239
- }
240
- ```
241
-
242
- ---
243
-
244
- ### `saveBase64AsFile(options)`
245
-
246
- Save a base64 string or data URI as a file. Perfect for handling base64 images, documents, or any binary data.
247
-
248
- ```javascript
249
- import { saveBase64AsFile } from 'rn-file-toolkit';
250
-
251
- // From data URI (auto-detects file extension)
252
- const result = await saveBase64AsFile({
253
- base64Data: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...',
254
- fileName: 'photo.png',
255
- destination: 'documents', // 'downloads' | 'cache' | 'documents'
256
- });
257
-
258
- // From plain base64 string
259
- const result = await saveBase64AsFile({
260
- base64Data: 'SGVsbG8gV29ybGQ=',
261
- fileName: 'hello.txt',
262
- destination: 'cache',
263
- });
264
-
265
- if (result.success) {
266
- console.log('File saved at:', result.filePath);
267
- }
268
- ```
269
-
270
- ---
271
-
272
- ### `urlToBase64(options)`
273
-
274
- Convert a web URL (image, video, gif, etc.) to base64 string. Perfect for converting remote media to base64 for local processing.
275
-
276
- ```javascript
277
- import { urlToBase64 } from 'rn-file-toolkit';
278
-
279
- const result = await urlToBase64({
280
- url: 'https://example.com/photo.jpg',
281
- headers: { Authorization: 'Bearer <token>' }, // optional
282
- });
283
-
284
- if (result.success) {
285
- console.log('Base64:', result.base64);
286
- console.log('Data URI:', result.dataUri);
287
- console.log('MIME Type:', result.mimeType); // e.g., 'image/jpeg'
288
-
289
- // Use in Image component
290
- // <Image source={{ uri: result.dataUri }} />
291
- }
292
- ```
293
-
294
71
  ---
295
72
 
296
- ### `shareFile(options)`
73
+ ## Core APIs
297
74
 
298
- Share a file with other apps using the native share dialog.
75
+ ### `download(options)`
76
+ For programmatic, queue-aware background downloads.
299
77
 
300
78
  ```javascript
301
- import { shareFile } from 'rn-file-toolkit';
302
-
303
- const result = await shareFile({
304
- filePath: '/path/to/document.pdf',
305
- title: 'Share Document', // Android only
306
- subject: 'Check this out', // Android only
307
- });
308
-
309
- if (result.success) {
310
- console.log('File shared successfully');
311
- }
312
- ```
313
-
314
- ---
315
-
316
- ### `openFile(options)`
79
+ import { download, setQueueOptions } from 'rn-file-toolkit';
317
80
 
318
- Open a file with the default app or app chooser.
81
+ // Optional: Configure global concurrency queue
82
+ setQueueOptions({ maxConcurrent: 3 });
319
83
 
320
- ```javascript
321
- import { openFile } from 'rn-file-toolkit';
322
-
323
- const result = await openFile({
324
- filePath: '/path/to/document.pdf',
325
- mimeType: 'application/pdf', // optional, auto-detected if not provided
84
+ const result = await download({
85
+ url: 'https://example.com/file.pdf',
86
+ destination: 'documents', // 'downloads' | 'cache' | 'documents'
87
+ queue: true, // Joins the managed queue
88
+ priority: 'high', // 'high' | 'normal'
89
+ retry: { attempts: 3, delay: 1000 },
90
+ checksum: { hash: 'd41d8cd...', algorithm: 'md5' },
91
+ onProgress: (p) => console.log(`${p.percent.toFixed(1)}%`),
326
92
  });
327
-
328
- if (result.success) {
329
- console.log('File opened');
330
- }
331
93
  ```
332
94
 
333
- ---
334
-
335
- ### `unzip(sourcePath, destDir)` · `zip(sourcePath, destPath)`
336
-
337
- Compress and extract ZIP archives natively — **no third-party library required**.
338
-
339
- - **Android** uses `java.util.zip` (built into the Android SDK, every API level).
340
- - **iOS** uses `zlib` (system framework, linked via `s.libraries = 'z'` in the podspec — ships on every iPhone/iPad).
95
+ ### `upload(options)`
96
+ Robust, memory-efficient multipart file uploading.
341
97
 
342
98
  ```javascript
343
- import { download, unzip, zip } from 'rn-file-toolkit';
99
+ import { upload } from 'rn-file-toolkit';
344
100
 
345
- // ── Unzip a downloaded archive ──────────────────────────────────────────────
346
- const dl = await download({
347
- url: 'https://example.com/assets.zip',
348
- destination: 'cache',
101
+ const result = await upload({
102
+ url: 'https://example.com/api/upload',
103
+ filePath: '/path/to/my_image.jpg',
104
+ fieldName: 'avatar',
105
+ parameters: { userId: '123' },
106
+ onProgress: (p) => console.log(`Uploading: ${p}%`),
349
107
  });
350
-
351
- if (dl.success) {
352
- const result = await unzip(
353
- dl.filePath, // absolute path to the .zip file
354
- '/path/to/output-folder' // destination directory (created if it doesn't exist)
355
- );
356
-
357
- if (result.success) {
358
- console.log('Destination:', result.destDir);
359
- console.log('Extracted files:', result.files);
360
- // result.files → ['/path/to/output-folder/image.png', ...]
361
- } else {
362
- console.log('Error:', result.error);
363
- }
364
- }
365
-
366
- // ── Zip a single file ───────────────────────────────────────────────────────
367
- const zipResult = await zip(
368
- '/path/to/document.pdf', // source file
369
- '/path/to/document.zip' // output archive path
370
- );
371
-
372
- if (zipResult.success) {
373
- console.log('Archive created at:', zipResult.zipPath);
374
- }
375
-
376
- // ── Zip an entire directory ─────────────────────────────────────────────────
377
- const dirResult = await zip(
378
- '/path/to/my-folder', // source directory
379
- '/path/to/my-folder.zip' // output archive path
380
- );
381
108
  ```
382
109
 
383
- > **Notes:**
384
- >
385
- > - `unzip` auto-creates the destination directory including any intermediate folders.
386
- > - `unzip` on Android protects against [zip-slip attacks](https://snyk.io/research/zip-slip-vulnerability) by validating each entry path.
387
- > - `zip` supports both single files and entire directory trees (recursive).
388
- > - Both functions run on a background thread and never block the JS thread.
389
- > - Supported compression methods: **Deflate** (method 8) and **Store** (method 0) — the two methods used by virtually every ZIP file.
390
-
391
- ---
392
-
393
- ### Pause / Resume / Cancel
110
+ ### Filesystem (`fs`)
111
+ Perform native filesystem operations directly.
394
112
 
395
113
  ```javascript
396
- import { pauseDownload, resumeDownload, cancelDownload } from 'rn-file-toolkit';
114
+ import { fs } from 'rn-file-toolkit';
397
115
 
398
- await pauseDownload(downloadId);
399
- await resumeDownload(downloadId);
400
- await cancelDownload(downloadId);
116
+ await fs.exists('/path/to/file.txt');
117
+ await fs.stat('/path/to/file.txt'); // { size, modified, isDir ... }
118
+ await fs.writeFile('/path/to/file.txt', 'hello', 'utf8'); // Supports 'base64'
119
+ await fs.copyFile('/src/file.txt', '/dst/file.txt');
120
+ await fs.mkdir('/path/to/folder');
121
+ const files = await fs.ls('/path/to/folder');
401
122
  ```
402
123
 
403
- ---
404
-
405
- ### Cache Management
124
+ ### Zip & Unzip
125
+ Compress and extract archives securely.
406
126
 
407
127
  ```javascript
408
- import { getCachedFiles, deleteFile, clearCache } from 'rn-file-toolkit';
409
-
410
- // List all files in the cache/documents folders
411
- const { files } = await getCachedFiles();
128
+ import { unzip, zip } from 'rn-file-toolkit';
412
129
 
413
- // Delete a specific file
414
- await deleteFile('/path/to/file.pdf');
415
-
416
- // Clear all managed files
417
- await clearCache();
130
+ await unzip('/path/to/assets.zip', '/path/to/output-folder');
131
+ await zip('/path/to/document.pdf', '/path/to/document.zip');
418
132
  ```
419
133
 
420
- ---
421
-
422
- ### `fs` (filesystem namespace)
423
-
424
- Use built-in file system helpers without adding another dependency.
134
+ ### Media & Utilities
425
135
 
426
136
  ```javascript
427
- import { fs } from 'rn-file-toolkit';
428
-
429
- await fs.exists('/path/to/file.pdf'); // → true/false
430
-
431
- await fs.stat('/path/to/file.pdf');
432
- // → { path, name, size, modified, isDir }
137
+ import { saveBase64AsFile, urlToBase64, shareFile, openFile } from 'rn-file-toolkit';
433
138
 
434
- await fs.readFile('/path/to/file.txt'); // utf8 by default
435
- await fs.readFile('/path/to/file.bin', 'base64');
139
+ // Convert base64 / Data URIs to files
140
+ await saveBase64AsFile({ base64Data: 'data:image/png;base64,...', destination: 'documents' });
436
141
 
437
- await fs.writeFile('/path/to/file.txt', 'hello');
438
- await fs.writeFile('/path/to/file.bin', 'SGVsbG8=', 'base64');
142
+ // Fetch remote media as base64
143
+ await urlToBase64({ url: 'https://example.com/photo.jpg' });
439
144
 
440
- await fs.copyFile('/src/file.pdf', '/dst/file.pdf');
441
- await fs.moveFile('/src/file.pdf', '/dst/file.pdf');
442
- await fs.deleteFile('/path/to/file.pdf');
145
+ // Share with native dialog
146
+ await shareFile({ filePath: '/path/to/document.pdf' });
443
147
 
444
- await fs.mkdir('/path/to/folder');
445
- await fs.ls('/path/to/folder'); // string[]
148
+ // Open with default app
149
+ await openFile({ filePath: '/path/to/document.pdf', mimeType: 'application/pdf' });
446
150
  ```
447
151
 
448
- > `readFile` / `writeFile` support encodings: `'utf8'` (default) and `'base64'`.
449
-
450
152
  ---
451
153
 
452
- ## Use Cases
453
-
454
- ### Download from URLs
455
-
456
- Perfect for downloading files from remote servers with progress tracking, background support, and resume capability.
154
+ ## API Type Reference
457
155
 
458
- ### Convert URLs to Base64
459
-
460
- Convert remote media (images, videos, gifs) to base64 strings for:
461
-
462
- - Display in Image components without downloading to disk
463
- - Inline embedding in HTML/emails
464
- - Upload to APIs requiring base64 format
465
- - Cross-platform data transfer
466
-
467
- ### Save Base64/Data URIs
468
-
469
- Convert base64-encoded data (like images from canvas, camera, or API responses) directly to files:
470
-
471
- - Canvas-generated images (`canvas.toDataURL()`)
472
- - Camera/photo library base64 outputs
473
- - API responses with base64-encoded files
474
- - Email attachments in base64 format
475
-
476
- ---
477
-
478
- ## Type Reference
479
-
480
- | Type | Fields |
481
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
156
+ | Type | Fields |
157
+ | -------------------- | ------ |
482
158
  | `DownloadOptions` | `url`, `fileName?`, `background?`, `headers?`, `destination?`, `notificationTitle?`, `notificationDescription?`, `checksum?`, `onProgress?`, `retry?`, `queue?`, `priority?` |
483
- | `ProgressInfo` | `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, `etaSeconds` |
484
- | `RetryOptions` | `attempts`, `delay?`, `onRetry?` |
485
- | `QueueOptions` | `maxConcurrent?` |
486
- | `QueueStatus` | `active`, `pending`, `maxConcurrent` |
487
- | `DownloadStatus` | `'idle' \| 'downloading' \| 'paused' \| 'done' \| 'error'` |
488
- | `UseDownloadReturn` | `start`, `pause`, `resume`, `cancel`, `status`, `progress`, `result`, `downloadId` |
489
- | `FsEncoding` | `'utf8' \| 'base64'` |
490
- | `FsStat` | `path`, `name`, `size`, `modified`, `isDir` |
491
- | `FsApi` | `exists`, `stat`, `readFile`, `writeFile`, `copyFile`, `moveFile`, `deleteFile`, `mkdir`, `ls` |
492
- | `UploadOptions` | `url`, `filePath`, `fieldName?`, `headers?`, `parameters?`, `onProgress?` |
493
- | `SaveBase64Options` | `base64Data`, `fileName?`, `destination?` |
494
- | `UrlToBase64Options` | `url`, `headers?` |
495
- | `ShareFileOptions` | `filePath`, `title?`, `subject?` |
496
- | `OpenFileOptions` | `filePath`, `mimeType?` |
497
- | `DownloadResult` | `success`, `filePath?`, `downloadId?`, `error?` |
498
- | `UploadResult` | `success`, `status?`, `data?`, `error?` |
499
- | `UnzipResult` | `success`, `destDir?`, `files?`, `error?` |
500
- | `ZipResult` | `success`, `zipPath?`, `error?` |
501
- | `SaveBase64Result` | `success`, `filePath?`, `error?` |
502
- | `UrlToBase64Result` | `success`, `base64?`, `mimeType?`, `dataUri?`, `error?` |
503
- | `ShareFileResult` | `success`, `completed?`, `error?` |
504
- | `OpenFileResult` | `success`, `error?` |
505
- | `Checksum` | `hash`, `algorithm: 'md5' \| 'sha1' \| 'sha256'` |
506
-
507
- ---
508
-
509
- ## Articles & Resources
510
-
511
- - [**I Got Tired of React Native File Downloads Being a Mess — So I Built rn-file-toolkit**](https://medium.com/@chavanrohit413/i-got-tired-of-react-native-file-downloads-being-a-mess-so-i-built-rn-file-toolkit-29b7a8b5c743) — Deep dive into the problems with existing solutions and how rn-file-toolkit solves them
512
-
513
- ---
514
-
515
- ## Links
516
-
517
- - [GitHub](https://github.com/chavan-labs/rn-file-toolkit)
518
- - [npm](https://www.npmjs.com/package/rn-file-toolkit)
159
+ | `ProgressInfo` | `percent`, `bytesDownloaded`, `totalBytes`, `speedBps`, `etaSeconds` |
160
+ | `RetryOptions` | `attempts`, `delay?`, `onRetry?` |
161
+ | `QueueOptions` | `maxConcurrent?` |
162
+ | `DownloadResult` | `success`, `filePath?`, `downloadId?`, `error?` |
163
+ | `UploadOptions` | `url`, `filePath`, `fieldName?`, `headers?`, `parameters?`, `onProgress?`, `uploadId?` |
164
+ | `UploadResult` | `success`, `status?`, `data?`, `error?`, `uploadId?` |
165
+ | `UseDownloadReturn` | `start`, `pause`, `resume`, `cancel`, `status`, `progress`, `result`, `downloadId` |
166
+ | `FsStat` | `path`, `name`, `size`, `modified`, `isDir` |
167
+ | `UnzipResult` | `success`, `destDir?`, `files?`, `error?` |
168
+ | `ZipResult` | `success`, `zipPath?`, `error?` |
519
169
 
520
170
  ---
521
171