@oscarpalmer/atoms 0.193.0 → 0.194.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/dist/array/difference.mjs +2 -2
  2. package/dist/array/intersection.mjs +2 -2
  3. package/dist/array/match.mjs +13 -13
  4. package/dist/array/slice.mjs +5 -5
  5. package/dist/array/sort.d.mts +5 -1
  6. package/dist/array/sort.mjs +4 -2
  7. package/dist/array/union.mjs +2 -2
  8. package/dist/beacon.d.mts +8 -1
  9. package/dist/beacon.mjs +52 -60
  10. package/dist/color/constants.d.mts +1 -1
  11. package/dist/color/constants.mjs +3 -5
  12. package/dist/color/instance.mjs +34 -41
  13. package/dist/color/misc/format.d.mts +3 -2
  14. package/dist/color/misc/format.mjs +4 -1
  15. package/dist/color/misc/is.d.mts +9 -1
  16. package/dist/color/misc/is.mjs +11 -1
  17. package/dist/color/misc/state.d.mts +6 -6
  18. package/dist/color/misc/state.mjs +11 -14
  19. package/dist/color/models.d.mts +23 -68
  20. package/dist/function/assert.mjs +2 -2
  21. package/dist/function/limit.d.mts +0 -6
  22. package/dist/function/limit.mjs +2 -2
  23. package/dist/function/memoize.mjs +19 -32
  24. package/dist/function/once.d.mts +0 -3
  25. package/dist/function/once.mjs +16 -13
  26. package/dist/function/retry.d.mts +1 -24
  27. package/dist/function/retry.mjs +1 -1
  28. package/dist/function/work.mjs +13 -11
  29. package/dist/herald.d.mts +30 -31
  30. package/dist/herald.mjs +74 -56
  31. package/dist/index.d.mts +100 -185
  32. package/dist/index.mjs +680 -702
  33. package/dist/internal/abort.d.mts +10 -0
  34. package/dist/internal/abort.mjs +14 -0
  35. package/dist/internal/array/chunk.mjs +2 -2
  36. package/dist/internal/array/find.mjs +2 -2
  37. package/dist/internal/array/sets.d.mts +4 -4
  38. package/dist/internal/array/sets.mjs +7 -7
  39. package/dist/internal/function/timer.mjs +19 -15
  40. package/dist/internal/number.mjs +7 -7
  41. package/dist/internal/result.mjs +3 -3
  42. package/dist/internal/sized.mjs +4 -4
  43. package/dist/internal/string.mjs +4 -4
  44. package/dist/internal/subscription.d.mts +24 -8
  45. package/dist/internal/subscription.mjs +49 -36
  46. package/dist/internal/value/equal.mjs +6 -6
  47. package/dist/internal/value/misc.mjs +14 -14
  48. package/dist/internal/value/set.mjs +2 -2
  49. package/dist/logger.mjs +15 -39
  50. package/dist/promise/constants.d.mts +17 -0
  51. package/dist/promise/constants.mjs +14 -0
  52. package/dist/promise/delay.mjs +7 -10
  53. package/dist/promise/helpers.mjs +1 -1
  54. package/dist/promise/index.mjs +14 -17
  55. package/dist/promise/misc.d.mts +2 -1
  56. package/dist/promise/misc.mjs +8 -7
  57. package/dist/promise/models.d.mts +4 -16
  58. package/dist/promise/models.mjs +4 -13
  59. package/dist/promise/timed.mjs +9 -10
  60. package/dist/query.mjs +15 -15
  61. package/dist/queue.mjs +103 -116
  62. package/dist/random.mjs +7 -7
  63. package/dist/result/index.d.mts +0 -3
  64. package/dist/result/index.mjs +1 -1
  65. package/dist/result/match.d.mts +0 -3
  66. package/dist/result/match.mjs +4 -4
  67. package/dist/result/misc.mjs +2 -2
  68. package/dist/result/work/flow.d.mts +0 -3
  69. package/dist/result/work/flow.mjs +5 -5
  70. package/dist/result/work/pipe.d.mts +0 -3
  71. package/dist/result/work/pipe.mjs +3 -3
  72. package/dist/string/case.mjs +20 -20
  73. package/dist/string/fuzzy.mjs +23 -18
  74. package/dist/string/index.mjs +7 -7
  75. package/dist/string/normalize.mjs +14 -14
  76. package/dist/string/template.mjs +2 -2
  77. package/dist/value/clone.mjs +10 -10
  78. package/dist/value/smush.mjs +2 -2
  79. package/package.json +13 -5
  80. package/src/array/difference.ts +0 -73
  81. package/src/array/exists.ts +0 -93
  82. package/src/array/filter.ts +0 -182
  83. package/src/array/find.ts +0 -183
  84. package/src/array/first.ts +0 -196
  85. package/src/array/flatten.ts +0 -20
  86. package/src/array/from.ts +0 -129
  87. package/src/array/get.ts +0 -131
  88. package/src/array/group-by.ts +0 -369
  89. package/src/array/index.ts +0 -26
  90. package/src/array/insert.ts +0 -52
  91. package/src/array/intersection.ts +0 -72
  92. package/src/array/last.ts +0 -194
  93. package/src/array/match.ts +0 -436
  94. package/src/array/move.ts +0 -315
  95. package/src/array/partition.ts +0 -91
  96. package/src/array/push.ts +0 -23
  97. package/src/array/reverse.ts +0 -33
  98. package/src/array/select.ts +0 -260
  99. package/src/array/single.ts +0 -93
  100. package/src/array/slice.ts +0 -335
  101. package/src/array/sort.ts +0 -607
  102. package/src/array/splice.ts +0 -106
  103. package/src/array/swap.ts +0 -322
  104. package/src/array/to-map.ts +0 -371
  105. package/src/array/to-record.ts +0 -351
  106. package/src/array/to-set.ts +0 -80
  107. package/src/array/toggle.ts +0 -79
  108. package/src/array/union.ts +0 -72
  109. package/src/array/unique.ts +0 -67
  110. package/src/array/update.ts +0 -75
  111. package/src/beacon.ts +0 -378
  112. package/src/color/constants.ts +0 -137
  113. package/src/color/index.ts +0 -83
  114. package/src/color/instance.ts +0 -162
  115. package/src/color/misc/alpha.ts +0 -56
  116. package/src/color/misc/format.ts +0 -29
  117. package/src/color/misc/get.ts +0 -210
  118. package/src/color/misc/is.ts +0 -221
  119. package/src/color/misc/state.ts +0 -243
  120. package/src/color/models.ts +0 -389
  121. package/src/color/space/hex.ts +0 -184
  122. package/src/color/space/hsl.ts +0 -174
  123. package/src/color/space/hwb.ts +0 -153
  124. package/src/color/space/rgb.ts +0 -240
  125. package/src/function/assert.ts +0 -174
  126. package/src/function/index.ts +0 -2
  127. package/src/function/limit.ts +0 -83
  128. package/src/function/memoize.ts +0 -202
  129. package/src/function/once.ts +0 -200
  130. package/src/function/retry.ts +0 -175
  131. package/src/function/work.ts +0 -1007
  132. package/src/herald.ts +0 -216
  133. package/src/index.ts +0 -68
  134. package/src/internal/array/callbacks.ts +0 -46
  135. package/src/internal/array/chunk.ts +0 -51
  136. package/src/internal/array/compact.ts +0 -56
  137. package/src/internal/array/find.ts +0 -200
  138. package/src/internal/array/group.ts +0 -42
  139. package/src/internal/array/index-of.ts +0 -182
  140. package/src/internal/array/insert.ts +0 -80
  141. package/src/internal/array/overlap.ts +0 -35
  142. package/src/internal/array/sets.ts +0 -74
  143. package/src/internal/array/shuffle.ts +0 -33
  144. package/src/internal/array/update.ts +0 -52
  145. package/src/internal/function/misc.ts +0 -8
  146. package/src/internal/function/timer.ts +0 -168
  147. package/src/internal/is.ts +0 -244
  148. package/src/internal/math/aggregate.ts +0 -164
  149. package/src/internal/math/misc.ts +0 -28
  150. package/src/internal/number.ts +0 -129
  151. package/src/internal/random.ts +0 -49
  152. package/src/internal/result.ts +0 -92
  153. package/src/internal/sized.ts +0 -25
  154. package/src/internal/string.ts +0 -128
  155. package/src/internal/subscription.ts +0 -264
  156. package/src/internal/value/compare.ts +0 -170
  157. package/src/internal/value/equal.ts +0 -465
  158. package/src/internal/value/get.ts +0 -57
  159. package/src/internal/value/handlers.ts +0 -95
  160. package/src/internal/value/has.ts +0 -118
  161. package/src/internal/value/misc.ts +0 -125
  162. package/src/internal/value/partial.ts +0 -46
  163. package/src/internal/value/set.ts +0 -132
  164. package/src/is.ts +0 -182
  165. package/src/logger.ts +0 -230
  166. package/src/math.ts +0 -281
  167. package/src/models.ts +0 -286
  168. package/src/number.ts +0 -1
  169. package/src/promise/delay.ts +0 -62
  170. package/src/promise/helpers.ts +0 -96
  171. package/src/promise/index.ts +0 -300
  172. package/src/promise/misc.ts +0 -96
  173. package/src/promise/models.ts +0 -195
  174. package/src/promise/timed.ts +0 -91
  175. package/src/query.ts +0 -147
  176. package/src/queue.ts +0 -814
  177. package/src/random.ts +0 -125
  178. package/src/result/index.ts +0 -105
  179. package/src/result/match.ts +0 -124
  180. package/src/result/misc.ts +0 -129
  181. package/src/result/models.ts +0 -83
  182. package/src/result/work/flow.ts +0 -488
  183. package/src/result/work/pipe.ts +0 -496
  184. package/src/sized/map.ts +0 -110
  185. package/src/sized/set.ts +0 -107
  186. package/src/string/case.ts +0 -236
  187. package/src/string/fuzzy.ts +0 -444
  188. package/src/string/index.ts +0 -199
  189. package/src/string/match.ts +0 -80
  190. package/src/string/normalize.ts +0 -205
  191. package/src/string/template.ts +0 -161
  192. package/src/value/clone.ts +0 -319
  193. package/src/value/collection.ts +0 -63
  194. package/src/value/diff.ts +0 -232
  195. package/src/value/freeze.ts +0 -322
  196. package/src/value/handle.ts +0 -3
  197. package/src/value/index.ts +0 -5
  198. package/src/value/merge.ts +0 -278
  199. package/src/value/omit.ts +0 -20
  200. package/src/value/pick.ts +0 -20
  201. package/src/value/shake.ts +0 -45
  202. package/src/value/smush.ts +0 -89
  203. package/src/value/transform.ts +0 -153
  204. package/src/value/unsmush.ts +0 -84
