Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ log.err("Print this with console.error");

### **fileAsyncTransport**

This transport requires the installation of `react-native-fs`([install tutorial here](https://github.com/itinance/react-native-fs)) or `expo-file-system`, and allows you to save the
This transport requires the installation of `react-native-fs`([install tutorial here](https://github.com/itinance/react-native-fs)) or `expo-file-system`(Supports both `legacy` and `next` api), and allows you to save the
logs on the `<filePath>/<fileName>.txt` file.

If you want a new file to be created every day you can use `{date-today}` in the fileName: `app_logs_{date-today}.log` -> `app_logs_D-M-YYYY.log`.
Expand Down
124 changes: 111 additions & 13 deletions src/transports/fileAsyncTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ type EXPOFS = {
) => Promise<{ exists: boolean }>;
appendFile: undefined;
};
type EXPONEXTFS = {
File: new (...args: string[]) => {
uri: string;
name: string;
exists: boolean;
create: (options?: {
intermediates?: boolean;
overwrite?: boolean;
}) => void;
open: () => {
writeBytes: (data: Uint8Array) => void;
close: () => void;
size: number | null;
offset: number | null;
};
};
Paths: any;
};

interface EXPOqueueitem {
FS: Required<EXPOFS>;
file: string;
Expand All @@ -34,18 +53,25 @@ interface EXPOqueueitem {
let EXPOqueue: Array<EXPOqueueitem> = [];
let EXPOelaborate = false;

interface EXPONEXTFSqueueitem {
FS: Required<EXPONEXTFS>;
file: string;
msg: string;
}

const EXPOFSreadwrite = async () => {
if (EXPOqueue.length === 0) return;

EXPOelaborate = true;
const item = EXPOqueue[0];

try {
const prevFile = await item.FS.readAsStringAsync(item.file).catch(() => "");
const prevFile =
(await item.FS.readAsStringAsync(item.file).catch(() => "")) || "";
const newMsg = prevFile + item.msg;
await item.FS.writeAsStringAsync(item.file, newMsg);
} catch (error) {
console.error("Failed to write log to file:", error);
console.error("Failed to write log to file (expo legacy):", error);
} finally {
EXPOelaborate = false;
EXPOqueue.shift();
Expand Down Expand Up @@ -96,6 +122,70 @@ const RNFSappend = async (FS: any, file: string, msg: string) => {
}
};

let EXPONEXTFSqueue: Array<EXPONEXTFSqueueitem> = [];
let EXPONEXTFSelaborate = false;

const EXPONEXTFSprocessQueue = async () => {
if (EXPONEXTFSqueue.length === 0) return;
EXPONEXTFSelaborate = true;
const item = EXPONEXTFSqueue[0];

try {
const FS: EXPONEXTFS = item.FS;
const FileClass = FS.File;
if (!FileClass) throw new Error("EXPO NEXT FS does not expose File");

const file = new FileClass(item.file);

try {
if (!file.exists) {
file.create({ intermediates: true });
}
} catch (e) {
// maybe concurrently created
}

const fileHandler = file.open();

try {
const size = typeof fileHandler.size === "number" ? fileHandler.size : 0;
fileHandler.offset = size

const encoder = new TextEncoder();
const bytes = encoder.encode(item.msg);

fileHandler.writeBytes(bytes);
} finally {
try {
fileHandler.close();
} catch (e) {
console.warn("EXPO FS NEXT error while closing FileHandle", e);
}
}
} catch (error) {
console.error("EXPO FS NEXT failed to write log to file:", error);
} finally {
EXPONEXTFSelaborate = false;
EXPONEXTFSqueue.shift();
if (EXPONEXTFSqueue.length > 0) {
EXPONEXTFSprocessQueue().then();
}
}
};

const EXPONEXTFSappend = async (FS: EXPONEXTFS, file: string, msg: string) => {
try {
EXPONEXTFSqueue.push({ FS, file, msg });
if (!EXPONEXTFSelaborate) {
await EXPONEXTFSprocessQueue();
}
return true;
} catch (error) {
console.error(error);
return false;
}
};

const dateReplacer = (filename: string, type?: "eu" | "us" | "iso") => {
let today = new Date();
let d = today.getDate();
Expand Down Expand Up @@ -134,19 +224,27 @@ const fileAsyncTransport: transportFunctionType<FileAsyncTransportOptions> = (
);
}

let FSF = props.options.FS as RNFS | EXPOFS;
const FSF = props.options.FS as RNFS | EXPOFS | EXPONEXTFS;

if (FSF.DocumentDirectoryPath && FSF.appendFile) {
if ((FSF as RNFS).DocumentDirectoryPath && (FSF as RNFS).appendFile) {
WRITE = RNFSappend;
filePath = FSF.DocumentDirectoryPath;
} else if (
FSF["documentDirectory"] &&
FSF["writeAsStringAsync"] &&
FSF["readAsStringAsync"] &&
FSF["getInfoAsync"]
filePath = (FSF as RNFS).DocumentDirectoryPath;
}
else if (
(FSF as EXPOFS).documentDirectory &&
(FSF as EXPOFS).writeAsStringAsync &&
(FSF as EXPOFS).readAsStringAsync &&
(FSF as EXPOFS).getInfoAsync
) {
WRITE = EXPOFSappend;
filePath = FSF.documentDirectory;
filePath = (FSF as EXPOFS).documentDirectory!;
}
else if (
(FSF as EXPONEXTFS).File &&
(FSF as EXPONEXTFS).Paths
) {
WRITE = EXPONEXTFSappend;
filePath = (FSF as EXPONEXTFS).Paths.document;
} else {
throw Error(
`react-native-logs: fileAsyncTransport - FileSystem not supported`
Expand All @@ -160,8 +258,8 @@ const fileAsyncTransport: transportFunctionType<FileAsyncTransportOptions> = (

if (props?.options?.filePath) filePath = props.options.filePath;

let output = `${props?.msg}\n`;
var path = filePath + "/" + fileName;
const output = `${props?.msg}\n`;
const path = `${filePath}/${fileName}`;

WRITE(FSF, path, output);
};
Expand Down