{"_id":"@byojs/matchall-starts-at","name":"@byojs/matchall-starts-at","dist-tags":{"latest":"0.0.0-pre-202605291121"},"versions":{"0.0.0-pre-202605291121":{"name":"@byojs/matchall-starts-at","description":"Hopeful/future polyfill: add start-index behavior to matchAll() regex/string matching","version":"0.0.0-pre-202605291121","main":"./src/matchall-starts-at.js","type":"module","scripts":{"test":"node test/runner.js"},"browser":{"":"./src/matchall-starts-at.js"},"exports":{".":{"types":"./src/matchall-starts-at.d.ts","default":"./src/matchall-starts-at.js"}},"repository":{"url":"git+https://github.com/byojs/matchall-starts-at.git"},"bugs":{"url":"https://github.com/byojs/matchall-starts-at/issues","email":"getify@gmail.com"},"homepage":"https://github.com/byojs/matchall-starts-at","author":{"name":"Kyle Simpson","email":"getify@gmail.com"},"license":"MIT","gitHead":"671d2bf3834ce2f21fe10e200fe3d6b75e6f6020","types":"./src/matchall-starts-at.d.ts","_id":"@byojs/matchall-starts-at@0.0.0-pre-202605291121","_nodeVersion":"24.16.0","_npmVersion":"11.15.0","dist":{"integrity":"sha512-JGLOEcEIxZn6FQHkRjErXK3tQ0/xsJtlRD5kHMUacccuEP+oIkwNgp+lUXmHtv7JTKYbuNeGhZsrhoSFyFj1oQ==","shasum":"fcdf1a9b68d1962af265b636e64fd68311205d80","tarball":"https://registry.npmjs.org/@byojs/matchall-starts-at/-/matchall-starts-at-0.0.0-pre-202605291121.tgz","fileCount":8,"unpackedSize":14047,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEXkMdK7fR3ZQgHELSJcAB6u9vSV8Fdy6CE05MEdmv7MAiAFAlttkC9POJyqs4Cdc/KiJkA/Y4fiBhKZJhUxqGumdw=="}]},"_npmUser":{"name":"getify","email":"getify@gmail.com"},"directories":{},"maintainers":[{"name":"getify","email":"getify@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/matchall-starts-at_0.0.0-pre-202605291121_1780071957144_0.8436989009820883"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T16:25:56.948Z","0.0.0-pre-202605291121":"2026-05-29T16:25:57.314Z","modified":"2026-05-29T16:25:57.705Z"},"maintainers":[{"name":"getify","email":"getify@gmail.com"}],"description":"Hopeful/future polyfill: add start-index behavior to matchAll() regex/string matching","homepage":"https://github.com/byojs/matchall-starts-at","repository":{"url":"git+https://github.com/byojs/matchall-starts-at.git"},"author":{"name":"Kyle Simpson","email":"getify@gmail.com"},"bugs":{"url":"https://github.com/byojs/matchall-starts-at/issues","email":"getify@gmail.com"},"license":"MIT","readme":"# @byojs/matchall-starts-at\n\nA BYOJS prollyfill adding explicit start-position support to JavaScript's regex match iteration APIs.\n\nJavaScript's native `String.prototype.matchAll(..)` already clones a supplied `RegExp` internally, but it also copies the regex's current `lastIndex` onto that clone. That preserves legacy regex cursor behavior, but it means `matchAll(..)` is still vulnerable to unexpected regex state.\n\nThis package preserves the existing default behavior, while adding an explicit `startsAt` parameter; to get a fresh, starting-from-the-beginning behavior, always pass `0` as the second argument:\n\n```js\nimport \"@byojs/matchall-starts-at\";\n\nvar re = /a/g;\nre.lastIndex = 2;\n\n[...\"baaa\".matchAll(re)].map(m => m.index);    // [ 2, 3 ]\n\n[...\"baaa\".matchAll(re,0)].map(m => m.index);  // [ 1, 2, 3 ]\n\n[...\"baaa\".matchAll(re,3)].map(m => m.index);  // [ 3 ]\n```\n\nThis is not a polyfill, in that there's currently no standards track proposal to add this to JS (**BUT THERE SHOULD BE!**).\n\nIt's a **prollyfill**: a speculative API improvement -- suggestion, future proposed polyfill -- for codebases that want a more explicit match-iteration cursor.\n\n## Why?\n\nNative `matchAll(..)` effectively behaves like this:\n\n```js\nvar clone = new RegExp(re);\nclone.lastIndex = re.lastIndex;\n```\n\nThis package gives you an explicit way to choose the starting position without mutating the original regex:\n\n```js\nvar clone = new RegExp(re);\nclone.lastIndex = startsAt;\n```\n\nSo this:\n\n```js\nstr.matchAll(re,0)\n```\n\nis the convenient equivalent of:\n\n```js\nvar clone = new RegExp(re);\nclone.lastIndex = 0;\n\nstr.matchAll(clone);\n```\n\n## Usage\n\nImport the package (only needed once since it patches global prototypes):\n\n```js\nimport \"@byojs/matchall-starts-at\";\n```\n\nAfter import, both APIs accept an optional finite-number `startsAt` argument:\n\n```js\nstr.matchAll(re,startsAt);\nre[Symbol.matchAll](str,startsAt);\n```\n\nThe existing one-argument behavior is preserved; **existing one-argument calls keep their native-compatible behavior**.\n\n```js\nvar re = /a/g;\nre.lastIndex = 2;\n\n[...\"baaa\".matchAll(re)].map(m => m.index);\n// [ 2, 3 ]\n\nre.lastIndex;\n// 2\n```\n\nTo ignore a polluted `lastIndex` and start from the beginning, pass `0` for the second argument:\n\n```js\nvar re = /a/g;\nre.lastIndex = 2;\n\n[...\"baaa\".matchAll(re,0)].map(m => m.index);\n// [ 1, 2, 3 ]\n\nre.lastIndex;\n// 2\n```\n\nTo start at another explicit offset:\n\n```js\n[...\"a-a-a-a\".matchAll(/a/g,4)].map(m => m.index);\n// [ 4, 6 ]\n```\n\n## Behavior\n\nThis package patches:\n\n```js\nRegExp.prototype[Symbol.matchAll]\n\nString.prototype.matchAll\n```\n\nIt only activates the new behavior when `startsAt` is a finite number:\n\n```js\n\"baaa\".matchAll(/a/g,0);         // explicit startsAt\n\"baaa\".matchAll(/a/g,2);         // explicit startsAt\n\n\"baaa\".matchAll(/a/g);           // native-compatible behavior\n\"baaa\".matchAll(/a/g,undefined); // native-compatible behavior\n\"baaa\".matchAll(/a/g,NaN);       // native-compatible behavior\n\"baaa\".matchAll(/a/g,Infinity);  // native-compatible behavior\n\"baaa\".matchAll(/a/g,\"0\");      // native-compatible behavior\n```\n\nThis narrower behavior is intentional. It avoids claiming arbitrary future second-argument shapes that JavaScript may eventually define.\n\nThat narrow activation is the main reason this package can justify patching global prototypes despite the usual \"don't touch globals\" rule.\n\n### Error on non `/g` regular expressions\n\nNon-global regex behavior for `String.prototype.matchAll(..)` is preserved:\n\n```js\n\"abc\".matchAll(/a/,0); // TypeError, same as native matchAll(..)\n```\n\nThe direct `RegExp.prototype[Symbol.matchAll](..)` path follows the platform's lower-level behavior.\n\n## Caution\n\nThis package intentionally modifies built-in prototypes.\n\nThat is appropriate for application code and controlled runtimes that deliberately opt into this behavior. It should not be imported by libraries that run inside other people's applications.\n\n## TypeScript Support\n\nType definitions for the patched/prolyfilled native prototype methods (`RegExp.prototype[Symbol.matchAll]` and `String.prototype.matchAll()`) are bundled with the package (in an external `.d.ts` file).\n\nTypeScript projects will pick the definitions up automatically; no separate `@types/` install needed.\n\n## Tests\n\nA test suite is included in this repository, as well as the npm package distribution. The default test behavior runs the test suite using the files in `src/`.\n\nTo run the test suite:\n\n```cmd\nnpm test\n```\n\n## License\n\n[![License](https://img.shields.io/badge/license-MIT-a1356a)](LICENSE.txt)\n\nAll code and documentation are (c) 2026 Kyle Simpson and released under the [MIT License](http://getify.mit-license.org/). A copy of the MIT License [is also included](LICENSE.txt).\n","readmeFilename":"README.md","_rev":"1-9a304ffe591398ae5bb4c31479c5b126"}