9 Commits

Author SHA1 Message Date
2969d64c45 feat: move to bigints for larger file sizes 2025-07-14 15:17:38 +10:00
e525ff44bb Merge pull request #3 from nickbabcock/rawzip-0.3
Bump rawzip to 0.3
2025-07-13 23:08:10 +10:00
52a685391a Bump rawzip to 0.3
No need for any patches ;)
2025-07-13 07:46:36 -05:00
535d5a4062 i give up, bump all versions 2025-07-02 20:54:06 +10:00
450734f5c9 bump version 2025-07-02 20:45:58 +10:00
20e2eda381 fix: regenerate lockfile 2025-07-02 20:45:02 +10:00
04d3f2dd8c fix: revert napi update 2025-07-02 20:33:53 +10:00
59ca57ee1b fix: bump napi version and commit lockfile 2025-07-02 20:20:19 +10:00
8f4b2a6c6d feat: add file peaking, 1.5.0 2025-07-02 18:03:35 +10:00
12 changed files with 1375 additions and 142 deletions

1
.gitignore vendored
View File

@ -186,7 +186,6 @@ $RECYCLE.BIN/
#Added by cargo
/target
Cargo.lock
.pnp.*
.yarn/*

1237
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,12 @@ crate-type = ["cdylib"]
[dependencies]
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "3.0.0-alpha.33", default-features = false, features = [
"napi4",
napi = { version = "3.0.0-beta.11", default-features = false, features = [
"napi6",
"async",
"web_stream",
] }
napi-derive = "3.0.0-alpha.33"
napi-derive = "3.0.0-beta.11"
hex = "0.4.3"
serde_json = "1.0.128"
md5 = "0.7.0"
@ -24,14 +24,11 @@ webpki = "0.22.4"
ring = "0.17.14"
tokio = { version = "1.45.1", features = ["fs", "io-util"] }
tokio-util = { version = "0.7.15", features = ["codec"] }
rawzip = "0.2.0"
rawzip = "0.3.0"
[package.metadata.patch]
crates = ["rawzip"]
[patch.crates-io]
rawzip = { path="./target/patch/rawzip-0.2.0" }
[dependencies.x509-parser]
version = "0.17.0"
features = ["verify"]

View File

@ -53,7 +53,7 @@ test("read file offset", async (t) => {
const testString = "0123456789";
fs.writeFileSync(dirName + "/TESTFILE", testString);
const stream = droplet.readFile(dirName, "TESTFILE", 1, 4);
const stream = droplet.readFile(dirName, "TESTFILE", BigInt(1), BigInt(4));
let finalString = "";

7
index.d.ts vendored
View File

@ -12,7 +12,12 @@ export declare function hasBackendForPath(path: string): boolean
export declare function listFiles(path: string): Array<string>
export declare function readFile(path: string, subPath: string, start?: number | undefined | null, end?: number | undefined | null): ReadableStream<Buffer> | null
/**
* This is inefficient, but is used in attempt to keep the interface simple
*/
export declare function peekFile(path: string, subPath: string): bigint
export declare function readFile(path: string, subPath: string, start?: bigint | undefined | null, end?: bigint | undefined | null): ReadableStream<Buffer> | null
export declare function signNonce(privateKey: string, nonce: string): string

View File

@ -365,11 +365,12 @@ if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
if (!nativeBinding) {
if (loadErrors.length > 0) {
// TODO Link to documentation with potential fixes
// - The package owner could build/publish bindings for this arch
// - The user may need to bundle the correct files
// - The user may need to re-install node_modules to get new packages
throw new Error('Failed to load native binding', { cause: loadErrors })
throw new Error(
`Cannot find native binding. ` +
`npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` +
'Please try `npm i` again after removing both package-lock.json and node_modules directory.',
{ cause: loadErrors }
)
}
throw new Error(`Failed to load native binding`)
}
@ -381,6 +382,7 @@ module.exports.generateManifest = nativeBinding.generateManifest
module.exports.generateRootCa = nativeBinding.generateRootCa
module.exports.hasBackendForPath = nativeBinding.hasBackendForPath
module.exports.listFiles = nativeBinding.listFiles
module.exports.peekFile = nativeBinding.peekFile
module.exports.readFile = nativeBinding.readFile
module.exports.signNonce = nativeBinding.signNonce
module.exports.verifyClientCertificate = nativeBinding.verifyClientCertificate

