react-native-executorch
Version:
An easy way to run AI models in React Native with ExecuTorch
138 lines (129 loc) • 5.85 kB
JavaScript
;
/**
* Resource Fetcher
*
* Provides an interface for downloading files (via `ResourceFetcher.fetch()`)
*
* Key functionality:
* - Download control: pause, resume, and cancel operations through:
* - Single file: `.pauseFetching()`, `.resumeFetching()`, `.cancelFetching()`
* - Downloaded file management:
* - `.getFilesTotalSize()`, `.listDownloadedFiles()`, `.listDownloadedModels()`, `.deleteResources()`
*
* Remark: The pausing/resuming/canceling works only for fetching remote resources.
*
* Most exported functions accept:
* - Multiple `ResourceSource` arguments, (union type of string, number or object)
*
* Method `.fetch()` takes argument as callback that reports download progress.
* Method`.fetch()` returns array of paths to successfully saved files or null if the download was paused or cancelled (then resume functions can return paths).
*
* Technical Implementation:
* - Maintains a `downloads` Map instance that tracks:
* - Currently downloading resources
* - Paused downloads
* - Successful downloads are automatically removed from the `downloads` Map
* - Uses the `ResourceSourceExtended` interface to enable pause/resume functionality:
* - Wraps user-provided `ResourceSource` elements
* - Implements linked list behavior via the `.next` attribute
* - Automatically processes subsequent downloads when `.next` contains a valid resource
*/
import { RnExecutorchError } from '../errors/errorUtils';
import { RnExecutorchErrorCode } from '../errors/ErrorCodes';
import { ResourceFetcherUtils } from './ResourceFetcherUtils';
import { Logger } from '../common/Logger';
/**
* Adapter interface for resource fetching operations.
* **Required Methods:**
* - `fetch`: Download resources to local storage (used by all modules)
* - `readAsString`: Read file contents as string (used for config files)
* @category Utilities - General
* @remarks
* This interface is intentionally minimal. Custom fetchers only need to implement
* these two methods for the library to function correctly.
*/
/**
* 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.
* @category Utilities - General
*/
export class ResourceFetcher {
static adapter = null;
static reportedUrls = new Set();
/**
* Sets a custom resource fetcher adapter for resource operations.
* @param adapter - The adapter instance to use for fetching resources.
* @remarks
* **INTERNAL**: Used by platform-specific init functions (expo/bare) to inject their fetcher implementation.
*/
static setAdapter(adapter) {
this.adapter = adapter;
}
/**
* Resets the resource fetcher adapter to null.
* @remarks
* **INTERNAL**: Used primarily for testing purposes to clear the adapter state.
*/
static resetAdapter() {
this.adapter = null;
}
/**
* Gets the current resource fetcher adapter instance.
* @returns The configured ResourceFetcherAdapter instance.
* @throws {RnExecutorchError} If no adapter has been set via {@link setAdapter}.
* @remarks
* **INTERNAL**: Used internally by all resource fetching operations.
*/
static getAdapter() {
if (!this.adapter) {
const errorMessage = 'ResourceFetcher adapter is not initialized. Please call initExecutorch({ resourceFetcher: ... }) with a valid adapter, e.g., from react-native-executorch-expo-resource-fetcher or react-native-executorch-bare-resource-fetcher. For more details please refer to: https://docs.swmansion.com/react-native-executorch/docs/next/fundamentals/loading-models';
// for sanity :)
Logger.error(errorMessage);
throw new RnExecutorchError(RnExecutorchErrorCode.ResourceFetcherAdapterNotInitialized, errorMessage);
}
return this.adapter;
}
/**
* Fetches resources (remote URLs, local files or embedded assets), downloads or stores them locally for use by React Native ExecuTorch.
* @param callback - Optional callback to track progress of all downloads, reported between 0 and 1.
* @param sources - Multiple resources that can be strings, asset references, or objects.
* @returns 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).
* If the fetch was interrupted, it returns a promise which resolves to `null`.
*/
static async fetch(callback = () => {}, ...sources) {
const result = await this.getAdapter().fetch(callback, ...sources);
if (result) {
for (const source of sources) {
if (typeof source === 'string' && !this.reportedUrls.has(source)) {
this.reportedUrls.add(source);
try {
ResourceFetcherUtils.triggerDownloadEvent(source);
ResourceFetcherUtils.triggerHuggingFaceDownloadCounter(source);
} catch (error) {
throw error;
}
}
}
}
return result;
}
/**
* Filesystem utilities for reading downloaded resources.
* @remarks
* Provides access to filesystem operations through the configured adapter.
* Currently supports reading file contents as strings for configuration files.
*/
static fs = {
/**
* Reads the contents of a file as a string.
* @param path - Absolute file path to read.
* @returns A promise that resolves to the file contents as a string.
* @remarks
* **REQUIRED**: Used internally for reading configuration files (e.g., tokenizer configs).
*/
readAsString: async path => {
return this.getAdapter().readAsString(path);
}
};
}
//# sourceMappingURL=ResourceFetcher.js.map