7zip-native 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -12
- package/bench/folder-concurrency.mts +192 -0
- package/dist/index.cjs +229 -21
- package/dist/index.d.cts +19 -2
- package/dist/index.d.mts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.mjs +219 -11
- package/native/addon.cpp +470 -0
- package/package.json +4 -3
- package/prebuilds/darwin-arm64/7zip_native.node +0 -0
- package/prebuilds/darwin-x64/7zip_native.node +0 -0
- package/prebuilds/linux-arm/7zip_native.node +0 -0
- package/prebuilds/linux-arm64/7zip_native.node +0 -0
- package/prebuilds/linux-ia32/7zip_native.node +0 -0
- package/prebuilds/linux-x64/7zip_native.node +0 -0
- package/prebuilds/win32-arm64/7z.dll +0 -0
- package/prebuilds/win32-arm64/7zip_native.node +0 -0
- package/prebuilds/win32-x64/7z.dll +0 -0
- package/prebuilds/win32-x64/7zip_native.node +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7z.so +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zAes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zAesRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zBuf2.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCompressionMode.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCrc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCrcOpt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zDecode.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zEncode.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zExtract.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zFolderInStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHandlerOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHeader.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zProperties.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zSpecStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zUpdate.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Aes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/AesOpt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Alloc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ApfsHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ApmHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArchiveExports.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArjHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Crc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Encoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Register.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Base64Handler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Coder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Enc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Register.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BcjCoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BcjRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BitlDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Blake2s.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bra.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bra86.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BraIA64.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BranchMisc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BranchRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BwtSort.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ByteSwap.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bz2Handler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CRC.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CWrappers.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabBlockInStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabHeader.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ChmHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ChmIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CodecExports.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CoderMixer2.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ComHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CopyCoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CopyRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CpioHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CpuArch.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CramfsHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CrcReg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CreateCoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Deflate64Register.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateEncoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateProps.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Delta.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeltaFilter.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DllExports2.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DmgHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DummyOutStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DynLimBuf.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ElfHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ExtHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FatHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileDir.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileFind.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileIO.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileName.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FilterCoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FindSignature.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FlvHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/GptHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/GzHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HandlerCont.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HandlerOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HfsHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HmacSha1.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HmacSha256.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HuffEnc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IhexHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ImplodeDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InBuffer.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InOutTempBuffer.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InStreamWithCRC.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IntToString.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoHeader.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ItemNameUtils.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LimitedStreams.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LockedStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LpHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFind.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindMt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindOpt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindPrepare.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzOutWindow.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzfseDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzhDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzhHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Dec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2DecMt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Enc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Encoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Register.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaDec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaEnc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaEncoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmsDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzxDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MachoHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MbrHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Md5.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Md5Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MemBlocks.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MethodId.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MethodProps.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MslzHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MtCoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MtDec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MubHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MultiStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyAes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyAesReg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyMap.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyString.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyVector.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyWindows.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyXml.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NewHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisDecode.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NtfsHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OffsetStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutBuffer.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutMemStream.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutStreamWithCRC.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutStreamWithSha1.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ParseProperties.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Pbkdf2HmacSha1.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PeHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7Dec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7Enc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7aDec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8Dec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8Enc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdEncoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdZip.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ProgressMt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ProgressUtils.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropId.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariant.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariantConv.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariantUtils.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/QcowHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/QuantumDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RandGen.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar1Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar20Crypto.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar2Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar3Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar3Vm.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Aes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Decoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Handler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarAes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarCodecsRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RpmHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Opt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Prepare.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Opt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Prepare.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha3.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha3Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Opt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Prepare.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ShrinkDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sort.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SparseHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SplitHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SquashfsHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamBinder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamObjects.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamUtils.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StringConvert.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StringToInt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SwapBytes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SwfHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Synchronization.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/System.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHandlerOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHeader.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarUpdate.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Threads.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TimeUtils.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UTFConvert.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UdfHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UdfIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UefiHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UniqBlocks.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VdiHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VhdHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VhdxHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VirtThread.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VmdkHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Wildcard.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimHandlerOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WzAes.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XarHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XpressDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xxh64.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xxh64Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xz.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Init.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Opt.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Reg.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzDec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzEnc.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzEncoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipAddCommon.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipCrypto.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipHandler.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipHandlerOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipIn.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipItem.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipOut.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipRegister.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipStrong.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipUpdate.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZlibDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZlibEncoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdDec.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdDecoder.o +0 -0
- package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdHandler.o +0 -0
- package/scripts/clean-upstream-build.mjs +0 -9
package/README.md
CHANGED
|
@@ -23,17 +23,17 @@ The package requires Node.js 18 or newer.
|
|
|
23
23
|
```ts
|
|
24
24
|
import {Archive} from '7zip-native';
|
|
25
25
|
|
|
26
|
-
const archive = await Archive.open('./
|
|
26
|
+
const archive = await Archive.open('./file.zip');
|
|
27
27
|
|
|
28
28
|
try
|
|
29
29
|
{
|
|
30
30
|
const entries = await archive.entries();
|
|
31
|
-
const
|
|
31
|
+
const file = await archive.getEntry('image.jpg');
|
|
32
32
|
|
|
33
|
-
if(
|
|
33
|
+
if(file && !file.isDirectory)
|
|
34
34
|
{
|
|
35
|
-
const preview = await archive.read(
|
|
36
|
-
const image = await archive.extract(
|
|
35
|
+
const preview = await archive.read(file.path, {offset: 0, length: 64 * 1024});
|
|
36
|
+
const image = await archive.extract(file.path);
|
|
37
37
|
console.log(entries.length, preview.length, image.length);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -63,7 +63,9 @@ Opens an archive from a filesystem path and indexes its metadata asynchronously.
|
|
|
63
63
|
const archive = await Archive.open('./archive.7z', {password: 'secret'});
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
`
|
|
66
|
+
`Archive.open()` accepts these options:
|
|
67
|
+
|
|
68
|
+
- `password`: Passed to the upstream handler if it requests a password. It is held for the lifetime of the archive handle, is not logged, and is limited to 1 MiB of UTF-8 data.
|
|
67
69
|
|
|
68
70
|
### Listing and looking up entries
|
|
69
71
|
|
|
@@ -109,7 +111,12 @@ const header = await archive.read(entry.path, {
|
|
|
109
111
|
});
|
|
110
112
|
```
|
|
111
113
|
|
|
112
|
-
|
|
114
|
+
`read()` accepts these options:
|
|
115
|
+
|
|
116
|
+
- `offset`: Byte position at which to start reading. Defaults to `0`; accepts a non-negative safe integer or `bigint`.
|
|
117
|
+
- `length`: Number of bytes to return. Required; accepts a non-negative safe integer or `bigint`. A range read is limited to 64 MiB.
|
|
118
|
+
|
|
119
|
+
A range read returns only the requested bytes. It uses the handler's normal extraction path, however, so a sequential or solid format may still need to decompress preceding data or the whole entry. It is not guaranteed to be constant-time random access.
|
|
113
120
|
|
|
114
121
|
### Streams and output destinations
|
|
115
122
|
|
|
@@ -125,7 +132,13 @@ for await (const chunk of archive.createReadStream(entry.path, {
|
|
|
125
132
|
}
|
|
126
133
|
```
|
|
127
134
|
|
|
128
|
-
|
|
135
|
+
`createReadStream()` accepts these options:
|
|
136
|
+
|
|
137
|
+
- `highWaterMark`: Readable buffer threshold in bytes. Must be an integer from 1 byte to 16 MiB; defaults to Node.js's Readable default.
|
|
138
|
+
- `maxBytes`: Maximum number of output bytes. Defaults to 4 GiB; accepts a non-negative `number` or `bigint`, or `null` to disable the limit.
|
|
139
|
+
- `signal`: Optional `AbortSignal` that cancels extraction.
|
|
140
|
+
|
|
141
|
+
The native engine emits bounded 64 KiB chunks and waits for stream demand, preserving backpressure. Destroying the stream or aborting its signal cancels extraction at the next output boundary.
|
|
129
142
|
|
|
130
143
|
To pipe directly to a Node.js `Writable`:
|
|
131
144
|
|
|
@@ -137,23 +150,63 @@ await archive.extractToStream(entry.path, createWriteStream('./page.jpg'), {
|
|
|
137
150
|
});
|
|
138
151
|
```
|
|
139
152
|
|
|
140
|
-
|
|
153
|
+
`extractToStream()` accepts the same `highWaterMark`, `maxBytes`, and `signal` options as `createReadStream()`. It respects backpressure and ends the destination when extraction succeeds. A destination error, early close, or abort rejects the Promise.
|
|
154
|
+
|
|
155
|
+
### Creating ZIP, 7z, TAR, and WIM archives
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
await Archive.create('./archive.zip', [
|
|
159
|
+
{sourcePath: './image.jpg', path: 'image.jpg'},
|
|
160
|
+
{sourcePath: './file.txt', path: 'file.txt'},
|
|
161
|
+
], {
|
|
162
|
+
compressionLevel: 5,
|
|
163
|
+
overwrite: false,
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`Archive.create()` accepts regular source files and their desired archive-internal paths:
|
|
168
|
+
|
|
169
|
+
- `sourcePath`: Filesystem path of the regular file to add.
|
|
170
|
+
- `path`: Desired path inside the archive, using `/` separators.
|
|
171
|
+
|
|
172
|
+
It also accepts these options:
|
|
173
|
+
|
|
174
|
+
- `format`: Archive format. If omitted, inferred as ZIP from `.zip`, 7z from `.7z`, TAR from `.tar`, or WIM from `.wim`. Set to `'zip'`, `'7z'`, `'tar'`, or `'wim'` to use another output extension.
|
|
175
|
+
- `compressionLevel`: Integer from 0 to 9; defaults to 5 and applies only to ZIP and 7z. TAR is uncompressed; WIM uses the upstream handler's default settings.
|
|
176
|
+
- `overwrite`: Defaults to `false`. When `true`, an existing output file is replaced after the new archive has been written.
|
|
177
|
+
|
|
178
|
+
Duplicate, unsafe, or conflicting internal paths are rejected. The output is first written to a temporary file beside the destination, then installed atomically, so an existing file is preserved if archive creation fails. Archive creation runs in the bounded native worker pool and does not launch a 7-Zip executable.
|
|
141
179
|
|
|
142
180
|
### Extracting to a folder
|
|
143
181
|
|
|
144
182
|
```ts
|
|
145
183
|
await archive.extractToFolder('./unpacked', {
|
|
146
184
|
paths: ['chapter/page1.jpg', 'chapter/page2.jpg'], // alternatively, use ids
|
|
185
|
+
concurrency: 2,
|
|
147
186
|
overwrite: true,
|
|
148
187
|
onProgress: ({filesExtracted, totalFiles, bytesProcessed, totalBytes, percent}) => {
|
|
149
188
|
console.log(`${filesExtracted}/${totalFiles} files, ${percent}% (${bytesProcessed}/${totalBytes} bytes)`);
|
|
150
189
|
},
|
|
190
|
+
onExtract: ({entry, outputPath}) => {
|
|
191
|
+
console.log(`Extracted ${entry.path} to ${outputPath}`);
|
|
192
|
+
},
|
|
151
193
|
maxBytes: 2n * 1024n * 1024n * 1024n,
|
|
152
194
|
signal: abortController.signal,
|
|
153
195
|
});
|
|
154
196
|
```
|
|
155
197
|
|
|
156
|
-
|
|
198
|
+
`extractToFolder()` accepts these options:
|
|
199
|
+
|
|
200
|
+
- `ids`: Entry IDs to extract. Omit both `ids` and `paths` to extract every entry.
|
|
201
|
+
- `paths`: Exact, original archive paths to extract, using `/` separators. This cannot be combined with `ids`.
|
|
202
|
+
- `concurrency`: Maximum number of files this call extracts simultaneously. Must be an integer from 1 to 128; defaults to 1 and is capped at the process-wide native worker-pool concurrency. This does not change `Archive.concurrency()`.
|
|
203
|
+
- `overwrite`: Defaults to `false`, so existing files are not overwritten. When `true`, each existing regular file is replaced only after its entry has been fully extracted to a temporary file alongside the destination. A failure does not truncate the existing file, but replacement may temporarily require extra disk space up to the size of the entry.
|
|
204
|
+
- `onProgress`: Called before extraction, as chunks are processed, and after each file completes. Receives `filesExtracted`, `totalFiles`, aggregated `bytesProcessed`, `totalBytes`, and the calculated `percent`.
|
|
205
|
+
- `onExtract`: Called once for each regular file after it is fully written and, when overwriting, after the final replacement. Receives `{entry, outputPath}`; `entry` retains the original archive metadata and `outputPath` is the final destination path.
|
|
206
|
+
- `maxBytes`: Maximum total uncompressed output size. Defaults to 4 GiB; set to `null` to disable the limit.
|
|
207
|
+
- `signal`: Optional `AbortSignal`. Cancellation stops new files from starting, cancels or waits for active extractions, cleans temporary replacement files, and rejects the call.
|
|
208
|
+
|
|
209
|
+
On Windows only, invalid filename characters (`< > : | ? * "`) and trailing dots/spaces in each destination component are replaced with `_`; selectors and entry metadata remain unchanged. Unsafe archive paths, path collisions, symlinked destination components, and symlink or non-file targets are rejected. Archive links are written as regular file data; the API does not create symbolic or hard links. If extraction fails partway through, files already written (or partially written) may remain in the destination.
|
|
157
210
|
|
|
158
211
|
### Concurrency
|
|
159
212
|
|
|
@@ -163,7 +216,11 @@ Archive.concurrency(8);
|
|
|
163
216
|
Archive.concurrency(0); // reset to the default
|
|
164
217
|
```
|
|
165
218
|
|
|
166
|
-
|
|
219
|
+
`Archive.concurrency(value?)` controls the process-wide native worker pool used by extraction, streams, and range reads:
|
|
220
|
+
|
|
221
|
+
- `value`: Omit to read the current setting. Set to an integer from 1 to 128 to configure the worker count, or `0` to restore the default.
|
|
222
|
+
|
|
223
|
+
The default is the lesser of 4 and the parallelism available to Node.js.
|
|
167
224
|
|
|
168
225
|
Concurrent operations on one archive use independent decoder contexts rather than calling one 7-Zip archive object simultaneously. This is safe for handlers that support independent contexts, but it does not guarantee a speedup. Solid archives may decompress shared data more than once; batching related entries may be faster.
|
|
169
226
|
|
|
@@ -189,6 +246,7 @@ Invalid argument types and values throw standard `TypeError` or `RangeError`. Ar
|
|
|
189
246
|
| `ERR_ARCHIVE_PASSWORD` | Password is missing or incorrect when requested by the handler |
|
|
190
247
|
| `ERR_ARCHIVE_PATH` | Unsafe or colliding path during folder extraction |
|
|
191
248
|
| `ERR_ARCHIVE_EXTRACT` | Entry extraction failed |
|
|
249
|
+
| `ERR_ARCHIVE_CREATE` | Archive creation failed or the output already exists |
|
|
192
250
|
|
|
193
251
|
Buffered `extract()` and `read()` do not currently support cancellation. Streams and folder extraction accept an `AbortSignal`.
|
|
194
252
|
|
|
@@ -199,6 +257,7 @@ The package uses the handlers registered in the pinned upstream `Format7zF` bund
|
|
|
199
257
|
### Format-specific notes
|
|
200
258
|
|
|
201
259
|
- **RAR:** extraction uses upstream code subject to its LGPL terms and the unRAR restriction. This package does not create RAR archives or implement the proprietary RAR compression algorithm. Review the upstream notices before redistribution.
|
|
260
|
+
- **Creation:** ZIP, 7z, TAR, and WIM archives can be created from filesystem files. Streams and directory trees are not accepted as sources.
|
|
202
261
|
- **ACE:** not supported by this 7-Zip revision.
|
|
203
262
|
- **Encryption:** password callbacks are connected to archive opening and extraction. AES-256 encrypted ZIP extraction and range reads are tested on Linux x64; encrypted-header behavior and password variants in other formats are not yet verified.
|
|
204
263
|
- **Partial reads:** memory use is limited to the requested range, but the decoder may still process more data internally, especially for solid or sequential formats.
|
|
@@ -236,7 +295,7 @@ When packaging with ASAR, ensure both `7zip_native.node` and the matching engine
|
|
|
236
295
|
}
|
|
237
296
|
```
|
|
238
297
|
|
|
239
|
-
Test the packaged application on each target; ASAR unpacking does not replace checking that the addon and engine can both be loaded from the packaged runtime.
|
|
298
|
+
If an application bundler relocates this package's JavaScript (for example, into a `www` directory), keep `7zip-native` resolvable as an installed dependency so the loader can locate the package's prebuilt binaries. Test the packaged application on each target; ASAR unpacking does not replace checking that the addon and engine can both be loaded from the packaged runtime.
|
|
240
299
|
|
|
241
300
|
## Build from source
|
|
242
301
|
|
|
@@ -295,6 +354,18 @@ npm run benchmark:concurrency -- \
|
|
|
295
354
|
|
|
296
355
|
The report includes median and p95 latency, throughput, speedup, and the number of entries that can overlap. `--max-files` selects evenly spaced entries, which is useful when sampling solid archives. Benchmarks report measurements only; results depend on the archive, machine, and workload and do not guarantee a speedup.
|
|
297
356
|
|
|
357
|
+
Compare `extractToFolder()` concurrency (1 through 16) across one or more archives:
|
|
358
|
+
|
|
359
|
+
```sh
|
|
360
|
+
npm run benchmark:folder-concurrency -- \
|
|
361
|
+
--archive "./samples/sample.zip" \
|
|
362
|
+
--archive "./archive.7z" \
|
|
363
|
+
--concurrencies 1,2,3,4,5,8,16 \
|
|
364
|
+
--iterations 1
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
By default, the benchmark tests all concurrencies from 1 to 16. Use `--concurrencies` to select a comma-separated subset, or `--concurrency` for one value; concurrency 1 is always included as the speedup baseline. Each run extracts one archive into a temporary directory, verifies the completed file and byte counts, and removes the output before continuing. The default is one iteration per concurrency; increase `--iterations` for more stable measurements. The global worker pool is set to 16 for the benchmark and restored afterward.
|
|
368
|
+
|
|
298
369
|
## License
|
|
299
370
|
|
|
300
371
|
This package is MIT-licensed. The integrated 7-Zip code and other bundled dependencies have their own licensing terms; see [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md) before redistribution.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import {mkdtemp, rm, stat} from 'node:fs/promises';
|
|
2
|
+
import {tmpdir} from 'node:os';
|
|
3
|
+
import {join, resolve} from 'node:path';
|
|
4
|
+
import {Archive, type ExtractToFolderProgress} from '../dist/index.mjs';
|
|
5
|
+
|
|
6
|
+
const usage = 'npm run benchmark:folder-concurrency -- --archive <path> [--archive <path> ...] [--iterations <count>] [--concurrency <workers> | --concurrencies <workers,...>]';
|
|
7
|
+
const archivePaths: string[] = [];
|
|
8
|
+
let iterations = 1;
|
|
9
|
+
let concurrencyOption: string | undefined;
|
|
10
|
+
let concurrenciesOption: string | undefined;
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
for(let index = 0; index < args.length; index++)
|
|
13
|
+
{
|
|
14
|
+
const argument = args[index]!;
|
|
15
|
+
if(argument === '--archive' || argument.startsWith('--archive='))
|
|
16
|
+
{
|
|
17
|
+
const equalsIndex = argument.indexOf('=');
|
|
18
|
+
const path = equalsIndex === -1 ? args[++index] : argument.slice(equalsIndex + 1);
|
|
19
|
+
if(!path || path.startsWith('--'))
|
|
20
|
+
{
|
|
21
|
+
throw new TypeError(`Missing value for --archive\nUsage: ${usage}`);
|
|
22
|
+
}
|
|
23
|
+
archivePaths.push(resolve(path));
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if(argument === '--iterations' || argument.startsWith('--iterations='))
|
|
27
|
+
{
|
|
28
|
+
const equalsIndex = argument.indexOf('=');
|
|
29
|
+
const value = equalsIndex === -1 ? args[++index] : argument.slice(equalsIndex + 1);
|
|
30
|
+
if(!value || value.startsWith('--'))
|
|
31
|
+
{
|
|
32
|
+
throw new TypeError(`Missing value for --iterations\nUsage: ${usage}`);
|
|
33
|
+
}
|
|
34
|
+
iterations = Number(value);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if(argument === '--concurrency' || argument.startsWith('--concurrency='))
|
|
38
|
+
{
|
|
39
|
+
if(concurrencyOption !== undefined)
|
|
40
|
+
{
|
|
41
|
+
throw new TypeError('Option --concurrency may only be specified once');
|
|
42
|
+
}
|
|
43
|
+
const equalsIndex = argument.indexOf('=');
|
|
44
|
+
concurrencyOption = equalsIndex === -1 ? args[++index] : argument.slice(equalsIndex + 1);
|
|
45
|
+
if(!concurrencyOption || concurrencyOption.startsWith('--'))
|
|
46
|
+
{
|
|
47
|
+
throw new TypeError(`Missing value for --concurrency\nUsage: ${usage}`);
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if(argument === '--concurrencies' || argument.startsWith('--concurrencies='))
|
|
52
|
+
{
|
|
53
|
+
if(concurrenciesOption !== undefined)
|
|
54
|
+
{
|
|
55
|
+
throw new TypeError('Option --concurrencies may only be specified once');
|
|
56
|
+
}
|
|
57
|
+
const equalsIndex = argument.indexOf('=');
|
|
58
|
+
concurrenciesOption = equalsIndex === -1 ? args[++index] : argument.slice(equalsIndex + 1);
|
|
59
|
+
if(!concurrenciesOption || concurrenciesOption.startsWith('--'))
|
|
60
|
+
{
|
|
61
|
+
throw new TypeError(`Missing value for --concurrencies\nUsage: ${usage}`);
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
throw new TypeError(`Unknown argument ${argument}\nUsage: ${usage}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if(archivePaths.length === 0)
|
|
69
|
+
{
|
|
70
|
+
throw new TypeError(`Specify at least one --archive\nUsage: ${usage}`);
|
|
71
|
+
}
|
|
72
|
+
if(!Number.isSafeInteger(iterations) || iterations < 1)
|
|
73
|
+
{
|
|
74
|
+
throw new RangeError('--iterations must be a positive integer');
|
|
75
|
+
}
|
|
76
|
+
if(concurrencyOption !== undefined && concurrenciesOption !== undefined)
|
|
77
|
+
{
|
|
78
|
+
throw new TypeError('Use either --concurrency or --concurrencies, not both');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function parseConcurrency(value: string): number
|
|
82
|
+
{
|
|
83
|
+
const concurrency = Number(value);
|
|
84
|
+
if(!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > 16)
|
|
85
|
+
{
|
|
86
|
+
throw new RangeError('Concurrency values must be integers between 1 and 16');
|
|
87
|
+
}
|
|
88
|
+
return concurrency;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const selectedConcurrencies = concurrencyOption === undefined
|
|
92
|
+
? concurrenciesOption === undefined
|
|
93
|
+
? Array.from({length: 16}, (_, index) => index + 1)
|
|
94
|
+
: concurrenciesOption.split(',').map(value => parseConcurrency(value.trim()))
|
|
95
|
+
: [parseConcurrency(concurrencyOption)];
|
|
96
|
+
const concurrencies = [...new Set([1, ...selectedConcurrencies])];
|
|
97
|
+
const originalConcurrency = Archive.concurrency();
|
|
98
|
+
const archiveResults = [];
|
|
99
|
+
try
|
|
100
|
+
{
|
|
101
|
+
Archive.concurrency(16);
|
|
102
|
+
for(const archivePath of archivePaths)
|
|
103
|
+
{
|
|
104
|
+
const archive = await Archive.open(archivePath);
|
|
105
|
+
try
|
|
106
|
+
{
|
|
107
|
+
const archiveSize = (await stat(archivePath)).size;
|
|
108
|
+
const files = (await archive.entries()).filter(entry => !entry.isDirectory);
|
|
109
|
+
if(files.length === 0)
|
|
110
|
+
{
|
|
111
|
+
throw new Error(`Archive contains no regular files: ${archivePath}`);
|
|
112
|
+
}
|
|
113
|
+
const expectedBytes = files.reduce((total, file) => total + file.size, 0n);
|
|
114
|
+
const measurements = [];
|
|
115
|
+
let serialMedian = 0;
|
|
116
|
+
for(const concurrency of concurrencies)
|
|
117
|
+
{
|
|
118
|
+
const durations: number[] = [];
|
|
119
|
+
for(let iteration = 0; iteration < iterations; iteration++)
|
|
120
|
+
{
|
|
121
|
+
const temporaryDirectory = await mkdtemp(join(tmpdir(), '7zip-native-folder-bench-'));
|
|
122
|
+
let finalProgress: ExtractToFolderProgress | undefined;
|
|
123
|
+
let completedFiles = 0;
|
|
124
|
+
try
|
|
125
|
+
{
|
|
126
|
+
const start = process.hrtime.bigint();
|
|
127
|
+
await archive.extractToFolder(join(temporaryDirectory, 'output'), {
|
|
128
|
+
concurrency,
|
|
129
|
+
onProgress: progress => {
|
|
130
|
+
finalProgress = progress;
|
|
131
|
+
},
|
|
132
|
+
onExtract: () => {
|
|
133
|
+
completedFiles++;
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
durations.push(Number(process.hrtime.bigint() - start) / 1e6);
|
|
137
|
+
if(!finalProgress
|
|
138
|
+
|| finalProgress.filesExtracted !== files.length
|
|
139
|
+
|| finalProgress.totalFiles !== files.length
|
|
140
|
+
|| finalProgress.bytesProcessed !== expectedBytes
|
|
141
|
+
|| finalProgress.totalBytes !== expectedBytes
|
|
142
|
+
|| completedFiles !== files.length)
|
|
143
|
+
{
|
|
144
|
+
throw new Error(`Extraction verification failed for ${archivePath} at concurrency ${concurrency}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
finally
|
|
148
|
+
{
|
|
149
|
+
await rm(temporaryDirectory, {recursive: true, force: true});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const sorted = [...durations].sort((a, b) => a - b);
|
|
153
|
+
const median = sorted[Math.floor(sorted.length / 2)]!;
|
|
154
|
+
const p95 = sorted[Math.ceil(sorted.length * 0.95) - 1]!;
|
|
155
|
+
if(concurrency === 1)
|
|
156
|
+
{
|
|
157
|
+
serialMedian = median;
|
|
158
|
+
}
|
|
159
|
+
measurements.push({
|
|
160
|
+
concurrency,
|
|
161
|
+
iterations,
|
|
162
|
+
median_ms: median,
|
|
163
|
+
p95_ms: p95,
|
|
164
|
+
throughput_mib_per_second: Number(expectedBytes) / (median / 1000) / 1024 / 1024,
|
|
165
|
+
speedup_vs_1: serialMedian / median,
|
|
166
|
+
runs_ms: durations,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
archiveResults.push({
|
|
170
|
+
archive: archivePath,
|
|
171
|
+
archive_bytes: archiveSize,
|
|
172
|
+
files: files.length,
|
|
173
|
+
uncompressed_bytes: expectedBytes.toString(),
|
|
174
|
+
measurements,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
finally
|
|
178
|
+
{
|
|
179
|
+
await archive.close();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
console.log(JSON.stringify({
|
|
183
|
+
global_pool_concurrency: 16,
|
|
184
|
+
concurrencies,
|
|
185
|
+
iterations,
|
|
186
|
+
archives: archiveResults,
|
|
187
|
+
}, null, 2));
|
|
188
|
+
}
|
|
189
|
+
finally
|
|
190
|
+
{
|
|
191
|
+
Archive.concurrency(originalConcurrency);
|
|
192
|
+
}
|