@oscarpalmer/atoms 0.59.0 → 0.60.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.
@@ -19,11 +19,12 @@ function insert(array, index, values) {
19
19
  insertValues("splice", array, values, index, 0);
20
20
  }
21
21
  function insertValues(type, array, values, start, deleteCount) {
22
- const chunked = chunk(values).reverse();
23
- const { length } = chunked;
22
+ const chunked = chunk(values);
23
+ const lastIndex = chunked.length - 1;
24
+ let index = Number(chunked.length);
24
25
  let returned;
25
- for (let index = 0;index < length; index += 1) {
26
- const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
26
+ while (--index >= 0) {
27
+ const result = array.splice(start, index === lastIndex ? deleteCount : 0, ...chunked[index]);
27
28
  if (returned == null) {
28
29
  returned = result;
29
30
  }
@@ -155,6 +156,25 @@ function groupValues(array, key, arrays, indicable) {
155
156
  function indexOf(array, value, key) {
156
157
  return findValue("index", array, value, key);
157
158
  }
159
+ // src/js/random.ts
160
+ function getRandomFloat(min, max) {
161
+ const minimum = min ?? Number.MIN_SAFE_INTEGER;
162
+ return Math.random() * ((max ?? Number.MAX_SAFE_INTEGER) - minimum) + minimum;
163
+ }
164
+ function getRandomInteger(min, max) {
165
+ return Math.floor(getRandomFloat(min, max));
166
+ }
167
+
168
+ // src/js/array/shuffle.ts
169
+ function shuffle2(array) {
170
+ const shuffled = array.slice();
171
+ const { length } = shuffled;
172
+ for (let index = 0;index < length; index += 1) {
173
+ const random2 = getRandomInteger(0, length);
174
+ [shuffled[index], shuffled[random2]] = [shuffled[random2], shuffled[index]];
175
+ }
176
+ return shuffled;
177
+ }
158
178
  // src/js/is.ts
159
179
  function isKey(value) {
160
180
  return typeof value === "number" || typeof value === "string";
@@ -254,6 +274,7 @@ export {
254
274
  toMap,
255
275
  splice,
256
276
  sort,
277
+ shuffle2 as shuffle,
257
278
  push,
258
279
  insert,
259
280
  indexOf,
@@ -17,6 +17,8 @@ import {groupBy} from "./group-by";
17
17
 
18
18
  export * from "./index-of";
19
19
  import {insert as insert2} from "./insert";
20
+
21
+ export * from "./shuffle";
20
22
  import {sort} from "./sort";
21
23
 
22
24
  export * from "./splice";
@@ -4,11 +4,12 @@ function insert(array, index, values) {
4
4
  insertValues("splice", array, values, index, 0);
5
5
  }
6
6
  function insertValues(type, array, values, start, deleteCount) {
7
- const chunked = chunk2(values).reverse();
8
- const { length } = chunked;
7
+ const chunked = chunk2(values);
8
+ const lastIndex = chunked.length - 1;
9
+ let index = Number(chunked.length);
9
10
  let returned;
10
- for (let index = 0;index < length; index += 1) {
11
- const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
11
+ while (--index >= 0) {
12
+ const result = array.splice(start, index === lastIndex ? deleteCount : 0, ...chunked[index]);
12
13
  if (returned == null) {
13
14
  returned = result;
14
15
  }
@@ -0,0 +1,14 @@
1
+ // src/js/array/shuffle.ts
2
+ import {getRandomInteger} from "../random";
3
+ function shuffle(array) {
4
+ const shuffled = array.slice();
5
+ const { length } = shuffled;
6
+ for (let index = 0;index < length; index += 1) {
7
+ const random2 = getRandomInteger(0, length);
8
+ [shuffled[index], shuffled[random2]] = [shuffled[random2], shuffled[index]];
9
+ }
10
+ return shuffled;
11
+ }
12
+ export {
13
+ shuffle
14
+ };
package/dist/js/index.js CHANGED
@@ -19,11 +19,12 @@ function insert(array, index, values) {
19
19
  insertValues("splice", array, values, index, 0);
20
20
  }
21
21
  function insertValues(type, array, values, start, deleteCount) {
22
- const chunked = chunk(values).reverse();
23
- const { length } = chunked;
22
+ const chunked = chunk(values);
23
+ const lastIndex = chunked.length - 1;
24
+ let index = Number(chunked.length);
24
25
  let returned;
25
- for (let index = 0;index < length; index += 1) {
26
- const result = array.splice(start, index === 0 ? deleteCount : 0, ...chunked[index]);
26
+ while (--index >= 0) {
27
+ const result = array.splice(start, index === lastIndex ? deleteCount : 0, ...chunked[index]);
27
28
  if (returned == null) {
28
29
  returned = result;
29
30
  }
@@ -155,6 +156,59 @@ function groupValues(array, key, arrays, indicable) {
155
156
  function indexOf(array, value, key) {
156
157
  return findValue("index", array, value, key);
157
158
  }
159
+ // src/js/random.ts
160
+ function getRandomBoolean() {
161
+ return Math.random() > 0.5;
162
+ }
163
+ function getRandomCharacters(length, selection) {
164
+ if (length < 1) {
165
+ return "";
166
+ }
167
+ const actualSelection = typeof selection === "string" && selection.length > 0 ? selection : "abcdefghijklmnopqrstuvwxyz";
168
+ let characters = "";
169
+ for (let index = 0;index < length; index += 1) {
170
+ characters += actualSelection.charAt(getRandomInteger(0, actualSelection.length));
171
+ }
172
+ return characters;
173
+ }
174
+ function getRandomColour() {
175
+ return `#${Array.from({ length: 6 }, getRandomHex).join("")}`;
176
+ }
177
+ function getRandomDate(earliest, latest) {
178
+ const earliestTime = earliest?.getTime() ?? -8640000000000000;
179
+ const latestTime = latest?.getTime() ?? 8640000000000000;
180
+ return new Date(getRandomInteger(earliestTime, latestTime));
181
+ }
182
+ function getRandomFloat(min, max) {
183
+ const minimum = min ?? Number.MIN_SAFE_INTEGER;
184
+ return Math.random() * ((max ?? Number.MAX_SAFE_INTEGER) - minimum) + minimum;
185
+ }
186
+ function getRandomHex() {
187
+ return "0123456789ABCDEF"[getRandomInteger(0, 16)];
188
+ }
189
+ function getRandomInteger(min, max) {
190
+ return Math.floor(getRandomFloat(min, max));
191
+ }
192
+ function getRandomItem(array) {
193
+ return array[getRandomInteger(0, array.length)];
194
+ }
195
+ function getRandomItems(array, amount) {
196
+ if (amount === 1) {
197
+ return array.length === 0 ? [] : [array[getRandomInteger(0, array.length)]];
198
+ }
199
+ return amount == null || amount >= array.length ? shuffle2(array) : shuffle2(array).slice(0, amount);
200
+ }
201
+
202
+ // src/js/array/shuffle.ts
203
+ function shuffle2(array) {
204
+ const shuffled = array.slice();
205
+ const { length } = shuffled;
206
+ for (let index = 0;index < length; index += 1) {
207
+ const random2 = getRandomInteger(0, length);
208
+ [shuffled[index], shuffled[random2]] = [shuffled[random2], shuffled[index]];
209
+ }
210
+ return shuffled;
211
+ }
158
212
  // src/js/string/index.ts
159
213
  function createUuid() {
160
214
  return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (substring) => (substring ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> substring / 4).toString(16));
@@ -1065,8 +1119,10 @@ function sum(values) {
1065
1119
  }
1066
1120
  // src/js/value/index.ts
1067
1121
  function partial(value, keys) {
1122
+ const { length } = keys;
1068
1123
  const result = {};
1069
- for (const key of keys) {
1124
+ for (let index = 0;index < length; index += 1) {
1125
+ const key = keys[index];
1070
1126
  result[key] = value[key];
1071
1127
  }
1072
1128
  return result;
@@ -1353,19 +1409,12 @@ function setValue(data2, path, value, ignoreCase) {
1353
1409
  let target = typeof data2 === "object" && data2 !== null ? data2 : {};
1354
1410
  for (let index = 0;index < length; index += 1) {
1355
1411
  const part = parts[index];
1356
- if (parts.indexOf(part) === lastIndex) {
1412
+ if (index === lastIndex) {
1357
1413
  handleValue(target, part, value, false, shouldIgnoreCase);
1358
1414
  break;
1359
1415
  }
1360
1416
  let next = handleValue(target, part, null, true, shouldIgnoreCase);
1361
1417
  if (typeof next !== "object" || next === null) {
1362
- if (isNumerical(part) && previous != null) {
1363
- const temporary = previous[parts[index - 1]];
1364
- if (!Array.isArray(temporary)) {
1365
- previous[parts[index - 1]] = typeof temporary === "object" && temporary !== null && Object.keys(temporary).every(isNumerical) ? Object.values(temporary) : [];
1366
- target = previous[parts[index - 1]];
1367
- }
1368
- }
1369
1418
  next = {};
1370
1419
  target[part] = next;
1371
1420
  }
@@ -1374,6 +1423,59 @@ function setValue(data2, path, value, ignoreCase) {
1374
1423
  }
1375
1424
  return data2;
1376
1425
  }
1426
+ // src/js/value/smush.ts
1427
+ var flatten2 = function(value, prefix) {
1428
+ const keys = Object.keys(value);
1429
+ const { length } = keys;
1430
+ const smushed = {};
1431
+ for (let index = 0;index < length; index += 1) {
1432
+ const key = keys[index];
1433
+ const val = value[key];
1434
+ if (isArrayOrPlainObject(val)) {
1435
+ Object.assign(smushed, {
1436
+ [join([prefix, key], ".")]: Array.isArray(val) ? [...val] : { ...val },
1437
+ ...flatten2(val, join([prefix, key], "."))
1438
+ });
1439
+ } else {
1440
+ smushed[join([prefix, key], ".")] = val;
1441
+ }
1442
+ }
1443
+ return smushed;
1444
+ };
1445
+ function smush(value) {
1446
+ return flatten2(value);
1447
+ }
1448
+ // src/js/value/unsmush.ts
1449
+ var getKeyGroups = function(value) {
1450
+ const keys = Object.keys(value);
1451
+ const { length } = keys;
1452
+ const grouped = [];
1453
+ for (let index = 0;index < length; index += 1) {
1454
+ const key = keys[index];
1455
+ const dots = key.split(".");
1456
+ if (grouped[dots.length] == null) {
1457
+ grouped[dots.length] = [key];
1458
+ } else {
1459
+ grouped[dots.length].push(key);
1460
+ }
1461
+ }
1462
+ return grouped;
1463
+ };
1464
+ function unsmush(value) {
1465
+ const groups = getKeyGroups(value);
1466
+ const { length } = groups;
1467
+ const unsmushed = {};
1468
+ for (let groupIndex = 1;groupIndex < length; groupIndex += 1) {
1469
+ const group = groups[groupIndex];
1470
+ const groupLength = group.length;
1471
+ for (let keyIndex = 0;keyIndex < groupLength; keyIndex += 1) {
1472
+ const key = group[keyIndex];
1473
+ const val = value[key];
1474
+ setValue(unsmushed, key, isArrayOrPlainObject(val) ? Array.isArray(val) ? [...val] : { ...val } : val);
1475
+ }
1476
+ }
1477
+ return unsmushed;
1478
+ }
1377
1479
  // src/js/query.ts
1378
1480
  function fromQuery(query) {
1379
1481
  const parts = query.split("&");
@@ -1453,42 +1555,6 @@ if (globalThis._atomic_queued == null) {
1453
1555
  }
1454
1556
  });
1455
1557
  }
1456
- // src/js/random.ts
1457
- function getRandomBoolean() {
1458
- return Math.random() > 0.5;
1459
- }
1460
- function getRandomCharacters(length, selection) {
1461
- if (length < 1) {
1462
- return "";
1463
- }
1464
- const actualSelection = typeof selection === "string" && selection.length > 0 ? selection : "abcdefghijklmnopqrstuvwxyz";
1465
- let characters = "";
1466
- for (let index = 0;index < length; index += 1) {
1467
- characters += actualSelection.charAt(getRandomInteger(0, actualSelection.length));
1468
- }
1469
- return characters;
1470
- }
1471
- function getRandomColour() {
1472
- return `#${Array.from({ length: 6 }, getRandomHex).join("")}`;
1473
- }
1474
- function getRandomDate(earliest, latest) {
1475
- const earliestTime = earliest?.getTime() ?? -8640000000000000;
1476
- const latestTime = latest?.getTime() ?? 8640000000000000;
1477
- return new Date(getRandomInteger(earliestTime, latestTime));
1478
- }
1479
- function getRandomFloat(min2, max2) {
1480
- const minimum = min2 ?? Number.MIN_SAFE_INTEGER;
1481
- return Math.random() * ((max2 ?? Number.MAX_SAFE_INTEGER) - minimum) + minimum;
1482
- }
1483
- function getRandomHex() {
1484
- return "0123456789ABCDEF"[getRandomInteger(0, 16)];
1485
- }
1486
- function getRandomInteger(min2, max2) {
1487
- return Math.floor(getRandomFloat(min2, max2));
1488
- }
1489
- function getRandomItem(array2) {
1490
- return array2[getRandomInteger(0, array2.length)];
1491
- }
1492
1558
  // src/js/timer.ts
1493
1559
  function delay(time2, timeout) {
1494
1560
  return new Promise((resolve, reject) => {
@@ -1502,20 +1568,20 @@ function delay(time2, timeout) {
1502
1568
  var getValueOrDefault = function(value2, defaultValue) {
1503
1569
  return typeof value2 === "number" && value2 > 0 ? value2 : defaultValue;
1504
1570
  };
1505
- var is9 = function(value2, pattern) {
1571
+ var is10 = function(value2, pattern) {
1506
1572
  return pattern.test(value2?.$timer);
1507
1573
  };
1508
1574
  function isRepeated(value2) {
1509
- return is9(value2, /^repeat$/);
1575
+ return is10(value2, /^repeat$/);
1510
1576
  }
1511
1577
  function isTimer(value2) {
1512
- return is9(value2, /^repeat|wait$/);
1578
+ return is10(value2, /^repeat|wait$/);
1513
1579
  }
1514
1580
  function isWaited(value2) {
1515
- return is9(value2, /^wait$/);
1581
+ return is10(value2, /^wait$/);
1516
1582
  }
1517
1583
  function isWhen(value2) {
1518
- return is9(value2, /^when$/) && typeof value2.then === "function";
1584
+ return is10(value2, /^when$/) && typeof value2.then === "function";
1519
1585
  }
1520
1586
  function repeat(callback, options) {
1521
1587
  return timer("repeat", callback, options ?? {}, true);
@@ -1773,6 +1839,7 @@ export {
1773
1839
  words,
1774
1840
  when,
1775
1841
  wait,
1842
+ unsmush,
1776
1843
  unique,
1777
1844
  truncate,
1778
1845
  toRecord,
@@ -1783,6 +1850,8 @@ export {
1783
1850
  splice,
1784
1851
  sort,
1785
1852
  snakeCase,
1853
+ smush,
1854
+ shuffle2 as shuffle,
1786
1855
  setValue,
1787
1856
  setStyles,
1788
1857
  setData,
@@ -1829,6 +1898,7 @@ export {
1829
1898
  getTextDirection,
1830
1899
  getTabbableElements,
1831
1900
  getString,
1901
+ getRandomItems,
1832
1902
  getRandomItem,
1833
1903
  getRandomInteger,
1834
1904
  getRandomHex,
package/dist/js/query.js CHANGED
@@ -21,12 +21,6 @@ function join(value, delimiter) {
21
21
  function isNullableOrWhitespace(value) {
22
22
  return value == null || /^\s*$/.test(getString(value));
23
23
  }
24
- function isNumber(value) {
25
- return typeof value === "number" && !Number.isNaN(value);
26
- }
27
- function isNumerical(value) {
28
- return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
29
- }
30
24
  function isPlainObject(value) {
31
25
  if (typeof value !== "object" || value === null) {
32
26
  return false;
@@ -63,19 +57,12 @@ function setValue(data, path, value, ignoreCase) {
63
57
  let target = typeof data === "object" && data !== null ? data : {};
64
58
  for (let index = 0;index < length; index += 1) {
65
59
  const part = parts[index];
66
- if (parts.indexOf(part) === lastIndex) {
60
+ if (index === lastIndex) {
67
61
  handleValue(target, part, value, false, shouldIgnoreCase);
68
62
  break;
69
63
  }
70
64
  let next = handleValue(target, part, null, true, shouldIgnoreCase);
71
65
  if (typeof next !== "object" || next === null) {
72
- if (isNumerical(part) && previous != null) {
73
- const temporary = previous[parts[index - 1]];
74
- if (!Array.isArray(temporary)) {
75
- previous[parts[index - 1]] = typeof temporary === "object" && temporary !== null && Object.keys(temporary).every(isNumerical) ? Object.values(temporary) : [];
76
- target = previous[parts[index - 1]];
77
- }
78
- }
79
66
  next = {};
80
67
  target[part] = next;
81
68
  }
package/dist/js/random.js CHANGED
@@ -1,3 +1,14 @@
1
+ // src/js/array/shuffle.ts
2
+ function shuffle(array) {
3
+ const shuffled = array.slice();
4
+ const { length } = shuffled;
5
+ for (let index = 0;index < length; index += 1) {
6
+ const random2 = getRandomInteger(0, length);
7
+ [shuffled[index], shuffled[random2]] = [shuffled[random2], shuffled[index]];
8
+ }
9
+ return shuffled;
10
+ }
11
+
1
12
  // src/js/random.ts
2
13
  function getRandomBoolean() {
3
14
  return Math.random() > 0.5;
@@ -34,7 +45,14 @@ function getRandomInteger(min, max) {
34
45
  function getRandomItem(array) {
35
46
  return array[getRandomInteger(0, array.length)];
36
47
  }
48
+ function getRandomItems(array, amount) {
49
+ if (amount === 1) {
50
+ return array.length === 0 ? [] : [array[getRandomInteger(0, array.length)]];
51
+ }
52
+ return amount == null || amount >= array.length ? shuffle(array) : shuffle(array).slice(0, amount);
53
+ }
37
54
  export {
55
+ getRandomItems,
38
56
  getRandomItem,
39
57
  getRandomInteger,
40
58
  getRandomHex,
@@ -1,4 +1,5 @@
1
1
  // src/js/random.ts
2
+ import {shuffle as shuffle2} from "./array/shuffle";
2
3
  function getRandomBoolean() {
3
4
  return Math.random() > 0.5;
4
5
  }
@@ -34,7 +35,14 @@ function getRandomInteger(min, max) {
34
35
  function getRandomItem(array) {
35
36
  return array[getRandomInteger(0, array.length)];
36
37
  }
38
+ function getRandomItems(array, amount) {
39
+ if (amount === 1) {
40
+ return array.length === 0 ? [] : [array[getRandomInteger(0, array.length)]];
41
+ }
42
+ return amount == null || amount >= array.length ? shuffle2(array) : shuffle2(array).slice(0, amount);
43
+ }
37
44
  export {
45
+ getRandomItems,
38
46
  getRandomItem,
39
47
  getRandomInteger,
40
48
  getRandomHex,
@@ -1,7 +1,9 @@
1
1
  // src/js/value/index.ts
2
2
  function partial(value, keys) {
3
+ const { length } = keys;
3
4
  const result = {};
4
- for (const key of keys) {
5
+ for (let index = 0;index < length; index += 1) {
6
+ const key = keys[index];
5
7
  result[key] = value[key];
6
8
  }
7
9
  return result;
@@ -29,12 +31,6 @@ function join(value, delimiter) {
29
31
  function isArrayOrPlainObject(value) {
30
32
  return Array.isArray(value) || isPlainObject(value);
31
33
  }
32
- function isNumber(value) {
33
- return typeof value === "number" && !Number.isNaN(value);
34
- }
35
- function isNumerical(value) {
36
- return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
37
- }
38
34
  function isPlainObject(value) {
39
35
  if (typeof value !== "object" || value === null) {
40
36
  return false;
@@ -324,19 +320,12 @@ function setValue(data, path, value, ignoreCase) {
324
320
  let target = typeof data === "object" && data !== null ? data : {};
325
321
  for (let index = 0;index < length; index += 1) {
326
322
  const part = parts[index];
327
- if (parts.indexOf(part) === lastIndex) {
323
+ if (index === lastIndex) {
328
324
  handleValue(target, part, value, false, shouldIgnoreCase);
329
325
  break;
330
326
  }
331
327
  let next = handleValue(target, part, null, true, shouldIgnoreCase);
332
328
  if (typeof next !== "object" || next === null) {
333
- if (isNumerical(part) && previous != null) {
334
- const temporary = previous[parts[index - 1]];
335
- if (!Array.isArray(temporary)) {
336
- previous[parts[index - 1]] = typeof temporary === "object" && temporary !== null && Object.keys(temporary).every(isNumerical) ? Object.values(temporary) : [];
337
- target = previous[parts[index - 1]];
338
- }
339
- }
340
329
  next = {};
341
330
  target[part] = next;
342
331
  }
@@ -345,7 +334,62 @@ function setValue(data, path, value, ignoreCase) {
345
334
  }
346
335
  return data;
347
336
  }
337
+ // src/js/value/smush.ts
338
+ var flatten = function(value, prefix) {
339
+ const keys = Object.keys(value);
340
+ const { length } = keys;
341
+ const smushed = {};
342
+ for (let index = 0;index < length; index += 1) {
343
+ const key = keys[index];
344
+ const val = value[key];
345
+ if (isArrayOrPlainObject(val)) {
346
+ Object.assign(smushed, {
347
+ [join([prefix, key], ".")]: Array.isArray(val) ? [...val] : { ...val },
348
+ ...flatten(val, join([prefix, key], "."))
349
+ });
350
+ } else {
351
+ smushed[join([prefix, key], ".")] = val;
352
+ }
353
+ }
354
+ return smushed;
355
+ };
356
+ function smush(value) {
357
+ return flatten(value);
358
+ }
359
+ // src/js/value/unsmush.ts
360
+ var getKeyGroups = function(value) {
361
+ const keys = Object.keys(value);
362
+ const { length } = keys;
363
+ const grouped = [];
364
+ for (let index = 0;index < length; index += 1) {
365
+ const key = keys[index];
366
+ const dots = key.split(".");
367
+ if (grouped[dots.length] == null) {
368
+ grouped[dots.length] = [key];
369
+ } else {
370
+ grouped[dots.length].push(key);
371
+ }
372
+ }
373
+ return grouped;
374
+ };
375
+ function unsmush(value) {
376
+ const groups = getKeyGroups(value);
377
+ const { length } = groups;
378
+ const unsmushed = {};
379
+ for (let groupIndex = 1;groupIndex < length; groupIndex += 1) {
380
+ const group = groups[groupIndex];
381
+ const groupLength = group.length;
382
+ for (let keyIndex = 0;keyIndex < groupLength; keyIndex += 1) {
383
+ const key = group[keyIndex];
384
+ const val = value[key];
385
+ setValue(unsmushed, key, isArrayOrPlainObject(val) ? Array.isArray(val) ? [...val] : { ...val } : val);
386
+ }
387
+ }
388
+ return unsmushed;
389
+ }
348
390
  export {
391
+ unsmush,
392
+ smush,
349
393
  setValue,
350
394
  partial,
351
395
  merge,
@@ -1,7 +1,9 @@
1
1
  // src/js/value/index.ts
2
2
  function partial(value, keys) {
3
+ const { length } = keys;
3
4
  const result = {};
4
- for (const key of keys) {
5
+ for (let index = 0;index < length; index += 1) {
6
+ const key = keys[index];
5
7
  result[key] = value[key];
6
8
  }
7
9
  return result;
@@ -13,6 +15,8 @@ export * from "./equal";
13
15
  export * from "./get";
14
16
  export * from "./merge";
15
17
  export * from "./set";
18
+ export * from "./smush";
19
+ export * from "./unsmush";
16
20
  export {
17
21
  partial
18
22
  };
@@ -1,6 +1,5 @@
1
1
  // src/js/value/set.ts
2
2
  import {handleValue} from "../internal/value-handle";
3
- import {isNumerical} from "../is";
4
3
  function setValue(data, path, value, ignoreCase) {
5
4
  const shouldIgnoreCase = ignoreCase === true;
6
5
  const parts = (shouldIgnoreCase ? path.toLowerCase() : path).split(".");
@@ -10,19 +9,12 @@ function setValue(data, path, value, ignoreCase) {
10
9
  let target = typeof data === "object" && data !== null ? data : {};
11
10
  for (let index = 0;index < length; index += 1) {
12
11
  const part = parts[index];
13
- if (parts.indexOf(part) === lastIndex) {
12
+ if (index === lastIndex) {
14
13
  handleValue(target, part, value, false, shouldIgnoreCase);
15
14
  break;
16
15
  }
17
16
  let next = handleValue(target, part, null, true, shouldIgnoreCase);
18
17
  if (typeof next !== "object" || next === null) {
19
- if (isNumerical(part) && previous != null) {
20
- const temporary = previous[parts[index - 1]];
21
- if (!Array.isArray(temporary)) {
22
- previous[parts[index - 1]] = typeof temporary === "object" && temporary !== null && Object.keys(temporary).every(isNumerical) ? Object.values(temporary) : [];
23
- target = previous[parts[index - 1]];
24
- }
25
- }
26
18
  next = {};
27
19
  target[part] = next;
28
20
  }
@@ -0,0 +1,27 @@
1
+ // src/js/value/smush.ts
2
+ import {isArrayOrPlainObject} from "../is";
3
+ import {join} from "../string";
4
+ var flatten = function(value, prefix) {
5
+ const keys = Object.keys(value);
6
+ const { length } = keys;
7
+ const smushed = {};
8
+ for (let index = 0;index < length; index += 1) {
9
+ const key = keys[index];
10
+ const val = value[key];
11
+ if (isArrayOrPlainObject(val)) {
12
+ Object.assign(smushed, {
13
+ [join([prefix, key], ".")]: Array.isArray(val) ? [...val] : { ...val },
14
+ ...flatten(val, join([prefix, key], "."))
15
+ });
16
+ } else {
17
+ smushed[join([prefix, key], ".")] = val;
18
+ }
19
+ }
20
+ return smushed;
21
+ };
22
+ function smush(value) {
23
+ return flatten(value);
24
+ }
25
+ export {
26
+ smush
27
+ };
@@ -0,0 +1,36 @@
1
+ // src/js/value/unsmush.ts
2
+ import {isArrayOrPlainObject} from "../is";
3
+ import {setValue} from "./set";
4
+ var getKeyGroups = function(value) {
5
+ const keys = Object.keys(value);
6
+ const { length } = keys;
7
+ const grouped = [];
8
+ for (let index = 0;index < length; index += 1) {
9
+ const key = keys[index];
10
+ const dots = key.split(".");
11
+ if (grouped[dots.length] == null) {
12
+ grouped[dots.length] = [key];
13
+ } else {
14
+ grouped[dots.length].push(key);
15
+ }
16
+ }
17
+ return grouped;
18
+ };
19
+ function unsmush(value) {
20
+ const groups = getKeyGroups(value);
21
+ const { length } = groups;
22
+ const unsmushed = {};
23
+ for (let groupIndex = 1;groupIndex < length; groupIndex += 1) {
24
+ const group = groups[groupIndex];
25
+ const groupLength = group.length;
26
+ for (let keyIndex = 0;keyIndex < groupLength; keyIndex += 1) {
27
+ const key = group[keyIndex];
28
+ const val = value[key];
29
+ setValue(unsmushed, key, isArrayOrPlainObject(val) ? Array.isArray(val) ? [...val] : { ...val } : val);
30
+ }
31
+ }
32
+ return unsmushed;
33
+ }
34
+ export {
35
+ unsmush
36
+ };
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://oscarpalmer.se"
5
5
  },
6
6
  "dependencies": {
7
- "type-fest": "^4.21.0"
7
+ "type-fest": "^4.22.1"
8
8
  },
9
9
  "description": "Sweet little atomic goodies…",
10
10
  "devDependencies": {
@@ -178,5 +178,5 @@
178
178
  },
179
179
  "type": "module",
180
180
  "types": "./types/index.d.ts",
181
- "version": "0.59.0"
181
+ "version": "0.60.0"
182
182
  }
@@ -25,6 +25,7 @@ export * from './find';
25
25
  export {groupBy} from './group-by';
26
26
  export * from './index-of';
27
27
  export {insert} from './insert';
28
+ export * from './shuffle';
28
29
  export {sort} from './sort';
29
30
  export * from './splice';
30
31
  export * from './to-map';
@@ -20,15 +20,16 @@ export function insertValues<Value>(
20
20
  start: number,
21
21
  deleteCount: number,
22
22
  ): unknown {
23
- const chunked = chunk(values).reverse();
24
- const {length} = chunked;
23
+ const chunked = chunk(values);
24
+ const lastIndex = chunked.length - 1;
25
25
 
26
+ let index = Number(chunked.length);
26
27
  let returned: Value[] | undefined;
27
28
 
28
- for (let index = 0; index < length; index += 1) {
29
+ while (--index >= 0) {
29
30
  const result = array.splice(
30
31
  start,
31
- index === 0 ? deleteCount : 0,
32
+ index === lastIndex ? deleteCount : 0,
32
33
  ...chunked[index],
33
34
  );
34
35
 
@@ -0,0 +1,17 @@
1
+ import {getRandomInteger} from '../random';
2
+
3
+ /**
4
+ * Shuffles an array
5
+ */
6
+ export function shuffle<Value>(array: Value[]): Value[] {
7
+ const shuffled = array.slice();
8
+ const {length} = shuffled;
9
+
10
+ for (let index = 0; index < length; index += 1) {
11
+ const random = getRandomInteger(0, length);
12
+
13
+ [shuffled[index], shuffled[random]] = [shuffled[random], shuffled[index]];
14
+ }
15
+
16
+ return shuffled;
17
+ }
package/src/js/random.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import {shuffle} from './array/shuffle';
2
+
1
3
  /**
2
4
  * Returns a random boolean
3
5
  */
@@ -79,3 +81,20 @@ export function getRandomInteger(min?: number, max?: number): number {
79
81
  export function getRandomItem<Value>(array: Value[]): Value {
80
82
  return array[getRandomInteger(0, array.length)];
81
83
  }
84
+
85
+ /**
86
+ * - Returns an amount of random items from an array
87
+ * - If `amount` is not specified, a shuffled array will be returned instead
88
+ */
89
+ export function getRandomItems<Value>(
90
+ array: Value[],
91
+ amount?: number,
92
+ ): Value[] {
93
+ if (amount === 1) {
94
+ return array.length === 0 ? [] : [array[getRandomInteger(0, array.length)]];
95
+ }
96
+
97
+ return amount == null || amount >= array.length
98
+ ? shuffle(array)
99
+ : shuffle(array).slice(0, amount);
100
+ }
@@ -28,7 +28,7 @@ type KeyedDiffValue = {
28
28
  * - `full` if the values are completely different
29
29
  * - `none` if the values are the same
30
30
  * - `partial` if the values are partially different
31
- * - `values` holds the differences with dot-notation keys
31
+ * - `values` holds the differences with dot notation keys
32
32
  */
33
33
  export function diff<First, Second = First>(
34
34
  first: First,
@@ -7,9 +7,12 @@ export function partial<Value extends PlainObject, Key extends keyof Value>(
7
7
  value: Value,
8
8
  keys: Key[],
9
9
  ): Pick<Value, Key> {
10
+ const {length} = keys;
10
11
  const result = {} as Pick<Value, Key>;
11
12
 
12
- for (const key of keys) {
13
+ for (let index = 0; index < length; index += 1) {
14
+ const key = keys[index];
15
+
13
16
  result[key] = value[key];
14
17
  }
15
18
 
@@ -22,3 +25,5 @@ export * from './equal';
22
25
  export * from './get';
23
26
  export * from './merge';
24
27
  export * from './set';
28
+ export * from './smush';
29
+ export * from './unsmush';
@@ -1,5 +1,4 @@
1
1
  import {handleValue} from '../internal/value-handle';
2
- import {isNumerical} from '../is';
3
2
  import type {Paths, PlainObject} from '../models';
4
3
 
5
4
  /**
@@ -46,7 +45,7 @@ export function setValue<Data extends PlainObject>(
46
45
  for (let index = 0; index < length; index += 1) {
47
46
  const part = parts[index];
48
47
 
49
- if (parts.indexOf(part) === lastIndex) {
48
+ if (index === lastIndex) {
50
49
  handleValue(target, part, value, false, shouldIgnoreCase);
51
50
 
52
51
  break;
@@ -55,21 +54,6 @@ export function setValue<Data extends PlainObject>(
55
54
  let next = handleValue(target, part, null, true, shouldIgnoreCase);
56
55
 
57
56
  if (typeof next !== 'object' || next === null) {
58
- if (isNumerical(part) && previous != null) {
59
- const temporary = previous[parts[index - 1]];
60
-
61
- if (!Array.isArray(temporary)) {
62
- previous[parts[index - 1]] =
63
- typeof temporary === 'object' &&
64
- temporary !== null &&
65
- Object.keys(temporary).every(isNumerical)
66
- ? Object.values(temporary)
67
- : [];
68
-
69
- target = previous[parts[index - 1]] as PlainObject;
70
- }
71
- }
72
-
73
57
  next = {};
74
58
 
75
59
  target[part] = next;
@@ -0,0 +1,38 @@
1
+ import type {Get, Paths, Simplify} from 'type-fest';
2
+ import type {ToString} from 'type-fest/source/internal';
3
+ import {isArrayOrPlainObject} from '../is';
4
+ import type {ArrayOrPlainObject, PlainObject} from '../models';
5
+ import {join} from '../string';
6
+
7
+ type Smushed<Value> = Simplify<{
8
+ [Key in Paths<Value>]: Get<Value, ToString<Key>>;
9
+ }>;
10
+
11
+ function flatten(value: ArrayOrPlainObject, prefix?: string): PlainObject {
12
+ const keys = Object.keys(value);
13
+ const {length} = keys;
14
+ const smushed = {} as Record<string, unknown>;
15
+
16
+ for (let index = 0; index < length; index += 1) {
17
+ const key = keys[index];
18
+ const val = value[key as never];
19
+
20
+ if (isArrayOrPlainObject(val)) {
21
+ Object.assign(smushed, {
22
+ [join([prefix, key], '.')]: Array.isArray(val) ? [...val] : {...val},
23
+ ...flatten(val, join([prefix, key], '.')),
24
+ });
25
+ } else {
26
+ smushed[join([prefix, key], '.')] = val;
27
+ }
28
+ }
29
+
30
+ return smushed as never;
31
+ }
32
+
33
+ /**
34
+ * Smushes an object into a flat object with dot notation keys
35
+ */
36
+ export function smush<Value extends PlainObject>(value: Value): Smushed<Value> {
37
+ return flatten(value) as never;
38
+ }
@@ -0,0 +1,65 @@
1
+ import type {KeysOfUnion, Simplify} from 'type-fest';
2
+ import {isArrayOrPlainObject} from '../is';
3
+ import type {PlainObject} from '../models';
4
+ import {setValue} from './set';
5
+
6
+ type Unsmushed<Value extends PlainObject> = Simplify<
7
+ Omit<
8
+ {
9
+ [Key in KeysOfUnion<Value>]: Value[Key];
10
+ },
11
+ `${string}.${string}`
12
+ >
13
+ >;
14
+
15
+ function getKeyGroups(value: PlainObject): string[][] {
16
+ const keys = Object.keys(value);
17
+ const {length} = keys;
18
+ const grouped: string[][] = [];
19
+
20
+ for (let index = 0; index < length; index += 1) {
21
+ const key = keys[index];
22
+ const dots = key.split('.');
23
+
24
+ if (grouped[dots.length] == null) {
25
+ grouped[dots.length] = [key];
26
+ } else {
27
+ grouped[dots.length].push(key);
28
+ }
29
+ }
30
+
31
+ return grouped;
32
+ }
33
+
34
+ /**
35
+ * Unsmushes a smushed object _(turning dot notation keys into nested keys)_
36
+ */
37
+ export function unsmush<Value extends PlainObject>(
38
+ value: Value,
39
+ ): Unsmushed<Value> {
40
+ const groups = getKeyGroups(value);
41
+ const {length} = groups;
42
+ const unsmushed: PlainObject = {};
43
+
44
+ for (let groupIndex = 1; groupIndex < length; groupIndex += 1) {
45
+ const group = groups[groupIndex];
46
+ const groupLength = group.length;
47
+
48
+ for (let keyIndex = 0; keyIndex < groupLength; keyIndex += 1) {
49
+ const key = group[keyIndex];
50
+ const val = value[key as never];
51
+
52
+ setValue(
53
+ unsmushed,
54
+ key,
55
+ isArrayOrPlainObject(val)
56
+ ? Array.isArray(val)
57
+ ? [...val]
58
+ : {...val}
59
+ : val,
60
+ );
61
+ }
62
+ }
63
+
64
+ return unsmushed as never;
65
+ }
@@ -17,6 +17,7 @@ export * from './find';
17
17
  export { groupBy } from './group-by';
18
18
  export * from './index-of';
19
19
  export { insert } from './insert';
20
+ export * from './shuffle';
20
21
  export { sort } from './sort';
21
22
  export * from './splice';
22
23
  export * from './to-map';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Shuffles an array
3
+ */
4
+ export declare function shuffle<Value>(array: Value[]): Value[];
package/types/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- import { Get, Paths, Primitive, UnknownArray, UnknownRecord } from 'type-fest';
3
+ import { Get, KeysOfUnion, Paths, Primitive, Simplify, UnknownArray, UnknownRecord } from 'type-fest';
4
4
  import { ToString } from 'type-fest/source/internal';
5
5
 
6
6
  export type ArrayOrPlainObject = UnknownArray | UnknownRecord;
@@ -91,6 +91,10 @@ export declare function indexOf<Model, Value = Model>(array: Model[], value: Val
91
91
  * - Uses chunking to avoid stack overflow
92
92
  */
93
93
  export declare function insert<Value>(array: Value[], index: number, values: Value[]): void;
94
+ /**
95
+ * Shuffles an array
96
+ */
97
+ export declare function shuffle<Value>(array: Value[]): Value[];
94
98
  /**
95
99
  * Sorts an array of items _(ascending by default)_
96
100
  */
@@ -657,6 +661,11 @@ export declare function getRandomInteger(min?: number, max?: number): number;
657
661
  * Returns a random item from an array
658
662
  */
659
663
  export declare function getRandomItem<Value>(array: Value[]): Value;
664
+ /**
665
+ * - Returns an amount of random items from an array
666
+ * - If `amount` is not specified, a shuffled array will be returned instead
667
+ */
668
+ export declare function getRandomItems<Value>(array: Value[], amount?: number): Value[];
660
669
  /**
661
670
  * Convert a string to camel case _(thisIsCamelCase)_
662
671
  */
@@ -869,7 +878,7 @@ export type DiffValue<First = unknown, Second = First> = {
869
878
  * - `full` if the values are completely different
870
879
  * - `none` if the values are the same
871
880
  * - `partial` if the values are partially different
872
- * - `values` holds the differences with dot-notation keys
881
+ * - `values` holds the differences with dot notation keys
873
882
  */
874
883
  export declare function diff<First, Second = First>(first: First, second: Second): DiffResult<First, Second>;
875
884
  /**
@@ -912,6 +921,20 @@ export declare function setValue<Data extends PlainObject, Path extends Paths<Da
912
921
  * - Returns the original object
913
922
  */
914
923
  export declare function setValue<Data extends PlainObject>(data: Data, path: string, value: unknown, ignoreCase?: boolean): Data;
924
+ export type Smushed<Value> = Simplify<{
925
+ [Key in Paths<Value>]: Get<Value, ToString<Key>>;
926
+ }>;
927
+ /**
928
+ * Smushes an object into a flat object with dot notation keys
929
+ */
930
+ export declare function smush<Value extends PlainObject>(value: Value): Smushed<Value>;
931
+ export type Unsmushed<Value extends PlainObject> = Simplify<Omit<{
932
+ [Key in KeysOfUnion<Value>]: Value[Key];
933
+ }, `${string}.${string}`>>;
934
+ /**
935
+ * Unsmushes a smushed object _(turning dot notation keys into nested keys)_
936
+ */
937
+ export declare function unsmush<Value extends PlainObject>(value: Value): Unsmushed<Value>;
915
938
  /**
916
939
  * Creates a new object with only the specified keys
917
940
  */
package/types/random.d.ts CHANGED
@@ -31,3 +31,8 @@ export declare function getRandomInteger(min?: number, max?: number): number;
31
31
  * Returns a random item from an array
32
32
  */
33
33
  export declare function getRandomItem<Value>(array: Value[]): Value;
34
+ /**
35
+ * - Returns an amount of random items from an array
36
+ * - If `amount` is not specified, a shuffled array will be returned instead
37
+ */
38
+ export declare function getRandomItems<Value>(array: Value[], amount?: number): Value[];
@@ -16,6 +16,6 @@ export type DiffValue<First = unknown, Second = First> = {
16
16
  * - `full` if the values are completely different
17
17
  * - `none` if the values are the same
18
18
  * - `partial` if the values are partially different
19
- * - `values` holds the differences with dot-notation keys
19
+ * - `values` holds the differences with dot notation keys
20
20
  */
21
21
  export declare function diff<First, Second = First>(first: First, second: Second): DiffResult<First, Second>;
@@ -9,3 +9,5 @@ export * from './equal';
9
9
  export * from './get';
10
10
  export * from './merge';
11
11
  export * from './set';
12
+ export * from './smush';
13
+ export * from './unsmush';
@@ -0,0 +1,11 @@
1
+ import type { Get, Paths, Simplify } from 'type-fest';
2
+ import type { ToString } from 'type-fest/source/internal';
3
+ import type { PlainObject } from '../models';
4
+ type Smushed<Value> = Simplify<{
5
+ [Key in Paths<Value>]: Get<Value, ToString<Key>>;
6
+ }>;
7
+ /**
8
+ * Smushes an object into a flat object with dot notation keys
9
+ */
10
+ export declare function smush<Value extends PlainObject>(value: Value): Smushed<Value>;
11
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { KeysOfUnion, Simplify } from 'type-fest';
2
+ import type { PlainObject } from '../models';
3
+ type Unsmushed<Value extends PlainObject> = Simplify<Omit<{
4
+ [Key in KeysOfUnion<Value>]: Value[Key];
5
+ }, `${string}.${string}`>>;
6
+ /**
7
+ * Unsmushes a smushed object _(turning dot notation keys into nested keys)_
8
+ */
9
+ export declare function unsmush<Value extends PlainObject>(value: Value): Unsmushed<Value>;
10
+ export {};