{"_id":"@abfcode/spine","_rev":"16-1e2442b209c3bf70949226ccd898c526","name":"@abfcode/spine","dist-tags":{"latest":"0.15.0"},"versions":{"0.1.0":{"name":"@abfcode/spine","version":"0.1.0","license":"Apache-2.0","_id":"@abfcode/spine@0.1.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"dist":{"shasum":"4d88bb3ce7e8669809620f93430bf563ed0a1d97","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.1.0.tgz","fileCount":4,"integrity":"sha512-y3kDqHC7Jb+PTRH8Vf/FjzqXjZClvzdxhCJdnjU6sY5imj3GZlQO4AD29KpCHkyPuFyQ7tb6MlKZTPvp6rBRaQ==","signatures":[{"sig":"MEYCIQDy1rkr1hFOKGcgA92AoeNaNSqeJcuU5M/wfJQuP5vqNgIhAJpRfd9H3aNQPKqymx3/mpi2FAy2RFZw1LQUsyXOIXYk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50866},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"6331441bd110a852685427a7b6ceb0f7c97f592e","scripts":{"dev":"tsup --watch","test":"vitest --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"_npmVersion":"11.16.0","description":"In-browser EPUB parser — a TypeScript port of Spine.","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.1.0_1783184513659_0.800822071799961","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@abfcode/spine","version":"0.1.1","license":"Apache-2.0","_id":"@abfcode/spine@0.1.1","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"dist":{"shasum":"cc25d48aa30fcfbf80b1edf17060dc2a86f19337","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.1.1.tgz","fileCount":4,"integrity":"sha512-RuMQyYgnxAHJCWSCh++3HmTokNunaf9mPwRDVYkXibTdtr6Ho2JHwPlGdTweE2zFW6SbqbRX3xrIRyIhq7vRcQ==","signatures":[{"sig":"MEUCIQC0F1FYhMBJsiGxSLQF/v8nCbcCEATqq2GVWZdghQWI8wIgfi36EUGCMkpcVx2zTESTnDn1JgSZj5W69be60Xmd75g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":52410},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b8b6df6723f819f396489ace435f94dc330b9a52","scripts":{"dev":"tsup --watch","test":"vitest --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"_npmVersion":"11.18.0","description":"In-browser EPUB parser — a TypeScript port of Spine.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.1.1_1783297804454_0.5594800209773851","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@abfcode/spine","version":"0.2.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.2.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"e1181add2bb82d72c13365e11e0e0930b20054c8","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.2.0.tgz","fileCount":5,"integrity":"sha512-JQqeCqnx6xsuoWDN8Idlh8WfO2ak9trQBQdnxHgYFa1wqsEsGh//eZlfhC2c554Bf8b5OY/iSDfn26qKAlfrHQ==","signatures":[{"sig":"MEYCIQCxgSL6crtHwpZsBophQ+rx6Y/p7pjGadk5r4YUn/sFEwIhAMB9bUQ0WBy8oxN9N8pcdg3TDNLifnEbtipujoujzL8P","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71759},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"2b79b805aaf5f96f3e304174a43b5c7b2e6689de","scripts":{"dev":"tsup --watch","test":"vitest --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.2.0_1783301897357_0.9828510490581688","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@abfcode/spine","version":"0.3.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.3.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"07fe3f48571fa12f650b67431c46b02e2430a959","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.3.0.tgz","fileCount":5,"integrity":"sha512-aeiLHZJ4aql8vNyWx5pS4iPKwOt4CX1OROwwAUJ3azKGRzXtffhTAQrG8BATjvETVh1xsMPw1xkm5I8FAsWqgg==","signatures":[{"sig":"MEUCIFGrHLH4mTYGtqLe3Ayj0089zZaUSkC/7DDQ66GhAI4JAiEAtBzuL0y6KhTaDFWqvhiSVjrn/m4IZeI1WQPtX0YRaxU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83558},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"a13baf670976d1c38558862cf04329a70955740c","scripts":{"dev":"tsup --watch","test":"vitest --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.3.0_1783303444551_0.03704746337389708","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@abfcode/spine","version":"0.4.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.4.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"1777c26886ad9856ce1cec5ecfac8526a1820306","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.4.0.tgz","fileCount":5,"integrity":"sha512-h3iw45eeN0LMcB+Zq0LfAT2SVAFIl8HqZclK6KSTXYhc0+k4oZNDCFS7wj8Eg+OFbY5cCTmNiVLoY3fziudQEg==","signatures":[{"sig":"MEUCIBFeZGSqtL9wQ5FUA5VK18IX7exZguzg37IvHNJ7jc0fAiEAok6A18pPMJSEjMSnYBxUp8MpeaN1PVwo9TTF2uh6AdA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":108122},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"b82697f06dcbb47cdf6769cebba27e9e38411e45","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.4.0_1783347878332_0.014927776452668962","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@abfcode/spine","version":"0.5.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.5.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"bb7a49a3dff06509884b28d115aa5876ddbe1654","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.5.0.tgz","fileCount":5,"integrity":"sha512-wo6Ib7vRBapctrjwtSesDdJjiWDYREw29YIcgYefm0RsKSa4FtPuXFGJwUFnQ5cXCqaJSc/Fqv+urBGgeeN2Tw==","signatures":[{"sig":"MEUCIQDPIuzFQ4woFvYih1kqGH/686SsS+ft5CIO/zVWOeS1CgIgK45+O5jBYQzeOTL1zcQ4E1qDMqyAGNjaY9Onxjwo5jw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113331},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"9588ab0512271acb86d8858fc2fbded4b3582d34","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.5.0_1783350167326_0.7761296182758686","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@abfcode/spine","version":"0.6.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.6.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"47a9e798f638073b17099e76fabd7f3f26bef6d1","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.6.0.tgz","fileCount":5,"integrity":"sha512-HwIDR+txJ7tPa4OOwpT13gV48SjE2EFl1Ui7i2lsdQavq8vXgJGR4cmtrPq+i+MxrNFOw5GJGBHDqFuVcPDaPA==","signatures":[{"sig":"MEUCIQDzlKzZyf9bIovB8T2gg3g8cpClyZrAqJMUy1E3bNLvuQIgcS6wqpgsCYEEX642vWSZJwLaA7PpEXIY+lOhT0k5RV4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115565},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"0b7d2f6b5bdb34e80034a5a8ec5fe45e93cd89d6","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.6.0_1783353000876_0.17254603243781075","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@abfcode/spine","version":"0.7.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.7.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"95db0b004e8f29816a5a0582ca3053c4e548924c","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.7.0.tgz","fileCount":5,"integrity":"sha512-qpdNlAIY5ph//XSEvGOhiE3pmp0iG8lFJjA9NPZ/ocb7iH85ihBrt3K7/11hzE+TLJZTwhW/Xxq/ZjVl1tleGQ==","signatures":[{"sig":"MEUCIQCgeiV382QQ7Va84Bj2D68mlhnBFZ6eyE6mcO1p6GpIVwIgB2J9YqXCpjclGr1B8OYCCOVtMkjqgoBdLMIxLXAxtTc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115583},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"236263bbbbc07f1c9d7e012054d312883024db1a","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB parser for browsers and beyond: structured blocks, normalized TOC, metadata, chunking, anchors.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.7.0_1783354500321_0.22434177140878786","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@abfcode/spine","version":"0.8.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.8.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"ca20aa29b31de550a905615e6c40018550ba235c","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.8.0.tgz","fileCount":9,"integrity":"sha512-nDikpLmdGnVqzutPKHW0miy1ANWhm4tEn/8Stohcr1z1yv/mMizH11A5QkcoatpsLTg/Xkg8AWQnGfMKMwJF4g==","signatures":[{"sig":"MEYCIQDzdXPf4l5gA1RHrNq5XFiVPelVJtIEfzBoGDyGJ4rhWgIhAKzJNozGiA0ly2IT5kG77DgkAJXdtVzpQqHJuH1eTkqV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":159468},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"}},"gitHead":"6e34c2a77f21f1e2449b8fc73256fb3738fa0cf7","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","conformance":"pnpm build && bash scripts/conformance.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.8.0_1783363850253_0.5136527904752881","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@abfcode/spine","version":"0.9.0","keywords":["epub","epub2","epub3","ebook","parser","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.9.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"31393f790fbc19b9dcc697d37f2388dfcaf1ed33","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.9.0.tgz","fileCount":14,"integrity":"sha512-6KuMfRmWLev1gsL4pbutKi8EcaomAZ9voko0Y1shcM1wZiYqMVTxFq1QSXY+Re7czAUo28Q8l3d4V33N4Y19eA==","signatures":[{"sig":"MEYCIQD4eKhQwI5OrTTlPd1shb7Y1glWD3Nr5HzCUs1kujFwUwIhAKrs/YRepIoY1Zc3eHJ6fSZgPzSxhwafU6q2QXgkC4QL","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":182157},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"d83ad4f32a1655763d81a266823471b6b10c578a","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","conformance":"pnpm build && bash scripts/conformance.sh","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.9.0_1783515274236_0.19148158058210285","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@abfcode/spine","version":"0.9.1","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.9.1","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"175adfa217090641f6c0ec6d555a19b311caf2b8","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.9.1.tgz","fileCount":14,"integrity":"sha512-vUuKehAv9pUs9d+Q3/yvW2Lgd7r8MBQqLfYiylO2jVYPk48wGsD3hNJ403Dh35oL1vVy/a77SmnFgT4LtOP/1w==","signatures":[{"sig":"MEUCIDXD4PQIb6sWYZTrGrAop7JY/hQHmtIn9yACdStxTuHmAiEAlE+QkvYR9Dw7VytlzLAtuJ7NmjXQME0DUVyOk6A4kDo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":182417},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"3ee7227f1a1d65dbf77b85d6f573add38ff73798","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","conformance":"pnpm build && bash scripts/conformance.sh","bench:browser":"pnpm build && node scripts/bench-browser.mjs","prepublishOnly":"npm run build"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.10.0","playwright-core":"^1.61.1"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.9.1_1783630505149_0.5097112454237915","host":"s3://npm-registry-packages-npm-production"}},"0.11.0":{"name":"@abfcode/spine","version":"0.11.0","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.11.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"54ed6b25cbb9954f0a348ac57ec89a6699128cbf","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.11.0.tgz","fileCount":14,"integrity":"sha512-zF86Qe4MCB3u0lKLGQV7kfHN/X0lNAxpt1rTJbgGHPJO29uSbM5HTSCiySUv2rjHQ0hj5jCyKy/BTsxvLV70Ig==","signatures":[{"sig":"MEUCIAMsBF2rNmDgwbi4RVyLel6X5Yk/y95p5ZUQOWDUtE5/AiEAz9C2wxcI6yKBYW9DVgg4P8GHEWJR7yt3rgI4/fJP0dI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":198883},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"1a224ad48ab5f9d222b80190fb8225ef71faa6c1","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"vitest bench --run","build":"tsup","conformance":"pnpm build && bash scripts/conformance.sh","verify:fuzz":"tsx scripts/fuzz-mutate.ts","verify:perf":"tsx scripts/perf-baseline.ts","corpus:fetch":"node scripts/corpus-fetch.mjs","verify:redos":"node scripts/redos-audit.mjs","bench:browser":"pnpm build && node scripts/bench-browser.mjs","verify:corpus":"tsx scripts/corpus-run.ts","verify:memory":"pnpm build >/dev/null && node --expose-gc scripts/memory-harness.mjs","prepublishOnly":"npm run build","verify:mutation":"stryker run","verify:splitter":"tsx scripts/splitter-oracle.ts"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","recheck":"^4.5.0","fast-check":"^4.9.0","typescript":"^5.9.3","@types/node":"^22.10.0","playwright-core":"^1.61.1","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.11.0_1783714211466_0.8967973474551632","host":"s3://npm-registry-packages-npm-production"}},"0.12.0":{"name":"@abfcode/spine","version":"0.12.0","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.12.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"9ac5fc631c1a35e60b04d66151c893a9dfb1eb01","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.12.0.tgz","fileCount":14,"integrity":"sha512-qjVg5NQkzECE2lLfveivhvavTvsgZ25PaHeFhIw5E/7MoKg70WxbFzdHlfRNdXa/RbY+qrA6vRFBljbAplMuIw==","signatures":[{"sig":"MEYCIQDySKgtPB4aZsMFP52G883sSubdTqZM/IzHE/6AlV2L2gIhALgmfqomgcNxSbSv/nPSyRJU7VBjTEnKdUOPPbdUpM6w","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200548},"main":"./dist/index.js","pnpm":{"onlyBuiltDependencies":["esbuild"]},"type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"7adb171b65f9a35e1fd1ed8f4411f73a8ed0aacf","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"pnpm build && node scripts/gen-scale-epub.mjs && vitest bench --run --outputJson .bench-fixtures/node-bench.json && node scripts/annotate-node-benchmark.mjs","build":"tsup","doctor":"node scripts/doctor.mjs","typecheck":"tsc --noEmit","conformance":"pnpm build && bash scripts/conformance.sh","verify:fuzz":"tsx scripts/fuzz-mutate.ts","verify:perf":"tsx scripts/perf-baseline.ts","corpus:fetch":"node scripts/corpus-fetch.mjs","verify:redos":"node scripts/redos-audit.mjs","verify:scale":"pnpm build >/dev/null && node scripts/scale-check.mjs","bench:browser":"pnpm build && node scripts/bench-browser.mjs","verify:corpus":"tsx scripts/corpus-run.ts","verify:memory":"pnpm build >/dev/null && node --expose-gc scripts/memory-harness.mjs","prepublishOnly":"npm run build","verify:mutation":"stryker run","verify:splitter":"tsx scripts/splitter-oracle.ts"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.28.2","devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^25.0.1","vitest":"^3.2.4","recheck":"^4.5.0","fast-check":"^4.9.0","typescript":"^5.9.3","@types/node":"^22.10.0","playwright-core":"^1.61.1","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.12.0_1783813984573_0.2425258405564441","host":"s3://npm-registry-packages-npm-production"}},"0.13.0":{"name":"@abfcode/spine","version":"0.13.0","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.13.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"919c05ee63cbe56be6a3c0fb28913bac2cce8ec7","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.13.0.tgz","fileCount":14,"integrity":"sha512-MxfSM+hL37NswBEjYu45vfWIBo6OI9Dp7MTYFIKK8DCe7GjVpf6/7OoQNXh/D5ijadJACeMHExDY4J44UjkDoA==","signatures":[{"sig":"MEQCICuv2D4eYc/pZw2SfKNs8J8AtWqn6fg1SfBb/mEL4+9YAiBMV3za+6ojuyM66pBXWJUNoJ16/QlO2WuPsdoBhgD+tw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":200756},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"cb0549bb24803c9c5150c4b78653526439f972df","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"pnpm build && node scripts/gen-scale-epub.mjs && vitest bench --run --outputJson .bench-fixtures/node-bench.json && node scripts/annotate-node-benchmark.mjs","build":"tsup && tsdown && node scripts/copy-dts.mjs","doctor":"node scripts/doctor.mjs","typecheck":"tsc --noEmit","conformance":"pnpm build && bash scripts/conformance.sh","verify:fuzz":"tsx scripts/fuzz-mutate.ts","verify:perf":"tsx scripts/perf-baseline.ts","corpus:fetch":"node scripts/corpus-fetch.mjs","verify:redos":"node scripts/redos-audit.mjs","verify:scale":"pnpm build >/dev/null && node scripts/scale-check.mjs","bench:browser":"pnpm build && node scripts/bench-browser.mjs","verify:corpus":"tsx scripts/corpus-run.ts","verify:memory":"pnpm build >/dev/null && node --expose-gc scripts/memory-harness.mjs","prepublishOnly":"npm run build","verify:package":"pnpm build && node scripts/check-packed-package.mjs","verify:mutation":"stryker run","verify:splitter":"tsx scripts/splitter-oracle.ts"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.18.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.12.0","devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^29.1.1","tsdown":"^0.22.5","vitest":"^4.1.10","recheck":"^4.5.0","fast-check":"^4.9.0","typescript":"^7.0.2","@types/node":"^24.13.3","playwright-core":"^1.61.1","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.13.0_1783826362047_0.2494062885524344","host":"s3://npm-registry-packages-npm-production"}},"0.14.0":{"name":"@abfcode/spine","version":"0.14.0","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"license":"Apache-2.0","_id":"@abfcode/spine@0.14.0","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"dist":{"shasum":"7833939fffcd68372f273d16c5381b065117bcd7","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.14.0.tgz","fileCount":14,"integrity":"sha512-VvDyKdnN64wTeCDeIOOClSlaDDu4endxmqcAxAfoNXrGNHNRQEkULSmJTbmDlzMuWYI2D6yP54pnZkju0LHTkA==","signatures":[{"sig":"MEUCIDAKzhdor9emqu/3t1pNuj4Juo1kX4hBCmFFbVBWMKwrAiEA7i2pcLYeYoVrNWIxr9f8vOJz1FmMJFesMntBztwFBDQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":220127},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./package.json":"./package.json"},"gitHead":"f0da2395e70a7ac92871a1f957ae9da0d15caede","scripts":{"dev":"tsup --watch","test":"vitest --run","bench":"pnpm build && node scripts/gen-scale-epub.mjs && vitest bench --run --outputJson .bench-fixtures/node-bench.json && node scripts/annotate-node-benchmark.mjs","build":"tsup && tsdown && node scripts/copy-dts.mjs","doctor":"node scripts/doctor.mjs","typecheck":"tsc --noEmit","conformance":"pnpm build && bash scripts/conformance.sh","verify:fuzz":"tsx scripts/fuzz-mutate.ts","verify:perf":"tsx scripts/perf-baseline.ts","corpus:fetch":"node scripts/corpus-fetch.mjs","verify:redos":"node scripts/redos-audit.mjs","verify:scale":"pnpm build >/dev/null && node scripts/scale-check.mjs","bench:browser":"pnpm build && node scripts/bench-browser.mjs","verify:corpus":"tsx scripts/corpus-run.ts","verify:memory":"pnpm build >/dev/null && node --expose-gc scripts/memory-harness.mjs","prepublishOnly":"npm run build","verify:package":"pnpm build && node scripts/check-packed-package.mjs","verify:mutation":"stryker run","verify:splitter":"tsx scripts/splitter-oracle.ts"},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"repository":{"url":"git+https://github.com/ABFCode/spine-ts.git","type":"git"},"_npmVersion":"11.16.0","description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"fflate":"^0.8.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.12.0","devDependencies":{"tsx":"^4.23.0","tsup":"^8.5.1","jsdom":"^29.1.1","tsdown":"^0.22.5","vitest":"^4.1.10","recheck":"^4.5.0","fast-check":"^4.9.0","typescript":"^7.0.2","@types/node":"^24.13.3","playwright-core":"^1.61.1","@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1"},"_npmOperationalInternal":{"tmp":"tmp/spine_0.14.0_1784245787226_0.002734915208542965","host":"s3://npm-registry-packages-npm-production"}},"0.15.0":{"name":"@abfcode/spine","version":"0.15.0","packageManager":"pnpm@11.12.0","engines":{"node":">=24"},"description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/ABFCode/spine-ts.git"},"homepage":"https://github.com/ABFCode/spine-ts#readme","bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./write":{"types":"./dist/write.d.ts","import":"./dist/write.js"},"./text":{"types":"./dist/text.d.ts","import":"./dist/text.js"},"./package.json":"./package.json"},"sideEffects":false,"scripts":{"build":"tsup && tsdown && node scripts/copy-dts.mjs","dev":"tsup --watch","doctor":"node scripts/doctor.mjs","typecheck":"tsc --noEmit","test":"vitest --run","conformance":"pnpm build && bash scripts/conformance.sh","bench":"pnpm build && node scripts/gen-scale-epub.mjs && vitest bench --run --outputJson .bench-fixtures/node-bench.json && node scripts/annotate-node-benchmark.mjs","prepublishOnly":"npm run build","bench:browser":"pnpm build && node scripts/bench-browser.mjs","verify:redos":"node scripts/redos-audit.mjs","corpus:fetch":"node scripts/corpus-fetch.mjs","verify:corpus":"tsx scripts/corpus-run.ts","verify:fidelity":"tsx scripts/fidelity-audit.ts --fixtures","verify:fidelity:corpus":"tsx scripts/fidelity-audit.ts --corpus","verify:fidelity:render":"pnpm build >/dev/null && node scripts/fidelity-render.mjs","verify:splitter":"tsx scripts/splitter-oracle.ts","verify:fuzz":"tsx scripts/fuzz-mutate.ts","verify:mutation":"stryker run","verify:perf":"tsx scripts/perf-baseline.ts","verify:memory":"pnpm build >/dev/null && node --expose-gc scripts/memory-harness.mjs","verify:scale":"pnpm build >/dev/null && node scripts/scale-check.mjs","verify:package":"pnpm build && node scripts/check-packed-package.mjs","verify:release":"node scripts/release-verify.mjs"},"dependencies":{"fflate":"^0.8.3"},"devDependencies":{"@stryker-mutator/core":"^9.6.1","@stryker-mutator/vitest-runner":"^9.6.1","@types/node":"^24.13.3","fast-check":"^4.9.0","jsdom":"^29.1.1","playwright-core":"^1.61.1","recheck":"^4.5.0","saxes":"^6.0.0","tsdown":"^0.22.5","tsup":"^8.5.1","tsx":"^4.23.0","typescript":"^7.0.2","vitest":"^4.1.10"},"gitHead":"a6d560abbbcb25edd9716a06de740f05cfe1ea26","_id":"@abfcode/spine@0.15.0","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-OkMR23hFUdWhiBtXFJezAcro2hTKmXIBmvZ0Uf5Ri86F6+T4TRKHS+Dsxlfa1n+5eG6B8sXa97ybiLmbyffJvw==","shasum":"ac4d80c1dfe860c515778e1d95c2602f60365b3c","tarball":"https://registry.npmjs.org/@abfcode/spine/-/spine-0.15.0.tgz","fileCount":14,"unpackedSize":233074,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD9sC1uvXSqKLMLqwqQmPFSuD73UCI0NZ90rjA1Wk3ruAIhAJWVl12LAejlAy5kf1h3v/jaC7MbwWBow2Lmycyh8ttQ"}]},"_npmUser":{"name":"ratticus","email":"abfinnegan+npm@gmail.com"},"directories":{},"maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/spine_0.15.0_1784259154207_0.985728368429795"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-04T17:01:53.445Z","modified":"2026-07-17T03:32:34.478Z","0.1.0":"2026-07-04T17:01:53.829Z","0.1.1":"2026-07-06T00:30:04.643Z","0.2.0":"2026-07-06T01:38:17.492Z","0.3.0":"2026-07-06T02:04:04.700Z","0.4.0":"2026-07-06T14:24:38.477Z","0.5.0":"2026-07-06T15:02:47.468Z","0.6.0":"2026-07-06T15:50:01.002Z","0.7.0":"2026-07-06T16:15:00.480Z","0.8.0":"2026-07-06T18:50:50.381Z","0.9.0":"2026-07-08T12:54:34.451Z","0.9.1":"2026-07-09T20:55:05.285Z","0.11.0":"2026-07-10T20:10:11.658Z","0.12.0":"2026-07-11T23:53:04.711Z","0.13.0":"2026-07-12T03:19:22.215Z","0.14.0":"2026-07-16T23:49:47.374Z","0.15.0":"2026-07-17T03:32:34.330Z"},"bugs":{"url":"https://github.com/ABFCode/spine-ts/issues"},"license":"Apache-2.0","homepage":"https://github.com/ABFCode/spine-ts#readme","keywords":["epub","epub2","epub3","ebook","parser","writer","converter","txt","markdown","webnovel","toc","ncx","chunking","rag","browser"],"repository":{"type":"git","url":"git+https://github.com/ABFCode/spine-ts.git"},"description":"Fast, dependency-light EPUB toolkit for parsing, transforming, normalizing, and writing ebooks anywhere.","maintainers":[{"name":"ratticus","email":"abfinnegan+npm@gmail.com"}],"readme":"# @abfcode/spine\n\n[![npm](https://img.shields.io/npm/v/%40abfcode%2Fspine)](https://www.npmjs.com/package/@abfcode/spine)\n[![CI](https://github.com/ABFCode/spine-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/ABFCode/spine-ts/actions/workflows/ci.yml)\n[![license](https://img.shields.io/npm/l/%40abfcode%2Fspine)](LICENSE)\n\nA fast EPUB toolkit: parse, write, normalize, and ingest ebooks anywhere.\nOne `parse()` call turns EPUB bytes into structured content blocks, real\nchapters, a normalized TOC, metadata, text chunks, and resolved anchors —\nbuilt for readers, RAG pipelines, TTS, and search indexing, and built to\nsurvive everything from pristine EPUB3 to broken OPF soup.\n\n```sh\nnpm install @abfcode/spine\n```\n\n## Why this one\n\n- **Runs anywhere — including where DOM parsers can't.** Node, browsers,\n  Web Workers, Electron (renderer *and* main), Bun, Deno, edge runtimes. Parsing\n  runs on an in-tree streaming tokenizer (2460/2460 html5lib conformance),\n  so there's no DOM anywhere. That's not a portability nicety: DOM-backed\n  parsing needs jsdom in Node (**5–7× slower** — measured against spine's\n  own earlier jsdom pipeline) and can't run in a Web Worker at all, because\n  `DOMParser` doesn't exist there.\n- **Fast at every scale.** Metadata remains millisecond-scale (lazy zip —\n  images you don't ask for are never inflated); Moby-Dick fully extracts in\n  about 40ms on the current reference run; a 3,000-chapter / ~14MB-text web\n  novel in about 480ms, scaling approximately linearly. Verified in-browser,\n  not just in Node — see [Performance](#performance).\n- **One runtime dependency** (`fflate`). Tokenizer, entities, zip directory,\n  XML handling: all in-tree, purpose-built for ebooks.\n- **Hard to break.** Malformed XML recovers with warnings, missing\n  containers/spines/TOCs fall back to archive scanning, DRM surfaces as a\n  typed error instead of garbage, and a fuzz suite guarantees termination.\n- **Built for real readers.** Chapters cut at TOC targets (multi-chapter\n  files and file-spanning chapters both come out right), footnote/`epub:type`\n  semantics, RTL direction, pre-resolved links and image paths — and the\n  block model is safe to render by construction: no innerHTML anywhere, so\n  a hostile EPUB can't smuggle `<script>` into your UI.\n- **Typed and verified, deeply.** TypeScript-first, stable error `code`s,\n  structured warnings, and 2,800+ tests across a dozen harnesses — unit,\n  html5lib conformance, property-based laws, generative + mutational fuzzing,\n  a hostile-input suite (zip bombs, ReDoS, entity expansion), golden corpora,\n  differential-vs-jsdom, generated round-trips, warning-free epubcheck, a\n  3,000-chapter scale harness, and a **wild corpus of 65 real books** parsed\n  end-to-end with committed diffable results. Mutation-tested (StrykerJS) and\n  perf/memory-regression-tracked. See [Verification](#verification).\n\n## Usage\n\n```ts\nimport { parse } from '@abfcode/spine'\n\nconst book = parse(epubBytes) // Uint8Array\n\nbook.metadata.title           // 'Moby Dick; Or, The Whale'\nbook.toc                      // normalized table of contents\nbook.blocks(0)                // structured blocks for spine item 0\n```\n\n### Writing and normalizing EPUBs\n\nThe experimental writer lives at a separate subpath, keeping parser-only\nbundles unchanged:\n\n```ts\nimport { parse } from '@abfcode/spine'\nimport { writeEpub, bookToSpec } from '@abfcode/spine/write'\n\nconst bytes = writeEpub({\n  metadata: { title: 'My Book', authors: ['A. Writer'] },\n  chapters: [\n    { title: 'One', content: { text: 'First paragraph.\\n\\nSecond paragraph.' } },\n  ],\n})\n\n// Clean and normalize an existing book:\nconst normalized = writeEpub(bookToSpec(parse(existingBytes)))\n\n// Or retain complete source XHTML for a surgical package/resource edit:\nconst faithful = writeEpub(bookToSpec(parse(existingBytes), {\n  preserveDocumentXhtml: true,\n}))\n```\n\nOutput is deterministic by default. EPUB3+NCX, nav-only EPUB3, and EPUB2 are\nsupported; the generated conformance matrix passes epubcheck with warnings\ntreated as failures. The writer API remains experimental until 1.0. See\n[the API reference](docs/API.md#writing-epubs-experimental-until-10).\n\n### Text ingestion (.txt / .md → EPUB)\n\nHuge amounts of webnovel content circulate as giant `.txt` rips. The `/text`\nsubpath turns them into shelf-ready books — for a library app's import flow,\nthat means raw rips go straight onto the shelf:\n\n```ts\nimport { textToEpub, textToBook } from '@abfcode/spine/text'\n\nconst epub = textToEpub(txtBytes, { metadata: { title: 'My Rip' } })\nconst book = textToBook(txtBytes) // or parse it in one step\n```\n\nChapters come from an ordered heuristic ruleset (`Chapter 1` / `CHAPTER IV` /\n`Ch. 3` / markdown headings / CJK `第一章` / ALL-CAPS conventions...) with\nguards biased toward under-splitting — a marker-less wall stays one chapter,\nand every cut is observable through `onWarning`. Handles legacy encodings\n(`gb18030`, `shift-jis`, ...), multi-file rips, Gutenberg boilerplate, and\npoetry; output passes epubcheck warning-free. Full options in\n[the API reference](docs/API.md#text-ingestion-experimental-until-10).\n\n### Chapters (RAG / TTS / export)\n\n```ts\nfor (const ch of book.iterChapters()) {\n  ch.title // 'CHAPTER 1. Loomings.' — cut at TOC targets, so multi-chapter\n  ch.text  // files and file-spanning chapters both come out right\n  ch.start // { spineIndex, blockIndex } — map text back to structure\n}\n```\n\n### Chunks (fixed-size text windows)\n\n```ts\nconst chunks = book.chunks({ mode: 'size', maxChars: 2000 })\n// each chunk: stable id, text, spineIndex, block range, anchors\n```\n\n### Reader rendering\n\n```ts\nconst blocks = book.blocks(spineIndex)\n// Inline texts carry their own separator spaces: concatenate directly.\n// See docs/API.md for the full Block/Inline model and whitespace contract.\n```\n\n### Off the main thread\n\nBlocks, chunks, and chapters are plain structured-clone-able objects, so\nworker parsing is just:\n\n```ts\n// worker.ts\nimport { parse } from '@abfcode/spine'\nonmessage = (e) => {\n  const book = parse(e.data)\n  postMessage({ toc: book.toc, chapters: book.chapters() })\n}\n```\n\n### Error handling\n\n```ts\nimport { isSpineError } from '@abfcode/spine'\n\ntry {\n  const book = parse(bytes)\n  console.warn(book.warnings) // non-fatal recoveries, if any\n} catch (e) {\n  if (isSpineError(e, 'drm_encrypted')) {\n    // tell the user the book is DRM-protected\n  }\n}\n```\n\n## Performance\n\nFull pipeline (parse + every block + fixed-size chunks), median from a quiet\nWSL2 reference run on this development machine with Node 24.11.1. These are\nmachine measurements, not cross-hardware guarantees:\n\n| book | size | time |\n| --- | --- | --- |\n| Alice in Wonderland | 135 KB | 7.4 ms |\n| Frankenstein | 349 KB | 13.6 ms |\n| Moby-Dick | 711 KB | 40.1 ms |\n| Leaves of Grass (379 spine files) | 680 KB | 75.3 ms |\n| War and Peace | 1.8 MB | 137.2 ms |\n| Complete Works of Shakespeare | 2.8 MB | 407.2 ms |\n| Synthetic web novel (3,000 chapters, 13,971,369 text chars) | 2.8 MB | 480.5 ms |\n\nMetadata + TOC only: 0.2–9.3 ms in that run. Scaling is approximately linear\nin book size — a 6,000-chapter novel takes ~2× the 3,000-chapter one. Run\n`pnpm bench` to reproduce. It generates the canonical scale EPUB plus a\nmanifest containing its size and SHA-256, then records full sample statistics\nunder the gitignored `.bench-fixtures/` directory. `pnpm verify:scale` is the\nregression gate: it fails if doubling chapter count approaches quadratic\ngrowth.\n\nThe numbers hold in the primary deployment environment, not just Node:\n`pnpm bench:browser` runs the same files in a module Worker inside real\nheadless Chromium and writes its own hash-linked JSON record. Across the\ncurrent Chrome 149 / Node 24 run, Worker heavy-extraction times were\n~1.03–1.57× Node; the canonical scale book was ~1.10× Node.\n\n## Documentation\n\n- [API reference](docs/API.md)\n- [Roadmap](ROADMAP.md)\n- [Changelog](CHANGELOG.md)\n\n## Development\n\n- Prerequisites: Node 24.15 or newer and the exact pnpm version pinned in\n  `package.json`. Corepack and GitHub Actions both read that pin; run\n  `pnpm run doctor` to verify Node, pnpm, the temporary directory, Java,\n  Chromium, Bun, and Deno without installing anything.\n- In WSL, Windows may leak `TEMP`/`TMP` paths into Node subprocesses. If\n  Vitest or tsx cannot create a temporary directory or IPC socket, run with\n  `TMPDIR=/tmp` (for example, `TMPDIR=/tmp pnpm test`).\n- `pnpm test` — the fast suite (PR-blocking, < ~30s): unit, property laws,\n  golden corpora, html5lib conformance, generative fuzz, hostile-input suite,\n  API-surface snapshot, differential-vs-jsdom, i18n\n- `pnpm typecheck` — type-check source, tests, and validation tooling; runs in\n  CI alongside the build and fast suite.\n- `UPDATE_GOLDEN=1 pnpm test` — regenerate golden snapshots after an\n  intentional change (review the diff!)\n- `pnpm bench` / `pnpm bench:browser` — corpus benchmarks (Node / worker)\n- `pnpm build` — emit `dist/` (ESM + `.d.ts`)\n\n## Verification\n\nThe fast suite (`pnpm test`), independent six-book EPUB relationship oracle,\nreal-Chrome rendered-fidelity check, ReDoS audit, package consumer, and\nNode/Bun/Deno smoke run in CI on every change. Heavier lanes have a command and\na committed baseline; the full writer-fidelity corpus also runs weekly:\n\n| lane | command | what it guards |\n| --- | --- | --- |\n| Wild corpus | `pnpm verify:corpus` | 65 real books parsed end-to-end; committed diffable per-book results |\n| Writer fidelity | `pnpm verify:fidelity`, `pnpm verify:fidelity:corpus -- --epubcheck`, `pnpm verify:fidelity:render` | independent raw relationship graph, first- and second-pass preservation, external EPUBCheck, computed-style and pixel parity, and controls that must fail when a stylesheet is detached |\n| Splitter oracle | `pnpm verify:splitter` | text-splitter precision/recall vs the same books' EPUB chapters |\n| Mutational fuzz | `pnpm verify:fuzz` | mutated EPUB bytes (zip surgery) must only ever throw typed errors (also a nightly CI run) |\n| ReDoS audit | `pnpm verify:redos` | every source regex checked for catastrophic backtracking (in CI) |\n| Mutation testing | `pnpm verify:mutation` | StrykerJS grades the tests themselves; a ratcheted baseline |\n| Performance / memory | `pnpm bench`, `pnpm bench:browser`, `pnpm verify:scale`, `pnpm verify:perf`, `pnpm verify:memory` | shipped-dist Node/Worker timings, linear scaling, book-ratio perf, no-leak / lazy-zip / heap envelopes |\n\nBaselines for the corpus, splitter, mutation score, and perf/memory are\ncommitted under `corpus/`, so a regression shows up as a reviewable diff.\n`pnpm verify:release` runs the complete local release matrix; see the\n[writer release checklist](docs/write-release-checklist.md).\n\n## Status & stability\n\n0.x: breaking changes land at minor versions and are called out in the\n[CHANGELOG](CHANGELOG.md). The compatibility promise itself is written down\nin the [stability contract](docs/API.md#stability-contract) — in short:\nerror codes, warning codes, the block model (including its JSON shape,\nwith unknown-kind tolerance for union growth), chapter coordinates, href\ncanonical form, and deterministic output are contract; message text and\ncross-version parse output are not (key persisted parses to the exported\n`VERSION`).\n\nESM-only, by design — every supported runtime speaks ESM natively. Type\ndeclarations ship with the package.\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}