@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,34 @@
|
|
|
1
|
+
import * as fc from 'fast-check';
|
|
2
|
+
import { testProp } from '@fast-check/ava';
|
|
3
|
+
import { runParser } from './parser.js';
|
|
4
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
|
+
import { createElementTerminatedSequenceArrayParser } from './elementTerminatedSequenceArrayParser.js';
|
|
6
|
+
testProp.serial('elementTerminatedSequenceArrayParser', [
|
|
7
|
+
fc
|
|
8
|
+
.string({
|
|
9
|
+
minLength: 1,
|
|
10
|
+
})
|
|
11
|
+
.map(string => ({
|
|
12
|
+
string,
|
|
13
|
+
terminator: string.slice(-1),
|
|
14
|
+
}))
|
|
15
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2),
|
|
16
|
+
], async (t, { string, terminator }) => {
|
|
17
|
+
const elementTerminatedSequenceArrayParser = createElementTerminatedSequenceArrayParser(terminator);
|
|
18
|
+
const createTestWrapperParser = (innerParser) => async (parserContext) => {
|
|
19
|
+
const strings = await innerParser(parserContext);
|
|
20
|
+
return {
|
|
21
|
+
strings,
|
|
22
|
+
nextPeek: await parserContext.peek(0),
|
|
23
|
+
position: parserContext.position,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const actual = await runParser(createTestWrapperParser(elementTerminatedSequenceArrayParser), string, stringParserInputCompanion);
|
|
27
|
+
t.deepEqual(actual, {
|
|
28
|
+
strings: [string.split(terminator)[0]],
|
|
29
|
+
nextPeek: undefined,
|
|
30
|
+
position: string.length,
|
|
31
|
+
});
|
|
32
|
+
}, {
|
|
33
|
+
verbose: true,
|
|
34
|
+
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type Parser } from './parser.js';
|
|
2
|
+
import { type DeriveSequenceElement } from './sequence.js';
|
|
3
|
+
export declare const createElementTerminatedSequenceParser: <Sequence, Element = DeriveSequenceElement<Sequence>>(terminatorElement: Element) => Parser<Sequence, Sequence, Element>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { setParserName } from './parser.js';
|
|
2
|
+
export const createElementTerminatedSequenceParser = (terminatorElement) => {
|
|
3
|
+
const elementTerminatedSequenceParser = async (parserContext) => {
|
|
4
|
+
let start = 0;
|
|
5
|
+
let window = 1;
|
|
6
|
+
while (true) {
|
|
7
|
+
const sequence = await parserContext.peekSequence(start, start + window);
|
|
8
|
+
if (sequence === undefined) {
|
|
9
|
+
window = Math.floor(window / 2);
|
|
10
|
+
parserContext.invariant(!(start === 0 && window === 0), 'Unexpected end of input without terminated sequence');
|
|
11
|
+
parserContext.invariant(window > 0, 'Unexpected end of input without terminator');
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const terminatorIndex = parserContext.indexOf(sequence, terminatorElement);
|
|
15
|
+
if (terminatorIndex === -1) {
|
|
16
|
+
start += window;
|
|
17
|
+
window *= 2;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const sequence_ = await parserContext.readSequence(0, start + terminatorIndex);
|
|
21
|
+
parserContext.skip(1);
|
|
22
|
+
return sequence_;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
setParserName(elementTerminatedSequenceParser, `.*?${JSON.stringify(terminatorElement)}`);
|
|
26
|
+
return elementTerminatedSequenceParser;
|
|
27
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as fc from 'fast-check';
|
|
2
|
+
import { testProp } from '@fast-check/ava';
|
|
3
|
+
import { runParser } from './parser.js';
|
|
4
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
5
|
+
import { createElementTerminatedSequenceParser } from './elementTerminatedSequenceParser.js';
|
|
6
|
+
testProp.serial('elementTerminatedSequenceParser', [
|
|
7
|
+
fc
|
|
8
|
+
.string({
|
|
9
|
+
minLength: 1,
|
|
10
|
+
})
|
|
11
|
+
.map(string => ({
|
|
12
|
+
string,
|
|
13
|
+
terminator: string.slice(-1),
|
|
14
|
+
}))
|
|
15
|
+
.filter(({ string, terminator }) => string.split(terminator).length === 2),
|
|
16
|
+
], async (t, { string, terminator }) => {
|
|
17
|
+
const elementTerminatedSequenceParser = createElementTerminatedSequenceParser(terminator);
|
|
18
|
+
const createTestWrapperParser = (innerParser) => async (parserContext) => {
|
|
19
|
+
const string = await innerParser(parserContext);
|
|
20
|
+
return {
|
|
21
|
+
string,
|
|
22
|
+
nextPeek: await parserContext.peek(0),
|
|
23
|
+
position: parserContext.position,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const actual = await runParser(createTestWrapperParser(elementTerminatedSequenceParser), string, stringParserInputCompanion);
|
|
27
|
+
t.deepEqual(actual, {
|
|
28
|
+
string: string.split(terminator)[0],
|
|
29
|
+
nextPeek: undefined,
|
|
30
|
+
position: string.length,
|
|
31
|
+
});
|
|
32
|
+
}, {
|
|
33
|
+
verbose: true,
|
|
34
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type Parser } from './parser.js';
|
|
2
2
|
import { type DeriveSequenceElement } from './sequence.js';
|
|
3
3
|
export declare const createEndOfInputParser: <Sequence, Element = DeriveSequenceElement<Sequence>>() => Parser<void, Sequence, Element>;
|
|
4
|
-
export declare const endOfInputParser: Parser<void,
|
|
4
|
+
export declare const endOfInputParser: Parser<void, unknown, unknown>;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { setParserName } from './parser.js';
|
|
2
|
+
export const createExactElementParser = (element) => {
|
|
3
|
+
const exactElementParser = async (parserContext) => {
|
|
4
|
+
const actualElement = await parserContext.peek(0);
|
|
5
|
+
parserContext.invariant(actualElement === element, 'Expected %s, got %s', element, actualElement);
|
|
6
|
+
parserContext.skip(1);
|
|
7
|
+
return element;
|
|
8
|
+
};
|
|
9
|
+
setParserName(exactElementParser, `createExactElementParser(${element})`);
|
|
10
|
+
return exactElementParser;
|
|
6
11
|
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Parser } from "./parser.js";
|
|
2
|
+
import { DeriveSequenceElement } from "./sequence.js";
|
|
3
|
+
export declare const createElementSwitchParser: <Output, Sequence, Element = DeriveSequenceElement<Sequence>>(childParsers: Map<Element, Parser<unknown, Sequence, Element>>, defaultParser?: Parser<unknown, Sequence, Element>) => Parser<Output, Sequence, Element>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import invariant from "invariant";
|
|
2
|
+
import { getParserName, setParserName } from "./parser.js";
|
|
3
|
+
import { parserImplementationInvariant } from "./parserImplementationInvariant.js";
|
|
4
|
+
export const createElementSwitchParser = (childParsers, defaultParser) => {
|
|
5
|
+
parserImplementationInvariant(childParsers.size > 0, 'Element switch parser must have at least one child parser.');
|
|
6
|
+
const elementSwitchParser = async (parserContext) => {
|
|
7
|
+
const currentElement = await parserContext.peek(0);
|
|
8
|
+
parserContext.invariant(currentElement !== undefined, 'Unexpected end of input.');
|
|
9
|
+
invariant(currentElement !== undefined, 'Unexpected end of input.');
|
|
10
|
+
const childParser = childParsers.get(currentElement) ?? defaultParser;
|
|
11
|
+
parserContext.invariant(childParser, `No child parser found for element: ${String(currentElement)}`);
|
|
12
|
+
const childParserOutput = await childParser(parserContext);
|
|
13
|
+
return childParserOutput;
|
|
14
|
+
};
|
|
15
|
+
const name = [
|
|
16
|
+
'elementSwitch(',
|
|
17
|
+
...Array.from(childParsers.entries()).map(([element, childParser]) => `${String(element)}=>${getParserName(childParser, 'anonymousElementSwitchChild')}`),
|
|
18
|
+
defaultParser ? `|default=>${getParserName(defaultParser, 'anonymousElementSwitchDefaultChild')}` : '',
|
|
19
|
+
')',
|
|
20
|
+
].join('');
|
|
21
|
+
return setParserName(elementSwitchParser, name);
|
|
22
|
+
};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { type Parser } from './parser.js';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const createExactSequenceNaiveParser: <Sequence>(sequence: Sequence) => Parser<Sequence, Sequence, unknown>;
|
|
3
|
+
export declare const createExactSequenceParser: <Sequence>(expectedSequence: Sequence) => Parser<Sequence, Sequence, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { inspect } from 'node:util';
|
|
2
1
|
import { setParserName } from './parser.js';
|
|
3
|
-
|
|
2
|
+
import { inspect } from './inspect.js';
|
|
3
|
+
export const createExactSequenceNaiveParser = (sequence) => {
|
|
4
4
|
const exactSequenceParser = async (parserContext) => {
|
|
5
5
|
const length = parserContext.length(sequence);
|
|
6
6
|
for (let index = 0; index < length; index++) {
|
|
@@ -13,3 +13,13 @@ export const createExactSequenceParser = (sequence) => {
|
|
|
13
13
|
setParserName(exactSequenceParser, inspect(sequence));
|
|
14
14
|
return exactSequenceParser;
|
|
15
15
|
};
|
|
16
|
+
export const createExactSequenceParser = (expectedSequence) => {
|
|
17
|
+
const exactSequenceParser = async (parserContext) => {
|
|
18
|
+
const length = parserContext.length(expectedSequence);
|
|
19
|
+
const actualSequence = await parserContext.readSequence(0, length);
|
|
20
|
+
parserContext.invariant(parserContext.equals(actualSequence, expectedSequence), 'Expected "%s", got "%s"', () => inspect(expectedSequence), () => inspect(actualSequence));
|
|
21
|
+
return expectedSequence;
|
|
22
|
+
};
|
|
23
|
+
setParserName(exactSequenceParser, inspect(expectedSequence));
|
|
24
|
+
return exactSequenceParser;
|
|
25
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fetchCid(cidOrPath: string): Promise<AsyncIterable<Uint8Array>>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fsPromises from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import pMemoize from 'p-memoize';
|
|
4
|
+
import envPaths from 'env-paths';
|
|
5
|
+
const paths = envPaths('parser.futpib.github.io');
|
|
6
|
+
function readableWebStreamOnFinish(readableWebStream, onFinish) {
|
|
7
|
+
const reader = readableWebStream.getReader();
|
|
8
|
+
const stream = new ReadableStream({
|
|
9
|
+
async start(controller) {
|
|
10
|
+
try {
|
|
11
|
+
while (true) {
|
|
12
|
+
const { done, value } = await reader.read();
|
|
13
|
+
if (done) {
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
controller.enqueue(value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
controller.close();
|
|
21
|
+
reader.releaseLock();
|
|
22
|
+
onFinish();
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
async cancel(reason) {
|
|
26
|
+
await reader.cancel(reason);
|
|
27
|
+
onFinish();
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
return stream;
|
|
31
|
+
}
|
|
32
|
+
class FsCache {
|
|
33
|
+
get _basePath() {
|
|
34
|
+
return path.join(paths.cache, 'fetchCid');
|
|
35
|
+
}
|
|
36
|
+
_getKeyPath(key) {
|
|
37
|
+
return path.join(this._basePath, key.replaceAll('/', '_'));
|
|
38
|
+
}
|
|
39
|
+
async get(key) {
|
|
40
|
+
try {
|
|
41
|
+
const file = await fsPromises.open(this._getKeyPath(key), 'r');
|
|
42
|
+
const stream = file.readableWebStream();
|
|
43
|
+
const streamWithClose = readableWebStreamOnFinish(stream, () => {
|
|
44
|
+
file.close();
|
|
45
|
+
});
|
|
46
|
+
return [streamWithClose, undefined];
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error.code === 'ENOENT') {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async has(key) {
|
|
56
|
+
const streams = await this.get(key);
|
|
57
|
+
try {
|
|
58
|
+
return streams !== undefined;
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
for (const stream of streams ?? []) {
|
|
62
|
+
await stream?.cancel();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async set(key, [_, value]) {
|
|
67
|
+
await fsPromises.mkdir(this._basePath, {
|
|
68
|
+
recursive: true,
|
|
69
|
+
});
|
|
70
|
+
const file = await fsPromises.open(this._getKeyPath(key), 'w');
|
|
71
|
+
try {
|
|
72
|
+
for await (const chunk of value) {
|
|
73
|
+
await file.write(chunk);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
await file.close();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async delete(key) {
|
|
81
|
+
await fsPromises.unlink(this._getKeyPath(key));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function reallyFetchCid(cid) {
|
|
85
|
+
const response = await fetch('https://ipfs.io/ipfs/' + cid);
|
|
86
|
+
return response.body.tee();
|
|
87
|
+
}
|
|
88
|
+
const cachedReallyFetchCid = pMemoize(reallyFetchCid, {
|
|
89
|
+
cache: new FsCache(),
|
|
90
|
+
});
|
|
91
|
+
export async function fetchCid(cidOrPath) {
|
|
92
|
+
if (cidOrPath.includes('/')) {
|
|
93
|
+
const file = await fsPromises.open(cidOrPath, 'r');
|
|
94
|
+
const stream = file.readableWebStream();
|
|
95
|
+
const streamWithClose = readableWebStreamOnFinish(stream, () => {
|
|
96
|
+
file.close();
|
|
97
|
+
});
|
|
98
|
+
return streamWithClose;
|
|
99
|
+
}
|
|
100
|
+
const [readable, unused] = await cachedReallyFetchCid(cidOrPath);
|
|
101
|
+
await unused?.cancel();
|
|
102
|
+
return readable;
|
|
103
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { fetchCid } from './fetchCid.js';
|
|
3
|
+
const cid = 'bafybeicb3qajmwy6li7hche2nkucvytaxcyxhwhphmi73tgydjzmyoqoda';
|
|
4
|
+
test('fetchCid', async (t) => {
|
|
5
|
+
await Promise.all([
|
|
6
|
+
fetchCid(cid),
|
|
7
|
+
fetchCid(cid),
|
|
8
|
+
fetchCid(cid),
|
|
9
|
+
]);
|
|
10
|
+
await Promise.all([
|
|
11
|
+
fetchCid(cid),
|
|
12
|
+
fetchCid(cid),
|
|
13
|
+
fetchCid(cid),
|
|
14
|
+
]);
|
|
15
|
+
t.pass();
|
|
16
|
+
});
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { type Parser } from './parser.js';
|
|
2
|
+
export declare const createFixedLengthSequenceParserNaive: <Sequence>(lengthInput: bigint | number) => Parser<Sequence, Sequence, unknown>;
|
|
2
3
|
export declare const createFixedLengthSequenceParser: <Sequence>(lengthInput: bigint | number) => Parser<Sequence, Sequence, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setParserName } from './parser.js';
|
|
2
2
|
import { parserImplementationInvariant } from './parserImplementationInvariant.js';
|
|
3
|
-
export const
|
|
3
|
+
export const createFixedLengthSequenceParserNaive = (lengthInput) => {
|
|
4
4
|
const length = BigInt(lengthInput);
|
|
5
5
|
parserImplementationInvariant(length >= 0n, 'Length must be non-negative got %s.', length);
|
|
6
6
|
const fixedLengthSequenceParser = async (parserContext) => {
|
|
@@ -14,3 +14,20 @@ export const createFixedLengthSequenceParser = (lengthInput) => {
|
|
|
14
14
|
setParserName(fixedLengthSequenceParser, `.{${length}}`);
|
|
15
15
|
return fixedLengthSequenceParser;
|
|
16
16
|
};
|
|
17
|
+
const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
|
|
18
|
+
export const createFixedLengthSequenceParser = (lengthInput) => {
|
|
19
|
+
const length = BigInt(lengthInput);
|
|
20
|
+
parserImplementationInvariant(length >= 0n, 'Length must be non-negative got %s.', length);
|
|
21
|
+
const fixedLengthSequenceParser = async (parserContext) => {
|
|
22
|
+
const safeIntegerSequences = [];
|
|
23
|
+
let remainingLength = length;
|
|
24
|
+
while (remainingLength > 0n) {
|
|
25
|
+
const safeIntegerLength = length > MAX_SAFE_INTEGER ? Number.MAX_SAFE_INTEGER : Number(length);
|
|
26
|
+
safeIntegerSequences.push(await parserContext.readSequence(0, safeIntegerLength));
|
|
27
|
+
remainingLength -= BigInt(safeIntegerLength);
|
|
28
|
+
}
|
|
29
|
+
return parserContext.concat(safeIntegerSequences);
|
|
30
|
+
};
|
|
31
|
+
setParserName(fixedLengthSequenceParser, `.{${length}}`);
|
|
32
|
+
return fixedLengthSequenceParser;
|
|
33
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
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 { runParserWithRemainingInput } from './parser.js';
|
|
6
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
7
|
+
import { HighResolutionTotalTimer } from './highResolutionTimer.js';
|
|
8
|
+
import { arbitrarilySlicedAsyncIterable } from './arbitrarilySlicedAsyncInterable.js';
|
|
9
|
+
const naiveTotalTimer = new HighResolutionTotalTimer();
|
|
10
|
+
const totalTimer = new HighResolutionTotalTimer();
|
|
11
|
+
testProp.serial('fixedLengthSequenceParser', [
|
|
12
|
+
fc
|
|
13
|
+
.bigInt({
|
|
14
|
+
min: 1n,
|
|
15
|
+
max: 2n ** 14n,
|
|
16
|
+
})
|
|
17
|
+
.chain(length => fc.tuple(arbitrarilySlicedAsyncIterable(fc.string({
|
|
18
|
+
minLength: Number(length),
|
|
19
|
+
maxLength: Number(length) * 2,
|
|
20
|
+
})), fc.constant(length))),
|
|
21
|
+
], async (t, [[_, sequence], length]) => {
|
|
22
|
+
const fixedLengthSequenceParserNaive = createFixedLengthSequenceParserNaive(length);
|
|
23
|
+
const fixedLengthSequenceParser = createFixedLengthSequenceParser(length);
|
|
24
|
+
const createTestWrapperParser = (innerParser) => async (parserContext) => {
|
|
25
|
+
const result = await innerParser(parserContext);
|
|
26
|
+
return {
|
|
27
|
+
result,
|
|
28
|
+
nextPeek: await parserContext.peek(0),
|
|
29
|
+
position: parserContext.position,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const { output: actualNaive } = await naiveTotalTimer.measureAsync(async () => runParserWithRemainingInput(createTestWrapperParser(fixedLengthSequenceParserNaive), sequence, stringParserInputCompanion));
|
|
33
|
+
t.true(actualNaive.result.length === Number(length));
|
|
34
|
+
const { output: actual } = await totalTimer.measureAsync(async () => runParserWithRemainingInput(createTestWrapperParser(fixedLengthSequenceParser), sequence, stringParserInputCompanion));
|
|
35
|
+
t.deepEqual(actual, actualNaive);
|
|
36
|
+
}, {
|
|
37
|
+
verbose: true,
|
|
38
|
+
});
|
|
39
|
+
test.serial('fixedLengthSequenceParser performance', t => {
|
|
40
|
+
t.true(totalTimer.time * 10n < naiveTotalTimer.time, `Naive: ${naiveTotalTimer.time / 1000000n}ms, Optimized: ${totalTimer.time / 1000000n}ms`);
|
|
41
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function hasExecutable(executable: string): Promise<boolean>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
export async function hasExecutable(executable) {
|
|
3
|
+
const hasExecutable = execa(executable).catch(() => false).then(() => true);
|
|
4
|
+
if (!hasExecutable) {
|
|
5
|
+
console.warn('Executable %o not found', executable);
|
|
6
|
+
}
|
|
7
|
+
return hasExecutable;
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare class HighResolutionSubTimer {
|
|
2
|
+
private readonly _parent;
|
|
3
|
+
private readonly _start;
|
|
4
|
+
private _ended;
|
|
5
|
+
constructor(_parent: HighResolutionTotalTimer, _start: bigint);
|
|
6
|
+
end(): void;
|
|
7
|
+
}
|
|
8
|
+
export declare class HighResolutionTotalTimer {
|
|
9
|
+
private _total;
|
|
10
|
+
start(): HighResolutionSubTimer;
|
|
11
|
+
add(time: bigint): void;
|
|
12
|
+
get time(): bigint;
|
|
13
|
+
measure<T>(fn: () => T): T;
|
|
14
|
+
measureAsync<T>(fn: () => Promise<T>): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import process from 'node:process';
|
|
2
|
+
import invariant from 'invariant';
|
|
3
|
+
class HighResolutionSubTimer {
|
|
4
|
+
_parent;
|
|
5
|
+
_start;
|
|
6
|
+
_ended = false;
|
|
7
|
+
constructor(_parent, _start) {
|
|
8
|
+
this._parent = _parent;
|
|
9
|
+
this._start = _start;
|
|
10
|
+
}
|
|
11
|
+
end() {
|
|
12
|
+
invariant(!this._ended, 'Timer already ended.');
|
|
13
|
+
const end = process.hrtime.bigint();
|
|
14
|
+
const time = end - this._start;
|
|
15
|
+
this._parent.add(time);
|
|
16
|
+
this._ended = true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class HighResolutionTotalTimer {
|
|
20
|
+
_total = 0n;
|
|
21
|
+
start() {
|
|
22
|
+
return new HighResolutionSubTimer(this, process.hrtime.bigint());
|
|
23
|
+
}
|
|
24
|
+
add(time) {
|
|
25
|
+
this._total += time;
|
|
26
|
+
}
|
|
27
|
+
get time() {
|
|
28
|
+
return this._total;
|
|
29
|
+
}
|
|
30
|
+
measure(fn) {
|
|
31
|
+
const timer = this.start();
|
|
32
|
+
const result = fn();
|
|
33
|
+
timer.end();
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
async measureAsync(fn) {
|
|
37
|
+
const timer = this.start();
|
|
38
|
+
const result = await fn();
|
|
39
|
+
timer.end();
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
}
|
package/build/inputReader.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { type ParserInputCompanion } from './parserInputCompanion.js';
|
|
2
|
+
import { type InputReaderState } from './inputReaderState.js';
|
|
2
3
|
export type InputReader<Sequence, Element> = {
|
|
3
4
|
get position(): number;
|
|
4
5
|
peek(offset: number): Promise<Element | undefined>;
|
|
6
|
+
peekSequence(start: number, end: number): Promise<Sequence | undefined>;
|
|
5
7
|
skip(offset: number): void;
|
|
6
8
|
lookahead(): InputReader<Sequence, Element>;
|
|
9
|
+
toInputReaderState(): InputReaderState<Sequence>;
|
|
7
10
|
};
|
|
8
11
|
export declare class InputReaderImplementation<Sequence, Element> implements InputReader<Sequence, Element> {
|
|
9
12
|
private readonly _parserInputCompanion;
|
|
@@ -11,12 +14,20 @@ export declare class InputReaderImplementation<Sequence, Element> implements Inp
|
|
|
11
14
|
private readonly _id;
|
|
12
15
|
private _position;
|
|
13
16
|
private _uncommitedSkipOffset;
|
|
17
|
+
private _inputAsyncIteratorDone;
|
|
14
18
|
private readonly _promiseMutex;
|
|
15
19
|
private readonly _sequenceBuffer;
|
|
16
20
|
constructor(_parserInputCompanion: ParserInputCompanion<Sequence, Element>, _inputAsyncIterator: AsyncIterator<Sequence>);
|
|
17
21
|
get [Symbol.toStringTag](): string;
|
|
18
22
|
get position(): number;
|
|
19
23
|
peek(offset: number): Promise<Element | undefined>;
|
|
24
|
+
peekSequence(start: number, end: number): Promise<Sequence | undefined>;
|
|
20
25
|
skip(offset: number): void;
|
|
21
26
|
lookahead(): InputReader<Sequence, Element>;
|
|
27
|
+
toInputReaderState(): {
|
|
28
|
+
consumedBufferedSequences: Sequence[];
|
|
29
|
+
unconsumedBufferedSequences: Sequence[];
|
|
30
|
+
unbufferedSequences: AsyncIterator<Sequence, any, any> | undefined;
|
|
31
|
+
position: number;
|
|
32
|
+
};
|
|
22
33
|
}
|
package/build/inputReader.js
CHANGED
|
@@ -9,6 +9,7 @@ export class InputReaderImplementation {
|
|
|
9
9
|
_id = inputReaderId++;
|
|
10
10
|
_position = 0;
|
|
11
11
|
_uncommitedSkipOffset = 0;
|
|
12
|
+
_inputAsyncIteratorDone = false;
|
|
12
13
|
_promiseMutex = new PromiseMutex();
|
|
13
14
|
_sequenceBuffer;
|
|
14
15
|
constructor(_parserInputCompanion, _inputAsyncIterator) {
|
|
@@ -41,6 +42,7 @@ export class InputReaderImplementation {
|
|
|
41
42
|
}
|
|
42
43
|
const inputIteratorResult = await this._inputAsyncIterator.next();
|
|
43
44
|
if (inputIteratorResult.done) {
|
|
45
|
+
this._inputAsyncIteratorDone = true;
|
|
44
46
|
return undefined;
|
|
45
47
|
}
|
|
46
48
|
parserImplementationInvariant(this._parserInputCompanion.is(inputIteratorResult.value), [
|
|
@@ -52,6 +54,23 @@ export class InputReaderImplementation {
|
|
|
52
54
|
}
|
|
53
55
|
});
|
|
54
56
|
}
|
|
57
|
+
async peekSequence(start, end) {
|
|
58
|
+
parserImplementationInvariant(start >= 0, 'start (%s) >= 0', start);
|
|
59
|
+
parserImplementationInvariant(end >= start, 'end (%s) >= start (%s)', start, end);
|
|
60
|
+
parserImplementationInvariant(Number.isSafeInteger(start), 'start (%s) is not a safe integer', start);
|
|
61
|
+
parserImplementationInvariant(Number.isSafeInteger(end), 'end (%s) is not a safe integer', end);
|
|
62
|
+
start += this._uncommitedSkipOffset;
|
|
63
|
+
end += this._uncommitedSkipOffset;
|
|
64
|
+
const sequence = this._sequenceBuffer.peekSequence(start, end);
|
|
65
|
+
if (sequence !== undefined) {
|
|
66
|
+
return sequence;
|
|
67
|
+
}
|
|
68
|
+
const lastElement = await this.peek(Math.max(0, end - 1));
|
|
69
|
+
if (lastElement === undefined) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return this._sequenceBuffer.peekSequence(start, end);
|
|
73
|
+
}
|
|
55
74
|
skip(offset) {
|
|
56
75
|
parserImplementationInvariant(offset >= 0, 'offset >= 0');
|
|
57
76
|
this._position += offset;
|
|
@@ -66,6 +85,15 @@ export class InputReaderImplementation {
|
|
|
66
85
|
lookahead() {
|
|
67
86
|
return new InputReaderLookaheadImplementation(this);
|
|
68
87
|
}
|
|
88
|
+
toInputReaderState() {
|
|
89
|
+
const { consumedBufferedSequences, unconsumedBufferedSequences, } = this._sequenceBuffer.toSequenceBufferState();
|
|
90
|
+
return {
|
|
91
|
+
consumedBufferedSequences,
|
|
92
|
+
unconsumedBufferedSequences,
|
|
93
|
+
unbufferedSequences: this._inputAsyncIteratorDone ? undefined : this._inputAsyncIterator,
|
|
94
|
+
position: this._position,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
69
97
|
}
|
|
70
98
|
class InputReaderLookaheadImplementation {
|
|
71
99
|
_inputReader;
|
|
@@ -91,6 +119,12 @@ class InputReaderLookaheadImplementation {
|
|
|
91
119
|
this._offset -= inputReaderMovedForward;
|
|
92
120
|
return this._inputReader.peek(this._offset + offset);
|
|
93
121
|
}
|
|
122
|
+
async peekSequence(start, end) {
|
|
123
|
+
const inputReaderMovedForward = this._inputReader.position - this._initialInputReaderPosition;
|
|
124
|
+
this._initialInputReaderPosition = this._inputReader.position;
|
|
125
|
+
this._offset -= inputReaderMovedForward;
|
|
126
|
+
return this._inputReader.peekSequence(this._offset + start, this._offset + end);
|
|
127
|
+
}
|
|
94
128
|
skip(offset) {
|
|
95
129
|
parserImplementationInvariant(offset >= 0, 'offset >= 0');
|
|
96
130
|
this._offset += offset;
|
|
@@ -102,4 +136,7 @@ class InputReaderLookaheadImplementation {
|
|
|
102
136
|
invariant(this.position === lookahead.position, 'this.position (%s) === lookahead.position (%s)', this.position, lookahead.position);
|
|
103
137
|
return lookahead;
|
|
104
138
|
}
|
|
139
|
+
toInputReaderState() {
|
|
140
|
+
return invariant(false, 'Not implemented');
|
|
141
|
+
}
|
|
105
142
|
}
|