Skip to content

Commit 12f533f

Browse files
committed
fix: add lazy import to constructor and improve error handling
1 parent 5ef0257 commit 12f533f

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed
Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,51 @@
11
import { decode as decodeBase64, encode as encodeBase64 } from 'base64-arraybuffer';
22
import { AttachmentData, EncodingType, LocalStorageAdapter } from '@powersync/common';
33

4-
try {
5-
var rnfs = require('@dr.pogodin/react-native-fs');
6-
} catch (e) {
7-
throw new Error(`Could not resolve @dr.pogodin/react-native-fs.
8-
To use the React Native File System attachment adapter please install @dr.pogodin/react-native-fs.`);
9-
}
4+
type ReactNativeFsModule = {
5+
DocumentDirectoryPath: string;
6+
exists(path: string): Promise<boolean>;
7+
mkdir(path: string): Promise<void>;
8+
unlink(path: string): Promise<void>;
9+
writeFile(path: string, contents: string, encoding?: 'base64' | 'utf8'): Promise<void>;
10+
readFile(path: string, encoding?: 'base64' | 'utf8'): Promise<string>;
11+
};
1012

1113
export class ReactNativeFileSystemStorageAdapter implements LocalStorageAdapter {
14+
private rnfs: ReactNativeFsModule;
1215
private storageDirectory: string;
1316

1417
constructor(storageDirectory?: string) {
18+
let rnfs: ReactNativeFsModule;
19+
try {
20+
rnfs = require('@dr.pogodin/react-native-fs');
21+
} catch (e) {
22+
throw new Error(`Could not resolve @dr.pogodin/react-native-fs.
23+
To use the React Native File System attachment adapter please install @dr.pogodin/react-native-fs.`);
24+
}
25+
26+
this.rnfs = rnfs;
1527
// Default to a subdirectory in the document directory
16-
this.storageDirectory = storageDirectory ?? `${rnfs.DocumentDirectoryPath}/attachments/`;
28+
this.storageDirectory = storageDirectory ?? `${this.rnfs.DocumentDirectoryPath}/attachments/`;
1729
}
1830

1931
async initialize(): Promise<void> {
20-
const dirExists = await rnfs.exists(this.storageDirectory);
32+
const dirExists = await this.rnfs.exists(this.storageDirectory);
2133
if (!dirExists) {
22-
await rnfs.mkdir(this.storageDirectory);
34+
await this.rnfs.mkdir(this.storageDirectory);
2335
}
2436
}
2537

2638
async clear(): Promise<void> {
27-
const dirExists = await rnfs.exists(this.storageDirectory);
39+
const dirExists = await this.rnfs.exists(this.storageDirectory);
2840
if (dirExists) {
29-
await rnfs.unlink(this.storageDirectory);
41+
await this.rnfs.unlink(this.storageDirectory);
42+
await this.rnfs.mkdir(this.storageDirectory);
3043
}
3144
}
3245

3346
getLocalUri(filename: string): string {
34-
return `${this.storageDirectory}${filename}`;
47+
const separator = this.storageDirectory.endsWith('/') ? '' : '/';
48+
return `${this.storageDirectory}${separator}${filename}`;
3549
}
3650

3751
async saveFile(
@@ -43,7 +57,7 @@ export class ReactNativeFileSystemStorageAdapter implements LocalStorageAdapter
4357

4458
if (typeof data === 'string') {
4559
const encoding = options?.encoding ?? EncodingType.Base64;
46-
await rnfs.writeFile(filePath, data, encoding === EncodingType.Base64 ? 'base64' : 'utf8');
60+
await this.rnfs.writeFile(filePath, data, encoding);
4761

4862
// Calculate size based on encoding
4963
if (encoding === EncodingType.Base64) {
@@ -54,7 +68,7 @@ export class ReactNativeFileSystemStorageAdapter implements LocalStorageAdapter
5468
}
5569
} else {
5670
const base64 = encodeBase64(data);
57-
await rnfs.WriteFile(filePath, base64, 'base64');
71+
await this.rnfs.writeFile(filePath, base64, 'base64');
5872
size = data.byteLength;
5973
}
6074

@@ -64,7 +78,7 @@ export class ReactNativeFileSystemStorageAdapter implements LocalStorageAdapter
6478
async readFile(filePath: string, options?: { encoding?: EncodingType; mediaType?: string }): Promise<ArrayBuffer> {
6579
const encoding = options?.encoding ?? EncodingType.Base64;
6680

67-
const content = await rnfs.readFile(filePath, encoding === EncodingType.Base64 ? 'base64' : 'utf8');
81+
const content = await this.rnfs.readFile(filePath, encoding);
6882

6983
if (encoding === EncodingType.UTF8) {
7084
const encoder = new TextEncoder();
@@ -75,27 +89,34 @@ export class ReactNativeFileSystemStorageAdapter implements LocalStorageAdapter
7589
}
7690

7791
async deleteFile(filePath: string, options?: { filename?: string }): Promise<void> {
78-
await rnfs.unlink(filePath).catch((error: any) => {
79-
if (error?.message?.includes('not exist') || error?.message?.includes('ENOENT')) {
92+
try {
93+
await this.rnfs.unlink(filePath);
94+
} catch (error: any) {
95+
// Ignore file not found errors
96+
if (error?.code === 'ENOENT' || error?.message?.includes('ENOENT') || error?.message?.includes('not exist')) {
8097
return;
8198
}
8299
throw error;
83-
});
100+
}
84101
}
85102

86103
async fileExists(filePath: string): Promise<boolean> {
87104
try {
88-
return await rnfs.exists(filePath);
89-
} catch {
90-
return false;
105+
return await this.rnfs.exists(filePath);
106+
} catch (error: any) {
107+
// Only return false for file-not-found errors
108+
if (error?.code === 'ENOENT' || error?.message?.includes('ENOENT')) {
109+
return false;
110+
}
111+
throw error;
91112
}
92113
}
93114

94115
async makeDir(path: string): Promise<void> {
95-
await rnfs.mkdir(path);
116+
await this.rnfs.mkdir(path);
96117
}
97118

98119
async rmDir(path: string): Promise<void> {
99-
await rnfs.unlink(path);
120+
await this.rnfs.unlink(path);
100121
}
101122
}

0 commit comments

Comments
 (0)