@oscarpalmer/atoms 0.184.2 → 0.186.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 (156) hide show
  1. package/dist/array/difference.d.mts +29 -0
  2. package/dist/array/exists.d.mts +35 -0
  3. package/dist/array/filter.d.mts +72 -2
  4. package/dist/array/find.d.mts +70 -0
  5. package/dist/array/first.d.mts +77 -2
  6. package/dist/array/flatten.d.mts +6 -0
  7. package/dist/array/flatten.mjs +6 -0
  8. package/dist/array/from.d.mts +36 -0
  9. package/dist/array/get.d.mts +21 -13
  10. package/dist/array/group-by.d.mts +142 -0
  11. package/dist/array/index.d.mts +2 -2
  12. package/dist/array/index.mjs +2 -2
  13. package/dist/array/insert.d.mts +16 -0
  14. package/dist/array/intersection.d.mts +29 -0
  15. package/dist/array/last.d.mts +75 -2
  16. package/dist/array/{position.d.mts → match.d.mts} +168 -36
  17. package/dist/array/{position.mjs → match.mjs} +16 -16
  18. package/dist/array/move.d.mts +78 -8
  19. package/dist/array/move.mjs +11 -1
  20. package/dist/array/partition.d.mts +35 -0
  21. package/dist/array/push.d.mts +8 -0
  22. package/dist/array/push.mjs +8 -0
  23. package/dist/array/reverse.d.mts +1 -0
  24. package/dist/array/reverse.mjs +1 -0
  25. package/dist/array/select.d.mts +94 -8
  26. package/dist/array/single.d.mts +29 -0
  27. package/dist/array/slice.d.mts +106 -16
  28. package/dist/array/sort.d.mts +30 -4
  29. package/dist/array/sort.mjs +1 -1
  30. package/dist/array/splice.d.mts +48 -0
  31. package/dist/array/splice.mjs +2 -1
  32. package/dist/array/swap.d.mts +113 -8
  33. package/dist/array/swap.mjs +2 -1
  34. package/dist/array/to-map.d.mts +124 -0
  35. package/dist/array/to-record.d.mts +124 -0
  36. package/dist/array/to-set.d.mts +24 -0
  37. package/dist/array/toggle.d.mts +38 -3
  38. package/dist/array/union.d.mts +29 -0
  39. package/dist/array/unique.d.mts +24 -0
  40. package/dist/array/update.d.mts +38 -3
  41. package/dist/beacon.d.mts +12 -0
  42. package/dist/beacon.mjs +9 -0
  43. package/dist/color/instance.d.mts +8 -0
  44. package/dist/color/instance.mjs +3 -0
  45. package/dist/color/models.d.mts +30 -0
  46. package/dist/function/assert.d.mts +29 -8
  47. package/dist/function/assert.mjs +29 -8
  48. package/dist/function/memoize.d.mts +3 -0
  49. package/dist/function/memoize.mjs +3 -0
  50. package/dist/function/retry.d.mts +3 -0
  51. package/dist/function/retry.mjs +3 -0
  52. package/dist/function/work.mjs +1 -1
  53. package/dist/index.d.mts +2158 -288
  54. package/dist/index.mjs +294 -181
  55. package/dist/internal/array/chunk.d.mts +6 -0
  56. package/dist/internal/array/chunk.mjs +6 -0
  57. package/dist/internal/array/compact.d.mts +12 -0
  58. package/dist/internal/array/index-of.d.mts +70 -0
  59. package/dist/internal/math/aggregate.d.mts +29 -0
  60. package/dist/internal/value/compare.d.mts +2 -1
  61. package/dist/internal/value/equal.d.mts +5 -0
  62. package/dist/internal/value/get.d.mts +27 -5
  63. package/dist/internal/value/has.d.mts +7 -7
  64. package/dist/internal/value/has.mjs +1 -1
  65. package/dist/internal/value/misc.d.mts +2 -2
  66. package/dist/internal/value/misc.mjs +10 -4
  67. package/dist/logger.d.mts +11 -0
  68. package/dist/logger.mjs +11 -0
  69. package/dist/models.d.mts +14 -1
  70. package/dist/promise/helpers.mjs +1 -1
  71. package/dist/promise/index.d.mts +0 -6
  72. package/dist/promise/models.d.mts +36 -0
  73. package/dist/promise/models.mjs +6 -0
  74. package/dist/queue.d.mts +13 -1
  75. package/dist/queue.mjs +9 -0
  76. package/dist/result/index.d.mts +0 -8
  77. package/dist/result/index.mjs +0 -8
  78. package/dist/result/match.d.mts +4 -4
  79. package/dist/result/work/flow.d.mts +12 -36
  80. package/dist/result/work/pipe.d.mts +11 -33
  81. package/dist/sized/set.d.mts +3 -2
  82. package/dist/sized/set.mjs +3 -2
  83. package/dist/value/collection.d.mts +1 -1
  84. package/dist/value/handle.mjs +1 -1
  85. package/dist/value/merge.d.mts +28 -25
  86. package/dist/value/merge.mjs +29 -18
  87. package/dist/value/shake.d.mts +3 -0
  88. package/dist/value/smush.d.mts +3 -0
  89. package/dist/value/transform.d.mts +10 -1
  90. package/dist/value/unsmush.d.mts +2 -3
  91. package/package.json +5 -5
  92. package/src/array/difference.ts +33 -0
  93. package/src/array/exists.ts +35 -0
  94. package/src/array/filter.ts +72 -2
  95. package/src/array/find.ts +70 -0
  96. package/src/array/first.ts +77 -3
  97. package/src/array/flatten.ts +6 -0
  98. package/src/array/from.ts +40 -0
  99. package/src/array/get.ts +21 -15
  100. package/src/array/group-by.ts +142 -0
  101. package/src/array/index.ts +1 -1
  102. package/src/array/insert.ts +16 -2
  103. package/src/array/intersection.ts +33 -0
  104. package/src/array/last.ts +75 -2
  105. package/src/array/{position.ts → match.ts} +197 -65
  106. package/src/array/move.ts +87 -13
  107. package/src/array/partition.ts +35 -0
  108. package/src/array/push.ts +8 -2
  109. package/src/array/reverse.ts +5 -0
  110. package/src/array/select.ts +96 -13
  111. package/src/array/single.ts +29 -0
  112. package/src/array/slice.ts +114 -24
  113. package/src/array/sort.ts +30 -4
  114. package/src/array/splice.ts +52 -4
  115. package/src/array/swap.ts +122 -13
  116. package/src/array/to-map.ts +124 -0
  117. package/src/array/to-record.ts +124 -0
  118. package/src/array/to-set.ts +24 -0
  119. package/src/array/toggle.ts +42 -3
  120. package/src/array/union.ts +33 -0
  121. package/src/array/unique.ts +24 -0
  122. package/src/array/update.ts +38 -3
  123. package/src/beacon.ts +12 -0
  124. package/src/color/index.ts +0 -3
  125. package/src/color/instance.ts +9 -1
  126. package/src/color/models.ts +30 -0
  127. package/src/function/assert.ts +66 -7
  128. package/src/function/memoize.ts +3 -0
  129. package/src/function/once.ts +5 -1
  130. package/src/function/retry.ts +3 -0
  131. package/src/internal/array/chunk.ts +6 -0
  132. package/src/internal/array/compact.ts +12 -0
  133. package/src/internal/array/index-of.ts +70 -0
  134. package/src/internal/math/aggregate.ts +29 -0
  135. package/src/internal/string.ts +0 -2
  136. package/src/internal/value/compare.ts +2 -1
  137. package/src/internal/value/equal.ts +5 -0
  138. package/src/internal/value/get.ts +27 -5
  139. package/src/internal/value/has.ts +10 -10
  140. package/src/internal/value/misc.ts +24 -13
  141. package/src/logger.ts +11 -0
  142. package/src/models.ts +18 -0
  143. package/src/promise/index.ts +0 -6
  144. package/src/promise/models.ts +36 -0
  145. package/src/queue.ts +13 -1
  146. package/src/result/index.ts +0 -8
  147. package/src/result/match.ts +4 -4
  148. package/src/result/work/flow.ts +12 -36
  149. package/src/result/work/pipe.ts +11 -33
  150. package/src/sized/set.ts +4 -3
  151. package/src/value/collection.ts +1 -1
  152. package/src/value/merge.ts +88 -66
  153. package/src/value/shake.ts +3 -0
  154. package/src/value/smush.ts +3 -0
  155. package/src/value/transform.ts +10 -1
  156. package/src/value/unsmush.ts +2 -8
