@develia/commons 0.3.29 → 0.3.31
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/dist/develia-commons.js +114 -33
- package/dist/develia-commons.min.js +1 -1
- package/dist/index.cjs.js +114 -33
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +112 -33
- package/dist/index.esm.js.map +1 -1
- package/package.json +3 -3
- package/src/array-manipulator.ts +1 -0
- package/src/array.ts +20 -0
- package/src/async-pool-executor.ts +60 -34
- package/src/collections.ts +24 -0
- package/src/from.ts +8 -8
- package/src/index.ts +2 -1
- package/src/{pair.ts → key-value-pair.ts} +1 -1
- package/src/lazy.ts +3 -3
- package/src/types.ts +4 -2
- package/src/utilities.ts +65 -9
|
@@ -1,59 +1,85 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {Supplier} from "./types";
|
|
2
|
+
import {delay} from "./utilities";
|
|
3
3
|
|
|
4
4
|
export default class AsyncPoolExecutor {
|
|
5
|
+
private _checkIntervalMs: number;
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
get maxConcurrency(): number {
|
|
8
|
+
return this._maxConcurrency;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
set maxConcurrency(value: number) {
|
|
12
|
+
this._maxConcurrency = value;
|
|
9
13
|
|
|
10
|
-
constructor(maxConcurrency: number) {
|
|
11
|
-
this._maxConcurrency = maxConcurrency;
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
private _proccess: any;
|
|
17
|
+
private _maxConcurrency: number;
|
|
18
|
+
private _activeTasks: number;
|
|
19
|
+
private _taskQueue: Array<Supplier<any>> = [];
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {number} maxConcurrency - The maximum number of concurrent tasks allowed.
|
|
24
|
+
* @param {number} [checkInterval=50] - The interval, in milliseconds, to check for capacity to run new tasks. Defaults to 50 ms.
|
|
25
|
+
*/
|
|
26
|
+
constructor(maxConcurrency: number, checkInterval: number = 50) {
|
|
27
|
+
this._maxConcurrency = maxConcurrency;
|
|
28
|
+
this._checkIntervalMs = checkInterval;
|
|
29
|
+
this._activeTasks = 0;
|
|
30
|
+
}
|
|
14
31
|
|
|
15
32
|
/**
|
|
16
33
|
* Submits a deferred task to a queue for asynchronous execution and returns a Promise resolving to its result.
|
|
17
34
|
* @template T
|
|
18
|
-
* @param {
|
|
19
|
-
* @return {Promise<T>} A Promise that resolves with the result of the executed task, or rejects if an error occurs during execution.
|
|
35
|
+
* @param {Supplier<T>} task - The deferred task to be executed asynchronously.
|
|
20
36
|
*/
|
|
21
|
-
public submit
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
public submit(task: Supplier<any>): void {
|
|
38
|
+
|
|
39
|
+
this._taskQueue.push(task);
|
|
40
|
+
|
|
41
|
+
if (this._proccess != null)
|
|
42
|
+
return;
|
|
43
|
+
|
|
44
|
+
this._proccess = setTimeout(async () => {
|
|
45
|
+
|
|
46
|
+
while (this._taskQueue.length > 0) {
|
|
47
|
+
|
|
48
|
+
while (this._activeTasks >= this._maxConcurrency) {
|
|
49
|
+
await delay(this._checkIntervalMs);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const task = this._taskQueue.shift();
|
|
53
|
+
if (task) {
|
|
25
54
|
this._activeTasks++;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
55
|
+
setTimeout(async () => {
|
|
56
|
+
try {
|
|
57
|
+
await task();
|
|
58
|
+
} finally {
|
|
59
|
+
this._activeTasks--;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
32
62
|
}
|
|
33
|
-
});
|
|
34
|
-
this._runNext();
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
63
|
|
|
38
64
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this._proccess = null;
|
|
68
|
+
}, 0);
|
|
69
|
+
|
|
70
|
+
|
|
44
71
|
}
|
|
45
72
|
|
|
46
73
|
|
|
47
74
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* before resolving the promise.
|
|
75
|
+
* Waits until all tasks (both queued and active) are completed.
|
|
76
|
+
* This method resolves only when there are no pending tasks.
|
|
51
77
|
*
|
|
52
|
-
* @return {Promise<void>} A promise that resolves when
|
|
78
|
+
* @return {Promise<void>} A promise that resolves when all tasks are complete.
|
|
53
79
|
*/
|
|
54
80
|
public async shutdown(): Promise<void> {
|
|
55
81
|
while (this._taskQueue.length > 0 || this._activeTasks > 0) {
|
|
56
|
-
await
|
|
82
|
+
await delay(this._checkIntervalMs);
|
|
57
83
|
}
|
|
58
84
|
}
|
|
59
|
-
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {isFunction} from "./utilities";
|
|
2
|
+
|
|
3
|
+
export class LazyMap<K, V> extends Map<K, V> {
|
|
4
|
+
|
|
5
|
+
private readonly _factoryMethod: (key: K) => V;
|
|
6
|
+
|
|
7
|
+
constructor(factoryMethod: (key: K) => V, entries?: readonly (readonly [K, V])[] | null) {
|
|
8
|
+
super(entries);
|
|
9
|
+
if (!isFunction(factoryMethod)) {
|
|
10
|
+
throw new Error("factoryMethod is not a function");
|
|
11
|
+
}
|
|
12
|
+
this._factoryMethod = factoryMethod;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Sobrescribir el método get
|
|
16
|
+
get(key: K): V {
|
|
17
|
+
if (!this.has(key)) {
|
|
18
|
+
const value = this._factoryMethod(key);
|
|
19
|
+
this.set(key, value);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
return super.get(key) as V;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/from.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {Consumer, EqualityComparer, UnaryFunction, Predicate,
|
|
1
|
+
import {Consumer, EqualityComparer, UnaryFunction, Predicate, Supplier, Optional, Nullable} from "./types";
|
|
2
2
|
import {toPairs} from "./utilities";
|
|
3
|
-
import
|
|
3
|
+
import KeyValuePair from "./key-value-pair";
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
export default function from<T>(source: Iterable<T> |
|
|
6
|
+
export default function from<T>(source: Iterable<T> | Supplier<Iterable<T>>): From<T> | From<KeyValuePair<any, any>> {
|
|
7
7
|
if (source == null)
|
|
8
8
|
throw "Source is null.";
|
|
9
9
|
if (typeof source === 'function')
|
|
@@ -19,8 +19,8 @@ export default function from<T>(source: Iterable<T> | Provider<Iterable<T>>): Fr
|
|
|
19
19
|
|
|
20
20
|
export class From<T> implements Iterable<T> {
|
|
21
21
|
|
|
22
|
-
public static object(obj: any): From<
|
|
23
|
-
return new From<
|
|
22
|
+
public static object(obj: any): From<KeyValuePair<any, any>> {
|
|
23
|
+
return new From<KeyValuePair<any, any>>(function () {
|
|
24
24
|
return toPairs(obj);
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -42,13 +42,13 @@ export class From<T> implements Iterable<T> {
|
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
private readonly _fn:
|
|
45
|
+
private readonly _fn: Supplier<Iterable<T>>
|
|
46
46
|
|
|
47
|
-
protected constructor(fn:
|
|
47
|
+
protected constructor(fn: Supplier<Iterable<T>>) {
|
|
48
48
|
this._fn = fn;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
public static fn<T>(callable:
|
|
51
|
+
public static fn<T>(callable: Supplier<Iterable<T>>): From<T> {
|
|
52
52
|
return new From<T>(callable);
|
|
53
53
|
};
|
|
54
54
|
|
package/src/index.ts
CHANGED
|
@@ -8,9 +8,10 @@ export {default as from, From} from './from';
|
|
|
8
8
|
export {default as Timer} from './timer'
|
|
9
9
|
export {default as TimeSpan} from './timespan'
|
|
10
10
|
export {default as Lazy} from './lazy'
|
|
11
|
-
export {default as
|
|
11
|
+
export {default as KeyValuePair} from './key-value-pair'
|
|
12
12
|
export {default as array, ArrayManipulator} from './array-manipulator';
|
|
13
13
|
export {default as AsyncPoolExecutor} from './async-pool-executor';
|
|
14
|
+
export * from './array'
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
|
package/src/lazy.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Nullable,
|
|
1
|
+
import {Nullable, Supplier} from "./types";
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -8,9 +8,9 @@ import {Nullable, Provider} from "./types";
|
|
|
8
8
|
export default class Lazy<T> {
|
|
9
9
|
private _valueCreated = false;
|
|
10
10
|
private _value: Nullable<T> = null;
|
|
11
|
-
private readonly _factoryMethod:
|
|
11
|
+
private readonly _factoryMethod: Supplier<T>;
|
|
12
12
|
|
|
13
|
-
constructor(getter:
|
|
13
|
+
constructor(getter: Supplier<T>) {
|
|
14
14
|
this._factoryMethod = getter;
|
|
15
15
|
}
|
|
16
16
|
|
package/src/types.ts
CHANGED
|
@@ -6,12 +6,14 @@ export type Consumer<T> = (arg: T) => void
|
|
|
6
6
|
|
|
7
7
|
export type Predicate<T> = (arg: T) => boolean;
|
|
8
8
|
|
|
9
|
-
export type
|
|
9
|
+
export type Supplier<T> = () => T;
|
|
10
10
|
|
|
11
11
|
export type Nullable<T> = T | null;
|
|
12
12
|
|
|
13
13
|
export type Optional<T> = T | undefined;
|
|
14
14
|
|
|
15
|
-
export type
|
|
15
|
+
export type Resolvable<T> = Promise<T> | Supplier<T>
|
|
16
|
+
|
|
17
|
+
export type PromiseExecutor = (resolve: Consumer<any>, reject: Consumer<any>) => any
|
|
16
18
|
|
|
17
19
|
|
package/src/utilities.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// noinspection JSUnusedGlobalSymbols
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
4
|
+
import KeyValuePair from "./key-value-pair";
|
|
5
|
+
import {Optional, Resolvable, Supplier} from "./types";
|
|
6
6
|
import {Type} from "./typing";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -77,13 +77,68 @@ export function isFunction(value: any): value is Function {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Compares two objects or arrays to check if they have the same fields and values,
|
|
82
|
+
* or the same elements if they are arrays.
|
|
83
|
+
*
|
|
84
|
+
* @param {any} a - The first object or array.
|
|
85
|
+
* @param {any} b - The second object or array.
|
|
86
|
+
* @return {boolean} - Returns true if the objects/arrays are equal, otherwise false.
|
|
87
|
+
*/
|
|
88
|
+
export function deepEqual(a: any, b: any): boolean {
|
|
89
|
+
if (a === b) {
|
|
90
|
+
// If both values are strictly equal, return true
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If either value is null or their types differ, return false
|
|
95
|
+
if (a === null || b === null || typeof a !== typeof b) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Check if both values are arrays
|
|
100
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
101
|
+
// Compare lengths and elements recursively
|
|
102
|
+
if (a.length !== b.length) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
for (let i = 0; i < a.length; i++) {
|
|
106
|
+
if (!deepEqual(a[i], b[i])) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check if both values are objects
|
|
114
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
115
|
+
const keysA = Object.keys(a);
|
|
116
|
+
const keysB = Object.keys(b);
|
|
117
|
+
|
|
118
|
+
// Compare the keys length and check if all keys/values match
|
|
119
|
+
if (keysA.length !== keysB.length) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
for (const key of keysA) {
|
|
123
|
+
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// For all other data types (e.g., numbers, strings, booleans), use strict equality
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
80
135
|
/**
|
|
81
136
|
* Pauses the execution of an asynchronous function for a specified duration.
|
|
82
137
|
*
|
|
83
138
|
* @param {number} ms - The delay duration in milliseconds.
|
|
84
139
|
* @return {Promise<void>} A promise that resolves after the specified delay.
|
|
85
140
|
*/
|
|
86
|
-
export async function delay(ms: number): Promise<void>{
|
|
141
|
+
export async function delay(ms: number): Promise<void> {
|
|
87
142
|
await new Promise(resolve => setTimeout(resolve, ms));
|
|
88
143
|
}
|
|
89
144
|
|
|
@@ -118,6 +173,7 @@ export function isNull(value: any): value is null {
|
|
|
118
173
|
return value === null;
|
|
119
174
|
}
|
|
120
175
|
|
|
176
|
+
|
|
121
177
|
/**
|
|
122
178
|
* Determines whether the given value is of type bigint.
|
|
123
179
|
* @param {any} value - The value to be checked.
|
|
@@ -200,13 +256,13 @@ export async function ajaxSubmit(selectorOrElement: HTMLFormElement | string): P
|
|
|
200
256
|
* Converts an object into an array of key-value pairs.
|
|
201
257
|
*
|
|
202
258
|
* @param {Record<string, any>} obj - The object to convert.
|
|
203
|
-
* @return {
|
|
259
|
+
* @return {KeyValuePair<string, any>[]} - The array of key-value pairs.
|
|
204
260
|
*/
|
|
205
|
-
export function toPairs(obj: Record<string, any>):
|
|
261
|
+
export function toPairs(obj: Record<string, any>): KeyValuePair<string, any>[] {
|
|
206
262
|
|
|
207
263
|
let output = [];
|
|
208
264
|
for (const key in obj) {
|
|
209
|
-
output.push(new
|
|
265
|
+
output.push(new KeyValuePair(key, obj[key]));
|
|
210
266
|
}
|
|
211
267
|
return output;
|
|
212
268
|
|
|
@@ -218,7 +274,7 @@ export function toPairs(obj: Record<string, any>): Pair<string, any>[] {
|
|
|
218
274
|
* @param {any} thing - The thing to be converted into a Promise.
|
|
219
275
|
* @returns {Promise<T>} - A Promise representing the given thing.
|
|
220
276
|
*/
|
|
221
|
-
export function promisify<T>(thing:
|
|
277
|
+
export function promisify<T>(thing: Resolvable<T>): Promise<T> {
|
|
222
278
|
|
|
223
279
|
if (thing instanceof Promise)
|
|
224
280
|
return thing;
|
|
@@ -240,8 +296,8 @@ export function promisify<T>(thing: Deferred<T>): Promise<T> {
|
|
|
240
296
|
|
|
241
297
|
|
|
242
298
|
export function ajaxSubmission(selectorOrElement: HTMLFormElement | string,
|
|
243
|
-
onSuccess: Optional<
|
|
244
|
-
onFailure: Optional<
|
|
299
|
+
onSuccess: Optional<Supplier<any>> = undefined,
|
|
300
|
+
onFailure: Optional<Supplier<any>> = undefined): void {
|
|
245
301
|
|
|
246
302
|
const form = typeof selectorOrElement === 'string'
|
|
247
303
|
? document.querySelector(selectorOrElement)
|