@oscarpalmer/atoms 0.71.0 → 0.72.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.
@@ -175,20 +175,119 @@ function shuffle2(array) {
175
175
  }
176
176
  return shuffled;
177
177
  }
178
+ // src/js/string/index.ts
179
+ function getString(value2) {
180
+ if (typeof value2 === "string") {
181
+ return value2;
182
+ }
183
+ if (typeof value2 !== "object" || value2 == null) {
184
+ return String(value2);
185
+ }
186
+ const valueOff = value2.valueOf?.() ?? value2;
187
+ const asString = valueOff?.toString?.() ?? String(valueOff);
188
+ return asString.startsWith("[object ") ? JSON.stringify(value2) : asString;
189
+ }
190
+ function join(value2, delimiter) {
191
+ return compact(value2).map(getString).filter((value3) => value3.trim().length > 0).join(typeof delimiter === "string" ? delimiter : "");
192
+ }
193
+ function words(value2) {
194
+ return value2.match(/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g) ?? [];
195
+ }
196
+ // src/js/math.ts
197
+ function max(values) {
198
+ return values.length > 0 ? Math.max(...values) : Number.NaN;
199
+ }
200
+
201
+ // src/js/number.ts
202
+ function getNumber(value) {
203
+ if (typeof value === "number") {
204
+ return value;
205
+ }
206
+ if (typeof value === "symbol") {
207
+ return Number.NaN;
208
+ }
209
+ let parsed = value?.valueOf?.() ?? value;
210
+ if (typeof parsed === "object") {
211
+ parsed = parsed?.toString() ?? parsed;
212
+ }
213
+ if (typeof parsed !== "string") {
214
+ return parsed == null ? Number.NaN : typeof parsed === "number" ? parsed : +parsed;
215
+ }
216
+ if (/^\s*0+\s*$/.test(parsed)) {
217
+ return 0;
218
+ }
219
+ const trimmed = parsed.trim();
220
+ if (trimmed.length === 0) {
221
+ return Number.NaN;
222
+ }
223
+ const isBinary = /^0b[01]+$/i.test(trimmed);
224
+ if (isBinary || /^0o[0-7]+$/i.test(trimmed)) {
225
+ return Number.parseInt(trimmed.slice(2), isBinary ? 2 : 8);
226
+ }
227
+ return +(/^0x[0-9a-f]+$/i.test(trimmed) ? trimmed : trimmed.replace(/_/g, ""));
228
+ }
229
+
230
+ // src/js/value/compare.ts
231
+ function compare(first, second) {
232
+ const firstParts = getParts(first);
233
+ const secondParts = getParts(second);
234
+ const length = max([firstParts.length, secondParts.length]);
235
+ const lastIndex = length - 1;
236
+ for (let index = 0;index < length; index += 1) {
237
+ const firstPart = firstParts[index];
238
+ const secondPart = secondParts[index];
239
+ if (firstPart === secondPart) {
240
+ if (index === lastIndex) {
241
+ return 0;
242
+ }
243
+ continue;
244
+ }
245
+ if (firstPart == null || typeof firstPart === "string" && firstPart.length === 0) {
246
+ return -1;
247
+ }
248
+ if (secondPart == null || typeof secondPart === "string" && secondPart.length === 0) {
249
+ return 1;
250
+ }
251
+ const firstNumber = getNumber(firstPart);
252
+ const secondNumber = getNumber(secondPart);
253
+ const firstIsNaN = Number.isNaN(firstNumber);
254
+ const secondIsNaN = Number.isNaN(secondNumber);
255
+ if (firstIsNaN || secondIsNaN) {
256
+ if (firstIsNaN && secondIsNaN) {
257
+ return getString(firstPart).localeCompare(getString(secondPart));
258
+ }
259
+ if (firstIsNaN) {
260
+ return 1;
261
+ }
262
+ if (secondIsNaN) {
263
+ return -1;
264
+ }
265
+ }
266
+ if (firstNumber === secondNumber) {
267
+ if (index === lastIndex) {
268
+ return 0;
269
+ }
270
+ continue;
271
+ }
272
+ return firstNumber - secondNumber;
273
+ }
274
+ return join(firstParts).localeCompare(join(secondParts));
275
+ }
276
+ function getParts(value) {
277
+ if (value == null) {
278
+ return [""];
279
+ }
280
+ if (Array.isArray(value)) {
281
+ return value;
282
+ }
283
+ return typeof value === "object" ? [value] : words(getString(value));
284
+ }
178
285
  // src/js/is.ts
179
286
  function isKey(value2) {
180
287
  return typeof value2 === "number" || typeof value2 === "string";
181
288
  }
182
289
 
183
290
  // src/js/array/sort.ts
