New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

throttled-queue

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

throttled-queue - npm Package Compare versions

Comparing version 2.0.3 to 2.1.0

36

dist/throttledQueue.js

@@ -13,4 +13,5 @@ "use strict";

var queue = [];
var lastCalled = 0;
var timeout = undefined;
var lastIntervalStart = 0;
var numRequestsPerInterval = 0;
var timeout;
/**

@@ -21,3 +22,3 @@ * Gets called at a set interval to remove items from the queue.

var dequeue = function () {
var threshold = lastCalled + interval;
var intervalEnd = lastIntervalStart + interval;
var now = Date.now();

@@ -27,13 +28,15 @@ /**

*/
if (now < threshold) {
if (now < intervalEnd) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
timeout && clearTimeout(timeout);
timeout = setTimeout(dequeue, threshold - now);
timeout !== undefined && clearTimeout(timeout);
timeout = setTimeout(dequeue, intervalEnd - now);
return;
}
lastIntervalStart = now;
numRequestsPerInterval = 0;
for (var _i = 0, _a = queue.splice(0, maxRequestsPerInterval); _i < _a.length; _i++) {
var callback = _a[_i];
callback.call({});
numRequestsPerInterval++;
void callback();
}
lastCalled = Date.now();
if (queue.length) {

@@ -47,6 +50,17 @@ timeout = setTimeout(dequeue, interval);

return function (fn) { return new Promise(function (resolve, reject) {
queue.push(function () { return Promise.resolve().then(fn).then(resolve).catch(reject); });
if (!timeout) {
timeout = setTimeout(dequeue, interval);
var callback = function () { return Promise.resolve().then(fn).then(resolve).catch(reject); };
var now = Date.now();
if (timeout === undefined && (now - lastIntervalStart) > interval) {
lastIntervalStart = now;
numRequestsPerInterval = 0;
}
if (numRequestsPerInterval++ < maxRequestsPerInterval) {
void callback();
}
else {
queue.push(callback);
if (timeout === undefined) {
timeout = setTimeout(dequeue, lastIntervalStart + interval - now);
}
}
}); };

@@ -53,0 +67,0 @@ }

{
"name": "throttled-queue",
"version": "2.0.3",
"version": "2.1.0",
"description": "Throttles arbitrary code to execute a maximum number of times per interval. Best for making throttled API requests.",

@@ -5,0 +5,0 @@ "main": "dist/throttledQueue.js",

@@ -114,7 +114,7 @@ # throttled-queue

const usernames = ['shaunpersad', 'forward-motion'];
const profiles = await Promise.all(usernames.map((username) => {
return throttle(() => {
const profiles = await Promise.all(
usernames.map((username) => throttle(() => {
return fetch(`https://api.github.com/search/users?q=${username}`);
});
}));
}))
);

@@ -128,3 +128,3 @@ const justMe = await throttle(() => fetch('https://api.github.com/search/users?q=shaunpersad'));

However, you may also specify the return type when needed:
However, you may also specify the return type of the promise when needed:
```typescript

@@ -131,0 +131,0 @@ import throttledQueue from 'throttled-queue';

@@ -14,4 +14,5 @@ function throttledQueue(

const queue: Array<() => Promise<void>> = [];
let lastCalled = 0;
let timeout: NodeJS.Timeout | undefined = undefined;
let lastIntervalStart = 0;
let numRequestsPerInterval = 0;
let timeout: NodeJS.Timeout | undefined;
/**

@@ -22,3 +23,3 @@ * Gets called at a set interval to remove items from the queue.

const dequeue = () => {
const threshold = lastCalled + interval;
const intervalEnd = lastIntervalStart + interval;
const now = Date.now();

@@ -28,12 +29,14 @@ /**

*/
if (now < threshold) {
if (now < intervalEnd) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
timeout && clearTimeout(timeout);
timeout = setTimeout(dequeue, threshold - now);
timeout !== undefined && clearTimeout(timeout);
timeout = setTimeout(dequeue, intervalEnd - now);
return;
}
lastIntervalStart = now;
numRequestsPerInterval = 0;
for (const callback of queue.splice(0, maxRequestsPerInterval)) {
callback.call({});
numRequestsPerInterval++;
void callback();
}
lastCalled = Date.now();
if (queue.length) {

@@ -48,6 +51,16 @@ timeout = setTimeout(dequeue, interval);

(resolve, reject) => {
queue.push(() => Promise.resolve().then(fn).then(resolve).catch(reject));
if (!timeout) {
timeout = setTimeout(dequeue, interval);
const callback = () => Promise.resolve().then(fn).then(resolve).catch(reject);
const now = Date.now();
if (timeout === undefined && (now - lastIntervalStart) > interval) {
lastIntervalStart = now;
numRequestsPerInterval = 0;
}
if (numRequestsPerInterval++ < maxRequestsPerInterval) {
void callback();
} else {
queue.push(callback);
if (timeout === undefined) {
timeout = setTimeout(dequeue, lastIntervalStart + interval - now);
}
}
},

@@ -54,0 +67,0 @@ );

import throttledQueue from '../src/throttledQueue';
function calculateRPMS(numRequests: number, timeStarted: number) {
return numRequests / (Date.now() - timeStarted);
}
describe('throttled-queue', function () {
it('should queue all fns', function (done) {
it('should queue all fns', function () {
const requestsPerInterval = 1;

@@ -20,101 +13,71 @@ const interval = 200;

void throttle(() => {
console.log('Throttling...');
numRequests++;
});
}
void throttle(() => {
return throttle(() => {
if (numRequests !== requestLimit) {
throw new Error('Not all callbacks queued.');
}
done();
});
});
it('should queue the fn within the interval', function (done) {
it('should queue the fn and honor the interval', function () {
const requestsPerInterval = 1;
const interval = 200;
const interval = 500;
const throttle = throttledQueue(requestsPerInterval, interval);
let lastExecuted = Date.now();
const requestLimit = 100;
let lastIntervalStart = process.hrtime.bigint();
let numRequests = 0;
const requestLimit = 100;
let numRequestsPerInterval = 0;
for (let x = 0; x < requestLimit; x++) {
void throttle(() => {
console.log('Throttling...');
const now = Date.now();
const timeElapsed = now - lastExecuted;
if (timeElapsed < interval) {
if ((process.hrtime.bigint() - lastIntervalStart) > (interval * 1000000)) {
lastIntervalStart = process.hrtime.bigint();
numRequestsPerInterval = 0;
}
if (++numRequestsPerInterval > requestsPerInterval) {
throw new Error('Did not honor interval.');
}
lastExecuted = now;
numRequests++;
});
}
void throttle(() => {
return throttle(() => {
if (numRequests !== requestLimit) {
throw new Error('Not all callbacks queued.');
}
done();
});
});
it('should queue the fn and honor the interval', function (done) {
it('should queue the fn and honor the interval with multiple requests per interval', function () {
const requestsPerInterval = 1;
const interval = 500;
const throttle = throttledQueue(requestsPerInterval, interval);
const timeStarted = Date.now();
const maxRpms = requestsPerInterval / interval;
let numRequests = 0;
const requestLimit = 100;
for (let x = 0; x < requestLimit; x++) {
void throttle(() => {
const rpms = calculateRPMS(++numRequests, timeStarted);
console.log(rpms, maxRpms);
if (rpms > maxRpms) {
throw new Error('Did not honor interval.');
}
});
}
void throttle(() => {
if (numRequests !== requestLimit) {
throw new Error('Not all callbacks queued.');
}
done();
});
});
it('should queue the fn and honor the interval with multiple requests per interval', function (done) {
const requestsPerInterval = 3;
const interval = 1000;
const throttle = throttledQueue(requestsPerInterval, interval);
const timeStarted = Date.now();
const maxRpms = requestsPerInterval / interval;
const requestLimit = 100;
let lastIntervalStart = process.hrtime.bigint();
let numRequests = 0;
const requestLimit = 100;
let numRequestsPerInterval = 0;
for (let x = 0; x < requestLimit; x++) {
void throttle(() => {
const rpms = calculateRPMS(++numRequests, timeStarted);
console.log(rpms, maxRpms);
if (rpms > maxRpms) {
if ((process.hrtime.bigint() - lastIntervalStart) > (interval * 1000000)) {
lastIntervalStart = process.hrtime.bigint();
numRequestsPerInterval = 0;
}
if (++numRequestsPerInterval > requestsPerInterval) {
throw new Error('Did not honor interval.');
}
numRequests++;
});
}
void throttle(() => {
return throttle(() => {
if (numRequests !== requestLimit) {
throw new Error('Not all callbacks queued.');
}
done();
});
});
it('should queue the fn and honor the interval with multiple evenly spaced requests per interval', function (done) {
it('should queue the fn and honor the interval with multiple evenly spaced requests per interval', function () {

@@ -124,22 +87,23 @@ const requestsPerInterval = 3;

const throttle = throttledQueue(requestsPerInterval, interval, true);
const timeStarted = Date.now();
const maxRpms = requestsPerInterval / interval;
const requestLimit = 100;
let lastIntervalStart = process.hrtime.bigint();
let numRequests = 0;
const requestLimit = 100;
let numRequestsPerInterval = 0;
for (let x = 0; x < requestLimit; x++) {
void throttle(() => {
const rpms = calculateRPMS(++numRequests, timeStarted);
console.log(rpms, maxRpms);
if (rpms > maxRpms) {
if ((process.hrtime.bigint() - lastIntervalStart) > (interval * 1000000)) {
lastIntervalStart = process.hrtime.bigint();
numRequestsPerInterval = 0;
}
if (++numRequestsPerInterval > requestsPerInterval) {
throw new Error('Did not honor interval.');
}
numRequests++;
});
}
void throttle(() => {
return throttle(() => {
if (numRequests !== requestLimit) {
throw new Error('Not all callbacks queued.');
}
done();
});

@@ -146,0 +110,0 @@ });

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