View File

@ -1,6 +1,6 @@
{
"name": "@drop-oss/droplet",
"version": "1.4.3",
"version": "1.6.0",
"main": "index.js",
"types": "index.d.ts",
"napi": {

View File

@ -1,26 +0,0 @@
diff --git a/src/archive.rs b/src/archive.rs
index 1203015..837c405 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -275,7 +275,7 @@ impl<'data> Iterator for ZipSliceEntries<'data> {
/// ```
#[derive(Debug, Clone)]
pub struct ZipArchive<R> {
- pub(crate) reader: R,
+ pub reader: R,
pub(crate) comment: ZipString,
pub(crate) eocd: EndOfCentralDirectory,
}
@@ -431,9 +431,9 @@ where
#[derive(Debug, Clone)]
pub struct ZipEntry<'archive, R> {
archive: &'archive ZipArchive<R>,
- body_offset: u64,
- body_end_offset: u64,
- entry: ZipArchiveEntryWayfinder,
+ pub body_offset: u64,
+ pub body_end_offset: u64,
+ pub entry: ZipArchiveEntryWayfinder,
}
impl<'archive, R> ZipEntry<'archive, R>

View File

@ -3,7 +3,7 @@ use core::arch;
use std::os::unix::fs::PermissionsExt;
use std::{
fs::File,
io::{self, Read},
io::{self, Read, Seek},
path::PathBuf,
pin::Pin,
rc::Rc,
@ -50,6 +50,7 @@ impl VersionBackend for PathVersionBackend {
results.push(VersionFile {
relative_filename: relative.to_string_lossy().to_string(),
permission: permissions,
size: metadata.len(),
});
}
@ -74,22 +75,22 @@ impl ZipVersionBackend {
}
}
pub fn new_entry(&self, entry: ZipEntry<'_, FileReader>) -> ZipFileWrapper {
pub fn new_entry(
&self,
entry: ZipEntry<'_, FileReader>,
wayfinder: ZipArchiveEntryWayfinder,
) -> ZipFileWrapper {
let (offset, end_offset) = entry.compressed_data_range();
ZipFileWrapper {
archive: self.archive.clone(),
wayfinder: entry.entry,
offset: entry.body_offset,
end_offset: entry.body_end_offset,
wayfinder,
offset,
end_offset,
}
}
}
impl Drop for ZipVersionBackend {
fn drop(&mut self) {
println!("dropping archive");
}
}
struct ZipFileWrapper {
pub struct ZipFileWrapper {
pub archive: Arc<ZipArchive<FileReader>>,
wayfinder: ZipArchiveEntryWayfinder,
offset: u64,
@ -101,7 +102,7 @@ impl Read for ZipFileWrapper {
let read_size = buf.len().min((self.end_offset - self.offset) as usize);
let read = self
.archive
.reader
.get_ref()
.read_at(&mut buf[..read_size], self.offset)?;
self.offset += read as u64;
Ok(read)
@ -109,12 +110,7 @@ impl Read for ZipFileWrapper {
}
impl Skippable for ZipFileWrapper {
fn skip(&mut self, amount: u64) {
/*io::copy(
&mut self.inner.reader().by_ref().take(amount),
&mut io::sink(),
)
.unwrap();
*/
self.offset += amount;
}
}
impl MinimumFileObject for ZipFileWrapper {}
@ -129,8 +125,9 @@ impl VersionBackend for ZipVersionBackend {
continue;
}
results.push(VersionFile {
relative_filename: entry.file_safe_path().unwrap().to_string(),
permission: 744, // apparently ZIPs with permissions are not supported by this library, so we let the owner do anything
relative_filename: String::from(entry.file_path().try_normalize().unwrap()),
permission: entry.mode().permissions(),
size: entry.uncompressed_size_hint(),
});
}
results
@ -141,7 +138,7 @@ impl VersionBackend for ZipVersionBackend {
let mut entries = self.archive.entries(read_buffer);
let entry = loop {
if let Some(v) = entries.next_entry().unwrap() {
if v.file_safe_path().unwrap().to_string() == file.relative_filename {
if v.file_path().try_normalize().unwrap().as_ref() == &file.relative_filename {
break Some(v);
}
} else {
@ -152,7 +149,7 @@ impl VersionBackend for ZipVersionBackend {
let wayfinder = entry.wayfinder();
let local_entry = self.archive.get_entry(wayfinder).unwrap();
let wrapper = self.new_entry(local_entry);
let wrapper = self.new_entry(local_entry, wayfinder);
Some(Box::new(wrapper))
}

View File

@ -4,10 +4,11 @@ use std::{
use tokio::io::{self, AsyncRead};
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct VersionFile {
pub relative_filename: String,
pub permission: u32,
pub size: u64,
}
pub trait Skippable {

View File

@ -60,37 +60,58 @@ pub fn list_files(path: String) -> Result<Vec<String>> {
Ok(files.into_iter().map(|e| e.relative_filename).collect())
}
/**
* This is inefficient, but is used in attempt to keep the interface simple
*/
#[napi]
pub fn peek_file(path: String, sub_path: String) -> Result<u64> {
let path = Path::new(&path);
let mut backend =
create_backend_for_path(path).ok_or(napi::Error::from_reason("No backend for path"))?;
let files = backend.list_files();
let file = files
.iter()
.find(|e| e.relative_filename == sub_path)
.ok_or(napi::Error::from_reason("Can't find file to peek"))?;
return Ok(file.size.try_into().unwrap());
}
#[napi]
pub fn read_file(
path: String,
sub_path: String,
env: &Env,
start: Option<u32>,
end: Option<u32>,
start: Option<BigInt>,
end: Option<BigInt>,
) -> Option<ReadableStream<'_, BufferSlice<'_>>> {
let path = Path::new(&path);
let mut backend = create_backend_for_path(path).unwrap();
let version_file = VersionFile {
relative_filename: sub_path,
permission: 0, // Shouldn't matter
size: 0, // Shouldn't matter
};
// Use `?` operator for cleaner error propagation from `Option`
let mut reader = backend.reader(&version_file)?;
// Skip the 'start' amount of bytes without seek
if let Some(skip) = start {
reader.skip(skip.into());
if let Some(skip) = start.clone() {
reader.skip(skip.get_u64().1.into());
// io::copy(&mut reader.by_ref().take(skip.into()), &mut io::sink()).unwrap();
}
let async_reader = if let Some(limit) = end {
let amount = limit - start.or(Some(0)).unwrap();
let amount = limit.get_u64().1 - start.map_or(Some(0), |v| Some(v.get_u64().1)).unwrap();
ReadToAsyncRead {
inner: Box::new(reader.take(amount.into())),
backend
backend,
}
} else {
ReadToAsyncRead { inner: reader, backend }
ReadToAsyncRead {
inner: reader,
backend,
}
};
// Create a FramedRead stream with BytesCodec for chunking

140
yarn.lock
View File

@ -43,11 +43,11 @@ __metadata:
languageName: node
linkType: hard
"@inquirer/checkbox@npm:^4.1.8":
version: 4.1.8
resolution: "@inquirer/checkbox@npm:4.1.8"
"@inquirer/checkbox@npm:^4.1.9":
version: 4.1.9
resolution: "@inquirer/checkbox@npm:4.1.9"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/figures": "npm:^1.0.12"
"@inquirer/type": "npm:^3.0.7"
ansi-escapes: "npm:^4.3.2"
@ -57,28 +57,28 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/6d726420b179c55b2f0001aaf6e339fa56e9e939afcbda31c386ab2e5d029ef6f2d392ec99c6a6950af1776a399791bbb88a635e4d047f1170b2ed8c5bba1e4c
checksum: 10c0/d1a93c31f3dad37f060bfdb6a8ba53f2cd36cfca7766c464c34aa95ecf691956c32be2f5b71cc8633ed7581452a04ab7b3a025d662270460d21b25069651ed42
languageName: node
linkType: hard
"@inquirer/confirm@npm:^5.1.12":
version: 5.1.12
resolution: "@inquirer/confirm@npm:5.1.12"
"@inquirer/confirm@npm:^5.1.13":
version: 5.1.13
resolution: "@inquirer/confirm@npm:5.1.13"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
peerDependencies:
"@types/node": ">=18"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/581aedfe8ce45e177fb4470a12f874f5162a4396636bf4140edc5812ffc8ed0d1fa7e9bbc3a7af618203089a084f489e0b32112947eedc6930a766fad992449e
checksum: 10c0/e09af25c4b4f51fdc7c6780e2325217515d3970a8baab3597ae27ea8d0ed68527c19b3ae95f85eeb62d880f6e8a0f3bff91277f0f46e092e993ca18ad17e4993
languageName: node
linkType: hard
"@inquirer/core@npm:^10.1.13":
version: 10.1.13
resolution: "@inquirer/core@npm:10.1.13"
"@inquirer/core@npm:^10.1.14":
version: 10.1.14
resolution: "@inquirer/core@npm:10.1.14"
dependencies:
"@inquirer/figures": "npm:^1.0.12"
"@inquirer/type": "npm:^3.0.7"
@ -93,15 +93,15 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/919208a31307297d5a07a44b9ebe69a999ce1470b31a2e1b5a04538bc36624d2053808cd6c677637a61690af09bdbdd635bd7031b64e3dd86c5b18df3ca7c3f9
checksum: 10c0/2553eb059201ebb182eb8e55a278ce3f2848a3abdfcf26e651b57b146f35baa19a286af0365ee5968b4459a1be93864ebf205a7af32fed8f995b394750a1d1f4
languageName: node
linkType: hard
"@inquirer/editor@npm:^4.2.13":
version: 4.2.13
resolution: "@inquirer/editor@npm:4.2.13"
"@inquirer/editor@npm:^4.2.14":
version: 4.2.14
resolution: "@inquirer/editor@npm:4.2.14"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
external-editor: "npm:^3.1.0"
peerDependencies:
@ -109,15 +109,15 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/e1a27d75f737d7847905c14cf04d66d864eeb0f3e4cb2d36e34b51993741c5b70c22754171820c5d880a740765471455a8a98874285fd4a10b162342898f6c6b
checksum: 10c0/40e85b4a598f3541f96185c61f0a5ba9abf9385f28cef8b8a1f9570729bbb98f32c80e98e4ce63bd3d07d4011b770d945587d9c6eecce3b03eb2ec08bd7f37ea
languageName: node
linkType: hard
"@inquirer/expand@npm:^4.0.15":
version: 4.0.15
resolution: "@inquirer/expand@npm:4.0.15"
"@inquirer/expand@npm:^4.0.16":
version: 4.0.16
resolution: "@inquirer/expand@npm:4.0.16"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
yoctocolors-cjs: "npm:^2.1.2"
peerDependencies:
@ -125,7 +125,7 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/d558e367995a38a31d830de45d1e6831b73a798d6076c7fc8bdb639d3fac947a5d15810f7336b45c7712fc0e21fe8a2728f7f594550a20b6b4a839a18f9086cb
checksum: 10c0/919e314c5bd86b957b491eff6aa79c990908b7898fc5d02968920be7866449d9dbf9bc33831eab922682e60b98553d753d1a3de6667fa6b1aa6443f457732713
languageName: node
linkType: hard
@ -136,41 +136,41 @@ __metadata:
languageName: node
linkType: hard
"@inquirer/input@npm:^4.1.12":
version: 4.1.12
resolution: "@inquirer/input@npm:4.1.12"
"@inquirer/input@npm:^4.2.0":
version: 4.2.0
resolution: "@inquirer/input@npm:4.2.0"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
peerDependencies:
"@types/node": ">=18"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/17b59547432f54a18ec573fde96c2c13c827f04faf694fc58239ec97e993ac6af151ed2a0521029c9199a4f422742dbe5dc23c20705748eafdc7dd26c7adca3a
checksum: 10c0/c9b671bbb8c8079e975c9138951b7abb6b06e04a44e47286b659569080140f5f18015ba3f2d55e90c5060a313a3c3e9e115138feced7abe7a94a43190a052199
languageName: node
linkType: hard
"@inquirer/number@npm:^3.0.15":
version: 3.0.15
resolution: "@inquirer/number@npm:3.0.15"
"@inquirer/number@npm:^3.0.16":
version: 3.0.16
resolution: "@inquirer/number@npm:3.0.16"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
peerDependencies:
"@types/node": ">=18"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/724fc0d10611a0a9ea43280a94ed9194b8bb22d9a2af940eb37592d0cebc9e6e219edc4f79d8c176f53fd1b078543a9e4773037c7bde4b8d929a3034406eec90
checksum: 10c0/066230f02cd253fe26cd78493c7c20b59063c8c2de5c8f5fadcaf4eb8650efc9e6555ba7d3703cc9ba7a751663f60e62e24b4a319d9536afa7ced7459e9b2320
languageName: node
linkType: hard
"@inquirer/password@npm:^4.0.15":
version: 4.0.15
resolution: "@inquirer/password@npm:4.0.15"
"@inquirer/password@npm:^4.0.16":
version: 4.0.16
resolution: "@inquirer/password@npm:4.0.16"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
ansi-escapes: "npm:^4.3.2"
peerDependencies:
@ -178,38 +178,38 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/673d7c33dd0ee951c96f349d4fb66f8762f31c62188546da4d7af544202b638eecef6b8c78e62f43a46c72a5fa0712d94a56ed56f12e1badbb1001128bc991bd
checksum: 10c0/b77c57ba152b50c640cd77637d1ed23662059689546e33b235937e7e108fbbf72b9b5c61834c545f74f1d18d5c836ef5a0dc78da31ea6affe9842c3471a27325
languageName: node
linkType: hard
"@inquirer/prompts@npm:^7.4.0":
version: 7.5.3
resolution: "@inquirer/prompts@npm:7.5.3"
version: 7.6.0
resolution: "@inquirer/prompts@npm:7.6.0"
dependencies:
"@inquirer/checkbox": "npm:^4.1.8"
"@inquirer/confirm": "npm:^5.1.12"
"@inquirer/editor": "npm:^4.2.13"
"@inquirer/expand": "npm:^4.0.15"
"@inquirer/input": "npm:^4.1.12"
"@inquirer/number": "npm:^3.0.15"
"@inquirer/password": "npm:^4.0.15"
"@inquirer/rawlist": "npm:^4.1.3"
"@inquirer/search": "npm:^3.0.15"
"@inquirer/select": "npm:^4.2.3"
"@inquirer/checkbox": "npm:^4.1.9"
"@inquirer/confirm": "npm:^5.1.13"
"@inquirer/editor": "npm:^4.2.14"
"@inquirer/expand": "npm:^4.0.16"
"@inquirer/input": "npm:^4.2.0"
"@inquirer/number": "npm:^3.0.16"
"@inquirer/password": "npm:^4.0.16"
"@inquirer/rawlist": "npm:^4.1.4"
"@inquirer/search": "npm:^3.0.16"
"@inquirer/select": "npm:^4.2.4"
peerDependencies:
"@types/node": ">=18"
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/14ba6f4a3bf1610d7c46399cd8367db8da1ab8c051ab7ff55003a5b36b5121429e3995e202c08156b7b6e7d4d9d032f39add98764c5ae3a7b4b657eb4926137f
checksum: 10c0/a00186a71388308a1bc83bd96fef14c702b6cfa34ecd7c7cf880405295b25aefd18a3b79363d788c9c31a2aa5e30732d21467a5b716fc35cc5fd303745ff2218
languageName: node
linkType: hard
"@inquirer/rawlist@npm:^4.1.3":
version: 4.1.3
resolution: "@inquirer/rawlist@npm:4.1.3"
"@inquirer/rawlist@npm:^4.1.4":
version: 4.1.4
resolution: "@inquirer/rawlist@npm:4.1.4"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/type": "npm:^3.0.7"
yoctocolors-cjs: "npm:^2.1.2"
peerDependencies:
@ -217,15 +217,15 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/d653e730188e6849df540186cf7cb0f37f06c64d03f075b5a617145671fb015c27aeb60adb003d1a05a925795968efff0a3ae5a737a8d04c5679aa6fdc423662
checksum: 10c0/2ee08bbdd982e4d565dc37b38b4f45e5a040ea1e60e3f8ec808106c1b541585e9a5c3a18f795ae2168820695ad55fb88b2e391c3a0d616a4e74620250292e2d3
languageName: node
linkType: hard
"@inquirer/search@npm:^3.0.15":
version: 3.0.15
resolution: "@inquirer/search@npm:3.0.15"
"@inquirer/search@npm:^3.0.16":
version: 3.0.16
resolution: "@inquirer/search@npm:3.0.16"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/figures": "npm:^1.0.12"
"@inquirer/type": "npm:^3.0.7"
yoctocolors-cjs: "npm:^2.1.2"
@ -234,15 +234,15 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/32b29789e72e53a7b6cfdbc1803bd9e466c424d9f0368a145bef9e25c6fbde72af29cdd4667a785fee79de213f11fa76453f8120ea02ac5158dce259565ce7fd
checksum: 10c0/34330cec50dd72669cdee14a413e7b43dee0e09c8f181a86ccfbdac424b6296e39dcc3c5992168d06c8f5e4cab54644913d5281723fa7a0f454c2c3cafeea192
languageName: node
linkType: hard
"@inquirer/select@npm:^4.2.3":
version: 4.2.3
resolution: "@inquirer/select@npm:4.2.3"
"@inquirer/select@npm:^4.2.4":
version: 4.2.4
resolution: "@inquirer/select@npm:4.2.4"
dependencies:
"@inquirer/core": "npm:^10.1.13"
"@inquirer/core": "npm:^10.1.14"
"@inquirer/figures": "npm:^1.0.12"
"@inquirer/type": "npm:^3.0.7"
ansi-escapes: "npm:^4.3.2"
@ -252,7 +252,7 @@ __metadata:
peerDependenciesMeta:
"@types/node":
optional: true
checksum: 10c0/376535f50a9c2e19e27a5c81930cd1b5afa0b7d86228e5789782955a2d0a89bf5a8890a97943042e1b393094fe236ce97c9ff4bb777c9b44b22c1424f883b063
checksum: 10c0/8c2dff78f331a52862252ffbc2ad1b8b91cbc556c2af1e6acc5878855ffff7048bb45eefa53e0ef4fbf5310361d9986d10c2882c2355f815e05d635cab9bb679
languageName: node
linkType: hard
@ -725,13 +725,13 @@ __metadata:
linkType: hard
"@napi-rs/wasm-runtime@npm:^0.2.10, @napi-rs/wasm-runtime@npm:^0.2.7, @napi-rs/wasm-runtime@npm:^0.2.9":
version: 0.2.10
resolution: "@napi-rs/wasm-runtime@npm:0.2.10"
version: 0.2.11
resolution: "@napi-rs/wasm-runtime@npm:0.2.11"
dependencies:
"@emnapi/core": "npm:^1.4.3"
"@emnapi/runtime": "npm:^1.4.3"
"@tybys/wasm-util": "npm:^0.9.0"
checksum: 10c0/4dce9bbb94a8969805574e1b55fdbeb7623348190265d77f6507ba32e535610deeb53a33ba0bb8b05a6520f379d418b92e8a01c5cd7b9486b136d2c0c26be0bd
checksum: 10c0/049bd14c58b99fbe0967b95e9921c5503df196b59be22948d2155f17652eb305cff6728efd8685338b855da7e476dd2551fbe3a313fc2d810938f0717478441e
languageName: node
linkType: hard