@@ -0,0 +1,10 @@
1
+ import { GenericCallback } from "../models.mjs";
2
+ //#region src/internal/abort.d.ts
3
+ type Aborter = {
4
+ callback: GenericCallback;
5
+ signal: AbortSignal;
6
+ cancel: () => void;
7
+ };
8
+ declare function createAborter(value: unknown, onAbort: () => void): Aborter | undefined;
9
+ //#endregion
10
+ export { Aborter, createAborter };
@@ -0,0 +1,14 @@
1
+ //#region src/internal/abort.ts
2
+ function createAborter(value, onAbort) {
3
+ if (!(value instanceof AbortSignal)) return;
4
+ value.addEventListener(ABORT_EVENT, onAbort, ABORT_OPTIONS);
5
+ return {
6
+ callback: onAbort,
7
+ signal: value,
8
+ cancel: () => value.removeEventListener(ABORT_EVENT, onAbort)
9
+ };
10
+ }
11
+ const ABORT_EVENT = "abort";
12
+ const ABORT_OPTIONS = { once: true };
13
+ //#endregion
14
+ export { createAborter };
@@ -15,7 +15,7 @@ function chunk(array, size) {
15
15
  if (!Array.isArray(array)) return [];
16
16
  if (array.length === 0) return [];
17
17
  const { length } = array;
18
- const actualSize = typeof size === "number" && size > 0 && size <= MAX_SIZE ? size : MAX_SIZE;
18
+ const actualSize = typeof size === "number" && size > 0 && size <= CHUNK_MAX_SIZE ? size : CHUNK_MAX_SIZE;
19
19
  if (length <= actualSize) return [array];
20
20
  const chunks = [];
21
21
  let index = 0;
@@ -25,6 +25,6 @@ function chunk(array, size) {
25
25
  }
26
26
  return chunks;
27
27
  }
