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.
Files changed (317) hide show
  1. package/README.md +96 -24
  2. package/bench/compare.mts +25 -11
  3. package/bench/folder-concurrency.mts +56 -14
  4. package/bench/multiprocess-extract.cjs +334 -0
  5. package/dist/index.cjs +194 -102
  6. package/dist/index.d.cts +10 -9
  7. package/dist/index.d.mts +10 -9
  8. package/dist/index.d.ts +10 -9
  9. package/dist/index.mjs +196 -104
  10. package/native/addon.cpp +1399 -71
  11. package/package.json +5 -3
  12. package/patches/deflate-input-buffer-size.patch +47 -0
  13. package/prebuilds/darwin-arm64/7zip_native.node +0 -0
  14. package/prebuilds/darwin-arm64/lib7z.dylib +0 -0
  15. package/prebuilds/darwin-x64/7zip_native.node +0 -0
  16. package/prebuilds/darwin-x64/lib7z.dylib +0 -0
  17. package/prebuilds/linux-arm/7z.so +0 -0
  18. package/prebuilds/linux-arm/7zip_native.node +0 -0
  19. package/prebuilds/linux-arm64/7z.so +0 -0
  20. package/prebuilds/linux-arm64/7zip_native.node +0 -0
  21. package/prebuilds/linux-ia32/7z.so +0 -0
  22. package/prebuilds/linux-ia32/7zip_native.node +0 -0
  23. package/prebuilds/linux-x64/7z.so +0 -0
  24. package/prebuilds/linux-x64/7zip_native.node +0 -0
  25. package/prebuilds/win32-arm64/7z.dll +0 -0
  26. package/prebuilds/win32-arm64/7zip_native.node +0 -0
  27. package/prebuilds/win32-x64/7z.dll +0 -0
  28. package/prebuilds/win32-x64/7zip_native.node +0 -0
  29. package/scripts/build-native.mjs +22 -1
  30. package/vendor/7zip/CPP/7zip/Archive/Archive2.def +1 -0
  31. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7z.so +0 -0
  32. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zAes.o +0 -0
  33. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zAesRegister.o +0 -0
  34. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zBuf2.o +0 -0
  35. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCompressionMode.o +0 -0
  36. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCrc.o +0 -0
  37. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zCrcOpt.o +0 -0
  38. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zDecode.o +0 -0
  39. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zEncode.o +0 -0
  40. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zExtract.o +0 -0
  41. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zFolderInStream.o +0 -0
  42. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHandler.o +0 -0
  43. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHandlerOut.o +0 -0
  44. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zHeader.o +0 -0
  45. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zIn.o +0 -0
  46. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zOut.o +0 -0
  47. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zProperties.o +0 -0
  48. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zRegister.o +0 -0
  49. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zSpecStream.o +0 -0
  50. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zStream.o +0 -0
  51. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/7zUpdate.o +0 -0
  52. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Aes.o +0 -0
  53. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/AesOpt.o +0 -0
  54. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Alloc.o +0 -0
  55. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ApfsHandler.o +0 -0
  56. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ApmHandler.o +0 -0
  57. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArHandler.o +0 -0
  58. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArchiveExports.o +0 -0
  59. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ArjHandler.o +0 -0
  60. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Crc.o +0 -0
  61. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Decoder.o +0 -0
  62. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Encoder.o +0 -0
  63. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BZip2Register.o +0 -0
  64. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Base64Handler.o +0 -0
  65. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2.o +0 -0
  66. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Coder.o +0 -0
  67. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Enc.o +0 -0
  68. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bcj2Register.o +0 -0
  69. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BcjCoder.o +0 -0
  70. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BcjRegister.o +0 -0
  71. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BitlDecoder.o +0 -0
  72. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Blake2s.o +0 -0
  73. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bra.o +0 -0
  74. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bra86.o +0 -0
  75. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BraIA64.o +0 -0
  76. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BranchMisc.o +0 -0
  77. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BranchRegister.o +0 -0
  78. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/BwtSort.o +0 -0
  79. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ByteSwap.o +0 -0
  80. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Bz2Handler.o +0 -0
  81. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CRC.o +0 -0
  82. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CWrappers.o +0 -0
  83. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabBlockInStream.o +0 -0
  84. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabHandler.o +0 -0
  85. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabHeader.o +0 -0
  86. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabIn.o +0 -0
  87. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CabRegister.o +0 -0
  88. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ChmHandler.o +0 -0
  89. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ChmIn.o +0 -0
  90. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CodecExports.o +0 -0
  91. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CoderMixer2.o +0 -0
  92. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ComHandler.o +0 -0
  93. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CopyCoder.o +0 -0
  94. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CopyRegister.o +0 -0
  95. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CpioHandler.o +0 -0
  96. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CpuArch.o +0 -0
  97. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CramfsHandler.o +0 -0
  98. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CrcReg.o +0 -0
  99. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/CreateCoder.o +0 -0
  100. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Deflate64Register.o +0 -0
  101. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateDecoder.o +0 -0
  102. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateEncoder.o +0 -0
  103. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateProps.o +0 -0
  104. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeflateRegister.o +0 -0
  105. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Delta.o +0 -0
  106. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DeltaFilter.o +0 -0
  107. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DllExports2.o +0 -0
  108. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DmgHandler.o +0 -0
  109. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DummyOutStream.o +0 -0
  110. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/DynLimBuf.o +0 -0
  111. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ElfHandler.o +0 -0
  112. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ExtHandler.o +0 -0
  113. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FatHandler.o +0 -0
  114. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileDir.o +0 -0
  115. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileFind.o +0 -0
  116. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileIO.o +0 -0
  117. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FileName.o +0 -0
  118. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FilterCoder.o +0 -0
  119. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FindSignature.o +0 -0
  120. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/FlvHandler.o +0 -0
  121. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/GptHandler.o +0 -0
  122. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/GzHandler.o +0 -0
  123. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HandlerCont.o +0 -0
  124. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HandlerOut.o +0 -0
  125. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HfsHandler.o +0 -0
  126. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HmacSha1.o +0 -0
  127. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HmacSha256.o +0 -0
  128. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/HuffEnc.o +0 -0
  129. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IhexHandler.o +0 -0
  130. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ImplodeDecoder.o +0 -0
  131. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InBuffer.o +0 -0
  132. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InOutTempBuffer.o +0 -0
  133. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/InStreamWithCRC.o +0 -0
  134. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IntToString.o +0 -0
  135. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoHandler.o +0 -0
  136. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoHeader.o +0 -0
  137. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoIn.o +0 -0
  138. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/IsoRegister.o +0 -0
  139. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ItemNameUtils.o +0 -0
  140. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LimitedStreams.o +0 -0
  141. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LockedStream.o +0 -0
  142. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LpHandler.o +0 -0
  143. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFind.o +0 -0
  144. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindMt.o +0 -0
  145. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindOpt.o +0 -0
  146. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzFindPrepare.o +0 -0
  147. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzOutWindow.o +0 -0
  148. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzfseDecoder.o +0 -0
  149. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzhDecoder.o +0 -0
  150. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzhHandler.o +0 -0
  151. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Dec.o +0 -0
  152. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2DecMt.o +0 -0
  153. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Decoder.o +0 -0
  154. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Enc.o +0 -0
  155. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Encoder.o +0 -0
  156. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Lzma2Register.o +0 -0
  157. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaDec.o +0 -0
  158. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaDecoder.o +0 -0
  159. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaEnc.o +0 -0
  160. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaEncoder.o +0 -0
  161. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaHandler.o +0 -0
  162. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmaRegister.o +0 -0
  163. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzmsDecoder.o +0 -0
  164. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/LzxDecoder.o +0 -0
  165. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MachoHandler.o +0 -0
  166. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MbrHandler.o +0 -0
  167. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Md5.o +0 -0
  168. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Md5Reg.o +0 -0
  169. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MemBlocks.o +0 -0
  170. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MethodId.o +0 -0
  171. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MethodProps.o +0 -0
  172. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MslzHandler.o +0 -0
  173. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MtCoder.o +0 -0
  174. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MtDec.o +0 -0
  175. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MubHandler.o +0 -0
  176. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MultiStream.o +0 -0
  177. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyAes.o +0 -0
  178. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyAesReg.o +0 -0
  179. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyMap.o +0 -0
  180. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyString.o +0 -0
  181. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyVector.o +0 -0
  182. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyWindows.o +0 -0
  183. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/MyXml.o +0 -0
  184. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NewHandler.o +0 -0
  185. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisDecode.o +0 -0
  186. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisHandler.o +0 -0
  187. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisIn.o +0 -0
  188. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NsisRegister.o +0 -0
  189. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/NtfsHandler.o +0 -0
  190. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OffsetStream.o +0 -0
  191. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutBuffer.o +0 -0
  192. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutMemStream.o +0 -0
  193. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutStreamWithCRC.o +0 -0
  194. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/OutStreamWithSha1.o +0 -0
  195. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ParseProperties.o +0 -0
  196. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Pbkdf2HmacSha1.o +0 -0
  197. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PeHandler.o +0 -0
  198. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7.o +0 -0
  199. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7Dec.o +0 -0
  200. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7Enc.o +0 -0
  201. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd7aDec.o +0 -0
  202. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8.o +0 -0
  203. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8Dec.o +0 -0
  204. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Ppmd8Enc.o +0 -0
  205. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdDecoder.o +0 -0
  206. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdEncoder.o +0 -0
  207. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdHandler.o +0 -0
  208. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdRegister.o +0 -0
  209. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PpmdZip.o +0 -0
  210. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ProgressMt.o +0 -0
  211. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ProgressUtils.o +0 -0
  212. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropId.o +0 -0
  213. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariant.o +0 -0
  214. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariantConv.o +0 -0
  215. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/PropVariantUtils.o +0 -0
  216. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/QcowHandler.o +0 -0
  217. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/QuantumDecoder.o +0 -0
  218. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RandGen.o +0 -0
  219. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar1Decoder.o +0 -0
  220. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar20Crypto.o +0 -0
  221. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar2Decoder.o +0 -0
  222. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar3Decoder.o +0 -0
  223. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar3Vm.o +0 -0
  224. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Aes.o +0 -0
  225. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Decoder.o +0 -0
  226. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Rar5Handler.o +0 -0
  227. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarAes.o +0 -0
  228. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarCodecsRegister.o +0 -0
  229. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RarHandler.o +0 -0
  230. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/RpmHandler.o +0 -0
  231. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1.o +0 -0
  232. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Opt.o +0 -0
  233. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Prepare.o +0 -0
  234. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha1Reg.o +0 -0
  235. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256.o +0 -0
  236. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Opt.o +0 -0
  237. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Prepare.o +0 -0
  238. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha256Reg.o +0 -0
  239. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha3.o +0 -0
  240. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha3Reg.o +0 -0
  241. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512.o +0 -0
  242. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Opt.o +0 -0
  243. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Prepare.o +0 -0
  244. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sha512Reg.o +0 -0
  245. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ShrinkDecoder.o +0 -0
  246. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Sort.o +0 -0
  247. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SparseHandler.o +0 -0
  248. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SplitHandler.o +0 -0
  249. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SquashfsHandler.o +0 -0
  250. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamBinder.o +0 -0
  251. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamObjects.o +0 -0
  252. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StreamUtils.o +0 -0
  253. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StringConvert.o +0 -0
  254. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/StringToInt.o +0 -0
  255. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SwapBytes.o +0 -0
  256. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/SwfHandler.o +0 -0
  257. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Synchronization.o +0 -0
  258. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/System.o +0 -0
  259. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHandler.o +0 -0
  260. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHandlerOut.o +0 -0
  261. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarHeader.o +0 -0
  262. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarIn.o +0 -0
  263. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarOut.o +0 -0
  264. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarRegister.o +0 -0
  265. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TarUpdate.o +0 -0
  266. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Threads.o +0 -0
  267. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/TimeUtils.o +0 -0
  268. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UTFConvert.o +0 -0
  269. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UdfHandler.o +0 -0
  270. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UdfIn.o +0 -0
  271. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UefiHandler.o +0 -0
  272. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/UniqBlocks.o +0 -0
  273. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VdiHandler.o +0 -0
  274. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VhdHandler.o +0 -0
  275. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VhdxHandler.o +0 -0
  276. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VirtThread.o +0 -0
  277. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/VmdkHandler.o +0 -0
  278. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Wildcard.o +0 -0
  279. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimHandler.o +0 -0
  280. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimHandlerOut.o +0 -0
  281. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimIn.o +0 -0
  282. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WimRegister.o +0 -0
  283. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/WzAes.o +0 -0
  284. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XarHandler.o +0 -0
  285. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XpressDecoder.o +0 -0
  286. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xxh64.o +0 -0
  287. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xxh64Reg.o +0 -0
  288. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/Xz.o +0 -0
  289. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64.o +0 -0
  290. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Init.o +0 -0
  291. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Opt.o +0 -0
  292. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzCrc64Reg.o +0 -0
  293. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzDec.o +0 -0
  294. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzDecoder.o +0 -0
  295. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzEnc.o +0 -0
  296. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzEncoder.o +0 -0
  297. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzHandler.o +0 -0
  298. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/XzIn.o +0 -0
  299. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZDecoder.o +0 -0
  300. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZHandler.o +0 -0
  301. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipAddCommon.o +0 -0
  302. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipCrypto.o +0 -0
  303. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipHandler.o +0 -0
  304. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipHandlerOut.o +0 -0
  305. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipIn.o +0 -0
  306. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipItem.o +0 -0
  307. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipOut.o +0 -0
  308. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipRegister.o +0 -0
  309. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipStrong.o +0 -0
  310. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZipUpdate.o +0 -0
  311. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZlibDecoder.o +0 -0
  312. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZlibEncoder.o +0 -0
  313. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdDec.o +0 -0
  314. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdDecoder.o +0 -0
  315. package/vendor/7zip/CPP/7zip/Bundles/Format7zF/_o/ZstdHandler.o +0 -0
  316. package/vendor/7zip/CPP/7zip/Compress/DeflateDecoder.cpp +15 -1
  317. 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('./comics.cbz');
