@oscarpalmer/atoms 0.193.0 → 0.194.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 (204) hide show
  1. package/dist/array/difference.mjs +2 -2
  2. package/dist/array/intersection.mjs +2 -2
  3. package/dist/array/match.mjs +13 -13
  4. package/dist/array/slice.mjs +5 -5
  5. package/dist/array/sort.d.mts +5 -1
  6. package/dist/array/sort.mjs +4 -2
  7. package/dist/array/union.mjs +2 -2
  8. package/dist/beacon.d.mts +8 -1
  9. package/dist/beacon.mjs +52 -60
  10. package/dist/color/constants.d.mts +1 -1
  11. package/dist/color/constants.mjs +3 -5
  12. package/dist/color/instance.mjs +34 -41
  13. package/dist/color/misc/format.d.mts +3 -2
  14. package/dist/color/misc/format.mjs +4 -1
  15. package/dist/color/misc/is.d.mts +9 -1
  16. package/dist/color/misc/is.mjs +11 -1
  17. package/dist/color/misc/state.d.mts +6 -6
  18. package/dist/color/misc/state.mjs +11 -14
  19. package/dist/color/models.d.mts +23 -68
  20. package/dist/function/assert.mjs +2 -2
  21. package/dist/function/limit.d.mts +0 -6
  22. package/dist/function/limit.mjs +2 -2
  23. package/dist/function/memoize.mjs +19 -32
  24. package/dist/function/once.d.mts +0 -3
  25. package/dist/function/once.mjs +16 -13
  26. package/dist/function/retry.d.mts +1 -24
  27. package/dist/function/retry.mjs +1 -1
  28. package/dist/function/work.mjs +13 -11
  29. package/dist/herald.d.mts +30 -31
  30. package/dist/herald.mjs +74 -56
  31. package/dist/index.d.mts +100 -185
  32. package/dist/index.mjs +680 -702
  33. package/dist/internal/abort.d.mts +10 -0
  34. package/dist/internal/abort.mjs +14 -0
  35. package/dist/internal/array/chunk.mjs +2 -2
  36. package/dist/internal/array/find.mjs +2 -2
  37. package/dist/internal/array/sets.d.mts +4 -4
  38. package/dist/internal/array/sets.mjs +7 -7
  39. package/dist/internal/function/timer.mjs +19 -15
  40. package/dist/internal/number.mjs +7 -7
  41. package/dist/internal/result.mjs +3 -3
  42. package/dist/internal/sized.mjs +4 -4
  43. package/dist/internal/string.mjs +4 -4
  44. package/dist/internal/subscription.d.mts +24 -8
  45. package/dist/internal/subscription.mjs +49 -36
  46. package/dist/internal/value/equal.mjs +6 -6
  47. package/dist/internal/value/misc.mjs +14 -14
  48. package/dist/internal/value/set.mjs +2 -2
  49. package/dist/logger.mjs +15 -39
  50. package/dist/promise/constants.d.mts +17 -0
  51. package/dist/promise/constants.mjs +14 -0
  52. package/dist/promise/delay.mjs +7 -10
  53. package/dist/promise/helpers.mjs +1 -1
  54. package/dist/promise/index.mjs +14 -17
  55. package/dist/promise/misc.d.mts +2 -1
  56. package/dist/promise/misc.mjs +8 -7
  57. package/dist/promise/models.d.mts +4 -16
  58. package/dist/promise/models.mjs +4 -13
  59. package/dist/promise/timed.mjs +9 -10
  60. package/dist/query.mjs +15 -15
  61. package/dist/queue.mjs +103 -116
  62. package/dist/random.mjs +7 -7
  63. package/dist/result/index.d.mts +0 -3
  64. package/dist/result/index.mjs +1 -1
  65. package/dist/result/match.d.mts +0 -3
  66. package/dist/result/match.mjs +4 -4
  67. package/dist/result/misc.mjs +2 -2
  68. package/dist/result/work/flow.d.mts +0 -3
  69. package/dist/result/work/flow.mjs +5 -5
  70. package/dist/result/work/pipe.d.mts +0 -3
  71. package/dist/result/work/pipe.mjs +3 -3
  72. package/dist/string/case.mjs +20 -20
  73. package/dist/string/fuzzy.mjs +23 -18
  74. package/dist/string/index.mjs +7 -7
  75. package/dist/string/normalize.mjs +14 -14
  76. package/dist/string/template.mjs +2 -2
  77. package/dist/value/clone.mjs +10 -10
  78. package/dist/value/smush.mjs +2 -2
  79. package/package.json +13 -5
  80. package/src/array/difference.ts +0 -73
  81. package/src/array/exists.ts +0 -93
  82. package/src/array/filter.ts +0 -182
  83. package/src/array/find.ts +0 -183
  84. package/src/array/first.ts +0 -196
  85. package/src/array/flatten.ts +0 -20
  86. package/src/array/from.ts +0 -129
  87. package/src/array/get.ts +0 -131
  88. package/src/array/group-by.ts +0 -369
  89. package/src/array/index.ts +0 -26
  90. package/src/array/insert.ts +0 -52
  91. package/src/array/intersection.ts +0 -72
  92. package/src/array/last.ts +0 -194
  93. package/src/array/match.ts +0 -436
  94. package/src/array/move.ts +0 -315
  95. package/src/array/partition.ts +0 -91
  96. package/src/array/push.ts +0 -23
  97. package/src/array/reverse.ts +0 -33
  98. package/src/array/select.ts +0 -260
  99. package/src/array/single.ts +0 -93
  100. package/src/array/slice.ts +0 -335
  101. package/src/array/sort.ts +0 -607
  102. package/src/array/splice.ts +0 -106
  103. package/src/array/swap.ts +0 -322
  104. package/src/array/to-map.ts +0 -371
  105. package/src/array/to-record.ts +0 -351
  106. package/src/array/to-set.ts +0 -80
  107. package/src/array/toggle.ts +0 -79
  108. package/src/array/union.ts +0 -72
  109. package/src/array/unique.ts +0 -67
  110. package/src/array/update.ts +0 -75
  111. package/src/beacon.ts +0 -378
  112. package/src/color/constants.ts +0 -137
  113. package/src/color/index.ts +0 -83
  114. package/src/color/instance.ts +0 -162
  115. package/src/color/misc/alpha.ts +0 -56
  116. package/src/color/misc/format.ts +0 -29
  117. package/src/color/misc/get.ts +0 -210
  118. package/src/color/misc/is.ts +0 -221
  119. package/src/color/misc/state.ts +0 -243
  120. package/src/color/models.ts +0 -389
  121. package/src/color/space/hex.ts +0 -184
  122. package/src/color/space/hsl.ts +0 -174
  123. package/src/color/space/hwb.ts +0 -153
  124. package/src/color/space/rgb.ts +0 -240
  125. package/src/function/assert.ts +0 -174
  126. package/src/function/index.ts +0 -2
  127. package/src/function/limit.ts +0 -83
  128. package/src/function/memoize.ts +0 -202
  129. package/src/function/once.ts +0 -200
  130. package/src/function/retry.ts +0 -175
  131. package/src/function/work.ts +0 -1007
  132. package/src/herald.ts +0 -216
  133. package/src/index.ts +0 -68
  134. package/src/internal/array/callbacks.ts +0 -46
  135. package/src/internal/array/chunk.ts +0 -51
  136. package/src/internal/array/compact.ts +0 -56
  137. package/src/internal/array/find.ts +0 -200
  138. package/src/internal/array/group.ts +0 -42
  139. package/src/internal/array/index-of.ts +0 -182
  140. package/src/internal/array/insert.ts +0 -80
  141. package/src/internal/array/overlap.ts +0 -35
  142. package/src/internal/array/sets.ts +0 -74
  143. package/src/internal/array/shuffle.ts +0 -33
  144. package/src/internal/array/update.ts +0 -52
  145. package/src/internal/function/misc.ts +0 -8
  146. package/src/internal/function/timer.ts +0 -168
  147. package/src/internal/is.ts +0 -244
  148. package/src/internal/math/aggregate.ts +0 -164
  149. package/src/internal/math/misc.ts +0 -28
  150. package/src/internal/number.ts +0 -129
  151. package/src/internal/random.ts +0 -49
  152. package/src/internal/result.ts +0 -92
  153. package/src/internal/sized.ts +0 -25
  154. package/src/internal/string.ts +0 -128
  155. package/src/internal/subscription.ts +0 -264
  156. package/src/internal/value/compare.ts +0 -170
  157. package/src/internal/value/equal.ts +0 -465
  158. package/src/internal/value/get.ts +0 -57
  159. package/src/internal/value/handlers.ts +0 -95
  160. package/src/internal/value/has.ts +0 -118
  161. package/src/internal/value/misc.ts +0 -125
  162. package/src/internal/value/partial.ts +0 -46
  163. package/src/internal/value/set.ts +0 -132
  164. package/src/is.ts +0 -182
  165. package/src/logger.ts +0 -230
  166. package/src/math.ts +0 -281
  167. package/src/models.ts +0 -286
  168. package/src/number.ts +0 -1
  169. package/src/promise/delay.ts +0 -62
  170. package/src/promise/helpers.ts +0 -96
  171. package/src/promise/index.ts +0 -300
  172. package/src/promise/misc.ts +0 -96
  173. package/src/promise/models.ts +0 -195
  174. package/src/promise/timed.ts +0 -91
  175. package/src/query.ts +0 -147
  176. package/src/queue.ts +0 -814
  177. package/src/random.ts +0 -125
  178. package/src/result/index.ts +0 -105
  179. package/src/result/match.ts +0 -124
  180. package/src/result/misc.ts +0 -129
  181. package/src/result/models.ts +0 -83
  182. package/src/result/work/flow.ts +0 -488
  183. package/src/result/work/pipe.ts +0 -496
  184. package/src/sized/map.ts +0 -110
  185. package/src/sized/set.ts +0 -107
  186. package/src/string/case.ts +0 -236
  187. package/src/string/fuzzy.ts +0 -444
  188. package/src/string/index.ts +0 -199
  189. package/src/string/match.ts +0 -80
  190. package/src/string/normalize.ts +0 -205
  191. package/src/string/template.ts +0 -161
  192. package/src/value/clone.ts +0 -319
  193. package/src/value/collection.ts +0 -63
  194. package/src/value/diff.ts +0 -232
  195. package/src/value/freeze.ts +0 -322
  196. package/src/value/handle.ts +0 -3
  197. package/src/value/index.ts +0 -5
  198. package/src/value/merge.ts +0 -278
  199. package/src/value/omit.ts +0 -20
  200. package/src/value/pick.ts +0 -20
  201. package/src/value/shake.ts +0 -45
  202. package/src/value/smush.ts +0 -89
  203. package/src/value/transform.ts +0 -153
  204. package/src/value/unsmush.ts +0 -84
