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 manifest.json
# JetBrains # JetBrains
.idea .idea
TESTFILE

2
index.d.ts vendored
View File

@ -5,7 +5,7 @@
function hasBackendForPath(path: string): boolean function hasBackendForPath(path: string): boolean
function listFiles(path: string): Array<string> 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 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 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> function generateRootCa(): Array<string>

View File

@ -2,13 +2,19 @@
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::PermissionsExt;
use std::{ use std::{
fs::{self, metadata, File}, fs::{self, metadata, File},
io::{BufReader, Read}, io::{self, BufReader, ErrorKind, Read},
path::{Path, PathBuf}, path::{Path, PathBuf},
task::Poll, task::Poll,
}; };
use napi::{bindgen_prelude::*, tokio_stream::{Stream, StreamExt}}; use napi::{
use tokio_util::{bytes::BytesMut, codec::{BytesCodec, FramedRead}}; bindgen_prelude::*,
tokio_stream::{Stream, StreamExt},
};
use tokio_util::{
bytes::BytesMut,
codec::{BytesCodec, FramedRead},
};
fn _list_files(vec: &mut Vec<PathBuf>, path: &Path) { fn _list_files(vec: &mut Vec<PathBuf>, path: &Path) {
if metadata(path).unwrap().is_dir() { if metadata(path).unwrap().is_dir() {
@ -128,21 +134,32 @@ pub fn read_file(
path: String, path: String,
sub_path: String, sub_path: String,
env: &Env, env: &Env,
) -> Option<ReadableStream<'static, Vec<u8>>> { ) -> Option<ReadableStream<'static, BufferSlice<'static>>> {
let path = Path::new(&path); let path = Path::new(&path);
let backend = create_backend_for_path(path).unwrap(); let backend = create_backend_for_path(path).unwrap();
let version_file = VersionFile { let version_file = VersionFile {
relative_filename: sub_path, relative_filename: sub_path,
permission: 0, // Shouldn't matter permission: 0, // Shouldn't matter
}; };
// Use `?` operator for cleaner error propagation from `Option`
let reader = backend.reader(&version_file)?; 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 reader = tokio::fs::File::from_std(reader);
let stream = FramedRead::new(reader, BytesCodec::new()).map(|e| {
if let Ok(bytes) = e { // Create a FramedRead stream with BytesCodec for chunking
Ok(bytes.to_vec())
} else { let stream = FramedRead::new(reader, BytesCodec::new())
Err(napi::Error::from_reason(e.unwrap_err().to_string())) // 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()) Some(ReadableStream::create_with_stream_bytes(env, stream).unwrap())
} }