{"_id":"fd","_rev":"312230","name":"fd","description":"File descriptor manager","dist-tags":{"latest":"0.0.3"},"maintainers":[{"name":"rvagg","email":""}],"time":{"modified":"2021-06-03T19:53:10.000Z","created":"2013-01-09T05:54:45.615Z","0.0.3":"2018-04-05T17:18:37.000Z","0.0.2":"2013-01-10T00:49:30.138Z","0.0.1":"2013-01-10T00:21:49.247Z","0.0.0":"2013-01-09T05:54:45.615Z"},"users":{},"repository":{"type":"git","url":"git+https://github.com/rvagg/node-fd.git"},"versions":{"0.0.3":{"name":"fd","description":"File descriptor manager","version":"0.0.3","homepage":"https://github.com/rvagg/node-fd","authors":["Rod Vagg <rod@vagg.org> (https://github.com/rvagg)"],"keywords":["fd","fs","descriptor","file"],"main":"./index.js","repository":{"type":"git","url":"git+https://github.com/rvagg/node-fd.git"},"dependencies":{},"devDependencies":{"tap":"*","sinon":"*","mkfiletree":"*"},"scripts":{"test":"tap test.js"},"license":"MIT","gitHead":"e74f8cf3a30e89dd26ec6d3d8686e1a46675daac","bugs":{"url":"https://github.com/rvagg/node-fd/issues"},"_id":"fd@0.0.3","_npmVersion":"5.6.0","_nodeVersion":"8.11.1","_npmUser":{"name":"rvagg","email":"r@va.gg"},"dist":{"shasum":"b3240de86dbf5a345baae7382a07d4713566ff0c","size":6476,"noattachment":false,"key":"/fd/-/fd-0.0.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/fd/download/fd-0.0.3.tgz"},"maintainers":[{"name":"rvagg","email":""}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/fd_0.0.3_1522948716828_0.6648919626641419"},"_hasShrinkwrap":false,"publish_time":1522948717000,"_cnpm_publish_time":1522948717000},"0.0.2":{"name":"fd","description":"File descriptor manager","version":"0.0.2","homepage":"https://github.com/rvagg/node-fd","authors":["Rod Vagg <rod@vagg.org> (https://github.com/rvagg)"],"keywords":["fd","fs","descriptor","file"],"main":"./index.js","repository":{"type":"git","url":"https://github.com/rvagg/node-fd.git"},"dependencies":{},"devDependencies":{"tap":"*","sinon":"*","mkfiletree":"*"},"scripts":{"test":"tap test.js"},"license":"MIT","readmeFilename":"README.md","_id":"fd@0.0.2","dist":{"shasum":"e0edb2bd7a88cc86dd9f16391cba832418fd87ee","size":31458,"noattachment":false,"key":"/fd/-/fd-0.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/fd/download/fd-0.0.2.tgz"},"_npmVersion":"1.1.69","_npmUser":{"name":"rvagg","email":"rod@vagg.org"},"maintainers":[{"name":"rvagg","email":""}],"directories":{},"publish_time":1357778970138,"_cnpm_publish_time":1357778970138,"_hasShrinkwrap":false},"0.0.1":{"name":"fd","description":"File descriptor manager","version":"0.0.1","homepage":"https://github.com/rvagg/node-fd","authors":["Rod Vagg <rod@vagg.org> (https://github.com/rvagg)"],"keywords":["fd","fs","descriptor","file"],"main":"./index.js","repository":{"type":"git","url":"https://github.com/rvagg/node-fd.git"},"dependencies":{},"devDependencies":{"tap":"*","sinon":"*","mkfiletree":"*"},"scripts":{"test":"tap test.js"},"license":"MIT","readmeFilename":"README.md","_id":"fd@0.0.1","dist":{"shasum":"9ad4d8eed4f777995d576d992ee84e1c18c24bae","size":31440,"noattachment":false,"key":"/fd/-/fd-0.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/fd/download/fd-0.0.1.tgz"},"_npmVersion":"1.1.69","_npmUser":{"name":"rvagg","email":"rod@vagg.org"},"maintainers":[{"name":"rvagg","email":""}],"directories":{},"publish_time":1357777309247,"_cnpm_publish_time":1357777309247,"_hasShrinkwrap":false},"0.0.0":{"name":"fd","description":"File descriptor manager","version":"0.0.0","homepage":"https://github.com/rvagg/node-fd","authors":["Rod Vagg <rod@vagg.org> (https://github.com/rvagg)"],"keywords":["fd","fs","descriptor","file"],"main":"./index.js","repository":{"type":"git","url":"https://github.com/rvagg/node-fd.git"},"dependencies":{},"devDependencies":{"tap":"*","sinon":"*","mkfiletree":"*"},"scripts":{"test":"tap test.js"},"license":"MIT","readmeFilename":"README.md","_id":"fd@0.0.0","dist":{"shasum":"7f98707ff734852f718e71a4fe1192de84960d99","size":4373,"noattachment":false,"key":"/fd/-/fd-0.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/fd/download/fd-0.0.0.tgz"},"_npmVersion":"1.1.69","_npmUser":{"name":"rvagg","email":"rod@vagg.org"},"maintainers":[{"name":"rvagg","email":""}],"directories":{},"publish_time":1357710885615,"_cnpm_publish_time":1357710885615,"_hasShrinkwrap":false}},"readme":"# fd [![Build Status](https://secure.travis-ci.org/rvagg/node-fd.png)](http://travis-ci.org/rvagg/node-fd)\n\nFile descriptor manager for Node.js. *Available in npm as <strong>fd</strong>*.\n\n**fd** manages `fs.open()` and `fs.close()` calls safely for you where there may be timing issues related to multiple-use of the same descriptor.\n\n**fd** provides `checkin()` and `checkout()` functions so your application can register its intent to use a file descriptor after it's been opened and then register that it has finished with the descriptor so that any pending `fs.close()` operations may be performed.\n\n**fd** naturally couples with [async-cache](https://github.com/isaacs/async-cache) to provide a safe pool of file descriptors.\n\n## Example\n\nLets make a static resource web server! This example can be found in the *example/* directory of this repository.\n\nWe use [async-cache](https://github.com/isaacs/async-cache) to cache both `fs.sync()` calls and `fd`s, but we hook it up to **fd** so we can safely manage opens and closes.\n\n```js\nconst fdman = require('fd')()\n    , http  = require('http')\n    , fs    = require('fs')\n    , path  = require('path')\n    , AC    = require('async-cache')\n    , mime  = require('mime')\n\n    , ROOT  = path.join(__dirname, 'public')\n\n      // an async cache for fs.stat calls, fresh for 10s\n    , statCache = AC({\n          max    : 100\n        , maxAge : 10000\n        , load   : function (path, callback) {\n                     fs.stat(path, callback)\n                   }\n      })\n\n      // an async cache for fds, fresh for 10s\n    , fdCache = AC({\n          max     : 100\n        , maxAge  : 10000\n          // use fdman to open & close\n        , load    : fdman.open.bind(fdman)\n        , dispose : fdman.close.bind(fdman)\n      })\n\n    , serveError = function (res) {\n        res.statusCode = 404\n        res.setHeader('content-type', 'text/plain')\n        res.end(http.STATUS_CODES[res.statusCode] + '\\n')\n      }\n\nhttp.createServer(function (req, res) {\n  var p = path.join(ROOT, req.url)\n\n  // get a fs.stat for this file\n  statCache.get(p, function (err, stat) {\n    if (err || !stat.isFile())\n      return serveError(res)\n\n    // get an fd for this file\n    fdCache.get(p, function (err, fd) {\n      var mimeType = mime.lookup(path.extname(p))\n          // get a safe checkin function from fdman that\n          // we could safely all multiple times for this single\n          // checkout\n        , checkin = fdman.checkinfn(p, fd)\n\n      // check out the fd for use\n      fdman.checkout(p, fd)\n\n      res.setHeader(\n          'content-type'\n          // don't force download, just show it\n        , mimeType != 'application/octet-stream' ? mimeType : 'text/plain'\n      )\n\n      // stream from the fd to the response\n      var st = fs.createReadStream(p, { fd: fd, start: 0, end: stat.size })n\n        .on('end', checkin)\n        .on('error', checkin)\n\n      // override destroy so we don't close the fd\n      st.destroy = function () {}\n\n      st.pipe(res)\n\n    })\n  })\n}).listen(8080)\n```\n\n## API\n\n### fd()\nCreate a new instance of **fd**. Typically called with `var fdman = require('fd')()`. You can have multiple, separate instances of **fd** operating at the same time, hence the need to instantiate.\n\n### fdman.open(path, callback)\nEquivalent to `fs.open(path, callback)`, you'll get back an `err` and `fd` parameters but the descriptor will go into the managed pool.\n\n### fdman.close(path, fd)\nWill call `fs.close(fd)` *only when the `fd` is no longer in use*. i.e. it will wait till all current uses have been checked in (see below).\n\n### fdman.checkout(path, fd)\nCalled when your application may need to use the `fd`. This should be called as early as possible, even if your application may not end up using it.\n\nIt is important to perform a `checkout()` as soon as you have a reference to the file descriptor if you may be using it, otherwise an asynchronous call may interrupt and call `close()` before you use it. You *don't have to use the `fd`* to register your intent to use it, as long as you eventually call `checkin()`.\n\n### fdman.checkin(path, fd)\nRegister with **fd** that you have finished using the descriptor and it can be safely closed if need be.\n\nThe descriptor may not need to be closed or there may be other uses of the descriptor currently checked out so a `checkin()` won't automatically lead to a `close()`.\n\n### fdman.checkinfn(path, fd)\nReturns a function that, when called, will safely perform a `checkin()` for you on the given path and descriptor. An important property of the function is that it will only perform a single `checkin()` regardless of how many times it is called.\n\nThis returned function is helpful for calling `checkin()` from multiple points in your application, such as in case of error, and you don't need to worry about whether it's been previously called for the current `checkout()`.\n\nSee the example above how this can be used.\n\n\n## Licence\n\nfd is Copyright (c) 2012 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.","_attachments":{},"homepage":"https://github.com/rvagg/node-fd","bugs":{"url":"https://github.com/rvagg/node-fd/issues"},"license":"MIT"}