opfs_project/
lib.rs

1#![cfg(all(target_family = "wasm", target_os = "unknown"))]
2
3use std::{
4    io::Result,
5    path::{Path, PathBuf},
6};
7
8mod fuse;
9mod package_lock;
10pub mod package_manager;
11mod util;
12
13pub use tokio_fs_ext::DirEntry;
14
15/// Read file content with fuse.link support
16pub async fn read<P: AsRef<Path>>(path: P) -> Result<Vec<u8>> {
17    let path_ref = path.as_ref();
18    let prepared_path = crate::util::prepare_path(path_ref);
19
20    // Try to read through node_modules fuse link logic first
21    if let Some(content) = fuse::try_read_through_fuse_link(&prepared_path).await? {
22        return Ok(content);
23    }
24
25    // Fallback to direct read
26    let content = tokio_fs_ext::read(&prepared_path).await?;
27    Ok(content)
28}
29
30/// Read directory contents with file type information and fuse.link support
31pub async fn read_dir<P: AsRef<Path>>(path: P) -> Result<Vec<tokio_fs_ext::DirEntry>> {
32    let path_ref = path.as_ref();
33    let prepared_path = crate::util::prepare_path(path_ref);
34
35    // Handle node_modules fuse.link logic
36    if let Some(entries) = fuse::try_read_dir_through_fuse_link(&prepared_path).await? {
37        return Ok(entries);
38    }
39
40    // Handle direct directory reading
41    let entries = crate::util::read_dir_direct(&prepared_path).await?;
42    Ok(entries)
43}
44
45pub async fn write(path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Result<()> {
46    // TODO: try fuse link first
47    tokio_fs_ext::write(path, content).await
48}
49
50pub async fn create_dir(path: impl AsRef<Path>) -> Result<()> {
51    // TODO: try fuse link first
52    tokio_fs_ext::create_dir(path).await
53}
54
55pub async fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
56    // TODO: try fuse link first
57    tokio_fs_ext::create_dir_all(path).await
58}
59
60pub async fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64> {
61    // TODO: try fuse link first
62    tokio_fs_ext::copy(from, to).await
63}
64
65pub async fn remove_file(path: impl AsRef<Path>) -> Result<()> {
66    // TODO: try fuse link first
67    tokio_fs_ext::remove_file(path).await
68}
69
70pub async fn remove_dir(path: impl AsRef<Path>) -> Result<()> {
71    // TODO: try fuse link first
72    tokio_fs_ext::remove_dir(path).await
73}
74
75pub async fn remove_dir_all(path: impl AsRef<Path>) -> Result<()> {
76    // TODO: try fuse link first
77    tokio_fs_ext::remove_dir_all(path).await
78}
79
80pub async fn metadata(path: impl AsRef<Path>) -> Result<tokio_fs_ext::Metadata> {
81    // TODO: try fuse link first
82    tokio_fs_ext::metadata(path).await
83}
84
85/// Set current working directory
86pub fn set_cwd(path: impl AsRef<Path>) {
87    tokio_fs_ext::set_current_dir(path).unwrap();
88}
89
90/// Read current working directory
91pub fn get_cwd() -> PathBuf {
92    tokio_fs_ext::current_dir().unwrap()
93}
94
95#[cfg(test)]
96pub mod test_utils {
97    use std::sync::Once;
98
99    static INIT: Once = Once::new();
100
101    /// Initialize tracing-web for tests
102    /// This should be called at the beginning of each test to enable web console logging
103    pub fn init_tracing() {
104        INIT.call_once(|| {
105            {
106                use tracing_subscriber::{
107                    fmt::{
108                        self,
109                        format::FmtSpan,
110                    },
111                    layer::SubscriberExt,
112                    registry,
113                    util::SubscriberInitExt,
114                };
115
116                use tracing_web::MakeWebConsoleWriter;
117
118                let fmt_layer = fmt::layer()
119                .without_time()
120                .with_span_events(FmtSpan::CLOSE)
121                .with_writer(MakeWebConsoleWriter::new());
122
123            registry().with(fmt_layer).init();
124            }
125        });
126    }
127}