@@ -17,7 +17,7 @@ type WrapValue<Value> = Result<UnwrapValue<Value>>;
17
17
  /**
18
18
  * Attempt to pipe a value through a function
19
19
  *
20
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
20
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
21
21
  * @param initial Initial value
22
22
  * @returns Piped result
23
23
  */
@@ -29,7 +29,7 @@ export async function attemptAsyncPipe<Initial, Piped>(
29
29
  /**
30
30
  * Attempt to pipe a value through a series of functions
31
31
  *
32
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
32
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
33
33
  * @param initial Initial value
34
34
  * @returns Piped result
35
35
  */
@@ -42,7 +42,7 @@ export async function attemptAsyncPipe<Initial, First, Second>(
42
42
  /**
43
43
  * Attempt to pipe a value through a series of functions
44
44
  *
45
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
45
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
46
46
  * @param initial Initial value
47
47
  * @returns Piped result
48
48
  */
@@ -56,7 +56,7 @@ export async function attemptAsyncPipe<Initial, First, Second, Third>(
56
56
  /**
57
57
  * Attempt to pipe a value through a series of functions
58
58
  *
59
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
59
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
60
60
  * @param initial Initial value
61
61
  * @returns Piped result
62
62
  */
@@ -71,7 +71,7 @@ export async function attemptAsyncPipe<Initial, First, Second, Third, Fourth>(
71
71
  /**
72
72
  * Attempt to pipe a value through a series of functions
73
73
  *
74
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
74
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
75
75
  * @param initial Initial value
76
76
  * @returns Piped result
77
77
  */
@@ -87,7 +87,7 @@ export async function attemptAsyncPipe<Initial, First, Second, Third, Fourth, Fi
87
87
  /**
88
88
  * Attempt to pipe a value through a series of functions
89
89
  *
90
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
90
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
91
91
  * @param initial Initial value
92
92
  * @returns Piped result
93
93
  */
@@ -104,7 +104,7 @@ export async function attemptAsyncPipe<Initial, First, Second, Third, Fourth, Fi
104
104
  /**
105
105
  * Attempt to pipe a value through a series of functions
106
106
  *
107
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
107
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
108
108
  * @param initial Initial value
109
109
  * @returns Piped result
110
110
  */
@@ -131,7 +131,7 @@ export async function attemptAsyncPipe<
131
131
  /**
132
132
  * Attempt to pipe a value through a series of functions
133
133
  *
134
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
134
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
135
135
  * @param initial Initial value
136
136
  * @returns Piped result
137
137
  */
@@ -160,7 +160,7 @@ export async function attemptAsyncPipe<
160
160
  /**
161
161
  * Attempt to pipe a value through a series of functions
162
162
  *
163
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
163
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
164
164
  * @param initial Initial value
165
165
  * @returns Piped result
166
166
  */
@@ -191,7 +191,7 @@ export async function attemptAsyncPipe<
191
191
  /**
192
192
  * Attempt to pipe a value through a series of functions
193
193
  *
194
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
194
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
195
195
  * @param initial Initial value
196
196
  * @returns Piped result
197
197
  */
@@ -224,7 +224,7 @@ export async function attemptAsyncPipe<
224
224
  /**
225
225
  * Attempt to pipe a result through a series of functions
226
226
  *
227
- * Available as `attemptAsyncPipe` and `attempt.pipe.async`
227
+ * Available as `attemptAsyncPipe` and `attemptPipe.async`
228
228
  * @param initial Initial result
229
229
  * @returns Piped result
230
230
  */
@@ -265,8 +265,6 @@ export async function attemptAsyncPipe(
265
265
 
266
266
  /**
267
267
  * Attempt to pipe a value through a function
268
- *
269
- * Available as `attemptPipe` and `attempt.pipe`
270
268
  * @param initial Initial value
271
269
  * @returns Piped result
272
270
  */
@@ -277,8 +275,6 @@ export function attemptPipe<Initial, Pipe>(
277
275
 
278
276
  /**
279
277
  * Attempt to pipe a value through a series of functions
280
- *
281
- * Available as `attemptPipe` and `attempt.pipe`
282
278
  * @param initial Initial value
283
279
  * @returns Piped result
284
280
  */
@@ -290,8 +286,6 @@ export function attemptPipe<Initial, First, Second>(
290
286
 
291
287
  /**
292
288
  * Attempt to pipe a value through a series of functions
293
- *
294
- * Available as `attemptPipe` and `attempt.pipe`
295
289
  * @param initial Initial value
296
290
  * @returns Piped result
297
291
  */
@@ -304,8 +298,6 @@ export function attemptPipe<Initial, First, Second, Third>(
304
298
 
305
299
  /**
306
300
  * Attempt to pipe a value through a series of functions
307
- *
308
- * Available as `attemptPipe` and `attempt.pipe`
309
301
  * @param initial Initial value
310
302
  * @returns Piped result
311
303
  */
@@ -319,8 +311,6 @@ export function attemptPipe<Initial, First, Second, Third, Fourth>(
319
311
 
320
312
  /**
321
313
  * Attempt to pipe a value through a series of functions
322
- *
323
- * Available as `attemptPipe` and `attempt.pipe`
324
314
  * @param initial Initial value
325
315
  * @returns Piped result
326
316
  */
@@ -335,8 +325,6 @@ export function attemptPipe<Initial, First, Second, Third, Fourth, Fifth>(
335
325
 
336
326
  /**
337
327
  * Attempt to pipe a value through a series of functions
338
- *
339
- * Available as `attemptPipe` and `attempt.pipe`
340
328
  * @param initial Initial value
341
329
  * @returns Piped result
342
330
  */
@@ -352,8 +340,6 @@ export function attemptPipe<Initial, First, Second, Third, Fourth, Fifth, Sixth>
352
340
 
353
341
  /**
354
342
  * Attempt to pipe a value through a series of functions
355
- *
356
- * Available as `attemptPipe` and `attempt.pipe`
357
343
  * @param initial Initial value
358
344
  * @returns Piped result
359
345
  */
@@ -370,8 +356,6 @@ export function attemptPipe<Initial, First, Second, Third, Fourth, Fifth, Sixth,
370
356
 
371
357
  /**
372
358
  * Attempt to pipe a value through a series of functions
373
- *
374
- * Available as `attemptPipe` and `attempt.pipe`
375
359
  * @param initial Initial value
376
360
  * @returns Piped result
377
361
  */
@@ -389,8 +373,6 @@ export function attemptPipe<Initial, First, Second, Third, Fourth, Fifth, Sixth,
389
373
 
390
374
  /**
391
375
  * Attempt to pipe a value through a series of functions
392
- *
393
- * Available as `attemptPipe` and `attempt.pipe`
394
376
  * @param initial Initial value
395
377
  * @returns Piped result
396
378
  */
@@ -420,8 +402,6 @@ export function attemptPipe<
420
402
 
421
403
  /**
422
404
  * Attempt to pipe a value through a series of functions
423
- *
424
- * Available as `attemptPipe` and `attempt.pipe`
425
405
  * @param initial Initial value
426
406
  * @returns Piped result
427
407
  */
@@ -453,8 +433,6 @@ export function attemptPipe<
453
433
 
454
434
  /**
455
435
  * Attempt to pipe a result through a series of functions
456
- *
457
- * Available as `attemptPipe` and `attempt.pipe`
458
436
  * @param initial Initial result
459
437
  * @returns Piped result
460
438
  */
package/src/sized/set.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import {getSizedMaximum} from '../internal/sized';
2
2
 
3
- // #region Types and classes
3
+ // #region Types
4
4
 
5
5
  /**
6
- * - A Set with a maximum size
7
- * - Behavior is similar to a _LRU_-cache, where the oldest values are removed
6
+ * A Set with a maximum size
7
+ *
8
+ * Behavior is similar to a _LRU_-cache, where the oldest values are removed
8
9
  */
9
10
  export class SizedSet<Value = unknown> extends Set<Value> {
10
11
  /**
@@ -13,7 +13,7 @@ export function inMap<Value>(map: Map<unknown, Value>, value: Value): boolean;
13
13
  * @param map Map to check in
14
14
  * @param value Value to check for
15
15
  * @param key To return the key for the value
16
- * @return The key for the value if it exists, otherwise `undefined`
16
+ * @returns The key for the value if it exists, otherwise `undefined`
17
17
  */
18
18
  export function inMap<Key, Value>(map: Map<Key, Value>, value: Value, key: true): Key;
19
19
 
@@ -1,6 +1,5 @@
1
1
  import {isArrayOrPlainObject} from '../internal/is';
2
- import {join} from '../internal/string';
3
- import type {ArrayOrPlainObject, NestedPartial, PlainObject} from '../models';
2
+ import type {ArrayOrPlainObject, NestedPartial, PlainObject, UnionToIntersection} from '../models';
4
3
 
5
4
  // #region Types
6
5
 
@@ -9,16 +8,19 @@ import type {ArrayOrPlainObject, NestedPartial, PlainObject} from '../models';
9
8
  */
10
9
  export type AssignOptions = Omit<MergeOptions, 'assignValues'>;
11
10
 
12
- /**
13
- * Assign values from multiple arrays or objects to the first one
14
- * @param to Value to assign to
15
- * @param from Values to assign
16
- * @returns Assigned value
17
- */
18
- export type Assigner<Model extends ArrayOrPlainObject = ArrayOrPlainObject> = (
19
- to: NestedPartial<Model>,
20
- from: NestedPartial<Model>[],
21
- ) => Model;
11
+ export type Assigner = {
12
+ /**
13
+ * Assign values from one or more objects to the first one
14
+ *
15
+ * @param to Value to assign to
16
+ * @param from Values to assign
17
+ * @returns Assigned value
18
+ */
19
+ <To extends PlainObject, From extends PlainObject[]>(
20
+ to: To,
21
+ from: [...From],
22
+ ): To & UnionToIntersection<From[number]>;
23
+ };
22
24
 
23
25
  /**
24
26
  * Options for merging values
@@ -54,14 +56,17 @@ export type MergeOptions = {
54
56
  skipNullableInArrays?: boolean;
55
57
  };
56
58
 
57
- /**
58
- * Merge multiple arrays or objects into a single one
59
- * @param values Values to merge
60
- * @returns Merged value
61
- */
62
- export type Merger<Model extends ArrayOrPlainObject = ArrayOrPlainObject> = (
63
- values: NestedPartial<Model>[],
64
- ) => Model;
59
+ export type Merger = {
60
+ /**
61
+ * Merge multiple arrays or objects into a single one
62
+ *
63
+ * @param values Values to merge
64
+ * @returns Merged value
65
+ */
66
+ <Values extends ArrayOrPlainObject[]>(
67
+ values: NestedPartial<Values[number]>[],
68
+ ): UnionToIntersection<Values[number]>;
69
+ };
65
70
 
66
71
  type Options = {
67
72
  assignValues: boolean;
@@ -77,22 +82,23 @@ type ReplaceableObjectsCallback = (name: string) => boolean;
77
82
  // #region Functions
78
83
 
79
84
  /**
80
- * Assign values from multiple arrays or objects to the first one
85
+ * Assign values from one or more objects to the first one
86
+ *
81
87
  * @param to Value to assign to
82
88
  * @param from Values to assign
83
89
  * @param options Assigning options
84
90
  * @returns Assigned value
85
91
  */
86
- export function assign<Model extends ArrayOrPlainObject>(
87
- to: NestedPartial<Model>,
88
- from: NestedPartial<Model>[],
92
+ export function assign<To extends PlainObject, From extends PlainObject[]>(
93
+ to: To,
94
+ from: [...From],
89
95
  options?: AssignOptions,
90
- ): Model {
96
+ ): To & UnionToIntersection<From[number]> {
91
97
  const actual = getMergeOptions(options);
92
98
 
93
99
  actual.assignValues = true;
94
100
 
95
- return mergeValues([to, ...from], actual, true) as Model;
101
+ return mergeValues([to, ...from], actual) as To & UnionToIntersection<From[number]>;
96
102
  }
97
103
 
98
104
  assign.initialize = initializeAssigner;
@@ -129,69 +135,50 @@ function getReplaceableObjects(value: unknown): ReplaceableObjectsCallback | und
129
135
  }
130
136
  }
131
137
 
132
- function handleMerge(values: ArrayOrPlainObject[], options: Options): ArrayOrPlainObject {
133
- return !Array.isArray(values) || values.length === 0 ? {} : mergeValues(values, options, true);
134
- }
135
-
136
138
  /**
137
139
  * Create an assigner with predefined options
138
140
  *
139
141
  * Available as `initializeAssigner` and `assign.initialize`
142
+ *
140
143
  * @param options Assigning options
141
144
  * @returns Assigner function
142
145
  */
143
- export function initializeAssigner<Model extends ArrayOrPlainObject>(
144
- options?: AssignOptions,
145
- ): Assigner<Model> {
146
+ export function initializeAssigner(options?: AssignOptions): Assigner {
146
147
  const actual = getMergeOptions(options);
147
148
 
148
149
  actual.assignValues = true;
149
150
 
150
- return ((to: ArrayOrPlainObject, from: NestedPartial<ArrayOrPlainObject>[]): ArrayOrPlainObject =>
151
- mergeValues([to, ...from], actual, true)) as Assigner<Model>;
151
+ return ((to: PlainObject, from: PlainObject[]): PlainObject =>
152
+ mergeValues([to, ...from], actual) as PlainObject) as Assigner;
152
153
  }
153
154
 
154
155
  /**
155
156
  * Create a merger with predefined options
156
157
  *
157
158
  * Available as `initializeMerger` and `merge.initialize`
159
+ *
158
160
  * @param options Merging options
159
161
  * @returns Merger function
160
162
  */
161
163
  export function initializeMerger(options?: MergeOptions): Merger {
162
164
  const actual = getMergeOptions(options);
163
165
 
164
- return <Model extends ArrayOrPlainObject>(values: NestedPartial<Model>[]): Model =>
165
- handleMerge(values, actual) as Model;
166
+ return ((values: NestedPartial<ArrayOrPlainObject>[]): ArrayOrPlainObject =>
167
+ mergeValues(values, actual)) as Merger;
166
168
  }
167
169
 
168
170
  /**
169
171
  * Merge multiple arrays or objects into a single one
172
+ *
170
173
  * @param values Values to merge
171
174
  * @param options Merging options
172
175
  * @returns Merged value
173
176
  */
174
- export function merge<Model extends ArrayOrPlainObject>(
175
- values: NestedPartial<Model>[],
176
- options?: MergeOptions,
177
- ): Model;
178
-
179
- /**
180
- * Merge multiple arrays or objects into a single one
181
- * @param values Values to merge
182
- * @param options Merging options
183
- * @returns Merged value
184
- */
185
- export function merge(
186
- values: NestedPartial<ArrayOrPlainObject>[],
177
+ export function merge<Values extends ArrayOrPlainObject[]>(
178
+ values: [...Values],
187
179
  options?: MergeOptions,
188
- ): ArrayOrPlainObject;
189
-
190
- export function merge(
191
- values: NestedPartial<ArrayOrPlainObject>[],
192
- options?: MergeOptions,
193
- ): ArrayOrPlainObject {
194
- return handleMerge(values, getMergeOptions(options));
180
+ ): UnionToIntersection<Values[number]> {
181
+ return mergeValues(values, getMergeOptions(options)) as UnionToIntersection<Values[number]>;
195
182
  }
196
183
 
197
184
  merge.initialize = initializeMerger;
@@ -199,20 +186,23 @@ merge.initialize = initializeMerger;
199
186
  function mergeObjects(
200
187
  values: ArrayOrPlainObject[],
201
188
  options: Options,
189
+ destination?: ArrayOrPlainObject,
202
190
  prefix?: string,
203
191
  ): ArrayOrPlainObject {
204
192
  const {length} = values;
205
- const isArray = values.every(Array.isArray);
206
- const merged = (options.assignValues ? values[0] : isArray ? [] : {}) as PlainObject;
207
193
 
208
- for (let outerIndex = 0; outerIndex < length; outerIndex += 1) {
194
+ const isArray = Array.isArray(destination ?? values[0]);
195
+ const merged = (destination ?? (isArray ? [] : {})) as PlainObject;
196
+
197
+ const offset = destination == null ? 0 : 1;
198
+
199
+ for (let outerIndex = offset; outerIndex < length; outerIndex += 1) {
209
200
  const item = values[outerIndex] as PlainObject;
210
201
  const keys = Object.keys(item);
211
202
  const size = keys.length;
212
203
 
213
204
  for (let innerIndex = 0; innerIndex < size; innerIndex += 1) {
214
205
  const key = keys[innerIndex];
215
- const full = join([prefix, key], '.');
216
206
 
217
207
  const next = item[key];
218
208
  const previous = merged[key];
@@ -221,12 +211,20 @@ function mergeObjects(
221
211
  continue;
222
212
  }
223
213
 
214
+ const full =
215
+ options.replaceableObjects == null ? undefined : prefix == null ? key : `${prefix}.${key}`;
216
+
224
217
  if (
225
218
  isArrayOrPlainObject(next) &&
226
219
  isArrayOrPlainObject(previous) &&
227
- !(options.replaceableObjects?.(full) ?? false)
220
+ !(options.replaceableObjects?.(full!) ?? false)
228
221
  ) {
229
- merged[key] = mergeValues([previous, next], options, false, full);
222
+ merged[key] = mergeObjects(
223
+ [previous, next],
224
+ options,
225
+ (destination == null ? undefined : merged[key]) as ArrayOrPlainObject,
226
+ full,
227
+ );
230
228
  } else {
231
229
  merged[key] = next;
232
230
  }
@@ -239,12 +237,36 @@ function mergeObjects(
239
237
  function mergeValues(
240
238
  values: ArrayOrPlainObject[],
241
239
  options: Options,
242
- validate: boolean,
243
240
  prefix?: string,
244
241
  ): ArrayOrPlainObject {
245
- const actual = validate ? values.filter(isArrayOrPlainObject) : values;
242
+ if (!Array.isArray(values)) {
243
+ return {};
244
+ }
245
+
246
+ const actual = values.filter(isArrayOrPlainObject);
247
+
248
+ if (actual.length === 0) {
249
+ return {};
250
+ }
251
+
252
+ if (
253
+ options.assignValues &&
254
+ actual.length === 2 &&
255
+ !Array.isArray(actual[0]) &&
256
+ Object.keys(actual[0]).length === 0
257
+ ) {
258
+ return Object.assign(actual[0], actual[1]);
259
+ }
260
+
261
+ if (actual.length > 1) {
262
+ return mergeObjects(actual, options, options.assignValues ? actual[0] : undefined, prefix);
263
+ }
246
264
 
247
- return actual.length > 1 ? mergeObjects(actual, options, prefix) : (actual[0] ?? {});
265
+ return options.assignValues
266
+ ? actual[0]
267
+ : Array.isArray(actual[0])
268
+ ? actual[0].slice()
269
+ : {...actual[0]};
248
270
  }
249
271
 
250
272
  // #endregion
@@ -3,6 +3,9 @@ import type {PlainObject} from '../models';
3
3
 
4
4
  // #region Types
5
5
 
6
+ /**
7
+ * A shaken object, without any `undefined` values
8
+ */
6
9
  export type Shaken<Value extends PlainObject> = {
7
10
  [Key in keyof Value]: Value[Key] extends undefined ? never : Value[Key];
8
11
  };
@@ -11,6 +11,9 @@ import type {
11
11
 
12
12
  // #region Types
13
13
 
14
+ /**
15
+ * A smushed object, with all nested objects flattened into a single level, using dot notation keys
16
+ */
14
17
  export type Smushed<Value extends PlainObject> = Simplify<{
15
18
  [NestedKey in NestedKeys<Value>]: NestedValue<Value, ToString<NestedKey>>;
16
19
  }>;
@@ -3,15 +3,24 @@ import type {GenericCallback, PlainObject} from '../models';
3
3
 
4
4
  // #region Types
5
5
 
6
+ /**
7
+ * A callback transform an object's properties
8
+ */
6
9
  type TransformCallback<Value extends PlainObject, Key extends keyof Value> = (
7
10
  key: Key,
8
11
  value: Value[Key],
9
12
  ) => Value[Key];
10
13
 
14
+ /**
15
+ * A collection of keyed callbacks to transform an object's properties
16
+ */
11
17
  type TransformCallbacks<Value extends PlainObject> = Partial<{
12
18
  [Key in keyof Value]: (value: Value[Key]) => Value[Key];
13
19
  }>;
14
20
 
21
+ /**
22
+ * A transformer function for an object, with predefined callbacks for transforming its properties
23
+ */
15
24
  export type Transformer<Value extends PlainObject> = {
16
25
  (value: Value): Value;
17
26
  };
@@ -66,7 +75,7 @@ export function initializeTransformer<Value extends PlainObject>(
66
75
  *
67
76
  * Available as `initializeTransformer` and `transform.initialize`
68
77
  * @param transformers Keyed transformer functions
69
- * @return Transformer
78
+ * @returns Transformer
70
79
  */
71
80
  export function initializeTransformer<Value extends PlainObject>(
72
81
  transformers: TransformCallbacks<Value>,
@@ -1,6 +1,6 @@
1
1
  import {isArrayOrPlainObject} from '../internal/is';
2
2
  import {setValue} from '../internal/value/set';
3
- import type {PlainObject, Simplify} from '../models';
3
+ import type {PlainObject, Simplify, UnionToIntersection} from '../models';
4
4
 
5
5
  // #region Types
6
6
 
@@ -17,14 +17,8 @@ type OrderedKey = {
17
17
  };
18
18
 
19
19
  /**
20
- * Thanks, type-fest!
20
+ * An unsmushed object, with all dot notation keys turned into nested keys
21
21
  */
22
- type UnionToIntersection<Union> = (
23
- Union extends unknown ? (distributedUnion: Union) => void : never
24
- ) extends (mergedIntersection: infer Intersection) => void
25
- ? Intersection & Union
26
- : never;
27
-
28
22
  export type Unsmushed<Value extends PlainObject> = Simplify<
29
23
  Omit<
30
24
  {