{"id":13454395,"url":"https://github.com/moxystudio/node-proper-lockfile","last_synced_at":"2025-10-07T13:57:26.888Z","repository":{"id":18570165,"uuid":"21772838","full_name":"moxystudio/node-proper-lockfile","owner":"moxystudio","description":"An inter-process and inter-machine lockfile utility that works on a local or network file system.","archived":false,"fork":false,"pushed_at":"2023-10-25T15:55:02.000Z","size":599,"stargazers_count":259,"open_issues_count":21,"forks_count":46,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-10-03T13:02:03.477Z","etag":null,"topics":["atomic","cross-process","filesystem","lock","lockfile","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/moxystudio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-07-12T17:47:01.000Z","updated_at":"2025-09-27T05:31:12.000Z","dependencies_parsed_at":"2024-06-18T12:26:14.962Z","dependency_job_id":"ec4af006-0826-46da-af8c-9c9f4966245c","html_url":"https://github.com/moxystudio/node-proper-lockfile","commit_stats":{"total_commits":180,"total_committers":17,"mean_commits":"10.588235294117647","dds":"0.18888888888888888","last_synced_commit":"9f8c303c91998e8404a911dc11c54029812bca69"},"previous_names":["indigounited/node-proper-lockfile"],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/moxystudio/node-proper-lockfile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnode-proper-lockfile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnode-proper-lockfile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnode-proper-lockfile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnode-proper-lockfile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/moxystudio","download_url":"https://codeload.github.com/moxystudio/node-proper-lockfile/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/moxystudio%2Fnode-proper-lockfile/sbom","scorecard":{"id":66220,"data":{"date":"2025-08-04","repo":{"name":"github.com/moxystudio/node-proper-lockfile","commit":"9f8c303c91998e8404a911dc11c54029812bca69"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":2,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":2,"reason":"Found 6/24 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"51 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-ff7x-qrg7-qggm","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-h726-x36v-rx45","Warn: Project is vulnerable to: GHSA-779f-wgxg-qr8f","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg","Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8","Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2","Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8","Warn: Project is vulnerable to: GHSA-7xcx-6wjh-7xp2","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-38fc-wpqx-33j7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T02:39:14.247Z","repository_id":18570165,"created_at":"2025-08-15T02:39:14.247Z","updated_at":"2025-08-15T02:39:14.247Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278548011,"owners_count":26004816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic","cross-process","filesystem","lock","lockfile","nodejs"],"created_at":"2024-07-31T08:00:53.708Z","updated_at":"2025-10-07T13:57:26.866Z","avatar_url":"https://github.com/moxystudio.png","language":"JavaScript","readme":"# proper-lockfile\n\n[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url]\n\n[npm-url]:https://npmjs.org/package/proper-lockfile\n[downloads-image]:https://img.shields.io/npm/dm/proper-lockfile.svg\n[npm-image]:https://img.shields.io/npm/v/proper-lockfile.svg\n[travis-url]:https://travis-ci.org/moxystudio/node-proper-lockfile\n[travis-image]:https://img.shields.io/travis/moxystudio/node-proper-lockfile/master.svg\n[codecov-url]:https://codecov.io/gh/moxystudio/node-proper-lockfile\n[codecov-image]:https://img.shields.io/codecov/c/github/moxystudio/node-proper-lockfile/master.svg\n[david-dm-url]:https://david-dm.org/moxystudio/node-proper-lockfile\n[david-dm-image]:https://img.shields.io/david/moxystudio/node-proper-lockfile.svg\n[david-dm-dev-url]:https://david-dm.org/moxystudio/node-proper-lockfile?type=dev\n[david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/node-proper-lockfile.svg\n\nAn inter-process and inter-machine lockfile utility that works on a local or network file system.\n\n\n## Installation\n\n`$ npm install proper-lockfile`\n\n\n## Design\n\nThere are various ways to achieve [file locking](http://en.wikipedia.org/wiki/File_locking).\n\nThis library utilizes the `mkdir` strategy which works atomically on any kind of file system, even network based ones.\nThe lockfile path is based on the file path you are trying to lock by suffixing it with `.lock`.\n\nWhen a lock is successfully acquired, the lockfile's `mtime` (modified time) is periodically updated to prevent staleness. This allows to effectively check if a lock is stale by checking its `mtime` against a stale threshold. If the update of the mtime fails several times, the lock might be compromised. The `mtime` is [supported](http://en.wikipedia.org/wiki/Comparison_of_file_systems) in almost every `filesystem`.\n\n\n### Comparison\n\nThis library is similar to [lockfile](https://github.com/isaacs/lockfile) but the latter has some drawbacks:\n\n- It relies on `open` with `O_EXCL` flag which has problems in network file systems. `proper-lockfile` uses `mkdir` which doesn't have this issue.\n\n\u003e O_EXCL is broken on NFS file systems; programs which rely on it for performing locking tasks will contain a race condition.\n\n- The lockfile staleness check is done via `ctime` (creation time) which is unsuitable for long running processes. `proper-lockfile` constantly updates lockfiles `mtime` to do proper staleness check.\n\n- It does not check if the lockfile was compromised which can lead to undesirable situations. `proper-lockfile` checks the lockfile when updating the `mtime`.\n\n- It has a default value of `0` for the stale option which isn't good because any crash or process kill that the package can't handle gracefully will leave the lock active forever.\n\n\n### Compromised\n\n`proper-lockfile` does not detect cases in which:\n\n- A `lockfile` is manually removed and someone else acquires the lock right after\n- Different `stale`/`update` values are being used for the same file, possibly causing two locks to be acquired on the same file\n\n`proper-lockfile` detects cases in which:\n\n- Updates to the `lockfile` fail\n- Updates take longer than expected, possibly causing the lock to become stale for a certain amount of time\n\n\nAs you see, the first two are a consequence of bad usage. Technically, it was possible to detect the first two but it would introduce complexity and eventual race conditions.\n\n\n## Usage\n\n### .lock(file, [options])\n\nTries to acquire a lock on `file` or rejects the promise on error.\n\nIf the lock succeeds, a `release` function is provided that should be called when you want to release the lock. The `release` function also rejects the promise on error (e.g. when the lock was already compromised).\n\nAvailable options:\n\n- `stale`: Duration in milliseconds in which the lock is considered stale, defaults to `10000` (minimum value is `5000`)\n- `update`: The interval in milliseconds in which the lockfile's `mtime` will be updated, defaults to `stale/2` (minimum value is `1000`, maximum value is `stale/2`)\n- `retries`: The number of retries or a [retry](https://www.npmjs.org/package/retry) options object, defaults to `0`\n- `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)\n- `fs`: A custom fs to use, defaults to `graceful-fs`\n- `onCompromised`: Called if the lock gets compromised, defaults to a function that simply throws the error which will probably cause the process to die\n- `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `\u003cdir path\u003e` and `options.lockfilePath` as `\u003cdir path\u003e/dir.lock`\n\n\n```js\nconst lockfile = require('proper-lockfile');\n\nlockfile.lock('some/file')\n.then((release) =\u003e {\n    // Do something while the file is locked\n\n    // Call the provided release function when you're done,\n    // which will also return a promise\n    return release();\n})\n.catch((e) =\u003e {\n    // either lock could not be acquired\n    // or releasing it failed\n    console.error(e)\n});\n\n// Alternatively, you may use lockfile('some/file') directly.\n```\n\n\n### .unlock(file, [options])\n\nReleases a previously acquired lock on `file` or rejects the promise on error.\n\nWhenever possible you should use the `release` function instead (as exemplified above). Still there are cases in which it's hard to keep a reference to it around code. In those cases `unlock()` might be handy.\n\nAvailable options:\n\n- `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)\n- `fs`: A custom fs to use, defaults to `graceful-fs`\n- `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `\u003cdir path\u003e` and `options.lockfilePath` as `\u003cdir path\u003e/dir.lock`\n\n\n```js\nconst lockfile = require('proper-lockfile');\n\nlockfile.lock('some/file')\n.then(() =\u003e {\n    // Do something while the file is locked\n\n    // Later..\n    return lockfile.unlock('some/file');\n});\n```\n\n### .check(file, [options])\n\nCheck if the file is locked and its lockfile is not stale, rejects the promise on error.\n\nAvailable options:\n\n- `stale`: Duration in milliseconds in which the lock is considered stale, defaults to `10000` (minimum value is `5000`)\n- `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)\n- `fs`: A custom fs to use, defaults to `graceful-fs`\n- `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `\u003cdir path\u003e` and `options.lockfilePath` as `\u003cdir path\u003e/dir.lock`\n\n\n```js\nconst lockfile = require('proper-lockfile');\n\nlockfile.check('some/file')\n.then((isLocked) =\u003e {\n    // isLocked will be true if 'some/file' is locked, false otherwise\n});\n```\n\n### .lockSync(file, [options])\n\nSync version of `.lock()`.   \nReturns the `release` function or throws on error.\n\n### .unlockSync(file, [options])\n\nSync version of `.unlock()`.   \nThrows on error.\n\n### .checkSync(file, [options])\n\nSync version of `.check()`.\nReturns a boolean or throws on error.\n\n\n## Graceful exit\n\n`proper-lockfile` automatically removes locks if the process exits, except if the process is killed with SIGKILL or it crashes due to a VM fatal error (e.g.: out of memory).\n\n\n## Tests\n\n`$ npm test`   \n`$ npm test -- --watch` during development\n\nThe test suite is very extensive. There's even a stress test to guarantee exclusiveness of locks.\n\n\n## License\n\nReleased under the [MIT License](https://www.opensource.org/licenses/mit-license.php).\n","funding_links":[],"categories":["Packages","Uncategorized","包"],"sub_categories":["Filesystem","Uncategorized","文件系统"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fnode-proper-lockfile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoxystudio%2Fnode-proper-lockfile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoxystudio%2Fnode-proper-lockfile/lists"}