@bybrave/proper-lockfile2

中文文档
5.1.0发布于 2026/10/14MITTypeScriptCommonJS近 30 天下载 5.6万

Maintained fork of proper-lockfile — an inter-process and inter-machine lockfile utility that works on a local or network file system

原始使用文档
文档目录10 节
  1. Why this fork
  2. The race, in short
  3. Install
  4. Usage
  5. API
  6. lock(file, [options]) → Promise<release>
  7. unlock(file, [options]) / check(file, [options]) → Promise
  8. Migrating from proper-lockfile
  9. Support
  10. Credits & license

@bybrave/proper-lockfile2

CI npm node types license

Maintained fork of proper-lockfile — an inter-process and inter-machine lockfile utility that works on a local or network file system.

Why this fork

The original proper-lockfile has not been released since 2021. This fork is a drop-in replacement that fixes a real double-lock race and ships the most requested features:

ChangeUpstream issue
Stale-lock reclaim race fixed: two processes could both "reclaim" the same stale lock and end up holding it simultaneously#121, root cause of many #92 reports
onReclaimed callback: know when your lock was acquired by reclaiming a stale one (e.g. to run crash recovery exactly once)#105
ELOCKED error message now hints at the retries option — the most common source of confusion#92
Ctrl-C and SIGTERM keep working: the exit handler is installed on the first acquired lock, not on require#111, #110
No Cannot read properties of undefined (reading 'updateTimeout') crash when a lock is released while an mtime update is being retried#113
onCompromised: undefined / null keeps the default handler instead of crashing#117
mtime precision is detected per device, so locks on filesystems with different precision work in one process#104
TypeScript type definitions included—
Updated dependencies, CI on Node 18/20/22, original test suite preserved (76 tests) + regression tests for every fix—

The race, in short

Upstream reclaims a stale lock with rmdir + mkdir. If process A detects a stale lock but stalls before its rmdir, process B can reclaim the lock and create a fresh one — which A's late rmdir then silently deletes, and both processes believe they own the lock. This fork claims stale locks by atomically renaming them to a unique path (only one process can win a rename) and verifies the claimed directory is still the stale one it saw. A reproduction script and regression tests are in test/fork.test.js.

Install

npm install @bybrave/proper-lockfile2

Usage

const lockfile = require('@bybrave/proper-lockfile2');

const release = await lockfile.lock('some/file');
// do your critical work...
await release();

Wait for a held lock instead of failing:

const release = await lockfile.lock('some/file', {
  retries: { retries: 5, maxTimeout: 1000 },
});

Run crash recovery when a stale lock (left by a dead process) is reclaimed:

const release = await lockfile.lock('some/file', {
  onReclaimed: () => runRecovery(),
});

Sync API: lockSync, unlockSync, checkSync (retries are not supported in sync mode).

API

lock(file, [options]) → Promise<release>

Acquires a lock on file, resolving with a release() function. Rejects with ELOCKED if the lock is held (and not stale).

OptionDefaultDescription
stale10000Ms after which a non-updated lock is considered stale (min 2000)
updatestale/2Interval of lockfile mtime refresh (min 1000, max stale/2)
retries0Number of retries (or a node-retry options object) while acquiring a held lock
realpathtrueResolve symlinks; set false to lock the symlink itself (also allows locking non-existing paths)
onCompromised(err) => { throw err; }Called when the lock can no longer be guaranteed
onReclaimed—Called when the lock was acquired by reclaiming a stale lockfile
lockfilePath${file}.lockCustom lockfile location
fsgraceful-fsCustom fs implementation

Locking a file that does not exist yet

With the default realpath: true the file must exist, because realpath resolves symlinks of the full path. This also shows up when locking a not-yet-created file under a symlinked directory such as /tmp on macOS (it points to /private/tmp), with ENOENT (#100, #99).

Either create the file first, or pass realpath: false. The trade-off of realpath: false: the lock is keyed by the path as written, so two processes that reach the same file through different symlinks (/tmp/foo and /private/tmp/foo) will not see each other's lock. Use one canonical path in all processes, e.g. fs.realpathSync(dir) + '/file' for a directory that exists.

unlock(file, [options]) / check(file, [options]) → Promise

Same semantics as the original: unlock releases a lock acquired in this process, check resolves with whether the file is currently locked. Options: stale (check only), realpath, lockfilePath, fs.

Full conceptual documentation (how mtime-based locking works, its guarantees and caveats) is in the original README — the design is unchanged.

Migrating from proper-lockfile

It is a drop-in replacement:

- const lockfile = require('proper-lockfile');
+ const lockfile = require('@bybrave/proper-lockfile2');

No API was removed or changed; onReclaimed is the only new option. Unlike the original, requiring the module no longer subscribes to process signals until a lock is acquired.

Support

If this package saves you time, you can support maintenance:

Ko-fi Bitcoin

Bitcoin (BTC): bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q

Credits & license

MIT. Based on proper-lockfile by André Cruz / MOXY.

版本与发布记录

@bybrave/proper-lockfile2 共发布 2 个版本,首次发布于 2026/07/05;过去 12 个月发布了 2 个版本。

版本发布日期距今
5.1.0latest2026/10/1425 天前
5.0.02026/07/054 个月前

关于 @bybrave/proper-lockfile2 的常见问题

@bybrave/proper-lockfile2 是什么?

Maintained fork of proper-lockfile — an inter-process and inter-machine lockfile utility that works on a local or network file system

如何安装 @bybrave/proper-lockfile2?

在项目目录运行 npm install @bybrave/proper-lockfile2,或使用 pnpm add / yarn add / bun add。

@bybrave/proper-lockfile2 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bybrave/proper-lockfile2 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@bybrave/proper-lockfile2 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@bybrave/proper-lockfile2 可以商用吗?

@bybrave/proper-lockfile2 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bybrave/proper-lockfile2 的下载量有多少?

根据 npm 官方下载统计,@bybrave/proper-lockfile2 在 2026/10/09 – 2026/11/07 这 30 天内被下载 55,734 次,日均约 1,858 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bybrave/proper-lockfile2 还在维护吗?

最新版本 5.1.0 发布于 2026/10/14(25 天前);至今共发布 2 个版本,其中过去 12 个月发布了 2 个;首次发布于 2026/07/05。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。