@oscarpalmer/atoms 0.158.0 → 0.160.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.
Files changed (120) hide show
  1. package/dist/array/difference.js +2 -0
  2. package/dist/array/exists.js +2 -0
  3. package/dist/array/filter.js +2 -0
  4. package/dist/array/find.js +2 -0
  5. package/dist/array/flatten.js +2 -0
  6. package/dist/array/from.js +2 -0
  7. package/dist/array/get.js +2 -0
  8. package/dist/array/group-by.js +2 -0
  9. package/dist/array/index-of.js +2 -0
  10. package/dist/array/index.js +2 -1
  11. package/dist/array/insert.js +2 -0
  12. package/dist/array/intersection.js +2 -0
  13. package/dist/array/partition.js +2 -0
  14. package/dist/array/position.js +58 -0
  15. package/dist/array/push.js +2 -0
  16. package/dist/array/select.js +2 -0
  17. package/dist/array/slice.js +2 -0
  18. package/dist/array/sort.js +2 -0
  19. package/dist/array/splice.js +2 -0
  20. package/dist/array/to-map.js +2 -0
  21. package/dist/array/to-record.js +2 -0
  22. package/dist/array/to-set.js +2 -0
  23. package/dist/array/toggle.js +2 -0
  24. package/dist/array/union.js +2 -0
  25. package/dist/array/unique.js +2 -0
  26. package/dist/array/update.js +2 -0
  27. package/dist/atoms.full.js +223 -162
  28. package/dist/beacon.js +2 -0
  29. package/dist/color/constants.js +35 -33
  30. package/dist/color/index.js +2 -0
  31. package/dist/color/instance.js +2 -0
  32. package/dist/color/misc/alpha.js +2 -0
  33. package/dist/color/misc/get.js +2 -0
  34. package/dist/color/misc/index.js +2 -0
  35. package/dist/color/misc/is.js +2 -0
  36. package/dist/color/misc/state.js +2 -0
  37. package/dist/color/space/hex.js +2 -0
  38. package/dist/color/space/hsl.js +2 -0
  39. package/dist/color/space/rgb.js +2 -0
  40. package/dist/function/assert.js +2 -0
  41. package/dist/function/index.js +2 -0
  42. package/dist/function/memoize.js +2 -0
  43. package/dist/function/once.js +2 -0
  44. package/dist/function/retry.js +2 -0
  45. package/dist/function/work.js +2 -0
  46. package/dist/index.js +5 -4
  47. package/dist/internal/array/callbacks.js +2 -0
  48. package/dist/internal/array/chunk.js +2 -0
  49. package/dist/internal/array/compact.js +2 -0
  50. package/dist/internal/array/find.js +6 -4
  51. package/dist/internal/array/group.js +2 -0
  52. package/dist/internal/array/insert.js +2 -0
  53. package/dist/internal/array/sets.js +8 -6
  54. package/dist/internal/array/shuffle.js +3 -1
  55. package/dist/internal/array/update.js +2 -0
  56. package/dist/internal/function/misc.js +2 -0
  57. package/dist/internal/function/timer.js +5 -3
  58. package/dist/internal/is.js +2 -0
  59. package/dist/internal/math/aggregate.js +2 -0
  60. package/dist/internal/number.js +2 -0
  61. package/dist/internal/random.js +2 -0
  62. package/dist/internal/result.js +2 -0
  63. package/dist/internal/sized.js +2 -0
  64. package/dist/internal/string.js +2 -0
  65. package/dist/internal/value/compare.js +2 -0
  66. package/dist/internal/value/equal.js +2 -0
  67. package/dist/internal/value/get.js +2 -0
  68. package/dist/internal/value/handlers.js +2 -0
  69. package/dist/internal/value/has.js +2 -0
  70. package/dist/internal/value/misc.js +2 -0
  71. package/dist/internal/value/partial.js +2 -0
  72. package/dist/internal/value/set.js +2 -0
  73. package/dist/is.js +2 -0
  74. package/dist/logger.js +2 -0
  75. package/dist/math.js +2 -0
  76. package/dist/promise/delay.js +3 -1
  77. package/dist/promise/helpers.js +8 -1
  78. package/dist/promise/index.js +9 -3
  79. package/dist/promise/misc.js +3 -1
  80. package/dist/promise/models.js +14 -12
  81. package/dist/promise/timed.js +3 -1
  82. package/dist/query.js +2 -0
  83. package/dist/queue.js +2 -0
  84. package/dist/random.js +2 -0
  85. package/dist/result/index.js +5 -3
  86. package/dist/result/match.js +2 -0
  87. package/dist/result/misc.js +2 -0
  88. package/dist/result/work/flow.js +2 -0
  89. package/dist/result/work/pipe.js +2 -0
  90. package/dist/sized/map.js +2 -0
  91. package/dist/sized/set.js +2 -0
  92. package/dist/string/case.js +2 -0
  93. package/dist/string/index.js +2 -0
  94. package/dist/string/match.js +2 -0
  95. package/dist/string/template.js +2 -0
  96. package/dist/value/clone.js +3 -1
  97. package/dist/value/diff.js +2 -0
  98. package/dist/value/merge.js +2 -0
  99. package/dist/value/omit.js +2 -0
  100. package/dist/value/pick.js +2 -0
  101. package/dist/value/smush.js +3 -1
  102. package/dist/value/unsmush.js +3 -1
  103. package/package.json +3 -3
  104. package/src/array/index.ts +1 -0
  105. package/src/array/position.ts +303 -0
  106. package/src/internal/array/sets.ts +3 -3
  107. package/src/internal/array/shuffle.ts +1 -1
  108. package/src/promise/helpers.ts +13 -3
  109. package/src/promise/index.ts +89 -19
  110. package/src/promise/misc.ts +1 -4
  111. package/src/promise/models.ts +18 -12
  112. package/src/value/clone.ts +1 -1
  113. package/src/value/smush.ts +1 -1
  114. package/src/value/unsmush.ts +1 -1
  115. package/types/array/index.d.ts +1 -0
  116. package/types/array/position.d.ts +117 -0
  117. package/types/promise/helpers.d.ts +3 -1
  118. package/types/promise/index.d.ts +52 -5
  119. package/types/promise/misc.d.ts +1 -1
  120. package/types/promise/models.d.ts +15 -11
