@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 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;
@@ -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;
@@ -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
+ }