atomic-lockfile 0.0.1-security → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of atomic-lockfile might be problematic. Click here for more details.
- package/CHANGELOG.md +35 -0
- package/LICENSE +21 -0
- package/README.md +207 -3
- package/dist/esm/adapters/atomic.js +42 -0
- package/dist/esm/adapters/atomic.js.map +1 -0
- package/dist/esm/adapters/fs.js +29 -0
- package/dist/esm/adapters/fs.js.map +1 -0
- package/dist/esm/adapters/index.js +27 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/mkdir.js +31 -0
- package/dist/esm/adapters/mkdir.js.map +1 -0
- package/dist/esm/adapters/symlink.js +29 -0
- package/dist/esm/adapters/symlink.js.map +1 -0
- package/dist/esm/async/check.js +11 -0
- package/dist/esm/async/check.js.map +1 -0
- package/dist/esm/async/index.js +4 -0
- package/dist/esm/async/index.js.map +1 -0
- package/dist/esm/async/lock.js +13 -0
- package/dist/esm/async/lock.js.map +1 -0
- package/dist/esm/async/unlock.js +8 -0
- package/dist/esm/async/unlock.js.map +1 -0
- package/dist/esm/cli/commands/cleanup.js +28 -0
- package/dist/esm/cli/commands/cleanup.js.map +1 -0
- package/dist/esm/cli/commands/list.js +26 -0
- package/dist/esm/cli/commands/list.js.map +1 -0
- package/dist/esm/cli/commands/lock.js +26 -0
- package/dist/esm/cli/commands/lock.js.map +1 -0
- package/dist/esm/cli/commands/status.js +27 -0
- package/dist/esm/cli/commands/status.js.map +1 -0
- package/dist/esm/cli/commands/unlock.js +20 -0
- package/dist/esm/cli/commands/unlock.js.map +1 -0
- package/dist/esm/cli/formatters/index.js +14 -0
- package/dist/esm/cli/formatters/index.js.map +1 -0
- package/dist/esm/cli/formatters/json.js +15 -0
- package/dist/esm/cli/formatters/json.js.map +1 -0
- package/dist/esm/cli/formatters/table.js +18 -0
- package/dist/esm/cli/formatters/table.js.map +1 -0
- package/dist/esm/cli/formatters/text.js +20 -0
- package/dist/esm/cli/formatters/text.js.map +1 -0
- package/dist/esm/cli/index.js +56 -0
- package/dist/esm/cli/index.js.map +1 -0
- package/dist/esm/compat/cjs.js +11 -0
- package/dist/esm/compat/cjs.js.map +1 -0
- package/dist/esm/compat/esm.js +11 -0
- package/dist/esm/compat/esm.js.map +1 -0
- package/dist/esm/compat/index.js +4 -0
- package/dist/esm/compat/index.js.map +1 -0
- package/dist/esm/compat/v1.js +23 -0
- package/dist/esm/compat/v1.js.map +1 -0
- package/dist/esm/config/defaults.js +12 -0
- package/dist/esm/config/defaults.js.map +1 -0
- package/dist/esm/config/index.js +17 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/config/schema.js +55 -0
- package/dist/esm/config/schema.js.map +1 -0
- package/dist/esm/constants/defaults.js +15 -0
- package/dist/esm/constants/defaults.js.map +1 -0
- package/dist/esm/constants/errors.js +37 -0
- package/dist/esm/constants/errors.js.map +1 -0
- package/dist/esm/constants/index.js +14 -0
- package/dist/esm/constants/index.js.map +1 -0
- package/dist/esm/constants/signals.js +21 -0
- package/dist/esm/constants/signals.js.map +1 -0
- package/dist/esm/constants/timeouts.js +16 -0
- package/dist/esm/constants/timeouts.js.map +1 -0
- package/dist/esm/core/acquire.js +51 -0
- package/dist/esm/core/acquire.js.map +1 -0
- package/dist/esm/core/buildLockData.js +23 -0
- package/dist/esm/core/buildLockData.js.map +1 -0
- package/dist/esm/core/check.js +62 -0
- package/dist/esm/core/check.js.map +1 -0
- package/dist/esm/core/cleanup.js +45 -0
- package/dist/esm/core/cleanup.js.map +1 -0
- package/dist/esm/core/handle.js +43 -0
- package/dist/esm/core/handle.js.map +1 -0
- package/dist/esm/core/index.js +8 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/list.js +38 -0
- package/dist/esm/core/list.js.map +1 -0
- package/dist/esm/core/release.js +21 -0
- package/dist/esm/core/release.js.map +1 -0
- package/dist/esm/errors/AbortError.js +18 -0
- package/dist/esm/errors/AbortError.js.map +1 -0
- package/dist/esm/errors/ConflictError.js +20 -0
- package/dist/esm/errors/ConflictError.js.map +1 -0
- package/dist/esm/errors/IOError.js +24 -0
- package/dist/esm/errors/IOError.js.map +1 -0
- package/dist/esm/errors/LockError.js +30 -0
- package/dist/esm/errors/LockError.js.map +1 -0
- package/dist/esm/errors/PermissionError.js +21 -0
- package/dist/esm/errors/PermissionError.js.map +1 -0
- package/dist/esm/errors/StaleError.js +27 -0
- package/dist/esm/errors/StaleError.js.map +1 -0
- package/dist/esm/errors/TimeoutError.js +21 -0
- package/dist/esm/errors/TimeoutError.js.map +1 -0
- package/dist/esm/errors/ValidationError.js +21 -0
- package/dist/esm/errors/ValidationError.js.map +1 -0
- package/dist/esm/errors/index.js +24 -0
- package/dist/esm/errors/index.js.map +1 -0
- package/dist/esm/events/emitter.js +41 -0
- package/dist/esm/events/emitter.js.map +1 -0
- package/dist/esm/events/index.js +3 -0
- package/dist/esm/events/index.js.map +1 -0
- package/dist/esm/events/types.js +15 -0
- package/dist/esm/events/types.js.map +1 -0
- package/dist/esm/hooks/afterLock.js +18 -0
- package/dist/esm/hooks/afterLock.js.map +1 -0
- package/dist/esm/hooks/afterUnlock.js +18 -0
- package/dist/esm/hooks/afterUnlock.js.map +1 -0
- package/dist/esm/hooks/beforeLock.js +18 -0
- package/dist/esm/hooks/beforeLock.js.map +1 -0
- package/dist/esm/hooks/beforeUnlock.js +18 -0
- package/dist/esm/hooks/beforeUnlock.js.map +1 -0
- package/dist/esm/hooks/index.js +24 -0
- package/dist/esm/hooks/index.js.map +1 -0
- package/dist/esm/hooks/onError.js +18 -0
- package/dist/esm/hooks/onError.js.map +1 -0
- package/dist/esm/hooks/onStale.js +18 -0
- package/dist/esm/hooks/onStale.js.map +1 -0
- package/dist/esm/hooks/onTimeout.js +18 -0
- package/dist/esm/hooks/onTimeout.js.map +1 -0
- package/dist/esm/index.js +21 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger/console.js +38 -0
- package/dist/esm/logger/console.js.map +1 -0
- package/dist/esm/logger/debug.js +26 -0
- package/dist/esm/logger/debug.js.map +1 -0
- package/dist/esm/logger/index.js +15 -0
- package/dist/esm/logger/index.js.map +1 -0
- package/dist/esm/logger/noop.js +12 -0
- package/dist/esm/logger/noop.js.map +1 -0
- package/dist/esm/meta/index.js +3 -0
- package/dist/esm/meta/index.js.map +1 -0
- package/dist/esm/meta/package.js +27 -0
- package/dist/esm/meta/package.js.map +1 -0
- package/dist/esm/meta/version.js +27 -0
- package/dist/esm/meta/version.js.map +1 -0
- package/dist/esm/middleware/index.js +11 -0
- package/dist/esm/middleware/index.js.map +1 -0
- package/dist/esm/middleware/logging.js +20 -0
- package/dist/esm/middleware/logging.js.map +1 -0
- package/dist/esm/middleware/metrics.js +32 -0
- package/dist/esm/middleware/metrics.js.map +1 -0
- package/dist/esm/middleware/retry.js +22 -0
- package/dist/esm/middleware/retry.js.map +1 -0
- package/dist/esm/middleware/timeout.js +28 -0
- package/dist/esm/middleware/timeout.js.map +1 -0
- package/dist/esm/platform/darwin.js +17 -0
- package/dist/esm/platform/darwin.js.map +1 -0
- package/dist/esm/platform/index.js +6 -0
- package/dist/esm/platform/index.js.map +1 -0
- package/dist/esm/platform/linux.js +31 -0
- package/dist/esm/platform/linux.js.map +1 -0
- package/dist/esm/platform/unix.js +34 -0
- package/dist/esm/platform/unix.js.map +1 -0
- package/dist/esm/platform/windows.js +22 -0
- package/dist/esm/platform/windows.js.map +1 -0
- package/dist/esm/plugins/cleanup.js +39 -0
- package/dist/esm/plugins/cleanup.js.map +1 -0
- package/dist/esm/plugins/heartbeat.js +31 -0
- package/dist/esm/plugins/heartbeat.js.map +1 -0
- package/dist/esm/plugins/index.js +6 -0
- package/dist/esm/plugins/index.js.map +1 -0
- package/dist/esm/plugins/pid.js +25 -0
- package/dist/esm/plugins/pid.js.map +1 -0
- package/dist/esm/plugins/stale.js +21 -0
- package/dist/esm/plugins/stale.js.map +1 -0
- package/dist/esm/plugins/ttl.js +28 -0
- package/dist/esm/plugins/ttl.js.map +1 -0
- package/dist/esm/promise/index.js +3 -0
- package/dist/esm/promise/index.js.map +1 -0
- package/dist/esm/promise/lock.js +13 -0
- package/dist/esm/promise/lock.js.map +1 -0
- package/dist/esm/promise/withLock.js +22 -0
- package/dist/esm/promise/withLock.js.map +1 -0
- package/dist/esm/registry/global.js +29 -0
- package/dist/esm/registry/global.js.map +1 -0
- package/dist/esm/registry/index.js +3 -0
- package/dist/esm/registry/index.js.map +1 -0
- package/dist/esm/registry/local.js +28 -0
- package/dist/esm/registry/local.js.map +1 -0
- package/dist/esm/strategies/advisory.js +19 -0
- package/dist/esm/strategies/advisory.js.map +1 -0
- package/dist/esm/strategies/exclusive.js +19 -0
- package/dist/esm/strategies/exclusive.js.map +1 -0
- package/dist/esm/strategies/index.js +27 -0
- package/dist/esm/strategies/index.js.map +1 -0
- package/dist/esm/strategies/optimistic.js +22 -0
- package/dist/esm/strategies/optimistic.js.map +1 -0
- package/dist/esm/strategies/shared.js +19 -0
- package/dist/esm/strategies/shared.js.map +1 -0
- package/dist/esm/sync/check.js +39 -0
- package/dist/esm/sync/check.js.map +1 -0
- package/dist/esm/sync/index.js +4 -0
- package/dist/esm/sync/index.js.map +1 -0
- package/dist/esm/sync/lock.js +39 -0
- package/dist/esm/sync/lock.js.map +1 -0
- package/dist/esm/sync/unlock.js +21 -0
- package/dist/esm/sync/unlock.js.map +1 -0
- package/dist/esm/types/adapter.js +2 -0
- package/dist/esm/types/adapter.js.map +1 -0
- package/dist/esm/types/events.js +2 -0
- package/dist/esm/types/events.js.map +1 -0
- package/dist/esm/types/index.js +2 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/lock.js +2 -0
- package/dist/esm/types/lock.js.map +1 -0
- package/dist/esm/types/logger.js +2 -0
- package/dist/esm/types/logger.js.map +1 -0
- package/dist/esm/types/options.js +2 -0
- package/dist/esm/types/options.js.map +1 -0
- package/dist/esm/types/state.js +2 -0
- package/dist/esm/types/state.js.map +1 -0
- package/dist/esm/types/strategy.js +2 -0
- package/dist/esm/types/strategy.js.map +1 -0
- package/dist/esm/utils/backoff.js +40 -0
- package/dist/esm/utils/backoff.js.map +1 -0
- package/dist/esm/utils/fs.js +88 -0
- package/dist/esm/utils/fs.js.map +1 -0
- package/dist/esm/utils/hash.js +20 -0
- package/dist/esm/utils/hash.js.map +1 -0
- package/dist/esm/utils/hostname.js +28 -0
- package/dist/esm/utils/hostname.js.map +1 -0
- package/dist/esm/utils/index.js +14 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/esm/utils/parse.js +44 -0
- package/dist/esm/utils/parse.js.map +1 -0
- package/dist/esm/utils/path.js +35 -0
- package/dist/esm/utils/path.js.map +1 -0
- package/dist/esm/utils/pid.js +35 -0
- package/dist/esm/utils/pid.js.map +1 -0
- package/dist/esm/utils/platform.js +35 -0
- package/dist/esm/utils/platform.js.map +1 -0
- package/dist/esm/utils/random.js +26 -0
- package/dist/esm/utils/random.js.map +1 -0
- package/dist/esm/utils/retry.js +37 -0
- package/dist/esm/utils/retry.js.map +1 -0
- package/dist/esm/utils/serialize.js +27 -0
- package/dist/esm/utils/serialize.js.map +1 -0
- package/dist/esm/utils/time.js +44 -0
- package/dist/esm/utils/time.js.map +1 -0
- package/dist/esm/utils/validate.js +42 -0
- package/dist/esm/utils/validate.js.map +1 -0
- package/dist/types/adapters/atomic.d.ts +3 -0
- package/dist/types/adapters/atomic.d.ts.map +1 -0
- package/dist/types/adapters/fs.d.ts +3 -0
- package/dist/types/adapters/fs.d.ts.map +1 -0
- package/dist/types/adapters/index.d.ts +9 -0
- package/dist/types/adapters/index.d.ts.map +1 -0
- package/dist/types/adapters/mkdir.d.ts +3 -0
- package/dist/types/adapters/mkdir.d.ts.map +1 -0
- package/dist/types/adapters/symlink.d.ts +3 -0
- package/dist/types/adapters/symlink.d.ts.map +1 -0
- package/dist/types/async/check.d.ts +6 -0
- package/dist/types/async/check.d.ts.map +1 -0
- package/dist/types/async/index.d.ts +4 -0
- package/dist/types/async/index.d.ts.map +1 -0
- package/dist/types/async/lock.d.ts +5 -0
- package/dist/types/async/lock.d.ts.map +1 -0
- package/dist/types/async/unlock.d.ts +5 -0
- package/dist/types/async/unlock.d.ts.map +1 -0
- package/dist/types/cli/commands/cleanup.d.ts +2 -0
- package/dist/types/cli/commands/cleanup.d.ts.map +1 -0
- package/dist/types/cli/commands/list.d.ts +2 -0
- package/dist/types/cli/commands/list.d.ts.map +1 -0
- package/dist/types/cli/commands/lock.d.ts +2 -0
- package/dist/types/cli/commands/lock.d.ts.map +1 -0
- package/dist/types/cli/commands/status.d.ts +2 -0
- package/dist/types/cli/commands/status.d.ts.map +1 -0
- package/dist/types/cli/commands/unlock.d.ts +2 -0
- package/dist/types/cli/commands/unlock.d.ts.map +1 -0
- package/dist/types/cli/formatters/index.d.ts +7 -0
- package/dist/types/cli/formatters/index.d.ts.map +1 -0
- package/dist/types/cli/formatters/json.d.ts +5 -0
- package/dist/types/cli/formatters/json.d.ts.map +1 -0
- package/dist/types/cli/formatters/table.d.ts +3 -0
- package/dist/types/cli/formatters/table.d.ts.map +1 -0
- package/dist/types/cli/formatters/text.d.ts +6 -0
- package/dist/types/cli/formatters/text.d.ts.map +1 -0
- package/dist/types/cli/index.d.ts +3 -0
- package/dist/types/cli/index.d.ts.map +1 -0
- package/dist/types/compat/cjs.d.ts +11 -0
- package/dist/types/compat/cjs.d.ts.map +1 -0
- package/dist/types/compat/esm.d.ts +11 -0
- package/dist/types/compat/esm.d.ts.map +1 -0
- package/dist/types/compat/index.d.ts +4 -0
- package/dist/types/compat/index.d.ts.map +1 -0
- package/dist/types/compat/v1.d.ts +15 -0
- package/dist/types/compat/v1.d.ts.map +1 -0
- package/dist/types/config/defaults.d.ts +3 -0
- package/dist/types/config/defaults.d.ts.map +1 -0
- package/dist/types/config/index.d.ts +9 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/config/schema.d.ts +12 -0
- package/dist/types/config/schema.d.ts.map +1 -0
- package/dist/types/constants/defaults.d.ts +15 -0
- package/dist/types/constants/defaults.d.ts.map +1 -0
- package/dist/types/constants/errors.d.ts +21 -0
- package/dist/types/constants/errors.d.ts.map +1 -0
- package/dist/types/constants/index.d.ts +14 -0
- package/dist/types/constants/index.d.ts.map +1 -0
- package/dist/types/constants/signals.d.ts +6 -0
- package/dist/types/constants/signals.d.ts.map +1 -0
- package/dist/types/constants/timeouts.d.ts +16 -0
- package/dist/types/constants/timeouts.d.ts.map +1 -0
- package/dist/types/core/acquire.d.ts +4 -0
- package/dist/types/core/acquire.d.ts.map +1 -0
- package/dist/types/core/buildLockData.d.ts +4 -0
- package/dist/types/core/buildLockData.d.ts.map +1 -0
- package/dist/types/core/check.d.ts +6 -0
- package/dist/types/core/check.d.ts.map +1 -0
- package/dist/types/core/cleanup.d.ts +14 -0
- package/dist/types/core/cleanup.d.ts.map +1 -0
- package/dist/types/core/handle.d.ts +4 -0
- package/dist/types/core/handle.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +9 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/core/list.d.ts +4 -0
- package/dist/types/core/list.d.ts.map +1 -0
- package/dist/types/core/release.d.ts +4 -0
- package/dist/types/core/release.d.ts.map +1 -0
- package/dist/types/errors/AbortError.d.ts +8 -0
- package/dist/types/errors/AbortError.d.ts.map +1 -0
- package/dist/types/errors/ConflictError.d.ts +9 -0
- package/dist/types/errors/ConflictError.d.ts.map +1 -0
- package/dist/types/errors/IOError.d.ts +10 -0
- package/dist/types/errors/IOError.d.ts.map +1 -0
- package/dist/types/errors/LockError.d.ts +12 -0
- package/dist/types/errors/LockError.d.ts.map +1 -0
- package/dist/types/errors/PermissionError.d.ts +9 -0
- package/dist/types/errors/PermissionError.d.ts.map +1 -0
- package/dist/types/errors/StaleError.d.ts +11 -0
- package/dist/types/errors/StaleError.d.ts.map +1 -0
- package/dist/types/errors/TimeoutError.d.ts +9 -0
- package/dist/types/errors/TimeoutError.d.ts.map +1 -0
- package/dist/types/errors/ValidationError.d.ts +9 -0
- package/dist/types/errors/ValidationError.d.ts.map +1 -0
- package/dist/types/errors/index.d.ts +14 -0
- package/dist/types/errors/index.d.ts.map +1 -0
- package/dist/types/events/emitter.d.ts +12 -0
- package/dist/types/events/emitter.d.ts.map +1 -0
- package/dist/types/events/index.d.ts +3 -0
- package/dist/types/events/index.d.ts.map +1 -0
- package/dist/types/events/types.d.ts +3 -0
- package/dist/types/events/types.d.ts.map +1 -0
- package/dist/types/hooks/afterLock.d.ts +7 -0
- package/dist/types/hooks/afterLock.d.ts.map +1 -0
- package/dist/types/hooks/afterUnlock.d.ts +7 -0
- package/dist/types/hooks/afterUnlock.d.ts.map +1 -0
- package/dist/types/hooks/beforeLock.d.ts +7 -0
- package/dist/types/hooks/beforeLock.d.ts.map +1 -0
- package/dist/types/hooks/beforeUnlock.d.ts +7 -0
- package/dist/types/hooks/beforeUnlock.d.ts.map +1 -0
- package/dist/types/hooks/index.d.ts +9 -0
- package/dist/types/hooks/index.d.ts.map +1 -0
- package/dist/types/hooks/onError.d.ts +6 -0
- package/dist/types/hooks/onError.d.ts.map +1 -0
- package/dist/types/hooks/onStale.d.ts +7 -0
- package/dist/types/hooks/onStale.d.ts.map +1 -0
- package/dist/types/hooks/onTimeout.d.ts +6 -0
- package/dist/types/hooks/onTimeout.d.ts.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logger/console.d.ts +3 -0
- package/dist/types/logger/console.d.ts.map +1 -0
- package/dist/types/logger/debug.d.ts +3 -0
- package/dist/types/logger/debug.d.ts.map +1 -0
- package/dist/types/logger/index.d.ts +8 -0
- package/dist/types/logger/index.d.ts.map +1 -0
- package/dist/types/logger/noop.d.ts +3 -0
- package/dist/types/logger/noop.d.ts.map +1 -0
- package/dist/types/meta/index.d.ts +3 -0
- package/dist/types/meta/index.d.ts.map +1 -0
- package/dist/types/meta/package.d.ts +8 -0
- package/dist/types/meta/package.d.ts.map +1 -0
- package/dist/types/meta/version.d.ts +14 -0
- package/dist/types/meta/version.d.ts.map +1 -0
- package/dist/types/middleware/index.d.ts +10 -0
- package/dist/types/middleware/index.d.ts.map +1 -0
- package/dist/types/middleware/logging.d.ts +3 -0
- package/dist/types/middleware/logging.d.ts.map +1 -0
- package/dist/types/middleware/metrics.d.ts +13 -0
- package/dist/types/middleware/metrics.d.ts.map +1 -0
- package/dist/types/middleware/retry.d.ts +5 -0
- package/dist/types/middleware/retry.d.ts.map +1 -0
- package/dist/types/middleware/timeout.d.ts +7 -0
- package/dist/types/middleware/timeout.d.ts.map +1 -0
- package/dist/types/platform/darwin.d.ts +5 -0
- package/dist/types/platform/darwin.d.ts.map +1 -0
- package/dist/types/platform/index.d.ts +6 -0
- package/dist/types/platform/index.d.ts.map +1 -0
- package/dist/types/platform/linux.d.ts +6 -0
- package/dist/types/platform/linux.d.ts.map +1 -0
- package/dist/types/platform/unix.d.ts +8 -0
- package/dist/types/platform/unix.d.ts.map +1 -0
- package/dist/types/platform/windows.d.ts +7 -0
- package/dist/types/platform/windows.d.ts.map +1 -0
- package/dist/types/plugins/cleanup.d.ts +4 -0
- package/dist/types/plugins/cleanup.d.ts.map +1 -0
- package/dist/types/plugins/heartbeat.d.ts +7 -0
- package/dist/types/plugins/heartbeat.d.ts.map +1 -0
- package/dist/types/plugins/index.d.ts +8 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/plugins/pid.d.ts +5 -0
- package/dist/types/plugins/pid.d.ts.map +1 -0
- package/dist/types/plugins/stale.d.ts +9 -0
- package/dist/types/plugins/stale.d.ts.map +1 -0
- package/dist/types/plugins/ttl.d.ts +7 -0
- package/dist/types/plugins/ttl.d.ts.map +1 -0
- package/dist/types/promise/index.d.ts +3 -0
- package/dist/types/promise/index.d.ts.map +1 -0
- package/dist/types/promise/lock.d.ts +6 -0
- package/dist/types/promise/lock.d.ts.map +1 -0
- package/dist/types/promise/withLock.d.ts +7 -0
- package/dist/types/promise/withLock.d.ts.map +1 -0
- package/dist/types/registry/global.d.ts +15 -0
- package/dist/types/registry/global.d.ts.map +1 -0
- package/dist/types/registry/index.d.ts +3 -0
- package/dist/types/registry/index.d.ts.map +1 -0
- package/dist/types/registry/local.d.ts +10 -0
- package/dist/types/registry/local.d.ts.map +1 -0
- package/dist/types/strategies/advisory.d.ts +4 -0
- package/dist/types/strategies/advisory.d.ts.map +1 -0
- package/dist/types/strategies/exclusive.d.ts +4 -0
- package/dist/types/strategies/exclusive.d.ts.map +1 -0
- package/dist/types/strategies/index.d.ts +9 -0
- package/dist/types/strategies/index.d.ts.map +1 -0
- package/dist/types/strategies/optimistic.d.ts +8 -0
- package/dist/types/strategies/optimistic.d.ts.map +1 -0
- package/dist/types/strategies/shared.d.ts +4 -0
- package/dist/types/strategies/shared.d.ts.map +1 -0
- package/dist/types/sync/check.d.ts +4 -0
- package/dist/types/sync/check.d.ts.map +1 -0
- package/dist/types/sync/index.d.ts +4 -0
- package/dist/types/sync/index.d.ts.map +1 -0
- package/dist/types/sync/lock.d.ts +7 -0
- package/dist/types/sync/lock.d.ts.map +1 -0
- package/dist/types/sync/unlock.d.ts +3 -0
- package/dist/types/sync/unlock.d.ts.map +1 -0
- package/dist/types/types/adapter.d.ts +21 -0
- package/dist/types/types/adapter.d.ts.map +1 -0
- package/dist/types/types/events.d.ts +37 -0
- package/dist/types/types/events.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +8 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/lock.d.ts +38 -0
- package/dist/types/types/lock.d.ts.map +1 -0
- package/dist/types/types/logger.d.ts +21 -0
- package/dist/types/types/logger.d.ts.map +1 -0
- package/dist/types/types/options.d.ts +52 -0
- package/dist/types/types/options.d.ts.map +1 -0
- package/dist/types/types/state.d.ts +34 -0
- package/dist/types/types/state.d.ts.map +1 -0
- package/dist/types/types/strategy.d.ts +24 -0
- package/dist/types/types/strategy.d.ts.map +1 -0
- package/dist/types/utils/backoff.d.ts +6 -0
- package/dist/types/utils/backoff.d.ts.map +1 -0
- package/dist/types/utils/fs.d.ts +12 -0
- package/dist/types/utils/fs.d.ts.map +1 -0
- package/dist/types/utils/hash.d.ts +7 -0
- package/dist/types/utils/hash.d.ts.map +1 -0
- package/dist/types/utils/hostname.d.ts +9 -0
- package/dist/types/utils/hostname.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +14 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/parse.d.ts +7 -0
- package/dist/types/utils/parse.d.ts.map +1 -0
- package/dist/types/utils/path.d.ts +10 -0
- package/dist/types/utils/path.d.ts.map +1 -0
- package/dist/types/utils/pid.d.ts +11 -0
- package/dist/types/utils/pid.d.ts.map +1 -0
- package/dist/types/utils/platform.d.ts +12 -0
- package/dist/types/utils/platform.d.ts.map +1 -0
- package/dist/types/utils/random.d.ts +7 -0
- package/dist/types/utils/random.d.ts.map +1 -0
- package/dist/types/utils/retry.d.ts +10 -0
- package/dist/types/utils/retry.d.ts.map +1 -0
- package/dist/types/utils/serialize.d.ts +7 -0
- package/dist/types/utils/serialize.d.ts.map +1 -0
- package/dist/types/utils/time.d.ts +12 -0
- package/dist/types/utils/time.d.ts.map +1 -0
- package/dist/types/utils/validate.d.ts +5 -0
- package/dist/types/utils/validate.d.ts.map +1 -0
- package/package.json +132 -3
- package/src/adapters/atomic.ts +39 -0
- package/src/adapters/fs.ts +30 -0
- package/src/adapters/index.ts +31 -0
- package/src/adapters/mkdir.ts +32 -0
- package/src/adapters/symlink.ts +30 -0
- package/src/async/check.ts +15 -0
- package/src/async/index.ts +3 -0
- package/src/async/lock.ts +15 -0
- package/src/async/unlock.ts +11 -0
- package/src/cli/commands/cleanup.ts +28 -0
- package/src/cli/commands/list.ts +27 -0
- package/src/cli/commands/lock.ts +27 -0
- package/src/cli/commands/status.ts +26 -0
- package/src/cli/commands/unlock.ts +20 -0
- package/src/cli/formatters/index.ts +18 -0
- package/src/cli/formatters/json.ts +18 -0
- package/src/cli/formatters/table.ts +26 -0
- package/src/cli/formatters/text.ts +22 -0
- package/src/cli/index.ts +61 -0
- package/src/compat/cjs.ts +11 -0
- package/src/compat/esm.ts +11 -0
- package/src/compat/index.ts +3 -0
- package/src/compat/v1.ts +35 -0
- package/src/config/defaults.ts +20 -0
- package/src/config/index.ts +24 -0
- package/src/config/schema.ts +66 -0
- package/src/constants/defaults.ts +14 -0
- package/src/constants/errors.ts +39 -0
- package/src/constants/index.ts +14 -0
- package/src/constants/signals.ts +26 -0
- package/src/constants/timeouts.ts +18 -0
- package/src/core/acquire.ts +54 -0
- package/src/core/buildLockData.ts +25 -0
- package/src/core/check.ts +66 -0
- package/src/core/cleanup.ts +53 -0
- package/src/core/handle.ts +62 -0
- package/src/core/index.ts +8 -0
- package/src/core/list.ts +38 -0
- package/src/core/release.ts +35 -0
- package/src/errors/AbortError.ts +25 -0
- package/src/errors/ConflictError.ts +28 -0
- package/src/errors/IOError.ts +39 -0
- package/src/errors/LockError.ts +39 -0
- package/src/errors/PermissionError.ts +35 -0
- package/src/errors/StaleError.ts +41 -0
- package/src/errors/TimeoutError.ts +28 -0
- package/src/errors/ValidationError.ts +28 -0
- package/src/errors/index.ts +28 -0
- package/src/events/emitter.ts +50 -0
- package/src/events/index.ts +2 -0
- package/src/events/types.ts +16 -0
- package/src/hooks/afterLock.ts +24 -0
- package/src/hooks/afterUnlock.ts +24 -0
- package/src/hooks/beforeLock.ts +28 -0
- package/src/hooks/beforeUnlock.ts +24 -0
- package/src/hooks/deps +0 -0
- package/src/hooks/index.ts +25 -0
- package/src/hooks/onError.ts +22 -0
- package/src/hooks/onStale.ts +24 -0
- package/src/hooks/onTimeout.ts +27 -0
- package/src/index.ts +25 -0
- package/src/logger/console.ts +39 -0
- package/src/logger/debug.ts +29 -0
- package/src/logger/index.ts +20 -0
- package/src/logger/noop.ts +13 -0
- package/src/meta/index.ts +2 -0
- package/src/meta/package.ts +29 -0
- package/src/meta/version.ts +26 -0
- package/src/middleware/index.ts +18 -0
- package/src/middleware/logging.ts +21 -0
- package/src/middleware/metrics.ts +44 -0
- package/src/middleware/retry.ts +25 -0
- package/src/middleware/timeout.ts +34 -0
- package/src/platform/darwin.ts +19 -0
- package/src/platform/index.ts +6 -0
- package/src/platform/linux.ts +32 -0
- package/src/platform/unix.ts +36 -0
- package/src/platform/windows.ts +26 -0
- package/src/plugins/cleanup.ts +45 -0
- package/src/plugins/heartbeat.ts +42 -0
- package/src/plugins/index.ts +7 -0
- package/src/plugins/pid.ts +26 -0
- package/src/plugins/stale.ts +33 -0
- package/src/plugins/ttl.ts +27 -0
- package/src/promise/index.ts +2 -0
- package/src/promise/lock.ts +23 -0
- package/src/promise/withLock.ts +30 -0
- package/src/registry/global.ts +39 -0
- package/src/registry/index.ts +11 -0
- package/src/registry/local.ts +37 -0
- package/src/strategies/advisory.ts +21 -0
- package/src/strategies/exclusive.ts +21 -0
- package/src/strategies/index.ts +31 -0
- package/src/strategies/optimistic.ts +29 -0
- package/src/strategies/shared.ts +23 -0
- package/src/sync/check.ts +43 -0
- package/src/sync/index.ts +3 -0
- package/src/sync/lock.ts +38 -0
- package/src/sync/unlock.ts +19 -0
- package/src/types/adapter.ts +23 -0
- package/src/types/events.ts +63 -0
- package/src/types/index.ts +24 -0
- package/src/types/lock.ts +40 -0
- package/src/types/logger.ts +23 -0
- package/src/types/options.ts +57 -0
- package/src/types/state.ts +36 -0
- package/src/types/strategy.ts +31 -0
- package/src/utils/backoff.ts +52 -0
- package/src/utils/fs.ts +93 -0
- package/src/utils/hash.ts +25 -0
- package/src/utils/hostname.ts +31 -0
- package/src/utils/index.ts +13 -0
- package/src/utils/parse.ts +43 -0
- package/src/utils/path.ts +43 -0
- package/src/utils/pid.ts +36 -0
- package/src/utils/platform.ts +45 -0
- package/src/utils/random.ts +31 -0
- package/src/utils/retry.ts +59 -0
- package/src/utils/serialize.ts +31 -0
- package/src/utils/time.ts +51 -0
- package/src/utils/validate.ts +45 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { LockHandle } from '../types/lock.js';
|
|
2
|
+
|
|
3
|
+
const localHandles = new Map<string, LockHandle>();
|
|
4
|
+
|
|
5
|
+
export function registerHandle(handle: LockHandle): void {
|
|
6
|
+
localHandles.set(handle.lockPath, handle);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function unregisterHandle(lockPath: string): void {
|
|
10
|
+
localHandles.delete(lockPath);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getHandle(lockPath: string): LockHandle | undefined {
|
|
14
|
+
return localHandles.get(lockPath);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function hasHandle(lockPath: string): boolean {
|
|
18
|
+
return localHandles.has(lockPath);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getAllHandles(): LockHandle[] {
|
|
22
|
+
return [...localHandles.values()];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getActiveHandles(): LockHandle[] {
|
|
26
|
+
return getAllHandles().filter((h) => h.acquired);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function releaseAllHandles(): Promise<void> {
|
|
30
|
+
const handles = [...localHandles.values()];
|
|
31
|
+
await Promise.allSettled(handles.map((h) => h.release()));
|
|
32
|
+
localHandles.clear();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function clearRegistry(): void {
|
|
36
|
+
localHandles.clear();
|
|
37
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { StrategyDefinition } from '../types/strategy.js';
|
|
2
|
+
|
|
3
|
+
export const advisoryStrategy: StrategyDefinition = {
|
|
4
|
+
name: 'advisory',
|
|
5
|
+
description: 'Cooperative locking — processes agree not to write when a lock is held.',
|
|
6
|
+
allowsConcurrent: false,
|
|
7
|
+
requiresKernel: false,
|
|
8
|
+
crossProcess: true,
|
|
9
|
+
crossMachine: false,
|
|
10
|
+
supports: {
|
|
11
|
+
ttl: true,
|
|
12
|
+
heartbeat: false,
|
|
13
|
+
shared: false,
|
|
14
|
+
upgrade: false,
|
|
15
|
+
downgrade: false,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function isAdvisoryLockRespected(): boolean {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { StrategyDefinition } from '../types/strategy.js';
|
|
2
|
+
|
|
3
|
+
export const exclusiveStrategy: StrategyDefinition = {
|
|
4
|
+
name: 'exclusive',
|
|
5
|
+
description: 'Only one process may hold the lock at a time. All others are blocked.',
|
|
6
|
+
allowsConcurrent: false,
|
|
7
|
+
requiresKernel: false,
|
|
8
|
+
crossProcess: true,
|
|
9
|
+
crossMachine: false,
|
|
10
|
+
supports: {
|
|
11
|
+
ttl: true,
|
|
12
|
+
heartbeat: true,
|
|
13
|
+
shared: false,
|
|
14
|
+
upgrade: false,
|
|
15
|
+
downgrade: false,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function isExclusiveCompatible(strategy: string): boolean {
|
|
20
|
+
return strategy === 'exclusive';
|
|
21
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export { exclusiveStrategy } from './exclusive.js';
|
|
2
|
+
export { sharedStrategy } from './shared.js';
|
|
3
|
+
export { advisoryStrategy } from './advisory.js';
|
|
4
|
+
export { optimisticStrategy } from './optimistic.js';
|
|
5
|
+
|
|
6
|
+
import type { LockStrategy, StrategyDefinition } from '../types/strategy.js';
|
|
7
|
+
import { exclusiveStrategy } from './exclusive.js';
|
|
8
|
+
import { sharedStrategy } from './shared.js';
|
|
9
|
+
import { advisoryStrategy } from './advisory.js';
|
|
10
|
+
import { optimisticStrategy } from './optimistic.js';
|
|
11
|
+
|
|
12
|
+
const strategyRegistry = new Map<LockStrategy, StrategyDefinition>([
|
|
13
|
+
['exclusive', exclusiveStrategy],
|
|
14
|
+
['shared', sharedStrategy],
|
|
15
|
+
['advisory', advisoryStrategy],
|
|
16
|
+
['optimistic', optimisticStrategy],
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
export function getStrategy(name: LockStrategy): StrategyDefinition {
|
|
20
|
+
const strategy = strategyRegistry.get(name);
|
|
21
|
+
if (!strategy) throw new Error(`Unknown strategy: "${name}"`);
|
|
22
|
+
return strategy;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function listStrategies(): LockStrategy[] {
|
|
26
|
+
return [...strategyRegistry.keys()];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isStrategyAvailable(name: LockStrategy): boolean {
|
|
30
|
+
return strategyRegistry.has(name);
|
|
31
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StrategyDefinition } from '../types/strategy.js';
|
|
2
|
+
|
|
3
|
+
export const optimisticStrategy: StrategyDefinition = {
|
|
4
|
+
name: 'optimistic',
|
|
5
|
+
description: 'Assume no conflict; detect conflicts on write and retry.',
|
|
6
|
+
allowsConcurrent: true,
|
|
7
|
+
requiresKernel: false,
|
|
8
|
+
crossProcess: true,
|
|
9
|
+
crossMachine: true,
|
|
10
|
+
supports: {
|
|
11
|
+
ttl: false,
|
|
12
|
+
heartbeat: false,
|
|
13
|
+
shared: true,
|
|
14
|
+
upgrade: false,
|
|
15
|
+
downgrade: false,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export interface OptimisticVersion {
|
|
20
|
+
version: number;
|
|
21
|
+
etag: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createOptimisticVersion(data: string): OptimisticVersion {
|
|
25
|
+
return {
|
|
26
|
+
version: Date.now(),
|
|
27
|
+
etag: Buffer.from(data).toString('base64'),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StrategyDefinition } from '../types/strategy.js';
|
|
2
|
+
|
|
3
|
+
export const sharedStrategy: StrategyDefinition = {
|
|
4
|
+
name: 'shared',
|
|
5
|
+
description: 'Multiple readers may hold the lock simultaneously; writers require exclusivity.',
|
|
6
|
+
allowsConcurrent: true,
|
|
7
|
+
requiresKernel: false,
|
|
8
|
+
crossProcess: true,
|
|
9
|
+
crossMachine: false,
|
|
10
|
+
supports: {
|
|
11
|
+
ttl: true,
|
|
12
|
+
heartbeat: true,
|
|
13
|
+
shared: true,
|
|
14
|
+
upgrade: true,
|
|
15
|
+
downgrade: true,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function countSharedHolders(lockDir: string, extension: string): Promise<number> {
|
|
20
|
+
return import('node:fs').then(({ promises }) =>
|
|
21
|
+
promises.readdir(lockDir).then((files: string[]) => files.filter((f: string) => f.endsWith(extension)).length),
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { accessSync, readFileSync, statSync, constants } from 'node:fs';
|
|
2
|
+
import { resolveLockPath } from '../utils/path.js';
|
|
3
|
+
import { safeDeserializeLockData } from '../utils/serialize.js';
|
|
4
|
+
import { DEFAULT_LOCK_EXTENSION } from '../constants/defaults.js';
|
|
5
|
+
import type { LockFile } from '../types/lock.js';
|
|
6
|
+
|
|
7
|
+
export function checkSync(filePath: string, lockExtension = DEFAULT_LOCK_EXTENSION): LockFile {
|
|
8
|
+
const lockPath = resolveLockPath(filePath, lockExtension);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
accessSync(lockPath, constants.F_OK);
|
|
12
|
+
} catch {
|
|
13
|
+
return { path: filePath, lockPath, data: null, exists: false, readable: false, writable: false, stale: false, expired: false, ageMs: 0 };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let raw: string | null = null;
|
|
17
|
+
try {
|
|
18
|
+
raw = readFileSync(lockPath, 'utf-8');
|
|
19
|
+
} catch { /* ignore */ }
|
|
20
|
+
|
|
21
|
+
const data = raw ? safeDeserializeLockData(raw) : null;
|
|
22
|
+
|
|
23
|
+
let ageMs = 0;
|
|
24
|
+
try {
|
|
25
|
+
ageMs = Date.now() - statSync(lockPath).mtimeMs;
|
|
26
|
+
} catch { /* ignore */ }
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
path: filePath,
|
|
30
|
+
lockPath,
|
|
31
|
+
data,
|
|
32
|
+
exists: true,
|
|
33
|
+
readable: raw !== null,
|
|
34
|
+
writable: true,
|
|
35
|
+
stale: false,
|
|
36
|
+
expired: false,
|
|
37
|
+
ageMs,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function isLockedSync(filePath: string, lockExtension = DEFAULT_LOCK_EXTENSION): boolean {
|
|
42
|
+
return checkSync(filePath, lockExtension).exists;
|
|
43
|
+
}
|
package/src/sync/lock.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { writeFileSync, accessSync, unlinkSync, constants } from 'node:fs';
|
|
2
|
+
import { resolveLockPath } from '../utils/path.js';
|
|
3
|
+
import { buildLockData } from '../core/buildLockData.js';
|
|
4
|
+
import { serializeLockData } from '../utils/serialize.js';
|
|
5
|
+
import { ConflictError } from '../errors/ConflictError.js';
|
|
6
|
+
import { DEFAULT_LOCK_EXTENSION, DEFAULT_ADAPTER } from '../constants/defaults.js';
|
|
7
|
+
import type { AcquireOptions } from '../types/options.js';
|
|
8
|
+
|
|
9
|
+
export function lockSync(filePath: string, options: AcquireOptions = {}): { lockPath: string; release: () => void } {
|
|
10
|
+
const lockPath = resolveLockPath(filePath, options.lockExtension ?? DEFAULT_LOCK_EXTENSION);
|
|
11
|
+
const data = buildLockData(options);
|
|
12
|
+
const content = serializeLockData(data);
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
accessSync(lockPath, constants.F_OK);
|
|
16
|
+
throw new ConflictError(filePath, lockPath, null);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
const e = err as NodeJS.ErrnoException;
|
|
19
|
+
if (e.code !== 'ENOENT') throw err;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
writeFileSync(lockPath, content, { encoding: 'utf-8', flag: 'wx' });
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
lockPath,
|
|
26
|
+
release: () => {
|
|
27
|
+
try { unlinkSync(lockPath); } catch { /* ignore */ }
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function tryLockSync(filePath: string, options?: AcquireOptions): ReturnType<typeof lockSync> | null {
|
|
33
|
+
try {
|
|
34
|
+
return lockSync(filePath, options);
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { unlinkSync } from 'node:fs';
|
|
2
|
+
import { resolveLockPath } from '../utils/path.js';
|
|
3
|
+
import { DEFAULT_LOCK_EXTENSION } from '../constants/defaults.js';
|
|
4
|
+
|
|
5
|
+
export function unlockSync(filePath: string, lockExtension = DEFAULT_LOCK_EXTENSION): void {
|
|
6
|
+
const lockPath = resolveLockPath(filePath, lockExtension);
|
|
7
|
+
try {
|
|
8
|
+
unlinkSync(lockPath);
|
|
9
|
+
} catch (err) {
|
|
10
|
+
const e = err as NodeJS.ErrnoException;
|
|
11
|
+
if (e.code !== 'ENOENT') throw err;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function forceUnlockSync(lockPath: string): void {
|
|
16
|
+
try {
|
|
17
|
+
unlinkSync(lockPath);
|
|
18
|
+
} catch { /* ignore */ }
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type AdapterName = 'fs' | 'atomic' | 'flock' | 'mkdir' | 'symlink';
|
|
2
|
+
|
|
3
|
+
export interface Adapter {
|
|
4
|
+
readonly name: AdapterName;
|
|
5
|
+
readonly atomic: boolean;
|
|
6
|
+
readonly crossPlatform: boolean;
|
|
7
|
+
acquire(lockPath: string, content: string): Promise<void>;
|
|
8
|
+
release(lockPath: string): Promise<void>;
|
|
9
|
+
check(lockPath: string): Promise<boolean>;
|
|
10
|
+
acquireSync?(lockPath: string, content: string): void;
|
|
11
|
+
releaseSync?(lockPath: string): void;
|
|
12
|
+
checkSync?(lockPath: string): boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AdapterCapabilities {
|
|
16
|
+
atomic: boolean;
|
|
17
|
+
crossPlatform: boolean;
|
|
18
|
+
supportsSync: boolean;
|
|
19
|
+
supportsShared: boolean;
|
|
20
|
+
requiresCleanup: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type AdapterFactory = () => Adapter;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { LockData } from './lock.js';
|
|
2
|
+
|
|
3
|
+
export type LockEventName =
|
|
4
|
+
| 'acquiring'
|
|
5
|
+
| 'acquired'
|
|
6
|
+
| 'releasing'
|
|
7
|
+
| 'released'
|
|
8
|
+
| 'refreshing'
|
|
9
|
+
| 'refreshed'
|
|
10
|
+
| 'stale'
|
|
11
|
+
| 'expired'
|
|
12
|
+
| 'conflict'
|
|
13
|
+
| 'retry'
|
|
14
|
+
| 'timeout'
|
|
15
|
+
| 'error';
|
|
16
|
+
|
|
17
|
+
export interface LockEvent {
|
|
18
|
+
name: LockEventName;
|
|
19
|
+
path: string;
|
|
20
|
+
lockPath: string;
|
|
21
|
+
timestamp: number;
|
|
22
|
+
pid: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AcquiredEvent extends LockEvent {
|
|
26
|
+
name: 'acquired';
|
|
27
|
+
data: LockData;
|
|
28
|
+
attempt: number;
|
|
29
|
+
elapsed: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ReleasedEvent extends LockEvent {
|
|
33
|
+
name: 'released';
|
|
34
|
+
held: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface StaleEvent extends LockEvent {
|
|
38
|
+
name: 'stale';
|
|
39
|
+
data: LockData;
|
|
40
|
+
ageMs: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface RetryEvent extends LockEvent {
|
|
44
|
+
name: 'retry';
|
|
45
|
+
attempt: number;
|
|
46
|
+
delay: number;
|
|
47
|
+
error: Error;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ErrorEvent extends LockEvent {
|
|
51
|
+
name: 'error';
|
|
52
|
+
error: Error;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type AnyLockEvent =
|
|
56
|
+
| AcquiredEvent
|
|
57
|
+
| ReleasedEvent
|
|
58
|
+
| StaleEvent
|
|
59
|
+
| RetryEvent
|
|
60
|
+
| ErrorEvent
|
|
61
|
+
| LockEvent;
|
|
62
|
+
|
|
63
|
+
export type LockEventHandler<T extends AnyLockEvent = AnyLockEvent> = (event: T) => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type { LockData, LockHandle, LockFile, LockState } from './lock.js';
|
|
2
|
+
export type {
|
|
3
|
+
AcquireOptions,
|
|
4
|
+
ReleaseOptions,
|
|
5
|
+
CheckOptions,
|
|
6
|
+
ListOptions,
|
|
7
|
+
GlobalOptions,
|
|
8
|
+
WithLockOptions,
|
|
9
|
+
} from './options.js';
|
|
10
|
+
export type { LockStrategy, StrategyDefinition, StrategyResult } from './strategy.js';
|
|
11
|
+
export type { AdapterName, Adapter, AdapterCapabilities, AdapterFactory } from './adapter.js';
|
|
12
|
+
export type { LogLevel, LogLevelNumber, LogEntry, Logger } from './logger.js';
|
|
13
|
+
export type {
|
|
14
|
+
LockEventName,
|
|
15
|
+
LockEvent,
|
|
16
|
+
AcquiredEvent,
|
|
17
|
+
ReleasedEvent,
|
|
18
|
+
StaleEvent,
|
|
19
|
+
RetryEvent,
|
|
20
|
+
ErrorEvent,
|
|
21
|
+
AnyLockEvent,
|
|
22
|
+
LockEventHandler,
|
|
23
|
+
} from './events.js';
|
|
24
|
+
export type { LockStateSnapshot, GlobalState, ProcessState } from './state.js';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface LockData {
|
|
2
|
+
pid: number;
|
|
3
|
+
hostname: string;
|
|
4
|
+
uid: number | null;
|
|
5
|
+
gid: number | null;
|
|
6
|
+
created: number;
|
|
7
|
+
updated: number;
|
|
8
|
+
expires: number | null;
|
|
9
|
+
ttl: number | null;
|
|
10
|
+
nonce: string;
|
|
11
|
+
version: number;
|
|
12
|
+
strategy: string;
|
|
13
|
+
meta: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface LockHandle {
|
|
17
|
+
readonly path: string;
|
|
18
|
+
readonly lockPath: string;
|
|
19
|
+
readonly data: LockData;
|
|
20
|
+
readonly acquired: boolean;
|
|
21
|
+
release(): Promise<void>;
|
|
22
|
+
refresh(): Promise<void>;
|
|
23
|
+
isStale(): boolean;
|
|
24
|
+
isExpired(): boolean;
|
|
25
|
+
toJSON(): LockData;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface LockFile {
|
|
29
|
+
path: string;
|
|
30
|
+
lockPath: string;
|
|
31
|
+
data: LockData | null;
|
|
32
|
+
exists: boolean;
|
|
33
|
+
readable: boolean;
|
|
34
|
+
writable: boolean;
|
|
35
|
+
stale: boolean;
|
|
36
|
+
expired: boolean;
|
|
37
|
+
ageMs: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type LockState = 'unlocked' | 'locked' | 'stale' | 'expired' | 'unknown';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
2
|
+
|
|
3
|
+
export type LogLevelNumber = 0 | 1 | 2 | 3 | 4 | 5;
|
|
4
|
+
|
|
5
|
+
export interface LogEntry {
|
|
6
|
+
level: LogLevel;
|
|
7
|
+
message: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
context?: Record<string, unknown>;
|
|
10
|
+
error?: Error;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Logger {
|
|
14
|
+
silent(message: string, context?: Record<string, unknown>): void;
|
|
15
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
16
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
17
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
18
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
19
|
+
trace(message: string, context?: Record<string, unknown>): void;
|
|
20
|
+
child(context: Record<string, unknown>): Logger;
|
|
21
|
+
setLevel(level: LogLevel): void;
|
|
22
|
+
getLevel(): LogLevel;
|
|
23
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { LockStrategy } from './strategy.js';
|
|
2
|
+
import type { AdapterName } from './adapter.js';
|
|
3
|
+
import type { LogLevel } from './logger.js';
|
|
4
|
+
|
|
5
|
+
export interface AcquireOptions {
|
|
6
|
+
retries?: number;
|
|
7
|
+
retryDelay?: number;
|
|
8
|
+
retryBackoff?: 'linear' | 'exponential' | 'fibonacci' | 'jitter';
|
|
9
|
+
retryMaxDelay?: number;
|
|
10
|
+
timeout?: number;
|
|
11
|
+
ttl?: number;
|
|
12
|
+
heartbeatInterval?: number;
|
|
13
|
+
staleAge?: number;
|
|
14
|
+
removeStale?: boolean;
|
|
15
|
+
strategy?: LockStrategy;
|
|
16
|
+
adapter?: AdapterName;
|
|
17
|
+
lockExtension?: string;
|
|
18
|
+
meta?: Record<string, unknown>;
|
|
19
|
+
signal?: AbortSignal;
|
|
20
|
+
onRetry?: (attempt: number, error: Error) => void;
|
|
21
|
+
onStale?: (lockPath: string) => void;
|
|
22
|
+
onAcquired?: (lockPath: string) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ReleaseOptions {
|
|
26
|
+
force?: boolean;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CheckOptions {
|
|
31
|
+
staleAge?: number;
|
|
32
|
+
strategy?: LockStrategy;
|
|
33
|
+
adapter?: AdapterName;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ListOptions {
|
|
37
|
+
directory?: string;
|
|
38
|
+
recursive?: boolean;
|
|
39
|
+
includeStale?: boolean;
|
|
40
|
+
includeExpired?: boolean;
|
|
41
|
+
lockExtension?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface GlobalOptions {
|
|
45
|
+
lockExtension?: string;
|
|
46
|
+
defaultTtl?: number;
|
|
47
|
+
defaultStaleAge?: number;
|
|
48
|
+
defaultRetries?: number;
|
|
49
|
+
defaultStrategy?: LockStrategy;
|
|
50
|
+
defaultAdapter?: AdapterName;
|
|
51
|
+
logLevel?: LogLevel;
|
|
52
|
+
tmpDir?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface WithLockOptions extends AcquireOptions {
|
|
56
|
+
throwOnError?: boolean;
|
|
57
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LockData, LockState } from './lock.js';
|
|
2
|
+
import type { LockStrategy } from './strategy.js';
|
|
3
|
+
import type { AdapterName } from './adapter.js';
|
|
4
|
+
|
|
5
|
+
export interface LockStateSnapshot {
|
|
6
|
+
path: string;
|
|
7
|
+
lockPath: string;
|
|
8
|
+
state: LockState;
|
|
9
|
+
data: LockData | null;
|
|
10
|
+
strategy: LockStrategy;
|
|
11
|
+
adapter: AdapterName;
|
|
12
|
+
acquisitions: number;
|
|
13
|
+
releases: number;
|
|
14
|
+
failures: number;
|
|
15
|
+
totalHeldMs: number;
|
|
16
|
+
lastAcquired: number | null;
|
|
17
|
+
lastReleased: number | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface GlobalState {
|
|
21
|
+
activeLocks: Map<string, LockStateSnapshot>;
|
|
22
|
+
totalAcquisitions: number;
|
|
23
|
+
totalReleases: number;
|
|
24
|
+
totalFailures: number;
|
|
25
|
+
totalStaleDetections: number;
|
|
26
|
+
startedAt: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ProcessState {
|
|
30
|
+
pid: number;
|
|
31
|
+
hostname: string;
|
|
32
|
+
uid: number | null;
|
|
33
|
+
gid: number | null;
|
|
34
|
+
locks: string[];
|
|
35
|
+
startedAt: number;
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type LockStrategy =
|
|
2
|
+
| 'exclusive'
|
|
3
|
+
| 'shared'
|
|
4
|
+
| 'advisory'
|
|
5
|
+
| 'mandatory'
|
|
6
|
+
| 'optimistic'
|
|
7
|
+
| 'pessimistic';
|
|
8
|
+
|
|
9
|
+
export interface StrategyDefinition {
|
|
10
|
+
name: LockStrategy;
|
|
11
|
+
description: string;
|
|
12
|
+
allowsConcurrent: boolean;
|
|
13
|
+
requiresKernel: boolean;
|
|
14
|
+
crossProcess: boolean;
|
|
15
|
+
crossMachine: boolean;
|
|
16
|
+
supports: {
|
|
17
|
+
ttl: boolean;
|
|
18
|
+
heartbeat: boolean;
|
|
19
|
+
shared: boolean;
|
|
20
|
+
upgrade: boolean;
|
|
21
|
+
downgrade: boolean;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StrategyResult {
|
|
26
|
+
success: boolean;
|
|
27
|
+
strategy: LockStrategy;
|
|
28
|
+
elapsed: number;
|
|
29
|
+
retries: number;
|
|
30
|
+
error?: Error;
|
|
31
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { randomJitter } from './random.js';
|
|
2
|
+
|
|
3
|
+
export type BackoffStrategy = 'linear' | 'exponential' | 'fibonacci' | 'jitter';
|
|
4
|
+
|
|
5
|
+
export function computeBackoffDelay(
|
|
6
|
+
attempt: number,
|
|
7
|
+
baseDelayMs: number,
|
|
8
|
+
strategy: BackoffStrategy,
|
|
9
|
+
maxDelayMs: number,
|
|
10
|
+
): number {
|
|
11
|
+
let delay: number;
|
|
12
|
+
|
|
13
|
+
switch (strategy) {
|
|
14
|
+
case 'linear':
|
|
15
|
+
delay = baseDelayMs * (attempt + 1);
|
|
16
|
+
break;
|
|
17
|
+
case 'exponential':
|
|
18
|
+
delay = baseDelayMs * Math.pow(2, attempt);
|
|
19
|
+
break;
|
|
20
|
+
case 'fibonacci':
|
|
21
|
+
delay = baseDelayMs * fibonacci(attempt + 1);
|
|
22
|
+
break;
|
|
23
|
+
case 'jitter':
|
|
24
|
+
delay = baseDelayMs * Math.pow(2, attempt) + randomJitter(50);
|
|
25
|
+
break;
|
|
26
|
+
default:
|
|
27
|
+
delay = baseDelayMs;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return Math.min(delay, maxDelayMs);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function fibonacci(n: number): number {
|
|
34
|
+
if (n <= 1) return n;
|
|
35
|
+
let a = 0, b = 1;
|
|
36
|
+
for (let i = 2; i <= n; i++) {
|
|
37
|
+
[a, b] = [b, a + b];
|
|
38
|
+
}
|
|
39
|
+
return b;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function computeExponentialDelay(attempt: number, base: number, max: number): number {
|
|
43
|
+
return Math.min(base * Math.pow(2, attempt), max);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function computeLinearDelay(attempt: number, base: number, max: number): number {
|
|
47
|
+
return Math.min(base * (attempt + 1), max);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function computeJitteredDelay(base: number, jitterMaxMs: number): number {
|
|
51
|
+
return base + randomJitter(jitterMaxMs);
|
|
52
|
+
}
|