Skip to content

Commit a911308

Browse files
@nk/rag multi text format (#175)
1 parent c26436e commit a911308

4 files changed

Lines changed: 63 additions & 16 deletions

File tree

database/exportImportRepository.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { SQLiteDatabase } from 'expo-sqlite';
22
import { getChatMessages, Message } from './chatRepository';
3-
import * as FileSystem from 'expo-file-system';
3+
import { File, Paths } from 'expo-file-system';
44
import * as Sharing from 'expo-sharing';
55
import * as DocumentPicker from 'expo-document-picker';
66
import { Alert } from 'react-native';
@@ -20,11 +20,9 @@ export const exportChatRoom = async (
2020
});
2121

2222
const fileName = `chat-${Date.now()}.json`;
23-
const fileUri = `${FileSystem.documentDirectory}${fileName}`;
24-
25-
await FileSystem.writeAsStringAsync(fileUri, jsonData, {
26-
encoding: FileSystem.EncodingType.UTF8,
27-
});
23+
const file = new File(Paths.document, fileName);
24+
await file.write(jsonData);
25+
const fileUri = file.uri;
2826

2927
if (await Sharing.isAvailableAsync()) {
3028
await Sharing.shareAsync(fileUri, {
@@ -54,7 +52,8 @@ export async function importChatRoom(): Promise<
5452
});
5553
if (result.canceled || !result.assets[0]?.uri) return;
5654
const uri = result.assets[0].uri;
57-
const fileContent = await FileSystem.readAsStringAsync(uri);
55+
const file = new File(uri);
56+
const fileContent = await file.text();
5857

5958
const chatData = JSON.parse(fileContent);
6059
const chat = {
@@ -67,7 +66,7 @@ export async function importChatRoom(): Promise<
6766
};
6867
return chat;
6968
} catch (error) {
70-
console.error('Failed to import chat room JSON:', error);
69+
console.error('Failed to import chat room JSON:', error);
7170
return;
7271
}
7372
}

hooks/useSourceUpload.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const useSourceUpload = () => {
1616

1717
const uploadSource = useCallback(async () => {
1818
const pickedFileResult = await DocumentPicker.getDocumentAsync({
19-
type: 'application/pdf',
19+
type: ['application/pdf', 'text/plain', 'text/markdown', 'text/html'],
2020
copyToCacheDirectory: true,
2121
});
2222

@@ -41,15 +41,15 @@ export const useSourceUpload = () => {
4141
});
4242
} else if (result.isEmpty) {
4343
warningSheetRef.current?.present({
44-
title: "Can't read PDF",
45-
subtitle: `The PDF "${newSource.name}" appears to be empty or unreadable. It won't be added to your sources.`,
44+
title: "Can't read document",
45+
subtitle: `The document "${newSource.name}" appears to be empty or unreadable. It won't be added to your sources.`,
4646
buttonTitle: 'OK',
4747
onConfirm: () => {},
4848
});
4949
} else {
5050
warningSheetRef.current?.present({
51-
title: "Can't read PDF",
52-
subtitle: `There was an error processing the PDF "${newSource.name}". Please try again.`,
51+
title: "Can't read document",
52+
subtitle: `There was an error processing the document "${newSource.name}". Please try again.`,
5353
buttonTitle: 'OK',
5454
onConfirm: () => {},
5555
});

store/sourceStore.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
import { SQLiteDatabase } from 'expo-sqlite';
1111
import { OPSQLiteVectorStore } from '@react-native-rag/op-sqlite';
1212
import { RecursiveCharacterTextSplitter } from 'react-native-rag';
13-
import { readPDF } from 'react-native-pdfium';
13+
import { readDocumentText } from '../utils/fileReaders';
1414
import { useLLMStore } from './llmStore';
1515

1616
interface SourceStore {
@@ -56,13 +56,12 @@ export const useSourceStore = create<SourceStore>((set, get) => ({
5656
const db = get().db;
5757
if (!db) return { success: false };
5858

59-
const normalizedUri = sourceUri.replace('file://', '');
6059
const tempId = -Date.now();
6160

6261
set({ isReading: true });
6362

6463
try {
65-
const sourceTextContent = await readPDF(normalizedUri);
64+
const sourceTextContent = await readDocumentText(sourceUri, source.type);
6665

6766
if (!sourceTextContent || sourceTextContent.trim().length === 0) {
6867
set({ isReading: false });

utils/fileReaders.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { readPDF } from 'react-native-pdfium';
2+
import { File } from 'expo-file-system';
3+
4+
/**
5+
* Reads text content from various file formats
6+
* @param filePath - The path to the file
7+
* @param fileType - The file extension (pdf, txt, md, html, csv, etc.)
8+
* @returns The extracted text content
9+
*/
10+
export async function readDocumentText(
11+
filePath: string,
12+
fileType: string
13+
): Promise<string> {
14+
const lowerFileType = fileType.toLowerCase();
15+
16+
switch (lowerFileType) {
17+
case 'pdf':
18+
// PDF reader needs path without file:// prefix
19+
const normalizedPath = filePath.replace('file://', '');
20+
return await readPDF(normalizedPath);
21+
22+
case 'txt':
23+
case 'md':
24+
case 'markdown':
25+
const textFile = new File(filePath);
26+
return await textFile.text();
27+
28+
case 'html':
29+
case 'htm':
30+
const htmlFile = new File(filePath);
31+
const htmlContent = await htmlFile.text();
32+
// Basic HTML tag stripping - removes all HTML tags
33+
return htmlContent
34+
.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') // Remove script tags
35+
.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '') // Remove style tags
36+
.replace(/<[^>]+>/g, ' ') // Remove all HTML tags
37+
.replace(/&nbsp;/g, ' ')
38+
.replace(/&amp;/g, '&')
39+
.replace(/&lt;/g, '<')
40+
.replace(/&gt;/g, '>')
41+
.replace(/&quot;/g, '"')
42+
.replace(/&#39;/g, "'")
43+
.replace(/\s+/g, ' ') // Normalize whitespace
44+
.trim();
45+
46+
default:
47+
throw new Error(`Unsupported file type: ${fileType}`);
48+
}
49+
}

0 commit comments

Comments
 (0)