npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ka-fuachie/parse-lib

v0.0.1

Published

A JavaScript parser combinator library designed for streaming inputs

Readme

Parse-lib

Parse-lib is a javascript parser combinator library designed for streaming data inputs. It is build on packrat parsing techniques to ensure parsing with linear time complexity. The library provides a set of utility parsers and combinators to build complex parsers from simple ones, allowing for easy construction of parsers for various data formats.

API

Parser

Instance of parser returned by all parser methods

[!CAUTION] Parsers should not be created directly as instances of this class, the api is subject to change

Instance methods

Parser.map()

Returns a new parser that transforms the parse result using the passed function param. Useful for applying structure to parse results

const digitParser = charFrom(["0", "9"]).map(d => ({
    type: "digit",
    value: d
}))

console.log(digitParser.parseString("2b"))
// {
//     status: "complete",
//     index: 1,
//     result: {
//         type: "digit",
//         value: 2,
//     },
//     error: null
// }
Parser.transform()

Takes a parser state and returns a transformed version using the parser's internal state transform function. Mainly used in conjuction with the Parser constructor to create custom parsers

Parser.parseString()

Takes a string input and returns result of parsing the input using the parser

const helloParser = literal("Hello")
console.log(helloParser.parseString("Hello world!"))
// {
//     status: "complete",
//     index: 5,
//     result: "hello",
//     error: null
// }
Parser.parseIterable()

Takes an iterable input and returns and iterable of the result of parsing the input using the parser. It yields intermediate results till the parser reaches a completed state

function* getInput() {
    yield "Hello"
    yield " World!"
}

const helloWorldParser = sequenceOf([
    literal("Hello"),
    literal(" "),
    literal("World!")
])

for (const result of helloWorldParser.parseIterable(getInput())) {
    console.log(result)
}
// {
//     status: "partial",
//     index: 5,
//     result: ["Hello", undefined, undefined],
//     error: null
// }
// {
//     status: "complete",
//     index: 13,
//     result: ["Hello", " ", "World!"],
//     error: null
// }

ParserStateStatus

Enum of a parser state status

  • ParserStateStatus.COMPLETE - Parser has successfully completed parsing
  • ParserStateStatus.PARTIAL - Parser needs more input to complete parsing
  • ParserStateStatus.ERROR - Parser has encountered an error while parsing

ParserUnexpectedEndOfInputError

An error indicating that the parser has reached the end of input unexpectedly while parsing. During streaming, this error indicates that the parser needs more input to continue parsing

literal

Takes a string literal and returns a parser that matches the exact string

literal("Hello").parseString("Hello World!")
// {
//     status: "complete",
//     index: 5,
//     result: "Hello",
//     error: null
// }

anyChar

Matches any single character from the input

anyChar().parseString("abc")
// {
//     status: "complete",
//     index: 1,
//     result: "a",
//     error: null
// }

charFrom

Takes a list of characters or character ranges and returns a parser that matches any single character from the list or range

charFrom("a", "b", "c").parseString("cat")
// {
//     status: "complete",
//     index: 1,
//     result: "c",
//     error: null
// }

charFrom(["0", "9"]).parseString("5abc") // Ranges are passed as 2-element tuples
// {
//     status: "complete",
//     index: 1,
//     result: "5",
//     error: null
// }

endOfInput

Matches the end of input

endOfInput().parseString("")
// {
//     status: "complete",
//     index: 0,
//     result: null,
//     error: null
// }

endOfInput().parseString("Hello")
// {
//     status: "error",
//     index: 0,
//     result: null,
//     error: Error('Expected end of input, but got "Hello"')
// }

sequenceOf

Takes a list of parsers and returns a parser that matches the sequence of parsers in order. The result is an array of the results of each parser

const helloWorldParser = sequenceOf([
    literal("Hello"),
    literal(" "),
    literal("World!")
])

console.log(helloWorldParser.parseString("Hello World!"))
// {
//     status: "complete",
//     index: 13,
//     result: ["Hello", " ", "World!"],
//     error: null
// }

oneOf

Takes a list of parsers and returns the result of the first successful parser. If all parsers fail, returns the error of the first parser

