Skip to content

Commit 2e4cd5b

Browse files
committed
docs: add a separate section for resource fetcher
1 parent 76ec2e1 commit 2e4cd5b

6 files changed

Lines changed: 177 additions & 45 deletions

File tree

.cspell-wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,4 @@ nˈɛvəɹ
180180
ˈɛniwˌʌn
181181
ˈɛls
182182
Synchronizable
183+
stringifying

docs/docs/01-fundamentals/01-getting-started.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ Installation is pretty straightforward, use your package manager of choice to in
4646
```
4747
npm install react-native-executorch
4848
# For Expo projects
49-
pnpm install react-native-executorch-expo-resource-fetcher
50-
# For bare RN projects
49+
npm install react-native-executorch-expo-resource-fetcher
50+
# For bare React Native projects
5151
npm install react-native-executorch-bare-resource-fetcher
5252
```
5353

@@ -58,7 +58,7 @@ Installation is pretty straightforward, use your package manager of choice to in
5858
pnpm install react-native-executorch
5959
# For Expo projects
6060
pnpm install react-native-executorch-expo-resource-fetcher
61-
# For bare RN projects
61+
# For bare React Native projects
6262
pnpm install react-native-executorch-bare-resource-fetcher
6363

6464
```
@@ -70,7 +70,7 @@ Installation is pretty straightforward, use your package manager of choice to in
7070
yarn add react-native-executorch
7171
# For Expo projects
7272
yarn install react-native-executorch-expo-resource-fetcher
73-
# For bare RN projects
73+
# For bare React Native projects
7474
yarn install react-native-executorch-bare-resource-fetcher
7575
```
7676

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
---
2-
title: Resource Fetcher
2+
title: Usage
33
---
44

5-
This module provides functions to download and work with downloaded files stored in the application's document directory inside the `react-native-executorch/` directory. These utilities can help you manage your storage and clean up the downloaded files when they are no longer needed.
5+
This page documents the resource fetcher APIs exposed by `react-native-executorch-expo-resource-fetcher` and `react-native-executorch-bare-resource-fetcher`. These adapters handle downloading and managing model files on disk.
6+
7+
:::info
8+
All examples below use `ExpoResourceFetcher`. If you're on bare React Native, replace the import with:
9+
10+
```typescript
11+
import { BareResourceFetcher } from 'react-native-executorch-bare-resource-fetcher';
12+
```
13+
14+
The API is identical between both adapters.
15+
:::
616

717
## fetch
818

9-
Fetches resources (remote URLs, local files or embedded assets), downloads or stores them locally for use by React Native ExecuTorch.
19+
Fetches resources (remote URLs, local files, or embedded assets) and stores them locally for use by React Native ExecuTorch.
1020

1121
### Reference
1222

1323
```typescript
14-
import { ResourceFetcher } from 'react-native-executorch';
24+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
1525

16-
const uris = await ResourceFetcher.fetch(
26+
const uris = await ExpoResourceFetcher.fetch(
1727
(progress) => console.log('Total progress:', progress),
1828
'https://.../llama3_2.pte',
1929
'https://.../qwen3.pte'
@@ -29,31 +39,31 @@ const uris = await ResourceFetcher.fetch(
2939

3040
`Promise<string[] | null>`:
3141

32-
- If the fetch was successful, it returns a promise which resolves to an array of local file paths for the downloaded/stored resources (without file:// prefix).
42+
- If the fetch was successful, it returns a promise which resolves to an array of local file paths for the downloaded/stored resources (without `file://` prefix).
3343
- If the fetch was interrupted by `pauseFetching` or `cancelFetching`, it returns a promise which resolves to `null`.
3444

3545
:::info
36-
If the resource is an object, it will be saved as a JSON file on disk.
46+
If the resource is an object, it will be saved as a JSON file on disk.
3747
:::
3848

3949
## pauseFetching
4050

41-
Pauses an ongoing download of files.
51+
Pauses an ongoing download.
4252

4353
### Reference
4454

