{"_id":"udsv","_rev":"9-9bb794e42ac8e5e95b71f05cda94736d","name":"udsv","dist-tags":{"latest":"0.7.3"},"versions":{"0.5.0":{"name":"udsv","version":"0.5.0","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.5.0","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"248aae0cf3ef75758588e6f042dc809add0cb808","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.5.0.tgz","fileCount":8,"integrity":"sha512-OZTYWdGM7K1mCSCw5cToLC++NlljolT5hb1yLnpOdKCtnggoAtiCIE+XojfssOkSlbESx0K3wJpAxJFcE5FAjw==","signatures":[{"sig":"MEUCIHqG65n2EM1hxXVPQi70fS0Xcvenroxq9Rkc+SZMCpsYAiEAtOF1a/+Tq+eSw0mjdx8GkyegsIqfQ8mszY/g4iYBjh8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":68271},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"18ffc088cea9cbcc4c4ff347b504b81af1a797d7","scripts":{"test":"node ./test/parse.spec.mjs && node ./test/api.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"9.8.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"20.5.1","_hasShrinkwrap":false,"devDependencies":{"rollup":"^3.28.1","papaparse":"^5.4.1","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.3"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.5.0_1693842338897_0.6797260115141297","host":"s3://npm-registry-packages"}},"0.5.1":{"name":"udsv","version":"0.5.1","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.5.1","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"dfc1ec3881987be08859a0e38043311402658204","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.5.1.tgz","fileCount":8,"integrity":"sha512-PvmZwBNpWLjmMgkh7jQY91MH156zKC/+CcJmB6x8OJqtE7upMqSxZFg5/hbP7qk2nEtQiGqXHflVHynwMwHKuA==","signatures":[{"sig":"MEQCIC6sgu8mKCM4QQrck86UlKISO2j3SAKUNYzdGlvNs59TAiBqcwk13AMezXh95Cjku3B50f+TLxZqlFuZxPO9hpVRMA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":69496},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"fd399bfa464ac7f80f6236a67bac8d990b382091","scripts":{"test":"node ./test/parse.spec.mjs && node ./test/api.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"9.8.1","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"20.6.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^3.28.1","papaparse":"^5.4.1","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.3"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.5.1_1693941065305_0.5760254924338815","host":"s3://npm-registry-packages"}},"0.5.2":{"name":"udsv","version":"0.5.2","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.5.2","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"c6be12a05023d758cdfbd99ea50e513964b469a5","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.5.2.tgz","fileCount":8,"integrity":"sha512-9Hdih75q3u4FqmVJhEr1azSxY9moYgDQEHWjlrJOIrIUng4lbiuwgKoBMhT1oMSjyf2Zg6ynsUThsAdC8Xg/Fw==","signatures":[{"sig":"MEUCIQCVDFo0iCz4xGilK547EAvSoXaWA4HNCUFL0vg411TJKAIgdAFFbjWwHHAMEWEmKW35Uo97hLsFtnht3uONOjY7eNE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":69561},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"ee54fd0e35724a95d9f98f0a0e9bcc46c1bef3be","scripts":{"test":"node ./test/parse.spec.mjs && node ./test/api.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"9.8.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"20.5.1","_hasShrinkwrap":false,"devDependencies":{"rollup":"^3.29.0","papaparse":"^5.4.1","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.3"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.5.2_1694136579865_0.32832621976475784","host":"s3://npm-registry-packages"}},"0.5.3":{"name":"udsv","version":"0.5.3","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.5.3","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"b6bf405e1f9e3c6c79e1d2ed75d59592aed27e39","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.5.3.tgz","fileCount":8,"integrity":"sha512-A4WSOXDgyu3ZlQnMZu9lVtuAhke9X5XG9RZFGbO3urSiCjwYKfy96XV/+BWnm1Y1lKKaBInU0e98Moy6TOiVYA==","signatures":[{"sig":"MEQCIEddh4O/mmV0mcBwkXY1C3blxy5/86UhELNTMa3QSZs/AiBAUwzZj2otLksURUoBsxDGriEaDKgIPF+rBaHGlieXGA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":69573},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"9863d38181512891fcf06fa765df6879a5ae8cda","scripts":{"test":"node ./test/parse.spec.mjs && node ./test/api.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"9.8.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"20.5.1","_hasShrinkwrap":false,"devDependencies":{"rollup":"^3.29.0","papaparse":"^5.4.1","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.3"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.5.3_1694292075171_0.0012318116586542693","host":"s3://npm-registry-packages"}},"0.6.0":{"name":"udsv","version":"0.6.0","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.6.0","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"6520e5a5f43e7822115c66f5b1ae1fbf39732e60","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.6.0.tgz","fileCount":8,"integrity":"sha512-na+0EoqqpDeNKZ0HVTtgYtFP9aQgsMwPM77UEK7g4OX2C42w+Qw7QZs9t1ocDGLidtcKJnsPy+o5XrBYaZfzCA==","signatures":[{"sig":"MEUCIQC8yTVqtBaQrN7rLLw0sjCLouLdxTv0RbEXadH0lpMetwIgLv5jqGPZGsV5Z1ZSnCVx5ZyGKZGkGBVRGTajErJGAr8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":71496},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"986aace78dfb9c8878dbb19c24451c649a48c204","scripts":{"test":"node ./test/parse.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"10.9.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.24.3","papaparse":"^5.4.1","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.6.0_1730685124608_0.6468722057899108","host":"s3://npm-registry-packages"}},"0.7.0":{"name":"udsv","version":"0.7.0","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.7.0","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"4e05440a644ad3b3ad88900ff077d29aa1fc8281","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.7.0.tgz","fileCount":8,"integrity":"sha512-aDnPk8QIgUFYBOkNAaRPEr0Ogt94j9z4kH89ZNkJNYJzSSEIQrfyTtNBG4HsYrcG/PZ3FpjbYTU6V2LfhUar7Q==","signatures":[{"sig":"MEYCIQC7dmSacch3K8ecbF/mtypl9kqNPlFigr/oybMR2PGFXwIhAMHP70opFY1mq1j+OGr0qflZ9wwlIpSTzIA+skmobclk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":79221},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"7ef9bbe25e21b6a33677480406d2ff04323e2ce5","scripts":{"test":"node ./test/parse.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"11.1.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.34.9","papaparse":"^5.5.2","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.7.0_1740940985324_0.7341411441580399","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"udsv","version":"0.7.1","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.7.1","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"7f57a7193e8a143b6949fa3e51e040f29eed8e5b","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.7.1.tgz","fileCount":8,"integrity":"sha512-f+r+dhMf6itVmkQXULl5OSvqobpKgm62DaXkkj+MIGLHFGKFct+6hE+5Qqf0KoLG3GS31AYOMygapUEJKMJfCg==","signatures":[{"sig":"MEUCIByNQnD9nH6TPqbIu/vUQo6jOCXS1Udjht0agkDHKOD4AiEAiRNWHdQZbvRRftX97AYvt/6iqZUEP3eFb8GMhaiRCnI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80513},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"25f051c457329b8bcabc91682c4f9b6b1c3c1413","scripts":{"test":"node ./test/parse.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"11.1.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.34.9","papaparse":"^5.5.2","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.7.1_1741038439774_0.46220800197028655","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"udsv","version":"0.7.2","keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","_id":"udsv@0.7.2","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"homepage":"https://github.com/leeoniya/uDSV#readme","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"dist":{"shasum":"d8ec49aa866af40ba52214c5b565ea67991a74d2","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.7.2.tgz","fileCount":8,"integrity":"sha512-It3T8Ho4fF/yVOmce6Ddl0e62i1Cpf5vD+NmMHYNjrimTSR7gPaT3yJ8Jsn/wXuEF9w8ZAV6IkXX8jSH+zkeCg==","signatures":[{"sig":"MEUCIGbtJk+Y63KPDfCm6LNZqaM6MGPNJA6jvD+g+tCsuwWrAiEAsKBg0V2JYxrKFqJdhmZtVEySgts3pXYaF293WGMRPtg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":80927},"main":"./dist/uDSV.cjs.js","types":"./dist/uDSV.d.ts","module":"./dist/uDSV.mjs","gitHead":"e2eac7fc67406aa08066e8bab48ef204aac979bb","scripts":{"test":"node ./test/parse.spec.mjs","build":"rollup -c --bundleConfigAsCjs"},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com"},"repository":{"url":"git+https://github.com/leeoniya/uDSV.git","type":"git"},"_npmVersion":"11.2.0","description":"A small, fast CSV parser","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.39.0","papaparse":"^5.5.2","rollup-plugin-re":"^1.0.7","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/udsv_0.7.2_1743909463053_0.40787859784091385","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"name":"udsv","version":"0.7.3","description":"A small, fast CSV parser","main":"./dist/uDSV.cjs.js","module":"./dist/uDSV.mjs","types":"./dist/uDSV.d.ts","scripts":{"build":"rollup -c --bundleConfigAsCjs","test":"node ./test/parse.spec.mjs"},"repository":{"type":"git","url":"git+https://github.com/leeoniya/uDSV.git"},"keywords":["csv","parse","parser"],"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"homepage":"https://github.com/leeoniya/uDSV#readme","devDependencies":{"@rollup/plugin-terser":"^0.4.4","papaparse":"^5.5.3","rollup":"^4.44.2","rollup-plugin-re":"^1.0.7"},"_id":"udsv@0.7.3","gitHead":"c11a444b26419b5a3c4db9c5c5400a4328e7741b","_nodeVersion":"24.3.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-RLDImCO8M0DQmMi9V9YRjoecAc8+GiylpZico6ZuibPvRGRj3LGI1YPYLzBrnQTSax0metXnDoBFg/1zSgGIhg==","shasum":"086340f1447921e194fb4bb79da6ba01e8cc2ffa","tarball":"https://registry.npmjs.org/udsv/-/udsv-0.7.3.tgz","fileCount":8,"unpackedSize":80771,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDvb5ORn2UltIBoweiVg+9RGjo/UaxO/R+yIUUxtNj7JAIgataoJ4onASxxVLiB+ApkpY5AdnWaVVF93WmZz17kquc="}]},"_npmUser":{"name":"leeoniya","email":"leeoniya@gmail.com","actor":{"name":"leeoniya","email":"leeoniya@gmail.com","type":"user"}},"directories":{},"maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/udsv_0.7.3_1751836247129_0.6551975141153807"},"_hasShrinkwrap":false}},"time":{"created":"2023-09-04T15:45:38.896Z","modified":"2025-07-06T21:10:47.495Z","0.5.0":"2023-09-04T15:45:39.084Z","0.5.1":"2023-09-05T19:11:05.509Z","0.5.2":"2023-09-08T01:29:40.017Z","0.5.3":"2023-09-09T20:41:15.393Z","0.6.0":"2024-11-04T01:52:04.769Z","0.7.0":"2025-03-02T18:43:05.502Z","0.7.1":"2025-03-03T21:47:19.959Z","0.7.2":"2025-04-06T03:17:43.264Z","0.7.3":"2025-07-06T21:10:47.315Z"},"bugs":{"url":"https://github.com/leeoniya/uDSV/issues"},"author":{"name":"Leon Sorokin","email":"leeoniya@gmail.com"},"license":"MIT","homepage":"https://github.com/leeoniya/uDSV#readme","keywords":["csv","parse","parser"],"repository":{"type":"git","url":"git+https://github.com/leeoniya/uDSV.git"},"description":"A small, fast CSV parser","maintainers":[{"name":"leeoniya","email":"leeoniya@gmail.com"}],"readme":"## 𝌠 μDSV\n\nA [faster](#performance) CSV parser in [5KB (min)](https://github.com/leeoniya/uDSV/tree/main/dist/uDSV.iife.min.js) _(MIT Licensed)_\n\n---\n### Introduction\n\nuDSV is a fast JS library for parsing well-formed CSV strings, either from memory or incrementally from disk or network.\nIt is mostly [RFC 4180](https://datatracker.ietf.org/doc/html/rfc4180) compliant, with support for quoted values containing commas, escaped quotes, and line breaks¹.\nThe aim of this project is to handle the 99.5% use-case without adding complexity and performance trade-offs to support the remaining 0.5%.\n\n¹ Line breaks (`\\n`,`\\r`,`\\r\\n`) within quoted values must match the row separator.\n\n---\n### Features\n\nWhat does uDSV pack into 5KB?\n\n- [RFC 4180](https://datatracker.ietf.org/doc/html/rfc4180) compliant\n- Incremental or full parsing, with optional accumulation\n- Auto-detection and customization of delimiters (rows, columns, quotes, escapes)\n- Schema inference and value typing: `string`, `number`, `boolean`, `date`, `json`\n- Defined handling of `''`, `'null'`, `'NaN'`\n- Whitespace trimming of values & skipping empty lines\n- Multi-row header skipping and column renaming\n- Multiple outputs: arrays (tuples), objects, nested objects, columnar arrays\n\nOf course, _most_ of these are table stakes for CSV parsers :)\n\n---\n### Performance\n\nIs it Lightning Fast™ or Blazing Fast™?\n\nNo, those are too slow! uDSV has [Ludicrous Speed™](https://www.youtube.com/watch?v=ygE01sOhzz0);\nit's faster than the parsers you recognize and faster than those you've never heard of.\n\nMost CSV parsers have one happy/fast path -- the one without quoted values, without value typing, and only when using the default settings & output format.\nOnce you're off that path, you can generally throw any self-promoting benchmarks in the trash.\nIn contrast, uDSV remains fast with any datasets and all options; its happy path is _every path_.\n\nOn a Ryzen 7 ThinkPad, Linux v6.14.7, and NodeJS v24.1.0, a diverse set of benchmarks show a 2x-5x performance boost relative to the [popular](https://github.com/search?q=csv+parser&type=repositories&s=stars&o=desc), [proven-fast](https://leanylabs.com/blog/js-csv-parsers-benchmarks/), [Papa Parse](https://www.papaparse.com/).\n\n**Parsing to arrays of strings**\n\n<pre>\n┌───────────────────────────────────────────────────────────────────────────────────────────────┐\n│ customers-100000.csv (17 MB, 12 cols x 100K rows)                        (parsing to strings) │\n├────────────────────────┬────────┬─────────────────────────────────────────────────────────────┤\n│ Name                   │ Rows/s │ Throughput (MiB/s)                                          │\n├────────────────────────┼────────┼─────────────────────────────────────────────────────────────┤\n│ csv-simple-parser      │ 2.21M  │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 366 │\n│ uDSV                   │ 2M     │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 330      │\n│ but-csv                │ 1.15M  │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 190                           │\n│ PapaParse              │ 1.13M  │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 186                           │\n│ ACsv                   │ 1.12M  │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 185                            │\n│ tiddlycsv              │ 1.11M  │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 183                            │\n│ d3-dsv                 │ 939K   │ ░░░░░░░░░░░░░░░░░░░░░░░░ 155                                │\n│ csv-rex                │ 884K   │ ░░░░░░░░░░░░░░░░░░░░░░ 146                                  │\n│ achilles-csv-parser    │ 856K   │ ░░░░░░░░░░░░░░░░░░░░░░ 141                                  │\n│ csv42                  │ 807K   │ ░░░░░░░░░░░░░░░░░░░░░ 133                                   │\n│ arquero                │ 541K   │ ░░░░░░░░░░░░░░ 89.4                                         │\n│ node-csvtojson         │ 478K   │ ░░░░░░░░░░░░ 78.9                                           │\n│ comma-separated-values │ 469K   │ ░░░░░░░░░░░░ 77.4                                           │\n│ CSVtoJSON              │ 447K   │ ░░░░░░░░░░░░ 73.8                                           │\n│ SheetJS                │ 411K   │ ░░░░░░░░░░░ 67.8                                            │\n│ @vanillaes/csv         │ 396K   │ ░░░░░░░░░░ 65.4                                             │\n│ csv-parser (neat-csv)  │ 278K   │ ░░░░░░░ 45.9                                                │\n│ dekkai                 │ 211K   │ ░░░░░░ 34.8                                                 │\n│ @gregoranders/csv      │ 198K   │ ░░░░░ 32.6                                                  │\n│ csv-js                 │ 193K   │ ░░░░░ 31.9                                                  │\n│ csv-parse/sync         │ 153K   │ ░░░░ 25.3                                                   │\n│ jquery-csv             │ 153K   │ ░░░░ 25.3                                                   │\n│ @fast-csv/parse        │ 106K   │ ░░░ 17.6                                                    │\n│ utils-dsv-base-parse   │ 68.9K  │ ░░ 11.4                                                     │\n└────────────────────────┴────────┴─────────────────────────────────────────────────────────────┘\n</pre>\n\n**Parsing to arrays with types**\n\nNote: `date` in the Types column means the lib created 100,000 `Date` objects; not all libs do.\n\n<pre>\n┌───────────────────────────────────────────────────────────────────────────────────────────────┐\n│ customers-100000.csv (17 MB, 12 cols x 100K rows)                        (parsing with types) │\n├────────────────────────┬────────┬────────────────────────────────────────┬────────────────────┤\n│ Name                   │ Rows/s │ Throughput (MiB/s)                     │ Types              │\n├────────────────────────┼────────┼────────────────────────────────────────┼────────────────────┤\n│ uDSV                   │ 967K   │ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 160 │ date,number,string │\n│ csv42                  │ 712K   │ ░░░░░░░░░░░░░░░░░░░░░░░░░░ 118         │ number,string      │\n│ csv-simple-parser      │ 697K   │ ░░░░░░░░░░░░░░░░░░░░░░░░░ 115          │ date,number,string │\n│ csv-rex                │ 629K   │ ░░░░░░░░░░░░░░░░░░░░░░░ 104            │ number,string      │\n│ achilles-csv-parser    │ 560K   │ ░░░░░░░░░░░░░░░░░░░░ 92.6              │ number,string      │\n│ comma-separated-values │ 471K   │ ░░░░░░░░░░░░░░░░░ 77.7                 │ number,string      │\n│ arquero                │ 459K   │ ░░░░░░░░░░░░░░░░░ 75.9                 │ date,number,string │\n│ PapaParse              │ 454K   │ ░░░░░░░░░░░░░░░░ 75                    │ number,string      │\n│ CSVtoJSON              │ 425K   │ ░░░░░░░░░░░░░░░ 70.1                   │ number,string      │\n│ d3-dsv                 │ 380K   │ ░░░░░░░░░░░░░░ 62.8                    │ date,number,string │\n│ @vanillaes/csv         │ 302K   │ ░░░░░░░░░░░ 49.9                       │ NaN,number,string  │\n│ csv-parser (neat-csv)  │ 260K   │ ░░░░░░░░░░ 43                          │ number,string      │\n│ csv-js                 │ 229K   │ ░░░░░░░░░ 37.9                         │ number,string      │\n│ dekkai                 │ 213K   │ ░░░░░░░░ 35.1                          │ number,string      │\n│ csv-parse/sync         │ 101K   │ ░░░░ 16.7                              │ date,number,string │\n│ SheetJS                │ 70.8K  │ ░░░ 11.7                               │ number,string      │\n└────────────────────────┴────────┴────────────────────────────────────────┴────────────────────┘\n</pre>\n\n**Parsing quote-heavy CSV to arrays with types**\n\nNote: `object` in the Types column means the lib called `JSON.parse()` 34,000 times; not all libs do.\n\n<pre>\n┌───────────────────────────────────────────────────────────────────────────────────────────────┐\n│ uszips.csv (6 MB, 18 cols x 34K rows)                                    (parsing with types) │\n├────────────────────────┬────────┬─────────────────────────┬───────────────────────────────────┤\n│ Name                   │ Rows/s │ Throughput (MiB/s)      │ Types                             │\n├────────────────────────┼────────┼─────────────────────────┼───────────────────────────────────┤\n│ uDSV                   │ 537K   │ ░░░░░░░░░░░░░░░░░░░░ 96 │ boolean,null,number,object,string │\n│ csv-simple-parser      │ 445K   │ ░░░░░░░░░░░░░░░░░ 79.6  │ boolean,null,number,object,string │\n│ achilles-csv-parser    │ 420K   │ ░░░░░░░░░░░░░░░░ 75.1   │ boolean,null,number,object,string │\n│ CSVtoJSON              │ 270K   │ ░░░░░░░░░░░ 48.2        │ number,string                     │\n│ d3-dsv                 │ 266K   │ ░░░░░░░░░░ 47.6         │ null,number,string                │\n│ comma-separated-values │ 261K   │ ░░░░░░░░░░ 46.6         │ number,string                     │\n│ csv-rex                │ 255K   │ ░░░░░░░░░░ 45.6         │ boolean,null,number,object,string │\n│ dekkai                 │ 248K   │ ░░░░░░░░░░ 44.3         │ NaN,number,string                 │\n│ arquero                │ 245K   │ ░░░░░░░░░░ 43.8         │ null,number,string                │\n│ csv42                  │ 235K   │ ░░░░░░░░░ 42            │ number,object,string              │\n│ csv-js                 │ 232K   │ ░░░░░░░░░ 41.4          │ boolean,number,string             │\n│ csv-parser (neat-csv)  │ 191K   │ ░░░░░░░░ 34.2           │ boolean,null,number,object,string │\n│ PapaParse              │ 176K   │ ░░░░░░░ 31.4            │ boolean,null,number,string        │\n│ @vanillaes/csv         │ 170K   │ ░░░░░░░ 30.4            │ NaN,number,string                 │\n│ SheetJS                │ 102K   │ ░░░░ 18.3               │ boolean,number,string             │\n│ csv-parse/sync         │ 92.2K  │ ░░░░ 16.5               │ number,string                     │\n└────────────────────────┴────────┴─────────────────────────┴───────────────────────────────────┘\n</pre>\n\nFor _way too many_ synthetic and real-world benchmarks, head over to [/bench](/bench)...and don't forget your coffee!\n\n---\n### Installation\n\n```\nnpm i udsv\n```\n\nor\n\n```html\n<script src=\"./dist/uDSV.iife.min.js\"></script>\n```\n\n---\n### API\n\nA 150 LoC [uDSV.d.ts](https://github.com/leeoniya/uDSV/blob/main/dist/uDSV.d.ts) TypeScript def.\n\n---\n### Basic Usage\n\n```js\nimport { inferSchema, initParser } from 'udsv';\n\nlet csvStr = 'a,b,c\\n1,2,3\\n4,5,6';\n\nlet schema = inferSchema(csvStr);\nlet parser = initParser(schema);\n\n// native format (fastest)\nlet stringArrs = parser.stringArrs(csvStr); // [ ['1','2','3'], ['4','5','6'] ]\n\n// typed formats (internally converted from native)\nlet typedArrs  = parser.typedArrs(csvStr);  // [ [1, 2, 3], [4, 5, 6] ]\nlet typedObjs  = parser.typedObjs(csvStr);  // [ {a: 1, b: 2, c: 3}, {a: 4, b: 5, c: 6} ]\nlet typedCols  = parser.typedCols(csvStr);  // [ [1, 4], [2, 5], [3, 6] ]\n\nlet stringObjs = parser.stringObjs(csvStr); // [ {a: '1', b: '2', c: '3'}, {a: '4', b: '5', c: '6'} ]\nlet stringCols = parser.stringCols(csvStr); // [ ['1', '4'], ['2', '5'], ['3', '6'] ]\n```\n\nSometimes you may need to render the unmodified string values (like in an editable grid), but want to sort/filter using the typed values (e.g. number or date columns).\nuDSV's `.typed*()` methods additionally accept the untyped string-tuples array returned by `parser.stringArrs(csvStr)`:\n\n```js\nlet schema = inferSchema(csvStr);\nlet parser = initParser(schema);\n\n// raw parsed strings for rendering\nlet stringArrs = parser.stringArrs(csvStr);\n// typed values for sorting/filtering\nlet typedObjs = parser.typedObjs(stringArrs);\n```\n\nNeed a custom or user-defined parser for a specific column?\nNo problem!\n\n```js\nconst csvStr = `a,b,c\\n1,2,a-b-c\\n4,5,d-e`;\n\nlet schema = inferSchema(csvStr);\nschema.cols[2].parse = str => str.split('-');\n\nlet parser = initParser(schema);\n\nlet rows = parser.typedObjs(csvStr);\n\n/*\n[\n  {a: 1, b: 2, c: ['a', 'b', 'c']},\n  {a: 4, b: 5, c: ['d', 'e',    ]},\n]\n*/\n```\n\nNested/deep objects can be re-constructed from column naming via `.typedDeep()`:\n\n```js\n// deep/nested objects (from column naming)\nlet csvStr2 = `\n_type,name,description,location.city,location.street,location.geo[0],location.geo[1],speed,heading,size[0],size[1],size[2]\nitem,Item 0,Item 0 description in text,Rotterdam,Main street,51.9280712,4.4207888,5.4,128.3,3.4,5.1,0.9\n`.trim();\n\nlet schema2 = inferSchema(csvStr2);\nlet parser2 = initParser(schema2);\n\nlet typedDeep = parser2.typedDeep(csvStr2);\n\n/*\n[\n  {\n    _type: 'item',\n    name: 'Item 0',\n    description: 'Item 0 description in text',\n    location: {\n      city: 'Rotterdam',\n      street: 'Main street',\n      geo: [ 51.9280712, 4.4207888 ]\n    },\n    speed: 5.4,\n    heading: 128.3,\n    size: [ 3.4, 5.1, 0.9 ],\n  }\n]\n*/\n```\n\n**CSP Note:**\n\nuDSV uses dynamically-generated functions (via `new Function()`) for its `.typed*()` methods.\nThese functions are lazy-generated and use `JSON.stringify()` [code-injection guards](https://github.com/leeoniya/uDSV/commit/4e7472a7015c0a7ae5ae76e41f282bd4bdcf0c67), so the risk should be minimal.\nNevertheless, if you have strict [CSP headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) without `unsafe-eval`, you won't be able to take advantage of the typed methods and will have to do the type conversion from the string tuples yourself.\n\n---\n### Incremental / Streaming\n\nuDSV has no inherent knowledge of streams.\nInstead, it exposes a generic incremental parsing API to which you can pass sequential chunks.\nThese chunks can come from various sources, such as a [Web Stream](https://css-tricks.com/web-streams-everywhere-and-fetch-for-node-js/) or [Node stream](https://nodejs.org/api/stream.html) via `fetch()` or `fs`, a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API), etc.\n\nHere's what it looks like with Node's [fs.createReadStream()](https://nodejs.org/api/fs.html#fscreatereadstreampath-options):\n\n```js\nlet stream = fs.createReadStream(filePath);\n\nlet parser = null;\nlet result = null;\n\nstream.on('data', (chunk) => {\n  // convert from Buffer\n  let strChunk = chunk.toString();\n  // on first chunk, infer schema and init parser\n  parser ??= initParser(inferSchema(strChunk));\n  // incremental parse to string arrays\n  parser.chunk(strChunk, parser.stringArrs);\n});\n\nstream.on('end', () => {\n  result = parser.end();\n});\n```\n\n...and Web streams [in Node](https://nodejs.org/api/webstreams.html), or [Fetch's Response.body](https://developer.mozilla.org/en-US/docs/Web/API/Response/body):\n\n```js\nlet stream = fs.createReadStream(filePath);\n\nlet webStream = Stream.Readable.toWeb(stream);\nlet textStream = webStream.pipeThrough(new TextDecoderStream());\n\nlet parser = null;\n\nfor await (const strChunk of textStream) {\n  parser ??= initParser(inferSchema(strChunk));\n  parser.chunk(strChunk, parser.stringArrs);\n}\n\nlet result = parser.end();\n```\n\nThe above examples show accumulating parsers -- they will buffer the full `result` into memory.\nThis may not be something you need (or want), for example with huge datasets where you're looking to get the sum of a single column, or want to filter only a small subset of rows.\nTo bypass this auto-accumulation behavior, simply pass your own handler as the third argument to `parser.chunk()`:\n\n```js\n// ...same as above\n\nlet sum = 0;\n\n// sums fourth column\nlet reducer = (row) => {\n  sum += row[3];\n};\n\nfor await (const strChunk of textStream) {\n  parser ??= initParser(inferSchema(strChunk));\n  parser.chunk(strChunk, parser.typedArrs, reducer); // typedArrs + reducer\n}\n\nparser.end();\n```\n\nBuilding on the non-accumulating example, Node's [Transform stream](https://nodejs.org/api/stream.html#implementing-a-transform-stream) will be something like:\n\n```js\nimport { Transform } from \"stream\";\n\nclass ParseCSVTransform extends Transform {\n  #parser = null;\n  #push   = null;\n\n  constructor() {\n    super({ objectMode: true });\n\n    this.#push = parsed => {\n      this.push(parsed);\n    };\n  }\n\n  _transform(chunk, encoding, callback) {\n    let strChunk = chunk.toString();\n    this.#parser ??= initParser(inferSchema(strChunk));\n    this.#parser.chunk(strChunk, this.#parser.typedArrs, this.#push);\n    callback();\n  }\n\n  _flush(callback) {\n    this.#parser.end();\n    callback();\n  }\n}\n```\n\n---\n### TODO?\n\n- handle #comment rows\n- emit empty-row and #comment events?","readmeFilename":"README.md"}