@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.
- package/.github/copilot-instructions.md +149 -0
- package/.github/workflows/copilot-setup-steps.yml +18 -0
- package/.github/workflows/main.yml +29 -8
- package/.yarn/releases/yarn-4.9.4.cjs +942 -0
- package/.yarnrc.yml +1 -1
- package/build/allSettledStream.js +32 -14
- package/build/allSettledStream.test.js +32 -0
- package/build/androidPackage.d.ts +39 -0
- package/build/androidPackageParser.d.ts +17 -0
- package/build/androidPackageParser.js +185 -0
- package/build/androidPackageParser.test.js +22 -0
- package/build/androidPackageUnparser.d.ts +4 -0
- package/build/androidPackageUnparser.js +94 -0
- package/build/androidPackageUnparser.test.js +26 -0
- package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
- package/build/arbitrarilySlicedAsyncInterable.js +3 -3
- package/build/arbitrarilySlicedAsyncInterator.js +2 -1
- package/build/arbitraryDalvikBytecode.d.ts +4 -0
- package/build/arbitraryDalvikBytecode.js +640 -0
- package/build/arbitraryDalvikExecutable.d.ts +3 -0
- package/build/arbitraryDalvikExecutable.js +282 -0
- package/build/arbitraryDosDateTime.js +1 -0
- package/build/arbitraryZipStream.js +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayParser.test.js +3 -3
- package/build/arrayUnparser.d.ts +1 -1
- package/build/backsmali.d.ts +3 -0
- package/build/backsmali.js +50 -0
- package/build/bsonParser.js +6 -2
- package/build/customInvariant.d.ts +2 -1
- package/build/customInvariant.js +4 -6
- package/build/dalvikBytecodeParser/formatParsers.d.ts +171 -0
- package/build/dalvikBytecodeParser/formatParsers.js +304 -0
- package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
- package/build/dalvikBytecodeParser/formatSizes.js +34 -0
- package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
- package/build/dalvikBytecodeParser/operationFormats.js +225 -0
- package/build/dalvikBytecodeParser.d.ts +1207 -0
- package/build/dalvikBytecodeParser.js +1289 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
- package/build/dalvikBytecodeUnparser.d.ts +3 -0
- package/build/dalvikBytecodeUnparser.js +642 -0
- package/build/dalvikBytecodeUnparser.test.js +25 -0
- package/build/dalvikExecutable.d.ts +215 -0
- package/build/dalvikExecutable.js +56 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
- package/build/dalvikExecutableParser/typeParsers.d.ts +11 -0
- package/build/dalvikExecutableParser/typeParsers.js +39 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +106 -0
- package/build/dalvikExecutableParser/typedNumbers.js +18 -0
- package/build/dalvikExecutableParser.d.ts +5 -0
- package/build/dalvikExecutableParser.js +1757 -0
- package/build/dalvikExecutableParser.test.js +72 -0
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +275 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
- package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
- package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
- package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
- package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
- package/build/dalvikExecutableUnparser/utils.js +108 -0
- package/build/dalvikExecutableUnparser.d.ts +4 -0
- package/build/dalvikExecutableUnparser.js +406 -0
- package/build/dalvikExecutableUnparser.test.js +31 -0
- package/build/debugLogInputParser.d.ts +4 -0
- package/build/debugLogInputParser.js +16 -0
- package/build/debugLogParser.js +14 -3
- package/build/disjunctionParser.d.ts +2 -1
- package/build/disjunctionParser.js +6 -4
- package/build/elementTerminatedArrayParser.d.ts +3 -0
- package/build/elementTerminatedArrayParser.js +18 -0
- package/build/elementTerminatedArrayParser.test.js +52 -0
- package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
- package/build/elementTerminatedSequenceArrayParser.js +32 -0
- package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
- package/build/elementTerminatedSequenceParser.d.ts +3 -0
- package/build/elementTerminatedSequenceParser.js +27 -0
- package/build/elementTerminatedSequenceParser.test.js +34 -0
- package/build/endOfInputParser.d.ts +1 -1
- package/build/exactElementParser.js +10 -5
- package/build/exactElementSwitchParser.d.ts +3 -0
- package/build/exactElementSwitchParser.js +22 -0
- package/build/exactSequenceParser.d.ts +2 -1
- package/build/exactSequenceParser.js +12 -2
- package/build/fetchCid.d.ts +1 -0
- package/build/fetchCid.js +103 -0
- package/build/fetchCid.test.js +16 -0
- package/build/fixedLengthSequenceParser.d.ts +1 -0
- package/build/fixedLengthSequenceParser.js +18 -1
- package/build/fixedLengthSequenceParser.test.js +41 -0
- package/build/hasExecutable.d.ts +1 -0
- package/build/hasExecutable.js +8 -0
- package/build/highResolutionTimer.d.ts +16 -0
- package/build/highResolutionTimer.js +42 -0
- package/build/inputReader.d.ts +11 -0
- package/build/inputReader.js +37 -0
- package/build/inputReader.test.js +161 -8
- package/build/inputReaderState.d.ts +10 -0
- package/build/inputReaderState.js +16 -0
- package/build/inspect.d.ts +1 -0
- package/build/inspect.js +7 -0
- package/build/javaKeyStoreParser.test.js +8 -8
- package/build/jsonParser.d.ts +2 -0
- package/build/jsonParser.js +19 -22
- package/build/lazyMessageError.d.ts +48 -0
- package/build/lazyMessageError.js +53 -0
- package/build/lazyMessageError.test.d.ts +1 -0
- package/build/lazyMessageError.test.js +15 -0
- package/build/leb128Parser.d.ts +7 -0
- package/build/leb128Parser.js +82 -0
- package/build/leb128Parser.test.d.ts +1 -0
- package/build/leb128Parser.test.js +107 -0
- package/build/lookaheadParser.d.ts +2 -0
- package/build/lookaheadParser.js +14 -0
- package/build/negativeLookaheadParser.js +22 -16
- package/build/negativeLookaheadParser.test.d.ts +1 -0
- package/build/negativeLookaheadParser.test.js +30 -0
- package/build/noStackCaptureOverheadError.d.ts +4 -0
- package/build/noStackCaptureOverheadError.js +9 -0
- package/build/noStackCaptureOverheadError.test.d.ts +1 -0
- package/build/noStackCaptureOverheadError.test.js +15 -0
- package/build/nonEmptyArrayParser.d.ts +2 -0
- package/build/nonEmptyArrayParser.js +32 -0
- package/build/nonEmptyArrayParser.test.d.ts +1 -0
- package/build/nonEmptyArrayParser.test.js +17 -0
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +11 -1
- package/build/parser.js +82 -32
- package/build/parser.test.js +141 -25
- package/build/parserAccessorParser.js +9 -1
- package/build/parserConsumedSequenceParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.js +21 -16
- package/build/parserContext.d.ts +22 -6
- package/build/parserContext.js +113 -57
- package/build/parserContext.test.js +33 -2
- package/build/parserCreatorCompose.d.ts +1 -0
- package/build/parserCreatorCompose.js +8 -2
- package/build/parserError.d.ts +605 -40
- package/build/parserError.js +98 -53
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.d.ts +15 -0
- package/build/parserInputCompanion.js +38 -0
- package/build/promiseCompose.d.ts +1 -1
- package/build/promiseCompose.js +11 -1
- package/build/promiseSettled.d.ts +1 -0
- package/build/promiseSettled.js +4 -0
- package/build/separatedArrayParser.d.ts +2 -0
- package/build/separatedArrayParser.js +39 -0
- package/build/separatedArrayParser.test.d.ts +1 -0
- package/build/separatedArrayParser.test.js +21 -0
- package/build/separatedNonEmptyArrayParser.d.ts +2 -0
- package/build/separatedNonEmptyArrayParser.js +40 -0
- package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
- package/build/separatedNonEmptyArrayParser.test.js +66 -0
- package/build/sequenceBuffer.d.ts +10 -0
- package/build/sequenceBuffer.js +54 -2
- package/build/sequenceBuffer.test.js +57 -0
- package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
- package/build/sequenceTerminatedSequenceParser.js +32 -0
- package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
- package/build/sequenceTerminatedSequenceParser.test.js +37 -0
- package/build/sequenceUnparser.d.ts +1 -1
- package/build/skipParser.d.ts +1 -1
- package/build/skipParser.js +4 -2
- package/build/skipToParser.d.ts +2 -0
- package/build/skipToParser.js +11 -0
- package/build/sliceBoundedParser.d.ts +1 -1
- package/build/sliceBoundedParser.js +7 -2
- package/build/sliceBoundedParser.test.js +30 -1
- package/build/smali.d.ts +1 -0
- package/build/smali.js +21 -0
- package/build/smaliParser.d.ts +68 -0
- package/build/smaliParser.js +2081 -0
- package/build/smaliParser.test.d.ts +1 -0
- package/build/smaliParser.test.js +410 -0
- package/build/stringFromAsyncIterable.d.ts +1 -0
- package/build/stringFromAsyncIterable.js +7 -0
- package/build/terminatedArrayParser.d.ts +3 -1
- package/build/terminatedArrayParser.js +79 -2
- package/build/terminatedArrayParser.test.d.ts +1 -0
- package/build/terminatedArrayParser.test.js +131 -0
- package/build/toAsyncIterable.d.ts +1 -0
- package/build/toAsyncIterable.js +7 -0
- package/build/toAsyncIterator.d.ts +1 -0
- package/build/toAsyncIterator.js +33 -0
- package/build/tupleParser.d.ts +4 -0
- package/build/tupleParser.js +1 -5
- package/build/unionParser.d.ts +2 -1
- package/build/unionParser.js +29 -14
- package/build/unionParser.test.d.ts +1 -0
- package/build/unionParser.test.js +60 -0
- package/build/unparser.d.ts +3 -3
- package/build/unparser.js +6 -4
- package/build/unparser.test.js +7 -19
- package/build/unparserContext.d.ts +2 -2
- package/build/unparserContext.js +2 -3
- package/build/unparserError.d.ts +2 -1
- package/build/unparserError.js +2 -1
- package/build/unparserImplementationInvariant.d.ts +1 -1
- package/build/unparserOutputCompanion.d.ts +1 -1
- package/build/unparserOutputCompanion.js +1 -1
- package/build/zipParser.d.ts +7 -2
- package/build/zipParser.js +36 -12
- package/build/zipUnparser.d.ts +7 -4
- package/build/zipUnparser.js +64 -45
- package/build/zipUnparser.test.js +15 -15
- package/package.json +33 -24
- package/src/allSettledStream.test.ts +40 -0
- package/src/allSettledStream.ts +47 -15
- package/src/androidPackage.ts +48 -0
- package/src/androidPackageParser.test.ts +27 -0
- package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
- package/src/androidPackageParser.test.ts.snap +0 -0
- package/src/androidPackageParser.ts +398 -0
- package/src/androidPackageUnparser.test.ts +34 -0
- package/src/androidPackageUnparser.ts +126 -0
- package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
- package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
- package/src/arbitraryDalvikBytecode.ts +992 -0
- package/src/arbitraryDalvikExecutable.ts +434 -0
- package/src/arbitraryDosDateTime.ts +1 -0
- package/src/arbitraryZipStream.ts +1 -1
- package/src/arrayParser.test.ts +3 -3
- package/src/arrayParser.ts +2 -2
- package/src/arrayUnparser.ts +2 -2
- package/src/backsmali.ts +74 -0
- package/src/bsonParser.test.ts +12 -14
- package/src/bsonParser.ts +13 -2
- package/src/customInvariant.ts +8 -12
- package/src/dalvikBytecodeParser/formatParsers.ts +780 -0
- package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
- package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
- package/src/dalvikBytecodeParser.ts +2873 -0
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
- package/src/dalvikBytecodeUnparser.test.ts +44 -0
- package/src/dalvikBytecodeUnparser.ts +758 -0
- package/src/dalvikExecutable.ts +282 -0
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
- package/src/dalvikExecutableParser/typeParsers.ts +74 -0
- package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
- package/src/dalvikExecutableParser.test.ts +89 -0
- package/src/dalvikExecutableParser.test.ts.md +634 -0
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +3245 -0
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +363 -0
- package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
- package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
- package/src/dalvikExecutableUnparser/utils.ts +149 -0
- package/src/dalvikExecutableUnparser.test.ts +57 -0
- package/src/dalvikExecutableUnparser.ts +581 -0
- package/src/debugLogInputParser.ts +28 -0
- package/src/debugLogParser.ts +19 -3
- package/src/disjunctionParser.ts +12 -7
- package/src/elementTerminatedArrayParser.test.ts +99 -0
- package/src/elementTerminatedArrayParser.ts +31 -0
- package/src/elementTerminatedSequenceArrayParser.test.ts +52 -0
- package/src/elementTerminatedSequenceArrayParser.ts +52 -0
- package/src/elementTerminatedSequenceParser.test.ts +52 -0
- package/src/elementTerminatedSequenceParser.ts +43 -0
- package/src/endOfInputParser.ts +1 -1
- package/src/exactElementParser.ts +17 -11
- package/src/exactElementSwitchParser.ts +41 -0
- package/src/exactSequenceParser.ts +23 -2
- package/src/fetchCid.test.ts +20 -0
- package/src/fetchCid.ts +121 -0
- package/src/fixedLengthSequenceParser.test.ts +75 -0
- package/src/fixedLengthSequenceParser.ts +28 -1
- package/src/hasExecutable.ts +11 -0
- package/src/highResolutionTimer.ts +49 -0
- package/src/inputReader.test.ts +204 -8
- package/src/inputReader.ts +76 -3
- package/src/inputReaderState.ts +33 -0
- package/src/inspect.ts +9 -0
- package/src/javaKeyStoreParser.test.ts +12 -15
- package/src/javaKeyStoreParser.ts +2 -6
- package/src/jsonParser.test.ts +2 -4
- package/src/jsonParser.ts +46 -62
- package/src/lazyMessageError.test.ts +21 -0
- package/src/lazyMessageError.ts +88 -0
- package/src/leb128Parser.test.ts +173 -0
- package/src/leb128Parser.ts +125 -0
- package/src/lookaheadParser.ts +19 -0
- package/src/negativeLookaheadParser.test.ts +49 -0
- package/src/negativeLookaheadParser.ts +27 -15
- package/src/noStackCaptureOverheadError.test.ts +17 -0
- package/src/noStackCaptureOverheadError.ts +12 -0
- package/src/nonEmptyArrayParser.test.ts +21 -0
- package/src/nonEmptyArrayParser.ts +44 -0
- package/src/optionalParser.ts +3 -2
- package/src/parser.test.ts +203 -31
- package/src/parser.test.ts.md +34 -27
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +172 -45
- package/src/parserAccessorParser.ts +12 -2
- package/src/parserConsumedSequenceParser.ts +26 -17
- package/src/parserContext.test.ts +37 -2
- package/src/parserContext.ts +185 -79
- package/src/parserCreatorCompose.ts +20 -2
- package/src/parserError.ts +144 -61
- package/src/parserImplementationInvariant.ts +3 -3
- package/src/parserInputCompanion.ts +55 -0
- package/src/promiseCompose.ts +17 -3
- package/src/promiseSettled.ts +6 -0
- package/src/separatedArrayParser.test.ts +34 -0
- package/src/separatedArrayParser.ts +55 -0
- package/src/separatedNonEmptyArrayParser.test.ts +117 -0
- package/src/separatedNonEmptyArrayParser.ts +61 -0
- package/src/sequenceBuffer.test.ts +70 -0
- package/src/sequenceBuffer.ts +88 -2
- package/src/sequenceTerminatedSequenceParser.test.ts +58 -0
- package/src/sequenceTerminatedSequenceParser.ts +62 -0
- package/src/sequenceUnparser.ts +2 -2
- package/src/skipParser.ts +7 -5
- package/src/skipToParser.ts +16 -0
- package/src/sliceBoundedParser.test.ts +35 -1
- package/src/sliceBoundedParser.ts +19 -1
- package/src/smali.ts +29 -0
- package/src/smaliParser.test.ts +443 -0
- package/src/smaliParser.test.ts.md +3907 -0
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +3348 -0
- package/src/stringFromAsyncIterable.ts +9 -0
- package/src/terminatedArrayParser.test.ts +258 -0
- package/src/terminatedArrayParser.ts +109 -6
- package/src/toAsyncIterable.ts +7 -0
- package/src/toAsyncIterator.ts +48 -0
- package/src/tupleParser.ts +8 -5
- package/src/uint8Array.ts +2 -3
- package/src/unionParser.test.ts +78 -0
- package/src/unionParser.ts +47 -21
- package/src/unparser.test.ts +18 -34
- package/src/unparser.ts +13 -9
- package/src/unparserContext.ts +9 -13
- package/src/unparserError.ts +2 -1
- package/src/unparserImplementationInvariant.ts +1 -1
- package/src/unparserOutputCompanion.ts +1 -1
- package/src/zip.ts +2 -6
- package/src/zipParser.ts +71 -20
- package/src/zipUnparser.test.ts +19 -19
- package/src/zipUnparser.ts +139 -90
- package/tsconfig.json +7 -1
- package/xo.config.ts +15 -0
- package/.yarn/releases/yarn-4.5.3.cjs +0 -934
- package/build/apk.d.ts +0 -39
- package/build/apkParser.d.ts +0 -16
- package/build/apkParser.js +0 -164
- package/build/apkParser.test.js +0 -22
- package/build/apkUnparser.d.ts +0 -4
- package/build/apkUnparser.js +0 -90
- package/build/apkUnparser.test.js +0 -26
- package/build/arbitraryDosDate.d.ts +0 -2
- package/build/arbitraryDosDate.js +0 -8
- package/build/arbitraryZipEntry.d.ts +0 -3
- package/build/arbitraryZipEntry.js +0 -26
- package/build/createDisjunctionParser.d.ts +0 -2
- package/build/createDisjunctionParser.js +0 -47
- package/build/createExactParser.d.ts +0 -2
- package/build/createExactParser.js +0 -12
- package/build/createSequentialUnionParser.d.ts +0 -2
- package/build/createSequentialUnionParser.js +0 -69
- package/build/fixedLengthChunkParser.d.ts +0 -2
- package/build/fixedLengthChunkParser.js +0 -12
- package/build/fixedLengthParser.d.ts +0 -2
- package/build/fixedLengthParser.js +0 -12
- package/build/inputChunkBuffer.d.ts +0 -15
- package/build/inputChunkBuffer.js +0 -40
- package/build/inputChunkBuffer.test.js +0 -34
- package/build/inputCompanion.d.ts +0 -18
- package/build/inputCompanion.js +0 -28
- package/build/invariantDefined.d.ts +0 -1
- package/build/invariantDefined.js +0 -5
- package/build/invariantIdentity.d.ts +0 -3
- package/build/invariantIdentity.js +0 -5
- package/build/javaKeystoreParser.d.ts +0 -2
- package/build/javaKeystoreParser.js +0 -7
- package/build/jsonParser2.d.ts +0 -3
- package/build/jsonParser2.js +0 -52
- package/build/jsonParser2.test.js +0 -22
- package/build/negativeLookahead.d.ts +0 -2
- package/build/negativeLookahead.js +0 -18
- package/build/parserCompose.d.ts +0 -3
- package/build/parserCompose.js +0 -7
- package/build/parserImplementationInvariantInvariant.d.ts +0 -3
- package/build/parserImplementationInvariantInvariant.js +0 -15
- package/build/parserInvariant.d.ts +0 -4
- package/build/parserInvariant.js +0 -11
- package/build/promiseFish.d.ts +0 -1
- package/build/promiseFish.js +0 -3
- package/build/sequenceParser.d.ts +0 -3
- package/build/sequenceParser.js +0 -10
- package/build/terminatedSequenceParser.d.ts +0 -2
- package/build/terminatedSequenceParser.js +0 -24
- package/build/unparserInputCompanion.d.ts +0 -15
- package/build/unparserInputCompanion.js +0 -13
- package/build/zipEntry.d.ts +0 -28
- package/build/zipFile.d.ts +0 -32
- package/build/zipFileEntry.d.ts +0 -6
- package/src/apk.ts +0 -48
- package/src/apkParser.test.ts +0 -30
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +0 -392
- package/src/apkUnparser.test.ts +0 -37
- package/src/apkUnparser.ts +0 -120
- package/src/invariantDefined.ts +0 -6
- package/src/invariantIdentity.ts +0 -8
- /package/build/{apk.js → androidPackage.js} +0 -0
- /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
- /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.d.ts → dalvikBytecodeUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
- /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
- /package/build/{jsonParser2.test.d.ts → dalvikExecutableUnparser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.js → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
- /package/build/{zipEntry.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
- /package/build/{zipFile.js → fetchCid.test.d.ts} +0 -0
- /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
|
|
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
|
+
}
|
package/src/inputReader.test.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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 ]);
|
package/src/inputReader.ts
CHANGED
|
@@ -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
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
12
|
+
const actual = await runParser(javaKeyStoreParser, javaKeyStoreStream, uint8ArrayParserInputCompanion, {
|
|
13
|
+
errorJoinMode: 'all',
|
|
14
|
+
});
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
t.snapshot(actual);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
19
|
|
|
20
|
-
|
|
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,
|
package/src/jsonParser.test.ts
CHANGED
|
@@ -7,10 +7,8 @@ import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
|
7
7
|
testProp(
|
|
8
8
|
'json',
|
|
9
9
|
[
|
|
10
|
-
arbitrarilySlicedAsyncIterator(
|
|
11
|
-
|
|
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, {
|