summaryrefslogtreecommitdiff
path: root/ext/node_resolver/package_json.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-07-25 19:08:14 -0400
committerGitHub <noreply@github.com>2024-07-25 19:08:14 -0400
commit3bf147fe287ac779b20d318daba56b336f356adf (patch)
tree3b5bfe2a1ad918b275a2cd08f7dcc05f90a180ab /ext/node_resolver/package_json.rs
parent0cf7f268a7df7711ac6ab8c2c67b4d7abf454fcd (diff)
refactor: decouple node resolution from deno_core (#24724)
Diffstat (limited to 'ext/node_resolver/package_json.rs')
-rw-r--r--ext/node_resolver/package_json.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/ext/node_resolver/package_json.rs b/ext/node_resolver/package_json.rs
new file mode 100644
index 000000000..de750f1d7
--- /dev/null
+++ b/ext/node_resolver/package_json.rs
@@ -0,0 +1,53 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use deno_package_json::PackageJson;
+use deno_package_json::PackageJsonRc;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::io::ErrorKind;
+use std::path::Path;
+use std::path::PathBuf;
+
+use crate::errors::PackageJsonLoadError;
+
+// use a thread local cache so that workers have their own distinct cache
+thread_local! {
+ static CACHE: RefCell<HashMap<PathBuf, PackageJsonRc>> = RefCell::new(HashMap::new());
+}
+
+pub struct PackageJsonThreadLocalCache;
+
+impl PackageJsonThreadLocalCache {
+ pub fn clear() {
+ CACHE.with(|cache| cache.borrow_mut().clear());
+ }
+}
+
+impl deno_package_json::PackageJsonCache for PackageJsonThreadLocalCache {
+ fn get(&self, path: &Path) -> Option<PackageJsonRc> {
+ CACHE.with(|cache| cache.borrow().get(path).cloned())
+ }
+
+ fn set(&self, path: PathBuf, package_json: PackageJsonRc) {
+ CACHE.with(|cache| cache.borrow_mut().insert(path, package_json));
+ }
+}
+
+/// Helper to load a package.json file using the thread local cache
+/// in node_resolver.
+pub fn load_pkg_json(
+ fs: &dyn deno_package_json::fs::DenoPkgJsonFs,
+ path: &Path,
+) -> Result<Option<PackageJsonRc>, PackageJsonLoadError> {
+ let result =
+ PackageJson::load_from_path(path, fs, Some(&PackageJsonThreadLocalCache));
+ match result {
+ Ok(pkg_json) => Ok(Some(pkg_json)),
+ Err(deno_package_json::PackageJsonLoadError::Io { source, .. })
+ if source.kind() == ErrorKind::NotFound =>
+ {
+ Ok(None)
+ }
+ Err(err) => Err(PackageJsonLoadError(err)),
+ }
+}