Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoSign in
Socket

@rushstack/node-core-library

Package Overview
Dependencies
Maintainers
3
Versions
157
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.13.1
to
5.14.0-pr5355.0
+8
-1
CHANGELOG.md
# Change Log - @rushstack/node-core-library
This log was last generated on Thu, 01 May 2025 00:11:12 GMT and should not be manually modified.
This log was last generated on Wed, 23 Jul 2025 20:55:57 GMT and should not be manually modified.
## 5.14.0
Wed, 23 Jul 2025 20:55:57 GMT
### Minor changes
- Add a `Async.runWithTimeoutAsync` function that executes an async function, resolving if the specified timeout elapses first.
## 5.13.1

@@ -6,0 +13,0 @@ Thu, 01 May 2025 00:11:12 GMT

+1
-1

@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.

"packageName": "@microsoft/api-extractor",
"packageVersion": "7.52.5"
"packageVersion": "7.52.11"
}
]
}

@@ -18,6 +18,23 @@ /**

/**
* Optionally used with the {@link (Async:class).(forEachAsync:2)} to enable weighted operations where an operation can
* take up more or less than one concurrency unit.
* Optionally used with the {@link (Async:class).(forEachAsync:2)} to enable weighted operations where an
* operation can take up more or less than one concurrency unit.
*/
weighted?: boolean;
/**
* This option affects the handling of task weights, applying a softer policy that favors maximizing parallelism
* instead of avoiding overload.
*
* @remarks
* By default, a new task cannot start executing if doing so would push the total weight above the concurrency limit.
* Set `allowOversubscription` to true to relax this rule, allowing a new task to start as long as the current
* total weight is below the concurrency limit. Either way, a task cannot start if the total weight already equals
* the concurrency limit; therefore, `allowOversubscription` has no effect when all tasks have weight 1.
*
* Example: Suppose the concurrency limit is 8, and seven tasks are running whose weights are 1, so the current
* total weight is 7. If an available task has weight 2, that would push the total weight to 9, exceeding
* the limit. This task can start only if `allowOversubscription` is true.
*
* @defaultValue false
*/
allowOversubscription?: boolean;
}

@@ -49,2 +66,22 @@ /**

* @remarks
* Used with {@link Async.runWithTimeoutAsync}.
*
* @public
*/
export interface IRunWithTimeoutOptions<TResult> {
/**
* The action to be performed. The action is executed with a timeout.
*/
action: () => Promise<TResult> | TResult;
/**
* The timeout in milliseconds.
*/
timeoutMs: number;
/**
* The message to use for the error if the timeout is reached.
*/
timeoutMessage?: string;
}
/**
* @remarks
* Used with {@link (Async:class).(forEachAsync:2)} and {@link (Async:class).(mapAsync:2)}.

@@ -151,2 +188,3 @@ *

* and the first operation has a weight of 2, then only one more operation can be in progress.
* Operations may exceed the concurrency limit based on the `allowOversubscription` option.
*

@@ -182,2 +220,8 @@ * If `callback` throws a synchronous exception, or if it returns a promise that rejects,

static getSignal(): [Promise<void>, () => void, (err: Error) => void];
/**
* Runs a promise with a timeout. If the promise does not resolve within the specified timeout,
* it will reject with an error.
* @remarks If the action is completely synchronous, runWithTimeoutAsync doesn't do anything meaningful.
*/
static runWithTimeoutAsync<TResult>({ action, timeoutMs, timeoutMessage }: IRunWithTimeoutOptions<TResult>): Promise<TResult>;
}

@@ -184,0 +228,0 @@ /**

@@ -45,3 +45,6 @@ "use strict";

let promiseHasResolvedOrRejected = false;
// iterator that is stored when the loop exits early due to not enough concurrency
let nextIterator = undefined;
async function queueOperationsAsync() {
var _a;
while (concurrentUnitsInProgress < concurrency &&

@@ -55,3 +58,3 @@ !iteratorIsComplete &&

concurrentUnitsInProgress += limitedConcurrency;
const currentIteratorResult = await iterator.next();
const currentIteratorResult = nextIterator !== null && nextIterator !== void 0 ? nextIterator : (await iterator.next());
// eslint-disable-next-line require-atomic-updates

@@ -66,4 +69,14 @@ iteratorIsComplete = !!currentIteratorResult.done;

// This should allow other operations to execute.
concurrentUnitsInProgress -= limitedConcurrency;
// Wait until there's enough capacity to run this job, this function will be re-entered as tasks call `onOperationCompletionAsync`
const wouldExceedConcurrency = concurrentUnitsInProgress + weight > concurrency;
const allowOversubscription = (_a = options === null || options === void 0 ? void 0 : options.allowOversubscription) !== null && _a !== void 0 ? _a : false;
if (!allowOversubscription && wouldExceedConcurrency) {
// eslint-disable-next-line require-atomic-updates
nextIterator = currentIteratorResult;
break;
}
// eslint-disable-next-line require-atomic-updates
nextIterator = undefined;
concurrentUnitsInProgress += weight;
concurrentUnitsInProgress -= limitedConcurrency;
Promise.resolve(callback(currentIteratorValue.element, arrayIndex++))

@@ -122,3 +135,2 @@ .then(async () => {

let retryCount = 0;
// eslint-disable-next-line no-constant-condition
while (true) {

@@ -156,2 +168,22 @@ try {

}
/**
* Runs a promise with a timeout. If the promise does not resolve within the specified timeout,
* it will reject with an error.
* @remarks If the action is completely synchronous, runWithTimeoutAsync doesn't do anything meaningful.
*/
static async runWithTimeoutAsync({ action, timeoutMs, timeoutMessage = 'Operation timed out' }) {
let timeoutHandle;
const promise = Promise.resolve(action());
const timeoutPromise = new Promise((resolve, reject) => {
timeoutHandle = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
});
try {
return Promise.race([promise, timeoutPromise]);
}
finally {
if (timeoutHandle) {
clearTimeout(timeoutHandle);
}
}
}
}

