build: update volta pnpm version
[poolifier.git] / src / utils.ts
CommitLineData
aa4bf4b2 1import * as os from 'node:os'
3c93feb9
JB
2import type {
3 MeasurementStatisticsRequirements,
4 WorkerChoiceStrategyOptions
5} from './pools/selection-strategies/selection-strategies-types'
59317253 6import type { KillBehavior } from './worker/worker-options'
bbeadd16 7
ff128cc9
JB
8/**
9 * Default task name.
10 */
11export const DEFAULT_TASK_NAME = 'default'
12
6e9d10db
JB
13/**
14 * An intentional empty function.
15 */
4f3c3d89 16export const EMPTY_FUNCTION: () => void = Object.freeze(() => {
6e9d10db 17 /* Intentionally empty */
4f3c3d89 18})
78099a15
JB
19
20/**
bbeadd16
JB
21 * Default worker choice strategy options.
22 */
23export const DEFAULT_WORKER_CHOICE_STRATEGY_OPTIONS: WorkerChoiceStrategyOptions =
24 {
932fc8be 25 runTime: { median: false },
5df69fab
JB
26 waitTime: { median: false },
27 elu: { median: false }
bbeadd16
JB
28 }
29
3c93feb9
JB
30/**
31 * Default measurement statistics requirements.
32 */
33export const DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS: MeasurementStatisticsRequirements =
34 {
35 aggregate: false,
36 average: false,
37 median: false
38 }
39
51474716 40/**
ab80dc46
JB
41 * Returns safe host OS optimized estimate of the default amount of parallelism a pool should use.
42 * Always returns a value greater than zero.
43 *
44 * @returns The host OS optimized maximum pool size.
51474716
JB
45 */
46export const availableParallelism = (): number => {
47 let availableParallelism = 1
48 try {
aa4bf4b2 49 availableParallelism = os.availableParallelism()
51474716 50 } catch {
aa4bf4b2 51 const numberOfCpus = os.cpus()
2845f2a5
JB
52 if (Array.isArray(numberOfCpus) && numberOfCpus.length > 0) {
53 availableParallelism = numberOfCpus.length
51474716
JB
54 }
55 }
56 return availableParallelism
57}
58
bbeadd16 59/**
afe0d5bf 60 * Computes the median of the given data set.
78099a15
JB
61 *
62 * @param dataSet - Data set.
63 * @returns The median of the given data set.
64 */
65export const median = (dataSet: number[]): number => {
4a45e8d2
JB
66 if (Array.isArray(dataSet) && dataSet.length === 0) {
67 return 0
68 }
78099a15
JB
69 if (Array.isArray(dataSet) && dataSet.length === 1) {
70 return dataSet[0]
71 }
c6f42dd6
JB
72 const sortedDataSet = dataSet.slice().sort((a, b) => a - b)
73 return (
74 (sortedDataSet[(sortedDataSet.length - 1) >> 1] +
75 sortedDataSet[sortedDataSet.length >> 1]) /
76 2
77 )
78099a15 78}
0d80593b 79
afe0d5bf
JB
80/**
81 * Rounds the given number to the given scale.
64383951 82 * The rounding is done using the "round half away from zero" method.
afe0d5bf
JB
83 *
84 * @param num - The number to round.
85 * @param scale - The scale to round to.
86 * @returns The rounded number.
87 */
88export const round = (num: number, scale = 2): number => {
89 const rounder = Math.pow(10, scale)
90 return Math.round(num * rounder * (1 + Number.EPSILON)) / rounder
91}
92
3c653a03
JB
93/**
94 * Is the given object a plain object?
95 *
96 * @param obj - The object to check.
97 * @returns `true` if the given object is a plain object, `false` otherwise.
98 */
0d80593b
JB
99export const isPlainObject = (obj: unknown): boolean =>
100 typeof obj === 'object' &&
101 obj !== null &&
102 obj?.constructor === Object &&
103 Object.prototype.toString.call(obj) === '[object Object]'
59317253
JB
104
105/**
106 * Detects whether the given value is a kill behavior or not.
107 *
108 * @typeParam KB - Which specific KillBehavior type to test against.
109 * @param killBehavior - Which kind of kill behavior to detect.
110 * @param value - Any value.
111 * @returns `true` if `value` was strictly equals to `killBehavior`, otherwise `false`.
112 */
113export const isKillBehavior = <KB extends KillBehavior>(
114 killBehavior: KB,
115 value: unknown
116): value is KB => {
117 return value === killBehavior
118}
49d1b48c
JB
119
120/**
121 * Detects whether the given value is an asynchronous function or not.
122 *
123 * @param fn - Any value.
124 * @returns `true` if `fn` was an asynchronous function, otherwise `false`.
125 */
126export const isAsyncFunction = (
127 fn: unknown
128): fn is (...args: unknown[]) => Promise<unknown> => {
129 return typeof fn === 'function' && fn.constructor.name === 'AsyncFunction'
130}