@oscarpalmer/atoms 0.19.0 → 0.21.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.
package/dist/js/index.js CHANGED
@@ -275,8 +275,17 @@ function getString(value) {
275
275
  const result = value?.toString?.() ?? value;
276
276
  return result?.toString?.() ?? String(result);
277
277
  }
278
- function isNullableOrWhitespace(value) {
279
- return value == null || getString(value).trim().length === 0;
278
+
279
+ // src/js/is.ts
280
+ function isArrayOrPlainObject(value) {
281
+ return Array.isArray(value) || isPlainObject(value);
282
+ }
283
+ function isPlainObject(value) {
284
+ if (typeof value !== "object" || value === null) {
285
+ return false;
286
+ }
287
+ const prototype = Object.getPrototypeOf(value);
288
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
280
289
  }
281
290
 
282
291
  // src/js/value.ts
@@ -286,13 +295,13 @@ var _getDiffs = function(first, second, prefix) {
286
295
  let outer = 0;
287
296
  for (;outer < 2; outer += 1) {
288
297
  const value = outer === 0 ? first : second;
289
- if (!isArrayOrObject(value)) {
298
+ if (!value) {
290
299
  continue;
291
300
  }
292
301
  const keys = Object.keys(value);
293
- const size = keys.length;
302
+ const { length } = keys;
294
303
  let inner = 0;
295
- for (;inner < size; inner += 1) {
304
+ for (;inner < length; inner += 1) {
296
305
  const key = keys[inner];
297
306
  if (checked.has(key)) {
298
307
  continue;
@@ -306,7 +315,9 @@ var _getDiffs = function(first, second, prefix) {
306
315
  to,
307
316
  key: prefixed
308
317
  });
309
- changes.push(..._getDiffs(from, to, prefixed));
318
+ if (isArrayOrPlainObject(from) && isArrayOrPlainObject(to)) {
319
+ changes.push(..._getDiffs(from, to, prefixed));
320
+ }
310
321
  }
311
322
  checked.add(key);
312
323
  }
@@ -345,8 +356,8 @@ function diff(first, second) {
345
356
  values: {}
346
357
  };
347
358
  const same = Object.is(first, second);
348
- const firstIsArrayOrObject = isArrayOrObject(first);
349
- const secondIsArrayOrObject = isArrayOrObject(second);
359
+ const firstIsArrayOrObject = isArrayOrPlainObject(first);
360
+ const secondIsArrayOrObject = isArrayOrPlainObject(second);
350
361
  if (same || !firstIsArrayOrObject && !secondIsArrayOrObject) {
351
362
  result.type = same ? "none" : "full";
352
363
  return result;
@@ -379,20 +390,11 @@ function get(data, key) {
379
390
  }
380
391
  return value;
381
392
  }
382
- function isArrayOrObject(value) {
383
- return /^(array|object)$/i.test(value?.constructor?.name);
384
- }
385
- function isNullable(value) {
386
- return value == null;
387
- }
388
- function isObject(value) {
389
- return /^object$/i.test(value?.constructor?.name);
390
- }
391
393
  function merge(...values) {
392
394
  if (values.length === 0) {
393
395
  return {};
394
396
  }
395
- const actual = values.filter(isArrayOrObject);
397
+ const actual = values.filter((value) => isArrayOrPlainObject(value));
396
398
  const result = actual.every(Array.isArray) ? [] : {};
397
399
  const { length } = actual;
398
400
  let itemIndex = 0;
@@ -405,8 +407,8 @@ function merge(...values) {
405
407
  const key = keys[keyIndex];
406
408
  const next = item[key];
407
409
  const previous = result[key];
408
- if (isArrayOrObject(next)) {
409
- result[key] = isArrayOrObject(previous) ? merge(previous, next) : merge(next);
410
+ if (isArrayOrPlainObject(next)) {
411
+ result[key] = isArrayOrPlainObject(previous) ? merge(previous, next) : merge(next);
410
412
  } else {
411
413
  result[key] = next;
412
414
  }
@@ -417,11 +419,12 @@ function merge(...values) {
417
419
  function set(data, key, value) {
418
420
  const parts = getString(key).split(".");
419
421
  const { length } = parts;
422
+ const lastIndex = length - 1;
420
423
  let index = 0;
421
424
  let target = typeof data === "object" ? data ?? {} : {};
422
425
  for (;index < length; index += 1) {
423
426
  const part = parts[index];
424
- if (parts.indexOf(part) === parts.length - 1) {
427
+ if (parts.indexOf(part) === lastIndex) {
425
428
  _setValue(target, part, value);
426
429
  break;
427
430
  }
@@ -436,36 +439,50 @@ function set(data, key, value) {
436
439
  }
437
440
 
438
441
  // src/js/proxy.ts
439
- var _createProxy = function(blob, value2) {
440
- if (!isArrayOrObject(value2) || _isProxy(value2)) {
442
+ var _createProxy = function(existing, value2) {
443
+ if (!isArrayOrPlainObject(value2) || _isProxy(value2) && value2.$ === existing) {
441
444
  return value2;
442
445
  }
443
446
  const isArray = Array.isArray(value2);
444
- const proxyBlob = blob ?? new ProxyBlob;
445
- const proxyValue = new Proxy(isArray ? [] : {}, {});
446
- Object.defineProperty(proxyValue, "$", {
447
- value: proxyBlob
447
+ const proxy = new Proxy(isArray ? [] : {}, {
448
+ get(target, property) {
449
+ return property === "$" ? manager : Reflect.get(target, property);
450
+ },
451
+ set(target, property, value3) {
452
+ return property === "$" || Reflect.set(target, property, _createProxy(manager, value3));
453
+ }
454
+ });
455
+ const manager = existing ?? new Manager(proxy);
456
+ Object.defineProperty(proxy, "$", {
457
+ value: manager
448
458
  });
449
459
  const keys = Object.keys(value2);
450
- const size = keys.length ?? 0;
460
+ const { length } = keys;
451
461
  let index = 0;
452
- for (;index < size; index += 1) {
462
+ for (;index < length; index += 1) {
453
463
  const key = keys[index];
454
- proxyValue[key] = _createProxy(proxyBlob, value2[key]);
464
+ proxy[key] = value2[key];
455
465
  }
456
- return proxyValue;
466
+ return proxy;
457
467
  };
458
468
  var _isProxy = function(value2) {
459
- return value2?.$ instanceof ProxyBlob;
469
+ return value2?.$ instanceof Manager;
460
470
  };
461
471
  function proxy(value2) {
462
- if (!isArrayOrObject(value2)) {
472
+ if (!isArrayOrPlainObject(value2)) {
463
473
  throw new Error("Proxy value must be an array or object");
464
474
  }
465
475
  return _createProxy(undefined, value2);
466
476
  }
467
477
 
468
- class ProxyBlob {
478
+ class Manager {
479
+ owner;
480
+ constructor(owner) {
481
+ this.owner = owner;
482
+ }
483
+ clone() {
484
+ return clone(merge(this.owner));
485
+ }
469
486
  }
470
487
  // src/js/timer.ts
471
488
  function repeat(callback, options) {
@@ -559,10 +576,6 @@ export {
559
576
  push,
560
577
  proxy,
561
578
  merge,
562
- isObject,
563
- isNullableOrWhitespace,
564
- isNullable,
565
- isArrayOrObject,
566
579
  insert,
567
580
  indexOf,
568
581
  groupBy,
package/dist/js/is.js ADDED
@@ -0,0 +1,44 @@
1
+ // src/js/string.ts
2
+ function getString(value) {
3
+ if (typeof value === "string") {
4
+ return value;
5
+ }
6
+ const result = value?.toString?.() ?? value;
7
+ return result?.toString?.() ?? String(result);
8
+ }
9
+
10
+ // src/js/is.ts
11
+ function isArrayOrPlainObject(value) {
12
+ return Array.isArray(value) || isPlainObject(value);
13
+ }
14
+ function isNullable(value) {
15
+ return value == null;
16
+ }
17
+ function isNullableOrWhitespace(value) {
18
+ return value == null || getString(value).trim().length === 0;
19
+ }
20
+ function isNumber(value) {
21
+ return typeof value === "number" && !Number.isNaN(value);
22
+ }
23
+ function isNumerical(value) {
24
+ return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
25
+ }
26
+ function isObject(value) {
27
+ return typeof value === "object" && value !== null || typeof value === "function";
28
+ }
29
+ function isPlainObject(value) {
30
+ if (typeof value !== "object" || value === null) {
31
+ return false;
32
+ }
33
+ const prototype = Object.getPrototypeOf(value);
34
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
35
+ }
36
+ export {
37
+ isPlainObject,
38
+ isObject,
39
+ isNumerical,
40
+ isNumber,
41
+ isNullableOrWhitespace,
42
+ isNullable,
43
+ isArrayOrPlainObject
44
+ };
package/dist/js/is.mjs ADDED
@@ -0,0 +1,36 @@
1
+ // src/js/is.ts
2
+ import {getString} from "./string";
3
+ function isArrayOrPlainObject(value) {
4
+ return Array.isArray(value) || isPlainObject(value);
5
+ }
6
+ function isNullable(value) {
7
+ return value == null;
8
+ }
9
+ function isNullableOrWhitespace(value) {
10
+ return value == null || getString(value).trim().length === 0;
11
+ }
12
+ function isNumber(value) {
13
+ return typeof value === "number" && !Number.isNaN(value);
14
+ }
15
+ function isNumerical(value) {
16
+ return isNumber(value) || typeof value === "string" && value.trim().length > 0 && !Number.isNaN(+value);
17
+ }
18
+ function isObject(value) {
19
+ return typeof value === "object" && value !== null || typeof value === "function";
20
+ }
21
+ function isPlainObject(value) {
22
+ if (typeof value !== "object" || value === null) {
23
+ return false;
24
+ }
25
+ const prototype = Object.getPrototypeOf(value);
26
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
27
+ }
28
+ export {
29
+ isPlainObject,
30
+ isObject,
31
+ isNumerical,
32
+ isNumber,
33
+ isNullableOrWhitespace,
34
+ isNullable,
35
+ isArrayOrPlainObject
36
+ };
package/dist/js/proxy.js CHANGED
@@ -1,39 +1,91 @@
1
+ // src/js/is.ts
2
+ function isArrayOrPlainObject(value) {
3
+ return Array.isArray(value) || isPlainObject(value);
4
+ }
5
+ function isPlainObject(value) {
6
+ if (typeof value !== "object" || value === null) {
7
+ return false;
8
+ }
9
+ const prototype = Object.getPrototypeOf(value);
10
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
11
+ }
12
+
1
13
  // src/js/value.ts
2
- function isArrayOrObject(value) {
3
- return /^(array|object)$/i.test(value?.constructor?.name);
14
+ function clone(value) {
15
+ return structuredClone(value);
16
+ }
17
+ function merge(...values) {
18
+ if (values.length === 0) {
19
+ return {};
20
+ }
21
+ const actual = values.filter((value) => isArrayOrPlainObject(value));
22
+ const result = actual.every(Array.isArray) ? [] : {};
23
+ const { length } = actual;
24
+ let itemIndex = 0;
25
+ for (;itemIndex < length; itemIndex += 1) {
26
+ const item = actual[itemIndex];
27
+ const keys = Object.keys(item);
28
+ const size = keys.length;
29
+ let keyIndex = 0;
30
+ for (;keyIndex < size; keyIndex += 1) {
31
+ const key = keys[keyIndex];
32
+ const next = item[key];
33
+ const previous = result[key];
34
+ if (isArrayOrPlainObject(next)) {
35
+ result[key] = isArrayOrPlainObject(previous) ? merge(previous, next) : merge(next);
36
+ } else {
37
+ result[key] = next;
38
+ }
39
+ }
40
+ }
41
+ return result;
4
42
  }
5
43
 
6
44
  // src/js/proxy.ts
7
- var _createProxy = function(blob, value2) {
8
- if (!isArrayOrObject(value2) || _isProxy(value2)) {
45
+ var _createProxy = function(existing, value2) {
46
+ if (!isArrayOrPlainObject(value2) || _isProxy(value2) && value2.$ === existing) {
9
47
  return value2;
10
48
  }
11
49
  const isArray = Array.isArray(value2);
12
- const proxyBlob = blob ?? new ProxyBlob;
13
- const proxyValue = new Proxy(isArray ? [] : {}, {});
14
- Object.defineProperty(proxyValue, "$", {
15
- value: proxyBlob
50
+ const proxy = new Proxy(isArray ? [] : {}, {
51
+ get(target, property) {
52
+ return property === "$" ? manager : Reflect.get(target, property);
53
+ },
54
+ set(target, property, value3) {
55
+ return property === "$" || Reflect.set(target, property, _createProxy(manager, value3));
56
+ }
57
+ });
58
+ const manager = existing ?? new Manager(proxy);
59
+ Object.defineProperty(proxy, "$", {
60
+ value: manager
16
61
  });
17
62
  const keys = Object.keys(value2);
18
- const size = keys.length ?? 0;
63
+ const { length } = keys;
19
64
  let index = 0;
20
- for (;index < size; index += 1) {
65
+ for (;index < length; index += 1) {
21
66
  const key = keys[index];
22
- proxyValue[key] = _createProxy(proxyBlob, value2[key]);
67
+ proxy[key] = value2[key];
23
68
  }
24
- return proxyValue;
69
+ return proxy;
25
70
  };
26
71
  var _isProxy = function(value2) {
27
- return value2?.$ instanceof ProxyBlob;
72
+ return value2?.$ instanceof Manager;
28
73
  };
29
74
  function proxy(value2) {
30
- if (!isArrayOrObject(value2)) {
75
+ if (!isArrayOrPlainObject(value2)) {
31
76
  throw new Error("Proxy value must be an array or object");
32
77
  }
33
78
  return _createProxy(undefined, value2);
34
79
  }
35
80
 
36
- class ProxyBlob {
81
+ class Manager {
82
+ owner;
83
+ constructor(owner) {
84
+ this.owner = owner;
85
+ }
86
+ clone() {
87
+ return clone(merge(this.owner));
88
+ }
37
89
  }
38
90
  export {
39
91
  proxy
package/dist/js/proxy.mjs CHANGED
@@ -1,35 +1,50 @@
1
1
  // src/js/proxy.ts
2
- import {isArrayOrObject} from "./value";
3
- var _createProxy = function(blob, value2) {
4
- if (!isArrayOrObject(value2) || _isProxy(value2)) {
2
+ import {isArrayOrPlainObject} from "./is";
3
+ import {clone, merge} from "./value";
4
+ var _createProxy = function(existing, value2) {
5
+ if (!isArrayOrPlainObject(value2) || _isProxy(value2) && value2.$ === existing) {
5
6
  return value2;
6
7
  }
7
8
  const isArray = Array.isArray(value2);
8
- const proxyBlob = blob ?? new ProxyBlob;
9
- const proxyValue = new Proxy(isArray ? [] : {}, {});
10
- Object.defineProperty(proxyValue, "$", {
11
- value: proxyBlob
9
+ const proxy = new Proxy(isArray ? [] : {}, {
10
+ get(target, property) {
11
+ return property === "$" ? manager : Reflect.get(target, property);
12
+ },
13
+ set(target, property, value3) {
14
+ return property === "$" || Reflect.set(target, property, _createProxy(manager, value3));
15
+ }
16
+ });
17
+ const manager = existing ?? new Manager(proxy);
18
+ Object.defineProperty(proxy, "$", {
19
+ value: manager
12
20
  });
13
21
  const keys = Object.keys(value2);
14
- const size = keys.length ?? 0;
22
+ const { length } = keys;
15
23
  let index = 0;
16
- for (;index < size; index += 1) {
24
+ for (;index < length; index += 1) {
17
25
  const key = keys[index];
18
- proxyValue[key] = _createProxy(proxyBlob, value2[key]);
26
+ proxy[key] = value2[key];
19
27
  }
20
- return proxyValue;
28
+ return proxy;
21
29
  };
22
30
  var _isProxy = function(value2) {
23
- return value2?.$ instanceof ProxyBlob;
31
+ return value2?.$ instanceof Manager;
24
32
  };
25
33
  function proxy(value2) {
26
- if (!isArrayOrObject(value2)) {
34
+ if (!isArrayOrPlainObject(value2)) {
27
35
  throw new Error("Proxy value must be an array or object");
28
36
  }
29
37
  return _createProxy(undefined, value2);
30
38
  }
31
39
 
32
- class ProxyBlob {
40
+ class Manager {
41
+ owner;
42
+ constructor(owner) {
43
+ this.owner = owner;
44
+ }
45
+ clone() {
46
+ return clone(merge(this.owner));
47
+ }
33
48
  }
34
49
  export {
35
50
  proxy
package/dist/js/string.js CHANGED
@@ -9,11 +9,7 @@ function getString(value) {
9
9
  const result = value?.toString?.() ?? value;
10
10
  return result?.toString?.() ?? String(result);
11
11
  }
12
- function isNullableOrWhitespace(value) {
13
- return value == null || getString(value).trim().length === 0;
14
- }
15
12
  export {
16
- isNullableOrWhitespace,
17
13
  getString,
18
14
  createUuid
19
15
  };
@@ -9,11 +9,7 @@ function getString(value) {
9
9
  const result = value?.toString?.() ?? value;
10
10
  return result?.toString?.() ?? String(result);
11
11
  }
12
- function isNullableOrWhitespace(value) {
13
- return value == null || getString(value).trim().length === 0;
14
- }
15
12
  export {
16
- isNullableOrWhitespace,
17
13
  getString,
18
14
  createUuid
19
15
  };
package/dist/js/value.js CHANGED
@@ -7,6 +7,18 @@ function getString(value) {
7
7
  return result?.toString?.() ?? String(result);
8
8
  }
9
9
 
10
+ // src/js/is.ts
11
+ function isArrayOrPlainObject(value) {
12
+ return Array.isArray(value) || isPlainObject(value);
13
+ }
14
+ function isPlainObject(value) {
15
+ if (typeof value !== "object" || value === null) {
16
+ return false;
17
+ }
18
+ const prototype = Object.getPrototypeOf(value);
19
+ return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
20
+ }
21
+
10
22
  // src/js/value.ts
11
23
  var _getDiffs = function(first, second, prefix) {
12
24
  const changes = [];
@@ -14,13 +26,13 @@ var _getDiffs = function(first, second, prefix) {
14
26
  let outer = 0;
15
27
  for (;outer < 2; outer += 1) {
16
28
  const value = outer === 0 ? first : second;
17
- if (!isArrayOrObject(value)) {
29
+ if (!value) {
18
30
  continue;
19
31
  }
20
32
  const keys = Object.keys(value);
21
- const size = keys.length;
33
+ const { length } = keys;
22
34
  let inner = 0;
23
- for (;inner < size; inner += 1) {
35
+ for (;inner < length; inner += 1) {
24
36
  const key = keys[inner];
25
37
  if (checked.has(key)) {
26
38
  continue;
@@ -34,7 +46,9 @@ var _getDiffs = function(first, second, prefix) {
34
46
  to,
35
47
  key: prefixed
36
48
  });
37
- changes.push(..._getDiffs(from, to, prefixed));
49
+ if (isArrayOrPlainObject(from) && isArrayOrPlainObject(to)) {
50
+ changes.push(..._getDiffs(from, to, prefixed));
51
+ }
38
52
  }
39
53
  checked.add(key);
40
54
  }
@@ -73,8 +87,8 @@ function diff(first, second) {
73
87
  values: {}
74
88
  };
75
89
  const same = Object.is(first, second);
76
- const firstIsArrayOrObject = isArrayOrObject(first);
77
- const secondIsArrayOrObject = isArrayOrObject(second);
90
+ const firstIsArrayOrObject = isArrayOrPlainObject(first);
91
+ const secondIsArrayOrObject = isArrayOrPlainObject(second);
78
92
  if (same || !firstIsArrayOrObject && !secondIsArrayOrObject) {
79
93
  result.type = same ? "none" : "full";
80
94
  return result;
@@ -107,20 +121,11 @@ function get(data, key) {
107
121
  }
108
122
  return value;
109
123
  }
110
- function isArrayOrObject(value) {
111
- return /^(array|object)$/i.test(value?.constructor?.name);
112
- }
113
- function isNullable(value) {
114
- return value == null;
115
- }
116
- function isObject(value) {
117
- return /^object$/i.test(value?.constructor?.name);
118
- }
119
124
  function merge(...values) {
120
125
  if (values.length === 0) {
121
126
  return {};
122
127
  }
123
- const actual = values.filter(isArrayOrObject);
128
+ const actual = values.filter((value) => isArrayOrPlainObject(value));
124
129
  const result = actual.every(Array.isArray) ? [] : {};
125
130
  const { length } = actual;
126
131
  let itemIndex = 0;
@@ -133,8 +138,8 @@ function merge(...values) {
133
138
  const key = keys[keyIndex];
134
139
  const next = item[key];
135
140
  const previous = result[key];
136
- if (isArrayOrObject(next)) {
137
- result[key] = isArrayOrObject(previous) ? merge(previous, next) : merge(next);
141
+ if (isArrayOrPlainObject(next)) {
142
+ result[key] = isArrayOrPlainObject(previous) ? merge(previous, next) : merge(next);
138
143
  } else {
139
144
  result[key] = next;
140
145
  }
@@ -145,11 +150,12 @@ function merge(...values) {
145
150
  function set(data, key, value) {
146
151
  const parts = getString(key).split(".");
147
152
  const { length } = parts;
153
+ const lastIndex = length - 1;
148
154
  let index = 0;
149
155
  let target = typeof data === "object" ? data ?? {} : {};
150
156
  for (;index < length; index += 1) {
151
157
  const part = parts[index];
152
- if (parts.indexOf(part) === parts.length - 1) {
158
+ if (parts.indexOf(part) === lastIndex) {
153
159
  _setValue(target, part, value);
154
160
  break;
155
161
  }
@@ -165,9 +171,6 @@ function set(data, key, value) {
165
171
  export {
166
172
  set,
167
173
  merge,
168
- isObject,
169
- isNullable,
170
- isArrayOrObject,
171
174
  get,
172
175
  diff,
173
176
  clone
package/dist/js/value.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/js/value.ts
2
+ import {isArrayOrPlainObject} from "./is";
2
3
  import {getString} from "./string";
3
4
  var _getDiffs = function(first, second, prefix) {
4
5
  const changes = [];
@@ -6,13 +7,13 @@ var _getDiffs = function(first, second, prefix) {
6
7
  let outer = 0;
7
8
  for (;outer < 2; outer += 1) {
8
9
  const value = outer === 0 ? first : second;
9
- if (!isArrayOrObject(value)) {
10
+ if (!value) {
10
11
  continue;
11
12
  }
12
13
  const keys = Object.keys(value);
13
- const size = keys.length;
14
+ const { length } = keys;
14
15
  let inner = 0;
15
- for (;inner < size; inner += 1) {
16
+ for (;inner < length; inner += 1) {
16
17
  const key = keys[inner];
17
18
  if (checked.has(key)) {
18
19
  continue;
@@ -26,7 +27,9 @@ var _getDiffs = function(first, second, prefix) {
26
27
  to,
27
28
  key: prefixed
28
29
  });
29
- changes.push(..._getDiffs(from, to, prefixed));
30
+ if (isArrayOrPlainObject(from) && isArrayOrPlainObject(to)) {
31
+ changes.push(..._getDiffs(from, to, prefixed));
32
+ }
30
33
  }
31
34
  checked.add(key);
32
35
  }
@@ -65,8 +68,8 @@ function diff(first, second) {
65
68
  values: {}
66
69
  };
67
70
  const same = Object.is(first, second);
68
- const firstIsArrayOrObject = isArrayOrObject(first);
69
- const secondIsArrayOrObject = isArrayOrObject(second);
71
+ const firstIsArrayOrObject = isArrayOrPlainObject(first);
72
+ const secondIsArrayOrObject = isArrayOrPlainObject(second);
70
73
  if (same || !firstIsArrayOrObject && !secondIsArrayOrObject) {
71
74
  result.type = same ? "none" : "full";
72
75
  return result;
@@ -99,20 +102,11 @@ function get(data, key) {
99
102
  }
100
103
  return value;
101
104
  }
102
- function isArrayOrObject(value) {
103
- return /^(array|object)$/i.test(value?.constructor?.name);
104
- }
105
- function isNullable(value) {
106
- return value == null;
107
- }
108
- function isObject(value) {
109
- return /^object$/i.test(value?.constructor?.name);
110
- }
111
105
  function merge(...values) {
112
106
  if (values.length === 0) {
113
107
  return {};
114
108
  }
115
- const actual = values.filter(isArrayOrObject);
109
+ const actual = values.filter((value) => isArrayOrPlainObject(value));
116
110
  const result = actual.every(Array.isArray) ? [] : {};
117
111
  const { length } = actual;
118
112
  let itemIndex = 0;
@@ -125,8 +119,8 @@ function merge(...values) {
125
119
  const key = keys[keyIndex];
126
120
  const next = item[key];
127
121
  const previous = result[key];
128
- if (isArrayOrObject(next)) {
129
- result[key] = isArrayOrObject(previous) ? merge(previous, next) : merge(next);
122
+ if (isArrayOrPlainObject(next)) {
123
+ result[key] = isArrayOrPlainObject(previous) ? merge(previous, next) : merge(next);
130
124
  } else {
131
125
  result[key] = next;
132
126
  }
@@ -137,11 +131,12 @@ function merge(...values) {
137
131
  function set(data, key, value) {
138
132
  const parts = getString(key).split(".");
139
133
  const { length } = parts;
134
+ const lastIndex = length - 1;
140
135
  let index = 0;
141
136
  let target = typeof data === "object" ? data ?? {} : {};
142
137
  for (;index < length; index += 1) {
143
138
  const part = parts[index];
144
- if (parts.indexOf(part) === parts.length - 1) {
139
+ if (parts.indexOf(part) === lastIndex) {
145
140
  _setValue(target, part, value);
146
141
  break;
147
142
  }
@@ -157,9 +152,6 @@ function set(data, key, value) {
157
152
  export {
158
153
  set,
159
154
  merge,
160
- isObject,
161
- isNullable,
162
- isArrayOrObject,
163
155
  get,
164
156
  diff,
165
157
  clone
package/package.json CHANGED
@@ -36,6 +36,12 @@
36
36
  "require": "./dist/js/element/focusable.js",
37
37
  "types": "./types/element/focusable.d.ts"
38
38
  },
39
+ "./is": {
40
+ "bun": "./src/js/is.ts",
41
+ "import": "./dist/js/is.mjs",
42
+ "require": "./dist/js/is.js",
43
+ "types": "./types/is.d.ts"
44
+ },
39
45
  "./number": {
40
46
  "bun": "./src/js/number.ts",
41
47
  "import": "./dist/js/number.mjs",
@@ -99,5 +105,5 @@
99
105
  },
100
106
  "type": "module",
101
107
  "types": "./types/index.d.ts",
102
- "version": "0.19.0"
108
+ "version": "0.21.0"
103
109
  }
package/src/js/array.ts CHANGED
@@ -1,4 +1,5 @@
1
- import {GenericObject, Key} from './value';
1
+ import {PlainObject} from './is';
2
+ import {Key} from './value';
2
3
 
3
4
  type BooleanCallback<T> = (item: T, index: number, array: T[]) => boolean;
4
5
 
@@ -35,7 +36,7 @@ function _getCallbacks<T>(
35
36
  }
36
37
 
37
38
  return {
38
- key: (item: T) => (item as GenericObject)?.[key as string] as Key,
39
+ key: (item: T) => (item as PlainObject)?.[key as string] as Key,
39
40
  };
40
41
  }
41
42
 
package/src/js/is.ts ADDED
@@ -0,0 +1,77 @@
1
+ import {getString} from './string';
2
+
3
+ export type ArrayOrPlainObject = unknown[] | PlainObject;
4
+
5
+ export type PlainObject = Record<string, unknown>;
6
+
7
+ /**
8
+ * Is the value an array or a plain object?
9
+ */
10
+ export function isArrayOrPlainObject(
11
+ value: unknown,
12
+ ): value is ArrayOrPlainObject {
13
+ return Array.isArray(value) || isPlainObject(value);
14
+ }
15
+
16
+ /**
17
+ * Is the value undefined or null?
18
+ */
19
+ export function isNullable(value: unknown): value is undefined | null {
20
+ return value == null;
21
+ }
22
+
23
+ /**
24
+ * Is the value undefined, null, or an empty string?
25
+ */
26
+ export function isNullableOrWhitespace(
27
+ value: unknown,
28
+ ): value is undefined | null | '' {
29
+ return value == null || getString(value).trim().length === 0;
30
+ }
31
+
32
+ /**
33
+ * Is the value a number?
34
+ */
35
+ export function isNumber(value: unknown): value is number {
36
+ return typeof value === 'number' && !Number.isNaN(value);
37
+ }
38
+
39
+ /**
40
+ * Is the value a number, or a number-like string?
41
+ */
42
+ export function isNumerical(value: unknown): value is number | `${number}` {
43
+ return (
44
+ isNumber(value) ||
45
+ (typeof value === 'string' &&
46
+ value.trim().length > 0 &&
47
+ !Number.isNaN(+value))
48
+ );
49
+ }
50
+
51
+ /**
52
+ * Is the value an object?
53
+ */
54
+ export function isObject(value: unknown): value is object {
55
+ return (
56
+ (typeof value === 'object' && value !== null) || typeof value === 'function'
57
+ );
58
+ }
59
+
60
+ /**
61
+ * Is the value a generic object?
62
+ */
63
+ export function isPlainObject(value: unknown): value is PlainObject {
64
+ if (typeof value !== 'object' || value === null) {
65
+ return false;
66
+ }
67
+
68
+ const prototype = Object.getPrototypeOf(value);
69
+
70
+ return (
71
+ (prototype === null ||
72
+ prototype === Object.prototype ||
73
+ Object.getPrototypeOf(prototype) === null) &&
74
+ !(Symbol.toStringTag in value) &&
75
+ !(Symbol.iterator in value)
76
+ );
77
+ }
package/src/js/proxy.ts CHANGED
@@ -1,49 +1,71 @@
1
- import {ArrayOrObject, GenericObject, isArrayOrObject} from './value';
1
+ import {ArrayOrPlainObject, PlainObject, isArrayOrPlainObject} from './is';
2
+ import {clone, merge} from './value';
2
3
 
3
- class ProxyBlob {}
4
+ class Manager<T extends ArrayOrPlainObject = PlainObject> {
5
+ constructor(readonly owner: Proxied<T>) {}
4
6
 
5
- type ProxyValue = {
6
- $: ProxyBlob;
7
- };
7
+ clone(): Proxied<T> {
8
+ return clone(merge(this.owner)) as Proxied<T>;
9
+ }
10
+ }
11
+
12
+ export type Proxied<T extends ArrayOrPlainObject = PlainObject> = {
13
+ $: Manager<T>;
14
+ } & T;
8
15
 
9
- function _createProxy<T extends ArrayOrObject>(
10
- blob: ProxyBlob | undefined,
16
+ function _createProxy<T extends ArrayOrPlainObject>(
17
+ existing: Manager | undefined,
11
18
  value: T,
12
- ): T {
13
- if (!isArrayOrObject(value) || _isProxy(value)) {
19
+ ): unknown {
20
+ if (
21
+ !isArrayOrPlainObject(value) ||
22
+ (_isProxy(value) && value.$ === existing)
23
+ ) {
14
24
  return value;
15
25
  }
16
26
 
17
27
  const isArray = Array.isArray(value);
18
- const proxyBlob = blob ?? new ProxyBlob();
19
- const proxyValue = new Proxy(isArray ? [] : {}, {});
20
28
 
21
- Object.defineProperty(proxyValue, '$', {
22
- value: proxyBlob,
29
+ const proxy = new Proxy(isArray ? [] : {}, {
30
+ get(target, property) {
31
+ return property === '$' ? manager : Reflect.get(target, property);
32
+ },
33
+ set(target, property, value) {
34
+ return (
35
+ property === '$' ||
36
+ Reflect.set(target, property, _createProxy(manager, value))
37
+ );
38
+ },
39
+ }) as Proxied;
40
+
41
+ const manager = existing ?? new Manager(proxy);
42
+
43
+ Object.defineProperty(proxy, '$', {
44
+ value: manager,
23
45
  });
24
46
 
25
- const keys = Object.keys(value);
26
- const size = keys.length ?? 0;
47
+ const keys = Object.keys(value);
48
+ const {length} = keys;
27
49
 
28
50
  let index = 0;
29
51
 
30
- for (; index < size; index += 1) {
52
+ for (; index < length; index += 1) {
31
53
  const key = keys[index];
32
54
 
33
- proxyValue[key as never] = _createProxy(proxyBlob, value[key as never]);
55
+ proxy[key as never] = value[key as never];
34
56
  }
35
57
 
36
- return proxyValue as T;
58
+ return proxy;
37
59
  }
38
60
 
39
- function _isProxy(value: unknown): value is ProxyValue {
40
- return (value as GenericObject)?.$ instanceof ProxyBlob;
61
+ function _isProxy(value: unknown): value is Proxied {
62
+ return (value as Proxied)?.$ instanceof Manager;
41
63
  }
42
64
 
43
- export function proxy<T extends ArrayOrObject>(value: T): T {
44
- if (!isArrayOrObject(value)) {
65
+ export function proxy<T extends PlainObject>(value: T): Proxied<T> {
66
+ if (!isArrayOrPlainObject(value)) {
45
67
  throw new Error('Proxy value must be an array or object');
46
68
  }
47
69
 
48
- return _createProxy(undefined, value);
70
+ return _createProxy(undefined, value) as Proxied<T>;
49
71
  }
package/src/js/string.ts CHANGED
@@ -24,12 +24,3 @@ export function getString(value: unknown): string {
24
24
 
25
25
  return result?.toString?.() ?? String(result);
26
26
  }
27
-
28
- /**
29
- * Is the value undefined, null, or an empty string?
30
- */
31
- export function isNullableOrWhitespace(
32
- value: unknown,
33
- ): value is undefined | null | '' {
34
- return value == null || getString(value).trim().length === 0;
35
- }
package/src/js/value.ts CHANGED
@@ -1,7 +1,7 @@
1
+ import {chunk} from './array';
2
+ import {ArrayOrPlainObject, PlainObject, isArrayOrPlainObject} from './is';
1
3
  import {getString} from './string';
2
4
 
3
- export type ArrayOrObject = unknown[] | GenericObject;
4
-
5
5
  export type DiffType = 'full' | 'none' | 'partial';
6
6
 
7
7
  export type DiffResult<T1 = unknown, T2 = T1> = {
@@ -15,15 +15,13 @@ export type DiffValue<T1 = unknown, T2 = T1> = {
15
15
  to: T2;
16
16
  };
17
17
 
18
- export type GenericObject = Record<string, unknown>;
19
-
20
18
  export type Key = number | string;
21
19
 
22
20
  type KeyedDiffValue = {
23
21
  key: string;
24
22
  } & DiffValue;
25
23
 
26
- export type ValueObject = ArrayOrObject | Map<unknown, unknown>;
24
+ export type ValueObject = ArrayOrPlainObject | Map<unknown, unknown>;
27
25
 
28
26
  function _getDiffs(
29
27
  first: unknown,
@@ -38,16 +36,16 @@ function _getDiffs(
38
36
  for (; outer < 2; outer += 1) {
39
37
  const value = outer === 0 ? first : second;
40
38
 
41
- if (!isArrayOrObject(value)) {
39
+ if (!value) {
42
40
  continue;
43
41
  }
44
42
 
45
43
  const keys = Object.keys(value);
46
- const size = keys.length;
44
+ const {length} = keys;
47
45
 
48
46
  let inner = 0;
49
47
 
50
- for (; inner < size; inner += 1) {
48
+ for (; inner < length; inner += 1) {
51
49
  const key = keys[inner];
52
50
 
53
51
  if (checked.has(key)) {
@@ -66,7 +64,9 @@ function _getDiffs(
66
64
  key: prefixed,
67
65
  });
68
66
 
69
- changes.push(..._getDiffs(from, to, prefixed));
67
+ if (isArrayOrPlainObject(from) && isArrayOrPlainObject(to)) {
68
+ changes.push(..._getDiffs(from, to, prefixed));
69
+ }
70
70
  }
71
71
 
72
72
  checked.add(key);
@@ -121,6 +121,16 @@ export function clone<T>(value: T): T {
121
121
  return structuredClone(value);
122
122
  }
123
123
 
124
+ /**
125
+ * - Find the differences between two values
126
+ * - Returns an object holding the result:
127
+ * - `original` holds the original values
128
+ * - `type` is the type of difference:
129
+ * - `full` if the values are completely different
130
+ * - `none` if the values are the same
131
+ * - `partial` if the values are partially different
132
+ * - `values` holds the differences with dot-notation keys
133
+ */
124
134
  export function diff<T1 = unknown, T2 = T1>(
125
135
  first: T1,
126
136
  second: T2,
@@ -136,8 +146,8 @@ export function diff<T1 = unknown, T2 = T1>(
136
146
 
137
147
  const same = Object.is(first, second);
138
148
 
139
- const firstIsArrayOrObject = isArrayOrObject(first);
140
- const secondIsArrayOrObject = isArrayOrObject(second);
149
+ const firstIsArrayOrObject = isArrayOrPlainObject(first);
150
+ const secondIsArrayOrObject = isArrayOrPlainObject(second);
141
151
 
142
152
  if (same || (!firstIsArrayOrObject && !secondIsArrayOrObject)) {
143
153
  result.type = same ? 'none' : 'full';
@@ -190,37 +200,19 @@ export function get(data: ValueObject, key: Key): unknown {
190
200
  return value;
191
201
  }
192
202
 
193
- /**
194
- * Is the value an array or a generic object?
195
- */
196
- export function isArrayOrObject(value: unknown): value is ArrayOrObject {
197
- return /^(array|object)$/i.test((value as ArrayOrObject)?.constructor?.name);
198
- }
199
-
200
- /**
201
- * Is the value undefined or null?
202
- */
203
- export function isNullable(value: unknown): value is undefined | null {
204
- return value == null;
205
- }
206
-
207
- /**
208
- * Is the value a generic object?
209
- */
210
- export function isObject(value: unknown): value is GenericObject {
211
- return /^object$/i.test((value as GenericObject)?.constructor?.name);
212
- }
213
-
214
203
  /**
215
204
  * Merges multiple arrays or objects into a single one
216
205
  */
217
- export function merge<T = ArrayOrObject>(...values: T[]): T {
206
+ export function merge<T = ArrayOrPlainObject>(...values: T[]): T {
218
207
  if (values.length === 0) {
219
208
  return {} as T;
220
209
  }
221
210
 
222
- const actual = values.filter(isArrayOrObject) as GenericObject[];
223
- const result = (actual.every(Array.isArray) ? [] : {}) as GenericObject;
211
+ const actual = values.filter(value =>
212
+ isArrayOrPlainObject(value),
213
+ ) as PlainObject[];
214
+
215
+ const result = (actual.every(Array.isArray) ? [] : {}) as PlainObject;
224
216
 
225
217
  const {length} = actual;
226
218
 
@@ -238,8 +230,8 @@ export function merge<T = ArrayOrObject>(...values: T[]): T {
238
230
  const next = item[key];
239
231
  const previous = result[key];
240
232
 
241
- if (isArrayOrObject(next)) {
242
- result[key] = isArrayOrObject(previous)
233
+ if (isArrayOrPlainObject(next)) {
234
+ result[key] = isArrayOrPlainObject(previous)
243
235
  ? merge(previous, next)
244
236
  : merge(next);
245
237
  } else {
@@ -264,6 +256,7 @@ export function set<T extends ValueObject>(
264
256
  ): T {
265
257
  const parts = getString(key).split('.');
266
258
  const {length} = parts;
259
+ const lastIndex = length - 1;
267
260
 
268
261
  let index = 0;
269
262
  let target: ValueObject = typeof data === 'object' ? data ?? {} : {};
@@ -271,7 +264,7 @@ export function set<T extends ValueObject>(
271
264
  for (; index < length; index += 1) {
272
265
  const part = parts[index];
273
266
 
274
- if (parts.indexOf(part) === parts.length - 1) {
267
+ if (parts.indexOf(part) === lastIndex) {
275
268
  _setValue(target, part, value);
276
269
 
277
270
  break;
package/types/is.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ export type ArrayOrPlainObject = unknown[] | PlainObject;
2
+ export type PlainObject = Record<string, unknown>;
3
+ /**
4
+ * Is the value an array or a plain object?
5
+ */
6
+ export declare function isArrayOrPlainObject(value: unknown): value is ArrayOrPlainObject;
7
+ /**
8
+ * Is the value undefined or null?
9
+ */
10
+ export declare function isNullable(value: unknown): value is undefined | null;
11
+ /**
12
+ * Is the value undefined, null, or an empty string?
13
+ */
14
+ export declare function isNullableOrWhitespace(value: unknown): value is undefined | null | '';
15
+ /**
16
+ * Is the value a number?
17
+ */
18
+ export declare function isNumber(value: unknown): value is number;
19
+ /**
20
+ * Is the value a number, or a number-like string?
21
+ */
22
+ export declare function isNumerical(value: unknown): value is number | `${number}`;
23
+ /**
24
+ * Is the value an object?
25
+ */
26
+ export declare function isObject(value: unknown): value is object;
27
+ /**
28
+ * Is the value a generic object?
29
+ */
30
+ export declare function isPlainObject(value: unknown): value is PlainObject;
package/types/proxy.d.ts CHANGED
@@ -1,2 +1,11 @@
1
- import { ArrayOrObject } from './value';
2
- export declare function proxy<T extends ArrayOrObject>(value: T): T;
1
+ import { ArrayOrPlainObject, PlainObject } from './is';
2
+ declare class Manager<T extends ArrayOrPlainObject = PlainObject> {
3
+ readonly owner: Proxied<T>;
4
+ constructor(owner: Proxied<T>);
5
+ clone(): Proxied<T>;
6
+ }
7
+ export type Proxied<T extends ArrayOrPlainObject = PlainObject> = {
8
+ $: Manager<T>;
9
+ } & T;
10
+ export declare function proxy<T extends PlainObject>(value: T): Proxied<T>;
11
+ export {};
package/types/string.d.ts CHANGED
@@ -6,7 +6,3 @@ export declare function createUuid(): string;
6
6
  * Get the string value from any value
7
7
  */
8
8
  export declare function getString(value: unknown): string;
9
- /**
10
- * Is the value undefined, null, or an empty string?
11
- */
12
- export declare function isNullableOrWhitespace(value: unknown): value is undefined | null | '';
package/types/value.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type ArrayOrObject = unknown[] | GenericObject;
1
+ import { ArrayOrPlainObject } from './is';
2
2
  export type DiffType = 'full' | 'none' | 'partial';
3
3
  export type DiffResult<T1 = unknown, T2 = T1> = {
4
4
  original: DiffValue<T1, T2>;
@@ -9,13 +9,22 @@ export type DiffValue<T1 = unknown, T2 = T1> = {
9
9
  from: T1;
10
10
  to: T2;
11
11
  };
12
- export type GenericObject = Record<string, unknown>;
13
12
  export type Key = number | string;
14
- export type ValueObject = ArrayOrObject | Map<unknown, unknown>;
13
+ export type ValueObject = ArrayOrPlainObject | Map<unknown, unknown>;
15
14
  /**
16
15
  * Clones any kind of value
17
16
  */
18
17
  export declare function clone<T>(value: T): T;
18
+ /**
19
+ * - Find the differences between two values
20
+ * - Returns an object holding the result:
21
+ * - `original` holds the original values
22
+ * - `type` is the type of difference:
23
+ * - `full` if the values are completely different
24
+ * - `none` if the values are the same
25
+ * - `partial` if the values are partially different
26
+ * - `values` holds the differences with dot-notation keys
27
+ */
19
28
  export declare function diff<T1 = unknown, T2 = T1>(first: T1, second: T2): DiffResult<T1, T2>;
20
29
  /**
21
30
  * - Get the value from an object using a key path
@@ -23,22 +32,10 @@ export declare function diff<T1 = unknown, T2 = T1>(first: T1, second: T2): Diff
23
32
  * - Returns `undefined` if the value is not found
24
33
  */
25
34
  export declare function get(data: ValueObject, key: Key): unknown;
26
- /**
27
- * Is the value an array or a generic object?
28
- */
29
- export declare function isArrayOrObject(value: unknown): value is ArrayOrObject;
30
- /**
31
- * Is the value undefined or null?
32
- */
33
- export declare function isNullable(value: unknown): value is undefined | null;
34
- /**
35
- * Is the value a generic object?
36
- */
37
- export declare function isObject(value: unknown): value is GenericObject;
38
35
  /**
39
36
  * Merges multiple arrays or objects into a single one
40
37
  */
41
- export declare function merge<T = ArrayOrObject>(...values: T[]): T;
38
+ export declare function merge<T = ArrayOrPlainObject>(...values: T[]): T;
42
39
  /**
43
40
  * - Set the value in an object using a key path
44
41
  * - You can set a nested value by using dot notation, e.g., `foo.bar.baz`
@@ -1,124 +0,0 @@
1
- // src/js/colour.ts
2
- import {between} from "./number";
3
- var _normaliseHex = function(value) {
4
- return typeof value === "string" ? value.replace(hexTrim, "") : undefined;
5
- };
6
- function hexToHSL(value) {
7
- return rgbToHSL(hexToRGB(value));
8
- }
9
- function hexToRGB(value) {
10
- const normalised = _normaliseHex(value);
11
- if (!isHexColour(normalised)) {
12
- return;
13
- }
14
- const matches = normalised.match(hexGroups);
15
- if (matches === null) {
16
- return;
17
- }
18
- return {
19
- blue: parseInt(matches[1], 16),
20
- green: parseInt(matches[2], 16),
21
- red: parseInt(matches[3], 16)
22
- };
23
- }
24
- function hslToHex(value) {
25
- if (isHSLColour(value)) {
26
- return rgbToHex(hslToRGB(value));
27
- }
28
- }
29
- function hslToRGB(value) {
30
- if (!isHSLColour(value)) {
31
- return;
32
- }
33
- function getValue(value2) {
34
- const k = (value2 + hue / 30) % 12;
35
- const a = saturation * Math.min(lightness, 1 - lightness);
36
- return lightness - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
37
- }
38
- let hue = Number(value.hue);
39
- let lightness = Number(value.lightness);
40
- let saturation = Number(value.saturation);
41
- hue %= 360;
42
- if (hue < 0) {
43
- hue += 360;
44
- }
45
- lightness /= 100;
46
- saturation /= 100;
47
- return {
48
- blue: Math.round(getValue(4) * 255),
49
- green: Math.round(getValue(8) * 255),
50
- red: Math.round(getValue(0) * 255)
51
- };
52
- }
53
- function isHexColour(value) {
54
- return typeof value === "string" && hexValue.test(value);
55
- }
56
- function isHSLColour(value) {
57
- return ["hue", "lightness", "saturation"].every((key) => between(value?.[key], 0, key === "hue" ? 360 : 100));
58
- }
59
- function isRGBColour(value) {
60
- return ["red", "green", "blue"].every((key) => between(value?.[key], 0, 255));
61
- }
62
- function rgbToHex(value) {
63
- if (isRGBColour(value)) {
64
- return `#${(value.blue | value.green << 8 | value.red << 16 | 1 << 24).toString(16).slice(1)}`;
65
- }
66
- }
67
- function rgbToHSL(value) {
68
- if (!isRGBColour(value)) {
69
- return;
70
- }
71
- let red = Number(value.red);
72
- let green = Number(value.green);
73
- let blue = Number(value.blue);
74
- red /= 255;
75
- green /= 255;
76
- blue /= 255;
77
- const min = Math.min(red, green, blue);
78
- const max = Math.max(red, green, blue);
79
- const chroma = max - min;
80
- const lightness = max - chroma / 2;
81
- let hue = 0;
82
- let saturation = 0;
83
- switch (chroma) {
84
- case red: {
85
- hue = (green - blue) / chroma % 6;
86
- break;
87
- }
88
- case green: {
89
- hue = (blue - red) / chroma + 2;
90
- break;
91
- }
92
- case blue: {
93
- hue = (red - green) / chroma + 2;
94
- break;
95
- }
96
- default: {
97
- break;
98
- }
99
- }
100
- saturation = max === 0 || lightness === 0 || lightness === 0 ? 0 : (max - lightness) / Math.min(lightness, 1 - lightness);
101
- hue *= 60;
102
- if (hue < 0) {
103
- hue += 360;
104
- }
105
- return {
106
- hue: Math.round(hue),
107
- saturation: Math.round(saturation * 100),
108
- lightness: Math.round(lightness * 100)
109
- };
110
- }
111
- var hexGroups = /^([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i;
112
- var hexTrim = /^(#|\s)|\s$/g;
113
- var hexValue = /^([\da-f]{3}){1,2}$/i;
114
- export {
115
- rgbToHex,
116
- rgbToHSL,
117
- isRGBColour,
118
- isHexColour,
119
- isHSLColour,
120
- hslToRGB,
121
- hslToHex,
122
- hexToRGB,
123
- hexToHSL
124
- };