7zip-native 0.0.6 → 0.0.8

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