es-toolkit 1.31.0-dev.999 → 1.32.0-dev.1003

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.
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Uses a binary search to determine the lowest index at which `value`
3
+ * should be inserted into `array` in order to maintain its sort order.
4
+ *
5
+ * @category Array
6
+ * @param {ArrayLike<T> | null | undefined} array The sorted array to inspect.
7
+ * @param {T} value The value to evaluate.
8
+ * @returns {number} Returns the index at which `value` should be inserted
9
+ * into `array`.
10
+ * @example
11
+ * sortedIndex([30, 50], 40)
12
+ * // => 1
13
+ */
14
+ declare function sortedIndex<T>(array: ArrayLike<T> | null | undefined, value: T): number;
15
+
16
+ export { sortedIndex };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Uses a binary search to determine the lowest index at which `value`
3
+ * should be inserted into `array` in order to maintain its sort order.
4
+ *
5
+ * @category Array
6
+ * @param {ArrayLike<T> | null | undefined} array The sorted array to inspect.
7
+ * @param {T} value The value to evaluate.
8
+ * @returns {number} Returns the index at which `value` should be inserted
9
+ * into `array`.
10
+ * @example
11
+ * sortedIndex([30, 50], 40)
12
+ * // => 1
13
+ */
14
+ declare function sortedIndex<T>(array: ArrayLike<T> | null | undefined, value: T): number;
15
+
16
+ export { sortedIndex };
@@ -0,0 +1,30 @@
1
+ import { sortedIndexBy } from './sortedIndexBy.mjs';
2
+ import { isNil } from '../../predicate/isNil.mjs';
3
+ import { isNull } from '../../predicate/isNull.mjs';
4
+ import { isSymbol } from '../../predicate/isSymbol.mjs';
5
+ import { isNumber } from '../predicate/isNumber.mjs';
6
+
7
+ const MAX_ARRAY_LENGTH = 4294967295;
8
+ const HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
9
+ function sortedIndex(array, value) {
10
+ if (isNil(array)) {
11
+ return 0;
12
+ }
13
+ let low = 0, high = isNil(array) ? low : array.length;
14
+ if (isNumber(value) && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
15
+ while (low < high) {
16
+ const mid = (low + high) >>> 1;
17
+ const compute = array[mid];
18
+ if (!isNull(compute) && !isSymbol(compute) && compute < value) {
19
+ low = mid + 1;
20
+ }
21
+ else {
22
+ high = mid;
23
+ }
24
+ }
25
+ return high;
26
+ }
27
+ return sortedIndexBy(array, value, value => value);
28
+ }
29
+
30
+ export { sortedIndex };
@@ -0,0 +1,19 @@
1
+ type Iteratee<T, R> = (value: T) => R;
2
+ /**
3
+ * This method is like `sortedIndex` except that it accepts `iteratee`
4
+ * which is invoked for `value` and each element of `array` to compute their
5
+ * sort ranking. The iteratee is invoked with one argument: (value).
6
+ *
7
+ * @param {ArrayLike<T> | null | undefined} array The sorted array to inspect.
8
+ * @param {T} value The value to evaluate.
9
+ * @param {(value: T) => R} iteratee The iteratee invoked per element.
10
+ * @returns {number} Returns the index at which `value` should be inserted
11
+ * into `array`.
12
+ * @example
13
+ * const objects = [{ 'n': 4 }, { 'n': 5 }]
14
+ * sortedIndexBy(objects, { 'n': 4 }, ({ n }) => n)
15
+ * // => 0
16
+ */
17
+ declare function sortedIndexBy<T, R>(array: ArrayLike<T> | null | undefined, value: T, iteratee?: Iteratee<T, R>, retHighest?: boolean): number;
18
+
19
+ export { sortedIndexBy };
@@ -0,0 +1,19 @@
1
+ type Iteratee<T, R> = (value: T) => R;
2
+ /**
3
+ * This method is like `sortedIndex` except that it accepts `iteratee`
4
+ * which is invoked for `value` and each element of `array` to compute their
5
+ * sort ranking. The iteratee is invoked with one argument: (value).
6
+ *
7
+ * @param {ArrayLike<T> | null | undefined} array The sorted array to inspect.
8
+ * @param {T} value The value to evaluate.
9
+ * @param {(value: T) => R} iteratee The iteratee invoked per element.
10
+ * @returns {number} Returns the index at which `value` should be inserted
11
+ * into `array`.
12
+ * @example
13
+ * const objects = [{ 'n': 4 }, { 'n': 5 }]
14
+ * sortedIndexBy(objects, { 'n': 4 }, ({ n }) => n)
15
+ * // => 0
16
+ */
17
+ declare function sortedIndexBy<T, R>(array: ArrayLike<T> | null | undefined, value: T, iteratee?: Iteratee<T, R>, retHighest?: boolean): number;
18
+
19
+ export { sortedIndexBy };
@@ -0,0 +1,56 @@
1
+ import { isNull } from '../../predicate/isNull.mjs';
2
+ import { isUndefined } from '../../predicate/isUndefined.mjs';
3
+ import { isNaN } from '../predicate/isNaN.mjs';
4
+ import { isNil } from '../predicate/isNil.mjs';
5
+ import { isSymbol } from '../predicate/isSymbol.mjs';
6
+
7
+ const MAX_ARRAY_LENGTH = 4294967295;
8
+ const MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
9
+ function sortedIndexBy(array, value, iteratee, retHighest) {
10
+ let low = 0;
11
+ let high = array == null ? 0 : array.length;
12
+ if (high === 0 || isNil(array)) {
13
+ return 0;
14
+ }
15
+ const transformedValue = iteratee?.(value);
16
+ const valIsNaN = isNaN(transformedValue);
17
+ const valIsNull = isNull(transformedValue);
18
+ const valIsSymbol = isSymbol(transformedValue);
19
+ const valIsUndefined = isUndefined(transformedValue);
20
+ while (low < high) {
21
+ let setLow;
22
+ const mid = Math.floor((low + high) / 2);
23
+ const computed = iteratee?.(array[mid]);
24
+ const othIsDefined = !isUndefined(computed);
25
+ const othIsNull = isNull(computed);
26
+ const othIsReflexive = !isNaN(computed);
27
+ const othIsSymbol = isSymbol(computed);
28
+ if (valIsNaN) {
29
+ setLow = retHighest || othIsReflexive;
30
+ }
31
+ else if (valIsUndefined) {
32
+ setLow = othIsReflexive && (retHighest || othIsDefined);
33
+ }
34
+ else if (valIsNull) {
35
+ setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
36
+ }
37
+ else if (valIsSymbol) {
38
+ setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
39
+ }
40
+ else if (othIsNull || othIsSymbol) {
41
+ setLow = false;
42
+ }
43
+ else {
44
+ setLow = retHighest ? computed <= transformedValue : computed < transformedValue;
45
+ }
46
+ if (setLow) {
47
+ low = mid + 1;
48
+ }
49
+ else {
50
+ high = mid;
51
+ }
52
+ }
53
+ return Math.min(high, MAX_ARRAY_INDEX);
54
+ }
55
+
56
+ export { sortedIndexBy };
@@ -61,6 +61,8 @@ export { isNull } from '../predicate/isNull.mjs';
61
61
  export { isPrimitive } from '../predicate/isPrimitive.mjs';
62
62
  export { isPromise } from '../predicate/isPromise.mjs';
63
63
  export { isUndefined } from '../predicate/isUndefined.mjs';
64
+ export { Mutex } from '../promise/mutex.mjs';
65
+ export { Semaphore } from '../promise/semaphore.mjs';
64
66
  export { timeout } from '../promise/timeout.mjs';
65
67
  export { withTimeout } from '../promise/withTimeout.mjs';
66
68
  export { capitalize } from '../string/capitalize.mjs';
@@ -108,6 +110,8 @@ export { size } from './array/size.mjs';
108
110
  export { slice } from './array/slice.mjs';
109
111
  export { some } from './array/some.mjs';
110
112
  export { sortBy } from './array/sortBy.mjs';
113
+ export { sortedIndex } from './array/sortedIndex.mjs';
114
+ export { sortedIndexBy } from './array/sortedIndexBy.mjs';
111
115
  export { tail } from './array/tail.mjs';
112
116
  export { take } from './array/take.mjs';
113
117
  export { takeRight } from './array/takeRight.mjs';
@@ -61,6 +61,8 @@ export { isNull } from '../predicate/isNull.js';
61
61
  export { isPrimitive } from '../predicate/isPrimitive.js';
62
62
  export { isPromise } from '../predicate/isPromise.js';
63
63
  export { isUndefined } from '../predicate/isUndefined.js';
64
+ export { Mutex } from '../promise/mutex.js';
65
+ export { Semaphore } from '../promise/semaphore.js';
64
66
  export { timeout } from '../promise/timeout.js';
65
67
  export { withTimeout } from '../promise/withTimeout.js';
66
68
  export { capitalize } from '../string/capitalize.js';
@@ -108,6 +110,8 @@ export { size } from './array/size.js';
108
110
  export { slice } from './array/slice.js';
109
111
  export { some } from './array/some.js';
110
112
  export { sortBy } from './array/sortBy.js';
113
+ export { sortedIndex } from './array/sortedIndex.js';
114
+ export { sortedIndexBy } from './array/sortedIndexBy.js';
111
115
  export { tail } from './array/tail.js';
112
116
  export { take } from './array/take.js';
113
117
  export { takeRight } from './array/takeRight.js';
@@ -11,7 +11,7 @@ const range$1 = require('../_chunk/range-HnEIT7.js');
11
11
  const randomInt = require('../_chunk/randomInt-CF7bZK.js');
12
12
  const toMerged = require('../_chunk/toMerged-BQTfB8.js');
13
13
  const isPlainObject$1 = require('../_chunk/isPlainObject-Xaozpc.js');
14
- const isWeakSet$1 = require('../_chunk/isWeakSet-BW79-8.js');
14
+ const isWeakSet$1 = require('../_chunk/isWeakSet-DoHqUM.js');
15
15
  const promise_index = require('../promise/index.js');
16
16
  const upperFirst$1 = require('../_chunk/upperFirst-CorAVn.js');
17
17
  const util_index = require('../util/index.js');
@@ -1297,6 +1297,90 @@ function sortBy(collection, ...criteria) {
1297
1297
  return orderBy(collection, zipWith.flatten(criteria), ['asc']);
1298
1298
  }
1299
1299
 
