7zip-native 0.0.7 → 0.0.10
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 +96 -24
- package/bench/compare.mts +25 -11
- package/bench/folder-concurrency.mts +56 -14
- package/bench/multiprocess-extract.cjs +334 -0
- package/dist/index.cjs +194 -102
- package/dist/index.d.cts +10 -9
- package/dist/index.d.mts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.mjs +196 -104
- package/native/addon.cpp +1399 -71
- package/package.json +5 -3
- package/patches/deflate-input-buffer-size.patch +47 -0
- package/prebuilds/darwin-arm64/7zip_native.node +0 -0
- package/prebuilds/darwin-arm64/lib7z.dylib +0 -0
- package/prebuilds/darwin-x64/7zip_native.node +0 -0
- package/prebuilds/darwin-x64/lib7z.dylib +0 -0
- package/prebuilds/linux-arm/7z.so +0 -0
- package/prebuilds/linux-arm/7zip_native.node +0 -0
- package/prebuilds/linux-arm64/7z.so +0 -0
- package/prebuilds/linux-arm64/7zip_native.node +0 -0
- package/prebuilds/linux-ia32/7z.so +0 -0
- package/prebuilds/linux-ia32/7zip_native.node +0 -0
- package/prebuilds/linux-x64/7z.so +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/scripts/build-native.mjs +22 -1
- package/vendor/7zip/CPP/7zip/Archive/Archive2.def +1 -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/vendor/7zip/CPP/7zip/Compress/DeflateDecoder.cpp +15 -1
- 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,14 @@ 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.
|
|
69
|
+
- `deflateBufferSize`: Input buffer size in bytes for Deflate extraction. Defaults to `32768`; accepts integers from `4096` through `2097152`. It is stored per archive and applied to each extraction, so different open archives can use different values.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const archive = await Archive.open('./archive.zip', {deflateBufferSize: 32768});
|
|
73
|
+
```
|
|
67
74
|
|
|
68
75
|
### Listing and looking up entries
|
|
69
76
|
|
|
@@ -107,9 +114,24 @@ const header = await archive.read(entry.path, {
|
|
|
107
114
|
offset: 0,
|
|
108
115
|
length: 64 * 1024,
|
|
109
116
|
});
|
|
117
|
+
const headers = await archive.read([first.path, second.id], {
|
|
118
|
+
offset: 0,
|
|
119
|
+
length: 64 * 1024,
|
|
120
|
+
});
|
|
121
|
+
const prefixes = await archive.read([
|
|
122
|
+
{entry: first.path, offset: 0, length: 8192},
|
|
123
|
+
{entry: second.id, offset: 0, length: 64},
|
|
124
|
+
]);
|
|
110
125
|
```
|
|
111
126
|
|
|
112
|
-
|
|
127
|
+
`read()` accepts one entry selector or a batch. For a selector array, the same range is used for every entry; use `ReadRequest[]` to specify a different range per entry. Both batch forms return buffers in request order and run as one native extraction operation. The selector-array form preserves repeated selectors; `ReadRequest[]` must contain unique entries.
|
|
128
|
+
|
|
129
|
+
`read()` accepts these options:
|
|
130
|
+
|
|
131
|
+
- `offset`: Byte position at which to start reading. Defaults to `0`; accepts a non-negative safe integer or `bigint`.
|
|
132
|
+
- `length`: Number of bytes to return. Required; accepts a non-negative safe integer or `bigint`. A range read is limited to 64 MiB.
|
|
133
|
+
|
|
134
|
+
A range read returns only the requested bytes. A batch is limited to 64 MiB per entry and 256 MiB total output. 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
135
|
|
|
114
136
|
### Streams and output destinations
|
|
115
137
|
|
|
@@ -125,7 +147,13 @@ for await (const chunk of archive.createReadStream(entry.path, {
|
|
|
125
147
|
}
|
|
126
148
|
```
|
|
127
149
|
|
|
128
|
-
|
|
150
|
+
`createReadStream()` accepts these options:
|
|
151
|
+
|
|
152
|
+
- `highWaterMark`: Readable buffer threshold in bytes. Must be an integer from 1 byte to 16 MiB; defaults to Node.js's Readable default.
|
|
153
|
+
- `maxBytes`: Maximum number of output bytes. Defaults to 4 GiB; accepts a non-negative `number` or `bigint`, or `null` to disable the limit.
|
|
154
|
+
- `signal`: Optional `AbortSignal` that cancels extraction.
|
|
155
|
+
|
|
156
|
+
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
157
|
|
|
130
158
|
To pipe directly to a Node.js `Writable`:
|
|
131
159
|
|
|
@@ -137,21 +165,34 @@ await archive.extractToStream(entry.path, createWriteStream('./page.jpg'), {
|
|
|
137
165
|
});
|
|
138
166
|
```
|
|
139
167
|
|
|
140
|
-
|
|
168
|
+
`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.
|
|
141
169
|
|
|
142
170
|
### Creating ZIP, 7z, TAR, and WIM archives
|
|
143
171
|
|
|
144
172
|
```ts
|
|
145
|
-
await Archive.create('./
|
|
146
|
-
{sourcePath: './
|
|
147
|
-
{sourcePath: './
|
|
173
|
+
await Archive.create('./archive.zip', [
|
|
174
|
+
{sourcePath: './image.jpg', path: 'image.jpg'},
|
|
175
|
+
{sourcePath: './file.txt', path: 'file.txt'},
|
|
148
176
|
], {
|
|
149
177
|
compressionLevel: 5,
|
|
150
178
|
overwrite: false,
|
|
151
179
|
});
|
|
152
180
|
```
|
|
153
181
|
|
|
154
|
-
`Archive.create()` accepts regular source files and their desired archive-internal paths
|
|
182
|
+
`Archive.create()` accepts regular source files and their desired archive-internal paths:
|
|
183
|
+
|
|
184
|
+
- `sourcePath`: Filesystem path of the regular file to add.
|
|
185
|
+
- `path`: Desired path inside the archive, using `/` separators.
|
|
186
|
+
|
|
187
|
+
The source file's modification time is stored in the archive.
|
|
188
|
+
|
|
189
|
+
It also accepts these options:
|
|
190
|
+
|
|
191
|
+
- `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.
|
|
192
|
+
- `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.
|
|
193
|
+
- `overwrite`: Defaults to `false`. When `true`, an existing output file is replaced after the new archive has been written.
|
|
194
|
+
|
|
195
|
+
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.
|
|
155
196
|
|
|
156
197
|
### Extracting to a folder
|
|
157
198
|
|
|
@@ -160,18 +201,27 @@ await archive.extractToFolder('./unpacked', {
|
|
|
160
201
|
paths: ['chapter/page1.jpg', 'chapter/page2.jpg'], // alternatively, use ids
|
|
161
202
|
concurrency: 2,
|
|
162
203
|
overwrite: true,
|
|
163
|
-
|
|
164
|
-
console.log(
|
|
165
|
-
},
|
|
166
|
-
onExtract: ({entry, outputPath}) => {
|
|
167
|
-
console.log(`Extracted ${entry.path} to ${outputPath}`);
|
|
204
|
+
onExtract: ({entry, outputPath, percent}) => {
|
|
205
|
+
console.log(`Extracted ${entry.path} to ${outputPath} (${percent}%)`);
|
|
168
206
|
},
|
|
169
207
|
maxBytes: 2n * 1024n * 1024n * 1024n,
|
|
170
208
|
signal: abortController.signal,
|
|
171
209
|
});
|
|
172
210
|
```
|
|
173
211
|
|
|
174
|
-
|
|
212
|
+
`extractToFolder()` accepts these options:
|
|
213
|
+
|
|
214
|
+
- `ids`: Entry IDs to extract. Omit both `ids` and `paths` to extract every entry.
|
|
215
|
+
- `paths`: Exact, original archive paths to extract, using `/` separators. This cannot be combined with `ids`.
|
|
216
|
+
- `concurrency`: Maximum number of native extraction batches this call runs 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()`.
|
|
217
|
+
- `overwrite`: Defaults to `false`, so existing files are not overwritten. When `true`, an existing regular file is removed before the new file is written directly to its final path. A failed extraction can leave the destination missing.
|
|
218
|
+
- `onExtract`: Called after each regular file has been completely written and closed; it does not wait for the rest of the batch. Concurrent extraction can make event order differ from selection order. Receives `{entry, outputPath, percent}`, where `percent` is the completed-file count divided by the total selected regular files. `entry` retains the original archive metadata and `outputPath` is the final destination path.
|
|
219
|
+
- `maxBytes`: Maximum total uncompressed output size. Defaults to 4 GiB; set to `null` to disable the limit.
|
|
220
|
+
- `signal`: Optional `AbortSignal`. Cancellation stops new files from starting, cancels or waits for active extractions, cleans temporary replacement files, and rejects the call.
|
|
221
|
+
|
|
222
|
+
Each native extraction call receives a batch of entry IDs and output paths. The addon queues disk writes asynchronously while 7-Zip continues extracting later entries; `onExtract` runs after that file's queued writes have completed and the file is closed. File contents are not streamed through Node.js or Electron. The `extractToFolder()` promise resolves after all `onExtract` callbacks have run.
|
|
223
|
+
|
|
224
|
+
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.
|
|
175
225
|
|
|
176
226
|
### Concurrency
|
|
177
227
|
|
|
@@ -181,7 +231,11 @@ Archive.concurrency(8);
|
|
|
181
231
|
Archive.concurrency(0); // reset to the default
|
|
182
232
|
```
|
|
183
233
|
|
|
184
|
-
|
|
234
|
+
`Archive.concurrency(value?)` controls the process-wide native worker pool used by extraction, streams, and range reads:
|
|
235
|
+
|
|
236
|
+
- `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.
|
|
237
|
+
|
|
238
|
+
The default is the lesser of 4 and the parallelism available to Node.js.
|
|
185
239
|
|
|
186
240
|
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.
|
|
187
241
|
|
|
@@ -256,7 +310,7 @@ When packaging with ASAR, ensure both `7zip_native.node` and the matching engine
|
|
|
256
310
|
}
|
|
257
311
|
```
|
|
258
312
|
|
|
259
|
-
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.
|
|
313
|
+
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.
|
|
260
314
|
|
|
261
315
|
## Build from source
|
|
262
316
|
|
|
@@ -290,7 +344,7 @@ BENCH_ITERATIONS=20 npm run benchmark -- "./archive.zip"
|
|
|
290
344
|
|
|
291
345
|
It measures native open/list, prefix reads, full extraction, and reads across independent archive handles. `BENCH_ITERATIONS` defaults to 15 and must be at least 3.
|
|
292
346
|
|
|
293
|
-
Compare the native API with the `
|
|
347
|
+
Compare the native API with the `7zzc` command-line baseline from `7zip-bin-full`:
|
|
294
348
|
|
|
295
349
|
```sh
|
|
296
350
|
npm run benchmark:compare -- \
|
|
@@ -301,7 +355,7 @@ npm run benchmark:compare -- \
|
|
|
301
355
|
--concurrency 4
|
|
302
356
|
```
|
|
303
357
|
|
|
304
|
-
The comparison validates entry listings and output data before reporting median and p95 latency. CLI timings include process startup.
|
|
358
|
+
The comparison validates entry listings and output data before reporting median and p95 latency. CLI timings include process startup. Prefix reads use `-slb`; non-solid archives abort decoding per item once the byte limit is reached. For a range, the CLI emits through `offset + length` and slices stdout because it has no ranged-read API; this still needs to decode the preceding bytes. Captured output is capped at 256 MiB, and full-archive comparison is skipped if an entry exceeds that limit.
|
|
305
359
|
|
|
306
360
|
Compare extraction concurrency:
|
|
307
361
|
|
|
@@ -315,16 +369,34 @@ npm run benchmark:concurrency -- \
|
|
|
315
369
|
|
|
316
370
|
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.
|
|
317
371
|
|
|
372
|
+
Compare parallel extraction of every file in the archive, divided among promises:
|
|
373
|
+
|
|
374
|
+
```sh
|
|
375
|
+
npm run benchmark:multiprocess -- \
|
|
376
|
+
--archive "./archive.zip" \
|
|
377
|
+
--parallel-counts 1,2,4 \
|
|
378
|
+
--iterations 3
|
|
379
|
+
|
|
380
|
+
ELECTRON_RUN_AS_NODE=1 electron bench/multiprocess-extract.cjs \
|
|
381
|
+
--archive "./archive.zip" \
|
|
382
|
+
--parallel-counts 1,2,4 \
|
|
383
|
+
--iterations 3 \
|
|
384
|
+
--deflate-buffer-size 262144
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
For each parallel count, the benchmark uses `Promise.all()`: every `7zip-native` promise opens its own handle to the same archive, and every `7zip-bin-full` promise spawns one `7zzc` command. All non-directory files in the archive are divided as evenly as possible among the concurrent operations. The native extraction pool is sized to the maximum requested parallel count so native promises can run concurrently. Outputs go to separate temporary directories and are verified by file size before cleanup. The report includes `Archive.open()` and CLI startup time. Native operations stay in the benchmark's Node/Electron process; only the CLI baseline spawns child processes.
|
|
388
|
+
|
|
318
389
|
Compare `extractToFolder()` concurrency (1 through 16) across one or more archives:
|
|
319
390
|
|
|
320
391
|
```sh
|
|
321
392
|
npm run benchmark:folder-concurrency -- \
|
|
322
393
|
--archive "./samples/sample.zip" \
|
|
323
394
|
--archive "./archive.7z" \
|
|
395
|
+
--concurrencies 1,2,3,4,5,8,16 \
|
|
324
396
|
--iterations 1
|
|
325
397
|
```
|
|
326
398
|
|
|
327
|
-
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.
|
|
399
|
+
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.
|
|
328
400
|
|
|
329
401
|
## License
|
|
330
402
|
|
package/bench/compare.mts
CHANGED
|
@@ -35,12 +35,12 @@ if(!Number.isSafeInteger(parallelConcurrency) || parallelConcurrency < 1 || para
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const require = createRequire(import.meta.url);
|
|
38
|
-
const binaryPackage = require('7zip-bin-full') as {
|
|
39
|
-
if(typeof binaryPackage.
|
|
38
|
+
const binaryPackage = require('7zip-bin-full') as {path7zc?: unknown};
|
|
39
|
+
if(typeof binaryPackage.path7zc !== 'string')
|
|
40
40
|
{
|
|
41
|
-
throw new TypeError('7zip-bin-full does not provide a
|
|
41
|
+
throw new TypeError('7zip-bin-full does not provide a path7zc binary for this platform');
|
|
42
42
|
}
|
|
43
|
-
const binaryPath = binaryPackage.
|
|
43
|
+
const binaryPath = binaryPackage.path7zc;
|
|
44
44
|
|
|
45
45
|
function runCli(args: readonly string[], outputLimit = maxCapturedBytes): Promise<Buffer>
|
|
46
46
|
{
|
|
@@ -142,10 +142,18 @@ function cliList(): Promise<CliEntry[]>
|
|
|
142
142
|
return runCli(['l', '-slt', '-sccUTF-8', archivePath]).then(parseCliEntries);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
function cliExtract(
|
|
145
|
+
function cliExtract(
|
|
146
|
+
paths: readonly string[],
|
|
147
|
+
outputLimit = maxCapturedBytes,
|
|
148
|
+
byteLimit?: number,
|
|
149
|
+
): Promise<Buffer>
|
|
146
150
|
{
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
const args = ['x'];
|
|
152
|
+
if(byteLimit !== undefined)
|
|
153
|
+
{
|
|
154
|
+
args.push(`-slb${byteLimit}`);
|
|
155
|
+
}
|
|
156
|
+
args.push(
|
|
149
157
|
archivePath,
|
|
150
158
|
...paths,
|
|
151
159
|
'-so',
|
|
@@ -154,7 +162,8 @@ function cliExtract(paths: readonly string[], outputLimit = maxCapturedBytes): P
|
|
|
154
162
|
'-bb0',
|
|
155
163
|
'-spd',
|
|
156
164
|
'-sccUTF-8',
|
|
157
|
-
|
|
165
|
+
);
|
|
166
|
+
return runCli(args, outputLimit);
|
|
158
167
|
}
|
|
159
168
|
|
|
160
169
|
function isGroupedExtractionResult(value: BenchmarkResult): value is GroupedExtractionResult
|
|
@@ -502,7 +511,7 @@ try
|
|
|
502
511
|
));
|
|
503
512
|
}
|
|
504
513
|
|
|
505
|
-
const rangeNote = '
|
|
514
|
+
const rangeNote = '7zzc uses -slb; non-solid archives abort per item, while ranges emit through offset + length and slice stdout';
|
|
506
515
|
for(const [name, offset, length] of [
|
|
507
516
|
['read_prefix', 0n, prefixLength],
|
|
508
517
|
['read_range_at_one_third', rangeOffset, rangeLength],
|
|
@@ -515,8 +524,13 @@ try
|
|
|
515
524
|
}
|
|
516
525
|
const nativeRead = () => archive.read(file.id, {offset, length});
|
|
517
526
|
const cliRead = async () => {
|
|
518
|
-
|
|
519
|
-
|
|
527
|
+
if(length === 0n)
|
|
528
|
+
{
|
|
529
|
+
return Buffer.alloc(0);
|
|
530
|
+
}
|
|
531
|
+
const limit = Number(offset + length);
|
|
532
|
+
const output = await cliExtract([file.path], limit, limit);
|
|
533
|
+
return output.subarray(Number(offset), limit);
|
|
520
534
|
};
|
|
521
535
|
results.push(await measurePair(name, nativeRead, cliRead));
|
|
522
536
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {mkdtemp, rm, stat} from 'node:fs/promises';
|
|
2
2
|
import {tmpdir} from 'node:os';
|
|
3
3
|
import {join, resolve} from 'node:path';
|
|
4
|
-
import {Archive
|
|
4
|
+
import {Archive} from '../dist/index.mjs';
|
|
5
5
|
|
|
6
|
-
const usage = 'npm run benchmark:folder-concurrency -- --archive <path> [--archive <path> ...] [--iterations <count>]';
|
|
6
|
+
const usage = 'npm run benchmark:folder-concurrency -- --archive <path> [--archive <path> ...] [--iterations <count>] [--concurrency <workers> | --concurrencies <workers,...>]';
|
|
7
7
|
const archivePaths: string[] = [];
|
|
8
8
|
let iterations = 1;
|
|
9
|
+
let concurrencyOption: string | undefined;
|
|
10
|
+
let concurrenciesOption: string | undefined;
|
|
9
11
|
const args = process.argv.slice(2);
|
|
10
12
|
for(let index = 0; index < args.length; index++)
|
|
11
13
|
{
|
|
@@ -32,6 +34,34 @@ for(let index = 0; index < args.length; index++)
|
|
|
32
34
|
iterations = Number(value);
|
|
33
35
|
continue;
|
|
34
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
|
+
}
|
|
35
65
|
throw new TypeError(`Unknown argument ${argument}\nUsage: ${usage}`);
|
|
36
66
|
}
|
|
37
67
|
|
|
@@ -43,8 +73,27 @@ if(!Number.isSafeInteger(iterations) || iterations < 1)
|
|
|
43
73
|
{
|
|
44
74
|
throw new RangeError('--iterations must be a positive integer');
|
|
45
75
|
}
|
|
76
|
+
if(concurrencyOption !== undefined && concurrenciesOption !== undefined)
|
|
77
|
+
{
|
|
78
|
+
throw new TypeError('Use either --concurrency or --concurrencies, not both');
|
|
79
|
+
}
|
|
46
80
|
|
|
47
|
-
|
|
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])];
|
|
48
97
|
const originalConcurrency = Archive.concurrency();
|
|
49
98
|
const archiveResults = [];
|
|
50
99
|
try
|
|
@@ -70,27 +119,20 @@ try
|
|
|
70
119
|
for(let iteration = 0; iteration < iterations; iteration++)
|
|
71
120
|
{
|
|
72
121
|
const temporaryDirectory = await mkdtemp(join(tmpdir(), '7zip-native-folder-bench-'));
|
|
73
|
-
let
|
|
122
|
+
let finalPercent = 0;
|
|
74
123
|
let completedFiles = 0;
|
|
75
124
|
try
|
|
76
125
|
{
|
|
77
126
|
const start = process.hrtime.bigint();
|
|
78
127
|
await archive.extractToFolder(join(temporaryDirectory, 'output'), {
|
|
79
128
|
concurrency,
|
|
80
|
-
|
|
81
|
-
finalProgress = progress;
|
|
82
|
-
},
|
|
83
|
-
onExtract: () => {
|
|
129
|
+
onExtract: ({percent}) => {
|
|
84
130
|
completedFiles++;
|
|
131
|
+
finalPercent = percent;
|
|
85
132
|
},
|
|
86
133
|
});
|
|
87
134
|
durations.push(Number(process.hrtime.bigint() - start) / 1e6);
|
|
88
|
-
if(
|
|
89
|
-
|| finalProgress.filesExtracted !== files.length
|
|
90
|
-
|| finalProgress.totalFiles !== files.length
|
|
91
|
-
|| finalProgress.bytesProcessed !== expectedBytes
|
|
92
|
-
|| finalProgress.totalBytes !== expectedBytes
|
|
93
|
-
|| completedFiles !== files.length)
|
|
135
|
+
if(completedFiles !== files.length || finalPercent !== 100)
|
|
94
136
|
{
|
|
95
137
|
throw new Error(`Extraction verification failed for ${archivePath} at concurrency ${concurrency}`);
|
|
96
138
|
}
|