@futpib/parser 1.0.0 → 1.0.2

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 (380) hide show
  1. package/build/allSettledStream.js +32 -14
  2. package/build/allSettledStream.test.js +32 -0
  3. package/build/androidPackage.d.ts +39 -0
  4. package/build/androidPackageParser.d.ts +17 -0
  5. package/build/androidPackageParser.js +183 -0
  6. package/build/{apkParser.test.js → androidPackageParser.test.js} +7 -7
  7. package/build/androidPackageUnparser.d.ts +4 -0
  8. package/build/androidPackageUnparser.js +90 -0
  9. package/build/androidPackageUnparser.test.js +26 -0
  10. package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
  11. package/build/arbitrarilySlicedAsyncInterable.js +3 -3
  12. package/build/arbitraryFileSystemEntry.js +1 -1
  13. package/build/arbitraryZip.d.ts +1 -1
  14. package/build/arbitraryZip.js +13 -19
  15. package/build/arbitraryZipPermissions.d.ts +1 -8
  16. package/build/arbitraryZipPermissions.js +1 -16
  17. package/build/arbitraryZipStream.d.ts +1 -1
  18. package/build/arbitraryZipStream.js +3 -3
  19. package/build/arrayParser.d.ts +1 -1
  20. package/build/arrayParser.js +2 -2
  21. package/build/arrayParser.test.js +4 -4
  22. package/build/arrayUnparser.d.ts +2 -0
  23. package/build/arrayUnparser.js +8 -0
  24. package/build/backsmali.d.ts +1 -0
  25. package/build/backsmali.js +22 -0
  26. package/build/bsonParser.js +6 -2
  27. package/build/bsonParser.test.js +2 -2
  28. package/build/{parserInvariant.d.ts → customInvariant.d.ts} +1 -1
  29. package/build/{parserInvariant.js → customInvariant.js} +1 -1
  30. package/build/dalvikBytecodeParser/formatParsers.d.ts +97 -0
  31. package/build/dalvikBytecodeParser/formatParsers.js +169 -0
  32. package/build/dalvikBytecodeParser.d.ts +107 -0
  33. package/build/dalvikBytecodeParser.js +836 -0
  34. package/build/dalvikExecutable.d.ts +158 -0
  35. package/build/dalvikExecutable.js +20 -0
  36. package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
  37. package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
  38. package/build/dalvikExecutableParser/typeParsers.d.ts +10 -0
  39. package/build/dalvikExecutableParser/typeParsers.js +34 -0
  40. package/build/dalvikExecutableParser/typedNumbers.d.ts +90 -0
  41. package/build/dalvikExecutableParser/typedNumbers.js +19 -0
  42. package/build/dalvikExecutableParser.d.ts +5 -0
  43. package/build/dalvikExecutableParser.js +1439 -0
  44. package/build/dalvikExecutableParser.test.js +70 -0
  45. package/build/dalvikExecutableParserAgainstSmaliParser.test.js +298 -0
  46. package/build/debugLogInputParser.d.ts +4 -0
  47. package/build/debugLogInputParser.js +16 -0
  48. package/build/debugLogParser.d.ts +1 -1
  49. package/build/debugLogParser.js +15 -4
  50. package/build/disjunctionParser.d.ts +2 -1
  51. package/build/disjunctionParser.js +4 -2
  52. package/build/elementParser.d.ts +2 -2
  53. package/build/elementParser.js +1 -1
  54. package/build/elementTerminatedArrayParser.d.ts +3 -0
  55. package/build/elementTerminatedArrayParser.js +18 -0
  56. package/build/elementTerminatedArrayParser.test.js +52 -0
  57. package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
  58. package/build/elementTerminatedSequenceArrayParser.js +32 -0
  59. package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
  60. package/build/elementTerminatedSequenceParser.d.ts +3 -0
  61. package/build/elementTerminatedSequenceParser.js +27 -0
  62. package/build/elementTerminatedSequenceParser.test.js +34 -0
  63. package/build/endOfInputParser.d.ts +2 -2
  64. package/build/exactElementParser.d.ts +1 -1
  65. package/build/exactElementParser.js +10 -5
  66. package/build/exactSequenceParser.d.ts +2 -1
  67. package/build/exactSequenceParser.js +12 -2
  68. package/build/fetchCid.d.ts +1 -0
  69. package/build/fetchCid.js +107 -0
  70. package/build/fixedLengthSequenceParser.d.ts +1 -0
  71. package/build/fixedLengthSequenceParser.js +18 -1
  72. package/build/fixedLengthSequenceParser.test.js +41 -0
  73. package/build/hasExecutable.d.ts +1 -0
  74. package/build/hasExecutable.js +8 -0
  75. package/build/highResolutionTimer.d.ts +16 -0
  76. package/build/highResolutionTimer.js +42 -0
  77. package/build/index.d.ts +5 -2
  78. package/build/index.js +3 -0
  79. package/build/inputReader.d.ts +14 -3
  80. package/build/inputReader.js +43 -6
  81. package/build/inputReader.test.js +172 -7
  82. package/build/inputReaderState.d.ts +10 -0
  83. package/build/inputReaderState.js +16 -0
  84. package/build/inspect.d.ts +1 -0
  85. package/build/inspect.js +7 -0
  86. package/build/javaKeyStoreParser.d.ts +2 -0
  87. package/build/javaKeyStoreParser.js +67 -0
  88. package/build/javaKeyStoreParser.test.d.ts +1 -0
  89. package/build/javaKeyStoreParser.test.js +16 -0
  90. package/build/jsonParser.d.ts +2 -0
  91. package/build/jsonParser.js +13 -15
  92. package/build/jsonParser.test.js +2 -2
  93. package/build/leb128Parser.d.ts +7 -0
  94. package/build/leb128Parser.js +82 -0
  95. package/build/leb128Parser.test.d.ts +1 -0
  96. package/build/leb128Parser.test.js +107 -0
  97. package/build/listParser.d.ts +1 -1
  98. package/build/listParser.js +5 -5
  99. package/build/lookaheadParser.d.ts +2 -0
  100. package/build/lookaheadParser.js +14 -0
  101. package/build/{negativeLookahead.d.ts → negativeLookaheadParser.d.ts} +1 -1
  102. package/build/negativeLookaheadParser.js +24 -0
  103. package/build/negativeLookaheadParser.test.d.ts +1 -0
  104. package/build/negativeLookaheadParser.test.js +30 -0
  105. package/build/nonEmptyArrayParser.d.ts +2 -0
  106. package/build/nonEmptyArrayParser.js +32 -0
  107. package/build/nonEmptyArrayParser.test.d.ts +1 -0
  108. package/build/nonEmptyArrayParser.test.js +16 -0
  109. package/build/optionalParser.d.ts +1 -1
  110. package/build/optionalParser.js +2 -2
  111. package/build/parser.d.ts +13 -4
  112. package/build/parser.js +67 -32
  113. package/build/parser.test.js +94 -27
  114. package/build/parserAccessorParser.d.ts +1 -1
  115. package/build/parserAccessorParser.js +9 -1
  116. package/build/parserConsumedSequenceParser.d.ts +2 -0
  117. package/build/parserConsumedSequenceParser.js +22 -0
  118. package/build/parserContext.d.ts +20 -6
  119. package/build/parserContext.js +70 -40
  120. package/build/parserContext.test.js +34 -7
  121. package/build/parserCreatorCompose.d.ts +4 -3
  122. package/build/parserCreatorCompose.js +9 -3
  123. package/build/parserError.d.ts +6 -0
  124. package/build/parserError.js +6 -6
  125. package/build/parserImplementationInvariant.d.ts +1 -1
  126. package/build/parserImplementationInvariant.js +2 -2
  127. package/build/parserInputCompanion.d.ts +35 -0
  128. package/build/parserInputCompanion.js +68 -0
  129. package/build/promiseCompose.d.ts +1 -1
  130. package/build/promiseCompose.js +12 -1
  131. package/build/promiseSettled.d.ts +1 -0
  132. package/build/promiseSettled.js +4 -0
  133. package/build/quantifierParser.d.ts +2 -0
  134. package/build/quantifierParser.js +17 -0
  135. package/build/separatedArrayParser.d.ts +2 -0
  136. package/build/separatedArrayParser.js +39 -0
  137. package/build/separatedArrayParser.test.d.ts +1 -0
  138. package/build/separatedArrayParser.test.js +21 -0
  139. package/build/sequenceBuffer.d.ts +13 -3
  140. package/build/sequenceBuffer.js +60 -8
  141. package/build/sequenceBuffer.test.js +59 -2
  142. package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
  143. package/build/sequenceTerminatedSequenceParser.js +32 -0
  144. package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
  145. package/build/sequenceTerminatedSequenceParser.test.js +37 -0
  146. package/build/sequenceUnparser.d.ts +2 -0
  147. package/build/sequenceUnparser.js +6 -0
  148. package/build/skipParser.d.ts +1 -1
  149. package/build/skipParser.js +4 -2
  150. package/build/skipToParser.d.ts +2 -0
  151. package/build/skipToParser.js +11 -0
  152. package/build/sliceBoundedParser.d.ts +2 -2
  153. package/build/sliceBoundedParser.js +8 -3
  154. package/build/sliceBoundedParser.test.js +37 -3
  155. package/build/smali.d.ts +1 -0
  156. package/build/smali.js +17 -0
  157. package/build/smaliParser.d.ts +12 -0
  158. package/build/smaliParser.js +656 -0
  159. package/build/smaliParser.test.d.ts +1 -0
  160. package/build/smaliParser.test.js +115 -0
  161. package/build/terminatedArrayParser.d.ts +4 -2
  162. package/build/terminatedArrayParser.js +82 -5
  163. package/build/terminatedArrayParser.test.d.ts +1 -0
  164. package/build/terminatedArrayParser.test.js +131 -0
  165. package/build/toAsyncIterable.d.ts +1 -0
  166. package/build/toAsyncIterable.js +7 -0
  167. package/build/toAsyncIterator.d.ts +1 -0
  168. package/build/toAsyncIterator.js +33 -0
  169. package/build/tupleParser.d.ts +4 -0
  170. package/build/tupleParser.js +1 -5
  171. package/build/uint8Array.d.ts +1 -0
  172. package/build/uint8Array.js +7 -0
  173. package/build/unionParser.d.ts +2 -1
  174. package/build/unionParser.js +27 -12
  175. package/build/unionParser.test.d.ts +1 -0
  176. package/build/unionParser.test.js +60 -0
  177. package/build/unparser.d.ts +8 -0
  178. package/build/unparser.js +104 -0
  179. package/build/unparser.test.d.ts +1 -0
  180. package/build/unparser.test.js +150 -0
  181. package/build/unparserContext.d.ts +31 -0
  182. package/build/unparserContext.js +74 -0
  183. package/build/unparserError.d.ts +9 -0
  184. package/build/unparserError.js +9 -0
  185. package/build/unparserImplementationInvariant.d.ts +2 -0
  186. package/build/unparserImplementationInvariant.js +5 -0
  187. package/build/unparserOutputCompanion.d.ts +15 -0
  188. package/build/unparserOutputCompanion.js +13 -0
  189. package/build/zip.d.ts +9 -17
  190. package/build/zipParser.d.ts +20 -12
  191. package/build/zipParser.js +83 -71
  192. package/build/zipParser.test.js +2 -7
  193. package/build/zipUnparser.d.ts +8 -0
  194. package/build/zipUnparser.js +200 -0
  195. package/build/zipUnparser.test.d.ts +1 -0
  196. package/build/zipUnparser.test.js +80 -0
  197. package/package.json +26 -8
  198. package/src/allSettledStream.test.ts +40 -0
  199. package/src/allSettledStream.ts +47 -15
  200. package/src/androidPackage.ts +48 -0
  201. package/src/{apkParser.test.ts → androidPackageParser.test.ts} +7 -8
  202. package/src/androidPackageParser.test.ts.md +271 -0
  203. package/src/androidPackageParser.test.ts.snap +0 -0
  204. package/src/androidPackageParser.ts +440 -0
  205. package/src/androidPackageUnparser.test.ts +36 -0
  206. package/src/androidPackageUnparser.ts +120 -0
  207. package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
  208. package/src/arbitraryFileSystemEntry.ts +2 -4
  209. package/src/arbitraryZip.ts +20 -27
  210. package/src/arbitraryZipPermissions.ts +0 -25
  211. package/src/arbitraryZipStream.ts +4 -4
  212. package/src/arrayParser.test.ts +4 -4
  213. package/src/arrayParser.ts +3 -2
  214. package/src/arrayUnparser.ts +13 -0
  215. package/src/backsmali.ts +30 -0
  216. package/src/bsonParser.test.ts +2 -2
  217. package/src/bsonParser.ts +16 -5
  218. package/src/{parserInvariant.ts → customInvariant.ts} +2 -2
  219. package/src/dalvikBytecodeParser/formatParsers.ts +421 -0
  220. package/src/dalvikBytecodeParser.ts +2074 -0
  221. package/src/dalvikExecutable.ts +220 -0
  222. package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
  223. package/src/dalvikExecutableParser/typeParsers.ts +65 -0
  224. package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
  225. package/src/dalvikExecutableParser.test.ts +89 -0
  226. package/src/dalvikExecutableParser.test.ts.md +634 -0
  227. package/src/dalvikExecutableParser.test.ts.snap +0 -0
  228. package/src/dalvikExecutableParser.ts +2768 -0
  229. package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +346 -0
  230. package/src/debugLogInputParser.ts +28 -0
  231. package/src/debugLogParser.ts +20 -4
  232. package/src/disjunctionParser.ts +10 -5
  233. package/src/elementParser.ts +3 -3
  234. package/src/elementTerminatedArrayParser.test.ts +99 -0
  235. package/src/elementTerminatedArrayParser.ts +31 -0
  236. package/src/elementTerminatedSequenceArrayParser.test.ts +54 -0
  237. package/src/elementTerminatedSequenceArrayParser.ts +52 -0
  238. package/src/elementTerminatedSequenceParser.test.ts +54 -0
  239. package/src/elementTerminatedSequenceParser.ts +43 -0
  240. package/src/endOfInputParser.ts +4 -4
  241. package/src/exactElementParser.ts +18 -12
  242. package/src/exactSequenceParser.ts +24 -3
  243. package/src/fetchCid.ts +125 -0
  244. package/src/fixedLengthSequenceParser.test.ts +77 -0
  245. package/src/fixedLengthSequenceParser.ts +28 -1
  246. package/src/hasExecutable.ts +11 -0
  247. package/src/highResolutionTimer.ts +49 -0
  248. package/src/index.ts +15 -2
  249. package/src/inputReader.test.ts +216 -7
  250. package/src/inputReader.ts +80 -5
  251. package/src/inputReaderState.ts +33 -0
  252. package/src/inspect.ts +9 -0
  253. package/src/javaKeyStore.ts +0 -0
  254. package/src/javaKeyStoreParser.test.ts +22 -0
  255. package/src/javaKeyStoreParser.test.ts.md +103 -0
  256. package/src/javaKeyStoreParser.test.ts.snap +0 -0
  257. package/src/javaKeyStoreParser.ts +136 -0
  258. package/src/jsonParser.test.ts +2 -2
  259. package/src/jsonParser.ts +23 -34
  260. package/src/leb128Parser.test.ts +171 -0
  261. package/src/leb128Parser.ts +125 -0
  262. package/src/listParser.ts +6 -6
  263. package/src/lookaheadParser.ts +19 -0
  264. package/src/negativeLookaheadParser.test.ts +53 -0
  265. package/src/negativeLookaheadParser.ts +36 -0
  266. package/src/nonEmptyArrayParser.test.ts +20 -0
  267. package/src/nonEmptyArrayParser.ts +44 -0
  268. package/src/optionalParser.ts +4 -3
  269. package/src/parser.test.ts +148 -27
  270. package/src/parser.test.ts.md +21 -21
  271. package/src/parser.test.ts.snap +0 -0
  272. package/src/parser.ts +153 -49
  273. package/src/parserAccessorParser.ts +12 -2
  274. package/src/parserConsumedSequenceParser.ts +29 -0
  275. package/src/parserContext.test.ts +38 -7
  276. package/src/parserContext.ts +127 -51
  277. package/src/parserCreatorCompose.ts +25 -7
  278. package/src/parserError.ts +9 -6
  279. package/src/parserImplementationInvariant.ts +2 -2
  280. package/src/parserInputCompanion.ts +102 -0
  281. package/src/promiseCompose.ts +17 -3
  282. package/src/promiseSettled.ts +6 -0
  283. package/src/quantifierParser.ts +25 -0
  284. package/src/separatedArrayParser.test.ts +34 -0
  285. package/src/separatedArrayParser.ts +55 -0
  286. package/src/sequenceBuffer.test.ts +72 -2
  287. package/src/sequenceBuffer.ts +93 -7
  288. package/src/sequenceTerminatedSequenceParser.test.ts +60 -0
  289. package/src/sequenceTerminatedSequenceParser.ts +62 -0
  290. package/src/sequenceUnparser.ts +9 -0
  291. package/src/skipParser.ts +7 -5
  292. package/src/skipToParser.ts +16 -0
  293. package/src/sliceBoundedParser.test.ts +45 -3
  294. package/src/sliceBoundedParser.ts +21 -3
  295. package/src/smali.ts +24 -0
  296. package/src/smaliParser.test.ts +132 -0
  297. package/src/smaliParser.test.ts.md +2320 -0
  298. package/src/smaliParser.test.ts.snap +0 -0
  299. package/src/smaliParser.ts +1166 -0
  300. package/src/terminatedArrayParser.test.ts +258 -0
  301. package/src/terminatedArrayParser.ts +111 -6
  302. package/src/toAsyncIterable.ts +7 -0
  303. package/src/toAsyncIterator.ts +48 -0
  304. package/src/tupleParser.ts +8 -5
  305. package/src/uint8Array.ts +10 -0
  306. package/src/unionParser.test.ts +79 -0
  307. package/src/unionParser.ts +44 -16
  308. package/src/unparser.test.ts +221 -0
  309. package/src/unparser.ts +209 -0
  310. package/src/unparserContext.ts +127 -0
  311. package/src/unparserError.ts +12 -0
  312. package/src/unparserImplementationInvariant.ts +6 -0
  313. package/src/unparserOutputCompanion.ts +24 -0
  314. package/src/zip.ts +10 -22
  315. package/src/zipParser.test.ts +2 -8
  316. package/src/zipParser.ts +223 -146
  317. package/src/zipUnparser.test.ts +119 -0
  318. package/src/zipUnparser.ts +300 -0
  319. package/build/apk.d.ts +0 -13
  320. package/build/apkParser.d.ts +0 -3
  321. package/build/apkParser.js +0 -135
  322. package/build/arbitraryDosDate.d.ts +0 -2
  323. package/build/arbitraryDosDate.js +0 -8
  324. package/build/arbitraryZipEntry.d.ts +0 -3
  325. package/build/arbitraryZipEntry.js +0 -26
  326. package/build/createDisjunctionParser.d.ts +0 -2
  327. package/build/createDisjunctionParser.js +0 -47
  328. package/build/createExactParser.d.ts +0 -2
  329. package/build/createExactParser.js +0 -12
  330. package/build/createSequentialUnionParser.d.ts +0 -2
  331. package/build/createSequentialUnionParser.js +0 -69
  332. package/build/fixedLengthChunkParser.d.ts +0 -2
  333. package/build/fixedLengthChunkParser.js +0 -12
  334. package/build/fixedLengthParser.d.ts +0 -2
  335. package/build/fixedLengthParser.js +0 -12
  336. package/build/inputChunkBuffer.d.ts +0 -15
  337. package/build/inputChunkBuffer.js +0 -40
  338. package/build/inputChunkBuffer.test.js +0 -34
  339. package/build/inputCompanion.d.ts +0 -18
  340. package/build/inputCompanion.js +0 -28
  341. package/build/invariantDefined.d.ts +0 -1
  342. package/build/invariantDefined.js +0 -5
  343. package/build/invariantIdentity.d.ts +0 -3
  344. package/build/invariantIdentity.js +0 -5
  345. package/build/jsonParser2.d.ts +0 -3
  346. package/build/jsonParser2.js +0 -52
  347. package/build/jsonParser2.test.js +0 -22
  348. package/build/negativeLookahead.js +0 -20
  349. package/build/parserCompose.d.ts +0 -3
  350. package/build/parserCompose.js +0 -7
  351. package/build/parserImplementationInvariantInvariant.d.ts +0 -3
  352. package/build/parserImplementationInvariantInvariant.js +0 -15
  353. package/build/promiseFish.d.ts +0 -1
  354. package/build/promiseFish.js +0 -3
  355. package/build/sequenceParser.d.ts +0 -3
  356. package/build/sequenceParser.js +0 -10
  357. package/build/terminatedSequenceParser.d.ts +0 -2
  358. package/build/terminatedSequenceParser.js +0 -24
  359. package/build/zipEntry.d.ts +0 -28
  360. package/build/zipFile.d.ts +0 -32
  361. package/build/zipFileEntry.d.ts +0 -6
  362. package/src/apk.ts +0 -16
  363. package/src/apkParser.test.ts.md +0 -268
  364. package/src/apkParser.test.ts.snap +0 -0
  365. package/src/apkParser.ts +0 -327
  366. package/src/inputCompanion.ts +0 -43
  367. package/src/invariantDefined.ts +0 -6
  368. package/src/invariantIdentity.ts +0 -8
  369. package/src/negativeLookahead.ts +0 -26
  370. /package/build/{apk.js → androidPackage.js} +0 -0
  371. /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
  372. /package/build/{arbitraryDosPermissions.d.ts → androidPackageUnparser.test.d.ts} +0 -0
  373. /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
  374. /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
  375. /package/build/{jsonParser2.test.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
  376. /package/build/{parserParsingInvariant.d.ts → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
  377. /package/build/{parserParsingInvariant.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
  378. /package/build/{zipEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
  379. /package/build/{zipFile.js → javaKeyStore.d.ts} +0 -0
  380. /package/build/{zipFileEntry.js → javaKeyStore.js} +0 -0
@@ -0,0 +1,221 @@
1
+ import test from 'ava';
2
+ import * as fc from 'fast-check';
3
+ import { runUnparser, Unparser } from './unparser.js';
4
+ import { stringUnparserOutputCompanion } from './unparserOutputCompanion.js';
5
+ import { testProp } from '@fast-check/ava';
6
+
7
+ test('writeLater', async t => {
8
+ const stringToBeWrittenBefore = 'before writeLater\n';
9
+ const stringToBeWrittenLater = 'written later\n';
10
+ const stringToBeWrittenAfter = 'after writeLater\n';
11
+
12
+ let expectedPositionA: number | undefined;
13
+ let expectedPositionB: number | undefined;
14
+
15
+ let actualPositionAFromWithinWriteLater: number | undefined;
16
+ let actualPositionBFromWithinWriteLater: number | undefined;
17
+
18
+ const unparser: Unparser<void, string> = async function * (_input, unparserContext) {
19
+ yield stringToBeWrittenBefore
20
+
21
+ expectedPositionA = unparserContext.position;
22
+
23
+ const writeLater = yield * unparserContext.writeLater(stringToBeWrittenLater.length);
24
+
25
+ expectedPositionB = unparserContext.position;
26
+
27
+ yield stringToBeWrittenAfter;
28
+
29
+ yield * unparserContext.writeEarlier(writeLater, async function * (_input, unparserContext) {
30
+ actualPositionAFromWithinWriteLater = unparserContext.position;
31
+
32
+ yield stringToBeWrittenLater;
33
+
34
+ actualPositionBFromWithinWriteLater = unparserContext.position;
35
+ }, undefined);
36
+ };
37
+
38
+ const stringsAsyncIterable = runUnparser(unparser, undefined, stringUnparserOutputCompanion);
39
+
40
+ const strings: string[] = [];
41
+
42
+ for await (const string of stringsAsyncIterable) {
43
+ strings.push(string);
44
+ }
45
+
46
+ const string = strings.join('');
47
+
48
+ t.is(string, stringToBeWrittenBefore + stringToBeWrittenLater + stringToBeWrittenAfter);
49
+
50
+ t.is(actualPositionAFromWithinWriteLater, expectedPositionA, 'position a');
51
+ t.is(actualPositionBFromWithinWriteLater, expectedPositionB, 'position b');
52
+
53
+ t.is(expectedPositionA, stringToBeWrittenBefore.length);
54
+ t.is(expectedPositionB, stringToBeWrittenBefore.length + stringToBeWrittenLater.length);
55
+ });
56
+
57
+ test('writeLater one deep', async t => {
58
+ const unparser: Unparser<void, string> = async function * (_input, unparserContext) {
59
+ yield '(';
60
+ const writeLaterA = yield * unparserContext.writeLater(3);
61
+ yield ')';
62
+
63
+ yield * unparserContext.writeEarlier(writeLaterA, async function * (_input, unparserContext) {
64
+ yield '[';
65
+ const writeLaterB = yield * unparserContext.writeLater(1);
66
+ yield ']';
67
+
68
+ yield * unparserContext.writeEarlier(writeLaterB, async function * (_input, unparserContext) {
69
+ yield 'a';
70
+ }, undefined);
71
+ }, undefined);
72
+ };
73
+
74
+ const stringsAsyncIterable = runUnparser(unparser, undefined, stringUnparserOutputCompanion);
75
+
76
+ const strings: string[] = [];
77
+
78
+ for await (const string of stringsAsyncIterable) {
79
+ strings.push(string);
80
+ }
81
+
82
+ const string = strings.join('');
83
+
84
+ t.is(string, '([a])');
85
+ });
86
+
87
+ test('writeLater deep', async t => {
88
+ const unparser: Unparser<void, string> = async function * (_input, unparserContext) {
89
+ yield '(';
90
+ const writeLaterA = yield * unparserContext.writeLater(5);
91
+ yield ')';
92
+
93
+ let writeLaterC: typeof writeLaterA;
94
+
95
+ yield * unparserContext.writeEarlier(writeLaterA, async function * (_input, unparserContext) {
96
+ yield '[';
97
+ const writeLaterB = yield * unparserContext.writeLater(3);
98
+ yield ']';
99
+
100
+ yield * unparserContext.writeEarlier(writeLaterB, async function * (_input, unparserContext) {
101
+ yield '{';
102
+ writeLaterC = yield * unparserContext.writeLater(1);
103
+ yield '}';
104
+ }, undefined);
105
+ }, undefined);
106
+
107
+ yield * unparserContext.writeEarlier(writeLaterC!, async function * (_input, unparserContext) {
108
+ yield 'a';
109
+ }, undefined);
110
+
111
+ yield 'z';
112
+ };
113
+
114
+ const stringsAsyncIterable = runUnparser(unparser, undefined, stringUnparserOutputCompanion);
115
+
116
+ const strings: string[] = [];
117
+
118
+ for await (const string of stringsAsyncIterable) {
119
+ strings.push(string);
120
+ }
121
+
122
+ const string = strings.join('');
123
+
124
+ t.is(string, '([{a}])z');
125
+ });
126
+
127
+ testProp(
128
+ 'writeLater positions and lengths',
129
+ [
130
+ fc.array(
131
+ fc.oneof(
132
+ fc.array(
133
+ fc.oneof(
134
+ fc.array(
135
+ fc.string(),
136
+ ),
137
+ fc.string(),
138
+ ),
139
+ ),
140
+ fc.string(),
141
+ ),
142
+ ),
143
+ ],
144
+ async (t, stringArray3) => {
145
+ const numberUnparser: Unparser<number, string> = async function * (input, unparserContext) {
146
+ yield input.toString().padStart(8, '0');
147
+ };
148
+
149
+ const createLengthPrefixedUnparser = <T>(
150
+ unparser: Unparser<T, string>,
151
+ ): Unparser<T, string> => {
152
+ return async function * (input, unparserContext) {
153
+ const length = yield * unparserContext.writeLater(8);
154
+ yield * unparser(input, unparserContext);
155
+ yield * unparserContext.writeEarlier(length, numberUnparser, unparserContext.position - length.positionEnd);
156
+ };
157
+ };
158
+
159
+ const unparser0: Unparser<string, string> = createLengthPrefixedUnparser(async function * (input, unparserContext) {
160
+ yield input;
161
+ });
162
+
163
+ const unparser1: Unparser<string[], string> = createLengthPrefixedUnparser(async function * (input, unparserContext) {
164
+ for (const string of input) {
165
+ yield * unparser0(string, unparserContext);
166
+ }
167
+ });
168
+
169
+ const unparser2: Unparser<(string | string[])[], string> = createLengthPrefixedUnparser(async function * (input, unparserContext) {
170
+ for (const stringArray2 of input) {
171
+ if (typeof stringArray2 === 'string') {
172
+ yield * unparser0(stringArray2, unparserContext);
173
+ } else {
174
+ yield * unparser1(stringArray2, unparserContext);
175
+ }
176
+ }
177
+ });
178
+
179
+ const unparser3: Unparser<(string | (string | string[])[])[], string> = createLengthPrefixedUnparser(async function * (input, unparserContext) {
180
+ for (const stringArray3 of input) {
181
+ if (typeof stringArray3 === 'string') {
182
+ yield * unparser0(stringArray3, unparserContext);
183
+ } else {
184
+ yield * unparser2(stringArray3, unparserContext);
185
+ }
186
+ }
187
+ });
188
+
189
+ const stringsAsyncIterable = runUnparser(unparser3, stringArray3, stringUnparserOutputCompanion);
190
+
191
+ const strings: string[] = [];
192
+
193
+ for await (const string of stringsAsyncIterable) {
194
+ strings.push(string);
195
+ }
196
+
197
+ const actualString = strings.join('');
198
+
199
+ type DeepArray<T> = T | DeepArray<T>[];
200
+
201
+ function getExpectedString(stringArray: DeepArray<string>): string {
202
+ let expectedString = stringArray;
203
+
204
+ if (typeof stringArray !== 'string') {
205
+ expectedString = stringArray.map(getExpectedString).join('');
206
+ }
207
+
208
+ return [
209
+ expectedString.length.toString().padStart(8, '0'),
210
+ expectedString,
211
+ ].join('');
212
+ }
213
+
214
+ const expectedString = getExpectedString(stringArray3);
215
+
216
+ t.deepEqual(actualString, expectedString);
217
+ },
218
+ {
219
+ verbose: true,
220
+ },
221
+ );
@@ -0,0 +1,209 @@
1
+ import invariant from "invariant";
2
+ import { DeriveSequenceElement } from "./sequence.js";
3
+ import { UnparserContext, UnparserContextImplementation, WriteEarlier, WriteLater } from "./unparserContext.js";
4
+ import { UnparserOutputCompanion } from "./unparserOutputCompanion.js";
5
+ import { unparserImplementationInvariant } from "./unparserImplementationInvariant.js";
6
+
7
+ type UnparserIterableValue<Sequence, Element> =
8
+ | Sequence
9
+ | Element
10
+ | WriteLater<Sequence, Element>
11
+ | WriteEarlier<Sequence, Element>
12
+ ;
13
+
14
+ type UnparserIterableValue_<Sequence, Element> =
15
+ | Sequence
16
+ | WriteLater<Sequence, Element>
17
+ | WriteEarlier<Sequence, Element>
18
+ ;
19
+
20
+ export type UnparserResult<Sequence, Element> = AsyncIterable<UnparserIterableValue<Sequence, Element>>;
21
+
22
+ type UnparserResult_<Sequence, Element> = AsyncIterable<UnparserIterableValue_<Sequence, Element>>;
23
+
24
+ export type Unparser<
25
+ Input,
26
+ Sequence,
27
+ Element = DeriveSequenceElement<Sequence>,
28
+ > = (
29
+ input: Input,
30
+ unparserContext: UnparserContext<Sequence, Element>,
31
+ ) => UnparserResult<Sequence, Element>;
32
+
33
+ async function * onYield<T>(asyncIterable: AsyncIterable<T>, onYield: (value: T) => void): AsyncIterable<T> {
34
+ for await (const value of asyncIterable) {
35
+ onYield(value);
36
+ yield value;
37
+ }
38
+ }
39
+
40
+ async function * elementsToSequences<
41
+ Sequence,
42
+ Element,
43
+ >(
44
+ values: UnparserResult<Sequence, Element>,
45
+ unparserOutputCompanion: UnparserOutputCompanion<Sequence, Element>,
46
+ ): UnparserResult_<Sequence, Element> {
47
+ let elements: Element[] = [];
48
+
49
+ for await (const value of values) {
50
+ if (
51
+ value instanceof WriteLater
52
+ || value instanceof WriteEarlier
53
+ ) {
54
+ if (elements.length > 0) {
55
+ const sequence = unparserOutputCompanion.from(elements);
56
+ yield sequence;
57
+ elements = [];
58
+ }
59
+
60
+ yield value;
61
+ } else if (unparserOutputCompanion.is(value)) {
62
+ if (unparserOutputCompanion.length(value) === 0) {
63
+ continue;
64
+ }
65
+
66
+ if (elements.length > 0) {
67
+ const sequence = unparserOutputCompanion.from(elements);
68
+ yield sequence;
69
+ elements = [];
70
+ }
71
+
72
+ yield value;
73
+ } else {
74
+ elements.push(value);
75
+ }
76
+ }
77
+
78
+ if (elements.length > 0) {
79
+ const sequence = unparserOutputCompanion.from(elements);
80
+ yield sequence;
81
+ }
82
+ }
83
+
84
+ function wrapUnparserResult<Sequence, Element>(
85
+ unparserResult: UnparserResult<Sequence, Element>,
86
+ unparserContext: UnparserContextImplementation<Sequence, Element>,
87
+ unparserOutputCompanion: UnparserOutputCompanion<Sequence, Element>,
88
+ ): UnparserResult_<Sequence, Element> {
89
+ return onYield(
90
+ elementsToSequences(
91
+ unparserResult,
92
+ unparserOutputCompanion,
93
+ ),
94
+ value => unparserContext.handleYield(value),
95
+ );
96
+ }
97
+
98
+ export async function * runUnparser<
99
+ Input,
100
+ Sequence,
101
+ Element = DeriveSequenceElement<Sequence>,
102
+ >(
103
+ unparser: Unparser<Input, Sequence, Element>,
104
+ input: Input,
105
+ unparserOutputCompanion: UnparserOutputCompanion<Sequence, Element>,
106
+ ): AsyncIterable<Sequence> {
107
+ const unparserContext = new UnparserContextImplementation(unparserOutputCompanion);
108
+
109
+ const values = unparser(input, unparserContext);
110
+ const valuesWithoutElements = wrapUnparserResult(
111
+ values,
112
+ unparserContext,
113
+ unparserOutputCompanion,
114
+ );
115
+
116
+ const outputQueue: Array<WriteLater<Sequence, Element> | Sequence> = [];
117
+
118
+ type Iterator = AsyncIterator<UnparserIterableValue_<Sequence, Element>, void>;
119
+ type PushOutput = (value: Sequence | WriteLater<Sequence, Element>) => void;
120
+ type FinishOutput = () => void;
121
+
122
+ const iteratorStack: [ Iterator, PushOutput, FinishOutput ][] = [
123
+ [
124
+ valuesWithoutElements[Symbol.asyncIterator](),
125
+ value => outputQueue.push(value),
126
+ () => {},
127
+ ],
128
+ ];
129
+
130
+ while (true) {
131
+ while (
132
+ outputQueue.length > 0
133
+ && !(outputQueue[0] instanceof WriteLater)
134
+ ) {
135
+ yield outputQueue.shift() as Sequence;
136
+ }
137
+
138
+ if (iteratorStack.length === 0) {
139
+ break;
140
+ }
141
+
142
+ const [ iterator, pushOutput, finishOutput ] = iteratorStack[0];
143
+
144
+ const iteratorResult = await iterator.next();
145
+
146
+ if (iteratorResult.done) {
147
+ finishOutput();
148
+ iteratorStack.shift();
149
+ continue;
150
+ }
151
+
152
+ const { value } = iteratorResult;
153
+
154
+ if (value instanceof WriteEarlier) {
155
+ const { writeLater, unparserResult, unparserContext } = value;
156
+
157
+ invariant(
158
+ unparserContext instanceof UnparserContextImplementation,
159
+ 'UnparserContext not an instance of UnparserContextImplementation.',
160
+ );
161
+
162
+ function getOutputQueueWriteLaterIndex() {
163
+ const outputQueueWriteLaterIndex = outputQueue.indexOf(writeLater);
164
+
165
+ unparserImplementationInvariant(
166
+ outputQueueWriteLaterIndex !== -1,
167
+ [
168
+ 'WriteLater has already been written or was not yielded yet.',
169
+ 'WriteLater stack: %s',
170
+ 'End of WriteLater stack.',
171
+ ],
172
+ writeLater.stack,
173
+ );
174
+
175
+ return outputQueueWriteLaterIndex;
176
+ }
177
+
178
+ const unparserResultWithoutElements = wrapUnparserResult(
179
+ unparserResult,
180
+ unparserContext,
181
+ unparserOutputCompanion,
182
+ );
183
+
184
+ const newPushOutput: PushOutput = value => {
185
+ const outputQueueWriteLaterIndex = getOutputQueueWriteLaterIndex();
186
+ outputQueue.splice(outputQueueWriteLaterIndex, 0, value);
187
+ };
188
+
189
+ const newFinishOutput: FinishOutput = () => {
190
+ const outputQueueWriteLaterIndex = getOutputQueueWriteLaterIndex();
191
+ const [ removedValue ] = outputQueue.splice(outputQueueWriteLaterIndex, 1);
192
+ invariant(
193
+ removedValue === writeLater,
194
+ 'WriteLater was not removed from the output queue.',
195
+ );
196
+ };
197
+
198
+ iteratorStack.unshift([
199
+ unparserResultWithoutElements[Symbol.asyncIterator](),
200
+ newPushOutput,
201
+ newFinishOutput,
202
+ ]);
203
+
204
+ continue;
205
+ }
206
+
207
+ pushOutput(value);
208
+ }
209
+ }
@@ -0,0 +1,127 @@
1
+ /* eslint-disable prefer-arrow-callback */
2
+
3
+ import { Unparser, UnparserResult } from "./unparser.js";
4
+ import { UnparserOutputCompanion } from "./unparserOutputCompanion.js";
5
+ import { unparserImplementationInvariant } from "./unparserImplementationInvariant.js";
6
+ import { parserImplementationInvariant } from "./parserImplementationInvariant.js";
7
+
8
+ export type UnparserContext<Sequence, Element> = {
9
+ get position(): number;
10
+
11
+ writeLater(length: number): AsyncIterable<WriteLater<Sequence, Element>, WriteLater<Sequence, Element>>;
12
+ writeEarlier<Input>(
13
+ writeLater: WriteLater<Sequence, Element>,
14
+ unparser: Unparser<Input, Sequence, Element>,
15
+ input: Input,
16
+ ): AsyncIterable<WriteEarlier<Sequence, Element>, void>;
17
+ };
18
+
19
+ export class WriteLater<Sequence, Element> extends Error {
20
+ name = 'WriteLater';
21
+
22
+ constructor (
23
+ private readonly _position: number,
24
+ private readonly _length: number,
25
+ ) {
26
+ super(`(position: ${_position}, length: ${_length})`);
27
+ }
28
+
29
+ get position() {
30
+ return this._position;
31
+ }
32
+
33
+ get positionEnd() {
34
+ return this._position + this._length;
35
+ }
36
+
37
+ get length() {
38
+ return this._length;
39
+ }
40
+ }
41
+
42
+ export class WriteEarlier<Sequence, Element> {
43
+ constructor(
44
+ public readonly writeLater: WriteLater<Sequence, Element>,
45
+ public readonly unparserResult: UnparserResult<Sequence, Element>,
46
+ public readonly unparserContext: UnparserContext<Sequence, Element>,
47
+ ) {}
48
+ }
49
+
50
+ export class UnparserContextImplementation<Sequence, Element> implements UnparserContext<Sequence, Element> {
51
+ private _position: number;
52
+
53
+ constructor(
54
+ private readonly _outputCompanion: UnparserOutputCompanion<Sequence, Element>,
55
+ position = 0,
56
+ ) {
57
+ this._position = position;
58
+ }
59
+
60
+ get position() {
61
+ return this._position;
62
+ }
63
+
64
+ async * writeLater(length: number): AsyncIterable<WriteLater<Sequence, Element>, WriteLater<Sequence, Element>> {
65
+ parserImplementationInvariant(
66
+ length >= 0,
67
+ 'Length of WriteLater must be non-negative, got %s.',
68
+ length,
69
+ );
70
+
71
+ const writeLater = new WriteLater<Sequence, Element>(this._position, length);
72
+ yield writeLater;
73
+ return writeLater;
74
+ }
75
+
76
+ async * writeEarlier<Input>(
77
+ writeLater: WriteLater<Sequence, Element>,
78
+ unparser: Unparser<Input, Sequence, Element>,
79
+ input: Input,
80
+ ): AsyncIterable<WriteEarlier<Sequence, Element>, void> {
81
+ const unparserContext = new UnparserContextImplementation(this._outputCompanion, writeLater.position);
82
+ yield new WriteEarlier(
83
+ writeLater,
84
+ (async function * () {
85
+ const startPosition = unparserContext.position;
86
+
87
+ yield * unparser(input, unparserContext);
88
+
89
+ const endPosition = unparserContext.position;
90
+ const writtenLength = endPosition - startPosition;
91
+
92
+ unparserImplementationInvariant(
93
+ writtenLength === writeLater.length,
94
+ [
95
+ 'WriteEarlier was supposed to write %s elements but wrote %s elements instead.',
96
+ 'Corresponding WriteLater stack (this is where it was created): %s',
97
+ 'End of corresponding WriteEarlier stack.',
98
+ ],
99
+ writeLater.length,
100
+ writtenLength,
101
+ writeLater.stack,
102
+ );
103
+ })(),
104
+ unparserContext,
105
+ );
106
+ }
107
+
108
+ handleYield(
109
+ value:
110
+ | Sequence
111
+ | WriteLater<Sequence, Element>
112
+ | WriteEarlier<Sequence, Element>
113
+ ,
114
+ ) {
115
+ if (value instanceof WriteEarlier) {
116
+ return;
117
+ }
118
+
119
+ if (value instanceof WriteLater) {
120
+ this._position += value.length;
121
+ return;
122
+ }
123
+
124
+ const length = this._outputCompanion.length(value);
125
+ this._position += length;
126
+ }
127
+ }
@@ -0,0 +1,12 @@
1
+
2
+ export class UnparserError extends Error {
3
+ name = 'UnparserError';
4
+ }
5
+
6
+ export class UnparserImplementationError extends UnparserError {
7
+ name = 'UnparserImplementationError';
8
+ }
9
+
10
+ export class UnparserImplementationInvariantError extends UnparserImplementationError {
11
+ name = 'UnparserImplementationInvariantError';
12
+ }
@@ -0,0 +1,6 @@
1
+ import { UnparserImplementationInvariantError } from './unparserError.js';
2
+ import { type Falsy, customInvariant, type ValueOrAccessor } from './customInvariant.js';
3
+
4
+ export function unparserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: any[]): Exclude<T, Falsy> {
5
+ return customInvariant(UnparserImplementationInvariantError, value, format, ...formatArguments);
6
+ }
@@ -0,0 +1,24 @@
1
+ import { StringParserInputCompanion, Uint8ArrayParserInputCompanion } from "./parserInputCompanion.js";
2
+
3
+ export type UnparserOutputCompanion<Sequence, Element> = {
4
+ is(value: unknown): value is Sequence;
5
+ from(elements: Element[]): Sequence;
6
+ concat(sequences: Sequence[]): Sequence;
7
+ length(sequence: Sequence): number;
8
+ };
9
+
10
+ export class StringUnparserOutputCompanion extends StringParserInputCompanion implements UnparserOutputCompanion<string, string> {
11
+ concat(sequences: string[]): string {
12
+ return sequences.join('');
13
+ }
14
+ }
15
+
16
+ export const stringUnparserOutputCompanion = new StringUnparserOutputCompanion();
17
+
18
+ export class Uint8ArrayUnparserOutputCompanion extends Uint8ArrayParserInputCompanion implements UnparserOutputCompanion<Uint8Array, number> {
19
+ concat(sequences: Uint8Array[]): Uint8Array {
20
+ return Buffer.concat(sequences);
21
+ }
22
+ }
23
+
24
+ export const uint8ArrayUnparserOutputCompanion = new Uint8ArrayUnparserOutputCompanion();
package/src/zip.ts CHANGED
@@ -4,37 +4,25 @@ export type ZipCompression =
4
4
  | 'deflate'
5
5
  ;
6
6
 
7
- export type ZipUnixPermissions = {
8
- type: 'unix';
9
- unixPermissions: number;
7
+ export type ZipEntryAttributes = {
10
8
  };
11
9
 
12
- export type ZipDosPermissions = {
13
- type: 'dos';
14
- dosPermissions: number;
15
- };
16
-
17
- export type ZipPermissions =
18
- | ZipUnixPermissions
19
- | ZipDosPermissions
20
- ;
21
-
22
- export type ZipFileEntry = {
23
- type: 'file';
10
+ type ZipEntryCommon = {
24
11
  path: string;
25
12
  date: Date;
26
13
  comment: string;
27
- permissions: ZipPermissions;
14
+ hostSystem: 'unix' | 'dos';
15
+ attributes: ZipEntryAttributes;
16
+ };
17
+
18
+ export type ZipFileEntry = ZipEntryCommon & {
19
+ type: 'file';
28
20
  compression: ZipCompression;
29
21
  content: Uint8Array;
30
22
  };
31
23
 
32
- export type ZipDirectoryEntry = {
24
+ export type ZipDirectoryEntry = ZipEntryCommon & {
33
25
  type: 'directory';
34
- path: string;
35
- date: Date;
36
- comment: string;
37
- permissions: ZipPermissions;
38
26
  };
39
27
 
40
28
  export type ZipEntry =
@@ -45,4 +33,4 @@ export type ZipEntry =
45
33
  export type Zip = {
46
34
  comment: string;
47
35
  entries: ZipEntry[];
48
- }
36
+ };
@@ -1,22 +1,16 @@
1
1
  import { testProp } from '@fast-check/ava';
2
2
  import { arbitraryZipStream } from './arbitraryZipStream.js';
3
3
  import { zipParser } from './zipParser.js';
4
- import { uint8ArrayInputCompanion } from './inputCompanion.js';
4
+ import { uint8ArrayParserInputCompanion } from './parserInputCompanion.js';
5
5
  import { runParser } from './parser.js';
6
6
 
7
- async function * readableStreamToUint8ArrayAsyncIterator(stream: ReadableStream<Uint8Array>) {
8
- for await (const chunk of stream) {
9
- yield chunk;
10
- }
11
- }
12
-
13
7
  testProp(
14
8
  'zip',
15
9
  [
16
10
  arbitraryZipStream,
17
11
  ],
18
12
  async (t, [ zip, zipStream ]) => {
19
- const actual = await runParser(zipParser, readableStreamToUint8ArrayAsyncIterator(zipStream), uint8ArrayInputCompanion, {
13
+ const actual = await runParser(zipParser, zipStream, uint8ArrayParserInputCompanion, {
20
14
  errorJoinMode: 'all',
21
15
  });
22
16