Skip to content

Commit 6eb2777

Browse files
committed
docs: 4.x documentation updates
1 parent 5da5a31 commit 6eb2777

File tree

2 files changed

+195
-27
lines changed

2 files changed

+195
-27
lines changed

README.md

Lines changed: 176 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# react-native-fs2
22
_A fork of [react-native-fs](https://github.com/itinance/react-native-fs) with a smaller footprint and fixes due to the upstream library seemingly being abandoned._
33

4+
**Now powered by [Nitro Modules](https://github.com/mrousavy/nitro)** for superior performance and type safety! 🚀
5+
46
### Why the fork?
57
This library intentional or not has become critical to the success of our mobile applications. We've noticed a few things that led to this fork:
68

@@ -18,19 +20,42 @@ We debated a few paths, but we felt it best to fork the project and make some ma
1820

1921
We will continue to support this library for as long as we use it.
2022

23+
## Features
24+
25+
- 🚀 **High Performance**: Powered by Nitro Modules with direct JSI bindings
26+
- 📁 **File System Operations**: Complete file system access (read, write, copy, move, etc.)
27+
- 🌊 **File Streaming** (Beta): Efficiently handle large files with streaming API
28+
- 📱 **MediaStore Support**: Android MediaStore integration for media files
29+
- ⬇️ **Downloads**: Background downloads with progress tracking
30+
- 🔒 **Type Safe**: Full TypeScript support with end-to-end type safety
31+
- 🎯 **Cross Platform**: iOS and Android support
32+
2133
### Installation
2234
```bash
2335
npm i --save react-native-fs2
36+
# Peer dependency required
37+
npm i --save react-native-nitro-modules
2438
```
2539

2640
#### Supported React Native Versions
2741
| react-native-fs2 | react-native |
2842
|------------------|--------------|
43+
| 4.x (nitro) | >=0.80 |
2944
| 3.0.x | >=0.69 |
3045

3146
### Changelog
3247
Changes can be found in [CHANGELOG.md](CHANGELOG.md)
3348

49+
### What's New in 4.x
50+
51+
- **Nitro Modules Architecture**: Complete rewrite using Nitro Modules for superior performance
52+
- **File Streaming API**: New streaming capabilities for large file operations (see [FILE_STREAM.md](./docs/FILE_STREAM.md))
53+
- **Better Type Safety**: End-to-end type safety from TypeScript to native code
54+
- **ArrayBuffer Built-in**: Native ArrayBuffer support without additional dependencies
55+
- **Backward Compatible API**: Most existing code works without changes!
56+
57+
> **Note**: v4.x requires `react-native-nitro-modules` as a peer dependency. See migration notes below.
58+
3459
## Usage
3560
```ts
3661
import RNFS from 'react-native-fs2';
@@ -114,15 +139,15 @@ await RNFS.completeHandler('JobID')
114139
// readDir(dirPath: string): Promise<ReadDirItem[]>
115140
const dirItems = await RNFS.readDir('DirPath')
116141
```
117-
* Retuns an `array` of `ReadDirItem` which are items that are present in the directory
142+
* Returns an `array` of `ReadDirItem` which are items that are present in the directory
118143
* `ReadDirItem`
119-
* ctime: `Date | undefined` -> The creation date of the file (iOS only)
120-
* mtime: `Date | undefined` -> The last modified date of the file
144+
* ctime: `number | undefined` -> The creation timestamp in milliseconds (iOS only)
145+
* mtime: `number` -> The last modified timestamp in milliseconds
121146
* name: `string` -> The name of the item
122147
* path: `string` -> The absolute path to the item
123148
* size: `number` -> Size in bytes
124-
* isFile: () => `boolean` -> Is the file just a file?
125-
* isDirectory: () => `boolean` -> Is the file a directory?
149+
* isFile: `boolean` -> Is the item a file?
150+
* isDirectory: `boolean` -> Is the item a directory?
126151

127152

128153
### `readFile`
@@ -134,8 +159,7 @@ const fileData = await RNFS.readFile('DirPath', 'utf8')
134159
* Optionally includes `EncodingOrOptions` with values:
135160
* `'utf8'` (default) | `'base64'` (for binary files) | `'ascii'` | `'arraybuffer'`
136161
* ...fileoptions
137-
* Note: `arraybuffer` requires [react-native-blob-jsi-helper](https://github.com/mrousavy/react-native-blob-jsi-helper)
138-
* `npm i react-native-blob-jsi-helper` or `yarn add react-native-blob-jsi-helper`
162+
* Note: `arraybuffer` support is built-in via Nitro Modules (no additional dependencies required)
139163

140164
### `read`
141165
```ts
@@ -202,13 +226,13 @@ await RNFS.write('FileToWrite', 'ContentsToWrite', -1, 'utf8')
202226
// stat(filepath: string): Promise<StatResult>
203227
const fileStats = await RNFS.stat('FilePath')
204228
```
205-
* Retuns an `array` of `StatResult` which are `statistics` of the `file`
229+
* Returns a `StatResult` object with statistics of the file
206230
* `StatResult`
207231
* path: `string` -> The same as filepath argument
208-
* ctime: `date` -> The creation date of the file
209-
* mtime: `date` -> The last modified date of the file
232+
* ctime: `number` -> The creation timestamp in milliseconds
233+
* mtime: `number` -> The last modified timestamp in milliseconds
210234
* size: `number` -> Size in bytes
211-
* mode: `number` -> UNIX file mode
235+
* mode: `number` -> UNIX file mode (iOS only)
212236
* originalFilepath: `string` -> Android: In case of content uri this is the pointed file path, otherwise is the same as path
213237
* isFile: () => `boolean` -> Is the file just a file?
214238
* isDirectory: () => `boolean` -> Is the file a directory?
@@ -278,6 +302,68 @@ await RNFS.scanFile('FilePath', Date, Date)
278302
```
279303
* Scan the file using [Media Scanner](https://developer.android.com/reference/android/media/MediaScannerConnection).
280304

305+
# File Streaming API (Beta)
306+
307+
React-native-fs2 now provides powerful file streaming capabilities for efficiently reading and writing large files without loading entire content into memory.
308+
309+
### `createReadStream`
310+
```ts
311+
import { createReadStream, listenToReadStreamData, listenToReadStreamProgress, listenToReadStreamEnd } from 'react-native-fs2';
312+
313+
const stream = await createReadStream('/path/to/large-file.dat', {
314+
bufferSize: 8192 // 8KB chunks
315+
});
316+
317+
// Listen for data chunks
318+
const unsubData = listenToReadStreamData(stream.streamId, (event) => {
319+
console.log(`Chunk ${event.chunk}: ${event.data.byteLength} bytes`);
320+
});
321+
322+
// Listen for progress
323+
const unsubProgress = listenToReadStreamProgress(stream.streamId, (event) => {
324+
console.log(`Progress: ${event.progress * 100}%`);
325+
});
326+
327+
// Listen for completion
328+
const unsubEnd = listenToReadStreamEnd(stream.streamId, (event) => {
329+
console.log('Stream finished');
330+
unsubData();
331+
unsubProgress();
332+
unsubEnd();
333+
});
334+
335+
await stream.start();
336+
```
337+
338+
### `createWriteStream`
339+
```ts
340+
import { createWriteStream, listenToWriteStreamProgress, listenToWriteStreamFinish } from 'react-native-fs2';
341+
342+
const stream = await createWriteStream('/path/to/output-file.dat', {
343+
append: false,
344+
createDirectories: true
345+
});
346+
347+
// Listen for progress
348+
const unsubProgress = listenToWriteStreamProgress(stream.streamId, (event) => {
349+
console.log(`Written: ${event.bytesWritten} bytes`);
350+
});
351+
352+
// Listen for completion
353+
const unsubFinish = listenToWriteStreamFinish(stream.streamId, (event) => {
354+
console.log('Write completed:', event.bytesWritten, 'bytes');
355+
unsubProgress();
356+
unsubFinish();
357+
});
358+
359+
// Write data in chunks
360+
await stream.write(chunk1);
361+
await stream.write(chunk2);
362+
await stream.close();
363+
```
364+
365+
**For complete streaming API documentation, see [FILE_STREAM.md](./docs/FILE_STREAM.md)**
366+
281367
# MediaStore
282368

283369
### RNFS2 can now interact with the MediaStore on Android. This allows you to add, delete, and update media files in the MediaStore.
@@ -433,3 +519,82 @@ type MediaStoreQueryResult = {
433519
#### iOS
434520
* `LibraryDirectoryPath` - Absolute path to [NSLibraryDirectory](https://developer.apple.com/documentation/foundation/nssearchpathdirectory/nslibrarydirectory)
435521
* `MainBundlePath` - Absolute path to main bundle directory.
522+
523+
## Migrating from v3.x to v4.x
524+
525+
The v4.x release brings significant improvements with minimal breaking changes. Most apps can upgrade with little to no code changes!
526+
527+
### Installation
528+
529+
1. **Install peer dependency:**
530+
```bash
531+
npm install react-native-nitro-modules
532+
# or
533+
yarn add react-native-nitro-modules
534+
```
535+
536+
2. **Update react-native-fs2:**
537+
```bash
538+
npm install react-native-fs2@latest
539+
# or
540+
yarn add react-native-fs2@latest
541+
```
542+
543+
### Breaking Changes
544+
545+
#### Timestamps are now numbers
546+
The only significant breaking change is that timestamps are now returned as numbers (milliseconds since epoch) instead of Date objects:
547+
548+
```typescript
549+
// v3.x
550+
const items = await RNFS.readDir(path);
551+
const date = items[0].mtime; // Date object
552+
553+
// v4.x
554+
const items = await RNFS.readDir(path);
555+
const timestamp = items[0].mtime; // number
556+
const date = new Date(items[0].mtime); // Convert to Date if needed
557+
```
558+
559+
This affects:
560+
- `readDir()` - `ctime` and `mtime` fields
561+
- `stat()` - `ctime` and `mtime` fields
562+
563+
### What Still Works
564+
565+
**All core file operations** - No changes required:
566+
```typescript
567+
await RNFS.readFile(path, 'utf8');
568+
await RNFS.writeFile(path, content, 'utf8');
569+
await RNFS.copyFile(src, dest);
570+
await RNFS.moveFile(src, dest);
571+
await RNFS.unlink(path);
572+
// ... all other operations work the same!
573+
```
574+
575+
**Download API** - Backward compatible:
576+
```typescript
577+
const { jobId, promise } = RNFS.downloadFile({
578+
fromUrl: url,
579+
toFile: path,
580+
begin: (res) => { },
581+
progress: (res) => { }
582+
});
583+
```
584+
585+
**MediaStore** (Android) - Works the same
586+
587+
### New Features to Explore
588+
589+
Once migrated, you can optionally explore:
590+
591+
- **File Streaming API**: For efficient large file operations (see [FILE_STREAM.md](./docs/FILE_STREAM.md))
592+
- **Better Performance**: Automatic via Nitro Modules architecture
593+
- **Enhanced Type Safety**: Full TypeScript support throughout
594+
595+
### Need Help?
596+
597+
If you encounter issues during migration:
598+
1. Check the [CHANGELOG.md](./CHANGELOG.md) for detailed changes
599+
2. Review [FILE_STREAM.md](./docs/FILE_STREAM.md) for streaming API
600+
3. Open an issue on [GitHub](https://github.com/sourcetoad/react-native-fs2/issues)

docs/FILE_STREAM.md

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ Creates a read stream for efficiently reading large files in chunks.
3131
```typescript
3232
interface ReadStreamOptions {
3333
bufferSize?: number; // Buffer size in bytes (default: 4096)
34-
start?: bigint; // Start position in bytes (default: 0)
35-
end?: bigint; // End position in bytes (default: file end)
34+
start?: number; // Start position in bytes (default: 0)
35+
end?: number; // End position in bytes (default: file end)
3636
}
3737
```
3838

@@ -93,20 +93,20 @@ function listenToReadStreamProgress(
9393
interface ReadStreamDataEvent {
9494
streamId: string;
9595
data: ArrayBuffer; // Raw data chunk
96-
chunk: bigint; // Chunk number (0-based)
97-
position: bigint; // Current position in file
96+
chunk: number; // Chunk number (0-based)
97+
position: number; // Current position in file
9898
}
9999

100100
interface ReadStreamProgressEvent {
101101
streamId: string;
102-
bytesRead: bigint; // Total bytes read so far
103-
totalBytes: bigint; // Total file size
102+
bytesRead: number; // Total bytes read so far
103+
totalBytes: number; // Total file size
104104
progress: number; // Progress as percentage (0-100)
105105
}
106106

107107
interface ReadStreamEndEvent {
108108
streamId: string;
109-
bytesRead: bigint; // Total bytes read
109+
bytesRead: number; // Total bytes read
110110
success: boolean;
111111
}
112112

@@ -208,21 +208,24 @@ interface WriteStreamOptions {
208208
```typescript
209209
interface WriteStreamHandle {
210210
streamId: string;
211-
211+
212212
// Write data chunk to stream
213213
write(data: ArrayBuffer): Promise<void>;
214-
214+
215215
// Flush any buffered data
216216
flush(): Promise<void>;
217-
217+
218218
// Close the stream and finish writing
219219
close(): Promise<void>;
220-
220+
221221
// Check if stream is active
222222
isActive(): Promise<boolean>;
223-
223+
224224
// Get current write position
225-
getPosition(): Promise<bigint>;
225+
getPosition(): Promise<number>;
226+
227+
// End the stream (alias for close)
228+
end(): Promise<void>;
226229
}
227230
```
228231

@@ -253,13 +256,13 @@ function listenToWriteStreamError(
253256
```typescript
254257
interface WriteStreamProgressEvent {
255258
streamId: string;
256-
bytesWritten: bigint; // Total bytes written so far
257-
lastChunkSize: bigint; // Size of last written chunk
259+
bytesWritten: number; // Total bytes written so far
260+
lastChunkSize: number; // Size of last written chunk
258261
}
259262

260263
interface WriteStreamFinishEvent {
261264
streamId: string;
262-
bytesWritten: bigint; // Total bytes written
265+
bytesWritten: number; // Total bytes written
263266
success: boolean;
264267
}
265268

0 commit comments

Comments
 (0)