26
+ const archive = await Archive.open('./file.zip');
27
27
 
28
28
  try
29
29
  {
30
30
  const entries = await archive.entries();
31
- const cover = await archive.getEntry('chapter/cover.jpg');
31
+ const file = await archive.getEntry('image.jpg');
32
32
 
33
- if(cover && !cover.isDirectory)
33
+ if(file && !file.isDirectory)
34
34
  {
35
- const preview = await archive.read(cover.path, {offset: 0, length: 64 * 1024});
36
- const image = await archive.extract(cover.path);
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
- `options.password` is passed to the upstream handler when 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.
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
- Offsets and lengths accept safe integers or `bigint`. A range read returns only the requested bytes and is limited to 64 MiB. 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.
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
- 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. Streams default to a 4 GiB output limit; set `maxBytes` to another non-negative `number` or `bigint`, or to `null` to disable the limit.
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
- This respects backpressure and ends the destination when extraction succeeds. A destination error, early close, or abort rejects the Promise.
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('./comic.cbz', [
146
- {sourcePath: './pages/cover.jpg', path: 'cover.jpg'},
147
- {sourcePath: './pages/01.jpg', path: 'pages/01.jpg'},
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. It infers ZIP from `.zip` or `.cbz`, 7z from `.7z`, TAR from `.tar`, and WIM from `.wim`; set `format: 'zip'`, `'7z'`, `'tar'`, or `'wim'` to use another output extension. Compression level is an 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. Duplicate, unsafe, or conflicting internal paths are rejected. The output is first written to a temporary file beside the destination, then installed atomically; an existing file is preserved unless `overwrite: true` is specified. Archive creation runs in the bounded native worker pool and does not launch a 7-Zip executable.
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
- onProgress: ({filesExtracted, totalFiles, bytesProcessed, totalBytes, percent}) => {
164
- console.log(`${filesExtracted}/${totalFiles} files, ${percent}% (${bytesProcessed}/${totalBytes} bytes)`);
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
- Folder extraction accepts either `ids` or exact, original archive `paths`; omit both to extract every entry, and do not provide both together. Paths use archive-internal `/` separators. `concurrency` sets the maximum number of files extracted simultaneously by this call; it must be an integer from 1 to 128, defaults to 1, and is capped at the process-wide native worker-pool concurrency. It does not change `Archive.concurrency()`. Extraction uses bounded memory and a bounded scheduler rather than queueing one promise per entry. Its default total output limit is 4 GiB; `maxBytes: null` disables that limit. Set `onProgress` to receive the number of regular files selected and fully extracted, the bytes emitted so far across active files, the total uncompressed bytes, and the calculated percentage. It is called before extraction, as data chunks are processed, and after each file completes. `onExtract` is called once per regular file after it is fully written; with `overwrite: true`, it runs after the final replacement. Its `entry` retains the original archive metadata and `outputPath` is the final destination path. On Windows only, invalid filename characters (`< > : | ? * "`) and trailing dots/spaces in each output component are replaced with `_`; selectors and entry metadata remain unchanged. By default, existing files are not overwritten; set `overwrite: true` to replace existing regular files. Replacement is committed only after that entry has been fully extracted, using a temporary file alongside the destination so a failure does not truncate the existing file. This can temporarily require extra disk space up to the size of the entry being replaced. Symlink or non-file targets are rejected. Unsafe archive paths, path collisions, and symlinked destination components are also 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.
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
- The setting controls the process-wide native worker pool used by extraction, streams, and range reads. The default is the lesser of 4 and the parallelism available to Node.js; the allowed range is 1–128 workers, with `0` restoring the default.
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 `7zip-bin-full` command-line baseline:
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. Since the CLI has no ranged-read API, its range baseline extracts the entry to stdout and slices the requested bytes; this is not equivalent to native range reading. Captured output is capped at 256 MiB, and full-archive comparison is skipped if an entry exceeds that limit.
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 {path7z?: unknown};
39
- if(typeof binaryPackage.path7z !== 'string')
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 path7z binary for this platform');
41
+ throw new TypeError('7zip-bin-full does not provide a path7zc binary for this platform');
42
42
  }
43
- const binaryPath = binaryPackage.path7z;
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(paths: readonly string[], outputLimit = maxCapturedBytes): Promise<Buffer>
145
+ function cliExtract(
146
+ paths: readonly string[],
147
+ outputLimit = maxCapturedBytes,
148
+ byteLimit?: number,
149
+ ): Promise<Buffer>
146
150
  {
147
- return runCli([
148
- 'x',
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
- ], outputLimit);
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 = '7zip-bin-full decompresses the whole entry and slices stdout; it has no ranged-read API';
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
- const full = await cliExtract([file.path], Number(file.size));
519
- return full.subarray(Number(offset), Number(offset + length));
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, type ExtractToFolderProgress} from '../dist/index.mjs';
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
- const concurrencies = Array.from({length: 16}, (_, index) => index + 1);
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 finalProgress: ExtractToFolderProgress | undefined;
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
- onProgress: progress => {
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(!finalProgress
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
  }