@futpib/parser 1.0.1 → 1.0.3

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 (425) hide show
  1. package/.github/copilot-instructions.md +149 -0
  2. package/.github/workflows/copilot-setup-steps.yml +18 -0
  3. package/.github/workflows/main.yml +29 -8
  4. package/.yarn/releases/yarn-4.9.4.cjs +942 -0
  5. package/.yarnrc.yml +1 -1
  6. package/build/allSettledStream.js +32 -14
  7. package/build/allSettledStream.test.js +32 -0
  8. package/build/androidPackage.d.ts +39 -0
  9. package/build/androidPackageParser.d.ts +17 -0
  10. package/build/androidPackageParser.js +185 -0
  11. package/build/androidPackageParser.test.js +22 -0
  12. package/build/androidPackageUnparser.d.ts +4 -0
  13. package/build/androidPackageUnparser.js +94 -0
  14. package/build/androidPackageUnparser.test.js +26 -0
  15. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  16. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  17. package/build/arbitrarilySlicedAsyncInterator.js +2 -1
  18. package/build/arbitraryDalvikBytecode.d.ts +4 -0
  19. package/build/arbitraryDalvikBytecode.js +640 -0
  20. package/build/arbitraryDalvikExecutable.d.ts +3 -0
  21. package/build/arbitraryDalvikExecutable.js +282 -0
  22. package/build/arbitraryDosDateTime.js +1 -0
  23. package/build/arbitraryZipStream.js +1 -1
  24. package/build/arrayParser.js +2 -2
  25. package/build/arrayParser.test.js +3 -3
  26. package/build/arrayUnparser.d.ts +1 -1
  27. package/build/backsmali.d.ts +3 -0
  28. package/build/backsmali.js +50 -0
  29. package/build/bsonParser.js +6 -2
  30. package/build/customInvariant.d.ts +2 -1
  31. package/build/customInvariant.js +4 -6
  32. package/build/dalvikBytecodeParser/formatParsers.d.ts +171 -0
  33. package/build/dalvikBytecodeParser/formatParsers.js +304 -0
  34. package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
  35. package/build/dalvikBytecodeParser/formatSizes.js +34 -0
  36. package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
  37. package/build/dalvikBytecodeParser/operationFormats.js +225 -0
  38. package/build/dalvikBytecodeParser.d.ts +1207 -0
  39. package/build/dalvikBytecodeParser.js +1289 -0
  40. package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
  41. package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
  42. package/build/dalvikBytecodeUnparser.d.ts +3 -0
  43. package/build/dalvikBytecodeUnparser.js +642 -0
  44. package/build/dalvikBytecodeUnparser.test.js +25 -0
  45. package/build/dalvikExecutable.d.ts +215 -0
  46. package/build/dalvikExecutable.js +56 -0
  47. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  48. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  49. package/build/dalvikExecutableParser/typeParsers.d.ts +11 -0
  50. package/build/dalvikExecutableParser/typeParsers.js +39 -0
  51. package/build/dalvikExecutableParser/typedNumbers.d.ts +106 -0
  52. package/build/dalvikExecutableParser/typedNumbers.js +18 -0
  53. package/build/dalvikExecutableParser.d.ts +5 -0
  54. package/build/dalvikExecutableParser.js +1757 -0
  55. package/build/dalvikExecutableParser.test.js +72 -0
  56. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +275 -0
  57. package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
  58. package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
  59. package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
  60. package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
  61. package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
  62. package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
  63. package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
  64. package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
  65. package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
  66. package/build/dalvikExecutableUnparser/utils.js +108 -0
  67. package/build/dalvikExecutableUnparser.d.ts +4 -0
  68. package/build/dalvikExecutableUnparser.js +406 -0
  69. package/build/dalvikExecutableUnparser.test.js +31 -0
  70. package/build/debugLogInputParser.d.ts +4 -0
  71. package/build/debugLogInputParser.js +16 -0
  72. package/build/debugLogParser.js +14 -3
  73. package/build/disjunctionParser.d.ts +2 -1
  74. package/build/disjunctionParser.js +6 -4
  75. package/build/elementTerminatedArrayParser.d.ts +3 -0
  76. package/build/elementTerminatedArrayParser.js +18 -0
  77. package/build/elementTerminatedArrayParser.test.js +52 -0
  78. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  79. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  80. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  81. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  82. package/build/elementTerminatedSequenceParser.js +27 -0
  83. package/build/elementTerminatedSequenceParser.test.js +34 -0
  84. package/build/endOfInputParser.d.ts +1 -1
  85. package/build/exactElementParser.js +10 -5
  86. package/build/exactElementSwitchParser.d.ts +3 -0
  87. package/build/exactElementSwitchParser.js +22 -0
  88. package/build/exactSequenceParser.d.ts +2 -1
  89. package/build/exactSequenceParser.js +12 -2
  90. package/build/fetchCid.d.ts +1 -0
  91. package/build/fetchCid.js +103 -0
  92. package/build/fetchCid.test.js +16 -0
  93. package/build/fixedLengthSequenceParser.d.ts +1 -0
  94. package/build/fixedLengthSequenceParser.js +18 -1
  95. package/build/fixedLengthSequenceParser.test.js +41 -0
  96. package/build/hasExecutable.d.ts +1 -0
  97. package/build/hasExecutable.js +8 -0
  98. package/build/highResolutionTimer.d.ts +16 -0
  99. package/build/highResolutionTimer.js +42 -0
  100. package/build/inputReader.d.ts +11 -0
  101. package/build/inputReader.js +37 -0
  102. package/build/inputReader.test.js +161 -8
  103. package/build/inputReaderState.d.ts +10 -0
  104. package/build/inputReaderState.js +16 -0
  105. package/build/inspect.d.ts +1 -0
  106. package/build/inspect.js +7 -0
  107. package/build/javaKeyStoreParser.test.js +8 -8
  108. package/build/jsonParser.d.ts +2 -0
  109. package/build/jsonParser.js +19 -22
  110. package/build/lazyMessageError.d.ts +48 -0
  111. package/build/lazyMessageError.js +53 -0
  112. package/build/lazyMessageError.test.d.ts +1 -0
  113. package/build/lazyMessageError.test.js +15 -0
  114. package/build/leb128Parser.d.ts +7 -0
  115. package/build/leb128Parser.js +82 -0
  116. package/build/leb128Parser.test.d.ts +1 -0
  117. package/build/leb128Parser.test.js +107 -0
  118. package/build/lookaheadParser.d.ts +2 -0
  119. package/build/lookaheadParser.js +14 -0
  120. package/build/negativeLookaheadParser.js +22 -16
  121. package/build/negativeLookaheadParser.test.d.ts +1 -0
  122. package/build/negativeLookaheadParser.test.js +30 -0
  123. package/build/noStackCaptureOverheadError.d.ts +4 -0
  124. package/build/noStackCaptureOverheadError.js +9 -0
  125. package/build/noStackCaptureOverheadError.test.d.ts +1 -0
  126. package/build/noStackCaptureOverheadError.test.js +15 -0
  127. package/build/nonEmptyArrayParser.d.ts +2 -0
  128. package/build/nonEmptyArrayParser.js +32 -0
  129. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  130. package/build/nonEmptyArrayParser.test.js +17 -0
  131. package/build/optionalParser.js +2 -2
  132. package/build/parser.d.ts +11 -1
  133. package/build/parser.js +82 -32
  134. package/build/parser.test.js +141 -25
  135. package/build/parserAccessorParser.js +9 -1
  136. package/build/parserConsumedSequenceParser.d.ts +1 -1
  137. package/build/parserConsumedSequenceParser.js +21 -16
  138. package/build/parserContext.d.ts +22 -6
  139. package/build/parserContext.js +113 -57
  140. package/build/parserContext.test.js +33 -2
  141. package/build/parserCreatorCompose.d.ts +1 -0
  142. package/build/parserCreatorCompose.js +8 -2
  143. package/build/parserError.d.ts +605 -40
  144. package/build/parserError.js +98 -53
  145. package/build/parserImplementationInvariant.d.ts +1 -1
  146. package/build/parserImplementationInvariant.js +2 -2
  147. package/build/parserInputCompanion.d.ts +15 -0
  148. package/build/parserInputCompanion.js +38 -0
  149. package/build/promiseCompose.d.ts +1 -1
  150. package/build/promiseCompose.js +11 -1
  151. package/build/promiseSettled.d.ts +1 -0
  152. package/build/promiseSettled.js +4 -0
  153. package/build/separatedArrayParser.d.ts +2 -0
  154. package/build/separatedArrayParser.js +39 -0
  155. package/build/separatedArrayParser.test.d.ts +1 -0
  156. package/build/separatedArrayParser.test.js +21 -0
  157. package/build/separatedNonEmptyArrayParser.d.ts +2 -0
  158. package/build/separatedNonEmptyArrayParser.js +40 -0
  159. package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
  160. package/build/separatedNonEmptyArrayParser.test.js +66 -0
  161. package/build/sequenceBuffer.d.ts +10 -0
  162. package/build/sequenceBuffer.js +54 -2
  163. package/build/sequenceBuffer.test.js +57 -0
  164. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  165. package/build/sequenceTerminatedSequenceParser.js +32 -0
  166. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  167. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  168. package/build/sequenceUnparser.d.ts +1 -1
  169. package/build/skipParser.d.ts +1 -1
  170. package/build/skipParser.js +4 -2
  171. package/build/skipToParser.d.ts +2 -0
  172. package/build/skipToParser.js +11 -0
  173. package/build/sliceBoundedParser.d.ts +1 -1
  174. package/build/sliceBoundedParser.js +7 -2
  175. package/build/sliceBoundedParser.test.js +30 -1
  176. package/build/smali.d.ts +1 -0
  177. package/build/smali.js +21 -0
  178. package/build/smaliParser.d.ts +68 -0
  179. package/build/smaliParser.js +2081 -0
  180. package/build/smaliParser.test.d.ts +1 -0
  181. package/build/smaliParser.test.js +410 -0
  182. package/build/stringFromAsyncIterable.d.ts +1 -0
  183. package/build/stringFromAsyncIterable.js +7 -0
  184. package/build/terminatedArrayParser.d.ts +3 -1
  185. package/build/terminatedArrayParser.js +79 -2
  186. package/build/terminatedArrayParser.test.d.ts +1 -0
  187. package/build/terminatedArrayParser.test.js +131 -0
  188. package/build/toAsyncIterable.d.ts +1 -0
  189. package/build/toAsyncIterable.js +7 -0
  190. package/build/toAsyncIterator.d.ts +1 -0
  191. package/build/toAsyncIterator.js +33 -0
  192. package/build/tupleParser.d.ts +4 -0
  193. package/build/tupleParser.js +1 -5
  194. package/build/unionParser.d.ts +2 -1
  195. package/build/unionParser.js +29 -14
  196. package/build/unionParser.test.d.ts +1 -0
  197. package/build/unionParser.test.js +60 -0
  198. package/build/unparser.d.ts +3 -3
  199. package/build/unparser.js +6 -4
  200. package/build/unparser.test.js +7 -19
  201. package/build/unparserContext.d.ts +2 -2
  202. package/build/unparserContext.js +2 -3
  203. package/build/unparserError.d.ts +2 -1
  204. package/build/unparserError.js +2 -1
  205. package/build/unparserImplementationInvariant.d.ts +1 -1
  206. package/build/unparserOutputCompanion.d.ts +1 -1
  207. package/build/unparserOutputCompanion.js +1 -1
  208. package/build/zipParser.d.ts +7 -2
  209. package/build/zipParser.js +36 -12
  210. package/build/zipUnparser.d.ts +7 -4
  211. package/build/zipUnparser.js +64 -45
  212. package/build/zipUnparser.test.js +15 -15
  213. package/package.json +33 -24
  214. package/src/allSettledStream.test.ts +40 -0
  215. package/src/allSettledStream.ts +47 -15
  216. package/src/androidPackage.ts +48 -0
  217. package/src/androidPackageParser.test.ts +27 -0
  218. package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
  219. package/src/androidPackageParser.test.ts.snap +0 -0
  220. package/src/androidPackageParser.ts +398 -0
  221. package/src/androidPackageUnparser.test.ts +34 -0
  222. package/src/androidPackageUnparser.ts +126 -0
  223. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  224. package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
  225. package/src/arbitraryDalvikBytecode.ts +992 -0
  226. package/src/arbitraryDalvikExecutable.ts +434 -0
  227. package/src/arbitraryDosDateTime.ts +1 -0
  228. package/src/arbitraryZipStream.ts +1 -1
  229. package/src/arrayParser.test.ts +3 -3
  230. package/src/arrayParser.ts +2 -2
  231. package/src/arrayUnparser.ts +2 -2
  232. package/src/backsmali.ts +74 -0
  233. package/src/bsonParser.test.ts +12 -14
  234. package/src/bsonParser.ts +13 -2
  235. package/src/customInvariant.ts +8 -12
  236. package/src/dalvikBytecodeParser/formatParsers.ts +780 -0
  237. package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
  238. package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
  239. package/src/dalvikBytecodeParser.ts +2873 -0
  240. package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
  241. package/src/dalvikBytecodeUnparser.test.ts +44 -0
  242. package/src/dalvikBytecodeUnparser.ts +758 -0
  243. package/src/dalvikExecutable.ts +282 -0
  244. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  245. package/src/dalvikExecutableParser/typeParsers.ts +74 -0
  246. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  247. package/src/dalvikExecutableParser.test.ts +89 -0
  248. package/src/dalvikExecutableParser.test.ts.md +634 -0
  249. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  250. package/src/dalvikExecutableParser.ts +3245 -0
  251. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +363 -0
  252. package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
  253. package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
  254. package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
  255. package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
  256. package/src/dalvikExecutableUnparser/utils.ts +149 -0
  257. package/src/dalvikExecutableUnparser.test.ts +57 -0
  258. package/src/dalvikExecutableUnparser.ts +581 -0
  259. package/src/debugLogInputParser.ts +28 -0
  260. package/src/debugLogParser.ts +19 -3
  261. package/src/disjunctionParser.ts +12 -7
  262. package/src/elementTerminatedArrayParser.test.ts +99 -0
  263. package/src/elementTerminatedArrayParser.ts +31 -0
  264. package/src/elementTerminatedSequenceArrayParser.test.ts +52 -0
  265. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  266. package/src/elementTerminatedSequenceParser.test.ts +52 -0
  267. package/src/elementTerminatedSequenceParser.ts +43 -0
  268. package/src/endOfInputParser.ts +1 -1
  269. package/src/exactElementParser.ts +17 -11
  270. package/src/exactElementSwitchParser.ts +41 -0
  271. package/src/exactSequenceParser.ts +23 -2
  272. package/src/fetchCid.test.ts +20 -0
  273. package/src/fetchCid.ts +121 -0
  274. package/src/fixedLengthSequenceParser.test.ts +75 -0
  275. package/src/fixedLengthSequenceParser.ts +28 -1
  276. package/src/hasExecutable.ts +11 -0
  277. package/src/highResolutionTimer.ts +49 -0
  278. package/src/inputReader.test.ts +204 -8
  279. package/src/inputReader.ts +76 -3
  280. package/src/inputReaderState.ts +33 -0
  281. package/src/inspect.ts +9 -0
  282. package/src/javaKeyStoreParser.test.ts +12 -15
  283. package/src/javaKeyStoreParser.ts +2 -6
  284. package/src/jsonParser.test.ts +2 -4
  285. package/src/jsonParser.ts +46 -62
  286. package/src/lazyMessageError.test.ts +21 -0
  287. package/src/lazyMessageError.ts +88 -0
  288. package/src/leb128Parser.test.ts +173 -0
  289. package/src/leb128Parser.ts +125 -0
  290. package/src/lookaheadParser.ts +19 -0
  291. package/src/negativeLookaheadParser.test.ts +49 -0
  292. package/src/negativeLookaheadParser.ts +27 -15
  293. package/src/noStackCaptureOverheadError.test.ts +17 -0
  294. package/src/noStackCaptureOverheadError.ts +12 -0
  295. package/src/nonEmptyArrayParser.test.ts +21 -0
  296. package/src/nonEmptyArrayParser.ts +44 -0
  297. package/src/optionalParser.ts +3 -2
  298. package/src/parser.test.ts +203 -31
  299. package/src/parser.test.ts.md +34 -27
  300. package/src/parser.test.ts.snap +0 -0
  301. package/src/parser.ts +172 -45
  302. package/src/parserAccessorParser.ts +12 -2
  303. package/src/parserConsumedSequenceParser.ts +26 -17
  304. package/src/parserContext.test.ts +37 -2
  305. package/src/parserContext.ts +185 -79
  306. package/src/parserCreatorCompose.ts +20 -2
  307. package/src/parserError.ts +144 -61
  308. package/src/parserImplementationInvariant.ts +3 -3
  309. package/src/parserInputCompanion.ts +55 -0
  310. package/src/promiseCompose.ts +17 -3
  311. package/src/promiseSettled.ts +6 -0
  312. package/src/separatedArrayParser.test.ts +34 -0
  313. package/src/separatedArrayParser.ts +55 -0
  314. package/src/separatedNonEmptyArrayParser.test.ts +117 -0
  315. package/src/separatedNonEmptyArrayParser.ts +61 -0
  316. package/src/sequenceBuffer.test.ts +70 -0
  317. package/src/sequenceBuffer.ts +88 -2
  318. package/src/sequenceTerminatedSequenceParser.test.ts +58 -0
  319. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  320. package/src/sequenceUnparser.ts +2 -2
  321. package/src/skipParser.ts +7 -5
  322. package/src/skipToParser.ts +16 -0
  323. package/src/sliceBoundedParser.test.ts +35 -1
  324. package/src/sliceBoundedParser.ts +19 -1
  325. package/src/smali.ts +29 -0
  326. package/src/smaliParser.test.ts +443 -0
  327. package/src/smaliParser.test.ts.md +3907 -0
  328. package/src/smaliParser.test.ts.snap +0 -0
  329. package/src/smaliParser.ts +3348 -0
  330. package/src/stringFromAsyncIterable.ts +9 -0
  331. package/src/terminatedArrayParser.test.ts +258 -0
  332. package/src/terminatedArrayParser.ts +109 -6
  333. package/src/toAsyncIterable.ts +7 -0
  334. package/src/toAsyncIterator.ts +48 -0
  335. package/src/tupleParser.ts +8 -5
  336. package/src/uint8Array.ts +2 -3
  337. package/src/unionParser.test.ts +78 -0
  338. package/src/unionParser.ts +47 -21
  339. package/src/unparser.test.ts +18 -34
  340. package/src/unparser.ts +13 -9
  341. package/src/unparserContext.ts +9 -13
  342. package/src/unparserError.ts +2 -1
  343. package/src/unparserImplementationInvariant.ts +1 -1
  344. package/src/unparserOutputCompanion.ts +1 -1
  345. package/src/zip.ts +2 -6
  346. package/src/zipParser.ts +71 -20
  347. package/src/zipUnparser.test.ts +19 -19
  348. package/src/zipUnparser.ts +139 -90
  349. package/tsconfig.json +7 -1
  350. package/xo.config.ts +15 -0
  351. package/.yarn/releases/yarn-4.5.3.cjs +0 -934
  352. package/build/apk.d.ts +0 -39
  353. package/build/apkParser.d.ts +0 -16
  354. package/build/apkParser.js +0 -164
  355. package/build/apkParser.test.js +0 -22
  356. package/build/apkUnparser.d.ts +0 -4
  357. package/build/apkUnparser.js +0 -90
  358. package/build/apkUnparser.test.js +0 -26
  359. package/build/arbitraryDosDate.d.ts +0 -2
  360. package/build/arbitraryDosDate.js +0 -8
  361. package/build/arbitraryZipEntry.d.ts +0 -3
  362. package/build/arbitraryZipEntry.js +0 -26
  363. package/build/createDisjunctionParser.d.ts +0 -2
  364. package/build/createDisjunctionParser.js +0 -47
  365. package/build/createExactParser.d.ts +0 -2
  366. package/build/createExactParser.js +0 -12
  367. package/build/createSequentialUnionParser.d.ts +0 -2
  368. package/build/createSequentialUnionParser.js +0 -69
  369. package/build/fixedLengthChunkParser.d.ts +0 -2
  370. package/build/fixedLengthChunkParser.js +0 -12
  371. package/build/fixedLengthParser.d.ts +0 -2
  372. package/build/fixedLengthParser.js +0 -12
  373. package/build/inputChunkBuffer.d.ts +0 -15
  374. package/build/inputChunkBuffer.js +0 -40
  375. package/build/inputChunkBuffer.test.js +0 -34
  376. package/build/inputCompanion.d.ts +0 -18
  377. package/build/inputCompanion.js +0 -28
  378. package/build/invariantDefined.d.ts +0 -1
  379. package/build/invariantDefined.js +0 -5
  380. package/build/invariantIdentity.d.ts +0 -3
  381. package/build/invariantIdentity.js +0 -5
  382. package/build/javaKeystoreParser.d.ts +0 -2
  383. package/build/javaKeystoreParser.js +0 -7
  384. package/build/jsonParser2.d.ts +0 -3
  385. package/build/jsonParser2.js +0 -52
  386. package/build/jsonParser2.test.js +0 -22
  387. package/build/negativeLookahead.d.ts +0 -2
  388. package/build/negativeLookahead.js +0 -18
  389. package/build/parserCompose.d.ts +0 -3
  390. package/build/parserCompose.js +0 -7
  391. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  392. package/build/parserImplementationInvariantInvariant.js +0 -15
  393. package/build/parserInvariant.d.ts +0 -4
  394. package/build/parserInvariant.js +0 -11
  395. package/build/promiseFish.d.ts +0 -1
  396. package/build/promiseFish.js +0 -3
  397. package/build/sequenceParser.d.ts +0 -3
  398. package/build/sequenceParser.js +0 -10
  399. package/build/terminatedSequenceParser.d.ts +0 -2
  400. package/build/terminatedSequenceParser.js +0 -24
  401. package/build/unparserInputCompanion.d.ts +0 -15
  402. package/build/unparserInputCompanion.js +0 -13
  403. package/build/zipEntry.d.ts +0 -28
  404. package/build/zipFile.d.ts +0 -32
  405. package/build/zipFileEntry.d.ts +0 -6
  406. package/src/apk.ts +0 -48
  407. package/src/apkParser.test.ts +0 -30
  408. package/src/apkParser.test.ts.snap +0 -0
  409. package/src/apkParser.ts +0 -392
  410. package/src/apkUnparser.test.ts +0 -37
  411. package/src/apkUnparser.ts +0 -120
  412. package/src/invariantDefined.ts +0 -6
  413. package/src/invariantIdentity.ts +0 -8
  414. /package/build/{apk.js → androidPackage.js} +0 -0
  415. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  416. /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  417. /package/build/{arbitraryDosPermissions.d.ts → dalvikBytecodeUnparser.test.d.ts} +0 -0
  418. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  419. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  420. /package/build/{jsonParser2.test.d.ts → dalvikExecutableUnparser.test.d.ts} +0 -0
  421. /package/build/{parserParsingInvariant.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  422. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  423. /package/build/{zipEntry.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  424. /package/build/{zipFile.js → fetchCid.test.d.ts} +0 -0
  425. /package/build/{zipFileEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
@@ -0,0 +1,75 @@
1
+ import test from 'ava';
2
+ import * as fc from 'fast-check';
3
+ import { testProp } from '@fast-check/ava';
4
+ import { createFixedLengthSequenceParser, createFixedLengthSequenceParserNaive } from './fixedLengthSequenceParser.js';
5
+ import { type Parser, runParserWithRemainingInput } from './parser.js';
6
+ import { stringParserInputCompanion } from './parserInputCompanion.js';
7
+ import { HighResolutionTotalTimer } from './highResolutionTimer.js';
8
+ import { arbitrarilySlicedAsyncIterable } from './arbitrarilySlicedAsyncInterable.js';
9
+
10
+ const naiveTotalTimer = new HighResolutionTotalTimer();
11
+ const totalTimer = new HighResolutionTotalTimer();
12
+
13
+ testProp.serial(
14
+ 'fixedLengthSequenceParser',
15
+ [
16
+ fc
17
+ .bigInt({
18
+ min: 1n,
19
+ max: 2n ** 14n,
20
+ })
21
+ .chain(length => fc.tuple(
22
+ arbitrarilySlicedAsyncIterable(fc.string({
23
+ minLength: Number(length),
24
+ maxLength: Number(length) * 2,
25
+ })),
26
+ fc.constant(length),
27
+ )),
28
+ ],
29
+ async (t, [ [ _, sequence ], length ]) => {
30
+ const fixedLengthSequenceParserNaive = createFixedLengthSequenceParserNaive<string>(length);
31
+ const fixedLengthSequenceParser = createFixedLengthSequenceParser<string>(length);
32
+
33
+ const createTestWrapperParser = (innerParser: typeof fixedLengthSequenceParser): Parser<{
34
+ result: string;
35
+ position: number;
36
+ }, string> => async parserContext => {
37
+ const result = await innerParser(parserContext);
38
+
39
+ return {
40
+ result,
41
+ nextPeek: await parserContext.peek(0),
42
+ position: parserContext.position,
43
+ };
44
+ };
45
+
46
+ const { output: actualNaive } = await naiveTotalTimer.measureAsync(async () => runParserWithRemainingInput(
47
+ createTestWrapperParser(fixedLengthSequenceParserNaive),
48
+ sequence,
49
+ stringParserInputCompanion,
50
+ ));
51
+
52
+ t.true(actualNaive.result.length === Number(length));
53
+
54
+ const { output: actual } = await totalTimer.measureAsync(async () => runParserWithRemainingInput(
55
+ createTestWrapperParser(fixedLengthSequenceParser),
56
+ sequence,
57
+ stringParserInputCompanion,
58
+ ));
59
+
60
+ t.deepEqual(actual, actualNaive);
61
+ },
62
+ {
63
+ verbose: true,
64
+ },
65
+ );
66
+
67
+ test.serial(
68
+ 'fixedLengthSequenceParser performance',
69
+ t => {
70
+ t.true(
71
+ totalTimer.time * 10n < naiveTotalTimer.time,
72
+ `Naive: ${naiveTotalTimer.time / 1_000_000n}ms, Optimized: ${totalTimer.time / 1_000_000n}ms`,
73
+ );
74
+ },
75
+ );
@@ -1,7 +1,7 @@
1
1
  import { setParserName, type Parser } from './parser.js';
2
2
  import { parserImplementationInvariant } from './parserImplementationInvariant.js';
3
3
 
4
- export const createFixedLengthSequenceParser = <Sequence>(lengthInput: bigint | number) => {
4
+ export const createFixedLengthSequenceParserNaive = <Sequence>(lengthInput: bigint | number) => {
5
5
  const length = BigInt(lengthInput);
6
6
 
7
7
  parserImplementationInvariant(length >= 0n, 'Length must be non-negative got %s.', length);
@@ -22,3 +22,30 @@ export const createFixedLengthSequenceParser = <Sequence>(lengthInput: bigint |
22
22
 
23
23
  return fixedLengthSequenceParser;
24
24
  };
25
+
26
+ const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
27
+
28
+ export const createFixedLengthSequenceParser = <Sequence>(lengthInput: bigint | number) => {
29
+ const length = BigInt(lengthInput);
30
+
31
+ parserImplementationInvariant(length >= 0n, 'Length must be non-negative got %s.', length);
32
+
33
+ const fixedLengthSequenceParser: Parser<Sequence, Sequence, unknown> = async parserContext => {
34
+ const safeIntegerSequences: Sequence[] = [];
35
+ let remainingLength = length;
36
+
37
+ while (remainingLength > 0n) {
38
+ const safeIntegerLength = length > MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : Number(length);
39
+
40
+ safeIntegerSequences.push(await parserContext.readSequence(0, safeIntegerLength));
41
+
42
+ remainingLength -= BigInt(safeIntegerLength);
43
+ }
44
+
45
+ return parserContext.concat(safeIntegerSequences);
46
+ };
47
+
48
+ setParserName(fixedLengthSequenceParser, `.{${length}}`);
49
+
50
+ return fixedLengthSequenceParser;
51
+ };
@@ -0,0 +1,11 @@
1
+ import { execa } from 'execa';
2
+
3
+ export async function hasExecutable(executable: string) {
4
+ const hasExecutable = execa(executable).catch(() => false).then(() => true);
5
+
6
+ if (!hasExecutable) {
7
+ console.warn('Executable %o not found', executable);
8
+ }
9
+
10
+ return hasExecutable;
11
+ }
@@ -0,0 +1,49 @@
1
+ import process from 'node:process';
2
+ import invariant from 'invariant';
3
+
4
+ class HighResolutionSubTimer {
5
+ private _ended = false;
6
+
7
+ constructor(
8
+ private readonly _parent: HighResolutionTotalTimer,
9
+ private readonly _start: bigint,
10
+ ) {}
11
+
12
+ end() {
13
+ invariant(!this._ended, 'Timer already ended.');
14
+ const end = process.hrtime.bigint();
15
+ const time = end - this._start;
16
+ this._parent.add(time);
17
+ this._ended = true;
18
+ }
19
+ }
20
+
21
+ export class HighResolutionTotalTimer {
22
+ private _total = 0n;
23
+
24
+ start(): HighResolutionSubTimer {
25
+ return new HighResolutionSubTimer(this, process.hrtime.bigint());
26
+ }
27
+
28
+ add(time: bigint) {
29
+ this._total += time;
30
+ }
31
+
32
+ get time() {
33
+ return this._total;
34
+ }
35
+
36
+ measure<T>(fn: () => T): T {
37
+ const timer = this.start();
38
+ const result = fn();
39
+ timer.end();
40
+ return result;
41
+ }
42
+
43
+ async measureAsync<T>(fn: () => Promise<T>): Promise<T> {
44
+ const timer = this.start();
45
+ const result = await fn();
46
+ timer.end();
47
+ return result;
48
+ }
49
+ }
@@ -1,7 +1,8 @@
1
1
  import test from 'ava';
2
2
  import { InputReaderImplementation } from './inputReader.js';
3
3
  import { stringParserInputCompanion } from './parserInputCompanion.js';
4
- import { ParserImplementationError } from './parserError.js';
4
+ import { toAsyncIterable } from './toAsyncIterable.js';
5
+ import { type InputReaderState } from './inputReaderState.js';
5
6
 
6
7
  test('inputReader', async t => {
7
8
  const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
@@ -46,6 +47,53 @@ test('inputReader', async t => {
46
47
  t.is(await inputReader.peek(0), undefined);
47
48
  });
48
49
 
50
+ test('inputReader peekSequence', async t => {
51
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
52
+ yield '';
53
+ yield 'abc';
54
+ yield 'def';
55
+ yield '';
56
+ yield 'gh';
57
+ })());
58
+
59
+ t.is(await inputReader.peekSequence(0, 0), '');
60
+ t.is(await inputReader.peekSequence(0, 1), 'a');
61
+
62
+ inputReader.skip(0);
63
+
64
+ t.is(await inputReader.peekSequence(1, 2), 'b');
65
+
66
+ inputReader.skip(1);
67
+
68
+ t.is(await inputReader.peekSequence(1, 7), 'bcdefgh'.slice(1, 7));
69
+ t.is(await inputReader.peekSequence(1, 8), undefined);
70
+
71
+ inputReader.skip(6);
72
+
73
+ t.is(await inputReader.peekSequence(0, 0), '');
74
+ t.is(await inputReader.peekSequence(0, 1), 'h');
75
+ t.is(await inputReader.peekSequence(1, 2), undefined);
76
+ t.is(await inputReader.peekSequence(2, 2), undefined);
77
+
78
+ inputReader.skip(1);
79
+
80
+ t.is(await inputReader.peekSequence(0, 0), '');
81
+ t.is(await inputReader.peekSequence(0, 1), undefined);
82
+ t.is(await inputReader.peekSequence(1, 1), undefined);
83
+
84
+ inputReader.skip(0);
85
+
86
+ t.is(await inputReader.peekSequence(0, 0), '');
87
+ t.is(await inputReader.peekSequence(0, 1), undefined);
88
+ t.is(await inputReader.peekSequence(1, 1), undefined);
89
+
90
+ inputReader.skip(1);
91
+
92
+ t.is(await inputReader.peekSequence(0, 0), undefined);
93
+ t.is(await inputReader.peekSequence(0, 1), undefined);
94
+ t.is(await inputReader.peekSequence(1, 1), undefined);
95
+ });
96
+
49
97
  test('inputReader.peek concurrent', async t => {
50
98
  const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
51
99
  yield * 'abcdefgh';
@@ -68,6 +116,64 @@ test('inputReader.peek concurrent', async t => {
68
116
  t.deepEqual(peeks, [ 'a', 'a', 'a', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' ]);
69
117
  });
70
118
 
119
+ test('inputReader.peekSequence concurrent', async t => {
120
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
121
+ yield * 'abcdefgh';
122
+ })());
123
+
124
+ const peeks = await Promise.all([ 1, 2, 3 ].flatMap(length => [
125
+ inputReader.peekSequence(0, 0 + length),
126
+ inputReader.peekSequence(0, 0 + length),
127
+ inputReader.peekSequence(0, 0 + length),
128
+ inputReader.peekSequence(0, 0 + length),
129
+ inputReader.peekSequence(1, 1 + length),
130
+ inputReader.peekSequence(2, 2 + length),
131
+ inputReader.peekSequence(3, 3 + length),
132
+ inputReader.peekSequence(4, 4 + length),
133
+ inputReader.peekSequence(5, 5 + length),
134
+ inputReader.peekSequence(6, 6 + length),
135
+ inputReader.peekSequence(7, 7 + length),
136
+ ]));
137
+
138
+ t.deepEqual(peeks, [
139
+ 'a',
140
+ 'a',
141
+ 'a',
142
+ 'a',
143
+ 'b',
144
+ 'c',
145
+ 'd',
146
+ 'e',
147
+ 'f',
148
+ 'g',
149
+ 'h',
150
+
151
+ 'ab',
152
+ 'ab',
153
+ 'ab',
154
+ 'ab',
155
+ 'bc',
156
+ 'cd',
157
+ 'de',
158
+ 'ef',
159
+ 'fg',
160
+ 'gh',
161
+ undefined,
162
+
163
+ 'abc',
164
+ 'abc',
165
+ 'abc',
166
+ 'abc',
167
+ 'bcd',
168
+ 'cde',
169
+ 'def',
170
+ 'efg',
171
+ 'fgh',
172
+ undefined,
173
+ undefined,
174
+ ]);
175
+ });
176
+
71
177
  test('inputReader skip while peeking', async t => {
72
178
  const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
73
179
  yield * 'abcdefgh';
@@ -77,8 +183,33 @@ test('inputReader skip while peeking', async t => {
77
183
 
78
184
  inputReader.skip(1);
79
185
 
186
+ const peekAfterSkipPromise = inputReader.peek(0);
187
+ const peekSequenceAfterSkipPromise = inputReader.peekSequence(0, 5);
188
+
80
189
  t.is(await peekPromise, 'a');
81
190
  t.is(await inputReader.peek(0), 'b');
191
+
192
+ t.is(await peekAfterSkipPromise, 'b');
193
+ t.is(await peekSequenceAfterSkipPromise, 'bcdef');
194
+ });
195
+
196
+ test('inputReader skip while peeking sequence', async t => {
197
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
198
+ yield * 'abcdefgh';
199
+ })());
200
+
201
+ const peekPromise = inputReader.peekSequence(1, 5);
202
+
203
+ inputReader.skip(1);
204
+
205
+ const peekAfterSkipPromise = inputReader.peek(0);
206
+ const peekSequenceAfterSkipPromise = inputReader.peekSequence(0, 4);
207
+
208
+ t.is(await peekPromise, 'bcde', 'peekPromise');
209
+ t.is(await inputReader.peekSequence(0, 4), 'bcde', 'inputReader.peekSequence(0, 4)');
210
+
211
+ t.is(await peekAfterSkipPromise, 'b', 'peekAfterSkipPromise');
212
+ t.is(await peekSequenceAfterSkipPromise, 'bcde', 'peekSequenceAfterSkipPromise');
82
213
  });
83
214
 
84
215
  test('inputReader.lookahead', async t => {
@@ -115,10 +246,16 @@ test('inputReader.lookahead', async t => {
115
246
  inputReader.skip(1);
116
247
 
117
248
  await t.throwsAsync(async () => lookahead0a.peek(0), {
118
- instanceOf: ParserImplementationError,
249
+ any: true,
250
+ name: 'ParserImplementationInvariantError',
251
+ });
252
+
253
+ await t.throwsAsync(async () => lookahead0b.peek(0), {
254
+ any: true,
255
+ });
256
+ await t.throwsAsync(async () => lookahead0c.peek(0), {
257
+ any: true,
119
258
  });
120
- await t.throwsAsync(async () => lookahead0b.peek(0));
121
- await t.throwsAsync(async () => lookahead0c.peek(0));
122
259
 
123
260
  const lookahead1a = inputReader.lookahead();
124
261
  const lookahead1b = inputReader.lookahead();
@@ -160,11 +297,19 @@ test('inputReader.lookahead', async t => {
160
297
 
161
298
  t.is(inputReader.position, 2);
162
299
 
163
- await t.throwsAsync(async () => lookahead0a.peek(0));
164
- await t.throwsAsync(async () => lookahead0b.peek(0));
165
- await t.throwsAsync(async () => lookahead0c.peek(0));
300
+ await t.throwsAsync(async () => lookahead0a.peek(0), {
301
+ any: true,
302
+ });
303
+ await t.throwsAsync(async () => lookahead0b.peek(0), {
304
+ any: true,
305
+ });
306
+ await t.throwsAsync(async () => lookahead0c.peek(0), {
307
+ any: true,
308
+ });
166
309
  t.is(await lookahead1a.peek(0), 'c');
167
- await t.throwsAsync(async () => lookahead1b.peek(0));
310
+ await t.throwsAsync(async () => lookahead1b.peek(0), {
311
+ any: true,
312
+ });
168
313
  t.is(await lookahead2a.peek(0), 'd');
169
314
  t.is(await lookahead2b.peek(0), 'c');
170
315
 
@@ -236,3 +381,54 @@ test('inputReader.lookahead skip position', async t => {
236
381
  t.is(await lookahead.peek(0), 'c');
237
382
  t.is(await lookahead1.peek(0), 'd');
238
383
  });
384
+
385
+ const END_OF_CONSUMED_SEQUENCES = Symbol('END_OF_CONSUMED_SEQUENCES');
386
+ const END_OF_BUFFERED_SEQUENCES = Symbol('END_OF_BUFFERED_SEQUENCES');
387
+
388
+ async function inputReaderStateToArray<Sequence>({
389
+ unconsumedBufferedSequences,
390
+ consumedBufferedSequences,
391
+ unbufferedSequences,
392
+ }: InputReaderState<Sequence>): Promise<Array<Sequence | typeof END_OF_CONSUMED_SEQUENCES | typeof END_OF_BUFFERED_SEQUENCES>> {
393
+ const unconsumedBufferedSequencesArray = [ ...unconsumedBufferedSequences ];
394
+ const consumedBufferedSequencesArray = [ ...consumedBufferedSequences ];
395
+
396
+ const unbufferedSequencesArray = [];
397
+ if (unbufferedSequences) {
398
+ for await (const sequence of toAsyncIterable(unbufferedSequences)) {
399
+ unbufferedSequencesArray.push(sequence);
400
+ }
401
+ }
402
+
403
+ return [
404
+ ...consumedBufferedSequencesArray,
405
+ END_OF_CONSUMED_SEQUENCES,
406
+ ...unconsumedBufferedSequencesArray,
407
+ END_OF_BUFFERED_SEQUENCES,
408
+ ...unbufferedSequencesArray,
409
+ ];
410
+ }
411
+
412
+ const inputReaderStateMacro = test.macro({
413
+ title: (providedTitle, input: readonly string[], position: number) =>
414
+ providedTitle ?? `inputReader.toInputReaderState ${JSON.stringify({ input, position })}`,
415
+ async exec(t, input: readonly string[], position: number, expected: ReadonlyArray<string | symbol>) {
416
+ const inputReader = new InputReaderImplementation(stringParserInputCompanion, (async function * () {
417
+ yield * input;
418
+ })());
419
+
420
+ inputReader.skip(position);
421
+ await inputReader.peek(0);
422
+
423
+ const actual = await inputReaderStateToArray(inputReader.toInputReaderState());
424
+
425
+ t.deepEqual(actual, expected);
426
+ },
427
+ });
428
+
429
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 0, [ END_OF_CONSUMED_SEQUENCES, 'abc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
430
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 1, [ 'a', END_OF_CONSUMED_SEQUENCES, 'bc', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
431
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 2, [ 'ab', END_OF_CONSUMED_SEQUENCES, 'c', END_OF_BUFFERED_SEQUENCES, 'def', '', 'gh' ]);
432
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 3, [ END_OF_CONSUMED_SEQUENCES, 'def', END_OF_BUFFERED_SEQUENCES, '', 'gh' ]);
433
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 4, [ 'd', END_OF_CONSUMED_SEQUENCES, 'ef', END_OF_BUFFERED_SEQUENCES, '', 'gh' ]);
434
+ test(inputReaderStateMacro, [ '', 'abc', 'def', '', 'gh' ], 8, [ END_OF_CONSUMED_SEQUENCES, END_OF_BUFFERED_SEQUENCES ]);
@@ -3,14 +3,18 @@ import invariant from 'invariant';
3
3
  import { type SequenceBuffer, SequenceBufferImplementation } from './sequenceBuffer.js';
4
4
  import { type ParserInputCompanion } from './parserInputCompanion.js';
5
5
  import { parserImplementationInvariant } from './parserImplementationInvariant.js';
6
+ import { type InputReaderState } from './inputReaderState.js';
6
7
 
7
8
  export type InputReader<Sequence, Element> = {
8
9
  get position(): number;
9
10
 
10
11
  peek(offset: number): Promise<Element | undefined>;
12
+ peekSequence(start: number, end: number): Promise<Sequence | undefined>;
11
13
  skip(offset: number): void;
12
14
 
13
15
  lookahead(): InputReader<Sequence, Element>;
16
+
17
+ toInputReaderState(): InputReaderState<Sequence>;
14
18
  };
15
19
 
16
20
  let inputReaderId = 0;
@@ -20,6 +24,7 @@ export class InputReaderImplementation<Sequence, Element> implements InputReader
20
24
 
21
25
  private _position = 0;
22
26
  private _uncommitedSkipOffset = 0;
27
+ private _inputAsyncIteratorDone = false;
23
28
 
24
29
  private readonly _promiseMutex = new PromiseMutex();
25
30
 
@@ -66,6 +71,8 @@ export class InputReaderImplementation<Sequence, Element> implements InputReader
66
71
  const inputIteratorResult = await this._inputAsyncIterator.next();
67
72
 
68
73
  if (inputIteratorResult.done) {
74
+ this._inputAsyncIteratorDone = true;
75
+
69
76
  return undefined;
70
77
  }
71
78
 
@@ -85,6 +92,47 @@ export class InputReaderImplementation<Sequence, Element> implements InputReader
85
92
  });
86
93
  }
87
94
 
95
+ async peekSequence(start: number, end: number): Promise<Sequence | undefined> {
96
+ parserImplementationInvariant(
97
+ start >= 0,
98
+ 'start (%s) >= 0',
99
+ start,
100
+ );
101
+ parserImplementationInvariant(
102
+ end >= start,
103
+ 'end (%s) >= start (%s)',
104
+ start,
105
+ end,
106
+ );
107
+ parserImplementationInvariant(
108
+ Number.isSafeInteger(start),
109
+ 'start (%s) is not a safe integer',
110
+ start,
111
+ );
112
+ parserImplementationInvariant(
113
+ Number.isSafeInteger(end),
114
+ 'end (%s) is not a safe integer',
115
+ end,
116
+ );
117
+
118
+ start += this._uncommitedSkipOffset;
119
+ end += this._uncommitedSkipOffset;
120
+
121
+ const sequence = this._sequenceBuffer.peekSequence(start, end);
122
+
123
+ if (sequence !== undefined) {
124
+ return sequence;
125
+ }
126
+
127
+ const lastElement = await this.peek(Math.max(0, end - 1));
128
+
129
+ if (lastElement === undefined) {
130
+ return undefined;
131
+ }
132
+
133
+ return this._sequenceBuffer.peekSequence(start, end);
134
+ }
135
+
88
136
  skip(offset: number) {
89
137
  parserImplementationInvariant(offset >= 0, 'offset >= 0');
90
138
 
@@ -101,15 +149,27 @@ export class InputReaderImplementation<Sequence, Element> implements InputReader
101
149
  lookahead(): InputReader<Sequence, Element> {
102
150
  return new InputReaderLookaheadImplementation(this);
103
151
  }
152
+
153
+ toInputReaderState() {
154
+ const {
155
+ consumedBufferedSequences,
156
+ unconsumedBufferedSequences,
157
+ } = this._sequenceBuffer.toSequenceBufferState();
158
+
159
+ return {
160
+ consumedBufferedSequences,
161
+ unconsumedBufferedSequences,
162
+ unbufferedSequences: this._inputAsyncIteratorDone ? undefined : this._inputAsyncIterator,
163
+ position: this._position,
164
+ };
165
+ }
104
166
  }
105
167
 
106
168
  class InputReaderLookaheadImplementation<Sequence, Element> implements InputReader<Sequence, Element> {
107
169
  private _initialInputReaderPosition = 0;
108
170
  private _offset = 0;
109
171
 
110
- constructor(
111
- private readonly _inputReader: InputReaderImplementation<Sequence, Element>,
112
- ) {
172
+ constructor(private readonly _inputReader: InputReaderImplementation<Sequence, Element>) {
113
173
  this._initialInputReaderPosition = this._inputReader.position;
114
174
  }
115
175
 
@@ -134,6 +194,15 @@ class InputReaderLookaheadImplementation<Sequence, Element> implements InputRead
134
194
  return this._inputReader.peek(this._offset + offset);
135
195
  }
136
196
 
197
+ async peekSequence(start: number, end: number): Promise<Sequence | undefined> {
198
+ const inputReaderMovedForward = this._inputReader.position - this._initialInputReaderPosition;
199
+
200
+ this._initialInputReaderPosition = this._inputReader.position;
201
+ this._offset -= inputReaderMovedForward;
202
+
203
+ return this._inputReader.peekSequence(this._offset + start, this._offset + end);
204
+ }
205
+
137
206
  skip(offset: number) {
138
207
  parserImplementationInvariant(offset >= 0, 'offset >= 0');
139
208
 
@@ -156,4 +225,8 @@ class InputReaderLookaheadImplementation<Sequence, Element> implements InputRead
156
225
 
157
226
  return lookahead;
158
227
  }
228
+
229
+ toInputReaderState() {
230
+ return invariant(false, 'Not implemented');
231
+ }
159
232
  }
@@ -0,0 +1,33 @@
1
+ export type InputReaderState<Sequence> = {
2
+ position: number;
3
+ consumedBufferedSequences: Sequence[];
4
+ unconsumedBufferedSequences: Sequence[];
5
+ unbufferedSequences: undefined | AsyncIterator<Sequence>;
6
+ };
7
+
8
+ export const inputReaderStateCompanion = {
9
+ isDone<Sequence>({
10
+ unconsumedBufferedSequences,
11
+ unbufferedSequences,
12
+ }: InputReaderState<Sequence>): boolean {
13
+ return (
14
+ unconsumedBufferedSequences.length === 0
15
+ && unbufferedSequences === undefined
16
+ );
17
+ },
18
+
19
+ async * toRemainingInputAsyncIterator<Sequence>({
20
+ unconsumedBufferedSequences,
21
+ unbufferedSequences,
22
+ }: InputReaderState<Sequence>): AsyncIterable<Sequence> {
23
+ yield * unconsumedBufferedSequences;
24
+
25
+ if (unbufferedSequences !== undefined) {
26
+ yield * {
27
+ [Symbol.asyncIterator]() {
28
+ return unbufferedSequences;
29
+ },
30
+ };
31
+ }
32
+ },
33
+ };
package/src/inspect.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { inspect as nodeInspect } from 'node:util';
2
+
3
+ export const inspect = (value: unknown) => {
4
+ if (value instanceof Uint8Array) {
5
+ value = Buffer.from(value);
6
+ }
7
+
8
+ return nodeInspect(value);
9
+ };
@@ -2,22 +2,19 @@ import test from 'ava';
2
2
  import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
3
3
  import { runParser } from './parser.js';
4
4
  import { javaKeyStoreParser } from './javaKeyStoreParser.js';
5
+ import { fetchCid } from './fetchCid.js';
5
6
 
6
- for (const javaKeyStoreCid of [
7
- 'bafkreig6k53b6p7bdvfjxc5mcb4qv3mffqls5ymqerxkqd6ih2xy5cs3n4',
8
- ]) {
9
- test(
10
- 'javaKeyStore ' + javaKeyStoreCid,
11
- async t => {
12
- const javaKeyStoreResponse = await fetch('https://ipfs.io/ipfs/' + javaKeyStoreCid);
7
+ const javaKeyStoreMacro = test.macro({
8
+ title: (providedTitle, javaKeyStoreCid: string) => providedTitle ?? `javaKeyStore ${javaKeyStoreCid}`,
9
+ async exec(t, javaKeyStoreCid: string) {
10
+ const javaKeyStoreStream = await fetchCid(javaKeyStoreCid);
13
11
 
14
- const javaKeyStoreStream = javaKeyStoreResponse.body!;
12
+ const actual = await runParser(javaKeyStoreParser, javaKeyStoreStream, uint8ArrayParserInputCompanion, {
13
+ errorJoinMode: 'all',
14
+ });
15
15
 
16
- const actual = await runParser(javaKeyStoreParser, javaKeyStoreStream, uint8ArrayParserInputCompanion, {
17
- errorJoinMode: 'all',
18
- });
16
+ t.snapshot(actual);
17
+ },
18
+ });
19
19
 
20
- t.snapshot(actual);
21
- },
22
- );
23
- }
20
+ test(javaKeyStoreMacro, 'bafkreig6k53b6p7bdvfjxc5mcb4qv3mffqls5ymqerxkqd6ih2xy5cs3n4');
@@ -66,9 +66,7 @@ const javaKeyStorePrivateKeyEntryCertificateParser = promiseCompose(
66
66
  ([ type, certificate ]) => ({ type, certificate }),
67
67
  );
68
68
 
69
- const javaKeyStorePrivateKeyEntryCertificateChainParser = createUint32BECountPrefixedParser(
70
- javaKeyStorePrivateKeyEntryCertificateParser,
71
- );
69
+ const javaKeyStorePrivateKeyEntryCertificateChainParser = createUint32BECountPrefixedParser(javaKeyStorePrivateKeyEntryCertificateParser);
72
70
 
73
71
  const javaKeyStorePrivateKeyEntryParser = promiseCompose(
74
72
  createTupleParser([
@@ -109,9 +107,7 @@ const javaKeyStoreEntryParser = createUnionParser([
109
107
  javaKeyStoreSecretKeyEntryParser,
110
108
  ]);
111
109
 
112
- const javaKeyStoreEntriesParser = createUint32BECountPrefixedParser(
113
- javaKeyStoreEntryParser,
114
- );
110
+ const javaKeyStoreEntriesParser = createUint32BECountPrefixedParser(javaKeyStoreEntryParser);
115
111
 
116
112
  const javaKeyStoreParser_ = createTupleParser([
117
113
  javaKeyStoreImplementationParser,
@@ -7,10 +7,8 @@ import { stringParserInputCompanion } from './parserInputCompanion.js';
7
7
  testProp(
8
8
  'json',
9
9
  [
10
- arbitrarilySlicedAsyncIterator(
11
- fc.tuple(fc.json(), fc.nat())
12
- .map(([ jsonString, indent ]) => JSON.stringify(JSON.parse(jsonString), null, indent)),
13
- ),
10
+ arbitrarilySlicedAsyncIterator(fc.tuple(fc.json(), fc.nat())
11
+ .map(([ jsonString, indent ]) => JSON.stringify(JSON.parse(jsonString), null, indent))),
14
12
  ],
15
13
  async (t, [ jsonString, jsonStringChunkIterator ]) => {
16
14
  const actual = await runParser(jsonValueParser, jsonStringChunkIterator, stringParserInputCompanion, {