{"_id":"@gmod/range-cache-filehandle","_rev":"7-d7ccea5525b188f22c29b5d5ee3d45dd","name":"@gmod/range-cache-filehandle","dist-tags":{"latest":"1.4.0"},"versions":{"1.0.0":{"name":"@gmod/range-cache-filehandle","version":"1.0.0","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.0.0","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"716c0497ed6eabd6b8c379d276b0a1b21d1e8173","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.0.0.tgz","fileCount":53,"integrity":"sha512-QYSVsYnJ+mqQ0XGcb4BtzgRxMlg9bBssvYJrf2kdgm+GIX4aRWs4JWPXzdvmMO4vo8L29YN56AB6Qjcbuf/E6A==","signatures":[{"sig":"MEUCIQDP2M7btPClJ6+JNvYZTL5DdkGSv4ET2Ysofasr39yaogIgGsfg/Ya0hkLSsLC3X/v1Q/1dHC/7tHz+PrCAhm3THaM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":226607},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"edb29cd5fef0e1cce21832887c10792d66d7c001","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"cmdcolin","email":"colin.diesh@gmail.com"},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.12.1","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"generic-filehandle2":"^2.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.0.0_1786850457345_0.8212607701101995","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@gmod/range-cache-filehandle","version":"1.0.1","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.0.1","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"b4e7338711eeebae2560250303b38dbb28b8f2d5","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.0.1.tgz","fileCount":53,"integrity":"sha512-27ToOTPpFnWZGOGPv98h3AJObauhwqKiAuOHUG7wCV3vf4izdQUqQfxunZl+GMkO+hLIm0m9mAW8L/XTI0FFOA==","signatures":[{"sig":"MEYCIQD0lmzGnTKqZ9K2BnaDKT4hWU/V2/sIGZnf/CbDSOwIxwIhAO5z0vDv3+5hn/rBkY6fpWhpTmWXnIXBH0sQc1+cZ1Pi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":224935},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"9d17425915a34ab0e3159cdf6467b4498cd6fa34","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"cmdcolin","email":"colin.diesh@gmail.com"},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.12.1","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.13.0","dependencies":{"generic-filehandle2":"^2.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.0.1_1786850789056_0.6917841920930579","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@gmod/range-cache-filehandle","version":"1.0.2","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.0.2","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"ff0e08de6564e020fa6e235abb981fb1f1324a43","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.0.2.tgz","fileCount":53,"integrity":"sha512-M1dQYtcPXMqHGBoxAUjX+czeVpWgWGfQWd1uI2k51Z8aYIyoBlHBYysbZX34oDCFKnjQUNO+/jR4wWx1vlDBeA==","signatures":[{"sig":"MEUCID1yx3FqiK01UhHBpAkeT1CDQNzm+Qd5JTkcAd8nDrlLAiEAkfyj4Qt6EcMV2IuB/pUMXyqOlDHToR1OdIJ1aIvWpcI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@gmod%2frange-cache-filehandle@1.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":224935},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"420de6b452c38342ad9ccde09380f1389417f8d3","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:69373189-7a6b-479d-8fa2-49bc6ed1887e"}},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.17.0","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"generic-filehandle2":"^2.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.0.2_1786851194218_0.4540211084715109","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@gmod/range-cache-filehandle","version":"1.1.0","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.1.0","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"bcafb53f413d16f97f1ce1ac8362ef13cb1f4f7b","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.1.0.tgz","fileCount":53,"integrity":"sha512-p0cAUby/mhLSlnqUXWaTcHUWJWywgAqaE3FlcM4tTVJDjNblCOf6Ju3PG9o8btUZI1g9+gBkNGkG2t+2j3TuNw==","signatures":[{"sig":"MEUCIAM/kfF6uoG3jhdsP6BbBHm3oZTFYIVvUbDgB0VeweQVAiEA+9iutLGxgWGzYyY+9XM2DRySZ26H8P7fFArfz7f/gZY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@gmod%2frange-cache-filehandle@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":338437},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"87454a615c5b73f81236c95462d60dd0b374c844","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:69373189-7a6b-479d-8fa2-49bc6ed1887e"}},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.17.0","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"generic-filehandle2":"^2.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.1.0_1786934626189_0.8111486194171325","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@gmod/range-cache-filehandle","version":"1.2.0","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.2.0","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"4f7a5fb7c19ab64f4fb019e7cf45a93b35b3d29d","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.2.0.tgz","fileCount":53,"integrity":"sha512-nDjTrYjhf6pDEafnU37bKv4r0YTX10v1QRpERgcXGE63/N6k83m2Jd57NX4KEEw1FxxGw+mHZQWtyk5WZC8ckA==","signatures":[{"sig":"MEUCIQCO/YixgbAea978PfQnmmzOcholH5nXrzESWgeKFn6zVQIgVoOpu++Uj22s9qUEEWK8kfpLU7V7kCOMhCOK3zvzFRM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@gmod%2frange-cache-filehandle@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":368827},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"cd91c8b7ce4ca4b3d6c09c901e7a1ac1369506b1","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:69373189-7a6b-479d-8fa2-49bc6ed1887e"}},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.17.0","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"generic-filehandle2":"^2.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.2.0_1786981215357_0.7930253955400195","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@gmod/range-cache-filehandle","version":"1.3.0","keywords":["byte-range","cache","filehandle","http","range-request"],"author":{"url":"https://github.com/cmdcolin","name":"Colin Diesh","email":"colin.diesh@gmail.com"},"license":"MIT","_id":"@gmod/range-cache-filehandle@1.3.0","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"dist":{"shasum":"b3a7f951ea3cad4bfbf6911b6c2a5cbccbe1cca8","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.3.0.tgz","fileCount":53,"integrity":"sha512-s7UGdQ7LBQMbVjTfScsA7E/7I/Haik8yB6GYnCS+K3mLuHKRo3gV9r09dBO6VI76drw31N+/opZiYoeNKN8BwA==","signatures":[{"sig":"MEYCIQDfMkJReF7Ijgh1ql4NlYjN6eSqCzsBIIwZS1PWHMcR0AIhAO+Lic+tDwcF2tMYAauW/B6i/Jsh/GVzd+5+Au3xV44p","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@gmod%2frange-cache-filehandle@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":400583},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"gitHead":"06ee4a3740a6445a1355ade62504db3bb5422f23","scripts":{"lint":"eslint --report-unused-disable-directives --max-warnings 0","test":"vitest","build":"pnpm build:esm && pnpm build:es5","clean":"rimraf dist esm","format":"prettier --write .","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","diagrams":"node scripts/generate-diagrams.ts","prebuild":"pnpm clean","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","build:esm":"tsc --outDir esm","typecheck":"tsc --noEmit -p tsconfig.lint.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","postversion":"git push --follow-tags","format:check":"prettier --check .","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:69373189-7a6b-479d-8fa2-49bc6ed1887e"}},"repository":{"url":"git+https://github.com/GMOD/range-cache-filehandle.git","type":"git"},"_npmVersion":"11.17.0","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","directories":{"lib":"dist"},"sideEffects":false,"_nodeVersion":"24.19.0","dependencies":{"generic-filehandle2":"^2.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.15.1","devDependencies":{"eslint":"^10.8.0","rimraf":"^6.1.3","vitest":"^4.1.10","prettier":"^3.9.6","git-cliff":"^2.13.1","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.5","typescript-eslint":"^8.65.0","@vitest/coverage-v8":"^4.1.10","eslint-plugin-import-x":"^4.17.1"},"_npmOperationalInternal":{"tmp":"tmp/range-cache-filehandle_1.3.0_1787500046289_0.7157728434116117","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@gmod/range-cache-filehandle","version":"1.4.0","packageManager":"pnpm@11.15.1","description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","license":"MIT","repository":{"type":"git","url":"git+https://github.com/GMOD/range-cache-filehandle.git"},"type":"module","sideEffects":false,"main":"dist/index.js","exports":{"import":"./esm/index.js","require":"./dist/index.js"},"author":{"name":"Colin Diesh","email":"colin.diesh@gmail.com","url":"https://github.com/cmdcolin"},"directories":{"lib":"dist"},"scripts":{"test":"vitest","clean":"rimraf dist esm","diagrams":"node scripts/generate-diagrams.ts","format":"prettier --write .","format:check":"prettier --check .","lint":"eslint --report-unused-disable-directives --max-warnings 0","typecheck":"tsc --noEmit -p tsconfig.lint.json","prebuild":"pnpm clean","build:esm":"tsc --outDir esm","build:es5":"tsc --module commonjs --moduleResolution bundler --outDir dist","postbuild:es5":"echo '{\"type\": \"commonjs\"}' > dist/package.json","preversion":"pnpm lint && pnpm format:check && pnpm typecheck && pnpm test --run && pnpm build","version":"git-cliff --tag v$npm_package_version --unreleased --prepend CHANGELOG.md && git add CHANGELOG.md","postversion":"git push --follow-tags","build":"pnpm build:esm && pnpm build:es5"},"keywords":["byte-range","cache","filehandle","http","range-request"],"dependencies":{"generic-filehandle2":"^2.4.0"},"devDependencies":{"@eslint/js":"^10.0.1","@types/node":"^25.9.5","@vitest/coverage-v8":"^4.1.10","eslint":"^10.8.0","eslint-plugin-import-x":"^4.17.1","git-cliff":"^2.13.1","prettier":"^3.9.6","rimraf":"^6.1.3","typescript":"^6.0.3","typescript-eslint":"^8.65.0","vitest":"^4.1.10"},"publishConfig":{"access":"public"},"gitHead":"8259486dd035ffa759091aaca9e3353001c95a9b","types":"./dist/index.d.ts","_id":"@gmod/range-cache-filehandle@1.4.0","bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"homepage":"https://github.com/GMOD/range-cache-filehandle#readme","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-JSyUdyjkRKIXWANNfpwBkoITAhU2n8b4Kb1/2swq17xcyO2Ux5mxzW6WgaM+DKBptiFsuraGYXI1aiZUgeOcrA==","shasum":"b2f2500253fb3387bb7c58337154019fccb2d3b9","tarball":"https://registry.npmjs.org/@gmod/range-cache-filehandle/-/range-cache-filehandle-1.4.0.tgz","fileCount":53,"unpackedSize":412186,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@gmod%2frange-cache-filehandle@1.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFy1aptfcB4LGbnhzgdqlXzsJfYPlcHLB8aAIFopfH6/AiB6MDX4s5j0+/nmxA25I6gpmXfUq1yGjGFWIciRINeoyw=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:69373189-7a6b-479d-8fa2-49bc6ed1887e"}},"maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/range-cache-filehandle_1.4.0_1787502123872_0.6999640574483439"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-16T03:20:57.203Z","modified":"2026-08-23T16:22:04.421Z","1.0.0":"2026-08-16T03:20:57.497Z","1.0.1":"2026-08-16T03:26:29.279Z","1.0.2":"2026-08-16T03:33:14.362Z","1.1.0":"2026-08-17T02:43:46.344Z","1.2.0":"2026-08-17T15:40:15.517Z","1.3.0":"2026-08-23T15:47:26.430Z","1.4.0":"2026-08-23T16:22:04.026Z"},"bugs":{"url":"https://github.com/GMOD/range-cache-filehandle/issues"},"author":{"name":"Colin Diesh","email":"colin.diesh@gmail.com","url":"https://github.com/cmdcolin"},"license":"MIT","homepage":"https://github.com/GMOD/range-cache-filehandle#readme","keywords":["byte-range","cache","filehandle","http","range-request"],"repository":{"type":"git","url":"git+https://github.com/GMOD/range-cache-filehandle.git"},"description":"A filehandle that caches byte ranges in chunks and coalesces adjacent reads into one request","maintainers":[{"name":"rbuels","email":"rbuels@gmail.com"},{"name":"cmdcolin","email":"colin.diesh@gmail.com"},{"name":"garrettjstevens","email":"stevens.garrett.j@gmail.com"}],"readme":"# @gmod/range-cache-filehandle\n\n[![NPM version](https://img.shields.io/npm/v/@gmod/range-cache-filehandle.svg?style=flat-square)](https://npmjs.org/package/@gmod/range-cache-filehandle)\n![Build Status](https://img.shields.io/github/actions/workflow/status/GMOD/range-cache-filehandle/publish.yml?branch=main)\n\nA `GenericFilehandle` that caches byte ranges in chunks and coalesces adjacent\nreads into one request.\n\nAn indexed genomics parser reads in a pattern the network is bad at: many small,\nadjacent, semi-random ranges, most of them near ones it just read. This layer\nsits under the parser and turns that into a few large requests, then serves the\nnext query's overlapping reads from memory.\n\n```sh\nnpm install @gmod/range-cache-filehandle\n```\n\n## Usage\n\nDrop-in for `RemoteFile` from\n[generic-filehandle2](https://github.com/GMOD/generic-filehandle2):\n\n```js\nimport { RemoteFileWithRangeCache } from '@gmod/range-cache-filehandle'\nimport { CramFile } from '@gmod/cram'\n\nconst cram = new CramFile({\n  filehandle: new RemoteFileWithRangeCache('https://example.com/file.cram'),\n})\n```\n\nA local file or `Blob` can be wrapped instead. The second argument keys this\nfile's chunks in the shared cache, so it must identify the underlying bytes:\n\n```js\nimport { CachedFilehandle } from '@gmod/range-cache-filehandle'\nimport { LocalFile } from 'generic-filehandle2'\n\nconst file = new CachedFilehandle(new LocalFile(path), `file://${path}`)\n```\n\n## What it does\n\n<img src=\"docs/img/chunks.svg\" alt=\"A read spanning five 256 KiB chunks: one is cached, one is already being fetched by another read, and the three that are missing become two range requests\" width=\"660\">\n\nThe picture is generated by running the cache — the range headers in it are the\nones that read sent. [CONTRIBUTING.md](CONTRIBUTING.md#docs) says how.\n\n- Serves reads from a 256 KiB chunk grid. The chunks a read is missing are\n  grouped into contiguous runs, one request each.\n- Joins a chunk another read has in flight rather than requesting it again.\n- Reference-counts each run's readers, so a shared request is cancelled only\n  once all of them abort. A reader passing no signal pins it for everyone.\n- Holds 1000 chunks (256 MB) per worker, swept after 15 minutes idle, 20\n  requests at a time **per origin**. `clearCache()` drops everything,\n  `clearCacheFor(key)` drops one file, `sweepIdleCache()` reclaims early.\n- Clamps reads past EOF once a size is known, from `Content-Range`, a 416, or\n  `stat()`.\n- Checks a `206` against what it claims to be, so a truncated body or a proxy\n  answering with the wrong range fails loudly instead of being cached as a file\n  that ends early.\n- Names a cause on failure: CORS, mixed content, a server ignoring the Range\n  header, a connection that goes 30s without answering.\n\nNothing is retried, and **nothing puts a clock on a transfer**. This layer\ncoalesces a run of chunks into one request, so a large one is the normal case,\nand any duration limit would cut off a slow download rather than a broken one —\n`fetch` [has no timeout of its own](https://github.com/whatwg/fetch/issues/951)\nfor the same reason. The way to stop a read is the `AbortSignal` you passed it,\nwhich is carried to the socket.\n\nRequests are capped per origin rather than per process so that one unresponsive\nserver cannot starve the others — the\n[per-endpoint semaphore](https://copdips.com/2023/01/python-aiohttp-rate-limit.html)\nshape, since a global limit \"will unnecessarily restrict requests to other\nendpoints as well\". Per origin and not per URL, because a presigned URL rotates\nits signature on every read and a pool keyed on that would be new every time.\n\n[docs/dataflow.md](docs/dataflow.md) has the diagram and walks one read through\nall of it.\n\n## Tuning\n\n`CHUNK_SIZE`, `MAX_CACHE_ENTRIES`, `CACHE_IDLE_TIMEOUT_MS`, `MAX_CONCURRENT` and\n`RESPONSE_TIMEOUT_MS` are exported for reading, not setting — the cache is\nmodule-global, so a knob on one filehandle would set policy for every other one\nin the process. What each was measured against is in `src/constants.ts` and in\n[docs/tuning.md](docs/tuning.md).\n\n## Docs\n\n- [docs/api.md](docs/api.md) — every export, and the `recordSize` hook a\n  subclass with its own `stat()` needs\n- [docs/dataflow.md](docs/dataflow.md) — how a read flows, with the diagram\n- [docs/sharing.md](docs/sharing.md) — one request, several readers, and whose\n  abort cancels it\n- [docs/tuning.md](docs/tuning.md) — the five constants, what measured them, and\n  what changes outside a browser\n- [docs/errors.md](docs/errors.md) — what each failure says and why\n\n## References\n\n- [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html) — HTTP semantics:\n  [Range](https://www.rfc-editor.org/rfc/rfc9110.html#section-14.2) §14.2,\n  [Content-Range](https://www.rfc-editor.org/rfc/rfc9110.html#section-14.4)\n  §14.4, [206](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.3.7)\n  §15.3.7, [416](https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.17)\n  §15.5.17. Only single-part ranges are cached; a multi-range request is passed\n  straight through rather than partly honored.\n- [WHATWG DOM: dependent signals](https://dom.spec.whatwg.org/#abortsignal-dependent-signals)\n  — why `AbortSignal.any` retains nothing while a hand-composed listener must be\n  removed.\n- [whatwg/fetch#951](https://github.com/whatwg/fetch/issues/951) — why `fetch`\n  has no timeout, and why this package adds none over a transfer.\n- [Per-endpoint rate limiting](https://copdips.com/2023/01/python-aiohttp-rate-limit.html)\n  — the semaphore-per-endpoint shape `MAX_CONCURRENT` uses.\n\n## The layer above\n\nThis caches bytes. Every parser that reads through it caches what it parsed out\nof them, on its own budget and its own idle timeout, and that cache is the one\nthat decides whether a read reaches this layer at all:\n\n- [@gmod/bam](https://github.com/GMOD/bam-js) —\n  [caching.md](https://github.com/GMOD/bam-js/blob/main/docs/caching.md)\n- [@gmod/cram](https://github.com/GMOD/cram-js) —\n  [memory.md](https://github.com/GMOD/cram-js/blob/main/docs/memory.md)\n- [@gmod/tabix](https://github.com/GMOD/tabix-js) —\n  [caching.md](https://github.com/GMOD/tabix-js/blob/main/docs/caching.md)\n- [@gmod/bbi](https://github.com/GMOD/bbi-js) —\n  [concurrency.md](https://github.com/GMOD/bbi-js/blob/main/docs/concurrency.md)\n\n## Provenance\n\nExtracted from JBrowse 2, where it was\n`@jbrowse/core/util/io/RemoteFileWithRangeCache`, so parsers can use it without\ndepending on `@jbrowse/core`.\n\nReplaces [http-range-fetcher](https://github.com/rbuels/http-range-fetcher), the\nearlier inspiration. That merges the requests made in the last 100 ms; this\nmerges the chunks a read is missing, so it needs no window to wait out and\ncarries an `AbortSignal` to the socket.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}