Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@rushstack/node-core-library

Package Overview
Dependencies
Maintainers
3
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rushstack/node-core-library - npm Package Compare versions

Comparing version 5.8.0 to 5.9.0

14

CHANGELOG.md
# Change Log - @rushstack/node-core-library
This log was last generated on Tue, 10 Sep 2024 20:08:11 GMT and should not be manually modified.
This log was last generated on Fri, 13 Sep 2024 00:11:42 GMT and should not be manually modified.
## 5.9.0
Fri, 13 Sep 2024 00:11:42 GMT
### Minor changes
- Add a `Sort.sortKeys` function for sorting keys in an object
- Rename `LockFile.acquire` to `Lockfile.acquireAsync`.
### Patches
- Fix an issue where attempting to acquire multiple `LockFile`s at the same time on POSIX would cause the second to immediately be acquired without releasing the first.
## 5.8.0

@@ -6,0 +18,0 @@ Tue, 10 Sep 2024 20:08:11 GMT

@@ -45,2 +45,6 @@ /**

/**
* @deprecated Use {@link LockFile.acquireAsync} instead.
*/
static acquire(resourceFolder: string, resourceName: string, maxWaitMs?: number): Promise<LockFile>;
/**
* Attempts to create the lockfile. Will continue to loop at every 100ms until the lock becomes available

@@ -59,3 +63,4 @@ * or the maxWaitMs is surpassed.

*/
static acquire(resourceFolder: string, resourceName: string, maxWaitMs?: number): Promise<LockFile>;
static acquireAsync(resourceFolder: string, resourceName: string, maxWaitMs?: number): Promise<LockFile>;
private static _tryAcquireInner;
/**

@@ -62,0 +67,0 @@ * Attempts to acquire the lock on a Linux or OSX machine

85

lib/LockFile.js

@@ -81,3 +81,3 @@ "use strict";

// So the caller can safely use this value as part of a unique process id (on the machine, without comparing
// accross reboots).
// across reboots).
return startTimeJiffies;

@@ -141,3 +141,3 @@ }

const psSplit = psStdout.split('\n');
// successfuly able to run "ps", but no process was found
// successfully able to run "ps", but no process was found
if (psSplit[1] === '') {

@@ -155,2 +155,5 @@ return undefined;

exports.getProcessStartTime = getProcessStartTime;
// A set of locks that currently exist in the current process, to be used when
// multiple locks are acquired in the same process.
const IN_PROC_LOCKS = new Set();
/**

@@ -171,2 +174,3 @@ * The `LockFile` implements a file-based mutex for synchronizing access to a shared resource

this._dirtyWhenAcquired = dirtyWhenAcquired;
IN_PROC_LOCKS.add(filePath);
}

@@ -183,11 +187,16 @@ /**

throw new Error(`The resource name "${resourceName}" is invalid.` +
` It must be an alphanumberic string with only "-" or "." It must start with an alphanumeric character.`);
` It must be an alphanumeric string with only "-" or "." It must start and end with an alphanumeric character.`);
}
if (process.platform === 'win32') {
return path.join(path.resolve(resourceFolder), `${resourceName}.lock`);
switch (process.platform) {
case 'win32': {
return path.resolve(resourceFolder, `${resourceName}.lock`);
}
case 'linux':
case 'darwin': {
return path.resolve(resourceFolder, `${resourceName}#${pid}.lock`);
}
default: {
throw new Error(`File locking not implemented for platform: "${process.platform}"`);
}
}
else if (process.platform === 'linux' || process.platform === 'darwin') {
return path.join(path.resolve(resourceFolder), `${resourceName}#${pid}.lock`);
}
throw new Error(`File locking not implemented for platform: "${process.platform}"`);
}

@@ -203,11 +212,12 @@ /**

FileSystem_1.FileSystem.ensureFolder(resourceFolder);
if (process.platform === 'win32') {
return LockFile._tryAcquireWindows(resourceFolder, resourceName);
}
else if (process.platform === 'linux' || process.platform === 'darwin') {
return LockFile._tryAcquireMacOrLinux(resourceFolder, resourceName);
}
throw new Error(`File locking not implemented for platform: "${process.platform}"`);
const lockFilePath = LockFile.getLockFilePath(resourceFolder, resourceName);
return LockFile._tryAcquireInner(resourceFolder, resourceName, lockFilePath);
}
/**
* @deprecated Use {@link LockFile.acquireAsync} instead.
*/
static acquire(resourceFolder, resourceName, maxWaitMs) {
return LockFile.acquireAsync(resourceFolder, resourceName, maxWaitMs);
}
/**
* Attempts to create the lockfile. Will continue to loop at every 100ms until the lock becomes available

@@ -226,22 +236,38 @@ * or the maxWaitMs is surpassed.

*/
static acquire(resourceFolder, resourceName, maxWaitMs) {
static async acquireAsync(resourceFolder, resourceName, maxWaitMs) {
const interval = 100;
const startTime = Date.now();
const retryLoop = async () => {
const lock = LockFile.tryAcquire(resourceFolder, resourceName);
const timeoutTime = maxWaitMs ? startTime + maxWaitMs : undefined;
await FileSystem_1.FileSystem.ensureFolderAsync(resourceFolder);
const lockFilePath = LockFile.getLockFilePath(resourceFolder, resourceName);
// eslint-disable-next-line no-unmodified-loop-condition
while (!timeoutTime || Date.now() <= timeoutTime) {
const lock = LockFile._tryAcquireInner(resourceFolder, resourceName, lockFilePath);
if (lock) {
return lock;
}
if (maxWaitMs && Date.now() > startTime + maxWaitMs) {
throw new Error(`Exceeded maximum wait time to acquire lock for resource "${resourceName}"`);
}
await Async_1.Async.sleepAsync(interval);
return retryLoop();
};
return retryLoop();
}
throw new Error(`Exceeded maximum wait time to acquire lock for resource "${resourceName}"`);
}
static _tryAcquireInner(resourceFolder, resourceName, lockFilePath) {
if (!IN_PROC_LOCKS.has(lockFilePath)) {
switch (process.platform) {
case 'win32': {
return LockFile._tryAcquireWindows(lockFilePath);
}
case 'linux':
case 'darwin': {
return LockFile._tryAcquireMacOrLinux(resourceFolder, resourceName, lockFilePath);
}
default: {
throw new Error(`File locking not implemented for platform: "${process.platform}"`);
}
}
}
}
/**
* Attempts to acquire the lock on a Linux or OSX machine
*/
static _tryAcquireMacOrLinux(resourceFolder, resourceName) {
static _tryAcquireMacOrLinux(resourceFolder, resourceName, pidLockFilePath) {
let dirtyWhenAcquired = false;

@@ -254,3 +280,2 @@ // get the current process' pid

}
const pidLockFilePath = LockFile.getLockFilePath(resourceFolder, resourceName);
let lockFileHandle;

@@ -278,3 +303,3 @@ let lockFile;

// we found at least one lockfile hanging around that isn't ours
const fileInFolderPath = path.join(resourceFolder, fileInFolder);
const fileInFolderPath = `${resourceFolder}/${fileInFolder}`;
dirtyWhenAcquired = true;

@@ -364,4 +389,3 @@ // console.log(`FOUND OTHER LOCKFILE: ${otherPid}`);

*/
static _tryAcquireWindows(resourceFolder, resourceName) {
const lockFilePath = LockFile.getLockFilePath(resourceFolder, resourceName);
static _tryAcquireWindows(lockFilePath) {
let dirtyWhenAcquired = false;

@@ -409,2 +433,3 @@ let fileHandle;

}
IN_PROC_LOCKS.delete(this._filePath);
this._fileWriter.close();

@@ -411,0 +436,0 @@ if (deleteFile) {

@@ -99,3 +99,17 @@ /**

static sortSet<T>(set: Set<T>, comparer?: (x: T, y: T) => number): void;
/**
* Sort the keys deeply given an object or an array.
*
* Doesn't handle cyclic reference.
*
* @param object - The object to be sorted
*
* @example
*
* ```ts
* console.log(Sort.sortKeys({ c: 3, b: 2, a: 1 })); // { a: 1, b: 2, c: 3}
* ```
*/
static sortKeys<T extends Partial<Record<string, unknown>> | unknown[]>(object: T): T;
}
//# sourceMappingURL=Sort.d.ts.map

@@ -210,4 +210,58 @@ "use strict";

}
/**
* Sort the keys deeply given an object or an array.
*
* Doesn't handle cyclic reference.
*
* @param object - The object to be sorted
*
* @example
*
* ```ts
* console.log(Sort.sortKeys({ c: 3, b: 2, a: 1 })); // { a: 1, b: 2, c: 3}
* ```
*/
static sortKeys(object) {
if (!isPlainObject(object) && !Array.isArray(object)) {
throw new TypeError(`Expected object or array`);
}
return Array.isArray(object) ? innerSortArray(object) : innerSortKeys(object);
}
}
exports.Sort = Sort;
function isPlainObject(obj) {
return obj !== null && typeof obj === 'object';
}
function innerSortArray(arr) {
const result = [];
for (const entry of arr) {
if (Array.isArray(entry)) {
result.push(innerSortArray(entry));
}
else if (isPlainObject(entry)) {
result.push(innerSortKeys(entry));
}
else {
result.push(entry);
}
}
return result;
}
function innerSortKeys(obj) {
const result = {};
const keys = Object.keys(obj).sort();
for (const key of keys) {
const value = obj[key];
if (Array.isArray(value)) {
result[key] = innerSortArray(value);
}
else if (isPlainObject(value)) {
result[key] = innerSortKeys(value);
}
else {
result[key] = value;
}
}
return result;
}
//# sourceMappingURL=Sort.js.map
{
"name": "@rushstack/node-core-library",
"version": "5.8.0",
"version": "5.9.0",
"description": "Core libraries that every NodeJS toolchain project should use",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc