@stryke/helpers 0.4.6 → 0.5.1

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/README.md CHANGED
@@ -54,20 +54,22 @@ other Stryke projects.
54
54
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
55
55
  ## Table of Contents
56
56
 
57
- - [Quick Features](#quick-features)
58
- - [Installing](#installing)
59
- - [Reduced Package Size](#reduced-package-size)
60
- - [Development](#development)
61
- - [Building](#building)
62
- - [Running unit tests](#running-unit-tests)
63
- - [Linting](#linting)
64
- - [Storm Workspaces](#storm-workspaces)
65
- - [Roadmap](#roadmap)
66
- - [Support](#support)
67
- - [License](#license)
68
- - [Changelog](#changelog)
69
- - [Contributing](#contributing)
70
- - [Contributors](#contributors)
57
+ - [Stryke - Helper Functions](#stryke---helper-functions)
58
+ - [Table of Contents](#table-of-contents)
59
+ - [Quick Features](#quick-features)
60
+ - [Installing](#installing)
61
+ - [Reduced Package Size](#reduced-package-size)
62
+ - [Development](#development)
63
+ - [Building](#building)
64
+ - [Running unit tests](#running-unit-tests)
65
+ - [Linting](#linting)
66
+ - [Storm Workspaces](#storm-workspaces)
67
+ - [Roadmap](#roadmap)
68
+ - [Support](#support)
69
+ - [License](#license)
70
+ - [Changelog](#changelog)
71
+ - [Contributing](#contributing)
72
+ - [Contributors](#contributors)
71
73
 
72
74
  <!-- END doctoc -->
73
75
 
@@ -101,6 +103,8 @@ The following modules are available in this package:
101
103
  - **throttle**: Provides a function to throttle another function, limiting its
102
104
  execution rate.
103
105
  - **timeout**: Provides a function to execute another function with a timeout.
106
+ - **semaphore**: Create a semaphore instance.
107
+ - **mutex**: Create a mutex instance.
104
108
  - **to-deep-key**: Provides a function to convert a path to a deep key.
105
109
  - **to-path**: Provides a function to convert a deep key to a path.
106
110
  - **unflatten-object**: Provides a function to unflatten a single level object
package/dist/index.cjs CHANGED
@@ -36,17 +36,6 @@ Object.keys(_deepClone).forEach(function (key) {
36
36
  }
37
37
  });
38
38
  });
39
- var _deepCopy = require("./deep-copy.cjs");
40
- Object.keys(_deepCopy).forEach(function (key) {
41
- if (key === "default" || key === "__esModule") return;
42
- if (key in exports && exports[key] === _deepCopy[key]) return;
43
- Object.defineProperty(exports, key, {
44
- enumerable: true,
45
- get: function () {
46
- return _deepCopy[key];
47
- }
48
- });
49
- });
50
39
  var _deepMerge = require("./deep-merge.cjs");
51
40
  Object.keys(_deepMerge).forEach(function (key) {
52
41
  if (key === "default" || key === "__esModule") return;
@@ -157,6 +146,17 @@ Object.keys(_matchSorter).forEach(function (key) {
157
146
  }
158
147
  });
159
148
  });
149
+ var _mutex = require("./mutex.cjs");
150
+ Object.keys(_mutex).forEach(function (key) {
151
+ if (key === "default" || key === "__esModule") return;
152
+ if (key in exports && exports[key] === _mutex[key]) return;
153
+ Object.defineProperty(exports, key, {
154
+ enumerable: true,
155
+ get: function () {
156
+ return _mutex[key];
157
+ }
158
+ });
159
+ });
160
160
  var _noop = require("./noop.cjs");
161
161
  Object.keys(_noop).forEach(function (key) {
162
162
  if (key === "default" || key === "__esModule") return;
@@ -190,6 +190,17 @@ Object.keys(_removeEmptyItems).forEach(function (key) {
190
190
  }
191
191
  });
192
192
  });
193
+ var _semaphore = require("./semaphore.cjs");
194
+ Object.keys(_semaphore).forEach(function (key) {
195
+ if (key === "default" || key === "__esModule") return;
196
+ if (key in exports && exports[key] === _semaphore[key]) return;
197
+ Object.defineProperty(exports, key, {
198
+ enumerable: true,
199
+ get: function () {
200
+ return _semaphore[key];
201
+ }
202
+ });
203
+ });
193
204
  var _setField = require("./set-field.cjs");
194
205
  Object.keys(_setField).forEach(function (key) {
195
206
  if (key === "default" || key === "__esModule") return;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from "./arg-identity";
2
2
  export * from "./debounce";
3
3
  export * from "./deep-clone";
4
- export * from "./deep-copy";
5
4
  export * from "./deep-merge";
6
5
  export * from "./delay";
7
6
  export * from "./filter-empty";
@@ -12,9 +11,11 @@ export * from "./get-unique";
12
11
  export * from "./identity";
13
12
  export * from "./is-equal";
14
13
  export * from "./match-sorter";
14
+ export * from "./mutex";
15
15
  export * from "./noop";
16
16
  export * from "./remove-accents";
17
17
  export * from "./remove-empty-items";
18
+ export * from "./semaphore";
18
19
  export * from "./set-field";
19
20
  export * from "./throttle";
20
21
  export * from "./timeout";
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export*from"./arg-identity";export*from"./debounce";export*from"./deep-clone";export*from"./deep-copy";export*from"./deep-merge";export*from"./delay";export*from"./filter-empty";export*from"./flatten-object";export*from"./get-field";export*from"./get-ordered-by";export*from"./get-unique";export*from"./identity";export*from"./is-equal";export*from"./match-sorter";export*from"./noop";export*from"./remove-accents";export*from"./remove-empty-items";export*from"./set-field";export*from"./throttle";export*from"./timeout";export*from"./to-deep-key";export*from"./to-path";export*from"./unflatten-object";export*from"./union";export*from"./with-timeout";
1
+ export*from"./arg-identity";export*from"./debounce";export*from"./deep-clone";export*from"./deep-merge";export*from"./delay";export*from"./filter-empty";export*from"./flatten-object";export*from"./get-field";export*from"./get-ordered-by";export*from"./get-unique";export*from"./identity";export*from"./is-equal";export*from"./match-sorter";export*from"./mutex";export*from"./noop";export*from"./remove-accents";export*from"./remove-empty-items";export*from"./semaphore";export*from"./set-field";export*from"./throttle";export*from"./timeout";export*from"./to-deep-key";export*from"./to-path";export*from"./unflatten-object";export*from"./union";export*from"./with-timeout";
package/dist/mutex.cjs ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Mutex = void 0;
7
+ var _semaphore = require("./semaphore.cjs");
8
+ class Mutex {
9
+ semaphore = new _semaphore.Semaphore(1);
10
+ get isLocked() {
11
+ return this.semaphore.available === 0;
12
+ }
13
+ async acquire() {
14
+ return this.semaphore.acquire();
15
+ }
16
+ release() {
17
+ this.semaphore.release();
18
+ }
19
+ }
20
+ exports.Mutex = Mutex;
@@ -0,0 +1,62 @@
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
+ export 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
+ }
package/dist/mutex.mjs ADDED
@@ -0,0 +1 @@
1
+ import{Semaphore as e}from"./semaphore";export class Mutex{semaphore=new e(1);get isLocked(){return this.semaphore.available===0}async acquire(){return this.semaphore.acquire()}release(){this.semaphore.release()}}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Semaphore = void 0;
7
+ class Semaphore {
8
+ capacity;
9
+ available;
10
+ deferredTasks = [];
11
+ constructor(e) {
12
+ this.capacity = e, this.available = e;
13
+ }
14
+ async acquire() {
15
+ if (this.available > 0) {
16
+ this.available--;
17
+ return;
18
+ }
19
+ return new Promise(e => {
20
+ this.deferredTasks.push(e);
21
+ });
22
+ }
23
+ release() {
24
+ const e = this.deferredTasks.shift();
25
+ if (e != null) {
26
+ e();
27
+ return;
28
+ }
29
+ this.available < this.capacity && this.available++;
30
+ }
31
+ }
32
+ exports.Semaphore = Semaphore;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * A counting semaphore for async functions that manages available permits.
3
+ * Semaphores are mainly used to limit the number of concurrent async tasks.
4
+ *
5
+ * Each `acquire` operation takes a permit or waits until one is available.
6
+ * Each `release` operation adds a permit, potentially allowing a waiting task to proceed.
7
+ *
8
+ * The semaphore ensures fairness by maintaining a FIFO (First In, First Out) order for acquirers.
9
+ *
10
+ * @example
11
+ * const sema = new Semaphore(2);
12
+ *
13
+ * async function task() {
14
+ * await sema.acquire();
15
+ * try {
16
+ * // This code can only be executed by two tasks at the same time
17
+ * } finally {
18
+ * sema.release();
19
+ * }
20
+ * }
21
+ *
22
+ * task();
23
+ * task();
24
+ * task(); // This task will wait until one of the previous tasks releases the semaphore.
25
+ */
26
+ export declare class Semaphore {
27
+ /**
28
+ * The maximum number of concurrent operations allowed.
29
+ */
30
+ capacity: number;
31
+ /**
32
+ * The number of available permits.
33
+ */
34
+ available: number;
35
+ private deferredTasks;
36
+ /**
37
+ * Creates an instance of Semaphore.
38
+ * @param capacity - The maximum number of concurrent operations allowed.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const sema = new Semaphore(3); // Allows up to 3 concurrent operations.
43
+ * ```
44
+ */
45
+ constructor(capacity: number);
46
+ /**
47
+ * Acquires a semaphore, blocking if necessary until one is available.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * const sema = new Semaphore(1);
52
+ *
53
+ * async function criticalSection() {
54
+ * await sema.acquire();
55
+ * try {
56
+ * // This code section cannot be executed simultaneously
57
+ * } finally {
58
+ * sema.release();
59
+ * }
60
+ * }
61
+ * ```
62
+ *
63
+ * @returns A promise that resolves when the semaphore is acquired.
64
+ */
65
+ acquire(): Promise<void>;
66
+ /**
67
+ * Releases a semaphore, allowing one more operation to proceed.
68
+ *
69
+ * @example
70
+ * const sema = new Semaphore(1);
71
+ *
72
+ * async function task() {
73
+ * await sema.acquire();
74
+ * try {
75
+ * // This code can only be executed by two tasks at the same time
76
+ * } finally {
77
+ * sema.release(); // Allows another waiting task to proceed.
78
+ * }
79
+ * }
80
+ */
81
+ release(): void;
82
+ }
@@ -0,0 +1 @@
1
+ export class Semaphore{capacity;available;deferredTasks=[];constructor(e){this.capacity=e,this.available=e}async acquire(){if(this.available>0){this.available--;return}return new Promise(e=>{this.deferredTasks.push(e)})}release(){const e=this.deferredTasks.shift();if(e!=null){e();return}this.available<this.capacity&&this.available++}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stryke/helpers",
3
- "version": "0.4.6",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "description": "A package containing miscellaneous helper functions that are used across many different Storm Software projects.",
6
6
  "repository": {
@@ -165,6 +165,20 @@
165
165
  "default": "./dist/set-field.mjs"
166
166
  }
167
167
  },
168
+ "./semaphore": {
169
+ "import": {
170
+ "types": "./dist/semaphore.d.ts",
171
+ "default": "./dist/semaphore.mjs"
172
+ },
173
+ "require": {
174
+ "types": "./dist/semaphore.d.ts",
175
+ "default": "./dist/semaphore.cjs"
176
+ },
177
+ "default": {
178
+ "types": "./dist/semaphore.d.ts",
179
+ "default": "./dist/semaphore.mjs"
180
+ }
181
+ },
168
182
  "./remove-empty-items": {
169
183
  "import": {
170
184
  "types": "./dist/remove-empty-items.d.ts",
@@ -198,6 +212,14 @@
198
212
  "require": { "types": "./dist/noop.d.ts", "default": "./dist/noop.cjs" },
199
213
  "default": { "types": "./dist/noop.d.ts", "default": "./dist/noop.mjs" }
200
214
  },
215
+ "./mutex": {
216
+ "import": { "types": "./dist/mutex.d.ts", "default": "./dist/mutex.mjs" },
217
+ "require": {
218
+ "types": "./dist/mutex.d.ts",
219
+ "default": "./dist/mutex.cjs"
220
+ },
221
+ "default": { "types": "./dist/mutex.d.ts", "default": "./dist/mutex.mjs" }
222
+ },
201
223
  "./match-sorter": {
202
224
  "import": {
203
225
  "types": "./dist/match-sorter.d.ts",
@@ -354,20 +376,6 @@
354
376
  "default": "./dist/deep-merge.mjs"
355
377
  }
356
378
  },
357
- "./deep-copy": {
358
- "import": {
359
- "types": "./dist/deep-copy.d.ts",
360
- "default": "./dist/deep-copy.mjs"
361
- },
362
- "require": {
363
- "types": "./dist/deep-copy.d.ts",
364
- "default": "./dist/deep-copy.cjs"
365
- },
366
- "default": {
367
- "types": "./dist/deep-copy.d.ts",
368
- "default": "./dist/deep-copy.mjs"
369
- }
370
- },
371
379
  "./deep-clone": {
372
380
  "import": {
373
381
  "types": "./dist/deep-clone.d.ts",
@@ -1,86 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.deepCopy = deepCopy;
7
- function A(r) {
8
- const t = new ArrayBuffer(r.byteLength);
9
- return new Uint8Array(t).set(new Uint8Array(r)), t;
10
- }
11
- function C(r) {
12
- const t = A(r.buffer);
13
- return new DataView(t, r.byteOffset, r.byteLength);
14
- }
15
- function g(r) {
16
- return new Date(r.getTime());
17
- }
18
- function d(r) {
19
- const t = new Map();
20
- for (const [n, o] of r.entries()) t.set(deepCopy(n), deepCopy(o));
21
- return t;
22
- }
23
- const u = {
24
- "[object Float32Array]": Float32Array,
25
- "[object Float64Array]": Float64Array,
26
- "[object Int8Array]": Int8Array,
27
- "[object Int16Array]": Int16Array,
28
- "[object Int32Array]": Int32Array,
29
- "[object Uint8Array]": Uint8Array,
30
- "[object Uint16Array]": Uint16Array,
31
- "[object Uint32Array]": Uint32Array,
32
- "[object Uint8ClampedArray]": Uint8ClampedArray
33
- },
34
- j = {
35
- "[object Date]": g,
36
- "[object ArrayBuffer]": A,
37
- "[object DataView]": C,
38
- "[object Float32Array]": e,
39
- "[object Float64Array]": e,
40
- "[object Int8Array]": e,
41
- "[object Int16Array]": e,
42
- "[object Int32Array]": e,
43
- "[object Uint8Array]": e,
44
- "[object Uint8ClampedArray]": e,
45
- "[object Uint16Array]": e,
46
- "[object Uint32Array]": e,
47
- "[object BigInt64Array]": e,
48
- "[object BigUint64Array]": e,
49
- "[object RegExp]": cloneRegExp,
50
- "[object Map]": d
51
- };
52
- function e(r) {
53
- try {
54
- u["[object BigInt64Array]"] = BigInt64Array, u["[object BigUint64Array]"] = BigUint64Array;
55
- } catch {}
56
- const t = A(r.buffer),
57
- n = u[Object.prototype.toString.call(r)];
58
- if (!n) throw new Error("Unsupported typed array type in `cloneTypedArray`.");
59
- return new n(t).subarray(r.byteOffset, r.byteOffset + r.length);
60
- }
61
- function f(r, t, n, o, y) {
62
- const a = detectType(r),
63
- i = copy(r, a);
64
- if (!isCollection(a)) return i;
65
- const b = getKeys(r, a);
66
- for (const s of b) {
67
- const c = getValue(r, s, a);
68
- if (o.has(c)) setValue(t, s, n.get(c), a);else {
69
- const p = detectType(c),
70
- l = copy(c, p);
71
- isCollection(p) && (n.set(c, l), o.add(c)), setValue(t, s, f(c, l, n, o, y), a);
72
- }
73
- }
74
- return t;
75
- }
76
- function deepCopy(r, t) {
77
- const {
78
- customizer: n = null
79
- } = t ?? {},
80
- o = detectType(r);
81
- if (!isCollection(o)) return copy(r, o, n);
82
- const y = copy(r, o, n),
83
- a = new WeakMap([[r, y]]),
84
- i = new WeakSet([r]);
85
- return f(r, y, a, i, n);
86
- }
@@ -1,11 +0,0 @@
1
- export interface Options {
2
- customizer?: Customizer;
3
- }
4
- /**
5
- * Deep copy value
6
- *
7
- * @param value - The value to copy.
8
- * @param options - The options object.
9
- * @returns Returns the copied value.
10
- */
11
- export declare function deepCopy<T extends Record<string, any>>(value: T, options?: Options): T;
@@ -1 +0,0 @@
1
- function A(r){const t=new ArrayBuffer(r.byteLength);return new Uint8Array(t).set(new Uint8Array(r)),t}function C(r){const t=A(r.buffer);return new DataView(t,r.byteOffset,r.byteLength)}function g(r){return new Date(r.getTime())}function d(r){const t=new Map;for(const[n,o]of r.entries())t.set(deepCopy(n),deepCopy(o));return t}const u={"[object Float32Array]":Float32Array,"[object Float64Array]":Float64Array,"[object Int8Array]":Int8Array,"[object Int16Array]":Int16Array,"[object Int32Array]":Int32Array,"[object Uint8Array]":Uint8Array,"[object Uint16Array]":Uint16Array,"[object Uint32Array]":Uint32Array,"[object Uint8ClampedArray]":Uint8ClampedArray},j={"[object Date]":g,"[object ArrayBuffer]":A,"[object DataView]":C,"[object Float32Array]":e,"[object Float64Array]":e,"[object Int8Array]":e,"[object Int16Array]":e,"[object Int32Array]":e,"[object Uint8Array]":e,"[object Uint8ClampedArray]":e,"[object Uint16Array]":e,"[object Uint32Array]":e,"[object BigInt64Array]":e,"[object BigUint64Array]":e,"[object RegExp]":cloneRegExp,"[object Map]":d};function e(r){try{u["[object BigInt64Array]"]=BigInt64Array,u["[object BigUint64Array]"]=BigUint64Array}catch{}const t=A(r.buffer),n=u[Object.prototype.toString.call(r)];if(!n)throw new Error("Unsupported typed array type in `cloneTypedArray`.");return new n(t).subarray(r.byteOffset,r.byteOffset+r.length)}function f(r,t,n,o,y){const a=detectType(r),i=copy(r,a);if(!isCollection(a))return i;const b=getKeys(r,a);for(const s of b){const c=getValue(r,s,a);if(o.has(c))setValue(t,s,n.get(c),a);else{const p=detectType(c),l=copy(c,p);isCollection(p)&&(n.set(c,l),o.add(c)),setValue(t,s,f(c,l,n,o,y),a)}}return t}export function deepCopy(r,t){const{customizer:n=null}=t??{},o=detectType(r);if(!isCollection(o))return copy(r,o,n);const y=copy(r,o,n),a=new WeakMap([[r,y]]),i=new WeakSet([r]);return f(r,y,a,i,n)}