const digitOrLetterParser = oneOf([
    charFrom(["0", "9"]),
    charFrom(["a", "z"], ["A", "Z"])
])

console.log(digitOrLetterParser.parseString("5abc"))
// {
//     status: "complete",
//     index: 1,
//     result: "5",
//     error: null
// }
console.log(digitOrLetterParser.parseString("abc"))
// {
//     status: "complete",
//     index: 1,
//     result: "a",
//     error: null
// }

zeroOrMore

Takes a parser and returns a parser that matches zero or more occurrences of the parser. The result is an array of the results of each occurrence

const digitParser = charFrom(["0", "9"])
const digitsParser = zeroOrMore(digitParser)
console.log(digitsParser.parseString("123abc"))
// {
//     status: "complete",
//     index: 3,
//     result: ["1", "2", "3"],
//     error: null
// }
console.log(digitsParser.parseString("abc"))
// {
//     status: "complete",
//     index: 0,
//     result: [],
//     error: null
// }

oneOrMore

Takes a parser and returns a parser that matches one or more occurrences of the parser. The result is an array of the results of each occurrence. It results in an error if it matches no occurence of the parser

const digitParser = charFrom(["0", "9"])
const digitsParser = oneOrMore(digitParser)
console.log(digitsParser.parseString("123abc"))
// {
//     status: "complete",
//     index: 3,
//     result: ["1", "2", "3"],
//     error: null
// }
console.log(digitsParser.parseString("abc"))
// {
//     status: "error",
//     index: 0,
//     result: null,
//     error: Error('Expected character from set, but got "abc"')
// }

optional

Takes a parser and returns a parser that matches zero or one occurrence of the parser. The result is the result of the parser or null if it matches no occurrence

const digitParser = charFrom(["0", "9"])
const optionalDigitParser = optional(digitParser)
console.log(optionalDigitParser.parseString("5abc"))
// {
//     status: "complete",
//     index: 1,
//     result: "5",
//     error: null
// }
console.log(optionalDigitParser.parseString("abc"))
// {
//     status: "complete",
//     index: 0,
//     result: null,
//     error: null
// }

followedBy

Takes a parser and returns a parser that matches the parser but does not consume any input.

const digitParser = charFrom(["0", "9"])
const followedByDigitParser = followedBy(digitParser)
console.log(followedByDigitParser.parseString("5abc"))
// {
//     status: "complete",
//     index: 0,
//     result: "5",
//     error: null
// }

notFollowedBy

Takes a parser and returns a parser that matches if the parser does not match, without consuming any input.

const digitParser = charFrom(["0", "9"])
const notFollowedByDigitParser = notFollowedBy(digitParser)
console.log(notFollowedByDigitParser.parseString("abc"))
// {
//     status: "complete",
//     index: 0,
//     result: null,
//     error: null
// }

lazy

Takes a function that returns a parser and returns a parser that defers the creation of the parser until it is needed. Useful for creating recursive parsers

const arrayValueParser = lazy(() => 
    oneOf([
        numberParser,
        stringParser,
        arrayParser
    ])
)
const betweenSquareBrackes = parser => (
    sequenceOf([
        literal("["),
        parser,
        literal("]")
    ]).map(results => results[1])
)
const commaSeparated = parser => (
    sequenceOf([
        parser,
        zeroOrMore(
            sequenceOf([
                literal(","),
                parser
            ]).map(results => results[1])
        )
    ]).map(([first, rest]) => [first, ...rest]])
)
const arrayParser = (
    betweenSquareBrackes(
        optional(
            commaSeparated(arrayValueParser)
        ).map(result => result ?? [])
    )
)

console.log(arrayParser.parseString('[1,["two",3],4]'))
// {
//     status: "complete",
//     index: 13,
//     result: [1, ["two", 3], 4],
//     error: null
// }

Roadmap to v0.1.0

  • [ ] .parseAsyncIterable() - Parse async iterable inputs
  • [ ] .parseReadableStream() - Parse ReadableStream inputs
  • [ ] .createParserTransformStream() - Create transform streams from parsers
  • [ ] Support for left recursion in grammars

Acknowledgements

This library was inspired by the following projects and resources: