{"_id":"dofs","_rev":"6-da370d3a2cc8ae8a14f12a855c882258","name":"dofs","dist-tags":{"rc":"0.0.1-rc.0","latest":"0.1.0"},"versions":{"0.0.1-rc.0":{"name":"dofs","version":"0.0.1-rc.0","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"dofs@0.0.1-rc.0","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"dist":{"shasum":"2f9f5069bf805d580c35e2ca92cca4c05246663f","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.0.1-rc.0.tgz","fileCount":15,"integrity":"sha512-Oq1lCRBicH3SwmGp+MqSUiY2vW2vccBWT330ICig7IrEg35dxpasT3RuVp+N6Sp6wU09zNoFogT5+UiYm/sTEw==","signatures":[{"sig":"MEYCIQCXaofQcCYMMKqQaMDlT5q3oyjbhunEfTqFe9w1m5pt8QIhAPwWmy3aRtQNJGE7f/FzRPNTax5qoYlADCh+1sdxPTVK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":313604},"main":"./dist/Fs.mjs","types":"./dist/Fs.d.mts","module":"./dist/Fs.mjs","exports":{".":{"types":"./dist/Fs.d.mts","import":"./dist/Fs.mjs"}},"gitHead":"649afc2079f9358babf8183fd4ef099a8d49d03a","scripts":{"build":"tsup","watch":"tsup --watch","cf-typegen":"wrangler types"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"repository":{"url":"git+https://github.com/benallfree/dofs.git","type":"git"},"_npmVersion":"10.8.1","description":"A filesystem for Cloudflare Durable Objects.","directories":{},"_nodeVersion":"20.12.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dofs_0.0.1-rc.0_1747591983687_0.9302219376172163","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.1":{"name":"dofs","version":"0.0.1-rc.1","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"dofs@0.0.1-rc.1","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"dist":{"shasum":"80bfcc7b24ca91c0add346e985b3106299bc19cd","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.0.1-rc.1.tgz","fileCount":5,"integrity":"sha512-0HFhrDsHttwj0uWYcvw3Zd0jcmHHCxE+227yMnL9/3Ggso1CGz3cUD2+A0d0Yu0DHjPxwx/mg7YE6uKYIONXYA==","signatures":[{"sig":"MEUCIQCSvw+vbfzhmRRolIuACDUUInkqr3OntVurAjvdo49MUwIgOf9F7EnWMGlFIIiPyWcjQqE5/VDepCKNGVrH9bVQ7yg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30981},"main":"./dist/Fs.mjs","types":"./dist/Fs.d.mts","module":"./dist/Fs.mjs","exports":{".":{"types":"./dist/Fs.d.mts","import":"./dist/Fs.mjs"}},"gitHead":"fcc96d5c68021e2985633e170932724ea5527135","scripts":{"build":"tsup","watch":"tsup --watch","cf-typegen":"wrangler types"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"repository":{"url":"git+https://github.com/benallfree/dofs.git","type":"git"},"_npmVersion":"10.8.1","description":"A filesystem for Cloudflare Durable Objects.","directories":{},"_nodeVersion":"20.12.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dofs_0.0.1-rc.1_1747592699280_0.5893244419755956","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.2":{"name":"dofs","version":"0.0.1-rc.2","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"dofs@0.0.1-rc.2","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"dist":{"shasum":"bf397ffd7e241234aa597cdc4354a695b09bad53","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.0.1-rc.2.tgz","fileCount":5,"integrity":"sha512-Zc5bEVLCvWYUeEITcxadZY6/Bdyb4HZ16U6WWJNEEebiVWohYkO3d7eggOPshVBzMmo6qzK4VEcIy6R1T36h6w==","signatures":[{"sig":"MEUCIQCWlC8ZU8FJPipw+VeqvGblPaOZDgdEGyu+dOMFPTGurgIgaHohAqS2Pa2js5PknrachpzeebibQ79crohEJym8sIA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33680},"main":"./dist/Fs.mjs","types":"./dist/Fs.d.mts","module":"./dist/Fs.mjs","exports":{".":{"types":"./dist/Fs.d.mts","import":"./dist/Fs.mjs"}},"gitHead":"d40f29dc635644bcbc6d284d3a278eb64ff96720","scripts":{"build":"tsup","watch":"tsup --watch","cf-typegen":"wrangler types"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"repository":{"url":"git+https://github.com/benallfree/dofs.git","type":"git"},"_npmVersion":"10.8.1","description":"A filesystem for Cloudflare Durable Objects.","directories":{},"_nodeVersion":"20.12.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dofs_0.0.1-rc.2_1747599133843_0.48916772968246525","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"dofs","version":"0.0.1","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"dofs@0.0.1","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"dist":{"shasum":"711fef6be63c3fc116760d79afe970925ec26e26","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.0.1.tgz","fileCount":7,"integrity":"sha512-vNfYmLREQNQRE0R+ZiUuoW4VkxLZm/M6PHxAlTE5YDwrDIYdSTA0rfZ3Rgp7g2Tkvv5VI9xTt7pUtdMD46eM1Q==","signatures":[{"sig":"MEYCIQCNJ8d5wPBq62OiLFcxo2B/a/0LCesrv0Fe8DqQ/lwrdAIhAMHelvX6ojf0W712KTx9Q/64+QxD/p+stkm2LtAsgUmV","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37809},"main":"./dist/Fs.mjs","types":"./dist/Fs.d.mts","module":"./dist/Fs.mjs","exports":{".":{"types":"./dist/Fs.d.mts","import":"./dist/Fs.mjs"},"./hono":{"types":"./dist/hono/index.d.mts","import":"./dist/hono/index.mjs"}},"gitHead":"2cf703ffc0054e8cdb418b0e95202d048263fd98","scripts":{"dev":"tsup --watch","build":"tsup","cf-typegen":"wrangler types"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"repository":{"url":"git+https://github.com/benallfree/dofs.git","type":"git"},"_npmVersion":"10.8.1","description":"A filesystem for Cloudflare Durable Objects.","directories":{},"_nodeVersion":"20.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.15.27"},"peerDependencies":{"hono":"^4.7.10"},"_npmOperationalInternal":{"tmp":"tmp/dofs_0.0.1_1748614304345_0.08301234034439431","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"dofs","version":"0.0.2","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"dofs@0.0.2","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"dist":{"shasum":"09146ec40299b9974c30644cce8c6972fefa2ed3","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.0.2.tgz","fileCount":8,"integrity":"sha512-4wrAldiKHEjnwBPjbMkmcwfur01jm7wt0MOsZJYzfgVR3U0SpmZ11HnQRy8rux3xRje9LyYJ/Vn6IskM+5L5tw==","signatures":[{"sig":"MEYCIQDLpr3V+HvNc41qd7dMpzUzAYI3QU1elQ9NegNRWgyOYAIhAKlAw6bPeMxpewrrsMcWrJmWcoZ6/+DFcmGAEMIpIMVi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97094},"main":"./dist/Fs.mjs","types":"./dist/Fs.d.mts","module":"./dist/Fs.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./hono":{"types":"./dist/hono.d.mts","import":"./dist/hono.mjs"}},"gitHead":"07d80da1ed65b1df6a7367ab2525f46875943364","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"repository":{"url":"git+https://github.com/benallfree/dofs.git","type":"git"},"_npmVersion":"10.8.1","description":"A filesystem for Cloudflare Durable Objects.","directories":{},"_nodeVersion":"20.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/node":"^22.15.30"},"peerDependencies":{"hono":"^4.7.10"},"_npmOperationalInternal":{"tmp":"tmp/dofs_0.0.2_1749177302165_0.6021706510398572","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"dofs","description":"A filesystem for Cloudflare Durable Objects.","version":"0.1.0","type":"module","author":{"name":"Ben Allfree","url":"https://x.com/benallfree"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/benallfree/dofs.git"},"keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","scripts":{"build":"tsdown","dev":"tsdown --watch"},"main":"./dist/Fs.js","module":"./dist/Fs.js","types":"./dist/Fs.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./hono":{"import":"./dist/hono.js","types":"./dist/hono.d.ts"}},"bin":{"dofs":"dist/cli/index.js"},"dependencies":{"commander":"^14.0.0","neofuse":"^0.0.1-rc.3"},"peerDependencies":{"hono":"^4.7.11"},"devDependencies":{"@types/node":"^22.15.30","tsdown":"^0.12.7"},"_id":"dofs@0.1.0","gitHead":"bcd0d02b5c899ea618311f7dab86f625c38b86b1","bugs":{"url":"https://github.com/benallfree/dofs/issues"},"_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-aF4SM2w1/DCjbZy3oTlRVbksp5TCPkSEETwslOQpdbnkMMyrOQ1Gk4C+LOgKAZRUdovS3qyLUVoKUtdrp+GldQ==","shasum":"b99c4bea0fc06d35b07e01bf19862030bc789d31","tarball":"https://registry.npmjs.org/dofs/-/dofs-0.1.0.tgz","fileCount":16,"unpackedSize":104016,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDrtsddc5OiOCplRwzq6nfm6lt3KwyIh2g1sSXhNrZXJAIgHgJY+3HrkLVfsgvA7jcs/JiGFuyYUVbIn2ElTFm5NF0="}]},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com","actor":{"name":"benallfree","email":"ben@benallfree.com","type":"user"}},"directories":{},"maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dofs_0.1.0_1750564244248_0.30865500957341174"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-18T18:13:03.601Z","modified":"2025-06-22T03:50:44.641Z","0.0.1-rc.0":"2025-05-18T18:13:03.870Z","0.0.1-rc.1":"2025-05-18T18:24:59.457Z","0.0.1-rc.2":"2025-05-18T20:12:14.029Z","0.0.1":"2025-05-30T14:11:44.519Z","0.0.2":"2025-06-06T02:35:02.354Z","0.1.0":"2025-06-22T03:50:44.458Z"},"bugs":{"url":"https://github.com/benallfree/dofs/issues"},"author":{"name":"Ben Allfree","url":"https://x.com/benallfree"},"license":"MIT","homepage":"https://github.com/benallfree/dofs/tree/main/packages/dofs","keywords":["cloudflare","durable objects","dofs","filesystem","file system","file-system","file-system-api","file-system-api-client","file-system-api-server","file-system-api-client-server"],"repository":{"type":"git","url":"git+https://github.com/benallfree/dofs.git"},"description":"A filesystem for Cloudflare Durable Objects.","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"readme":"# Durable Objects File System (dofs)\n\nA filesystem-like API for Cloudflare Durable Objects, supporting streaming reads and writes with chunked storage.\n\n## Features\n\n- File and directory operations (read, write, mkdir, rmdir, stat, etc.)\n- Efficient chunked storage for large files\n- Streaming read and write support via ReadableStream and WritableStream\n- Designed for use in Durable Objects (DOs)\n\n## Basic Usage\n\nThe recommended way to add dofs to your Durable Object is using the `@Dofs` decorator:\n\n```ts\nimport { DurableObject } from 'cloudflare:workers'\nimport { Dofs } from 'dofs'\n\n@Dofs({ chunkSize: 256 * 1024 })\nexport class MyDurableObject extends DurableObject<Env> {\n  // Your custom methods here\n  // Access filesystem via this.getFs()\n}\n```\n\nThe `@Dofs` decorator:\n\n- Automatically creates the `fs` property in your Durable Object\n- Adds a `getFs()` method to access the filesystem instance\n- Accepts the same configuration options as the `Fs` constructor\n- Works directly with classes extending `DurableObject`\n\n### Alternative: Using withDofs Helper\n\nFor cases where you need more control or are working with existing class hierarchies, you can use the `withDofs` helper:\n\n```ts\nimport { DurableObject } from 'cloudflare:workers'\nimport { withDofs } from 'dofs'\n\n// Create a concrete base class first\nclass MyDurableObjectBase extends DurableObject<Env> {\n  constructor(ctx: DurableObjectState, env: Env) {\n    super(ctx, env)\n  }\n}\n\n// Then extend it with dofs\nexport class MyDurableObject extends withDofs(MyDurableObjectBase) {\n  // Your custom methods here\n}\n\n// Or with configuration options:\nexport class MyDurableObject extends withDofs(MyDurableObjectBase, { chunkSize: 256 * 1024 }) {\n  // Your custom methods here\n}\n```\n\n**Important:** Due to TypeScript declaration generation limitations, `withDofs` requires a concrete base class. You cannot pass the abstract `DurableObject` class directly to `withDofs`.\n\nBoth approaches provide the same functionality:\n\n- Automatically creates the `fs` property in your Durable Object\n- Adds a `getFs()` method to access the filesystem instance\n- Accepts the same configuration options as the `Fs` constructor\n\n> Note: class instances can be [passed via RPC](https://developers.cloudflare.com/workers/runtime-apis/rpc/#class-instances) as long as they inherit from `RpcTarget` as `Fs` does.\n\n### Advanced: Manual Setup\n\nFor more control, you can manually create a dofs instance in your Durable Object:\n\n```ts\nimport { DurableObject } from 'cloudflare:workers'\nimport { Fs } from 'dofs'\n\nexport class MyDurableObject extends DurableObject<Env> {\n  private fs: Fs\n\n  constructor(ctx: DurableObjectState, env: Env) {\n    super(ctx, env)\n    this.fs = new Fs(ctx, env)\n  }\n\n  // Expose fs\n  public getDofs() {\n    return this.fs\n  }\n}\n```\n\n## Configuration Options\n\n### Chunk Size\n\nBy default, the chunk size is 64kb. You can configure it by passing the `chunkSize` option (in bytes) to the `Fs` constructor:\n\n```ts\nimport { Fs } from 'dofs'\n\nconst fs = new Fs(ctx, env, { chunkSize: 256 * 1024 }) // 256kb chunks\n```\n\n**How chunk size affects query frequency and cost:**\n\n- Smaller chunk sizes mean more database queries per file read/write, which can increase Durable Object query costs and latency.\n- Larger chunk sizes reduce the number of queries (lower cost, better throughput), but may use more memory per operation and can be less efficient for small files or random access.\n- Choose a chunk size that balances your workload's cost, performance, and memory needs.\n\n> **Note:** Chunk size cannot be changed after the first file has been written to the filesystem. It is fixed for the lifetime of the filesystem instance.\n\n### Device Size\n\nBy default, the device size (total storage available) is 1GB (`1024 * 1024 * 1024` bytes). You can change this limit using the `setDeviceSize` method:\n\n```ts\nfs.setDeviceSize(10 * 1024 * 1024 * 1024) // Set device size to 10GB\n```\n\n- The device size must be set before writing data that would exceed the current limit.\n- If you try to write more data than the device size allows, an `ENOSPC` error will be thrown.\n- You can check the current device size and usage with `getDeviceStats()`.\n\n```ts\nconst stats = fs.getDeviceStats()\nconsole.log(stats.deviceSize, stats.spaceUsed, stats.spaceAvailable)\n```\n\n> **Default:** 1GB if not set.\n\n## Streaming Support\n\n- **Read:** `readFile(path)` returns a `ReadableStream<Uint8Array>` for efficient, chunked reading.\n- **Write:** `writeFile(path, stream)` accepts a `ReadableStream<Uint8Array>` for efficient, chunked writing.\n- You can also use `writeFile(path, data)` with a string or ArrayBuffer for non-streaming writes.\n\n## API Reference\n\n**Note:** These are async from the CF Worker stub (RPC call), but are sync when called inside the Durable Object (direct call).\n\n- `readFile(path: string): ReadableStream<Uint8Array>`\n- `writeFile(path: string, data: string | ArrayBuffer | ReadableStream<Uint8Array>): void`\n- `read(path: string, options): ArrayBuffer` (non-streaming, offset/length)\n- `write(path: string, data, options): void` (non-streaming, offset)\n- `mkdir(path: string, options?): void`\n- `rmdir(path: string, options?): void`\n- `listDir(path: string, options?): string[]`\n- `stat(path: string): Stat`\n- `unlink(path: string): void`\n- `rename(oldPath: string, newPath: string): void`\n- `symlink(target: string, path: string): void`\n- `readlink(path: string): string`\n\n## Projects that work with dofs\n\n- dterm\n\n## Future Plans\n\n- In-memory block caching for improved read/write performance\n- Store small files (that fit in one block) directly in the inode table instead of the chunk table to reduce queries\n- `defrag()` method to allow changing chunk size and optimizing storage\n","readmeFilename":"README.md"}