{"id":23255177,"url":"https://github.com/ismailceylan/ascii-byte-stream","last_synced_at":"2026-02-09T03:32:41.451Z","repository":{"id":245397436,"uuid":"818413873","full_name":"ismailceylan/ascii-byte-stream","owner":"ismailceylan","description":"Makes logical operations on sets of strings using a cursor technique by treating them as streams.","archived":false,"fork":false,"pushed_at":"2024-11-18T15:42:02.000Z","size":59,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-31T03:55:56.043Z","etag":null,"topics":["byte","cursor","regular-expressions","stream"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ismailceylan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2024-06-21T19:58:22.000Z","updated_at":"2024-11-18T15:42:17.000Z","dependencies_parsed_at":"2024-06-22T00:23:59.246Z","dependency_job_id":"e6da53be-ef06-4184-b505-ce53b79c3a77","html_url":"https://github.com/ismailceylan/ascii-byte-stream","commit_stats":null,"previous_names":["ismailceylan/ascii-byte-stream"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ismailceylan/ascii-byte-stream","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismailceylan%2Fascii-byte-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismailceylan%2Fascii-byte-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismailceylan%2Fascii-byte-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismailceylan%2Fascii-byte-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ismailceylan","download_url":"https://codeload.github.com/ismailceylan/ascii-byte-stream/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ismailceylan%2Fascii-byte-stream/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29255602,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T03:07:45.136Z","status":"ssl_error","status_checked_at":"2026-02-09T03:07:24.123Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["byte","cursor","regular-expressions","stream"],"created_at":"2024-12-19T11:18:46.503Z","updated_at":"2026-02-09T03:32:41.437Z","avatar_url":"https://github.com/ismailceylan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ASCII Byte Stream\nThis is a small library that allows us to make logical operations on sets of strings using a cursor technique by treating them as streams.\n\n## Installation\n```bash\nnpm install @iceylan/ascii-byte-stream\n```\n\n## Usage\n```js\nimport ASCIIByteStream from \"@iceylan/ascii-byte-stream\";\n\nconst stream = new ASCIIByteStream( \"Hello, World!\" );\n\nstream.current; // \"H\"\nstream.cursor; // 0\n```\n\n## Properties\n`ASCIIByteStream` has the following properties:\n\n### cursor\nThe cursor is a writable and readable integer property that indicates the current character that the stream is pointing at. It starts at 0 and goes to the length of the stream - 1. Zeroth character is the first character in the stream. \n\n```js\nstream.cursor = 4;\nstream.current; // \"o\"\n```\n\n### raw\nWe can always access original string. This library does not modify the original data.\n\n```js\nstream.raw; // \"Hello, World!\"\n```\n\n### current\nIf we want to access the current character that the cursor is pointing at, we can use the `current` property.\n\nIt is a read only property. If the cursor has reached at the end of the stream, this will be undefined.\n\n```js\nstream.current; // \"H\"\n\nstream.cursor = Infinity;\nstream.current; // undefined\n```\n\n### next\nWe can move the cursor one character forward with the `next` property. It is a read only property with has a side effect on the cursor. If the cursor has reached at the end of the stream, this will be undefined. Otherwise it will return the next character in the stream.\n\n```js\nstream.current; // \"H\"\nstream.next; // \"e\"\nstream.current; // \"e\"\n```\n\n### prev\nWe can move the cursor one character backward with the `prev` property. It is also a read only property. If the cursor has reached at the beginning of the stream, this will return undefined. Otherwise it will return the previous character in the stream.\n\n```js\nstream.cursor = 4;\nstream.current; // \"o\"\n\nstream.prev; // \"l\"\nstream.current; // \"l\"\n```\n\n### length\nThe `length` property indicates the length of the stream. It is a read only property and an alias for `raw.length`.\n\n```js\nstream.length; // 13\nstream.raw.length; // 13\n```\n\n## Methods\n`ASCIIByteStream` has the following methods:\n\n### matches\nWe can match from the current character with the given target. It returns `true` if it matches, and `false` if it doesn't.\n\n```js\nstream.current; // \"H\"\n\nstream.matches( \"H\" ); // true\nstream.matches( \"Hell\" ); // true\nstream.matches( \"o\" ); // false\n```\n\nIt does not move the cursor.\n\n### before\nIt matches if the given target is found before the current character. It returns `true` if it matches, and `false` if it doesn't.\n\n```js\nstream.cursor = 4; // \"o\"\nstream.before( \"Hell\" ); // true\n```\n\nIt also does not move the cursor.\n\n### after\nIt matches if the given target is found after the current character. It returns `true` if it matches, and `false` if it doesn't. This method is very similar to `matches` method except that it doesn't use current character, starts from the next character.\n\n```js\nstream.cursor = 2; // \"e\"\nstream.after( \"llo\" ); // true\n```\n\nIt also does not move the cursor.\n\n### distanceTo\nIt returns there is how many characters between the current character and the given target. If the target is not found, it returns `Infinity`.\n\n```js\n// Hello World!\nstream.cursor = 0; // \"H\"\nstream.distanceTo( \"W\" ); // 5\n```\n\n### closest\nIt takes an array of targets and calculates their distances to the current character. It returns an array of arrays, where each inner array contains the target and its distance to the current position in the stream and the returned root array will be sorted in ascending before returned.\n\n```js\nstream.cursor = 0; // \"H\"\nstream.closest([ \"!\", \"W\" ]);\n```\n\nThe returned array is like:\n\n```js\n[\n\t[ \"W\", 5 ],\n\t[ \"!\", 10 ]\n]\n```\n\n### startTransaction\nIt starts a transaction. Returns a function that should be called after the transaction is done. It can be used to rollback the cursor.\n\n```js\nstream.current;\t// \"H\"\nstream.next; // \"e\"\n\nconst rollback = stream.startTransaction();\n\nstream.next; // \"l\"\nstream.next; // \"l\"\nstream.next; // \"o\"\nstream.cursor; // 4\n\nrollback();\n\nstream.current; // \"e\"\nstream.cursor; // 1\n```\n\n### getUntil\nIt returns a substring from the current cursor position to the first occurrence of the given target. If the target is not found, it returns `undefined`.\n\n```js\nstream.current; // \"H\"\nstream.getUntil( \" \" ); // \"Hello\"\n\nstream.current; // \" \"\nstream.cursor; // 5\n\nstream.getUntil( \"x\" ); // undefined\n```\n\nIt will move the cursor.\n\n### slice\nIt returns a substring as given `length` from the current cursor position. If the given `length` is negative, it will throws a `RangeError`. If `length` is `Infinity`, it will return all the remaining characters in the stream from the current cursor position. It will move the cursor.\n\n```js\nstream.cursor = 1;\nstream.current; // \"e\"\n\nstream.slice( 3 ); // \"ell\"\n\nstream.current; // \"o\"\nstream.cursor; // 4\n\nstream.slice( -1 ); // RangeError\nstream.slice( Infinity ); // \"o World!\"\n```\n\n### move\nIt moves the cursor ahead from the current position by the given `length`. If the given `length` is negative, it will move the cursor backwards. It returns the stream's itself.\n\n```js\n// Hello World!\nstream.current; // \"e\"\nstream.cursor; // 1\n\nstream.move( 6 );\n\nstream.current; // \"o\"\nstream.cursor; // 7\n```\n\n### moveTo\nIt teleports the cursor to the given position. It returns the stream's itself. Its an alias for `stream.cursor = position` syntax.\n\n```js\nstream.current; // \"e\"\nstream.cursor; // 1\n\nstream.moveTo( 6 );\n\nstream.current; // \"W\"\nstream.cursor; // 6\n\nstream.moveTo( 0 );\n\nstream.current; // \"H\"\nstream.cursor; // 0\n```\n\n### jumpTo\nIt finds the index of the target in the stream starting from the current cursor position and move the cursor to that position. It returns the cursor position.\n\n```js\nstream.cursor = 1;\nstream.current; // \"e\"\n\nstream.jumpTo( \"W\" ); // 6\n\nstream.current; // \"W\"\nstream.cursor; // 6\n```\n\n### consume\nIt eats the given target character set(s) starting from the position of the cursor in the stream until it encounters something else.\n\nThe consumed data will be returned.\n\n```js\n//   v  \u003c-- cursor is here\n\"Hellooo World!\".consume( \"o\" ); // ooo\n//      ^  \u003c-- cursor is here now\n```\n\nIt supports multibyte character targets.\n\n```js\n//     v  \u003c-- cursor is here\n\"Hello 121212 World!\".consume( \"12\" ); // 121212 \n//           ^  \u003c-- cursor is here now\n```\n\nIt supports more than one target. With this, it will consume if the characters at the reached position matches with any of the given targets.\n\n```js\n//    v  \u003c-- cursor is here\n\"Hello\\s\\t\\t\\s\\sWorld!\".consume([ \"\\s\", \"\\t\" ]); // \\s\\t\\t\\s\\s\n//              ^  \u003c-- cursor is here now\n```\n\n## Iteration\nWe can easily iterate over the stream.\n\n### do-while loop\nSince the library returns undefined values for `next` property to indicate the cursor has reached the end of the stream, we can use it a `do-while` braker. This kind of loop will walk over all the characters in the stream individually unless we move the cursor manually inside the loop.\n\n```js\nlet stack = \"\";\n\ndo\n{\n\t// we can consume current character\n\tstack += stream.current;\n}\nwhile( stream.next !== undefined );\n\nconsole.log( stack );\n// Hello World!\n```\n\n### while loop\nWe can also use `while` loop to iterate over the stream. This kind of loop will give us opportunity to move the cursor when we need to and move as long as we need to.\n\n```js\nlet stack = \"\";\n\nwhile( stream.current !== undefined )\n{\n\t// we can consume current character\n\tstack += stream.current;\n\n\t// we should move the cursor\n\tstream.next;\n}\n\nconsole.log( stack );\n// Hello World!\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fismailceylan%2Fascii-byte-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fismailceylan%2Fascii-byte-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fismailceylan%2Fascii-byte-stream/lists"}