socket-function 1.1.24 → 1.1.26

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.
package/index.d.ts CHANGED
@@ -619,15 +619,13 @@ declare module "socket-function/src/batching" {
619
619
  } | T[], fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
620
620
  export declare function safeLoop<T, R>(config: {
621
621
  data: T[];
622
- fnc: (item: T) => MaybePromise<R>;
623
- /** If set, yields after blocking for this many ms. */
622
+ /** If set, yields after blocking for this many ms. ONLY applies if your function does not return promises. Default = 1000ms */
624
623
  maxBlockingTime?: number;
625
- /** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
626
- * e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
624
+ /** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
627
625
  maxActiveFraction?: number;
628
626
  doNotWarnOnSlow?: boolean;
629
627
  name?: string;
630
- }): Promise<R[]>;
628
+ }, fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
631
629
 
632
630
  }
633
631
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "socket-function",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
package/src/batching.d.ts CHANGED
@@ -43,12 +43,10 @@ export declare function unblockLoop<T, R>(config: {
43
43
  } | T[], fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
44
44
  export declare function safeLoop<T, R>(config: {
45
45
  data: T[];
46
- fnc: (item: T) => MaybePromise<R>;
47
- /** If set, yields after blocking for this many ms. */
46
+ /** If set, yields after blocking for this many ms. ONLY applies if your function does not return promises. Default = 1000ms */
48
47
  maxBlockingTime?: number;
49
- /** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
50
- * e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
48
+ /** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
51
49
  maxActiveFraction?: number;
52
50
  doNotWarnOnSlow?: boolean;
53
51
  name?: string;
54
- }): Promise<R[]>;
52
+ }, fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
package/src/batching.ts CHANGED
@@ -374,16 +374,15 @@ export async function unblockLoop<T, R>(config: {
374
374
 
375
375
  export async function safeLoop<T, R>(config: {
376
376
  data: T[];
377
- fnc: (item: T) => MaybePromise<R>;
378
- /** If set, yields after blocking for this many ms. */
377
+ /** If set, yields after blocking for this many ms. ONLY applies if your function does not return promises. Default = 1000ms */
379
378
  maxBlockingTime?: number;
380
- /** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
381
- * e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
379
+ /** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
382
380
  maxActiveFraction?: number;
383
381
  doNotWarnOnSlow?: boolean;
384
382
  name?: string;
385
- }): Promise<R[]> {
386
- let { data, fnc, maxBlockingTime, maxActiveFraction, doNotWarnOnSlow, name } = config;
383
+ }, fnc: (item: T) => MaybePromise<R>): Promise<R[]> {
384
+ let { data, maxActiveFraction, doNotWarnOnSlow, name } = config;
385
+ let maxBlockingTime = config.maxBlockingTime ?? 1000;
387
386
 
388
387
  let label = name || fnc.name || fnc.toString().slice(0, 100);
389
388
  let startTime = Date.now();
@@ -407,26 +406,34 @@ export async function safeLoop<T, R>(config: {
407
406
  }
408
407
 
409
408
  let results: R[] = [];
410
- let lastYieldTime = Date.now();
409
+ let activeTimeSinceYield = 0;
411
410
  try {
412
411
  for (index = 0; index < data.length; index++) {
413
412
  indexStartTime = Date.now();
414
413
  let result = fnc(data[index]);
414
+ let isPromise = false;
415
415
  if (result && typeof result === "object" && "then" in result) {
416
+ isPromise = true;
416
417
  result = await result;
417
418
  }
418
419
  results.push(result);
419
420
 
420
- if (maxBlockingTime !== undefined) {
421
- let blockedFor = Date.now() - lastYieldTime;
422
- if (blockedFor > maxBlockingTime) {
423
- let backOffTime = 0;
424
- if (maxActiveFraction !== undefined && maxActiveFraction > 0 && maxActiveFraction < 1) {
425
- backOffTime = blockedFor / maxActiveFraction - blockedFor;
426
- }
427
- await delay(backOffTime);
428
- lastYieldTime = Date.now();
429
- }
421
+ activeTimeSinceYield += Date.now() - indexStartTime;
422
+
423
+ let backOffTime: number | undefined;
424
+
425
+ if (!isPromise && activeTimeSinceYield > maxBlockingTime) {
426
+ backOffTime = 0;
427
+ }
428
+
429
+ if (maxActiveFraction !== undefined && maxActiveFraction > 0 && maxActiveFraction < 1) {
430
+ let target = activeTimeSinceYield / maxActiveFraction - activeTimeSinceYield;
431
+ backOffTime = Math.max(backOffTime ?? 0, target);
432
+ }
433
+
434
+ if (backOffTime !== undefined) {
435
+ await delay(backOffTime);
436
+ activeTimeSinceYield = 0;
430
437
  }
431
438
  }
432
439
  } finally {