4555
```typescript
46-
import { ResourceFetcher } from 'react-native-executorch';
56+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
4757

48-
const uris = ResourceFetcher.fetch(
58+
const uris = ExpoResourceFetcher.fetch(
4959
(progress) => console.log('Total progress:', progress),
5060
'https://.../llama3_2.pte',
5161
'https://.../qwen3.pte'
5262
).then((uris) => {
53-
console.log('URI resolved to: ', uris); // since we pause the fetch, uris is resolved to null
63+
console.log('URI resolved to: ', uris); // null, since we paused
5464
});
5565

56-
await ResourceFetcher.pauseFetching(
66+
await ExpoResourceFetcher.pauseFetching(
5767
'https://.../llama3_2.pte',
5868
'https://.../qwen3.pte'
5969
);
@@ -69,31 +79,31 @@ await ResourceFetcher.pauseFetching(
6979

7080
## resumeFetching
7181

72-
Resumes a paused download of files.
82+
Resumes a paused download.
7383

7484
### Reference
7585

7686
```typescript
77-
import { ResourceFetcher } from 'react-native-executorch';
87+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
7888

79-
const uris = ResourceFetcher.fetch(
89+
const uris = ExpoResourceFetcher.fetch(
8090
(progress) => console.log('Total progress:', progress),
8191
'https://.../llama3_2.pte',
8292
'https://.../qwen3.pte'
8393
).then((uris) => {
84-
console.log('URI resolved as: ', uris); // since we pause the fetch, uris is resolved to null
94+
console.log('URI resolved as: ', uris); // null, since we paused
8595
});
8696

87-
await ResourceFetcher.pauseFetching(
97+
await ExpoResourceFetcher.pauseFetching(
8898
'https://.../llama3_2.pte',
8999
'https://.../qwen3.pte'
90100
);
91101

92-
const resolvedUris = await ResourceFetcher.resumeFetching(
102+
const resolvedUris = await ExpoResourceFetcher.resumeFetching(
93103
'https://.../llama3_2.pte',
94104
'https://.../qwen3.pte'
95105
);
96-
//resolvedUris is resolved to file paths to fetched resources, unless explicitly paused/cancel again.
106+
// resolvedUris resolves to file paths, unless paused/cancelled again
97107
```
98108

99109
### Parameters
@@ -104,31 +114,31 @@ const resolvedUris = await ResourceFetcher.resumeFetching(
104114

105115
`Promise<string[] | null>`:
106116

107-
- If the fetch was successful, it returns a promise which resolves to an array of local file paths for the downloaded resources (without file:// prefix).
108-
- If the fetch was again interrupted by `pauseFetching` or `cancelFetching`, it returns a promise which resolves to null.
117+
- If the fetch was successful, it returns a promise which resolves to an array of local file paths for the downloaded resources (without `file://` prefix).
118+
- If the fetch was again interrupted by `pauseFetching` or `cancelFetching`, it returns a promise which resolves to `null`.
109119

110120
:::info
111-
The other way to resume paused resources is to simply call `fetch` again. However, `resumeFetching` is faster.
121+
You can also resume a paused download by calling `fetch` again with the same sources. However, `resumeFetching` is faster as it resumes from where it left off.
112122
:::
113123

114124
## cancelFetching
115125

116-
Cancels an ongoing/paused download of files.
126+
Cancels an ongoing or paused download.
117127

118128
### Reference
119129

120130
```typescript
121-
import { ResourceFetcher } from 'react-native-executorch';
131+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
122132

123-
const uris = ResourceFetcher.fetch(
133+
const uris = ExpoResourceFetcher.fetch(
124134
(progress) => console.log('Total progress:', progress),
125135
'https://.../llama3_2.pte',
126136
'https://.../qwen3.pte'
127137
).then((uris) => {
128-
console.log('URI resolved as: ', uris); // since we cancel the fetch, uris is resolved to null
138+
console.log('URI resolved as: ', uris); // null, since we cancelled
129139
});
130140

131-
await ResourceFetcher.cancelFetching(
141+
await ExpoResourceFetcher.cancelFetching(
132142
'https://.../llama3_2.pte',
133143
'https://.../qwen3.pte'
134144
);
@@ -149,9 +159,9 @@ Deletes downloaded resources from the local filesystem.
149159
### Reference
150160

151161
```typescript
152-
import { ResourceFetcher } from 'react-native-executorch';
162+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
153163

154-
await ResourceFetcher.deleteResources('https://.../llama3_2.pte');
164+
await ExpoResourceFetcher.deleteResources('https://.../llama3_2.pte');
155165
```
156166

157167
### Parameters
@@ -164,14 +174,14 @@ await ResourceFetcher.deleteResources('https://.../llama3_2.pte');
164174

165175
## getFilesTotalSize
166176

167-
Fetches the info about files size. Works only for remote files.
177+
Fetches the combined size of remote files. Works only for remote URLs.
168178

169179
### Reference
170180

171181
```typescript
172-
import { ResourceFetcher } from 'react-native-executorch';
182+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
173183

174-
const totalSize = await ResourceFetcher.getFilesTotalSize(
184+
const totalSize = await ExpoResourceFetcher.getFilesTotalSize(
175185
'https://.../llama3_2.pte',
176186
'https://.../qwen3.pte'
177187
);
@@ -183,36 +193,36 @@ const totalSize = await ResourceFetcher.getFilesTotalSize(
183193

184194
### Returns
185195

186-
`Promise<number>` – A promise that resolves to combined size of files in bytes.
196+
`Promise<number>` – A promise that resolves to the combined size of files in bytes.
187197

188198
## listDownloadedFiles
189199

190-
Lists all the downloaded files used by React Native ExecuTorch.
200+
Lists all files downloaded by React Native ExecuTorch.
191201

192202
### Reference
193203

194204
```typescript
195-
import { ResourceFetcher } from 'react-native-executorch';
205+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
196206

197-
const filesUris = await ResourceFetcher.listDownloadedFiles();
207+
const filesUris = await ExpoResourceFetcher.listDownloadedFiles();
198208
```
199209

200210
### Returns
201211

202-
`Promise<string[]>` - A promise, which resolves to an array of URIs for all the downloaded files.
212+
`Promise<string[]>` - A promise that resolves to an array of URIs for all downloaded files.
203213

204214
## listDownloadedModels
205215

206-
Lists all the downloaded models used by React Native ExecuTorch.
216+
Lists all downloaded model files (`.pte`).
207217

208218
### Reference
209219

210220
```typescript
211-
import { ResourceFetcher } from 'react-native-executorch';
221+
import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
212222

213-
const modelsUris = await ResourceFetcher.listDownloadedModels();
223+
const modelsUris = await ExpoResourceFetcher.listDownloadedModels();
214224
```
215225

216226
### Returns
217227

218-
`Promise<string[]>` - A promise, which resolves to an array of URIs for all the downloaded models.
228+
`Promise<string[]>` - A promise that resolves to an array of URIs for all downloaded model files.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
---
2+
title: Custom Adapter
3+
---
4+
5+
If the built-in `BareResourceFetcher` and `ExpoResourceFetcher` don't fit your needs, for example, you want to use a different download library, or fetch from a private server you can implement your own adapter and plug it into React Native ExecuTorch.
6+
7+
## The ResourceFetcherAdapter interface
8+
9+
Your adapter must implement the `ResourceFetcherAdapter` interface exported from `react-native-executorch`. This interface defines every method which is used under the hood by React Native ExecuTorch:
10+
11+
```typescript
12+
import {
13+
ResourceFetcherAdapter,
14+
ResourceSource,
15+
} from 'react-native-executorch';
16+
17+
interface ResourceFetcherAdapter {
18+
fetch(
19+
callback: (downloadProgress: number) => void,
20+
...sources: ResourceSource[]
21+
): Promise<string[] | null>;
22+
23+
readAsString(path: string): Promise<string>;
24+
}
25+
```
26+
27+
### `fetch`
28+
29+
This is the core method called by every model hook and module whenever it needs to resolve a model or resource to a local file path.
30+
31+
- `callback` — called with a progress value between `0` and `1` as downloads proceed. Called with `1` when complete.
32+
- `...sources` — one or more `ResourceSource` values:
33+
- `string` — a remote URL or an absolute local file path.
34+
- `number` — a bundled asset reference from `require('./model.pte')`.
35+
- `object` — an inline JS object (e.g. a tokenizer config) that should be JSON-serialized and written to disk. Your adapter is responsible for stringifying it and saving it as a file, then returning the local path. This allows callers to pass configs inline instead of hosting them at a URL.
36+
- **Returns** an array of absolute local file paths (without `file://` prefix), one per source, in the same order. Return `null` if the fetch was intentionally interrupted (e.g. cancelled by the user).
37+
38+
### `readAsString`
39+
40+
Called internally to read configuration files (e.g. tokenizer configs) that were previously downloaded via `fetch`.
41+
42+
- `path` — absolute path to the file on disk.
43+
- **Returns** the file contents as a UTF-8 string.
44+
45+
## Example
46+
47+
Here's a minimal custom adapter that downloads files using the browser `fetch` API (useful for testing or web targets):
48+
49+
```typescript
50+
import * as FileSystem from 'expo-file-system';
51+
import {
52+
ResourceFetcherAdapter,
53+
ResourceSource,
54+
} from 'react-native-executorch';
55+
56+
export const MyCustomFetcher: ResourceFetcherAdapter = {
57+
async fetch(callback, ...sources: ResourceSource[]) {
58+
const paths: string[] = [];
59+
60+
for (let i = 0; i < sources.length; i++) {
61+
const source = sources[i];
62+
63+
if (typeof source !== 'string') {
64+
throw new Error('MyCustomFetcher only supports string URLs');
65+
}
66+
67+
const filename = source.split('/').pop()!;
68+
const localUri = FileSystem.documentDirectory + filename;
69+
70+
const downloadResumable = FileSystem.createDownloadResumable(
71+
source,
72+
localUri,
73+
{},
74+
({ totalBytesWritten, totalBytesExpectedToWrite }) => {
75+
const fileProgress = totalBytesWritten / totalBytesExpectedToWrite;
76+
const overallProgress = (i + fileProgress) / sources.length;
77+
callback(overallProgress);
78+
}
79+
);
80+
81+
const result = await downloadResumable.downloadAsync();
82+
if (!result) return null;
83+
84+
paths.push(result.uri.replace('file://', ''));
85+
}
86+
87+
callback(1);
88+
return paths;
89+
},
90+
91+
async readAsString(path: string) {
92+
return await FileSystem.readAsStringAsync('file://' + path, {
93+
encoding: FileSystem.EncodingType.UTF8,
94+
});
95+
},
96+
};
97+
```
98+
99+
## Registering your adapter
100+
101+
Pass your adapter to `initExecutorch` at the entry point of your app, before any other library API is called:
102+
103+
```typescript
104+
import { initExecutorch } from 'react-native-executorch';
105+
import { MyCustomFetcher } from './MyCustomFetcher';
106+
107+
initExecutorch({ resourceFetcher: MyCustomFetcher });
108+
```
109+
110+
Any model hook or module used after this point will route all resource fetching through your adapter.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"label": "Resource Fetcher",
3+
"link": {
4+
"type": "generated-index"
5+
}
6+
}

docs/sidebars.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ const sidebars = {
4040
label: 'Utilities',
4141
items: [{ type: 'autogenerated', dirName: '05-utilities' }],
4242
},
43+
{
44+
type: 'category',
45+
label: 'Resource Fetcher',
46+
items: [{ type: 'autogenerated', dirName: '08-resource-fetcher' }],
47+
},
4348
{
4449
type: 'category',
4550
label: 'Other',

0 commit comments

Comments
 (0)