@@ -1,25 +0,0 @@
1
- // #region Functions
2
-
3
- import {clamp} from './number';
4
-
5
- export function getSizedMaximum(first?: unknown, second?: unknown): number {
6
- let actual: number;
7
-
8
- if (typeof first === 'number') {
9
- actual = first;
10
- } else {
11
- actual = typeof second === 'number' ? second : MAXIMUM_DEFAULT;
12
- }
13
-
14
- return clamp(actual, 1, MAXIMUM_ABSOLUTE);
15
- }
16
-
17
- // #endregion
18
-
19
- // #region Variables
20
-
21
- const MAXIMUM_ABSOLUTE = 16_777_216; // 2^24
22
-
23
- const MAXIMUM_DEFAULT = 1_048_576; // 2^20
24
-
25
- // #endregion
@@ -1,128 +0,0 @@
1
- // #region Functions
2
-
3
- /**
4
- * Get the string value from any value
5
- *
6
- * @param value Original value
7
- * @returns String representation of the value
8
- *
9
- * @example
10
- * ```typescript
11
- * getString(null) // => ''
12
- * getString('foo') // => 'foo'
13
- * getString(123) // => '123'
14
- * getString(true) // => 'true'
15
- * getString([1, 2, 3]) // => '1,2,3'
16
- * getString({a: 1}) // => '{"a":1}'
17
- * getString(() => 123) // => '123'
18
- * ```
19
- */
20
- export function getString(value: unknown): string {
21
- if (typeof value === 'string') {
22
- return value;
23
- }
24
-
25
- if (value == null) {
26
- return '';
27
- }
28
-
29
- if (typeof value === 'function') {
30
- return getString(value());
31
- }
32
-
33
- if (typeof value !== 'object') {
34
- return String(value);
35
- }
36
-
37
- const asString = String(value.valueOf?.() ?? value);
38
-
39
- return asString.startsWith('[object ') ? JSON.stringify(value) : asString;
40
- }
41
-
42
- export function ignoreKey(key: string): boolean {
43
- return EXPRESSION_IGNORED.test(key);
44
- }
45
-
46
- export function interpolate(strings: TemplateStringsArray, values: unknown[]): string {
47
- const {length} = strings;
48
-
49
- let interpolated = '';
50
-
51
- for (let index = 0; index < length; index += 1) {
52
- const value = values[index];
53
-
54
- interpolated += `${strings[index]}${Array.isArray(value) ? join(value.map(getString)) : getString(value)}`;
55
- }
56
-
57
- return interpolated;
58
- }
59
-
60
- /**
61
- * Join an array of values into a string _(while ignoring empty values)_
62
- *
63
- * _(`null`, `undefined`, and any values that become whitespace-only strings are considered empty)_
64
- *
65
- * @param array Array of values
66
- * @param delimiter Delimiter to use between values
67
- * @returns Joined string
68
- */
69
- export function join(array: unknown[], delimiter?: string): string {
70
- if (!Array.isArray(array)) {
71
- return '';
72
- }
73
-
74
- const {length} = array;
75
-
76
- if (length === 0) {
77
- return '';
78
- }
79
-
80
- const values: string[] = [];
81
-
82
- for (let index = 0; index < length; index += 1) {
83
- const item = getString(array[index]);
84
-
85
- if (item.length > 0) {
86
- values.push(item);
87
- }
88
- }
89
-
90
- return values.join(typeof delimiter === 'string' ? delimiter : '');
91
- }
92
-
93
- function tryCallback<T, U>(value: T, callback: (value: T) => U): U {
94
- try {
95
- return callback(value);
96
- } catch {
97
- return value as never;
98
- }
99
- }
100
-
101
- export function tryDecode(value: string): string {
102
- return tryCallback(value, decodeURIComponent);
103
- }
104
-
105
- export function tryEncode(value: boolean | number | string): unknown {
106
- return tryCallback(value, encodeURIComponent);
107
- }
108
-
109
- /**
110
- * Split a string into words _(and other readable parts)_
111
- *
112
- * @param value Original string
113
- * @returns Array of words found in the string
114
- */
115
- export function words(value: string): string[] {
116
- return typeof value === 'string' ? (value.match(EXPRESSION_WORDS) ?? []) : [];
117
- }
118
-
119
- // #endregion
120
-
121
- // #region Variables
122
-
123
- const EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
124
-
125
- // oxlint-disable-next-line no-control-regex: Lodash uses it, so it's fine ;-)
126
- const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
127
-
128
- // #endregion
@@ -1,264 +0,0 @@
1
- import type {Key} from '../models';
2
- import {isPlainObject} from './is';
3
-
4
- // #region Types
5
-
6
- export type Subscription = {
7
- /**
8
- * Is the subscription active?
9
- */
10
- get active(): boolean;
11
-
12
- /**
13
- * Unsubscribe from changes
14
- */
15
- unsubscribe(): void;
16
- };
17
-
18
- export type SubscriptionParameters = {
19
- isActive?: () => boolean;
20
- key?: Key;
21
- property: SubscriptionProperty;
22
- subscriptions: Subscriptions;
23
- value: unknown;
24
- };
25
-
26
- export type SubscriptionProperty = {
27
- key: string;
28
- value: unknown;
29
- };
30
-
31
- type SubscriptionState = {
32
- active: boolean;
33
- parameters: SubscriptionParameters;
34
- };
35
-
36
- export type Subscriptions<Value = unknown> = {
37
- items: SubscriptionsItems;
38
- keys?: Set<Key>;
39
- values: SubscriptionsValues<Value>;
40
- };
41
-
42
- type SubscriptionsItems = {
43
- any: Set<Subscription>;
44
- keyed?: Map<Key, Set<Subscription>>;
45
- };
46
-
47
- type SubscriptionsValues<Value = unknown> = {
48
- from: SubscriptionsValuesItem<Value, Subscription>;
49
- to: SubscriptionsValuesItem<Subscription, Value>;
50
- };
51
-
52
- type SubscriptionsValuesItem<MapKey, MapValue> = {
53
- any: Map<MapKey, MapValue>;
54
- keyed?: Map<Key, Map<MapKey, MapValue>>;
55
- };
56
-
57
- // #endregion
58
-
59
- // #region Functions
60
-
61
- function addSubscription(subscription: Subscription, state: SubscriptionState): void {
62
- const {key, subscriptions, value} = state.parameters;
63
- const {items, values} = subscriptions;
64
-
65
- if (key == null) {
66
- items.any.add(subscription);
67
- values.from.any.set(value, subscription);
68
- values.to.any.set(subscription, value);
69
-
70
- return;
71
- }
72
-
73
- if (items.keyed == null || values.from.keyed == null || values.to.keyed == null) {
74
- // TODO: fix tests or document
75
- // istanbul ignore next
76
- return;
77
- }
78
-
79
- let keyedItems = items.keyed.get(key);
80
-
81
- if (keyedItems == null) {
82
- keyedItems = new Set();
83
-
84
- items.keyed.set(key, keyedItems);
85
- }
86
-
87
- keyedItems.add(subscription);
88
-
89
- let keyedFrom = values.from.keyed.get(key);
90
-
91
- if (keyedFrom == null) {
92
- keyedFrom = new Map();
93
-
94
- values.from.keyed.set(key, keyedFrom);
95
- }
96
-
97
- keyedFrom.set(value, subscription);
98
-
99
- let keyedTo = values.to.keyed.get(key);
100
-
101
- if (keyedTo == null) {
102
- keyedTo = new Map();
103
-
104
- values.to.keyed.set(key, keyedTo);
105
- }
106
-
107
- keyedTo.set(subscription, value);
108
- }
109
-
110
- export function clearSubscriptions(store: Subscriptions): void {
111
- for (const susbcription of store.values.to.any.keys()) {
112
- susbcription.unsubscribe();
113
- }
114
-
115
- if (store.values.to.keyed != null) {
116
- for (const values of store.values.to.keyed.values()) {
117
- for (const susbcription of values.keys()) {
118
- susbcription.unsubscribe();
119
- }
120
- }
121
- }
122
- }
123
-
124
- function getExistingSubscription(state: SubscriptionState): Subscription | undefined {
125
- const {parameters} = state;
126
- const {values} = parameters.subscriptions;
127
-
128
- return parameters.key == null
129
- ? values.from.any.get(parameters.value)
130
- : values.from.keyed?.get(parameters.key)?.get(parameters.value);
131
- }
132
-
133
- export function getSubscription(parameters: SubscriptionParameters): Subscription {
134
- const state: SubscriptionState = {
135
- parameters,
136
- active: true,
137
- };
138
-
139
- const existing = getExistingSubscription(state);
140
-
141
- if (existing != null) {
142
- return existing;
143
- }
144
-
145
- if (
146
- parameters.subscriptions.keys != null &&
147
- parameters.key != null &&
148
- !parameters.subscriptions.keys.has(parameters.key)
149
- ) {
150
- throw new Error();
151
- }
152
-
153
- const instance = {
154
- unsubscribe: () => {
155
- removeSubscription(instance as Subscription, state);
156
- },
157
- };
158
-
159
- Object.defineProperties(instance, {
160
- [PROPERTY]: {
161
- enumerable: false,
162
- value: true,
163
- },
164
- [parameters.property.key]: {
165
- enumerable: false,
166
- value: parameters.property.value,
167
- },
168
- active: {
169
- enumerable: true,
170
- get: () => (parameters.isActive?.() ?? true) && state.active,
171
- },
172
- });
173
-
174
- addSubscription(instance as Subscription, state);
175
-
176
- return Object.freeze(instance) as Subscription;
177
- }
178
-
179
- export function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value> {
180
- return {
181
- keys,
182
- items: {
183
- any: new Set(),
184
- keyed: keys == null ? undefined : new Map(),
185
- },
186
- values: {
187
- from: {
188
- any: new Map(),
189
- keyed: keys == null ? undefined : new Map(),
190
- },
191
- to: {
192
- any: new Map(),
193
- keyed: keys == null ? undefined : new Map(),
194
- },
195
- },
196
- };
197
- }
198
-
199
- /**
200
- * Is the value a subscription?
201
- *
202
- * @param value Value to check
203
- * @returns `true` if the value is a subscription, otherwise `false`
204
- */
205
- export function isSubscription(value: unknown): value is Subscription {
206
- return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
207
- }
208
-
209
- function removeFromStore(
210
- items: Set<Subscription>,
211
- values: SubscriptionsValues,
212
- subscription: Subscription,
213
- value: unknown,
214
- key?: Key,
215
- ): void {
216
- items.delete(subscription);
217
-
218
- if (key == null) {
219
- values.from.any.delete(value);
220
- values.to.any.delete(subscription);
221
- } else {
222
- values.from.keyed?.get(key)?.delete(value);
223
- values.to.keyed?.get(key)?.delete(subscription);
224
- }
225
- }
226
-
227
- function removeSubscription(subscription: Subscription, state: SubscriptionState): void {
228
- if (!state.active) {
229
- return;
230
- }
231
-
232
- state.active = false;
233
-
234
- const {key, subscriptions, value} = state.parameters;
235
- const {items, values} = subscriptions;
236
-
237
- if (key == null) {
238
- removeFromStore(items.any, values, subscription, value);
239
-
240
- return;
241
- }
242
-
243
- const keyed = items.keyed?.get(key);
244
-
245
- if (items.keyed == null || keyed == null) {
246
- // TODO, fix tests or document
247
- // istanbul ignore next
248
- return;
249
- }
250
-
251
- removeFromStore(keyed, values, subscription, value, key);
252
-
253
- if (keyed.size === 0) {
254
- items.keyed.delete(key);
255
- }
256
- }
257
-
258
- // #endregion
259
-
260
- // #region Variables
261
-
262
- const PROPERTY = '$subscription';
263
-
264
- // #endregion
@@ -1,170 +0,0 @@
1
- import type {Constructor} from '../../models';
2
- import {max} from '../math/aggregate';
3
- import {getString, words} from '../string';
4
- import {getCompareHandlers} from './handlers';
5
-
6
- // #region Types
7
-
8
- type Comparator<Value = any> = (first: Value, second: Value) => number;
9
-
10
- // #endregion
11
-
12
- // #region Special variables
13
-
14
- const COMPARE_NAME: string = 'compare';
15
-
16
- // #endregion
17
-
18
- // #region Functions
19
-
20
- /**
21
- * Compare two values _(for sorting purposes)_
22
- *
23
- * @param first First value
24
- * @param second Second value
25
- * @returns `0` if equal; `-1` first comes before second; `1` first comes after second
26
- */
27
- export function compare(first: unknown, second: unknown): number {
28
- if (Object.is(first, second)) {
29
- return 0;
30
- }
31
-
32
- if (first == null) {
33
- return -1;
34
- }
35
-
36
- if (second == null) {
37
- return 1;
38
- }
39
-
40
- let comparison = compareValue(first, second, false);
41
-
42
- if (comparison != null) {
43
- return comparison;
44
- }
45
-
46
- const firstParts = getComparisonParts(first);
47
- const secondParts = getComparisonParts(second);
48
- const length = max([firstParts.length, secondParts.length]);
49
-
50
- const lastIndex = length - 1;
51
-
52
- for (let index = 0; index < length; index += 1) {
53
- const firstPart = firstParts[index];
54
- const secondPart = secondParts[index];
55
-
56
- comparison = compareValue(firstPart, secondPart, true);
57
-
58
- if (comparison === 0) {
59
- if (index === lastIndex) {
60
- break;
61
- }
62
-
63
- continue;
64
- }
65
-
66
- return comparison as number;
67
- }
68
-
69
- return 0;
70
- }
71
-
72
- compare.handlers = getCompareHandlers<number>(compare, {
73
- callback: (first, second, compareStrings) => {
74
- if (compareStrings) {
75
- return getString(first).localeCompare(getString(second));
76
- }
77
- },
78
- method: COMPARE_NAME,
79
- });
80
-
81
- compare.deregister = deregisterComparator;
82
- compare.register = registerComparator;
83
-
84
- function compareNumbers(first: bigint | number, second: bigint | number): number {
85
- if (Object.is(first, second)) {
86
- return 0;
87
- }
88
-
89
- if (Number.isNaN(first)) {
90
- return -1;
91
- }
92
-
93
- if (Number.isNaN(second)) {
94
- return 1;
95
- }
96
-
97
- return first > second ? 1 : -1;
98
- }
99
-
100
- function compareSymbols(first: symbol, second: symbol): number {
101
- return getString(first.description ?? first).localeCompare(
102
- getString(second.description ?? second),
103
- );
104
- }
105
-
106
- function compareValue(
107
- first: unknown,
108
- second: unknown,
109
- compareStrings: boolean,
110
- ): number | undefined {
111
- const firstType = typeof first;
112
- const secondType = typeof second;
113
-
114
- if (firstType === secondType && firstType in comparators) {
115
- return comparators[firstType as keyof typeof comparators](first as never, second as never);
116
- }
117
-
118
- if (first instanceof Date && second instanceof Date) {
119
- return compareNumbers(first.getTime(), second.getTime());
120
- }
121
-
122
- return compare.handlers.handle(first, second, compareStrings);
123
- }
124
-
125
- /**
126
- * Deregister a custom comparison handler for a class
127
- *
128
- * _Available as `deregisterComparator` and `compare.deregister`_
129
- *
130
- * @param constructor Class constructor
131
- */
132
- export function deregisterComparator<Instance>(constructor: Constructor<Instance>): void {
133
- compare.handlers.deregister(constructor);
134
- }
135
-
136
- function getComparisonParts(value: unknown): unknown[] {
137
- if (Array.isArray(value)) {
138
- return value;
139
- }
140
-
141
- return typeof value === 'object' ? [value] : words(getString(value));
142
- }
143
-
144
- /**
145
- * Register a custom comparison handler for a class
146
- *
147
- * _Available as `registerComparator` and `compare.register`_
148
- *
149
- * @param constructor Class constructor
150
- * @param handler Method name or comparison function _(defaults to `compare`)_
151
- */
152
- export function registerComparator<Instance>(
153
- constructor: Constructor<Instance>,
154
- handler?: string | Comparator<Instance>,
155
- ): void {
156
- compare.handlers.register(constructor, handler);
157
- }
158
-
159
- // #endregion
160
-
161
- // #region Variables
162
-
163
- const comparators: Record<string, Comparator> = {
164
- bigint: compareNumbers,
165
- boolean: (first, second) => compareNumbers(first ? 1 : 0, second ? 1 : 0),
166
- number: compareNumbers,
167
- symbol: compareSymbols,
168
- };
169
-
170
- // #endregion