@phothinmaung/resolves 1.0.0
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/LICENSE +19 -0
- package/README.md +94 -0
- package/lib/index.cjs +107 -0
- package/lib/index.d.cts +28 -0
- package/lib/index.d.mts +28 -0
- package/lib/index.mjs +107 -0
- package/package.json +47 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright 2025 Pho Thin Maung<phothinmg@disroot.org>
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute
|
|
6
|
+
this software for any purpose with or without fee is
|
|
7
|
+
hereby granted, provided that the above copyright
|
|
8
|
+
notice and this permission notice appear in all copies.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
|
|
11
|
+
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
|
|
12
|
+
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
13
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
|
14
|
+
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
15
|
+
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
16
|
+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
|
17
|
+
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
19
|
+
THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://github.com/phothinmg/ptmbox/blob/main/kadown.svg" width="160" height="160" alt="susee" />
|
|
3
|
+
<h1>@phothinmaung/resolves</h1>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
The package lets you run a list of functions in series, concurrently, or using an allSettled pattern, returning an array of Promise-resolved results. It is useful for managing multiple asynchronous or synchronous tasks with different strategies.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Run functions in series (one after another)**
|
|
11
|
+
- **Run functions concurrently (all at once)**
|
|
12
|
+
- **Run functions with allSettled (wait for all to finish, regardless of success/failure)**
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i @phothinmaung/resolves
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### commonjs
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
const resolves = require("@phothinmaung/resolves");
|
|
26
|
+
|
|
27
|
+
const asyncFunction = async (str) => {
|
|
28
|
+
return await new Promise((resolve) => resolve(str));
|
|
29
|
+
};
|
|
30
|
+
const syncFunction = (str) => str;
|
|
31
|
+
const syncFunctionNum = (num) => num;
|
|
32
|
+
|
|
33
|
+
const rit = resolves([
|
|
34
|
+
[asyncFunction, "Result 1"],
|
|
35
|
+
[syncFunction, "Result 2"],
|
|
36
|
+
[syncFunctionNum, 3],
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
rit.series().then((res) => {
|
|
40
|
+
console.log(`result-1 : ${res[0]}`); // result-1 : Result 1
|
|
41
|
+
console.log(`result-2 : ${res[1]}`); // result-2 : Result 2
|
|
42
|
+
console.log(`result-3 : ${res[2]}`); // result-3 : 3
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### typescript
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import resolves from "@phothinmaung/resolves";
|
|
50
|
+
|
|
51
|
+
const asyncFunction = async (str: string): Promise<string> => {
|
|
52
|
+
return await new Promise((resolve) => resolve(str));
|
|
53
|
+
};
|
|
54
|
+
const syncFunction = (str: string): string => str;
|
|
55
|
+
const syncFunctionNum = (num: number): number => num;
|
|
56
|
+
|
|
57
|
+
const rit = resolves<[Promise<string>, string, number]>([
|
|
58
|
+
[asyncFunction, "Result 1"],
|
|
59
|
+
[syncFunction, "Result 2"],
|
|
60
|
+
[syncFunctionNum, 3],
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
const [a1, b1, c1] = await rit.series();
|
|
64
|
+
const [a2, b2, c2] = await rit.concurrent();
|
|
65
|
+
const [a3, b3, c3] = await rit.allSettled();
|
|
66
|
+
// Result 1 - Result 2 - 3
|
|
67
|
+
console.log(`${a1} - ${b1} - ${c1}`);
|
|
68
|
+
console.log(`${a2} - ${b2} - ${c2}`);
|
|
69
|
+
console.log(`${a3} - ${b3} - ${c3}`);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
`resolves<R extends any[]>(params: { [K in keyof R]: Param<R[K]> },time?: number)`
|
|
75
|
+
|
|
76
|
+
parameters :
|
|
77
|
+
|
|
78
|
+
- An array of tuples : `[[(...args:any[])=>any,...args:any[]]]`
|
|
79
|
+
The first place of tuple is function and rest are parameters of that function.
|
|
80
|
+
|
|
81
|
+
- Number of milliseconds(optional) : `time?:number` The amount of time to wait before resolving the promise. Defaults to 500ms.
|
|
82
|
+
|
|
83
|
+
returns :
|
|
84
|
+
|
|
85
|
+
An object with `series`, `concurrent`, and `allSettled` properties. Each property is a function that takes no arguments and returns a promise. The promise resolves with the results of running the functions in the specified manner.
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
[ISC][file-license] © [Pho Thin Mg][ptm]
|
|
90
|
+
|
|
91
|
+
<!-- markdownlint-disable MD053 -->
|
|
92
|
+
|
|
93
|
+
[file-license]: LICENSE
|
|
94
|
+
[ptm]: https://github.com/phothinmg
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const isPromiseFun = (fun) =>
|
|
2
|
+
Object.prototype.toString.call(fun) === "[object AsyncFunction]" ||
|
|
3
|
+
fun.constructor.name === "AsyncFunction";
|
|
4
|
+
|
|
5
|
+
function walkPromise(param, time = 500) {
|
|
6
|
+
const fn = param[0];
|
|
7
|
+
const args = param.slice(1);
|
|
8
|
+
if (isPromiseFun(fn)) {
|
|
9
|
+
return () => fn(...args);
|
|
10
|
+
} else {
|
|
11
|
+
return () =>
|
|
12
|
+
new Promise((res, rej) => {
|
|
13
|
+
try {
|
|
14
|
+
const r = fn(...args);
|
|
15
|
+
setTimeout(() => res(r), time);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
rej(error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Run a list of functions in series, concurrently, or allSettled.
|
|
25
|
+
*
|
|
26
|
+
* @param {Array} params - A list of functions to run. Each function should be
|
|
27
|
+
* the first element of an array, and the remainder of the array should be
|
|
28
|
+
* the arguments to pass to the function.
|
|
29
|
+
* @param {Number} time - The amount of time to wait before resolving the
|
|
30
|
+
* promise. Defaults to 500ms.
|
|
31
|
+
* @return {Object} An object with `series`, `concurrent`, and `allSettled`
|
|
32
|
+
* properties. Each property is a function that takes no arguments and
|
|
33
|
+
* returns a promise. The promise resolves with the results of running the
|
|
34
|
+
* functions in the specified manner.
|
|
35
|
+
*/
|
|
36
|
+
function resolves(params, time = 500) {
|
|
37
|
+
const funs = params.map((w) => walkPromise(w, time));
|
|
38
|
+
const _funs = funs.map((f) => f());
|
|
39
|
+
const results = [];
|
|
40
|
+
const series = async () => {
|
|
41
|
+
for (const fn of _funs) {
|
|
42
|
+
const idx = _funs.indexOf(fn);
|
|
43
|
+
try {
|
|
44
|
+
const result = await new Promise((resolve) =>
|
|
45
|
+
setTimeout(resolve(fn), time),
|
|
46
|
+
);
|
|
47
|
+
results.push(result);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error(`Error in ${funs[idx].name}`);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return results;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Run the functions concurrently, meaning that all of the functions will be
|
|
58
|
+
* run simultaneously. If any of the functions reject, the promise returned
|
|
59
|
+
* by this function will reject with the same error.
|
|
60
|
+
*
|
|
61
|
+
* @return {Promise} A promise that resolves with an array of results from
|
|
62
|
+
* each of the functions, in the same order as the input `params`.
|
|
63
|
+
*/
|
|
64
|
+
const concurrent = async () => {
|
|
65
|
+
try {
|
|
66
|
+
const res = await Promise.all(_funs);
|
|
67
|
+
results.push(...res);
|
|
68
|
+
return results;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("One of the functions rejected:", error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Run the functions concurrently and return a promise that resolves when all
|
|
77
|
+
* of the functions have either resolved or rejected. If any of the functions
|
|
78
|
+
* reject, the promise returned by this function will not reject; instead, the
|
|
79
|
+
* error will be logged to the console and the process will exit with status 1.
|
|
80
|
+
*
|
|
81
|
+
* @return {Promise} A promise that resolves with an array of results from
|
|
82
|
+
* each of the functions, in the same order as the input `params`.
|
|
83
|
+
*/
|
|
84
|
+
const allSettled = async () => {
|
|
85
|
+
try {
|
|
86
|
+
const res = await Promise.allSettled(_funs);
|
|
87
|
+
results.push(
|
|
88
|
+
...res.filter((re) => re.status === "fulfilled").map((re) => re.value),
|
|
89
|
+
);
|
|
90
|
+
const errors = res
|
|
91
|
+
.filter((re) => re.status === "rejected")
|
|
92
|
+
.map((re) => re.reason);
|
|
93
|
+
if (errors.length) {
|
|
94
|
+
console.warn("One of the functions rejected:", errors[0]);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
return results;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error("One of the functions rejected:", error);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return { series, concurrent, allSettled };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
module.exports = resolves;
|
package/lib/index.d.cts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
2
|
+
type Fun<T> = (...arg: any) => T;
|
|
3
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
4
|
+
type Param<T> = [Fun<T>, ...any[]];
|
|
5
|
+
/**
|
|
6
|
+
* Run a list of functions in series, concurrently, or allSettled.
|
|
7
|
+
*
|
|
8
|
+
* @param {Array} params - A list of functions to run. Each function should be
|
|
9
|
+
* the first element of an array, and the remainder of the array should be
|
|
10
|
+
* the arguments to pass to the function.
|
|
11
|
+
* @param {Number} time - The amount of time to wait before resolving the
|
|
12
|
+
* promise. Defaults to 500ms.
|
|
13
|
+
* @return {Object} An object with `series`, `concurrent`, and `allSettled`
|
|
14
|
+
* properties. Each property is a function that takes no arguments and
|
|
15
|
+
* returns a promise. The promise resolves with the results of running the
|
|
16
|
+
* functions in the specified manner.
|
|
17
|
+
*/
|
|
18
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
19
|
+
declare function resolves<R extends any[]>(
|
|
20
|
+
params: { [K in keyof R]: Param<R[K]> },
|
|
21
|
+
time?: number,
|
|
22
|
+
): {
|
|
23
|
+
series: () => Promise<R>;
|
|
24
|
+
concurrent: () => Promise<R>;
|
|
25
|
+
allSettled: () => Promise<R>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export = resolves;
|
package/lib/index.d.mts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
2
|
+
type Fun<T> = (...arg: any) => T;
|
|
3
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
4
|
+
type Param<T> = [Fun<T>, ...any[]];
|
|
5
|
+
/**
|
|
6
|
+
* Run a list of functions in series, concurrently, or allSettled.
|
|
7
|
+
*
|
|
8
|
+
* @param {Array} params - A list of functions to run. Each function should be
|
|
9
|
+
* the first element of an array, and the remainder of the array should be
|
|
10
|
+
* the arguments to pass to the function.
|
|
11
|
+
* @param {Number} time - The amount of time to wait before resolving the
|
|
12
|
+
* promise. Defaults to 500ms.
|
|
13
|
+
* @return {Object} An object with `series`, `concurrent`, and `allSettled`
|
|
14
|
+
* properties. Each property is a function that takes no arguments and
|
|
15
|
+
* returns a promise. The promise resolves with the results of running the
|
|
16
|
+
* functions in the specified manner.
|
|
17
|
+
*/
|
|
18
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
19
|
+
declare function resolves<R extends any[]>(
|
|
20
|
+
params: { [K in keyof R]: Param<R[K]> },
|
|
21
|
+
time?: number,
|
|
22
|
+
): {
|
|
23
|
+
series: () => Promise<R>;
|
|
24
|
+
concurrent: () => Promise<R>;
|
|
25
|
+
allSettled: () => Promise<R>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default resolves;
|
package/lib/index.mjs
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
const isPromiseFun = (fun) =>
|
|
2
|
+
Object.prototype.toString.call(fun) === "[object AsyncFunction]" ||
|
|
3
|
+
fun.constructor.name === "AsyncFunction";
|
|
4
|
+
|
|
5
|
+
function walkPromise(param, time = 500) {
|
|
6
|
+
const fn = param[0];
|
|
7
|
+
const args = param.slice(1);
|
|
8
|
+
if (isPromiseFun(fn)) {
|
|
9
|
+
return () => fn(...args);
|
|
10
|
+
} else {
|
|
11
|
+
return () =>
|
|
12
|
+
new Promise((res, rej) => {
|
|
13
|
+
try {
|
|
14
|
+
const r = fn(...args);
|
|
15
|
+
setTimeout(() => res(r), time);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
rej(error);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Run a list of functions in series, concurrently, or allSettled.
|
|
25
|
+
*
|
|
26
|
+
* @param {Array} params - A list of functions to run. Each function should be
|
|
27
|
+
* the first element of an array, and the remainder of the array should be
|
|
28
|
+
* the arguments to pass to the function.
|
|
29
|
+
* @param {Number} time - The amount of time to wait before resolving the
|
|
30
|
+
* promise. Defaults to 500ms.
|
|
31
|
+
* @return {Object} An object with `series`, `concurrent`, and `allSettled`
|
|
32
|
+
* properties. Each property is a function that takes no arguments and
|
|
33
|
+
* returns a promise. The promise resolves with the results of running the
|
|
34
|
+
* functions in the specified manner.
|
|
35
|
+
*/
|
|
36
|
+
function resolves(params, time = 500) {
|
|
37
|
+
const funs = params.map((w) => walkPromise(w, time));
|
|
38
|
+
const _funs = funs.map((f) => f());
|
|
39
|
+
const results = [];
|
|
40
|
+
const series = async () => {
|
|
41
|
+
for (const fn of _funs) {
|
|
42
|
+
const idx = _funs.indexOf(fn);
|
|
43
|
+
try {
|
|
44
|
+
const result = await new Promise((resolve) =>
|
|
45
|
+
setTimeout(resolve(fn), time),
|
|
46
|
+
);
|
|
47
|
+
results.push(result);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error(`Error in ${funs[idx].name}`);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return results;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Run the functions concurrently, meaning that all of the functions will be
|
|
58
|
+
* run simultaneously. If any of the functions reject, the promise returned
|
|
59
|
+
* by this function will reject with the same error.
|
|
60
|
+
*
|
|
61
|
+
* @return {Promise} A promise that resolves with an array of results from
|
|
62
|
+
* each of the functions, in the same order as the input `params`.
|
|
63
|
+
*/
|
|
64
|
+
const concurrent = async () => {
|
|
65
|
+
try {
|
|
66
|
+
const res = await Promise.all(_funs);
|
|
67
|
+
results.push(...res);
|
|
68
|
+
return results;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error("One of the functions rejected:", error);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Run the functions concurrently and return a promise that resolves when all
|
|
77
|
+
* of the functions have either resolved or rejected. If any of the functions
|
|
78
|
+
* reject, the promise returned by this function will not reject; instead, the
|
|
79
|
+
* error will be logged to the console and the process will exit with status 1.
|
|
80
|
+
*
|
|
81
|
+
* @return {Promise} A promise that resolves with an array of results from
|
|
82
|
+
* each of the functions, in the same order as the input `params`.
|
|
83
|
+
*/
|
|
84
|
+
const allSettled = async () => {
|
|
85
|
+
try {
|
|
86
|
+
const res = await Promise.allSettled(_funs);
|
|
87
|
+
results.push(
|
|
88
|
+
...res.filter((re) => re.status === "fulfilled").map((re) => re.value),
|
|
89
|
+
);
|
|
90
|
+
const errors = res
|
|
91
|
+
.filter((re) => re.status === "rejected")
|
|
92
|
+
.map((re) => re.reason);
|
|
93
|
+
if (errors.length) {
|
|
94
|
+
console.warn("One of the functions rejected:", errors[0]);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
return results;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error("One of the functions rejected:", error);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
return { series, concurrent, allSettled };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export default resolves;
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phothinmaung/resolves",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Run a list of functions in series, concurrently, or allSettled.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.cjs",
|
|
7
|
+
"module": "lib/index.mjs",
|
|
8
|
+
"types": "lib/index.d.cts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"require": {
|
|
12
|
+
"types": "./lib/index.d.cts",
|
|
13
|
+
"default": "./lib/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./lib/index.d.mts",
|
|
17
|
+
"default": "./lib/index.mjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"Promise",
|
|
23
|
+
"resolved"
|
|
24
|
+
],
|
|
25
|
+
"author": {
|
|
26
|
+
"name": "Pho Thin Mg",
|
|
27
|
+
"email": "phothinmg@disroot.org",
|
|
28
|
+
"url": "https://phothinmg.github.io/"
|
|
29
|
+
},
|
|
30
|
+
"license": "ISC",
|
|
31
|
+
"files": [
|
|
32
|
+
"lib",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"README.md",
|
|
35
|
+
"package.json"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"url": "git+https://github.com/phothinmg/resolves.git",
|
|
42
|
+
"type": "git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/phothinmg/resolves/issues"
|
|
46
|
+
}
|
|
47
|
+
}
|