28
- const MAX_SIZE = 5e3;
28
+ const CHUNK_MAX_SIZE = 5e3;
29
29
  //#endregion
30
30
  export { chunk };
@@ -40,7 +40,7 @@ function findValues(type, array, parameters, mapper) {
40
40
  const { length } = array;
41
41
  const { bool, key, value } = getFindParameters(parameters);
42
42
  const callbacks = getArrayCallbacks(bool, key);
43
- if (type === "unique" && callbacks?.keyed == null && length >= UNIQUE_THRESHOLD) {
43
+ if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
44
44
  result.matched = [...new Set(array)];
45
45
  return result;
46
46
  }
@@ -77,6 +77,6 @@ const FIND_VALUE_INDEX = "index";
77
77
  const FIND_VALUE_ITEM = "item";
78
78
  const FIND_VALUES_ALL = "all";
79
79
  const FIND_VALUES_UNIQUE = "unique";
80
- const UNIQUE_THRESHOLD = 100;
80
+ const FIND_UNIQUE_THRESHOLD = 100;
81
81
  //#endregion
82
82
  export { FIND_VALUES_ALL, FIND_VALUES_UNIQUE, FIND_VALUE_INDEX, FIND_VALUE_ITEM, findAbsoluteValueOrDefault, findValue, findValues, getFindParameters };
@@ -1,8 +1,8 @@
1
1
  //#region src/internal/array/sets.d.ts
2
2
  type CompareSetsType = 'difference' | 'intersection' | 'union';
3
3
  declare function compareSets(type: CompareSetsType, first: unknown[], second: unknown[], key?: unknown): unknown[];
4
- declare const COMPARE_SETS_DIFFERENCE: CompareSetsType;
5
- declare const COMPARE_SETS_INTERSECTION: CompareSetsType;
6
- declare const COMPARE_SETS_UNION: CompareSetsType;
4
+ declare const SETS_COMPARE_DIFFERENCE: CompareSetsType;
5
+ declare const SETS_COMPARE_INTERSECTION: CompareSetsType;
6
+ declare const SETS_COMPARE_UNION: CompareSetsType;
7
7
  //#endregion
8
- export { COMPARE_SETS_DIFFERENCE, COMPARE_SETS_INTERSECTION, COMPARE_SETS_UNION, compareSets };
8
+ export { SETS_COMPARE_DIFFERENCE, SETS_COMPARE_INTERSECTION, SETS_COMPARE_UNION, compareSets };
@@ -2,9 +2,9 @@ import { getArrayCallback } from "./callbacks.mjs";
2
2
  //#region src/internal/array/sets.ts
3
3
  function compareSets(type, first, second, key) {
4
4
  if (!Array.isArray(first)) return [];
5
- const isDifference = type === COMPARE_SETS_DIFFERENCE;
6
- const isIntersection = type === COMPARE_SETS_INTERSECTION;
7
- const isUnion = type === COMPARE_SETS_UNION;
5
+ const isDifference = type === SETS_COMPARE_DIFFERENCE;
6
+ const isIntersection = type === SETS_COMPARE_INTERSECTION;
7
+ const isUnion = type === SETS_COMPARE_UNION;
8
8
  if (first.length === 0) return isDifference ? first.slice() : isIntersection ? [] : second.slice();
9
9
  if (!Array.isArray(second) || second.length === 0) return isIntersection ? [] : first.slice();
10
10
  const callback = getArrayCallback(key);
@@ -25,8 +25,8 @@ function compareSets(type, first, second, key) {
25
25
  }
26
26
  return result;
27
27
  }
28
- const COMPARE_SETS_DIFFERENCE = "difference";
29
- const COMPARE_SETS_INTERSECTION = "intersection";
30
- const COMPARE_SETS_UNION = "union";
28
+ const SETS_COMPARE_DIFFERENCE = "difference";
29
+ const SETS_COMPARE_INTERSECTION = "intersection";
30
+ const SETS_COMPARE_UNION = "union";
31
31
  //#endregion
32
- export { COMPARE_SETS_DIFFERENCE, COMPARE_SETS_INTERSECTION, COMPARE_SETS_UNION, compareSets };
32
+ export { SETS_COMPARE_DIFFERENCE, SETS_COMPARE_INTERSECTION, SETS_COMPARE_UNION, compareSets };
@@ -1,9 +1,16 @@
1
1
  //#region src/internal/function/timer.ts
2
2
  function getAsyncTimer(type, callback, time) {
3
+ function cancel() {
4
+ clearTimer(id);
5
+ if (last != null && !last.running) {
6
+ last.reject();
7
+ last = void 0;
8
+ }
9
+ }
3
10
  async function run(item) {
4
11
  const now = performance.now();
5
12
  start ??= now;
6
- if (interval === 0 || now - start >= interval - OFFSET) {
13
+ if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
7
14
  start = throttle ? now : void 0;
8
15
  item.running = true;
9
16
  try {
@@ -23,7 +30,7 @@ function getAsyncTimer(type, callback, time) {
23
30
  let last;
24
31
  let start;
25
32
  const timer = (...parameters) => {
26
- timer.cancel();
33
+ cancel();
27
34
  const next = {
28
35
  parameters,
29
36
  running: false
@@ -34,25 +41,23 @@ function getAsyncTimer(type, callback, time) {
34
41
  });
35
42
  last = next;
36
43
  if (throttle) run(next);
37
- else id = startTimer(() => {
38
- run(next);
39
- });
44
+ else id = startTimer(() => run(next));
40
45
  return next.promise;
41
46
  };
42
- timer.cancel = () => {
43
- clearTimer(id);
44
- if (last != null && !last.running) last.reject();
45
- };
47
+ Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
46
48
  return timer;
47
49
  }
48
50
  function getInterval(value) {
49
51
  return typeof value === "number" && value > 0 ? value : 0;
50
52
  }
51
53
  function getTimer(type, callback, time) {
54
+ function cancel() {
55
+ clearTimer(id);
56
+ }
52
57
  function run() {
53
58
  const now = performance.now();
54
59
  start ??= now;
55
- if (interval === 0 || now - start >= interval - OFFSET) {
60
+ if (interval === 0 || now - start >= interval - TIMER_OFFSET) {
56
61
  start = throttle ? now : void 0;
57
62
  callback(...args);
58
63
  } else id = startTimer(run);
@@ -63,18 +68,17 @@ function getTimer(type, callback, time) {
63
68
  let id;
64
69
  let start;
65
70
  const timer = (...parameters) => {
66
- timer.cancel();
71
+ cancel();
67
72
  args = parameters;
68
73
  if (throttle) run();
69
74
  else id = startTimer(run);
70
75
  };
71
- timer.cancel = () => {
72
- clearTimer(id);
73
- };
76
+ Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
74
77
  return timer;
75
78
  }
76
- const OFFSET = 5;
79
+ const TIMER_CANCEL = "cancel";
77
80
  const TIMER_DEBOUNCE = "debounce";
81
+ const TIMER_OFFSET = 5;
78
82
  const TIMER_THROTTLE = "throttle";
79
83
  const TIMER_WAIT = "wait";
80
84
  // istanbul ignore next
@@ -59,17 +59,17 @@ function getNumber(value) {
59
59
  if (typeof parsed !== "string") return getNumber(parsed);
60
60
  const trimmed = parsed.trim();
61
61
  if (trimmed.length === 0) return NaN;
62
- if (EXPRESSION_ZEROISH.test(parsed)) return 0;
63
- const isBinary = EXPRESSION_BINARY.test(trimmed);
64
- if (isBinary || EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : OCTAL_VALUE);
62
+ if (NUMBER_EXPRESSION_ZEROISH.test(parsed)) return 0;
63
+ const isBinary = NUMBER_EXPRESSION_BINARY.test(trimmed);
64
+ if (isBinary || NUMBER_EXPRESSION_OCTAL.test(trimmed)) return Number.parseInt(trimmed.slice(2), isBinary ? 2 : NUMBER_OCTAL_VALUE);
65
65
  return Number(trimmed);
66
66
  }
67
67
  function getNumberOrDefault(value, defaultValue, minimum) {
68
68
  return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? Math.floor(value) : defaultValue;
69
69
  }
70
- const EXPRESSION_BINARY = /^0b[01]+$/i;
71
- const EXPRESSION_OCTAL = /^0o[0-7]+$/i;
72
- const EXPRESSION_ZEROISH = /^\s*0+\s*$/;
73
- const OCTAL_VALUE = 8;
70
+ const NUMBER_EXPRESSION_BINARY = /^0b[01]+$/i;
71
+ const NUMBER_EXPRESSION_OCTAL = /^0o[0-7]+$/i;
72
+ const NUMBER_EXPRESSION_ZEROISH = /^\s*0+\s*$/;
73
+ const NUMBER_OCTAL_VALUE = 8;
74
74
  //#endregion
75
75
  export { between, clamp, getNumber, getNumberOrDefault };
@@ -17,9 +17,9 @@ function isResult(value) {
17
17
  }
18
18
  function isResultValue(value, okValue) {
19
19
  if (isNonPlainObject(value)) return false;
20
- return value.ok === okValue && (okValue ? PROPERTY_VALUE : PROPERTY_ERROR) in value;
20
+ return value.ok === okValue && (okValue ? RESULT_PROPERTY_VALUE : RESULT_PROPERTY_ERROR) in value;
21
21
  }
22
- const PROPERTY_ERROR = "error";
23
- const PROPERTY_VALUE = "value";
22
+ const RESULT_PROPERTY_ERROR = "error";
23
+ const RESULT_PROPERTY_VALUE = "value";
24
24
  //#endregion
25
25
  export { isError, isOk, isResult };
@@ -3,10 +3,10 @@ import { clamp } from "./number.mjs";
3
3
  function getSizedMaximum(first, second) {
4
4
  let actual;
5
5
  if (typeof first === "number") actual = first;
6
- else actual = typeof second === "number" ? second : MAXIMUM_DEFAULT;
7
- return clamp(actual, 1, MAXIMUM_ABSOLUTE);
6
+ else actual = typeof second === "number" ? second : SIZED_MAXIMUM_DEFAULT;
7
+ return clamp(actual, 1, SIZED_MAXIMUM_ABSOLUTE);
8
8
  }
9
- const MAXIMUM_ABSOLUTE = 16777216;
10
- const MAXIMUM_DEFAULT = 1048576;
9
+ const SIZED_MAXIMUM_ABSOLUTE = 16777216;
10
+ const SIZED_MAXIMUM_DEFAULT = 1048576;
11
11
  //#endregion
12
12
  export { getSizedMaximum };
@@ -25,7 +25,7 @@ function getString(value) {
25
25
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
26
26
  }
27
27
  function ignoreKey(key) {
28
- return EXPRESSION_IGNORED.test(key);
28
+ return STRING_EXPRESSION_IGNORED.test(key);
29
29
  }
30
30
  function interpolate(strings, values) {
31
31
  const { length } = strings;
@@ -76,9 +76,9 @@ function tryEncode(value) {
76
76
  * @returns Array of words found in the string
77
77
  */
78
78
  function words(value) {
79
- return typeof value === "string" ? value.match(EXPRESSION_WORDS) ?? [] : [];
79
+ return typeof value === "string" ? value.match(STRING_EXPRESSION_WORDS) ?? [] : [];
80
80
  }
81
- const EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
82
- const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
81
+ const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)/i;
82
+ const STRING_EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
83
83
  //#endregion
84
84
  export { getString, ignoreKey, interpolate, join, tryDecode, tryEncode, words };
@@ -12,16 +12,33 @@ type Subscription = {
12
12
  };
13
13
  type SubscriptionParameters = {
14
14
  isActive?: () => boolean;
15
- key?: Key;
16
- property: SubscriptionProperty;
17
- subscriptions: Subscriptions;
15
+ key?: unknown;
16
+ signal?: AbortSignal;
18
17
  value: unknown;
19
18
  };
19
+ /**
20
+ * Property information for subscription identification
21
+ */
20
22
  type SubscriptionProperty = {
23
+ /**
24
+ * Name of the property used to identify a subscription
25
+ */
21
26
  key: string;
22
- value: unknown;
27
+ /**
28
+ * Value of the property used to identify a subscription _(defaults to `subscription`)_
29
+ */
30
+ value?: unknown;
23
31
  };
24
32
  type Subscriptions<Value = unknown> = {
33
+ state: SubscriptionsState<Value>;
34
+ clear: () => void;
35
+ create: (parameters: SubscriptionParameters) => [Subscription, boolean];
36
+ };
37
+ type SubscriptionsParameters = {
38
+ keys?: Set<Key>;
39
+ property: SubscriptionProperty;
40
+ };
41
+ type SubscriptionsState<Value = unknown> = {
25
42
  items: SubscriptionsItems;
26
43
  keys?: Set<Key>;
27
44
  values: SubscriptionsValues<Value>;
@@ -38,9 +55,7 @@ type SubscriptionsValuesItem<MapKey, MapValue> = {
38
55
  any: Map<MapKey, MapValue>;
39
56
  keyed?: Map<Key, Map<MapKey, MapValue>>;
40
57
  };
41
- declare function clearSubscriptions(store: Subscriptions): void;
42
- declare function getSubscription(parameters: SubscriptionParameters): Subscription;
43
- declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptions<Value>;
58
+ declare function createSubscriptions<Value = unknown>(parameters: SubscriptionsParameters): Subscriptions<Value>;
44
59
  /**
45
60
  * Is the value a subscription?
46
61
  *
@@ -48,5 +63,6 @@ declare function getSubscriptions<Value = unknown>(keys?: Set<Key>): Subscriptio
48
63
  * @returns `true` if the value is a subscription, otherwise `false`
49
64
  */
50
65
  declare function isSubscription(value: unknown): value is Subscription;
66
+ declare const SUBSCRIPTION_NAME = "subscription";
51
67
  //#endregion
52
- export { Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions, clearSubscriptions, getSubscription, getSubscriptions, isSubscription };
68
+ export { SUBSCRIPTION_NAME, Subscription, SubscriptionParameters, SubscriptionProperty, Subscriptions, createSubscriptions, isSubscription };
@@ -1,14 +1,16 @@
1
- import { isPlainObject } from "./is.mjs";
1
+ import { isKey, isPlainObject } from "./is.mjs";
2
+ import { createAborter } from "./abort.mjs";
2
3
  //#region src/internal/subscription.ts
3
- function addSubscription(subscription, state) {
4
- const { key, subscriptions, value } = state.parameters;
5
- const { items, values } = subscriptions;
6
- if (key == null) {
4
+ function addSubscription(subscriptions, subscription, state) {
5
+ const { key, value } = state.parameters;
6
+ const { items, values } = subscriptions.state;
7
+ if (!isKey(key)) {
7
8
  items.any.add(subscription);
8
9
  values.from.any.set(value, subscription);
9
10
  values.to.any.set(subscription, value);
10
11
  return;
11
12
  }
13
+ /* istanbul ignore if */
12
14
  if (items.keyed == null || values.from.keyed == null || values.to.keyed == null)
13
15
  // istanbul ignore next
14
16
  return;
@@ -35,41 +37,31 @@ function clearSubscriptions(store) {
35
37
  for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
36
38
  if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
37
39
  }
38
- function getExistingSubscription(state) {
39
- const { parameters } = state;
40
- const { values } = parameters.subscriptions;
41
- return parameters.key == null ? values.from.any.get(parameters.value) : values.from.keyed?.get(parameters.key)?.get(parameters.value);
42
- }
43
- function getSubscription(parameters) {
40
+ function createSubscription(subscriptions, property, parameters) {
41
+ if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
44
42
  const state = {
45
43
  parameters,
46
44
  active: true
47
45
  };
48
- const existing = getExistingSubscription(state);
49
- if (existing != null) return existing;
50
- if (parameters.subscriptions.keys != null && parameters.key != null && !parameters.subscriptions.keys.has(parameters.key)) throw new Error();
51
- const instance = { unsubscribe: () => {
52
- removeSubscription(instance, state);
53
- } };
46
+ const existing = getExistingSubscription(subscriptions, state);
47
+ if (existing != null) return [existing, true];
48
+ if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
49
+ state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
50
+ const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
54
51
  Object.defineProperties(instance, {
55
- [PROPERTY]: {
56
- enumerable: false,
57
- value: true
58
- },
59
- [parameters.property.key]: {
60
- enumerable: false,
61
- value: parameters.property.value
62
- },
52
+ [SUBSCRIPTION_PROPERTY]: { value: true },
53
+ [property.key]: { value: property.value ?? "subscription" },
63
54
  active: {
64
55
  enumerable: true,
65
56
  get: () => (parameters.isActive?.() ?? true) && state.active
66
57
  }
67
58
  });
68
- addSubscription(instance, state);
69
- return Object.freeze(instance);
59
+ addSubscription(subscriptions, instance, state);
60
+ return [Object.freeze(instance), false];
70
61
  }
71
- function getSubscriptions(keys) {
72
- return {
62
+ function createSubscriptions(parameters) {
63
+ const { keys, property } = parameters;
64
+ const state = {
73
65
  keys,
74
66
  items: {
75
67
  any: /* @__PURE__ */ new Set(),
@@ -86,6 +78,17 @@ function getSubscriptions(keys) {
86
78
  }
87
79
  }
88
80
  };
81
+ const instance = {
82
+ state,
83
+ clear: () => clearSubscriptions(state),
84
+ create: (parameters) => createSubscription(instance, property, parameters)
85
+ };
86
+ return instance;
87
+ }
88
+ function getExistingSubscription(subscriptions, state) {
89
+ const { parameters } = state;
90
+ const { values } = subscriptions.state;
91
+ return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
89
92
  }
90
93
  /**
91
94
  * Is the value a subscription?
@@ -94,7 +97,7 @@ function getSubscriptions(keys) {
94
97
  * @returns `true` if the value is a subscription, otherwise `false`
95
98
  */
96
99
  function isSubscription(value) {
97
- return isPlainObject(value) && PROPERTY in value && value[PROPERTY] === true;
100
+ return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
98
101
  }
99
102
  function removeFromStore(items, values, subscription, value, key) {
100
103
  items.delete(subscription);
@@ -106,22 +109,32 @@ function removeFromStore(items, values, subscription, value, key) {
106
109
  values.to.keyed?.get(key)?.delete(subscription);
107
110
  }
108
111
  }
109
- function removeSubscription(subscription, state) {
112
+ function removeSubscription(subscriptions, subscription, state) {
110
113
  if (!state.active) return;
114
+ state.aborter = void 0;
111
115
  state.active = false;
112
- const { key, subscriptions, value } = state.parameters;
113
- const { items, values } = subscriptions;
114
- if (key == null) {
116
+ state.parameters.isActive = void 0;
117
+ state.parameters.signal = void 0;
118
+ const { key, value } = state.parameters;
119
+ const { items, values } = subscriptions.state;
120
+ if (!isKey(key)) {
115
121
  removeFromStore(items.any, values, subscription, value);
116
122
  return;
117
123
  }
118
124
  const keyed = items.keyed?.get(key);
125
+ /* istanbul ignore if */
119
126
  if (items.keyed == null || keyed == null)
120
127
  // istanbul ignore next
121
128
  return;
122
129
  removeFromStore(keyed, values, subscription, value, key);
123
130
  if (keyed.size === 0) items.keyed.delete(key);
124
131
  }
125
- const PROPERTY = "$subscription";
132
+ function unsubscribe(subscriptions, subscription, state) {
133
+ state.aborter?.cancel();
134
+ removeSubscription(subscriptions, subscription, state);
135
+ }
136
+ const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
137
+ const SUBSCRIPTION_NAME = "subscription";
138
+ const SUBSCRIPTION_PROPERTY = "$subscription";
126
139
  //#endregion
127
- export { clearSubscriptions, getSubscription, getSubscriptions, isSubscription };
140
+ export { SUBSCRIPTION_NAME, createSubscriptions, isSubscription };
@@ -60,7 +60,7 @@ function equalPlainObject(first, second, options) {
60
60
  firstKeys = firstKeys.filter((key) => filterKey(key, options));
61
61
  secondKeys = secondKeys.filter((key) => filterKey(key, options));
62
62
  }
63
- const secondSet = secondKeys.length >= MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
63
+ const secondSet = secondKeys.length >= EQUAL_MINIMUM_LENGTH_FOR_SET ? new Set(secondKeys) : void 0;
64
64
  const { length } = firstKeys;
65
65
  if (length !== secondKeys.length) return false;
66
66
  for (let index = 0; index < length; index += 1) {
@@ -105,9 +105,9 @@ function equalValue(first, second, options) {
105
105
  case first instanceof ArrayBuffer && second instanceof ArrayBuffer: return equalArrayBuffer(first, second, options);
106
106
  case first instanceof Date && second instanceof Date: return Object.is(first.getTime(), second.getTime());
107
107
  case first instanceof DataView && second instanceof DataView: return equalDataView(first, second, options);
108
- case first instanceof Error && second instanceof Error: return equalProperties(first, second, ERROR_PROPERTIES, options);
108
+ case first instanceof Error && second instanceof Error: return equalProperties(first, second, EQUAL_ERROR_PROPERTIES, options);
109
109
  case first instanceof Map && second instanceof Map: return equalMap(first, second, options);
110
- case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EXPRESSION_PROPERTIES, options);
110
+ case first instanceof RegExp && second instanceof RegExp: return equalProperties(first, second, EQUAL_EXPRESSION_PROPERTIES, options);
111
111
  case first instanceof Set && second instanceof Set: return equalSet(first, second, options);
112
112
  case Array.isArray(first) && Array.isArray(second): return equalArray(first, second, options);
113
113
  case isPlainObject(first) && isPlainObject(second): return equalPlainObject(first, second, options);
@@ -169,8 +169,8 @@ function registerEqualizer(constructor, handler) {
169
169
  }
170
170
  const EQUAL_ARRAY_PEEK_PERCENTAGE = 10;
171
171
  const EQUAL_ARRAY_THRESHOLD = 100;
172
- const ERROR_PROPERTIES = ["name", "message"];
173
- const EXPRESSION_PROPERTIES = ["source", "flags"];
174
- const MINIMUM_LENGTH_FOR_SET = 16;
172
+ const EQUAL_ERROR_PROPERTIES = ["name", "message"];
173
+ const EQUAL_EXPRESSION_PROPERTIES = ["source", "flags"];
174
+ const EQUAL_MINIMUM_LENGTH_FOR_SET = 16;
175
175
  //#endregion
176
176
  export { deregisterEqualizer, equal, initializeEqualizer, registerEqualizer };
@@ -7,8 +7,8 @@ function findKey(needle, haystack) {
7
7
  return index > -1 ? keys[index] : needle;
8
8
  }
9
9
  function getNestedValue(data, path, ignoreCase) {
10
- if (typeof data !== "object" || data === null) return error(NESTED_MESSAGE_INPUT);
11
- if (typeof path !== "string" || path.trim().length === 0) return error(NESTED_MESSAGE_PATH);
10
+ if (typeof data !== "object" || data === null) return error(MISC_NESTED_MESSAGE_INPUT);
11
+ if (typeof path !== "string" || path.trim().length === 0) return error(MISC_NESTED_MESSAGE_PATH);
12
12
  const shouldIgnoreCase = ignoreCase === true;
13
13
  const paths = getPaths(path, shouldIgnoreCase);
14
14
  if (typeof paths === "string") return handleValue(data, paths, null, true, shouldIgnoreCase);
@@ -24,24 +24,24 @@ function getNestedValue(data, path, ignoreCase) {
24
24
  }
25
25
  function getPaths(path, lowercase) {
26
26
  const normalized = lowercase ? path.toLowerCase() : path;
27
- if (!EXPRESSION_NESTED.test(normalized)) return normalized;
28
- return normalized.replace(EXPRESSION_BRACKET, ".$1").replace(EXPRESSION_DOTS, "").split(".");
27
+ if (!MISC_EXPRESSION_NESTED.test(normalized)) return normalized;
28
+ return normalized.replace(MISC_EXPRESSION_BRACKET, ".$1").replace(MISC_EXPRESSION_DOTS, "").split(".");
29
29
  }
30
30
  function handleValue(data, path, value, get, ignoreCase) {
31
31
  if (typeof data === "object" && data !== null) {
32
- if (ignoreKey(path)) return error(NESTED_MESSAGE_UNSAFE);
32
+ if (ignoreKey(path)) return error(MISC_NESTED_MESSAGE_UNSAFE);
33
33
  const key = ignoreCase ? findKey(path, data) : path;
34
- if (get) return key in data ? ok(data[key]) : error(NESTED_MESSAGE_MISSING);
34
+ if (get) return key in data ? ok(data[key]) : error(MISC_NESTED_MESSAGE_MISSING);
35
35
  data[key] = typeof value === "function" ? value(data[key]) : value;
36
36
  }
37
- if (get) return error(NESTED_MESSAGE_MISSING);
37
+ if (get) return error(MISC_NESTED_MESSAGE_MISSING);
38
38
  }
39
- const EXPRESSION_BRACKET = /\[(\w+)\]/g;
40
- const EXPRESSION_DOTS = /^\.|\.$/g;
41
- const EXPRESSION_NESTED = /\.|\[\w+\]/;
42
- const NESTED_MESSAGE_INPUT = "Expected data to be an object";
43
- const NESTED_MESSAGE_MISSING = "Expected property to exist in object";
44
- const NESTED_MESSAGE_PATH = "Expected path to be a string";
45
- const NESTED_MESSAGE_UNSAFE = "Access to this property is not allowed";
39
+ const MISC_EXPRESSION_BRACKET = /\[(\w+)\]/g;
40
+ const MISC_EXPRESSION_DOTS = /^\.|\.$/g;
41
+ const MISC_EXPRESSION_NESTED = /\.|\[\w+\]/;
42
+ const MISC_NESTED_MESSAGE_INPUT = "Expected data to be an object";
43
+ const MISC_NESTED_MESSAGE_MISSING = "Expected property to exist in object";
44
+ const MISC_NESTED_MESSAGE_PATH = "Expected path to be a string";
45
+ const MISC_NESTED_MESSAGE_UNSAFE = "Access to this property is not allowed";
46
46
  //#endregion
47
47
  export { findKey, getNestedValue, getPaths, handleValue };
@@ -20,7 +20,7 @@ function setValue(data, path, value, ignoreCase) {
20
20
  let next = handleValue(target, currentPath, null, true, shouldIgnoreCase).value;
21
21
  if (typeof next !== "object" || next === null) {
22
22
  const nextPath = paths[index + 1];
23
- if (EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
23
+ if (SET_EXPRESSION_INDEX.test(nextPath)) next = Array.from({ length: Number(nextPath) + 1 }, () => void 0);
24
24
  else next = {};
25
25
  target[currentPath] = next;
26
26
  }
@@ -28,6 +28,6 @@ function setValue(data, path, value, ignoreCase) {
28
28
  }
29
29
  return data;
30
30
  }
31
- const EXPRESSION_INDEX = /^\d+$/;
31
+ const SET_EXPRESSION_INDEX = /^\d+$/;
32
32
  //#endregion
33
33
  export { setValue };
package/dist/logger.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  import { noop } from "./internal/function/misc.mjs";
2
+ import { getString } from "./internal/string.mjs";
2
3
  //#region src/logger.ts
3
4
  function isLogger(value) {
4
- return isLoggerInstance(NAME_LOGGER, value);
5
+ return isLoggerInstance(LOGGER_NAME, value);
5
6
  }
6
7
  function isLoggerInstance(name, value) {
7
- return typeof value === "object" && value !== null && value[KEY_LOGGER] === name;
8
+ return typeof value === "object" && value !== null && value[LOGGER_PROPERTY] === name;
8
9
  }
9
10
  function isTimedLogger(value) {
10
- return isLoggerInstance(NAME_TIMED, value);
11
+ return isLoggerInstance(LOGGER_NAME_TIMED, value);
11
12
  }
12
13
  function timedLogger(label) {
13
14
  function stop() {
@@ -26,35 +27,20 @@ function timedLogger(label) {
26
27
  };
27
28
  const instance = {};
28
29
  Object.defineProperties(instance, {
29
- [KEY_LOGGER]: {
30
- enumerable: false,
31
- value: NAME_TIMED
32
- },
30
+ [LOGGER_PROPERTY]: { value: LOGGER_NAME_TIMED },
33
31
  active: {
34
32
  enumerable: true,
35
- get() {
36
- return state.started && !state.stopped && enabled;
37
- }
38
- },
39
- log: {
40
- enumerable: true,
41
- get() {
42
- return this.active ? logger : noop;
43
- }
33
+ get: () => state.started && !state.stopped && enabled
44
34
  },
45
- stop: {
46
- enumerable: true,
47
- get() {
48
- return instance.active ? stop() : noop;
49
- }
50
- }
35
+ log: { get: () => instance.active ? logger : noop },
36
+ stop: { get: () => instance.active ? stop() : noop }
51
37
  });
52
38
  if (state.started) console.time(label);
53
39
  return Object.freeze(instance);
54
40
  }
55
- const KEY_LOGGER = "$logger";
56
- const NAME_LOGGER = "Logger";
57
- const NAME_TIMED = "TimedLogger";
41
+ const LOGGER_NAME = "Logger";
42
+ const LOGGER_NAME_TIMED = "TimedLogger";
43
+ const LOGGER_PROPERTY = "$logger";
58
44
  const methods = [
59
45
  "debug",
60
46
  "dir",
@@ -73,25 +59,15 @@ const methods = [
73
59
  const Logger = (() => {
74
60
  const instance = {};
75
61
  Object.defineProperties(instance, {
76
- [KEY_LOGGER]: {
77
- enumerable: false,
78
- value: NAME_LOGGER
79
- },
62
+ [LOGGER_PROPERTY]: { value: LOGGER_NAME },
80
63
  enabled: {
81
64
  enumerable: true,
82
- get() {
83
- return enabled;
84
- },
85
- set(value) {
65
+ get: () => enabled,
66
+ set: (value) => {
86
67
  enabled = typeof value === "boolean" ? value : enabled;
87
68
  }
88
69
  },
89
- time: {
90
- enumerable: true,
91
- value(label) {
92
- return timedLogger(label);
93
- }
94
- }
70
+ time: { value: (label) => timedLogger(getString(label)) }
95
71
  });
96
72
  for (const method of methods) Object.defineProperty(instance, method, {
97
73
  enumerable: true,