@@ -0,0 +1,303 @@
1
+ // #region Types
2
+
3
+ import {getArrayCallback} from '../internal/array/callbacks';
4
+ import type {PlainObject} from '../models';
5
+
6
+ export type ArrayPosition = 'end' | 'inside' | 'invalid' | 'outside' | 'same' | 'start';
7
+
8
+ // #endregion
9
+
10
+ // #region Functions
11
+
12
+ /**
13
+ * Does the needle array end the haystack array?
14
+ * @param haystack Haystack array
15
+ * @param needle Needle array
16
+ * @param key Key to get an item's value for matching
17
+ * @return `true` if the haystack ends with the needle, otherwise `false`
18
+ */
19
+ export function endsWithArray<Item extends PlainObject>(
20
+ haystack: Item[],
21
+ needle: Item[],
22
+ key: keyof Item,
23
+ ): boolean;
24
+
25
+ /**
26
+ * Does the needle array end the haystack array?
27
+ * @param haystack Haystack array
28
+ * @param needle Needle array
29
+ * @param callback Callback to get an item's value for matching
30
+ * @return `true` if the haystack ends with the needle, otherwise `false`
31
+ */
32
+ export function endsWithArray<Item>(
33
+ haystack: Item[],
34
+ needle: Item[],
35
+ callback: (item: Item, index: number, array: Item[]) => unknown,
36
+ ): boolean;
37
+
38
+ /**
39
+ * Does the needle array end the haystack array?
40
+ * @param haystack Haystack array
41
+ * @param needle Needle array
42
+ * @return `true` if the haystack ends with the needle, otherwise `false`
43
+ */
44
+ export function endsWithArray<Item>(haystack: Item[], needle: Item[]): boolean;
45
+
46
+ export function endsWithArray(haystack: unknown[], needle: unknown[], key?: unknown): boolean {
47
+ return endings.has(getPosition(haystack, needle, key)[1]);
48
+ }
49
+
50
+ /**
51
+ * Get the position of an array within another array
52
+ * @param haystack Haystack array
53
+ * @param needle Needle array
54
+ * @param key Key to get an item's value for matching
55
+ * @returns Position of the needle within the haystack
56
+ */
57
+ export function getArrayPosition<Item extends PlainObject>(
58
+ haystack: Item[],
59
+ needle: Item[],
60
+ key: keyof Item,
61
+ ): ArrayPosition;
62
+
63
+ /**
64
+ * Get the position of an array within another array
65
+ * @param haystack Haystack array
66
+ * @param needle Needle array
67
+ * @param callback Callback to get an item's value for matching
68
+ * @returns Position of the needle within the haystack
69
+ */
70
+ export function getArrayPosition<Item>(
71
+ haystack: Item[],
72
+ needle: Item[],
73
+ callback: (item: Item, index: number, array: Item[]) => unknown,
74
+ ): ArrayPosition;
75
+
76
+ /**
77
+ * Get the position of an array within another array
78
+ * @param haystack Haystack array
79
+ * @param needle Needle array
80
+ * @returns Position of the needle within the haystack
81
+ */
82
+ export function getArrayPosition<Item>(haystack: Item[], needle: Item[]): ArrayPosition;
83
+
84
+ export function getArrayPosition(
85
+ haystack: unknown[],
86
+ needle: unknown[],
87
+ key?: unknown,
88
+ ): ArrayPosition {
89
+ return getPosition(haystack, needle, key)[1];
90
+ }
91
+
92
+ function getName(start: number, haystack: number, needle: number): ArrayPosition {
93
+ if (start === 0) {
94
+ return haystack === needle ? POSITION_SAME : POSITION_START;
95
+ }
96
+
97
+ return start + needle === haystack ? POSITION_END : POSITION_INSIDE;
98
+ }
99
+
100
+ function getPosition(
101
+ haystack: unknown[],
102
+ needle: unknown[],
103
+ key?: unknown,
104
+ ): readonly [number, ArrayPosition] {
105
+ if (!Array.isArray(haystack) || !Array.isArray(needle)) {
106
+ return invalid;
107
+ }
108
+
109
+ const haystackLength = haystack.length;
110
+ const needleLength = needle.length;
111
+
112
+ if (haystackLength === 0 || needleLength === 0) {
113
+ return outside;
114
+ }
115
+
116
+ if (needleLength > haystackLength) {
117
+ return outside;
118
+ }
119
+
120
+ const callback = getArrayCallback(key);
121
+
122
+ const limit = haystackLength - needleLength + 1;
123
+
124
+ let needleValues = callback == null ? needle : needle.slice();
125
+
126
+ if (callback != null) {
127
+ for (let needleIndex = 0; needleIndex < needleLength; needleIndex += 1) {
128
+ needleValues[needleIndex] = callback(needle[needleIndex], needleIndex, needle);
129
+ }
130
+ }
131
+
132
+ for (let haystackIndex = 0; haystackIndex < limit; haystackIndex += 1) {
133
+ let haystackItem = haystack[haystackIndex];
134
+ let haystackValue = callback?.(haystackItem, haystackIndex, haystack) ?? haystackItem;
135
+
136
+ if (!Object.is(haystackValue, needleValues[0])) {
137
+ continue;
138
+ }
139
+
140
+ if (needleLength === 1) {
141
+ return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
142
+ }
143
+
144
+ for (let needleIndex = 1; needleIndex < needleLength; needleIndex += 1) {
145
+ haystackItem = haystack[haystackIndex + needleIndex];
146
+
147
+ haystackValue =
148
+ callback?.(haystackItem, haystackIndex + needleIndex, haystack) ?? haystackItem;
149
+
150
+ if (!Object.is(haystackValue, needleValues[needleIndex])) {
151
+ break;
152
+ }
153
+
154
+ if (needleIndex === needleLength - 1) {
155
+ return [haystackIndex, getName(haystackIndex, haystackLength, needleLength)];
156
+ }
157
+ }
158
+ }
159
+
160
+ return outside;
161
+ }
162
+
163
+ /**
164
+ * Does the needle array exist within the haystack array?
165
+ * @param haystack Haystack array
166
+ * @param needle Needle array
167
+ * @param key Key to get an item's value for matching
168
+ * @return `true` if the haystack includes the needle, otherwise `false`
169
+ */
170
+ export function includesArray<Item extends PlainObject>(
171
+ haystack: Item[],
172
+ needle: Item[],
173
+ key: keyof Item,
174
+ ): boolean;
175
+
176
+ /**
177
+ * Does the needle array exist within the haystack array?
178
+ * @param haystack Haystack array
179
+ * @param needle Needle array
180
+ * @param callback Callback to get an item's value for matching
181
+ * @return `true` if the haystack includes the needle, otherwise `false`
182
+ */
183
+ export function includesArray<Item>(
184
+ haystack: Item[],
185
+ needle: Item[],
186
+ callback: (item: Item, index: number, array: Item[]) => unknown,
187
+ ): boolean;
188
+
189
+ /**
190
+ * Does the needle array exist within the haystack array?
191
+ * @param haystack Haystack array
192
+ * @param needle Needle array
193
+ * @return `true` if the haystack includes the needle, otherwise `false`
194
+ */
195
+ export function includesArray<Item>(haystack: Item[], needle: Item[]): boolean;
196
+
197
+ export function includesArray(haystack: unknown[], needle: unknown[], key?: unknown): boolean {
198
+ return !outsides.has(getPosition(haystack, needle, key)[1]);
199
+ }
200
+
201
+ /**
202
+ * Get the index of an array within another array
203
+ * @param haystack Haystack array
204
+ * @param needle Needle array
205
+ * @param key Key to get an item's value for matching
206
+ * @return Index of the needle's start within the haystack, or `-1` if it is not found
207
+ */
208
+ export function indexOfArray<Item extends PlainObject>(
209
+ haystack: Item[],
210
+ needle: Item[],
211
+ key: keyof Item,
212
+ ): number;
213
+
214
+ /**
215
+ * Get the index of an array within another array
216
+ * @param haystack Haystack array
217
+ * @param needle Needle array
218
+ * @param callback Callback to get an item's value for matching
219
+ * @return Index of the needle's start within the haystack, or `-1` if it is not found
220
+ */
221
+ export function indexOfArray<Item>(
222
+ haystack: Item[],
223
+ needle: Item[],
224
+ callback: (item: Item, index: number, array: Item[]) => unknown,
225
+ ): number;
226
+
227
+ /**
228
+ * Get the index of an array within another array
229
+ * @param haystack Haystack array
230
+ * @param needle Needle array
231
+ * @return Index of the needle's start within the haystack, or `-1` if it is not found
232
+ */
233
+ export function indexOfArray<Item>(haystack: Item[], needle: Item[]): number;
234
+
235
+ export function indexOfArray(haystack: unknown[], needle: unknown[], key?: unknown): number {
236
+ return getPosition(haystack, needle, key)[0];
237
+ }
238
+
239
+ /**
240
+ * Does the needle array start the haystack array?
241
+ * @param haystack Haystack array
242
+ * @param needle Needle array
243
+ * @param key Key to get an item's value for matching
244
+ * @return `true` if the haystack starts with the needle, otherwise `false`
245
+ */
246
+ export function startsWithArray<Item extends PlainObject>(
247
+ haystack: Item[],
248
+ needle: Item[],
249
+ key: keyof Item,
250
+ ): boolean;
251
+
252
+ /**
253
+ * Does the needle array start the haystack array?
254
+ * @param haystack Haystack array
255
+ * @param needle Needle array
256
+ * @param callback Callback to get an item's value for matching
257
+ * @return `true` if the haystack starts with the needle, otherwise `false`
258
+ */
259
+ export function startsWithArray<Item>(
260
+ haystack: Item[],
261
+ needle: Item[],
262
+ callback: (item: Item, index: number, array: Item[]) => unknown,
263
+ ): boolean;
264
+
265
+ /**
266
+ * Does the needle array start the haystack array?
267
+ * @param haystack Haystack array
268
+ * @param needle Needle array
269
+ * @return `true` if the haystack starts with the needle, otherwise `false`
270
+ */
271
+ export function startsWithArray<Item>(haystack: Item[], needle: Item[]): boolean;
272
+
273
+ export function startsWithArray(haystack: unknown[], needle: unknown[], key?: unknown): boolean {
274
+ return starts.has(getPosition(haystack, needle, key)[1]);
275
+ }
276
+
277
+ // #endregion
278
+
279
+ // #region Variables
280
+
281
+ const POSITION_END: ArrayPosition = 'end';
282
+
283
+ const POSITION_INSIDE: ArrayPosition = 'inside';
284
+
285
+ const POSITION_INVALID: ArrayPosition = 'invalid';
286
+
287
+ const POSITION_OUTSIDE: ArrayPosition = 'outside';
288
+
289
+ const POSITION_SAME: ArrayPosition = 'same';
290
+
291
+ const POSITION_START: ArrayPosition = 'start';
292
+
293
+ const endings = new Set<ArrayPosition>([POSITION_END, POSITION_SAME]);
294
+
295
+ const invalid = [-1, POSITION_INVALID] as const;
296
+
297
+ const outside = [-1, POSITION_OUTSIDE] as const;
298
+
299
+ const outsides = new Set<ArrayPosition>([POSITION_INVALID, POSITION_OUTSIDE]);
300
+
301
+ const starts = new Set<ArrayPosition>([POSITION_START, POSITION_SAME]);
302
+
303
+ // #endregion
@@ -23,11 +23,11 @@ export function compareSets(
23
23
  const isUnion = type === COMPARE_SETS_UNION;
24
24
 
25
25
  if (first.length === 0) {
26
- return isDifference ? [...first] : isIntersection ? [] : [...second];
26
+ return isDifference ? first.slice() : isIntersection ? [] : second.slice();
27
27
  }
28
28
 
29
29
  if (!Array.isArray(second) || second.length === 0) {
30
- return isIntersection ? [] : [...first];
30
+ return isIntersection ? [] : first.slice();
31
31
  }
32
32
 
33
33
  const callback = getArrayCallback(key);
@@ -47,7 +47,7 @@ export function compareSets(
47
47
 
48
48
  length = source.length;
49
49
 
50
- const result: unknown[] = isUnion ? [...first] : [];
50
+ const result: unknown[] = isUnion ? first.slice() : [];
51
51
 
52
52
  for (let index = 0; index < length; index += 1) {
53
53
  const item = source[index];
@@ -12,7 +12,7 @@ export function shuffle<Item>(array: Item[]): Item[] {
12
12
  return [];
13
13
  }
14
14
 
15
- const shuffled = [...array];
15
+ const shuffled = array.slice();
16
16
 
17
17
  if (shuffled.length < 2) {
18
18
  return shuffled;
@@ -1,14 +1,16 @@
1
1
  import type {RequiredKeys} from '../models';
2
+ import {error, ok} from '../result';
3
+ import type {Result} from '../result/models';
2
4
  import {
3
- PROMISE_STRATEGY_DEFAULT,
4
5
  PROMISE_STRATEGY_ALL,
6
+ PROMISE_STRATEGY_DEFAULT,
5
7
  PROMISE_TYPE_FULFILLED,
6
8
  PROMISE_TYPE_REJECTED,
7
9
  type FulfilledPromise,
8
10
  type PromiseOptions,
9
11
  type PromisesOptions,
10
- type PromisesResultItem,
11
12
  type PromiseStrategy,
13
+ type PromisesValue,
12
14
  type RejectedPromise,
13
15
  } from './models';
14
16
 
@@ -56,6 +58,14 @@ export function getPromisesOptions(input: unknown): RequiredKeys<PromisesOptions
56
58
  };
57
59
  }
58
60
 
61
+ export function getResultsFromPromises<Value>(
62
+ promised: PromisesValue<Value>[],
63
+ ): Result<Value>[] {
64
+ return promised.map(result =>
65
+ isFulfilled(result) ? ok(result.value) : error(result.reason),
66
+ ) as Result<Value>[];
67
+ }
68
+
59
69
  export function getStrategyOrDefault(value: unknown): PromiseStrategy {
60
70
  return PROMISE_STRATEGY_ALL.has(value as PromiseStrategy)
61
71
  ? (value as PromiseStrategy)
@@ -84,7 +94,7 @@ function isType(value: unknown, type: string): boolean {
84
94
  return (
85
95
  typeof value === 'object' &&
86
96
  value !== null &&
87
- (value as PromisesResultItem<unknown>).status === type
97
+ (value as PromisesValue<unknown>).status === type
88
98
  );
89
99
  }
90
100
 
@@ -1,4 +1,5 @@
1
- import {getPromiseOptions, getPromisesOptions} from './helpers';
1
+ import type {Result} from '../result/models';
2
+ import {getPromiseOptions, getPromisesOptions, getResultsFromPromises} from './helpers';
2
3
  import {handleResult, settlePromise} from './misc';
3
4
  import {
4
5
  PROMISE_ABORT_OPTIONS,
@@ -11,9 +12,11 @@ import {
11
12
  type PromiseData,
12
13
  type PromiseHandlers,
13
14
  type PromiseOptions,
14
- type Promises,
15
+ type PromisesItems,
15
16
  type PromisesOptions,
16
17
  type PromisesResult,
18
+ type PromisesValue,
19
+ type PromisesValues,
17
20
  } from './models';
18
21
  import {getTimedPromise} from './timed';
19
22
 
@@ -111,9 +114,22 @@ export async function attemptPromise<Value>(
111
114
  * @returns List of results
112
115
  */
113
116
  export async function promises<Items extends unknown[], Options extends PromisesOptions>(
114
- items: Promises<Items>,
117
+ items: [...Items],
115
118
  options?: Options,
116
- ): Promise<Options['strategy'] extends 'first' ? Items : PromisesResult<Items>>;
119
+ ): Promise<Options['strategy'] extends 'first' ? Items : PromisesValues<PromisesItems<Items>>>;
120
+
121
+ /**
122
+ * Handle a list of promises, returning their results in an ordered array.
123
+ *
124
+ * Depending on the strategy, the function will either reject on the first error encountered or return an array of rejected and resolved results
125
+ * @param items List of promises
126
+ * @param options Options for handling the promises
127
+ * @returns List of results
128
+ */
129
+ export async function promises<Value, Options extends PromisesOptions>(
130
+ items: Promise<Value>[],
131
+ options?: Options,
132
+ ): Promise<Options['strategy'] extends 'first' ? Value[] : PromisesValue<Value>[]>;
117
133
 
118
134
  /**
119
135
  * Handle a list of promises, returning their results in an ordered array.
@@ -124,9 +140,19 @@ export async function promises<Items extends unknown[], Options extends Promises
124
140
  * @returns List of results
125
141
  */
126
142
  export async function promises<Items extends unknown[]>(
127
- items: Promises<Items>,
143
+ items: [...Items],
128
144
  strategy: 'first',
129
- ): Promise<Items>;
145
+ ): Promise<PromisesItems<Items>>;
146
+
147
+ /**
148
+ * Handle a list of promises, returning their results in an ordered array.
149
+ *
150
+ * If any promise in the list is rejected, the whole function will reject
151
+ * @param items List of promises
152
+ * @param strategy Strategy for handling the promises; rejects on the first error encountered
153
+ * @returns List of results
154
+ */
155
+ export async function promises<Value>(items: Promise<Value>[], strategy: 'first'): Promise<Value[]>;
130
156
 
131
157
  /**
132
158
  * Handle a list of promises, returning their results in an ordered array of rejected and resolved results
@@ -135,14 +161,22 @@ export async function promises<Items extends unknown[]>(
135
161
  * @returns List of results
136
162
  */
137
163
  export async function promises<Items extends unknown[]>(
138
- items: Promises<Items>,
164
+ items: [...Items],
139
165
  signal?: AbortSignal,
140
- ): Promise<PromisesResult<Items>>;
166
+ ): Promise<PromisesValues<PromisesItems<Items>>>;
141
167
 
142
- export async function promises<Items extends unknown[]>(
143
- items: Promises<Items>,
144
- options?: unknown,
145
- ): Promise<Items | PromisesResult<Items>> {
168
+ /**
169
+ * Handle a list of promises, returning their results in an ordered array of rejected and resolved results
170
+ * @param items List of promises
171
+ * @param signal AbortSignal for aborting the operation _(when aborted, the promise will reject with the reason of the signal)_
172
+ * @returns List of results
173
+ */
174
+ export async function promises<Value>(
175
+ items: Promise<Value>[],
176
+ signal?: AbortSignal,
177
+ ): Promise<PromisesValue<Value>[]>;
178
+
179
+ export async function promises(items: unknown[], options?: unknown): Promise<unknown[]> {
146
180
  const {signal, strategy} = getPromisesOptions(options);
147
181
 
148
182
  if (signal?.aborted ?? false) {
@@ -157,7 +191,7 @@ export async function promises<Items extends unknown[]>(
157
191
  const {length} = actual;
158
192
 
159
193
  if (length === 0) {
160
- return actual as unknown as Items | PromisesResult<Items>;
194
+ return Promise.reject(new TypeError(PROMISE_MESSAGE_EXPECTATION_PROMISES));
161
195
  }
162
196
 
163
197
  const complete = strategy === PROMISE_STRATEGY_DEFAULT;
@@ -168,12 +202,12 @@ export async function promises<Items extends unknown[]>(
168
202
 
169
203
  signal?.addEventListener('abort', abort, PROMISE_ABORT_OPTIONS);
170
204
 
171
- const data: PromiseData<Items> = {
205
+ const data: PromiseData = {
172
206
  last: length - 1,
173
- result: [] as unknown as Items | PromisesResult<Items>,
207
+ result: [] as unknown[],
174
208
  };
175
209
 
176
- let handlers: PromiseHandlers<Items>;
210
+ let handlers: PromiseHandlers;
177
211
 
178
212
  return new Promise((resolve, reject) => {
179
213
  handlers = {reject, resolve};
@@ -206,6 +240,41 @@ export async function promises<Items extends unknown[]>(
206
240
  });
207
241
  }
208
242
 
243
+ promises.result = resultPromises;
244
+
245
+ /**
246
+ * Handle a list of promises, returning their results in an ordered array of results _({@link Result})_.
247
+ *
248
+ * Depending on the strategy, the function will either reject on the first error encountered or return an array of rejected and resolved results
249
+ * @param items List of promises
250
+ * @param signal AbortSignal for aborting the operation _(when aborted, the promise will reject with the reason of the signal)_
251
+ * @returns List of results
252
+ */
253
+ async function resultPromises<Items extends unknown[]>(
254
+ items: [...Items],
255
+ signal?: AbortSignal,
256
+ ): Promise<PromisesResult<PromisesItems<Items>>>;
257
+
258
+ /**
259
+ * Handle a list of promises, returning their results in an ordered array of results _({@link Result})_.
260
+ *
261
+ * Depending on the strategy, the function will either reject on the first error encountered or return an array of rejected and resolved results
262
+ * @param items List of promises
263
+ * @param signal AbortSignal for aborting the operation _(when aborted, the promise will reject with the reason of the signal)_
264
+ * @returns List of results
265
+ */
266
+ async function resultPromises<Value>(
267
+ items: Promise<Value>[],
268
+ signal?: AbortSignal,
269
+ ): Promise<Result<Awaited<Value>>[]>;
270
+
271
+ async function resultPromises(
272
+ items: Promise<unknown>[],
273
+ signal?: AbortSignal,
274
+ ): Promise<Result<unknown>[]> {
275
+ return promises(items, signal).then(getResultsFromPromises);
276
+ }
277
+
209
278
  // #endregion
210
279
 
211
280
  // #region Exports
@@ -218,12 +287,13 @@ export {
218
287
  CancelablePromise,
219
288
  PromiseTimeoutError,
220
289
  type FulfilledPromise,
221
- type RejectedPromise,
222
290
  type PromiseOptions,
223
- type PromiseStrategy,
224
291
  type PromisesOptions,
225
292
  type PromisesResult,
226
- type PromisesResultItem,
293
+ type PromiseStrategy,
294
+ type PromisesValues as PromisesValue,
295
+ type PromisesValue as PromisesValueItem,
296
+ type RejectedPromise,
227
297
  } from './models';
228
298
  export {timed} from './timed';
229
299
 
@@ -22,10 +22,7 @@ export function cancelable<Value>(
22
22
  return new CancelablePromise(executor);
23
23
  }
24
24
 
25
- export function handleResult<Items extends unknown[]>(
26
- status: string,
27
- parameters: PromiseParameters<Items>,
28
- ): void {
25
+ export function handleResult(status: string, parameters: PromiseParameters): void {
29
26
  const {abort, complete, data, handlers, index, signal, value} = parameters;
30
27
 
31
28
  if (signal?.aborted ?? false) {
@@ -1,3 +1,5 @@
1
+ import type {Result} from '../result/models';
2
+
1
3
  // #region Types
2
4
 
3
5
  export class CancelablePromise<Value = void> extends Promise<Value> {
@@ -28,16 +30,16 @@ export class CancelablePromise<Value = void> extends Promise<Value> {
28
30
 
29
31
  export type FulfilledPromise<Value> = {
30
32
  status: typeof PROMISE_TYPE_FULFILLED;
31
- value: Value;
33
+ value: Awaited<Value>;
32
34
  };
33
35
 
34
- export type PromiseData<Items extends unknown[]> = {
36
+ export type PromiseData = {
35
37
  last: number;
36
- result: Items | PromisesResult<Items>;
38
+ result: unknown[];
37
39
  };
38
40
 
39
- export type PromiseHandlers<Items extends unknown[]> = {
40
- resolve: (value: Items | PromisesResult<Items>) => void;
41
+ export type PromiseHandlers = {
42
+ resolve: (value: unknown[]) => void;
41
43
  reject: (reason: unknown) => void;
42
44
  };
43
45
 
@@ -52,11 +54,11 @@ export type PromiseOptions = {
52
54
  time?: number;
53
55
  };
54
56
 
55
- export type PromiseParameters<Items extends unknown[]> = {
57
+ export type PromiseParameters = {
56
58
  abort: () => void;
57
59
  complete: boolean;
58
- data: PromiseData<Items>;
59
- handlers: PromiseHandlers<Items>;
60
+ data: PromiseData;
61
+ handlers: PromiseHandlers;
60
62
  index: number;
61
63
  signal?: AbortSignal;
62
64
  value?: unknown;
@@ -64,7 +66,7 @@ export type PromiseParameters<Items extends unknown[]> = {
64
66
 
65
67
  /**
66
68
  * Promise handling strategy
67
- *
69
+ *
68
70
  * - `complete`: wait for all promises to settle, then return the results
69
71
  * - Returns an array of fulfilled and/or rejected results
70
72
  * - `first`: rejects on the first rejected promise
@@ -80,7 +82,7 @@ export class PromiseTimeoutError extends Error {
80
82
  }
81
83
  }
82
84
 
83
- export type Promises<Items extends unknown[]> = {
85
+ export type PromisesItems<Items extends unknown[]> = {
84
86
  [K in keyof Items]: Promise<Items[K]>;
85
87
  };
86
88
 
@@ -90,10 +92,14 @@ export type PromisesOptions = {
90
92
  };
91
93
 
92
94
  export type PromisesResult<Items extends unknown[]> = {
93
- [K in keyof Items]: Items[K] extends Promise<infer Value> ? PromisesResultItem<Value> : never;
95
+ [K in keyof Items]: Items[K] extends Promise<infer Value> ? Result<Awaited<Value>> : never;
94
96
  };
95
97
 
96
- export type PromisesResultItem<Value> = FulfilledPromise<Value> | RejectedPromise;
98
+ export type PromisesValue<Value> = FulfilledPromise<Value> | RejectedPromise;
99
+
100
+ export type PromisesValues<Items extends unknown[]> = {
101
+ [K in keyof Items]: Items[K] extends Promise<infer Value> ? PromisesValue<Awaited<Value>> : never;
102
+ };
97
103
 
98
104
  export type RejectedPromise = {
99
105
  status: typeof PROMISE_TYPE_REJECTED;
@@ -130,7 +130,7 @@ function clonePlainObject(
130
130
  references: WeakMap<WeakKey, unknown>,
131
131
  ): ArrayOrPlainObject {
132
132
  if (depth >= MAX_CLONE_DEPTH) {
133
- return Array.isArray(value) ? [...value] : {...value};
133
+ return Array.isArray(value) ? value.slice() : {...value};
134
134
  }
135
135
 
136
136
  const cloned = (Array.isArray(value) ? [] : {}) as PlainObject;
@@ -44,7 +44,7 @@ function flattenObject(
44
44
  if (isArrayOrPlainObject(val)) {
45
45
  const prefixedKey = join([prefix, key], '.');
46
46
 
47
- flattened[prefixedKey] = Array.isArray(val) ? [...val] : {...val};
47
+ flattened[prefixedKey] = Array.isArray(val) ? val.slice() : {...val};
48
48
 
49
49
  const nested = flattenObject(val, depth + 1, smushed, prefixedKey);
50
50
  const nestedKeys = Object.keys(nested);
@@ -77,7 +77,7 @@ export function unsmush<Value extends PlainObject>(value: Value): Unsmushed<Valu
77
77
  let next = val;
78
78
 
79
79
  if (isArrayOrPlainObject(val)) {
80
- next = Array.isArray(val) ? [...val] : {...val};
80
+ next = Array.isArray(val) ? val.slice() : {...val};
81
81
  }
82
82
 
83
83
  setValue(unsmushed, key, next);
@@ -12,6 +12,7 @@ export * from './index-of';
12
12
  export * from './insert';
13
13
  export * from './intersection';
14
14
  export * from './partition';
15
+ export * from './position';
15
16
  export * from './push';
16
17
  export * from './select';
17
18
  export * from './slice';