{"_id":"@emdzej/csfs-manifest","_rev":"4-98c21e8ff0647620ac1705160cd58d4f","name":"@emdzej/csfs-manifest","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@emdzej/csfs-manifest","version":"0.1.0","keywords":["filesystem","browser","zip","range-requests","opfs","file-system-access","http"],"license":"MIT","_id":"@emdzej/csfs-manifest@0.1.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/csfs/tree/main/packages/manifest#readme","bugs":{"url":"https://github.com/emdzej/csfs/issues"},"dist":{"shasum":"f0b55892bad9ab83b9d3b6fcc17f84e370588268","tarball":"https://registry.npmjs.org/@emdzej/csfs-manifest/-/csfs-manifest-0.1.0.tgz","fileCount":7,"integrity":"sha512-5Hqu5GoBgCheFyCFgAtSaFfzv3iOHjWZnD2u6ZXf19zl544RifmqztOaQaTK8dHrLvobWE4WbyROzzVEhIzYsQ==","signatures":[{"sig":"MEQCICLwT61sJuMsv5aFncGj8DmxB90AnPv60SkaV2LnbYEGAiA8Nou9a6cHWlZybgy2PucwdUPd3iCs3Sxf+42gNWwUng==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23405},"main":"dist/index.js","type":"module","_from":"file:emdzej-csfs-manifest-0.1.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -b","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/cbe6aad86d5b85bc96ff07fa45387bf0/emdzej-csfs-manifest-0.1.0.tgz","_integrity":"sha512-5Hqu5GoBgCheFyCFgAtSaFfzv3iOHjWZnD2u6ZXf19zl544RifmqztOaQaTK8dHrLvobWE4WbyROzzVEhIzYsQ==","repository":{"url":"git+https://github.com/emdzej/csfs.git","type":"git","directory":"packages/manifest"},"_npmVersion":"11.16.0","description":"The HTTP manifest format, and building one from any file system","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/csfs-core":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/csfs-manifest_0.1.0_1788549003927_0.5115205559755698","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@emdzej/csfs-manifest","version":"0.1.1","keywords":["filesystem","browser","zip","range-requests","opfs","file-system-access","http"],"license":"MIT","_id":"@emdzej/csfs-manifest@0.1.1","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/csfs/tree/main/packages/manifest#readme","bugs":{"url":"https://github.com/emdzej/csfs/issues"},"dist":{"shasum":"53455827c04a58a9c4e43990c9bef31018c42ba7","tarball":"https://registry.npmjs.org/@emdzej/csfs-manifest/-/csfs-manifest-0.1.1.tgz","fileCount":7,"integrity":"sha512-WPxs1aEo2Bg4vRRmFeu7g9uj2hvBAJPXYOWS1rGyHSgM47MrtjZErgHtDjHiPZpIX58OQQM5T4r3Uib+0FVZkQ==","signatures":[{"sig":"MEUCIQCEDyMEKEeui0iO6kudxoULr945Z/ttzX92x1fh43ftYAIgGL9U7q+4F1ktdrAO8525z546T0XzwzPSVXjtlG9pm6U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIF1QDLa7C5en4047BVnr8bNBr7j0q/aM7RNWWXYQard0AiEAmG/IYuavt4ZAwGKwhClT5HUIPr0kGZye0ysrCdz0OZc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23405},"main":"dist/index.js","type":"module","_from":"file:emdzej-csfs-manifest-0.1.1.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -b","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/44707112e1e408e8c1a2afc0a7e4a778/emdzej-csfs-manifest-0.1.1.tgz","_integrity":"sha512-WPxs1aEo2Bg4vRRmFeu7g9uj2hvBAJPXYOWS1rGyHSgM47MrtjZErgHtDjHiPZpIX58OQQM5T4r3Uib+0FVZkQ==","repository":{"url":"git+https://github.com/emdzej/csfs.git","type":"git","directory":"packages/manifest"},"_npmVersion":"11.16.0","description":"The HTTP manifest format, and building one from any file system","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/csfs-core":"0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.13.1"},"_npmOperationalInternal":{"tmp":"tmp/csfs-manifest_0.1.1_1788968620235_0.1730094116582459","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@emdzej/csfs-manifest","version":"0.2.0","keywords":["filesystem","browser","zip","range-requests","opfs","file-system-access","http"],"license":"MIT","_id":"@emdzej/csfs-manifest@0.2.0","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"homepage":"https://github.com/emdzej/csfs/tree/main/packages/manifest#readme","bugs":{"url":"https://github.com/emdzej/csfs/issues"},"dist":{"shasum":"675170ce51db976e3cfbb8aa6cdb3e6420bb08c1","tarball":"https://registry.npmjs.org/@emdzej/csfs-manifest/-/csfs-manifest-0.2.0.tgz","fileCount":11,"integrity":"sha512-9TLRqryT2Fkmaz/4GLx5Hyb7YaknUzaC+mhhzrzz7nbBjzBrPh5ohXSqw0u80j0ye+DCd4831SbBp2nACjQiXw==","signatures":[{"sig":"MEUCIBnk59yWmYAQzqVMAexXn+rW7r9dUVnQTYuy2kYA99NpAiEA/ScZhquy+zyx2Og0XQmoy5lN5HtIqRJhx0/EIvINMzw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDI4DC/OrwgrPYfnF8U9tpEHk+a8u9MfaAZCQToETJzUwIgDvAcavNkWN+lqqVDXfJg4KIfuaOAz/KpdZ6vo6RSD6o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43960},"main":"dist/index.js","type":"module","_from":"file:emdzej-csfs-manifest-0.2.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc -b","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit"},"_npmUser":{"name":"emdzej","email":"michal@jaskolski.pro"},"_resolved":"/private/var/folders/7h/x_w_580x4s9dq3sq11tpvzkwy3nbj8/T/dbf1bd8324ee1cd67be673440ad98f65/emdzej-csfs-manifest-0.2.0.tgz","_integrity":"sha512-9TLRqryT2Fkmaz/4GLx5Hyb7YaknUzaC+mhhzrzz7nbBjzBrPh5ohXSqw0u80j0ye+DCd4831SbBp2nACjQiXw==","repository":{"url":"git+https://github.com/emdzej/csfs.git","type":"git","directory":"packages/manifest"},"_npmVersion":"11.16.0","description":"The HTTP manifest format, and building one from any file system","directories":{},"_nodeVersion":"22.22.1","dependencies":{"@emdzej/csfs-core":"0.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.13.1","@emdzej/csfs-node":"0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/csfs-manifest_0.2.0_1789548739168_0.3772150242437893","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@emdzej/csfs-manifest@0.3.0","bugs":{"url":"https://github.com/emdzej/csfs/issues"},"dist":{"shasum":"a5e09fbdb1692ac6d39bd552b1608069f87056d7","tarball":"https://registry.npmjs.org/@emdzej/csfs-manifest/-/csfs-manifest-0.3.0.tgz","fileCount":7,"integrity":"sha512-kM+ZtrBauWTXnHKZ8/Hkju+s1ixJbJZgj2g9ehgJ0XB1bmkmRJdYrAQBrSZfBgGF798sEv8MiVGVXDj5KVAJZA==","signatures":[{"sig":"MEUCIQC7k4b5n6qNKN4ZzK3uQ4oKQMArA6CYKqxV+z/RwU50IwIgXC6KfsWFqygX8/PvrRF2ayV0QeHK/N/kWL9/FaNutXk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDGDn6/cWdEPBry1us2mwbsJa26cE3rVJxU8xJs3gPL/QIgT2a99qLwLwP58rhwq3tCmLwCt8lZcidVcsg/rMKvoSU="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@emdzej%2fcsfs-manifest@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":37077},"main":"dist/index.js","name":"@emdzej/csfs-manifest","type":"module","_from":"file:dist-npm/emdzej-csfs-manifest-0.3.0.tgz","types":"dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"license":"MIT","scripts":{"build":"tsc -b","clean":"rm -rf dist .turbo *.tsbuildinfo","typecheck":"tsc --noEmit"},"version":"0.3.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:13b20ad7-b6fe-44e8-9536-dc1750080a60"}},"homepage":"https://github.com/emdzej/csfs/tree/main/packages/manifest#readme","keywords":["filesystem","browser","zip","range-requests","opfs","file-system-access","http"],"_resolved":"/home/runner/work/csfs/csfs/dist-npm/emdzej-csfs-manifest-0.3.0.tgz","_integrity":"sha512-kM+ZtrBauWTXnHKZ8/Hkju+s1ixJbJZgj2g9ehgJ0XB1bmkmRJdYrAQBrSZfBgGF798sEv8MiVGVXDj5KVAJZA==","repository":{"url":"git+https://github.com/emdzej/csfs.git","type":"git","directory":"packages/manifest"},"_npmVersion":"11.20.0","description":"The HTTP manifest format, and building one from any file system","directories":{},"maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"sideEffects":false,"_nodeVersion":"24.21.0","dependencies":{"@emdzej/csfs-core":"0.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.20.4","@emdzej/csfs-node":"0.3.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/csfs-manifest_0.3.0_1790326386249_0.01701992152389531"}}},"time":{"created":"2026-09-04T19:10:03.776Z","modified":"2026-09-25T08:53:06.643Z","0.1.0":"2026-09-04T19:10:04.059Z","0.1.1":"2026-09-09T15:43:40.327Z","0.2.0":"2026-09-16T08:52:19.249Z","0.3.0":"2026-09-25T08:53:06.347Z"},"bugs":{"url":"https://github.com/emdzej/csfs/issues"},"license":"MIT","homepage":"https://github.com/emdzej/csfs/tree/main/packages/manifest#readme","keywords":["filesystem","browser","zip","range-requests","opfs","file-system-access","http"],"repository":{"url":"git+https://github.com/emdzej/csfs.git","type":"git","directory":"packages/manifest"},"description":"The HTTP manifest format, and building one from any file system","maintainers":[{"name":"emdzej","email":"michal@jaskolski.pro"}],"readme":"# @emdzej/csfs-manifest\n\nThe manifest format that lets a tree on a static host describe itself, and the\nbuilder that produces one.\n\n_Part of [csfs](https://github.com/emdzej/csfs) — a **c**lient **s**ide **f**ile **s**ystem: one read API over static HTTP, a picked directory,\nOPFS, and inside zip archives._\n\n```ts\nimport { buildManifest, formatManifest } from \"@emdzej/csfs-manifest\";\nimport { nodeFileSystem } from \"@emdzej/csfs-node\";\n\nconst manifest = await buildManifest(nodeFileSystem(\"./data\"), {\n  label: \"my tree\",\n  builtAt: new Date().toISOString(),\n});\nawait writeFile(\"./data/csfs-manifest.json\", formatManifest(manifest));\n```\n\nFrom a terminal, that is\n[`@emdzej/csfs-cli`](https://www.npmjs.com/package/@emdzej/csfs-cli). In a\nbrowser, the [demo](https://csfs.emdzej.pl) does it from a picked folder — the\nbuilder takes any `CsFileSystem`, so the same code runs in both.\n\n## Why it exists\n\n**HTTP cannot list a directory.** A static host serves any file you name and\ntells you nothing about what is there. `@emdzej/csfs-http` needs to answer\n`directory()` and to know a file's size before it can range-request it, and\nneither is discoverable. So the tree carries the answer.\n\nThe other backends need no manifest; they can list for themselves.\n\n## The format\n\n```json\n{\n  \"csfs\": 1,\n  \"label\": \"my tree\",\n  \"builtAt\": \"2026-09-03T10:00:00.000Z\",\n  \"files\": { \"/pr/index.dat\": 40960, \"/drawings.zip\": 991232000 },\n  \"archives\": [{ \"archive\": \"/drawings.zip\", \"serves\": \"/drawings\", \"entry\": \"basename\" }]\n}\n```\n\n**Flat, not nested**, for three reasons: a lookup is one map hit rather than a\nfetch per directory level; paths in a real tree share long prefixes and so\ncompress well; and directories can be _derived_ from the paths, which is what\nlets an archive stand in for a directory that is not on disk at all.\n\n`archives` is how a tree declares what it keeps packed, ready to hand to\n`withTransparentArchives`. On a real tree, keeping nine vendor archives packed\nremoved **184,610 files** while serving the same bytes.\n\n`builtAt` is supplied by the caller and omitted when absent — a builder should\nnot invent a timestamp, and a deterministic build wants to leave it out.\n\n## What it costs\n\nMeasured on a real tree: **43,915 entries describing 15.30 GB come to 4.02 MB\nof JSON, 0.42 MB gzipped** — 9.4:1, at a host's default level. Paid once, when the tree is opened.\n\nExtracting that tree's nine archives serves the same bytes from 228,515 paths,\nand the manifest becomes 14.72 MB — 1.68 MB gzipped. A manifest is priced in\npaths, not bytes, which is the argument for declaring an archive rather than\nunpacking it.\n\nWorth it at that scale and irrelevant for a dozen files — but a tree in the\nmillions would want something other than JSON, and this format does not pretend\notherwise. Use `filter` to leave out what no one will ask for:\n\n```ts\nawait buildManifest(fs, { filter: (path) => !path.endsWith(\".tmp\") });\n```\n\n## `ManifestIndex`\n\n`parseManifest` validates unknown JSON into a `Manifest` — it is reading a file\noff the network, so the shape is checked rather than asserted. `ManifestIndex`\nwraps one for lookups: `size(path)`, `hasFile`, `hasDirectory`, and\n`entriesOf(dir)`, with the directory structure derived once on construction so\nlisting a directory does not scan every path.\n\n## Licence\n\n**MIT** — see [LICENSE](https://github.com/emdzej/csfs/blob/main/LICENSE).\n","readmeFilename":"README.md"}