@@ -158,0 +190,0 @@ exports.Async = Async;

@@ -87,5 +87,3 @@ "use strict";

const PARENT_PROCESS_ID_GROUP = 'ppid';
// eslint-disable-next-line @rushstack/security/no-unsafe-regexp
const PROCESS_LIST_ENTRY_REGEX_WIN32 = new RegExp(`^(?<${NAME_GROUP}>.+?)\\s+(?<${PARENT_PROCESS_ID_GROUP}>\\d+)\\s+(?<${PROCESS_ID_GROUP}>\\d+)\\s*$`);
// eslint-disable-next-line @rushstack/security/no-unsafe-regexp
const PROCESS_LIST_ENTRY_REGEX_UNIX = new RegExp(`^\\s*(?<${PARENT_PROCESS_ID_GROUP}>\\d+)\\s+(?<${PROCESS_ID_GROUP}>\\d+)\\s+(?<${NAME_GROUP}>.+?)\\s*$`);

@@ -357,3 +355,2 @@ function parseProcessInfoEntry(line, existingProcessInfoById, platform) {

}
/* eslint-enable @rushstack/no-new-null */
/**

@@ -360,0 +357,0 @@ * Get the list of processes currently running on the system, keyed by the process ID.

@@ -1228,7 +1228,5 @@ "use strict";

if (FileSystem.isFileDoesNotExistError(error)) {
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `File does not exist: ${error.path}\n${error.message}`;
}
else if (FileSystem.isFolderDoesNotExistError(error)) {
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `Folder does not exist: ${error.path}\n${error.message}`;

@@ -1240,15 +1238,11 @@ }

const extendedError = error;
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `File or folder already exists: ${extendedError.dest}\n${error.message}`;
}
else if (FileSystem.isUnlinkNotPermittedError(error)) {
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `File or folder could not be deleted: ${error.path}\n${error.message}`;
}
else if (FileSystem.isDirectoryError(error)) {
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `Target is a folder, not a file: ${error.path}\n${error.message}`;
}
else if (FileSystem.isNotDirectoryError(error)) {
// eslint-disable-line @typescript-eslint/no-use-before-define
error.message = `Target is not a folder: ${error.path}\n${error.message}`;

@@ -1255,0 +1249,0 @@ }

@@ -8,3 +8,3 @@ /// <reference types="node" preserve="true" />

export { AlreadyReportedError } from './AlreadyReportedError';
export { Async, AsyncQueue, type IAsyncParallelismOptions, type IRunWithRetriesOptions, type IWeighted } from './Async';
export { Async, AsyncQueue, type IAsyncParallelismOptions, type IRunWithRetriesOptions, type IRunWithTimeoutOptions, type IWeighted } from './Async';
export type { Brand } from './PrimitiveTypes';

@@ -11,0 +11,0 @@ export { FileConstants, FolderConstants } from './Constants';

@@ -141,3 +141,2 @@ "use strict";

*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static sortMapKeys(map, keyComparer = Sort.compareByValue) {

@@ -198,3 +197,2 @@ // Sorting a map is expensive, so first check whether it's already sorted.

*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static sortSet(set, comparer = Sort.compareByValue) {

@@ -201,0 +199,0 @@ // Sorting a set is expensive, so first check whether it's already sorted.

{
"name": "@rushstack/node-core-library",
"version": "5.13.1",
"version": "5.14.0-pr5355.0",
"description": "Core libraries that every NodeJS toolchain project should use",

@@ -24,3 +24,3 @@ "main": "lib/index.js",

"devDependencies": {
"@rushstack/heft": "0.73.2",
"@rushstack/heft": "0.74.3",
"@types/fs-extra": "7.0.0",

@@ -30,4 +30,4 @@ "@types/jju": "1.4.1",

"@types/semver": "7.5.0",
"decoupled-local-node-rig": "1.0.0",
"local-eslint-config": "1.0.0"
"eslint": "~9.25.1",
"decoupled-local-node-rig": "1.0.0"
},

@@ -34,0 +34,0 @@ "peerDependencies": {

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

Sorry, the diff of this file is not supported yet

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