rn-file-toolkit 1.0.10 → 1.0.11
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 +1 -1
- package/android/src/main/AndroidManifest.xml +4 -2
- package/android/src/main/java/com/filetoolkit/FileToolkitModule.kt +227 -128
- package/app.plugin.js +34 -8
- package/ios/FileToolkit.mm +346 -155
- package/lib/commonjs/NativeFileToolkit.js.map +1 -1
- package/lib/commonjs/index.js +109 -30
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/NativeFileToolkit.js.map +1 -1
- package/lib/module/index.js +109 -31
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/NativeFileToolkit.d.ts +2 -0
- package/lib/typescript/commonjs/src/NativeFileToolkit.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +89 -8
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/NativeFileToolkit.d.ts +2 -0
- package/lib/typescript/module/src/NativeFileToolkit.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +89 -8
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/react-native.config.js +8 -0
- package/src/NativeFileToolkit.ts +4 -0
- package/src/index.tsx +189 -35
|
@@ -11,7 +11,9 @@ export interface DownloadOptions {
|
|
|
11
11
|
background?: boolean;
|
|
12
12
|
headers?: Record<string, string>;
|
|
13
13
|
destination?: 'downloads' | 'cache' | 'documents';
|
|
14
|
+
/** Notification title shown during background download. @platform Android */
|
|
14
15
|
notificationTitle?: string;
|
|
16
|
+
/** Notification description shown during background download. @platform Android */
|
|
15
17
|
notificationDescription?: string;
|
|
16
18
|
checksum?: {
|
|
17
19
|
hash: string;
|
|
@@ -185,7 +187,18 @@ export declare function cancelDownload(id: string): Promise<ActionResult>;
|
|
|
185
187
|
export declare function getCachedFiles(): Promise<CacheResult>;
|
|
186
188
|
export declare function deleteFile(path: string): Promise<ActionResult>;
|
|
187
189
|
export declare function clearCache(): Promise<ActionResult>;
|
|
188
|
-
export
|
|
190
|
+
export interface BackgroundDownloadInfo {
|
|
191
|
+
downloadId: string;
|
|
192
|
+
url: string;
|
|
193
|
+
status: number;
|
|
194
|
+
progress: number;
|
|
195
|
+
}
|
|
196
|
+
export interface BackgroundDownloadsResult {
|
|
197
|
+
success: boolean;
|
|
198
|
+
downloads?: BackgroundDownloadInfo[];
|
|
199
|
+
error?: string;
|
|
200
|
+
}
|
|
201
|
+
export declare function getBackgroundDownloads(): Promise<BackgroundDownloadsResult>;
|
|
189
202
|
export declare function exists(path: string): Promise<boolean>;
|
|
190
203
|
export declare function stat(path: string): Promise<FsStat>;
|
|
191
204
|
export declare function readFile(path: string, enc?: FsEncoding): Promise<string>;
|
|
@@ -198,18 +211,62 @@ export declare function df(): Promise<DiskSpaceResult>;
|
|
|
198
211
|
export declare function appendFile(path: string, data: string, enc?: FsEncoding): Promise<void>;
|
|
199
212
|
export declare function hash(path: string, algorithm?: HashAlgorithm): Promise<HashResult>;
|
|
200
213
|
export declare function getCookies(domain: string): Promise<CookiesResult>;
|
|
201
|
-
export declare function
|
|
214
|
+
export declare function clearAllCookies(): Promise<ActionResult>;
|
|
215
|
+
export declare function clearCookies(domain: string): Promise<ActionResult>;
|
|
202
216
|
export declare function saveToMediaStore(opts: MediaStoreOptions): Promise<MediaStoreResult>;
|
|
217
|
+
/**
|
|
218
|
+
* Session management API for grouping downloaded files into named sessions.
|
|
219
|
+
*
|
|
220
|
+
* @remarks
|
|
221
|
+
* Sessions are stored in JS memory only — they do **not** persist across app
|
|
222
|
+
* restarts or React Native hot-reloads. Use sessions for temporary grouping
|
|
223
|
+
* within a single app lifecycle (e.g., clearing temp files on user logout).
|
|
224
|
+
*/
|
|
203
225
|
export declare const session: SessionApi;
|
|
204
226
|
export declare const cookies: {
|
|
205
227
|
get: typeof getCookies;
|
|
206
228
|
clear: typeof clearCookies;
|
|
229
|
+
clearAll: typeof clearAllCookies;
|
|
207
230
|
};
|
|
231
|
+
/**
|
|
232
|
+
* File system API — POSIX-style operations.
|
|
233
|
+
*
|
|
234
|
+
* @remarks
|
|
235
|
+
* All `fs.*` methods **throw** on failure (via exceptions), unlike top-level
|
|
236
|
+
* helpers such as `deleteFile()` which return `{ success: false }`.
|
|
237
|
+
*
|
|
238
|
+
* To avoid IDE auto-import conflicts with Node's built-in `fs`, consider:
|
|
239
|
+
* ```ts
|
|
240
|
+
* import { fs as fileSystem } from 'rn-file-toolkit';
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
208
243
|
export declare const fs: FsApi;
|
|
209
|
-
export
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
244
|
+
export interface DownloadCompleteEvent {
|
|
245
|
+
success: boolean;
|
|
246
|
+
downloadId: string;
|
|
247
|
+
filePath?: string;
|
|
248
|
+
error?: string;
|
|
249
|
+
}
|
|
250
|
+
export interface DownloadErrorEvent {
|
|
251
|
+
success: boolean;
|
|
252
|
+
downloadId: string;
|
|
253
|
+
error: string;
|
|
254
|
+
}
|
|
255
|
+
export interface UploadProgressEvent {
|
|
256
|
+
url: string;
|
|
257
|
+
uploadId: string;
|
|
258
|
+
progress: number;
|
|
259
|
+
}
|
|
260
|
+
export interface DownloadRetryEvent {
|
|
261
|
+
downloadId: string;
|
|
262
|
+
url: string;
|
|
263
|
+
attempt: number;
|
|
264
|
+
error: string;
|
|
265
|
+
}
|
|
266
|
+
export declare function onDownloadComplete(cb: (event: DownloadCompleteEvent) => void): () => void;
|
|
267
|
+
export declare function onDownloadError(cb: (event: DownloadErrorEvent) => void): () => void;
|
|
268
|
+
export declare function onUploadProgress(cb: (event: UploadProgressEvent) => void): () => void;
|
|
269
|
+
export declare function onDownloadRetry(cb: (event: DownloadRetryEvent) => void): () => void;
|
|
213
270
|
export declare function saveBase64AsFile(opts: SaveBase64Options): Promise<SaveBase64Result>;
|
|
214
271
|
export declare function urlToBase64(opts: UrlToBase64Options): Promise<UrlToBase64Result>;
|
|
215
272
|
export declare function shareFile(opts: ShareFileOptions): Promise<ShareFileResult>;
|
|
@@ -225,8 +282,8 @@ export interface ZipResult {
|
|
|
225
282
|
zipPath?: string;
|
|
226
283
|
error?: string;
|
|
227
284
|
}
|
|
228
|
-
export declare function unzip(
|
|
229
|
-
export declare function zip(
|
|
285
|
+
export declare function unzip(sourcePath: string, destDir: string): Promise<UnzipResult>;
|
|
286
|
+
export declare function zip(sourcePath: string, destPath: string): Promise<ZipResult>;
|
|
230
287
|
export interface UseDownloadReturn {
|
|
231
288
|
start: (options: DownloadOptions) => Promise<DownloadResult>;
|
|
232
289
|
pause: () => Promise<void>;
|
|
@@ -237,7 +294,29 @@ export interface UseDownloadReturn {
|
|
|
237
294
|
result: DownloadResult | null;
|
|
238
295
|
downloadId: string | null;
|
|
239
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* React hook for managing a single download with progress, pause/resume, and cancel.
|
|
299
|
+
*
|
|
300
|
+
* @remarks
|
|
301
|
+
* The `start` callback is memoised with an empty dependency array but uses a
|
|
302
|
+
* ref internally to always read the **latest** `onProgress` callback you pass,
|
|
303
|
+
* so you do not need to memoise your options object.
|
|
304
|
+
*/
|
|
240
305
|
export declare function useDownload(): UseDownloadReturn;
|
|
306
|
+
/**
|
|
307
|
+
* Default export — provides all APIs as a single namespace.
|
|
308
|
+
*
|
|
309
|
+
* **For optimal tree-shaking, prefer named imports:**
|
|
310
|
+
* ```ts
|
|
311
|
+
* import { download, upload, fs } from 'rn-file-toolkit';
|
|
312
|
+
* ```
|
|
313
|
+
*
|
|
314
|
+
* **Error handling patterns:**
|
|
315
|
+
* - Top-level functions (`download`, `upload`, `deleteFile`, etc.) return
|
|
316
|
+
* `{ success: boolean; error?: string }` and **never throw**.
|
|
317
|
+
* - `fs.*` methods **throw** on failure via exceptions.
|
|
318
|
+
* - `useDownload()` sets `status` to `'error'` on failure.
|
|
319
|
+
*/
|
|
241
320
|
declare const _default: {
|
|
242
321
|
download: typeof download;
|
|
243
322
|
upload: typeof upload;
|
|
@@ -271,11 +350,13 @@ declare const _default: {
|
|
|
271
350
|
hash: typeof hash;
|
|
272
351
|
getCookies: typeof getCookies;
|
|
273
352
|
clearCookies: typeof clearCookies;
|
|
353
|
+
clearAllCookies: typeof clearAllCookies;
|
|
274
354
|
saveToMediaStore: typeof saveToMediaStore;
|
|
275
355
|
fs: FsApi;
|
|
276
356
|
cookies: {
|
|
277
357
|
get: typeof getCookies;
|
|
278
358
|
clear: typeof clearCookies;
|
|
359
|
+
clearAll: typeof clearAllCookies;
|
|
279
360
|
};
|
|
280
361
|
session: SessionApi;
|
|
281
362
|
useDownload: typeof useDownload;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;IAClD,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mFAAmF;IACnF,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;KACtC,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;KACpD,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC;CACnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACrC,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,QAAQ,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvE,SAAS,EAAE,CACT,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,UAAU,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,UAAU,EAAE,CACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,UAAU,KAClB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,EAAE,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAC5E;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAwFD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE3D;AAED,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAuGD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAG1E;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAyB1E;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAMrE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAMtE;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAMtE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAM3D;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAMpE;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,CAMxD;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,yBAAyB,CAAC,CAMjF;AAMD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3D;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIxD;AAED,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,UAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,UAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE;AAED,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvD;AAED,wBAAsB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIxD;AAED,wBAAsB,EAAE,IAAI,OAAO,CAAC,eAAe,CAAC,CAMnD;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,UAAmB,GACvB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,IAAI,CACxB,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,aAAqB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAMrB;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAMvE;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAE7D;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAMxE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AA6CD;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,EAAE,UAKrB,CAAC;AAEF,eAAO,MAAM,OAAO;;;;CAInB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,EAAE,EAAE,KAgBhB,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,GACzC,MAAM,IAAI,CAMZ;AACD,wBAAgB,eAAe,CAC7B,EAAE,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GACtC,MAAM,IAAI,CAMZ;AACD,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GACvC,MAAM,IAAI,CAMZ;AACD,wBAAgB,eAAe,CAC7B,EAAE,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GACtC,MAAM,IAAI,CAMZ;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAmB3B;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,iBAAiB,CAAC,CAM5B;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,eAAe,CAAC,CAS1B;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAM7E;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,KAAK,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAMtB;AAED,wBAAsB,GAAG,CACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,CAAC,CAMpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7D,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7D,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,IAAI,iBAAiB,CAsE/C;AAED;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACH,wBAyCE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rn-file-toolkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "The ultimate native file management toolkit for React Native. Features background downloads, resumable uploads, filesystem operations, queues, zip/unzip, and media utilities with zero third-party dependencies.",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/module/index.js",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"lib",
|
|
25
25
|
"android",
|
|
26
26
|
"ios",
|
|
27
|
-
"cpp",
|
|
28
27
|
"*.podspec",
|
|
29
28
|
"react-native.config.js",
|
|
30
29
|
"app.plugin.js",
|
package/src/NativeFileToolkit.ts
CHANGED
|
@@ -30,6 +30,10 @@ export interface Spec extends TurboModule {
|
|
|
30
30
|
getCookies(domain: string): Promise<Object>;
|
|
31
31
|
clearCookies(domain: string): Promise<Object>;
|
|
32
32
|
saveToMediaStore(options: Object): Promise<Object>;
|
|
33
|
+
|
|
34
|
+
// Event emitter support
|
|
35
|
+
addListener(eventName: string): void;
|
|
36
|
+
removeListeners(count: number): void;
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export default TurboModuleRegistry.getEnforcing<Spec>('FileToolkit');
|
package/src/index.tsx
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { useState, useCallback, useRef } from 'react';
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
2
2
|
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
3
3
|
import FileToolkitSpec from './NativeFileToolkit';
|
|
4
4
|
|
|
5
5
|
const FileToolkitModule = NativeModules.FileToolkit || FileToolkitSpec;
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
let _eventEmitter: NativeEventEmitter | null = null;
|
|
8
|
+
function getEventEmitter(): NativeEventEmitter {
|
|
9
|
+
if (!_eventEmitter) {
|
|
10
|
+
_eventEmitter = new NativeEventEmitter(FileToolkitModule);
|
|
11
|
+
}
|
|
12
|
+
return _eventEmitter;
|
|
13
|
+
}
|
|
7
14
|
|
|
8
15
|
export interface ProgressInfo {
|
|
9
16
|
percent: number;
|
|
@@ -19,7 +26,9 @@ export interface DownloadOptions {
|
|
|
19
26
|
background?: boolean;
|
|
20
27
|
headers?: Record<string, string>;
|
|
21
28
|
destination?: 'downloads' | 'cache' | 'documents';
|
|
29
|
+
/** Notification title shown during background download. @platform Android */
|
|
22
30
|
notificationTitle?: string;
|
|
31
|
+
/** Notification description shown during background download. @platform Android */
|
|
23
32
|
notificationDescription?: string;
|
|
24
33
|
checksum?: {
|
|
25
34
|
hash: string;
|
|
@@ -282,11 +291,27 @@ class DownloadQueue {
|
|
|
282
291
|
const _globalQueue = new DownloadQueue();
|
|
283
292
|
|
|
284
293
|
function _generateId(): string {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
// Use crypto.getRandomValues (available on Hermes since RN 0.73) for collision resistance
|
|
295
|
+
if (
|
|
296
|
+
typeof globalThis.crypto !== 'undefined' &&
|
|
297
|
+
typeof globalThis.crypto.getRandomValues === 'function'
|
|
298
|
+
) {
|
|
299
|
+
const bytes = new Uint8Array(16);
|
|
300
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
301
|
+
bytes[6] = (bytes[6]! & 0x0f) | 0x40; // version 4
|
|
302
|
+
bytes[8] = (bytes[8]! & 0x3f) | 0x80; // variant 1
|
|
303
|
+
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join(
|
|
304
|
+
''
|
|
305
|
+
);
|
|
306
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(
|
|
307
|
+
12,
|
|
308
|
+
16
|
|
309
|
+
)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
310
|
+
}
|
|
311
|
+
// Fallback for older Hermes: timestamp + random suffix for uniqueness
|
|
312
|
+
return `${Date.now().toString(36)}-${Math.random()
|
|
313
|
+
.toString(36)
|
|
314
|
+
.slice(2, 10)}`;
|
|
290
315
|
}
|
|
291
316
|
|
|
292
317
|
export function setQueueOptions(options: QueueOptions): void {
|
|
@@ -309,7 +334,7 @@ async function _executeDownload(
|
|
|
309
334
|
let _smoothedSpeedBps: number = 0;
|
|
310
335
|
|
|
311
336
|
if (options.onProgress) {
|
|
312
|
-
progressSubscription =
|
|
337
|
+
progressSubscription = getEventEmitter().addListener(
|
|
313
338
|
'onDownloadProgress',
|
|
314
339
|
(event: any) => {
|
|
315
340
|
const matchesId = event.downloadId === knownDownloadId;
|
|
@@ -352,7 +377,7 @@ async function _executeDownload(
|
|
|
352
377
|
}
|
|
353
378
|
|
|
354
379
|
if (options.retry?.onRetry) {
|
|
355
|
-
retrySubscription =
|
|
380
|
+
retrySubscription = getEventEmitter().addListener(
|
|
356
381
|
'onDownloadRetry',
|
|
357
382
|
(event: any) => {
|
|
358
383
|
const matchesId = event.downloadId === knownDownloadId;
|
|
@@ -378,12 +403,14 @@ async function _executeDownload(
|
|
|
378
403
|
headers: options.headers ?? {},
|
|
379
404
|
destination: options.destination ?? 'downloads',
|
|
380
405
|
};
|
|
406
|
+
// Strip JS-only fields — functions cannot be serialized across the native bridge
|
|
381
407
|
delete nativeOpts.onProgress;
|
|
382
408
|
delete nativeOpts.queue;
|
|
383
409
|
delete nativeOpts.priority;
|
|
384
410
|
if (nativeOpts.retry) {
|
|
411
|
+
// Reconstruct retry without the onRetry callback to prevent function leak
|
|
385
412
|
nativeOpts.retry = {
|
|
386
|
-
attempts: nativeOpts.retry.attempts,
|
|
413
|
+
attempts: nativeOpts.retry.attempts ?? 0,
|
|
387
414
|
delay: nativeOpts.retry.delay,
|
|
388
415
|
};
|
|
389
416
|
}
|
|
@@ -405,7 +432,7 @@ export async function upload(options: UploadOptions): Promise<UploadResult> {
|
|
|
405
432
|
let sub: any = null;
|
|
406
433
|
const uploadId = options.uploadId || _generateId();
|
|
407
434
|
if (options.onProgress) {
|
|
408
|
-
sub =
|
|
435
|
+
sub = getEventEmitter().addListener('onUploadProgress', (e: any) => {
|
|
409
436
|
if (e.uploadId === uploadId) options.onProgress!(e.progress);
|
|
410
437
|
});
|
|
411
438
|
}
|
|
@@ -476,7 +503,20 @@ export async function clearCache(): Promise<ActionResult> {
|
|
|
476
503
|
}
|
|
477
504
|
}
|
|
478
505
|
|
|
479
|
-
export
|
|
506
|
+
export interface BackgroundDownloadInfo {
|
|
507
|
+
downloadId: string;
|
|
508
|
+
url: string;
|
|
509
|
+
status: number;
|
|
510
|
+
progress: number;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export interface BackgroundDownloadsResult {
|
|
514
|
+
success: boolean;
|
|
515
|
+
downloads?: BackgroundDownloadInfo[];
|
|
516
|
+
error?: string;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export async function getBackgroundDownloads(): Promise<BackgroundDownloadsResult> {
|
|
480
520
|
try {
|
|
481
521
|
return await (FileToolkitModule as any).getBackgroundDownloads();
|
|
482
522
|
} catch (err: any) {
|
|
@@ -575,7 +615,11 @@ export async function getCookies(domain: string): Promise<CookiesResult> {
|
|
|
575
615
|
}
|
|
576
616
|
}
|
|
577
617
|
|
|
578
|
-
export async function
|
|
618
|
+
export async function clearAllCookies(): Promise<ActionResult> {
|
|
619
|
+
return clearCookies('');
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export async function clearCookies(domain: string): Promise<ActionResult> {
|
|
579
623
|
try {
|
|
580
624
|
return await (FileToolkitModule as any).clearCookies(domain);
|
|
581
625
|
} catch (err: any) {
|
|
@@ -640,6 +684,14 @@ async function _sessionClearAll(): Promise<ActionResult> {
|
|
|
640
684
|
: { success: true };
|
|
641
685
|
}
|
|
642
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Session management API for grouping downloaded files into named sessions.
|
|
689
|
+
*
|
|
690
|
+
* @remarks
|
|
691
|
+
* Sessions are stored in JS memory only — they do **not** persist across app
|
|
692
|
+
* restarts or React Native hot-reloads. Use sessions for temporary grouping
|
|
693
|
+
* within a single app lifecycle (e.g., clearing temp files on user logout).
|
|
694
|
+
*/
|
|
643
695
|
export const session: SessionApi = {
|
|
644
696
|
add: _sessionAdd,
|
|
645
697
|
get: _sessionGet,
|
|
@@ -650,8 +702,21 @@ export const session: SessionApi = {
|
|
|
650
702
|
export const cookies = {
|
|
651
703
|
get: getCookies,
|
|
652
704
|
clear: clearCookies,
|
|
705
|
+
clearAll: clearAllCookies,
|
|
653
706
|
};
|
|
654
707
|
|
|
708
|
+
/**
|
|
709
|
+
* File system API — POSIX-style operations.
|
|
710
|
+
*
|
|
711
|
+
* @remarks
|
|
712
|
+
* All `fs.*` methods **throw** on failure (via exceptions), unlike top-level
|
|
713
|
+
* helpers such as `deleteFile()` which return `{ success: false }`.
|
|
714
|
+
*
|
|
715
|
+
* To avoid IDE auto-import conflicts with Node's built-in `fs`, consider:
|
|
716
|
+
* ```ts
|
|
717
|
+
* import { fs as fileSystem } from 'rn-file-toolkit';
|
|
718
|
+
* ```
|
|
719
|
+
*/
|
|
655
720
|
export const fs: FsApi = {
|
|
656
721
|
exists,
|
|
657
722
|
stat,
|
|
@@ -661,7 +726,8 @@ export const fs: FsApi = {
|
|
|
661
726
|
copyFile,
|
|
662
727
|
moveFile,
|
|
663
728
|
deleteFile: async (p) => {
|
|
664
|
-
|
|
729
|
+
const res = await (FileToolkitModule as any).deleteFile(p);
|
|
730
|
+
_ensure(res, 'DEL_ERROR');
|
|
665
731
|
},
|
|
666
732
|
mkdir,
|
|
667
733
|
ls,
|
|
@@ -669,20 +735,66 @@ export const fs: FsApi = {
|
|
|
669
735
|
hash,
|
|
670
736
|
};
|
|
671
737
|
|
|
672
|
-
export
|
|
673
|
-
|
|
738
|
+
export interface DownloadCompleteEvent {
|
|
739
|
+
success: boolean;
|
|
740
|
+
downloadId: string;
|
|
741
|
+
filePath?: string;
|
|
742
|
+
error?: string;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
export interface DownloadErrorEvent {
|
|
746
|
+
success: boolean;
|
|
747
|
+
downloadId: string;
|
|
748
|
+
error: string;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
export interface UploadProgressEvent {
|
|
752
|
+
url: string;
|
|
753
|
+
uploadId: string;
|
|
754
|
+
progress: number;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
export interface DownloadRetryEvent {
|
|
758
|
+
downloadId: string;
|
|
759
|
+
url: string;
|
|
760
|
+
attempt: number;
|
|
761
|
+
error: string;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
export function onDownloadComplete(
|
|
765
|
+
cb: (event: DownloadCompleteEvent) => void
|
|
766
|
+
): () => void {
|
|
767
|
+
const s = getEventEmitter().addListener(
|
|
768
|
+
'onDownloadComplete',
|
|
769
|
+
cb as (event: any) => void
|
|
770
|
+
);
|
|
674
771
|
return () => s.remove();
|
|
675
772
|
}
|
|
676
|
-
export function onDownloadError(
|
|
677
|
-
|
|
773
|
+
export function onDownloadError(
|
|
774
|
+
cb: (event: DownloadErrorEvent) => void
|
|
775
|
+
): () => void {
|
|
776
|
+
const s = getEventEmitter().addListener(
|
|
777
|
+
'onDownloadError',
|
|
778
|
+
cb as (event: any) => void
|
|
779
|
+
);
|
|
678
780
|
return () => s.remove();
|
|
679
781
|
}
|
|
680
|
-
export function onUploadProgress(
|
|
681
|
-
|
|
782
|
+
export function onUploadProgress(
|
|
783
|
+
cb: (event: UploadProgressEvent) => void
|
|
784
|
+
): () => void {
|
|
785
|
+
const s = getEventEmitter().addListener(
|
|
786
|
+
'onUploadProgress',
|
|
787
|
+
cb as (event: any) => void
|
|
788
|
+
);
|
|
682
789
|
return () => s.remove();
|
|
683
790
|
}
|
|
684
|
-
export function onDownloadRetry(
|
|
685
|
-
|
|
791
|
+
export function onDownloadRetry(
|
|
792
|
+
cb: (event: DownloadRetryEvent) => void
|
|
793
|
+
): () => void {
|
|
794
|
+
const s = getEventEmitter().addListener(
|
|
795
|
+
'onDownloadRetry',
|
|
796
|
+
cb as (event: any) => void
|
|
797
|
+
);
|
|
686
798
|
return () => s.remove();
|
|
687
799
|
}
|
|
688
800
|
|
|
@@ -753,19 +865,25 @@ export interface ZipResult {
|
|
|
753
865
|
error?: string;
|
|
754
866
|
}
|
|
755
867
|
|
|
756
|
-
export async function unzip(
|
|
868
|
+
export async function unzip(
|
|
869
|
+
sourcePath: string,
|
|
870
|
+
destDir: string
|
|
871
|
+
): Promise<UnzipResult> {
|
|
757
872
|
try {
|
|
758
|
-
return await (FileToolkitModule as any).unzip(
|
|
759
|
-
} catch {
|
|
760
|
-
return { success: false, error: 'UNZIP_ERROR' };
|
|
873
|
+
return await (FileToolkitModule as any).unzip(sourcePath, destDir);
|
|
874
|
+
} catch (err: any) {
|
|
875
|
+
return { success: false, error: err?.message || 'UNZIP_ERROR' };
|
|
761
876
|
}
|
|
762
877
|
}
|
|
763
878
|
|
|
764
|
-
export async function zip(
|
|
879
|
+
export async function zip(
|
|
880
|
+
sourcePath: string,
|
|
881
|
+
destPath: string
|
|
882
|
+
): Promise<ZipResult> {
|
|
765
883
|
try {
|
|
766
|
-
return await (FileToolkitModule as any).zip(
|
|
767
|
-
} catch {
|
|
768
|
-
return { success: false, error: 'ZIP_ERROR' };
|
|
884
|
+
return await (FileToolkitModule as any).zip(sourcePath, destPath);
|
|
885
|
+
} catch (err: any) {
|
|
886
|
+
return { success: false, error: err?.message || 'ZIP_ERROR' };
|
|
769
887
|
}
|
|
770
888
|
}
|
|
771
889
|
|
|
@@ -780,14 +898,34 @@ export interface UseDownloadReturn {
|
|
|
780
898
|
downloadId: string | null;
|
|
781
899
|
}
|
|
782
900
|
|
|
901
|
+
/**
|
|
902
|
+
* React hook for managing a single download with progress, pause/resume, and cancel.
|
|
903
|
+
*
|
|
904
|
+
* @remarks
|
|
905
|
+
* The `start` callback is memoised with an empty dependency array but uses a
|
|
906
|
+
* ref internally to always read the **latest** `onProgress` callback you pass,
|
|
907
|
+
* so you do not need to memoise your options object.
|
|
908
|
+
*/
|
|
783
909
|
export function useDownload(): UseDownloadReturn {
|
|
784
910
|
const [status, setStatus] = useState<any>('idle');
|
|
785
911
|
const [progress, setProgress] = useState<ProgressInfo | null>(null);
|
|
786
912
|
const [result, setResult] = useState<DownloadResult | null>(null);
|
|
787
913
|
const [downloadId, setDownloadId] = useState<string | null>(null);
|
|
788
914
|
const downloadIdRef = useRef<string | null>(null);
|
|
915
|
+
const latestOptsRef = useRef<DownloadOptions | null>(null);
|
|
916
|
+
|
|
917
|
+
// Cancel any in-flight download when the component unmounts to prevent
|
|
918
|
+
// native event listeners from calling setState on an unmounted component.
|
|
919
|
+
useEffect(() => {
|
|
920
|
+
return () => {
|
|
921
|
+
if (downloadIdRef.current) {
|
|
922
|
+
cancelDownload(downloadIdRef.current);
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
}, []);
|
|
789
926
|
|
|
790
927
|
const start = useCallback(async (opts: DownloadOptions) => {
|
|
928
|
+
latestOptsRef.current = opts;
|
|
791
929
|
const id = opts.downloadId || _generateId();
|
|
792
930
|
setStatus('downloading');
|
|
793
931
|
setProgress(null);
|
|
@@ -799,7 +937,8 @@ export function useDownload(): UseDownloadReturn {
|
|
|
799
937
|
downloadId: id,
|
|
800
938
|
onProgress: (p) => {
|
|
801
939
|
setProgress(p);
|
|
802
|
-
|
|
940
|
+
// Always call the latest onProgress — avoids stale-closure issues
|
|
941
|
+
latestOptsRef.current?.onProgress?.(p);
|
|
803
942
|
},
|
|
804
943
|
});
|
|
805
944
|
setResult(res);
|
|
@@ -815,14 +954,14 @@ export function useDownload(): UseDownloadReturn {
|
|
|
815
954
|
|
|
816
955
|
const pause = useCallback(async () => {
|
|
817
956
|
if (downloadIdRef.current) {
|
|
818
|
-
await pauseDownload(downloadIdRef.current);
|
|
819
|
-
setStatus('paused');
|
|
957
|
+
const res = await pauseDownload(downloadIdRef.current);
|
|
958
|
+
if (res.success) setStatus('paused');
|
|
820
959
|
}
|
|
821
960
|
}, []);
|
|
822
961
|
const resume = useCallback(async () => {
|
|
823
962
|
if (downloadIdRef.current) {
|
|
824
|
-
await resumeDownload(downloadIdRef.current);
|
|
825
|
-
setStatus('downloading');
|
|
963
|
+
const res = await resumeDownload(downloadIdRef.current);
|
|
964
|
+
if (res.success) setStatus('downloading');
|
|
826
965
|
}
|
|
827
966
|
}, []);
|
|
828
967
|
const cancel = useCallback(async () => {
|
|
@@ -839,6 +978,20 @@ export function useDownload(): UseDownloadReturn {
|
|
|
839
978
|
return { start, pause, resume, cancel, status, progress, result, downloadId };
|
|
840
979
|
}
|
|
841
980
|
|
|
981
|
+
/**
|
|
982
|
+
* Default export — provides all APIs as a single namespace.
|
|
983
|
+
*
|
|
984
|
+
* **For optimal tree-shaking, prefer named imports:**
|
|
985
|
+
* ```ts
|
|
986
|
+
* import { download, upload, fs } from 'rn-file-toolkit';
|
|
987
|
+
* ```
|
|
988
|
+
*
|
|
989
|
+
* **Error handling patterns:**
|
|
990
|
+
* - Top-level functions (`download`, `upload`, `deleteFile`, etc.) return
|
|
991
|
+
* `{ success: boolean; error?: string }` and **never throw**.
|
|
992
|
+
* - `fs.*` methods **throw** on failure via exceptions.
|
|
993
|
+
* - `useDownload()` sets `status` to `'error'` on failure.
|
|
994
|
+
*/
|
|
842
995
|
export default {
|
|
843
996
|
download,
|
|
844
997
|
upload,
|
|
@@ -872,6 +1025,7 @@ export default {
|
|
|
872
1025
|
hash,
|
|
873
1026
|
getCookies,
|
|
874
1027
|
clearCookies,
|
|
1028
|
+
clearAllCookies,
|
|
875
1029
|
saveToMediaStore,
|
|
876
1030
|
fs,
|
|
877
1031
|
cookies,
|