@nestia/e2e 8.0.0-dev.20250829 → 8.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 +21 -21
- package/README.md +93 -93
- package/lib/ArrayUtil.d.ts +15 -15
- package/lib/ArrayUtil.js +39 -41
- package/lib/ArrayUtil.js.map +1 -1
- package/package.json +1 -1
- package/src/ArrayUtil.ts +29 -30
- package/src/MapUtil.ts +86 -86
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2023 Jeongho Nam
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jeongho Nam
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
# Nestia
|
|
2
|
-

|
|
3
|
-
|
|
4
|
-
[](https://github.com/samchon/nestia/blob/master/LICENSE)
|
|
5
|
-
[](https://www.npmjs.com/package/@nestia/fetcher)
|
|
6
|
-
[](https://www.npmjs.com/package/@nestia/fetcher)
|
|
7
|
-
[](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
|
|
8
|
-
[](https://nestia.io/docs/)
|
|
9
|
-
[](https://gurubase.io/g/nestia)
|
|
10
|
-
[](https://discord.gg/E94XhzrUCZ)
|
|
11
|
-
|
|
12
|
-
Nestia is a set of helper libraries for NestJS, supporting below features:
|
|
13
|
-
|
|
14
|
-
- `@nestia/core`:
|
|
15
|
-
- Super-fast/easy decorators
|
|
16
|
-
- Advanced WebSocket routes
|
|
17
|
-
- `@nestia/sdk`:
|
|
18
|
-
- Swagger generator, more evolved than ever
|
|
19
|
-
- SDK library generator for clients
|
|
20
|
-
- Mockup Simulator for client applications
|
|
21
|
-
- Automatic E2E test functions generator
|
|
22
|
-
- `@nestia/e2e`: Test program utilizing e2e test functions
|
|
23
|
-
- `@nestia/benchmark`: Benchmark program using e2e test functions
|
|
24
|
-
- `@nestia/editor`: Swagger-UI with Online TypeScript Editor
|
|
25
|
-
- [`@agentica`](https://github.com/wrtnlabs/agentica): Agentic AI library specialized in LLM function calling
|
|
26
|
-
- [`@autobe`](https://github.com/wrtnlabs/autobe): Vibe coding agent generating NestJS application
|
|
27
|
-
- `nestia`: Just CLI (command line interface) tool
|
|
28
|
-
|
|
29
|
-
> [!NOTE]
|
|
30
|
-
>
|
|
31
|
-
> - **Only one line** required, with pure TypeScript type
|
|
32
|
-
> - Enhance performance **30x** up
|
|
33
|
-
> - Runtime validator is **20,000x faster** than `class-validator`
|
|
34
|
-
> - JSON serialization is **200x faster** than `class-transformer`
|
|
35
|
-
> - Software Development Kit
|
|
36
|
-
> - Collection of typed `fetch` functions with DTO structures like [tRPC](https://trpc.io/)
|
|
37
|
-
> - Mockup simulator means embedded backend simulator in the SDK
|
|
38
|
-
> - similar with [msw](https://mswjs.io/), but fully automated
|
|
39
|
-
|
|
40
|
-

|
|
41
|
-
|
|
42
|
-
> Left is NestJS server code, and right is client (frontend) code utilizing SDK
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Sponsors and Backers
|
|
48
|
-
Thanks for your support.
|
|
49
|
-
|
|
50
|
-
Your donation would encourage `nestia` development.
|
|
51
|
-
|
|
52
|
-
[](https://opencollective.com/nestia)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
## Guide Documents
|
|
58
|
-
Check out the document in the [website](https://nestia.io/docs/):
|
|
59
|
-
|
|
60
|
-
### 🏠 Home
|
|
61
|
-
- [Introduction](https://nestia.io/docs/)
|
|
62
|
-
- [Setup](https://nestia.io/docs/setup/)
|
|
63
|
-
- [Pure TypeScript](https://nestia.io/docs/pure)
|
|
64
|
-
|
|
65
|
-
### 📖 Features
|
|
66
|
-
- Core Library
|
|
67
|
-
- [`@WebSocketRoute`](https://nestia.io/docs/core/WebSocketRoute)
|
|
68
|
-
- [`@TypedRoute`](https://nestia.io/docs/core/TypedRoute/)
|
|
69
|
-
- [**`@TypedBody`**](https://nestia.io/docs/core/TypedBody/)
|
|
70
|
-
- [`@TypedParam`](https://nestia.io/docs/core/TypedParam/)
|
|
71
|
-
- [`@TypedQuery`](https://nestia.io/docs/core/TypedQuery/)
|
|
72
|
-
- [`@TypedFormData`](https://nestia.io/docs/core/TypedFormData/)
|
|
73
|
-
- [`@TypedHeaders`](https://nestia.io/docs/core/TypedHeaders/)
|
|
74
|
-
- [`@TypedException`](https://nestia.io/docs/core/TypedException/)
|
|
75
|
-
- Software Development Kit
|
|
76
|
-
- [SDK Builder](https://nestia.io/docs/sdk/)
|
|
77
|
-
- [Mockup Simulator](https://nestia.io/docs/sdk/simulate/)
|
|
78
|
-
- [E2E Test Functions](https://nestia.io/docs/sdk/e2e/)
|
|
79
|
-
- [Distribution](https://nestia.io/docs/sdk/distribute/)
|
|
80
|
-
- Swagger Document
|
|
81
|
-
- [Swagger Builder](https://nestia.io/docs/swagger/)
|
|
82
|
-
- [**AI Chatbot Development**](https://nestia.io/docs/swagger/chat/)
|
|
83
|
-
- [Cloud Swagger Editor](https://nestia.io/docs/swagger/editor/)
|
|
84
|
-
- [Documentation Strategy](https://nestia.io/docs/swagger/strategy/)
|
|
85
|
-
- E2E Testing
|
|
86
|
-
- [Why E2E Test?](https://nestia.io/docs/e2e/why/)
|
|
87
|
-
- [Test Program Development](https://nestia.io/docs/e2e/development/)
|
|
88
|
-
- [Performance Benchmark](https://nestia.io/docs/e2e/benchmark/)
|
|
89
|
-
|
|
90
|
-
### 🔗 Appendix
|
|
91
|
-
- [API Documents](https://nestia.io/api)
|
|
92
|
-
- [⇲ Benchmark Result](https://github.com/samchon/nestia/tree/master/benchmark/results/11th%20Gen%20Intel(R)%20Core(TM)%20i5-1135G7%20%40%202.40GHz)
|
|
93
|
-
- [⇲ `dev.to` Articles](https://dev.to/samchon/series/22751)
|
|
1
|
+
# Nestia
|
|
2
|
+

|
|
3
|
+
|
|
4
|
+
[](https://github.com/samchon/nestia/blob/master/LICENSE)
|
|
5
|
+
[](https://www.npmjs.com/package/@nestia/fetcher)
|
|
6
|
+
[](https://www.npmjs.com/package/@nestia/fetcher)
|
|
7
|
+
[](https://github.com/samchon/nestia/actions?query=workflow%3Abuild)
|
|
8
|
+
[](https://nestia.io/docs/)
|
|
9
|
+
[](https://gurubase.io/g/nestia)
|
|
10
|
+
[](https://discord.gg/E94XhzrUCZ)
|
|
11
|
+
|
|
12
|
+
Nestia is a set of helper libraries for NestJS, supporting below features:
|
|
13
|
+
|
|
14
|
+
- `@nestia/core`:
|
|
15
|
+
- Super-fast/easy decorators
|
|
16
|
+
- Advanced WebSocket routes
|
|
17
|
+
- `@nestia/sdk`:
|
|
18
|
+
- Swagger generator, more evolved than ever
|
|
19
|
+
- SDK library generator for clients
|
|
20
|
+
- Mockup Simulator for client applications
|
|
21
|
+
- Automatic E2E test functions generator
|
|
22
|
+
- `@nestia/e2e`: Test program utilizing e2e test functions
|
|
23
|
+
- `@nestia/benchmark`: Benchmark program using e2e test functions
|
|
24
|
+
- `@nestia/editor`: Swagger-UI with Online TypeScript Editor
|
|
25
|
+
- [`@agentica`](https://github.com/wrtnlabs/agentica): Agentic AI library specialized in LLM function calling
|
|
26
|
+
- [`@autobe`](https://github.com/wrtnlabs/autobe): Vibe coding agent generating NestJS application
|
|
27
|
+
- `nestia`: Just CLI (command line interface) tool
|
|
28
|
+
|
|
29
|
+
> [!NOTE]
|
|
30
|
+
>
|
|
31
|
+
> - **Only one line** required, with pure TypeScript type
|
|
32
|
+
> - Enhance performance **30x** up
|
|
33
|
+
> - Runtime validator is **20,000x faster** than `class-validator`
|
|
34
|
+
> - JSON serialization is **200x faster** than `class-transformer`
|
|
35
|
+
> - Software Development Kit
|
|
36
|
+
> - Collection of typed `fetch` functions with DTO structures like [tRPC](https://trpc.io/)
|
|
37
|
+
> - Mockup simulator means embedded backend simulator in the SDK
|
|
38
|
+
> - similar with [msw](https://mswjs.io/), but fully automated
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
> Left is NestJS server code, and right is client (frontend) code utilizing SDK
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Sponsors and Backers
|
|
48
|
+
Thanks for your support.
|
|
49
|
+
|
|
50
|
+
Your donation would encourage `nestia` development.
|
|
51
|
+
|
|
52
|
+
[](https://opencollective.com/nestia)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
## Guide Documents
|
|
58
|
+
Check out the document in the [website](https://nestia.io/docs/):
|
|
59
|
+
|
|
60
|
+
### 🏠 Home
|
|
61
|
+
- [Introduction](https://nestia.io/docs/)
|
|
62
|
+
- [Setup](https://nestia.io/docs/setup/)
|
|
63
|
+
- [Pure TypeScript](https://nestia.io/docs/pure)
|
|
64
|
+
|
|
65
|
+
### 📖 Features
|
|
66
|
+
- Core Library
|
|
67
|
+
- [`@WebSocketRoute`](https://nestia.io/docs/core/WebSocketRoute)
|
|
68
|
+
- [`@TypedRoute`](https://nestia.io/docs/core/TypedRoute/)
|
|
69
|
+
- [**`@TypedBody`**](https://nestia.io/docs/core/TypedBody/)
|
|
70
|
+
- [`@TypedParam`](https://nestia.io/docs/core/TypedParam/)
|
|
71
|
+
- [`@TypedQuery`](https://nestia.io/docs/core/TypedQuery/)
|
|
72
|
+
- [`@TypedFormData`](https://nestia.io/docs/core/TypedFormData/)
|
|
73
|
+
- [`@TypedHeaders`](https://nestia.io/docs/core/TypedHeaders/)
|
|
74
|
+
- [`@TypedException`](https://nestia.io/docs/core/TypedException/)
|
|
75
|
+
- Software Development Kit
|
|
76
|
+
- [SDK Builder](https://nestia.io/docs/sdk/)
|
|
77
|
+
- [Mockup Simulator](https://nestia.io/docs/sdk/simulate/)
|
|
78
|
+
- [E2E Test Functions](https://nestia.io/docs/sdk/e2e/)
|
|
79
|
+
- [Distribution](https://nestia.io/docs/sdk/distribute/)
|
|
80
|
+
- Swagger Document
|
|
81
|
+
- [Swagger Builder](https://nestia.io/docs/swagger/)
|
|
82
|
+
- [**AI Chatbot Development**](https://nestia.io/docs/swagger/chat/)
|
|
83
|
+
- [Cloud Swagger Editor](https://nestia.io/docs/swagger/editor/)
|
|
84
|
+
- [Documentation Strategy](https://nestia.io/docs/swagger/strategy/)
|
|
85
|
+
- E2E Testing
|
|
86
|
+
- [Why E2E Test?](https://nestia.io/docs/e2e/why/)
|
|
87
|
+
- [Test Program Development](https://nestia.io/docs/e2e/development/)
|
|
88
|
+
- [Performance Benchmark](https://nestia.io/docs/e2e/benchmark/)
|
|
89
|
+
|
|
90
|
+
### 🔗 Appendix
|
|
91
|
+
- [API Documents](https://nestia.io/api)
|
|
92
|
+
- [⇲ Benchmark Result](https://github.com/samchon/nestia/tree/master/benchmark/results/11th%20Gen%20Intel(R)%20Core(TM)%20i5-1135G7%20%40%202.40GHz)
|
|
93
|
+
- [⇲ `dev.to` Articles](https://dev.to/samchon/series/22751)
|
package/lib/ArrayUtil.d.ts
CHANGED
|
@@ -64,10 +64,10 @@ export declare namespace ArrayUtil {
|
|
|
64
64
|
* const urls = ['url1', 'url2', 'url3'];
|
|
65
65
|
*
|
|
66
66
|
* await ArrayUtil.asyncForEach(urls, async (url, index) => {
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
67
|
+
* console.log(`Processing ${index}: ${url}`);
|
|
68
|
+
* const data = await fetch(url);
|
|
69
|
+
* await processData(data);
|
|
70
|
+
* console.log(`Completed ${index}: ${url}`);
|
|
71
71
|
* });
|
|
72
72
|
* console.log('All URLs processed sequentially');
|
|
73
73
|
* ```
|
|
@@ -92,11 +92,11 @@ export declare namespace ArrayUtil {
|
|
|
92
92
|
* const userIds = [1, 2, 3, 4, 5];
|
|
93
93
|
*
|
|
94
94
|
* const userDetails = await ArrayUtil.asyncMap(userIds)(
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
95
|
+
* async (id, index) => {
|
|
96
|
+
* console.log(`Fetching user ${id} (${index + 1}/${userIds.length})`);
|
|
97
|
+
* const response = await fetch(`/api/users/${id}`);
|
|
98
|
+
* return await response.json();
|
|
99
|
+
* }
|
|
100
100
|
* );
|
|
101
101
|
* console.log('All users fetched:', userDetails);
|
|
102
102
|
* ```
|
|
@@ -106,7 +106,7 @@ export declare namespace ArrayUtil {
|
|
|
106
106
|
* @returns A function that takes a transformation function and returns a
|
|
107
107
|
* Promise resolving to the transformed array
|
|
108
108
|
*/
|
|
109
|
-
const asyncMap: <Input>(elements: readonly Input[]
|
|
109
|
+
const asyncMap: <Input, Output>(elements: readonly Input[], closure: (elem: Input, index: number, array: readonly Input[]) => Promise<Output>) => Promise<Output[]>;
|
|
110
110
|
/**
|
|
111
111
|
* Executes an asynchronous function a specified number of times sequentially.
|
|
112
112
|
*
|
|
@@ -137,8 +137,8 @@ export declare namespace ArrayUtil {
|
|
|
137
137
|
/**
|
|
138
138
|
* Checks if at least one element in the array satisfies the given condition.
|
|
139
139
|
*
|
|
140
|
-
* Similar to JavaScript's native some() method. Returns true immediately
|
|
141
|
-
*
|
|
140
|
+
* Similar to JavaScript's native some() method. Returns true immediately when
|
|
141
|
+
* the first element satisfying the condition is found.
|
|
142
142
|
*
|
|
143
143
|
* @example
|
|
144
144
|
* ```typescript
|
|
@@ -180,9 +180,9 @@ export declare namespace ArrayUtil {
|
|
|
180
180
|
*
|
|
181
181
|
* // Generate an array of default user objects
|
|
182
182
|
* const users = ArrayUtil.repeat(3, index => ({
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
183
|
+
* id: index + 1,
|
|
184
|
+
* name: `User${index + 1}`,
|
|
185
|
+
* email: `user${index + 1}@example.com`
|
|
186
186
|
* }));
|
|
187
187
|
* console.log(users);
|
|
188
188
|
* // [
|
package/lib/ArrayUtil.js
CHANGED
|
@@ -141,10 +141,10 @@ var ArrayUtil;
|
|
|
141
141
|
* const urls = ['url1', 'url2', 'url3'];
|
|
142
142
|
*
|
|
143
143
|
* await ArrayUtil.asyncForEach(urls, async (url, index) => {
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
144
|
+
* console.log(`Processing ${index}: ${url}`);
|
|
145
|
+
* const data = await fetch(url);
|
|
146
|
+
* await processData(data);
|
|
147
|
+
* console.log(`Completed ${index}: ${url}`);
|
|
148
148
|
* });
|
|
149
149
|
* console.log('All URLs processed sequentially');
|
|
150
150
|
* ```
|
|
@@ -180,11 +180,11 @@ var ArrayUtil;
|
|
|
180
180
|
* const userIds = [1, 2, 3, 4, 5];
|
|
181
181
|
*
|
|
182
182
|
* const userDetails = await ArrayUtil.asyncMap(userIds)(
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
183
|
+
* async (id, index) => {
|
|
184
|
+
* console.log(`Fetching user ${id} (${index + 1}/${userIds.length})`);
|
|
185
|
+
* const response = await fetch(`/api/users/${id}`);
|
|
186
|
+
* return await response.json();
|
|
187
|
+
* }
|
|
188
188
|
* );
|
|
189
189
|
* console.log('All users fetched:', userDetails);
|
|
190
190
|
* ```
|
|
@@ -194,33 +194,31 @@ var ArrayUtil;
|
|
|
194
194
|
* @returns A function that takes a transformation function and returns a
|
|
195
195
|
* Promise resolving to the transformed array
|
|
196
196
|
*/
|
|
197
|
-
ArrayUtil.asyncMap = function (elements) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}); };
|
|
223
|
-
};
|
|
197
|
+
ArrayUtil.asyncMap = function (elements, closure) { return __awaiter(_this, void 0, void 0, function () {
|
|
198
|
+
var ret;
|
|
199
|
+
var _this = this;
|
|
200
|
+
return __generator(this, function (_a) {
|
|
201
|
+
switch (_a.label) {
|
|
202
|
+
case 0:
|
|
203
|
+
ret = [];
|
|
204
|
+
return [4 /*yield*/, ArrayUtil.asyncForEach(elements, function (elem, index, array) { return __awaiter(_this, void 0, void 0, function () {
|
|
205
|
+
var output;
|
|
206
|
+
return __generator(this, function (_a) {
|
|
207
|
+
switch (_a.label) {
|
|
208
|
+
case 0: return [4 /*yield*/, closure(elem, index, array)];
|
|
209
|
+
case 1:
|
|
210
|
+
output = _a.sent();
|
|
211
|
+
ret.push(output);
|
|
212
|
+
return [2 /*return*/];
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}); })];
|
|
216
|
+
case 1:
|
|
217
|
+
_a.sent();
|
|
218
|
+
return [2 /*return*/, ret];
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}); };
|
|
224
222
|
/**
|
|
225
223
|
* Executes an asynchronous function a specified number of times sequentially.
|
|
226
224
|
*
|
|
@@ -289,8 +287,8 @@ var ArrayUtil;
|
|
|
289
287
|
/**
|
|
290
288
|
* Checks if at least one element in the array satisfies the given condition.
|
|
291
289
|
*
|
|
292
|
-
* Similar to JavaScript's native some() method. Returns true immediately
|
|
293
|
-
*
|
|
290
|
+
* Similar to JavaScript's native some() method. Returns true immediately when
|
|
291
|
+
* the first element satisfying the condition is found.
|
|
294
292
|
*
|
|
295
293
|
* @example
|
|
296
294
|
* ```typescript
|
|
@@ -332,9 +330,9 @@ var ArrayUtil;
|
|
|
332
330
|
*
|
|
333
331
|
* // Generate an array of default user objects
|
|
334
332
|
* const users = ArrayUtil.repeat(3, index => ({
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
333
|
+
* id: index + 1,
|
|
334
|
+
* name: `User${index + 1}`,
|
|
335
|
+
* email: `user${index + 1}@example.com`
|
|
338
336
|
* }));
|
|
339
337
|
* console.log(users);
|
|
340
338
|
* // [
|
package/lib/ArrayUtil.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrayUtil.js","sourceRoot":"","sources":["../src/ArrayUtil.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,IAAiB,SAAS,
|
|
1
|
+
{"version":3,"file":"ArrayUtil.js","sourceRoot":"","sources":["../src/ArrayUtil.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/ArrayUtil.ts
CHANGED
|
@@ -79,10 +79,10 @@ export namespace ArrayUtil {
|
|
|
79
79
|
* const urls = ['url1', 'url2', 'url3'];
|
|
80
80
|
*
|
|
81
81
|
* await ArrayUtil.asyncForEach(urls, async (url, index) => {
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
82
|
+
* console.log(`Processing ${index}: ${url}`);
|
|
83
|
+
* const data = await fetch(url);
|
|
84
|
+
* await processData(data);
|
|
85
|
+
* console.log(`Completed ${index}: ${url}`);
|
|
86
86
|
* });
|
|
87
87
|
* console.log('All URLs processed sequentially');
|
|
88
88
|
* ```
|
|
@@ -119,11 +119,11 @@ export namespace ArrayUtil {
|
|
|
119
119
|
* const userIds = [1, 2, 3, 4, 5];
|
|
120
120
|
*
|
|
121
121
|
* const userDetails = await ArrayUtil.asyncMap(userIds)(
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
122
|
+
* async (id, index) => {
|
|
123
|
+
* console.log(`Fetching user ${id} (${index + 1}/${userIds.length})`);
|
|
124
|
+
* const response = await fetch(`/api/users/${id}`);
|
|
125
|
+
* return await response.json();
|
|
126
|
+
* }
|
|
127
127
|
* );
|
|
128
128
|
* console.log('All users fetched:', userDetails);
|
|
129
129
|
* ```
|
|
@@ -133,22 +133,21 @@ export namespace ArrayUtil {
|
|
|
133
133
|
* @returns A function that takes a transformation function and returns a
|
|
134
134
|
* Promise resolving to the transformed array
|
|
135
135
|
*/
|
|
136
|
-
export const asyncMap =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
};
|
|
136
|
+
export const asyncMap = async <Input, Output>(
|
|
137
|
+
elements: readonly Input[],
|
|
138
|
+
closure: (
|
|
139
|
+
elem: Input,
|
|
140
|
+
index: number,
|
|
141
|
+
array: readonly Input[],
|
|
142
|
+
) => Promise<Output>,
|
|
143
|
+
): Promise<Output[]> => {
|
|
144
|
+
const ret: Output[] = [];
|
|
145
|
+
await asyncForEach(elements, async (elem, index, array) => {
|
|
146
|
+
const output: Output = await closure(elem, index, array);
|
|
147
|
+
ret.push(output);
|
|
148
|
+
});
|
|
149
|
+
return ret;
|
|
150
|
+
};
|
|
152
151
|
|
|
153
152
|
/**
|
|
154
153
|
* Executes an asynchronous function a specified number of times sequentially.
|
|
@@ -189,8 +188,8 @@ export namespace ArrayUtil {
|
|
|
189
188
|
/**
|
|
190
189
|
* Checks if at least one element in the array satisfies the given condition.
|
|
191
190
|
*
|
|
192
|
-
* Similar to JavaScript's native some() method. Returns true immediately
|
|
193
|
-
*
|
|
191
|
+
* Similar to JavaScript's native some() method. Returns true immediately when
|
|
192
|
+
* the first element satisfying the condition is found.
|
|
194
193
|
*
|
|
195
194
|
* @example
|
|
196
195
|
* ```typescript
|
|
@@ -236,9 +235,9 @@ export namespace ArrayUtil {
|
|
|
236
235
|
*
|
|
237
236
|
* // Generate an array of default user objects
|
|
238
237
|
* const users = ArrayUtil.repeat(3, index => ({
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
238
|
+
* id: index + 1,
|
|
239
|
+
* name: `User${index + 1}`,
|
|
240
|
+
* email: `user${index + 1}@example.com`
|
|
242
241
|
* }));
|
|
243
242
|
* console.log(users);
|
|
244
243
|
* // [
|
package/src/MapUtil.ts
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A namespace providing utility functions for Map manipulation.
|
|
3
|
-
*
|
|
4
|
-
* This namespace contains helper functions for working with JavaScript Map
|
|
5
|
-
* objects, providing convenient methods for common Map operations like
|
|
6
|
-
* retrieving values with lazy initialization.
|
|
7
|
-
*
|
|
8
|
-
* @author Jeongho Nam - https://github.com/samchon
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* // Create a cache with lazy initialization
|
|
12
|
-
* const cache = new Map<string, ExpensiveObject>();
|
|
13
|
-
*
|
|
14
|
-
* const obj = MapUtil.take(cache, "key1", () => {
|
|
15
|
-
* console.log("Creating expensive object...");
|
|
16
|
-
* return new ExpensiveObject();
|
|
17
|
-
* });
|
|
18
|
-
*
|
|
19
|
-
* // Subsequent calls return cached value without re-creating
|
|
20
|
-
* const sameObj = MapUtil.take(cache, "key1", () => new ExpensiveObject());
|
|
21
|
-
* console.log(obj === sameObj); // true
|
|
22
|
-
* ```;
|
|
23
|
-
*/
|
|
24
|
-
export namespace MapUtil {
|
|
25
|
-
/**
|
|
26
|
-
* Retrieves a value from a Map or creates it using a lazy initialization
|
|
27
|
-
* function.
|
|
28
|
-
*
|
|
29
|
-
* This function implements the "get or create" pattern for Maps. If the key
|
|
30
|
-
* exists in the Map, it returns the existing value. Otherwise, it calls the
|
|
31
|
-
* provided factory function to create a new value, stores it in the Map, and
|
|
32
|
-
* returns it. The factory function is only called when the key doesn't exist,
|
|
33
|
-
* enabling lazy initialization and caching patterns.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```typescript
|
|
37
|
-
* // Simple caching example
|
|
38
|
-
* const userCache = new Map<number, User>();
|
|
39
|
-
*
|
|
40
|
-
* const user = MapUtil.take(userCache, userId, () => {
|
|
41
|
-
* // This expensive operation only runs if userId is not cached
|
|
42
|
-
* return fetchUserFromDatabase(userId);
|
|
43
|
-
* });
|
|
44
|
-
*
|
|
45
|
-
* // Configuration object caching
|
|
46
|
-
* const configs = new Map<string, Config>();
|
|
47
|
-
*
|
|
48
|
-
* const dbConfig = MapUtil.take(configs, "database", () => ({
|
|
49
|
-
* host: "localhost",
|
|
50
|
-
* port: 5432,
|
|
51
|
-
* database: "myapp"
|
|
52
|
-
* }));
|
|
53
|
-
*
|
|
54
|
-
* // Lazy computation results
|
|
55
|
-
* const computationCache = new Map<string, number>();
|
|
56
|
-
*
|
|
57
|
-
* const result = MapUtil.take(computationCache, "fibonacci-40", () => {
|
|
58
|
-
* console.log("Computing fibonacci(40)...");
|
|
59
|
-
* return fibonacci(40); // Only computed once
|
|
60
|
-
* });
|
|
61
|
-
*
|
|
62
|
-
* // Using with complex keys
|
|
63
|
-
* const cache = new Map<[number, number], Matrix>();
|
|
64
|
-
* const key: [number, number] = [rows, cols];
|
|
65
|
-
*
|
|
66
|
-
* const matrix = MapUtil.take(cache, key, () =>
|
|
67
|
-
* generateIdentityMatrix(rows, cols)
|
|
68
|
-
* );
|
|
69
|
-
* ```;
|
|
70
|
-
*
|
|
71
|
-
* @template K - The type of keys in the Map
|
|
72
|
-
* @template V - The type of values in the Map
|
|
73
|
-
* @param map - The Map to retrieve from or update
|
|
74
|
-
* @param key - The key to look up in the Map
|
|
75
|
-
* @param value - A factory function that creates the value if key doesn't exist
|
|
76
|
-
* @returns The existing value if found, or the newly created value
|
|
77
|
-
*/
|
|
78
|
-
export function take<K, V>(map: Map<K, V>, key: K, value: () => V): V {
|
|
79
|
-
if (map.has(key)) {
|
|
80
|
-
return map.get(key) as V;
|
|
81
|
-
}
|
|
82
|
-
const newValue = value();
|
|
83
|
-
map.set(key, newValue);
|
|
84
|
-
return newValue;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* A namespace providing utility functions for Map manipulation.
|
|
3
|
+
*
|
|
4
|
+
* This namespace contains helper functions for working with JavaScript Map
|
|
5
|
+
* objects, providing convenient methods for common Map operations like
|
|
6
|
+
* retrieving values with lazy initialization.
|
|
7
|
+
*
|
|
8
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Create a cache with lazy initialization
|
|
12
|
+
* const cache = new Map<string, ExpensiveObject>();
|
|
13
|
+
*
|
|
14
|
+
* const obj = MapUtil.take(cache, "key1", () => {
|
|
15
|
+
* console.log("Creating expensive object...");
|
|
16
|
+
* return new ExpensiveObject();
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Subsequent calls return cached value without re-creating
|
|
20
|
+
* const sameObj = MapUtil.take(cache, "key1", () => new ExpensiveObject());
|
|
21
|
+
* console.log(obj === sameObj); // true
|
|
22
|
+
* ```;
|
|
23
|
+
*/
|
|
24
|
+
export namespace MapUtil {
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves a value from a Map or creates it using a lazy initialization
|
|
27
|
+
* function.
|
|
28
|
+
*
|
|
29
|
+
* This function implements the "get or create" pattern for Maps. If the key
|
|
30
|
+
* exists in the Map, it returns the existing value. Otherwise, it calls the
|
|
31
|
+
* provided factory function to create a new value, stores it in the Map, and
|
|
32
|
+
* returns it. The factory function is only called when the key doesn't exist,
|
|
33
|
+
* enabling lazy initialization and caching patterns.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Simple caching example
|
|
38
|
+
* const userCache = new Map<number, User>();
|
|
39
|
+
*
|
|
40
|
+
* const user = MapUtil.take(userCache, userId, () => {
|
|
41
|
+
* // This expensive operation only runs if userId is not cached
|
|
42
|
+
* return fetchUserFromDatabase(userId);
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Configuration object caching
|
|
46
|
+
* const configs = new Map<string, Config>();
|
|
47
|
+
*
|
|
48
|
+
* const dbConfig = MapUtil.take(configs, "database", () => ({
|
|
49
|
+
* host: "localhost",
|
|
50
|
+
* port: 5432,
|
|
51
|
+
* database: "myapp"
|
|
52
|
+
* }));
|
|
53
|
+
*
|
|
54
|
+
* // Lazy computation results
|
|
55
|
+
* const computationCache = new Map<string, number>();
|
|
56
|
+
*
|
|
57
|
+
* const result = MapUtil.take(computationCache, "fibonacci-40", () => {
|
|
58
|
+
* console.log("Computing fibonacci(40)...");
|
|
59
|
+
* return fibonacci(40); // Only computed once
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Using with complex keys
|
|
63
|
+
* const cache = new Map<[number, number], Matrix>();
|
|
64
|
+
* const key: [number, number] = [rows, cols];
|
|
65
|
+
*
|
|
66
|
+
* const matrix = MapUtil.take(cache, key, () =>
|
|
67
|
+
* generateIdentityMatrix(rows, cols)
|
|
68
|
+
* );
|
|
69
|
+
* ```;
|
|
70
|
+
*
|
|
71
|
+
* @template K - The type of keys in the Map
|
|
72
|
+
* @template V - The type of values in the Map
|
|
73
|
+
* @param map - The Map to retrieve from or update
|
|
74
|
+
* @param key - The key to look up in the Map
|
|
75
|
+
* @param value - A factory function that creates the value if key doesn't exist
|
|
76
|
+
* @returns The existing value if found, or the newly created value
|
|
77
|
+
*/
|
|
78
|
+
export function take<K, V>(map: Map<K, V>, key: K, value: () => V): V {
|
|
79
|
+
if (map.has(key)) {
|
|
80
|
+
return map.get(key) as V;
|
|
81
|
+
}
|
|
82
|
+
const newValue = value();
|
|
83
|
+
map.set(key, newValue);
|
|
84
|
+
return newValue;
|
|
85
|
+
}
|
|
86
|
+
}
|