fix: Changed FramedRead to work with ReadableStream

Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
quexeky
2025-05-28 14:52:42 +10:00
parent 45a26c7156
commit b6910e717b
3 changed files with 33 additions and 13 deletions

5
.gitignore vendored
View File

@ -201,4 +201,7 @@ test.mjs
manifest.json
# JetBrains
.idea
.idea
TESTFILE

2
index.d.ts vendored
View File

@ -5,7 +5,7 @@
function hasBackendForPath(path: string): boolean
function listFiles(path: string): Array<string>
function readFile(path: string, subPath: string): ReadableStream<Array<number>> | null
function readFile(path: string, subPath: string): ReadableStream<Buffer> | null
function callAltThreadFunc(tsfn: ((err: Error | null, ) => any)): void
function generateManifest(dir: string, progressSfn: ((err: Error | null, arg: number) => any), logSfn: ((err: Error | null, arg: string) => any), callbackSfn: ((err: Error | null, arg: string) => any)): void
function generateRootCa(): Array<string>

View File

@ -2,13 +2,19 @@
use std::os::unix::fs::PermissionsExt;
use std::{
fs::{self, metadata, File},
io::{BufReader, Read},
io::{self, BufReader, ErrorKind, Read},
path::{Path, PathBuf},
task::Poll,
};
use napi::{bindgen_prelude::*, tokio_stream::{Stream, StreamExt}};
use tokio_util::{bytes::BytesMut, codec::{BytesCodec, FramedRead}};
use napi::{
bindgen_prelude::*,
tokio_stream::{Stream, StreamExt},
};
use tokio_util::{
bytes::BytesMut,
codec::{BytesCodec, FramedRead},
};
fn _list_files(vec: &mut Vec<PathBuf>, path: &Path) {
if metadata(path).unwrap().is_dir() {
@ -128,21 +134,32 @@ pub fn read_file(
path: String,
sub_path: String,
env: &Env,
) -> Option<ReadableStream<'static, Vec<u8>>> {
) -> Option<ReadableStream<'static, BufferSlice<'static>>> {
let path = Path::new(&path);
let backend = create_backend_for_path(path).unwrap();
let version_file = VersionFile {
relative_filename: sub_path,
permission: 0, // Shouldn't matter
};
// Use `?` operator for cleaner error propagation from `Option`
let reader = backend.reader(&version_file)?;
// Convert std::fs::File to tokio::fs::File for async operations
let reader = tokio::fs::File::from_std(reader);
let stream = FramedRead::new(reader, BytesCodec::new()).map(|e| {
if let Ok(bytes) = e {
Ok(bytes.to_vec())
} else {
Err(napi::Error::from_reason(e.unwrap_err().to_string()))
}
});
// Create a FramedRead stream with BytesCodec for chunking
let stream = FramedRead::new(reader, BytesCodec::new())
// Use StreamExt::map to transform each Result item
.map(|result_item| {
result_item
// Apply Result::map to transform Ok(BytesMut) to Ok(Vec<u8>)
.map(|bytes| bytes.to_vec())
// Apply Result::map_err to transform Err(std::io::Error) to Err(napi::Error)
.map_err(|e| napi::Error::from(e)) // napi::Error implements From<tokio::io::Error>
});
// Create the napi-rs ReadableStream from the tokio_stream::Stream
// The unwrap() here means if stream creation fails, it will panic.
// For a production system, consider returning Result<Option<...>> and handling this.
Some(ReadableStream::create_with_stream_bytes(env, stream).unwrap())
}