184
- function comparison(first, second) {
185
- if (typeof first === "number" && typeof second === "number") {
186
- return first - second;
187
- }
188
- const firstAsNumber = Number(first);
189
- const secondAsNumber = Number(second);
190
- return Number.isNaN(firstAsNumber) || Number.isNaN(secondAsNumber) ? String(first).localeCompare(String(second)) : firstAsNumber - secondAsNumber;
191
- }
192
291
  function sort(array2, first, second) {
193
292
  if (array2.length < 2) {
194
293
  return array2;
@@ -217,13 +316,13 @@ function sort(array2, first, second) {
217
316
  return direction === "asc" ? array2.sort() : array2.sort((first2, second2) => second2 - first2);
218
317
  }
219
318
  if (length === 1) {
220
- return array2.sort((first2, second2) => comparison(keys[0].callback(first2), keys[0].callback(second2)) * (keys[0].direction === "asc" ? 1 : -1));
319
+ return array2.sort((first2, second2) => compare(keys[0].callback(first2), keys[0].callback(second2)) * (keys[0].direction === "asc" ? 1 : -1));
221
320
  }
222
321
  const sorted = array2.sort((first2, second2) => {
223
322
  for (let index = 0;index < length; index += 1) {
224
323
  const { callback, direction: direction2 } = keys[index];
225
324
  const descending = direction2 === "desc";
226
- const compared = comparison(callback(descending ? second2 : first2), callback(descending ? first2 : second2));
325
+ const compared = compare(callback(descending ? second2 : first2), callback(descending ? first2 : second2));
227
326
  if (compared !== 0) {
228
327
  return compared;
229
328
  }
@@ -1,13 +1,6 @@
1
1
  // src/js/array/sort.ts
2
2
  import {isKey} from "../is";
3
- function comparison(first, second) {
4
- if (typeof first === "number" && typeof second === "number") {
5
- return first - second;
6
- }
7
- const firstAsNumber = Number(first);
8
- const secondAsNumber = Number(second);
9
- return Number.isNaN(firstAsNumber) || Number.isNaN(secondAsNumber) ? String(first).localeCompare(String(second)) : firstAsNumber - secondAsNumber;
10
- }
3
+ import {compare as compare2} from "../value/compare";
11
4
  function sort(array, first, second) {
12
5
  if (array.length < 2) {
13
6
  return array;
@@ -36,13 +29,13 @@ function sort(array, first, second) {
36
29
  return direction === "asc" ? array.sort() : array.sort((first2, second2) => second2 - first2);
37
30
  }
38
31
  if (length === 1) {
39
- return array.sort((first2, second2) => comparison(keys[0].callback(first2), keys[0].callback(second2)) * (keys[0].direction === "asc" ? 1 : -1));
32
+ return array.sort((first2, second2) => compare2(keys[0].callback(first2), keys[0].callback(second2)) * (keys[0].direction === "asc" ? 1 : -1));
40
33
  }
41
34
  const sorted = array.sort((first2, second2) => {
42
35
  for (let index = 0;index < length; index += 1) {
43
36
  const { callback, direction: direction2 } = keys[index];
44
37
  const descending = direction2 === "desc";
45
- const compared = comparison(callback(descending ? second2 : first2), callback(descending ? first2 : second2));
38
+ const compared = compare2(callback(descending ? second2 : first2), callback(descending ? first2 : second2));
46
39
  if (compared !== 0) {
47
40
  return compared;
48
41
  }
@@ -3,6 +3,27 @@ function noop() {
3
3
  }
4
4
 
5
5
  // src/js/emitter.ts
6
+ function emitter(value) {
7
+ return new Emitter(value);
8
+ }
9
+ function finishEmitter(state, emit) {
10
+ if (state.active) {
11
+ state.active = false;
12
+ const entries = [...state.observers.entries()];
13
+ const { length } = entries;
14
+ for (let index = 0;index < length; index += 1) {
15
+ const [subscription, observer] = entries[index];
16
+ if (emit) {
17
+ observer.complete?.();
18
+ }
19
+ subscription.destroy();
20
+ }
21
+ state.observers.clear();
22
+ state.observable = undefined;
23
+ state.observers = undefined;
24
+ state.value = undefined;
25
+ }
26
+ }
6
27
  function getObserver(first, second, third) {
7
28
  let observer = {
8
29
  next: noop
@@ -21,20 +42,6 @@ function getObserver(first, second, third) {
21
42
  }
22
43
  return observer;
23
44
  }
24
- function emitter(value) {
25
- return new Emitter(value);
26
- }
27
- function finishEmitter(state, emit) {
28
- if (state.active) {
29
- state.active = false;
30
- for (const [subscription, observer] of state.observers) {
31
- if (emit) {
32
- observer.complete?.();
33
- }
34
- subscription.unsubscribe();
35
- }
36
- }
37
- }
38
45
 
39
46
  class Emitter {
40
47
  get active() {
@@ -108,12 +115,17 @@ class Subscription {
108
115
  };
109
116
  }
110
117
  get closed() {
111
- return this.state.closed || !this.state.emitter.active;
118
+ return this.state.closed || !(this.state.emitter?.active ?? false);
119
+ }
120
+ destroy() {
121
+ this.unsubscribe();
122
+ this.state.emitter = undefined;
123
+ this.state.observers = undefined;
112
124
  }
113
125
  unsubscribe() {
114
126
  if (!this.state.closed) {
115
127
  this.state.closed = true;
116
- this.state.observers.delete(this);
128
+ this.state.observers?.delete(this);
117
129
  }
118
130
  }
119
131
  }
@@ -1,5 +1,26 @@
1
1
  // src/js/emitter.ts
2
2
  import {noop} from "./function";
3
+ function emitter(value) {
4
+ return new Emitter(value);
5
+ }
6
+ function finishEmitter(state, emit) {
7
+ if (state.active) {
8
+ state.active = false;
9
+ const entries = [...state.observers.entries()];
10
+ const { length } = entries;
11
+ for (let index = 0;index < length; index += 1) {
12
+ const [subscription, observer] = entries[index];
13
+ if (emit) {
14
+ observer.complete?.();
15
+ }
16
+ subscription.destroy();
17
+ }
18
+ state.observers.clear();
19
+ state.observable = undefined;
20
+ state.observers = undefined;
21
+ state.value = undefined;
22
+ }
23
+ }
3
24
  function getObserver(first, second, third) {
4
25
  let observer = {
5
26
  next: noop
@@ -18,20 +39,6 @@ function getObserver(first, second, third) {
18
39
  }
19
40
  return observer;
20
41
  }
21
- function emitter(value) {
22
- return new Emitter(value);
23
- }
24
- function finishEmitter(state, emit) {
25
- if (state.active) {
26
- state.active = false;
27
- for (const [subscription, observer] of state.observers) {
28
- if (emit) {
29
- observer.complete?.();
30
- }
31
- subscription.unsubscribe();
32
- }
33
- }
34
- }
35
42
 
36
43
  class Emitter {
37
44
  get active() {
@@ -105,12 +112,17 @@ class Subscription {
105
112
  };
106
113
  }
107
114
  get closed() {
108
- return this.state.closed || !this.state.emitter.active;
115
+ return this.state.closed || !(this.state.emitter?.active ?? false);
116
+ }
117
+ destroy() {
118
+ this.unsubscribe();
119
+ this.state.emitter = undefined;
120
+ this.state.observers = undefined;
109
121
  }
110
122
  unsubscribe() {
111
123
  if (!this.state.closed) {
112
124
  this.state.closed = true;
113
- this.state.observers.delete(this);
125
+ this.state.observers?.delete(this);
114
126
  }
115
127
  }
116
128
  }
@@ -61,16 +61,21 @@ class Memoised {
61
61
  this.state = { cache, getter };
62
62
  }
63
63
  clear() {
64
- this.state.cache.clear();
64
+ this.state.cache?.clear();
65
65
  }
66
66
  delete(key) {
67
- return this.state.cache.delete(key);
67
+ return this.state.cache?.delete(key);
68
+ }
69
+ destroy() {
70
+ this.state.cache.clear();
71
+ this.state.cache = undefined;
72
+ this.state.getter = noop;
68
73
  }
69
74
  get(key) {
70
- return this.state.cache.get(key);
75
+ return this.state.cache?.get(key);
71
76
  }
72
77
  has(key) {
73
- return this.state.cache.has(key);
78
+ return this.state.cache?.has(key) ?? false;
74
79
  }
75
80
  run(...parameters) {
76
81
  return this.state.getter(...parameters);
@@ -54,16 +54,21 @@ class Memoised {
54
54
  this.state = { cache, getter };
55
55
  }
56
56
  clear() {
57
- this.state.cache.clear();
57
+ this.state.cache?.clear();
58
58
  }
59
59
  delete(key) {
60
- return this.state.cache.delete(key);
60
+ return this.state.cache?.delete(key);
61
+ }
62
+ destroy() {
63
+ this.state.cache.clear();
64
+ this.state.cache = undefined;
65
+ this.state.getter = noop;
61
66
  }
62
67
  get(key) {
63
- return this.state.cache.get(key);
68
+ return this.state.cache?.get(key);
64
69
  }
65
70
  has(key) {
66
- return this.state.cache.has(key);
71
+ return this.state.cache?.has(key) ?? false;
67
72
  }
68
73
  run(...parameters) {
69
74
  return this.state.getter(...parameters);