1300
+ function isNaN(value) {
1301
+ return Number.isNaN(value);
1302
+ }
1303
+
1304
+ function isNil(x) {
1305
+ return x == null;
1306
+ }
1307
+
1308
+ const MAX_ARRAY_LENGTH$2 = 4294967295;
1309
+ const MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH$2 - 1;
1310
+ function sortedIndexBy(array, value, iteratee, retHighest) {
1311
+ let low = 0;
1312
+ let high = array == null ? 0 : array.length;
1313
+ if (high === 0 || isNil(array)) {
1314
+ return 0;
1315
+ }
1316
+ const transformedValue = iteratee?.(value);
1317
+ const valIsNaN = isNaN(transformedValue);
1318
+ const valIsNull = isWeakSet$1.isNull(transformedValue);
1319
+ const valIsSymbol = isSymbol(transformedValue);
1320
+ const valIsUndefined = isWeakSet$1.isUndefined(transformedValue);
1321
+ while (low < high) {
1322
+ let setLow;
1323
+ const mid = Math.floor((low + high) / 2);
1324
+ const computed = iteratee?.(array[mid]);
1325
+ const othIsDefined = !isWeakSet$1.isUndefined(computed);
1326
+ const othIsNull = isWeakSet$1.isNull(computed);
1327
+ const othIsReflexive = !isNaN(computed);
1328
+ const othIsSymbol = isSymbol(computed);
1329
+ if (valIsNaN) {
1330
+ setLow = retHighest || othIsReflexive;
1331
+ }
1332
+ else if (valIsUndefined) {
1333
+ setLow = othIsReflexive && (retHighest || othIsDefined);
1334
+ }
1335
+ else if (valIsNull) {
1336
+ setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
1337
+ }
1338
+ else if (valIsSymbol) {
1339
+ setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
1340
+ }
1341
+ else if (othIsNull || othIsSymbol) {
1342
+ setLow = false;
1343
+ }
1344
+ else {
1345
+ setLow = retHighest ? computed <= transformedValue : computed < transformedValue;
1346
+ }
1347
+ if (setLow) {
1348
+ low = mid + 1;
1349
+ }
1350
+ else {
1351
+ high = mid;
1352
+ }
1353
+ }
1354
+ return Math.min(high, MAX_ARRAY_INDEX);
1355
+ }
1356
+
1357
+ function isNumber(value) {
1358
+ return typeof value === 'number' || value instanceof Number;
1359
+ }
1360
+
1361
+ const MAX_ARRAY_LENGTH$1 = 4294967295;
1362
+ const HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH$1 >>> 1;
1363
+ function sortedIndex(array, value) {
1364
+ if (isWeakSet$1.isNil(array)) {
1365
+ return 0;
1366
+ }
1367
+ let low = 0, high = isWeakSet$1.isNil(array) ? low : array.length;
1368
+ if (isNumber(value) && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
1369
+ while (low < high) {
1370
+ const mid = (low + high) >>> 1;
1371
+ const compute = array[mid];
1372
+ if (!isWeakSet$1.isNull(compute) && !isWeakSet$1.isSymbol(compute) && compute < value) {
1373
+ low = mid + 1;
1374
+ }
1375
+ else {
1376
+ high = mid;
1377
+ }
1378
+ }
1379
+ return high;
1380
+ }
1381
+ return sortedIndexBy(array, value, value => value);
1382
+ }
1383
+
1300
1384
  function tail(arr) {
1301
1385
  if (!isArrayLike(arr)) {
1302
1386
  return [];
@@ -2452,10 +2536,6 @@ function omit(obj, ...keysArr) {
2452
2536
  return result;
2453
2537
  }
2454
2538
 
2455
- function isNil(x) {
2456
- return x == null;
2457
- }
2458
-
2459
2539
  function pick(obj, ...keysArr) {
2460
2540
  if (isNil(obj)) {
2461
2541
  return {};
@@ -2611,14 +2691,6 @@ function isMap(value) {
2611
2691
  return isWeakSet$1.isMap(value);
2612
2692
  }
2613
2693
 
2614
- function isNaN(value) {
2615
- return Number.isNaN(value);
2616
- }
2617
-
2618
- function isNumber(value) {
2619
- return typeof value === 'number' || value instanceof Number;
2620
- }
2621
-
2622
2694
  function isRegExp(value) {
2623
2695
  return isWeakSet$1.isRegExp(value);
2624
2696
  }
@@ -3141,6 +3213,8 @@ exports.isNotNil = isWeakSet$1.isNotNil;
3141
3213
  exports.isNull = isWeakSet$1.isNull;
3142
3214
  exports.isPromise = isWeakSet$1.isPromise;
3143
3215
  exports.isUndefined = isWeakSet$1.isUndefined;
3216
+ exports.Mutex = promise_index.Mutex;
3217
+ exports.Semaphore = promise_index.Semaphore;
3144
3218
  exports.timeout = promise_index.timeout;
3145
3219
  exports.withTimeout = promise_index.withTimeout;
3146
3220
  exports.capitalize = upperFirst$1.capitalize;
@@ -3300,6 +3374,8 @@ exports.slice = slice;
3300
3374
  exports.snakeCase = snakeCase;
3301
3375
  exports.some = some;
3302
3376
  exports.sortBy = sortBy;
3377
+ exports.sortedIndex = sortedIndex;
3378
+ exports.sortedIndexBy = sortedIndexBy;
3303
3379
  exports.spread = spread;
3304
3380
  exports.startCase = startCase;
3305
3381
  exports.startsWith = startsWith;
@@ -62,6 +62,8 @@ export { isNotNil } from '../predicate/isNotNil.mjs';
62
62
  export { isNull } from '../predicate/isNull.mjs';
63
63
  export { isPromise } from '../predicate/isPromise.mjs';
64
64
  export { isUndefined } from '../predicate/isUndefined.mjs';
65
+ export { Mutex } from '../promise/mutex.mjs';
66
+ export { Semaphore } from '../promise/semaphore.mjs';
65
67
  export { timeout } from '../promise/timeout.mjs';
66
68
  export { withTimeout } from '../promise/withTimeout.mjs';
67
69
  export { capitalize } from '../string/capitalize.mjs';
@@ -110,6 +112,8 @@ export { size } from './array/size.mjs';
110
112
  export { slice } from './array/slice.mjs';
111
113
  export { some } from './array/some.mjs';
112
114
  export { sortBy } from './array/sortBy.mjs';
115
+ export { sortedIndex } from './array/sortedIndex.mjs';
116
+ export { sortedIndexBy } from './array/sortedIndexBy.mjs';
113
117
  export { tail } from './array/tail.mjs';
114
118
  export { take } from './array/take.mjs';
115
119
  export { takeRight } from './array/takeRight.mjs';
package/dist/index.d.mts CHANGED
@@ -137,6 +137,8 @@ export { isUndefined } from './predicate/isUndefined.mjs';
137
137
  export { isWeakMap } from './predicate/isWeakMap.mjs';
138
138
  export { isWeakSet } from './predicate/isWeakSet.mjs';
139
139
  export { delay } from './promise/delay.mjs';
140
+ export { Mutex } from './promise/mutex.mjs';
141
+ export { Semaphore } from './promise/semaphore.mjs';
140
142
  export { timeout } from './promise/timeout.mjs';
141
143
  export { withTimeout } from './promise/withTimeout.mjs';
142
144
  export { camelCase } from './string/camelCase.mjs';
package/dist/index.d.ts CHANGED
@@ -137,6 +137,8 @@ export { isUndefined } from './predicate/isUndefined.js';
137
137
  export { isWeakMap } from './predicate/isWeakMap.js';
138
138
  export { isWeakSet } from './predicate/isWeakSet.js';
139
139
  export { delay } from './promise/delay.js';
140
+ export { Mutex } from './promise/mutex.js';
141
+ export { Semaphore } from './promise/semaphore.js';
140
142
  export { timeout } from './promise/timeout.js';
141
143
  export { withTimeout } from './promise/withTimeout.js';
142
144
  export { camelCase } from './string/camelCase.js';
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ const randomInt = require('./_chunk/randomInt-CF7bZK.js');
14
14
  const math_index = require('./math/index.js');
15
15
  const toMerged = require('./_chunk/toMerged-BQTfB8.js');
16
16
  const object_index = require('./object/index.js');
17
- const isWeakSet = require('./_chunk/isWeakSet-BW79-8.js');
17
+ const isWeakSet = require('./_chunk/isWeakSet-DoHqUM.js');
18
18
  const predicate_index = require('./predicate/index.js');
19
19
  const isPlainObject = require('./_chunk/isPlainObject-Xaozpc.js');
20
20
  const delay = require('./_chunk/delay-_VMfFa.js');
@@ -155,17 +155,19 @@ exports.isNull = isWeakSet.isNull;
155
155
  exports.isPromise = isWeakSet.isPromise;
156
156
  exports.isRegExp = isWeakSet.isRegExp;
157
157
  exports.isSet = isWeakSet.isSet;
158
+ exports.isSymbol = isWeakSet.isSymbol;
158
159
  exports.isUndefined = isWeakSet.isUndefined;
159
160
  exports.isWeakMap = isWeakSet.isWeakMap;
160
161
  exports.isWeakSet = isWeakSet.isWeakSet;
161
162
  exports.isBoolean = predicate_index.isBoolean;
162
163
  exports.isError = predicate_index.isError;
163
164
  exports.isString = predicate_index.isString;
164
- exports.isSymbol = predicate_index.isSymbol;
165
165
  exports.isPlainObject = isPlainObject.isPlainObject;
166
166
  exports.isPrimitive = isPlainObject.isPrimitive;
167
167
  exports.isTypedArray = isPlainObject.isTypedArray;
168
168
  exports.delay = delay.delay;
169
+ exports.Mutex = promise_index.Mutex;
170
+ exports.Semaphore = promise_index.Semaphore;
169
171
  exports.timeout = promise_index.timeout;
170
172
  exports.withTimeout = promise_index.withTimeout;
171
173
  exports.camelCase = upperFirst.camelCase;
package/dist/index.mjs CHANGED
@@ -137,6 +137,8 @@ export { isUndefined } from './predicate/isUndefined.mjs';
137
137
  export { isWeakMap } from './predicate/isWeakMap.mjs';
138
138
  export { isWeakSet } from './predicate/isWeakSet.mjs';
139
139
  export { delay } from './promise/delay.mjs';
140
+ export { Mutex } from './promise/mutex.mjs';
141
+ export { Semaphore } from './promise/semaphore.mjs';
140
142
  export { timeout } from './promise/timeout.mjs';
141
143
  export { withTimeout } from './promise/withTimeout.mjs';
142
144
  export { camelCase } from './string/camelCase.mjs';
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
4
 
5
- const isWeakSet = require('../_chunk/isWeakSet-BW79-8.js');
5
+ const isWeakSet = require('../_chunk/isWeakSet-DoHqUM.js');
6
6
  const isPlainObject = require('../_chunk/isPlainObject-Xaozpc.js');
7
7
 
8
8
  function isBoolean(x) {
@@ -17,10 +17,6 @@ function isString(value) {
17
17
  return typeof value === 'string';
18
18
  }
19
19
 
20
- function isSymbol(value) {
21
- return typeof value === 'symbol';
22
- }
23
-
24
20
  exports.isArrayBuffer = isWeakSet.isArrayBuffer;
25
21
  exports.isBlob = isWeakSet.isBlob;
26
22
  exports.isBuffer = isWeakSet.isBuffer;
@@ -40,6 +36,7 @@ exports.isNull = isWeakSet.isNull;
40
36
  exports.isPromise = isWeakSet.isPromise;
41
37
  exports.isRegExp = isWeakSet.isRegExp;
42
38
  exports.isSet = isWeakSet.isSet;
39
+ exports.isSymbol = isWeakSet.isSymbol;
43
40
  exports.isUndefined = isWeakSet.isUndefined;
44
41
  exports.isWeakMap = isWeakSet.isWeakMap;
45
42
  exports.isWeakSet = isWeakSet.isWeakSet;
@@ -49,4 +46,3 @@ exports.isTypedArray = isPlainObject.isTypedArray;
49
46
  exports.isBoolean = isBoolean;
50
47
  exports.isError = isError;
51
48
  exports.isString = isString;
52
- exports.isSymbol = isSymbol;
@@ -1,3 +1,5 @@
1
1
  export { delay } from './delay.mjs';
2
+ export { Mutex } from './mutex.mjs';
3
+ export { Semaphore } from './semaphore.mjs';
2
4
  export { timeout } from './timeout.mjs';
3
5
  export { withTimeout } from './withTimeout.mjs';
@@ -1,3 +1,5 @@
1
1
  export { delay } from './delay.js';
2
+ export { Mutex } from './mutex.js';
3
+ export { Semaphore } from './semaphore.js';
2
4
  export { timeout } from './timeout.js';
3
5
  export { withTimeout } from './withTimeout.js';
@@ -5,6 +5,48 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5
5
  const delay = require('../_chunk/delay-_VMfFa.js');
6
6
  const error_index = require('../error/index.js');
7
7
 
8
+ class Semaphore {
9
+ capacity;
10
+ available;
11
+ deferredTasks = [];
12
+ constructor(capacity) {
13
+ this.capacity = capacity;
14
+ this.available = capacity;
15
+ }
16
+ async acquire() {
17
+ if (this.available > 0) {
18
+ this.available--;
19
+ return;
20
+ }
21
+ return new Promise(resolve => {
22
+ this.deferredTasks.push(resolve);
23
+ });
24
+ }
25
+ release() {
26
+ const deferredTask = this.deferredTasks.shift();
27
+ if (deferredTask != null) {
28
+ deferredTask();
29
+ return;
30
+ }
31
+ if (this.available < this.capacity) {
32
+ this.available++;
33
+ }
34
+ }
35
+ }
36
+
37
+ class Mutex {
38
+ semaphore = new Semaphore(1);
39
+ get isLocked() {
40
+ return this.semaphore.available === 0;
41
+ }
42
+ async acquire() {
43
+ return this.semaphore.acquire();
44
+ }
45
+ release() {
46
+ this.semaphore.release();
47
+ }
48
+ }
49
+
8
50
  async function timeout(ms) {
9
51
  await delay.delay(ms);
10
52
  throw new error_index.TimeoutError();
@@ -15,5 +57,7 @@ async function withTimeout(run, ms) {
15
57
  }
16
58
 
17
59
  exports.delay = delay.delay;
60
+ exports.Mutex = Mutex;
61
+ exports.Semaphore = Semaphore;
18
62
  exports.timeout = timeout;
19
63
  exports.withTimeout = withTimeout;
@@ -1,3 +1,5 @@
1
1
  export { delay } from './delay.mjs';
2
+ export { Mutex } from './mutex.mjs';
3
+ export { Semaphore } from './semaphore.mjs';
2
4
  export { timeout } from './timeout.mjs';
3
5
  export { withTimeout } from './withTimeout.mjs';
@@ -0,0 +1,64 @@
1
+ /**
2
+ * A Mutex (mutual exclusion lock) for async functions.
3
+ * It allows only one async task to access a critical section at a time.
4
+ *
5
+ * @example
6
+ * const mutex = new Mutex();
7
+ *
8
+ * async function criticalSection() {
9
+ * await mutex.acquire();
10
+ * try {
11
+ * // This code section cannot be executed simultaneously
12
+ * } finally {
13
+ * mutex.release();
14
+ * }
15
+ * }
16
+ *
17
+ * criticalSection();
18
+ * criticalSection(); // This call will wait until the first call releases the mutex.
19
+ */
20
+ declare class Mutex {
21
+ private semaphore;
22
+ /**
23
+ * Checks if the mutex is currently locked.
24
+ * @returns {boolean} True if the mutex is locked, false otherwise.
25
+ *
26
+ * @example
27
+ * const mutex = new Mutex();
28
+ * console.log(mutex.isLocked); // false
29
+ * await mutex.acquire();
30
+ * console.log(mutex.isLocked); // true
31
+ * mutex.release();
32
+ * console.log(mutex.isLocked); // false
33
+ */
34
+ get isLocked(): boolean;
35
+ /**
36
+ * Acquires the mutex, blocking if necessary until it is available.
37
+ * @returns {Promise<void>} A promise that resolves when the mutex is acquired.
38
+ *
39
+ * @example
40
+ * const mutex = new Mutex();
41
+ * await mutex.acquire();
42
+ * try {
43
+ * // This code section cannot be executed simultaneously
44
+ * } finally {
45
+ * mutex.release();
46
+ * }
47
+ */
48
+ acquire(): Promise<void>;
49
+ /**
50
+ * Releases the mutex, allowing another waiting task to proceed.
51
+ *
52
+ * @example
53
+ * const mutex = new Mutex();
54
+ * await mutex.acquire();
55
+ * try {
56
+ * // This code section cannot be executed simultaneously
57
+ * } finally {
58
+ * mutex.release(); // Allows another waiting task to proceed.
59
+ * }
60
+ */
61
+ release(): void;
62
+ }
63
+
64
+ export { Mutex };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * A Mutex (mutual exclusion lock) for async functions.
3
+ * It allows only one async task to access a critical section at a time.
4
+ *
5
+ * @example
6
+ * const mutex = new Mutex();
7
+ *
8
+ * async function criticalSection() {
9
+ * await mutex.acquire();
10
+ * try {
11
+ * // This code section cannot be executed simultaneously
12
+ * } finally {
13
+ * mutex.release();
14
+ * }
15
+ * }
16
+ *
17
+ * criticalSection();
18
+ * criticalSection(); // This call will wait until the first call releases the mutex.
19
+ */
20
+ declare class Mutex {
21
+ private semaphore;
22
+ /**
23
+ * Checks if the mutex is currently locked.
24
+ * @returns {boolean} True if the mutex is locked, false otherwise.
25
+ *
26
+ * @example
27
+ * const mutex = new Mutex();
28
+ * console.log(mutex.isLocked); // false
29
+ * await mutex.acquire();
30
+ * console.log(mutex.isLocked); // true
31
+ * mutex.release();
32
+ * console.log(mutex.isLocked); // false
33
+ */
34
+ get isLocked(): boolean;
35
+ /**
36
+ * Acquires the mutex, blocking if necessary until it is available.
37
+ * @returns {Promise<void>} A promise that resolves when the mutex is acquired.
38
+ *
39
+ * @example
40
+ * const mutex = new Mutex();
41
+ * await mutex.acquire();
42
+ * try {
43
+ * // This code section cannot be executed simultaneously
44
+ * } finally {
45
+ * mutex.release();
46
+ * }
47
+ */
48
+ acquire(): Promise<void>;
49
+ /**
50
+ * Releases the mutex, allowing another waiting task to proceed.
51
+ *
52
+ * @example
53
+ * const mutex = new Mutex();
54
+ * await mutex.acquire();
55
+ * try {
56
+ * // This code section cannot be executed simultaneously
57
+ * } finally {
58
+ * mutex.release(); // Allows another waiting task to proceed.
59
+ * }
60
+ */
61
+ release(): void;
62
+ }
63
+
64
+ export { Mutex };