{"id":19584793,"url":"https://github.com/flex-development/vfile-reader","last_synced_at":"2026-02-25T06:36:13.888Z","repository":{"id":238621317,"uuid":"796928608","full_name":"flex-development/vfile-reader","owner":"flex-development","description":"vfile utility to read from a file","archived":false,"fork":false,"pushed_at":"2025-02-17T11:56:58.000Z","size":2866,"stargazers_count":2,"open_issues_count":14,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-28T13:33:38.721Z","etag":null,"topics":["character","code-point","reader","unicode","vfile","vfile-util"],"latest_commit_sha":null,"homepage":"https://github.com/flex-development/vfile-reader","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flex-development.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/funding.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["flex-development"]}},"created_at":"2024-05-06T22:07:52.000Z","updated_at":"2024-11-21T11:16:42.000Z","dependencies_parsed_at":"2024-05-20T12:28:25.485Z","dependency_job_id":"a6798b67-d78a-408c-b22b-7cb8ec6461a9","html_url":"https://github.com/flex-development/vfile-reader","commit_stats":null,"previous_names":["flex-development/vfile-reader"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/flex-development/vfile-reader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fvfile-reader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fvfile-reader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fvfile-reader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fvfile-reader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flex-development","download_url":"https://codeload.github.com/flex-development/vfile-reader/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flex-development%2Fvfile-reader/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29812618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-25T05:36:42.804Z","status":"ssl_error","status_checked_at":"2026-02-25T05:36:31.934Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["character","code-point","reader","unicode","vfile","vfile-util"],"created_at":"2024-11-11T07:49:46.567Z","updated_at":"2026-02-25T06:36:13.868Z","avatar_url":"https://github.com/flex-development.png","language":"TypeScript","funding_links":["https://github.com/sponsors/flex-development"],"categories":[],"sub_categories":[],"readme":"# vfile-reader\n\n[![github release](https://img.shields.io/github/v/release/flex-development/vfile-reader.svg?include_prereleases\u0026sort=semver)](https://github.com/flex-development/vfile-reader/releases/latest)\n[![npm](https://img.shields.io/npm/v/@flex-development/vfile-reader.svg)](https://npmjs.com/package/@flex-development/vfile-reader)\n[![codecov](https://codecov.io/gh/flex-development/vfile-reader/graph/badge.svg?token=XJBC8OxhNZ)](https://codecov.io/gh/flex-development/vfile-reader)\n[![module type: esm](https://img.shields.io/badge/module%20type-esm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)\n[![license](https://img.shields.io/github/license/flex-development/vfile-reader.svg)](LICENSE.md)\n[![conventional commits](https://img.shields.io/badge/-conventional%20commits-fe5196?logo=conventional-commits\u0026logoColor=ffffff)](https://conventionalcommits.org/)\n[![typescript](https://img.shields.io/badge/-typescript-3178c6?logo=typescript\u0026logoColor=ffffff)](https://typescriptlang.org/)\n[![vitest](https://img.shields.io/badge/-vitest-6e9f18?style=flat\u0026logo=vitest\u0026logoColor=ffffff)](https://vitest.dev/)\n[![yarn](https://img.shields.io/badge/-yarn-2c8ebb?style=flat\u0026logo=yarn\u0026logoColor=ffffff)](https://yarnpkg.com/)\n\n[vfile][vfile] utility to read from a file\n\n## Contents\n\n- [What is this?](#what-is-this)\n- [When should I use this?](#when-should-i-use-this)\n- [Install](#install)\n- [Use](#use)\n- [API](#api)\n  - [`Reader(file[, start])`](#readerfile-start)\n    - [`Reader#eof`](#readereof)\n    - [`Reader#includes(value)`](#readerincludesvalue)\n    - [`Reader#index`](#readerindex)\n    - [`Reader#next`](#readernext)\n    - [`Reader#now()`](#readernow)\n    - [`Reader#offset([point])`](#readeroffsetpoint)\n    - [`Reader#output`](#readeroutput)\n    - [`Reader#peek([k])`](#readerpeekk)\n    - [`Reader#point([offset])`](#readerpointoffset)\n    - [`Reader#previous`](#readerprevious)\n    - [`Reader#read([k])`](#readerreadk)\n    - [`Reader#reset()`](#readerreset)\n    - [`Reader#serialize(...values)`](#readerserializevalues)\n    - [`Reader#slice(range)`](#readerslicerange)\n    - [`Reader#sliceSerialize(range)`](#readersliceserializerange)\n    - [`Reader#start`](#readerstart)\n  - [`CharacterReader(file[, start])`](#characterreaderfile-start)\n    - [`CharacterReader#peekMatch(test)`](#characterreaderpeekmatchtest)\n  - [`CodeReader(file[, start])`](#codereaderfile-start)\n    - [`CodeReader.check(test)`](#codereaderchecktest)\n    - [`CodeReader.serialize(...codes)`](#codereaderserializecodes)\n    - [`CodeReader#check(test)`](#codereaderchecktest-1)\n  - [`chars`](#chars)\n  - [`codes`](#codes)\n  - [`CharacterMatch`](#charactermatch)\n  - [`Character`](#character)\n  - [`CodeCheckFactory`](#codecheckfactory)\n  - [`CodeCheck`](#codecheck)\n  - [`Code`](#code)\n  - [`Position`](#position)\n  - [`RangeTuple`](#rangetuple)\n  - [`Range`](#range)\n  - [`ReaderIterator\u003cT\u003e`](#readeriteratort)\n  - [`ReaderIteratorResult`](#readeriteratorresult)\n  - [`ReaderSlice\u003cT\u003e`](#readerslicet)\n  - [`ReaderValue`](#readervalue)\n  - [`ReaderValues\u003cT\u003e`](#readervaluest)\n- [Types](#types)\n- [Related](#related)\n- [Contribute](#contribute)\n\n## What is this?\n\nThis package implements an input reader that can be used to read characters and character codes (code points) from a\nfile.\n\n## When should I use this?\n\nThis package is useful when characters or codes need to be read individually or as a group, such as when building a\nparser or tokenizer.\n\n## Install\n\nThis package is [ESM only][esm].\n\nIn Node.js (version 18+) with [yarn][yarn]:\n\n```sh\nyarn add @flex-development/vfile-reader\n```\n\n\u003cblockquote\u003e\n  \u003csmall\u003e\n    See \u003ca href='https://yarnpkg.com/protocol/git'\u003eGit - Protocols | Yarn\u003c/a\u003e\n    \u0026nbsp;for details regarding installing from Git.\n  \u003c/small\u003e\n\u003c/blockquote\u003e\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```ts\nimport {\n  CharacterReader,\n  CodeReader,\n  chars,\n  codes\n} from 'https://esm.sh/@flex-development/vfile-reader'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import {\n    CharacterReader,\n    CodeReader,\n    chars,\n    codes\n  } from 'https://esm.sh/@flex-development/vfile-reader'\n\u003c/script\u003e\n```\n\n## Use\n\n```ts\nimport { CharacterReader, CodeReader } from '@flex-development/vfile-reader'\nimport { read } from 'to-vfile'\nimport type { VFile } from 'vfile'\n\nconst file: VFile = await read('__fixtures__/emojis.txt') // 😍👍🚀❇️\n\nconst chars: CharacterReader = new CharacterReader(file)\nconst codes: CodeReader = new CodeReader(file)\n\n// for (const char of chars) console.dir({ char, now: chars.now() })\n// for (const code of codes) console.dir({ code, now: codes.now() })\n\nwhile (!chars.eof) {\n  console.dir({\n    char: chars.read(),\n    code: codes.read(),\n    now: codes.now()\n  })\n}\n```\n\n...yields\n\n```sh\n{ char: '😍', code: 128525, now: { column: 1, line: 1, offset: 0 } }\n{ char: '👍', code: 128077, now: { column: 2, line: 1, offset: 1 } }\n{ char: '🚀', code: 128640, now: { column: 3, line: 1, offset: 2 } }\n{ char: '❇', code: 10055, now: { column: 4, line: 1, offset: 3 } }\n{ char: '️', code: 65039, now: { column: 5, line: 1, offset: 4 } }\n{ char: '\\n', code: 10, now: { column: 6, line: 1, offset: 5 } }\n{ char: null, code: null, now: { column: 1, line: 2, offset: 6 } }\n```\n\n## API\n\nThis package exports the following identifiers:\n\n- [`CharacterReader`](#characterreaderfile-start)\n- [`CodeReader`](#codereaderfile-start)\n- [`Reader`](#readerfile-start)\n- [`chars`](#chars)\n- [`codes`](#codes)\n\nThere is no default export.\n\n### `Reader(file[, start])`\n\n\u003e **extends**: [`Location`][location]\\\n\u003e **implements**: [`ReaderIterator\u003cT\u003e`](#readeriteratort)\n\nCreate a new input reader.\n\nPass a `start` point to make reader locations relative to a specific place. Any point or offset accessed will be\nrelative to the given point.\n\n**Note**: This is an abstract class and must be extended.\n\n- `file` ([`Value`][vfile-value] | [`VFile`][vfile-api] | `null` | `undefined`) \u0026mdash; file to read\n- `start` ([`Point`][point] | `null` | `undefined`) \u0026mdash; point before first reader value\n\n#### \u003csmall\u003eType Parameters\u003c/small\u003e\n\n- `T` ([`ReaderValue`](#readervalue)) \u0026mdash; reader output value\n\n#### `Reader#eof`\n\n(`boolean`) Boolean indicating if reader has reached the end of file, with `true` denoting end of file.\n\n#### `Reader#includes(value)`\n\nCheck if the file contains the given search `value`, relative to the current reader position.\n\n##### `Parameters`\n\n- `value` (`string`) \u0026mdash; value to search for in file\n\n##### `Returns`\n\n(`boolean`) `true` if file contains search `value`.\n\n#### `Reader#index`\n\n([`Offset`][offset]) Index of current reader value.\n\n#### `Reader#next()`\n\nGet the next reader result.\n\nUnlike [`peek`](#readerpeekk), this method changes the position of the reader.\n\n##### `Returns`\n\n([`ReaderIteratorResult\u003cT\u003e`](#readeriteratorresult)) Next reader result.\n\n#### `Reader#now()`\n\nGet the current point in the file.\n\n##### `Returns`\n\n([`Point`][point]) Current point in file, relative to [`reader#start`](#readerstart).\n\n#### `Reader#offset([point])`\n\nSee [`Location#offset([point])`][locationoffset-point].\n\n#### `Reader#output`\n\n(`T`) Current reader value or `null`, with `null` denoting end of file. Equivalent to\n[`reader.peek(0)`](#readerpeekk).\n\n#### `Reader#peek([k])`\n\nGet the next `k`-th reader value from the file without changing the position of the reader, with `null` denoting end of\nfile.\n\n##### `Parameters`\n\n- `k` (`number | undefined`) \u0026mdash; difference between index of next `k`-th reader value and index of current value\n  - **default**: `1`\n\n##### `Returns`\n\n(`T`) Peeked reader value or `null`.\n\n#### `Reader#point([offset])`\n\nSee [`Location#point([offset])`][locationpoint-offset].\n\n#### `Reader#previous`\n\n(`T`) Previous reader value or `null`, with `null` denoting beginning or end of file. Equivalent to\n[`reader.peek(-1)`](#readerpeekk).\n\n#### `Reader#read([k])`\n\nGet the next `k`-th reader value from the file, with `null` denoting end of file.\n\nUnlike [`peek`](#readerpeekk), this method changes the position of the reader.\n\n##### `Parameters`\n\n- `k` (`number | undefined`) \u0026mdash; difference between index of next `k`-th reader value and index of current value\n  - **default**: `1`\n\n##### `Returns`\n\n(`T`) Next `k`-th reader value or `null`.\n\n#### `Reader#reset()`\n\nReset the position of the reader.\n\n##### `Returns`\n\n(`this`) The repositioned reader.\n\n#### `Reader#serialize(...values)`\n\nConvert the specified sequence of reader values to a string.\n\n##### `Parameters`\n\n- `...values` (`ReaderSlice\u003cT\u003e | T[]`) \u0026mdash; reader value sequence\n\n##### `Returns`\n\n(`string`) String created from reader value sequence.\n\n#### `Reader#slice(range)`\n\nGet the values spanning `range` without changing the position of the reader.\n\n##### `Parameters`\n\n- `range` ([`Range`](#range)) \u0026mdash; slice position\n\n##### `Returns`\n\n([`ReaderSlice\u003cT\u003e`](#readerslicet)) Reader value slice.\n\n#### `Reader#sliceSerialize(range)`\n\nGet the text spanning `range` without changing the position of the reader.\n\n##### `Parameters`\n\n- `range` ([`Range`](#range)) \u0026mdash; slice position\n\n##### `Returns`\n\n(`string`) Serialized slice.\n\n#### `Reader#start`\n\n([`Point`][point]) Point before first reader value in file.\n\n### `CharacterReader(file[, start])`\n\n\u003e **extends**: `Reader\u003cCharacter\u003e`\n\nCreate a new character reader.\n\n#### `CharacterReader#peekMatch(test)`\n\nGet the next match from the file without changing the position of the reader, with `null` denoting no match.\n\n##### `Parameters`\n\n- `test` (`RegExp`) \u0026mdash; character test\n\n##### `Returns`\n\n([`CharacterMatch`](#charactermatch)) Peeked character match or `null`.\n\n### `CodeReader(file[, start])`\n\n\u003e **extends**: `Reader\u003cCode\u003e`\n\nCreate a new character code reader.\n\n#### `CodeReader.check(test)`\n\nCreate a code check from a character code or regular expression.\n\n##### `Parameters`\n\n- `test` (`Code | RegExp`) \u0026mdash; test to create check from\n\n##### `Returns`\n\n([`CodeCheck`](#codecheck)) Code check.\n\n#### `CodeReader.serialize(...codes)`\n\nConvert the specified sequence of character codes to a string.\n\n##### `Parameters`\n\n- `...codes` ([`Code[]`](#code)) \u0026mdash; character code sequence\n\n##### `Returns`\n\n(`string`) String created from character code sequence.\n\n#### `CodeReader#check(test)`\n\nInstance method equivalent of [`CodeReader.check(test)`](#codereaderchecktest).\n\n### `chars`\n\nCharacter dictionary.\n\n### `codes`\n\nCharacter code dictionary.\n\n### `CharacterMatch`\n\nMatch in a source file, with `null` denoting no match (TypeScript type).\n\n```ts\ntype CharacterMatch = RegExpExecArray | null\n```\n\n### `Character`\n\nCharacter in a source file, with `null` denoting end of file (TypeScript type).\n\n```ts\ntype Character = string | null\n```\n\n### `CodeCheckFactory`\n\nCreate a code check from a character code or regular expression (TypeScript type).\n\n```ts\ntype CodeCheckFactory = (test: Code | RegExp) =\u003e CodeCheck\n```\n\n#### `Parameters`\n\n- `test` (`Code | RegExp`) \u0026mdash; test to create check from\n\n#### `Returns`\n\n([`CodeCheck`](#codecheck)) Code check.\n\n### `CodeCheck`\n\nCheck whether a character code, or sequence of codes, matches the bound test (TypeScript type).\n\n```ts\ntype CodeCheck = (code: Code | Code[]) =\u003e boolean\n```\n\n#### `Parameters`\n\n- `code` (`Code | Code[]`) \u0026mdash; code or code sequence to check\n\n#### `Returns`\n\n(`boolean`) `true` if `code` matches bound test.\n\n### `Code`\n\nCharacter code ([code point][codepointat]) in a source file, with `null` denoting end of file (TypeScript type).\n\n```ts\ntype Code = number | null\n```\n\n### `Position`\n\nRange between two points in a source file (TypeScript interface).\n\n\u003e See also: [`Point`][point]\n\n```ts\ninterface Position {\n  end: Point\n  start: Point\n}\n```\n\nThe `start` field represents the place of the first reader value in the range. The `end` field represents the place of\nthe last reader value in the range.\n\n### `RangeTuple`\n\nList, where the first value is the location of the first reader value in a slice, and the last is the location of the\nlast reader value, with `null` or `undefined` denoting all values after the first (inclusive) are included in the slice\n(TypeScript type).\n\n\u003e See also: [`Offset`][offset], [`Point`][point]\n\n```ts\ntype RangeTuple = [\n  start: Offset | Point,\n  end?: Offset | Point | null | undefined\n]\n```\n\n### `Range`\n\nUnion of range types (TypeScript type).\n\n```ts\ntype Range = Position | RangeTuple\n```\n\n### `ReaderIterator\u003cT\u003e`\n\nInput reader iterator API (TypeScript interface).\n\n```ts\ninterface ReaderIterator\u003cT extends ReaderValue = ReaderValue\u003e {\n  [Symbol.iterator](): ReaderIterator\u003cT\u003e\n  next(): ReaderIteratorResult\u003cT\u003e\n}\n```\n\n### `ReaderIteratorResult`\n\nUnion of iterator results (TypeScript type).\n\n```ts\ntype ReaderIteratorResult\u003c\n  T extends ReaderValue = ReaderValue\n\u003e = IteratorReturnResult\u003cT\u003e | IteratorYieldResult\u003cT\u003e\n```\n\n### `ReaderSlice\u003cT\u003e`\n\nArray representing a slice of reader output values (TypeScript type).\n\n```ts\ntype ReaderSlice\u003cT extends ReaderValue = ReaderValue\u003e =\n  | [...values: NonNullable\u003cT\u003e[], value: NonNullable\u003cT\u003e]\n  | [...values: ReaderValues\u003cT\u003e]\n  | []\n```\n\n### `ReaderValue`\n\nCharacter or character code in a source file, with `null` denoting the end of file (TypeScript type).\n\n```ts\ntype ReaderValue = Character | Code\n```\n\n### `ReaderValues\u003cT\u003e`\n\nReader output values (TypeScript type).\n\n```ts\ntype ReaderValues\u003cT extends ReaderValue = ReaderValue\u003e = readonly [\n  ...values: NonNullable\u003cT\u003e[],\n  eof: null\n]\n```\n\n## Types\n\nThis package is fully typed with [TypeScript][typescript].\n\n## Related\n\n- [`vfile-location`][vfile-location] \u0026mdash; [vfile][vfile] utility to convert between point and offset based locations\n\n## Contribute\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md).\n\nThis project has a [code of conduct](CODE_OF_CONDUCT.md). By interacting with this repository, organization, or\ncommunity you agree to abide by its terms.\n\n[codepointat]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n[esmsh]: https://esm.sh/\n[location]: https://github.com/flex-development/vfile-location#locationfile-start\n[locationoffset-point]: https://github.com/flex-development/vfile-location#locationoffsetpoint\n[locationpoint-offset]: https://github.com/flex-development/vfile-location#locationpointoffset\n[offset]: https://github.com/flex-development/unist-util-types#offset\n[point]: https://github.com/flex-development/vfile-location#point\n[typescript]: https://www.typescriptlang.org\n[vfile-api]: https://github.com/vfile/vfile#vfileoptions\n[vfile-location]: https://github.com/flex-development/vfile-location\n[vfile-value]: https://github.com/vfile/vfile#value\n[vfile]: https://github.com/vfile/vfile\n[yarn]: https://yarnpkg.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflex-development%2Fvfile-reader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflex-development%2Fvfile-reader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflex-development%2Fvfile-reader/lists"}