Improve the export code and index file creation.

This commit is contained in:
xazukx
2025-11-26 01:27:14 -07:00
parent 6c1f01018d
commit 464367acea
2 changed files with 71 additions and 53 deletions

View File

@@ -1,12 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "Inflector"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
version = 4
[[package]]
name = "crate1"
@@ -33,9 +27,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.78"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
@@ -49,11 +43,18 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "renamed"
version = "0.1.0"
dependencies = [
"ts-rs",
]
[[package]]
name = "syn"
version = "2.0.48"
version = "2.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
dependencies = [
"proc-macro2",
"quote",
@@ -71,18 +72,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.56"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.56"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
@@ -91,7 +92,7 @@ dependencies = [
[[package]]
name = "ts-rs"
version = "7.1.1"
version = "11.0.1"
dependencies = [
"thiserror",
"ts-rs-macros",
@@ -99,9 +100,8 @@ dependencies = [
[[package]]
name = "ts-rs-macros"
version = "7.1.1"
version = "11.0.1"
dependencies = [
"Inflector",
"proc-macro2",
"quote",
"syn",

View File

@@ -30,55 +30,31 @@ fn maybe_update_index(path: &Path) -> Result<(), ExportError> {
let Some(stem) = path.file_stem().and_then(std::ffi::OsStr::to_str) else { return Ok(()); };
let index_path = parent.join("index.ts");
// Compute the module path to re-export from this index file
let mut module_path = format!("./{}", stem);
if cfg!(feature = "import-esm") {
module_path.push_str(".js");
}
let module_key = normalize_index_module_key(&format!("./{}", stem));
let lock = &mut get_index_paths().lock().unwrap();
// Initialize set with existing entries if we see this index file for the first time in this process
let set = lock.entry(index_path.clone()).or_insert_with(|| read_existing_exports(&index_path));
let set = lock
.entry(index_path.clone())
.or_insert_with(|| read_existing_exports(&index_path));
if set.contains(&module_path) {
if !set.insert(module_key) {
return Ok(());
}
// Ensure the index file exists and has a header when created
if !index_path.exists() {
use std::io::Write as _;
let mut f = File::create(&index_path)?;
f.write_all(NOTE.as_bytes())?;
f.write_all(b"\n")?;
f.sync_all()?;
}
// Append the new export line
{
use std::io::Write as _;
let mut f = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open(&index_path)?;
writeln!(f, "export * from \"{}\";", module_path)?;
f.sync_all()?;
}
set.insert(module_path);
Ok(())
write_sorted_index_file(&index_path, set)
}
fn read_existing_exports(index_path: &Path) -> HashSet<String> {
let mut existing = HashSet::new();
fn read_existing_exports(index_path: &Path) -> BTreeSet<String> {
let mut existing = BTreeSet::new();
if let Ok(mut f) = std::fs::OpenOptions::new().read(true).open(index_path) {
use std::io::Read;
let mut s = String::new();
if f.read_to_string(&mut s).is_ok() {
for line in s.lines() {
if let Some(path) = extract_export_path(line) {
existing.insert(path);
existing.insert(normalize_index_module_key(&path));
}
}
}
@@ -98,14 +74,56 @@ fn extract_export_path(line: &str) -> Option<String> {
Some(path_part.to_string())
}
fn normalize_index_module_key(path: &str) -> String {
let mut normalized = path.trim().trim_matches('"').trim_matches('\'').replace('\\', "/");
if let Some(stripped) = normalized.strip_suffix(".ts") {
normalized = stripped.to_string();
} else if let Some(stripped) = normalized.strip_suffix(".js") {
normalized = stripped.to_string();
}
if normalized.starts_with("./") || normalized.starts_with("../") || normalized.starts_with('/') {
normalized
} else {
format!("./{}", normalized)
}
}
fn write_sorted_index_file(
index_path: &Path,
modules: &BTreeSet<String>,
) -> Result<(), ExportError> {
use std::io::Write as _;
let mut contents = String::new();
contents.push_str(NOTE);
contents.push('\n');
for key in modules {
let module_path = if cfg!(feature = "import-esm") {
format!("{}.js", key)
} else {
key.clone()
};
writeln!(&mut contents, "export * from \"{}\";", module_path)
.expect("writing to a string should not fail");
}
let mut file = File::create(index_path)?;
file.write_all(contents.as_bytes())?;
file.sync_all()?;
Ok(())
}
static EXPORT_PATHS: OnceLock<Mutex<HashMap<PathBuf, HashSet<String>>>> = OnceLock::new();
static INDEX_PATHS: OnceLock<Mutex<HashMap<PathBuf, HashSet<String>>>> = OnceLock::new();
static INDEX_PATHS: OnceLock<Mutex<HashMap<PathBuf, BTreeSet<String>>>> = OnceLock::new();
fn get_export_paths<'a>() -> &'a Mutex<HashMap<PathBuf, HashSet<String>>> {
EXPORT_PATHS.get_or_init(Default::default)
}
fn get_index_paths<'a>() -> &'a Mutex<HashMap<PathBuf, HashSet<String>>> {
fn get_index_paths<'a>() -> &'a Mutex<HashMap<PathBuf, BTreeSet<String>>> {
INDEX_PATHS.get_or_init(Default::default)
}