diff --git a/packages/react-native-executorch/src/constants/directories.ts b/packages/react-native-executorch/src/constants/directories.ts index ac20d04d8..3cc6e68a9 100644 --- a/packages/react-native-executorch/src/constants/directories.ts +++ b/packages/react-native-executorch/src/constants/directories.ts @@ -1,3 +1,5 @@ -import { documentDirectory } from 'expo-file-system'; +import { importLegacyExpoFSModules } from '../utils/ResourceFetcher'; + +const { documentDirectory } = importLegacyExpoFSModules(); export const RNEDirectory = `${documentDirectory}react-native-executorch/`; diff --git a/packages/react-native-executorch/src/controllers/LLMController.ts b/packages/react-native-executorch/src/controllers/LLMController.ts index bcc131eba..bbc113a76 100644 --- a/packages/react-native-executorch/src/controllers/LLMController.ts +++ b/packages/react-native-executorch/src/controllers/LLMController.ts @@ -1,9 +1,11 @@ import { ResourceSource } from '../types/common'; -import { ResourceFetcher } from '../utils/ResourceFetcher'; +import { + importLegacyExpoFSModules, + ResourceFetcher, +} from '../utils/ResourceFetcher'; import { ETError, getError } from '../Error'; import { Template } from '@huggingface/jinja'; import { DEFAULT_CHAT_CONFIG } from '../constants/llmDefaults'; -import { readAsStringAsync } from 'expo-file-system'; import { ChatConfig, GenerationConfig, @@ -14,6 +16,7 @@ import { } from '../types/llm'; import { parseToolCall } from '../utils/llm'; import { Logger } from '../common/Logger'; +const { readAsStringAsync } = importLegacyExpoFSModules(); export class LLMController { private nativeModule: any; diff --git a/packages/react-native-executorch/src/utils/ResourceFetcher.ts b/packages/react-native-executorch/src/utils/ResourceFetcher.ts index fa2fd8c09..efc16ab63 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcher.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcher.ts @@ -27,7 +27,27 @@ * - Implements linked list behavior via the `.next` attribute * - Automatically processes subsequent downloads when `.next` contains a valid resource */ -import { +import type * as FileSystemTypes from 'expo-file-system'; + +export function importLegacyExpoFSModules() { + let FileSystem: typeof FileSystemTypes; + + try { + const expoPkg = require('expo/package.json'); + const sdkVersion = expoPkg.version.split('.')[0]; + + if (Number(sdkVersion) > 53) { + FileSystem = require('expo-file-system/legacy'); + } else { + FileSystem = require('expo-file-system'); + } + } catch (e) { + throw new Error('Expo must be installed to use react-native-executorch'); + } + return FileSystem; +} + +const { cacheDirectory, copyAsync, createDownloadResumable, @@ -37,7 +57,8 @@ import { EncodingType, deleteAsync, readDirectoryAsync, -} from 'expo-file-system'; +} = importLegacyExpoFSModules(); + import { Asset } from 'expo-asset'; import { Platform } from 'react-native'; import { RNEDirectory } from '../constants/directories'; diff --git a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts index 67d6edc9b..d36a9ba5e 100644 --- a/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts +++ b/packages/react-native-executorch/src/utils/ResourceFetcherUtils.ts @@ -1,16 +1,14 @@ -/** - * @internal - */ - -import { - DownloadResumable, - getInfoAsync, - makeDirectoryAsync, -} from 'expo-file-system'; +import type * as FileSystemTypes from 'expo-file-system'; import { RNEDirectory } from '../constants/directories'; import { ResourceSource } from '../types/common'; import { Asset } from 'expo-asset'; import { Logger } from '../common/Logger'; +import { importLegacyExpoFSModules } from './ResourceFetcher'; + +/** + * @internal + */ +const { getInfoAsync, makeDirectoryAsync } = importLegacyExpoFSModules(); export const enum HTTP_CODE { OK = 200, @@ -42,7 +40,7 @@ export interface ResourceSourceExtended { } export interface DownloadResource { - downloadResumable: DownloadResumable; + downloadResumable: FileSystemTypes.DownloadResumable; status: DownloadStatus; extendedInfo: ResourceSourceExtended; } @@ -75,7 +73,7 @@ export namespace ResourceFetcherUtils { let totalLength = 0; let previousFilesTotalLength = 0; for (const source of sources) { - const type = await ResourceFetcherUtils.getType(source); + const type = ResourceFetcherUtils.getType(source); let length = 0; try { if (type === SourceType.REMOTE_FILE && typeof source === 'string') {