@oscarpalmer/atoms 0.197.0 → 0.199.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/index.mjs CHANGED
@@ -16,10 +16,18 @@ function getArrayCallbacks(bool, key, value) {
16
16
  }
17
17
  //#endregion
18
18
  //#region src/internal/array/find.ts
19
+ function createFindParameters(original) {
20
+ const { length } = original;
21
+ return {
22
+ bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
23
+ key: length === 2 ? original[0] : void 0,
24
+ value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
25
+ };
26
+ }
19
27
  function findValue(type, array, parameters, reversed) {
20
28
  const findIndex = type === FIND_VALUE_INDEX;
21
29
  if (!Array.isArray(array) || array.length === 0) return findIndex ? -1 : void 0;
22
- const { bool, key, value } = getFindParameters(parameters);
30
+ const { bool, key, value } = createFindParameters(parameters);
23
31
  const callbacks = getArrayCallbacks(bool, key);
24
32
  if (callbacks?.bool == null && callbacks?.keyed == null) {
25
33
  if (findIndex) return reversed ? array.lastIndexOf(value) : array.indexOf(value);
@@ -54,7 +62,7 @@ function findValues(type, array, parameters, mapper) {
54
62
  };
55
63
  if (!Array.isArray(array) || array.length === 0) return result;
56
64
  const { length } = array;
57
- const { bool, key, value } = getFindParameters(parameters);
65
+ const { bool, key, value } = createFindParameters(parameters);
58
66
  const callbacks = getArrayCallbacks(bool, key);
59
67
  if (type === "unique" && callbacks?.keyed == null && length >= FIND_UNIQUE_THRESHOLD) {
60
68
  result.matched = [...new Set(array)];
@@ -81,14 +89,6 @@ function findValues(type, array, parameters, mapper) {
81
89
  }
82
90
  return result;
83
91
  }
84
- function getFindParameters(original) {
85
- const { length } = original;
86
- return {
87
- bool: length === 1 && typeof original[0] === "function" ? original[0] : void 0,
88
- key: length === 2 ? original[0] : void 0,
89
- value: length === 1 && typeof original[0] !== "function" ? original[0] : original[1]
90
- };
91
- }
92
92
  const FIND_VALUE_INDEX = "index";
93
93
  const FIND_VALUE_ITEM = "item";
94
94
  const FIND_VALUES_UNIQUE = "unique";
@@ -1043,8 +1043,8 @@ const STRING_EXPRESSION_IGNORED = /(^|\.)(__proto__|constructor|prototype)(\.|$)
1043
1043
  const STRING_EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
1044
1044
  //#endregion
1045
1045
  //#region src/internal/value/handlers.ts
1046
- function getCompareHandlers(owner, options) {
1047
- const handlers = getHandlers(owner, options);
1046
+ function createCompareHandlers(owner, options) {
1047
+ const handlers = createHandlers(owner, options);
1048
1048
  return {
1049
1049
  deregister(constructor) {
1050
1050
  handlers.deregister(constructor);
@@ -1059,7 +1059,7 @@ function getCompareHandlers(owner, options) {
1059
1059
  }
1060
1060
  };
1061
1061
  }
1062
- function getHandlers(owner, options) {
1062
+ function createHandlers(owner, options) {
1063
1063
  const handlers = /* @__PURE__ */ new WeakMap();
1064
1064
  return {
1065
1065
  deregister(constructor) {
@@ -1077,8 +1077,8 @@ function getHandlers(owner, options) {
1077
1077
  }
1078
1078
  };
1079
1079
  }
1080
- function getSelfHandlers(owner, options) {
1081
- const handlers = getHandlers(owner, options);
1080
+ function createSelfHandlers(owner, options) {
1081
+ const handlers = createHandlers(owner, options);
1082
1082
  return {
1083
1083
  deregister(constructor) {
1084
1084
  handlers.deregister(constructor);
@@ -1174,7 +1174,7 @@ const comparators = {
1174
1174
  number: compareNumbers,
1175
1175
  symbol: compareSymbols
1176
1176
  };
1177
- const compareHandlers = getCompareHandlers(compare, {
1177
+ const compareHandlers = createCompareHandlers(compare, {
1178
1178
  callback: (first, second, compareStrings) => compareStrings ? getString(first).localeCompare(getString(second)) : void 0,
1179
1179
  method: COMPARE_NAME
1180
1180
  });
@@ -1431,6 +1431,14 @@ Object.defineProperty(toRecord, "arrays", { value: toRecordArrays });
1431
1431
  */
1432
1432
  function noop() {}
1433
1433
  //#endregion
1434
+ //#region src/internal/defaults.ts
1435
+ function getBooleanOrDefault(value, defaultValue) {
1436
+ return typeof value === "boolean" ? value : defaultValue;
1437
+ }
1438
+ function getNumberOrDefault(value, defaultValue, minimum) {
1439
+ return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? value : defaultValue;
1440
+ }
1441
+ //#endregion
1434
1442
  //#region src/internal/function/timer.ts
1435
1443
  function getAsyncTimer(type, callback, time) {
1436
1444
  function cancel() {
@@ -1457,7 +1465,7 @@ function getAsyncTimer(type, callback, time) {
1457
1465
  }
1458
1466
  } else id = startTimer(() => run(item));
1459
1467
  }
1460
- const interval = getInterval(time);
1468
+ const interval = getNumberOrDefault(time, 0);
1461
1469
  const throttle = type === TIMER_THROTTLE;
1462
1470
  let id;
1463
1471
  let last;
@@ -1480,9 +1488,6 @@ function getAsyncTimer(type, callback, time) {
1480
1488
  Object.defineProperty(timer, TIMER_CANCEL, { value: () => cancel() });
1481
1489
  return timer;
1482
1490
  }
1483
- function getInterval(value) {
1484
- return typeof value === "number" && value > 0 ? value : 0;
1485
- }
1486
1491
  function getTimer(type, callback, time) {
1487
1492
  function cancel() {
1488
1493
  clearTimer(id);
@@ -1495,7 +1500,7 @@ function getTimer(type, callback, time) {
1495
1500
  callback(...args);
1496
1501
  } else id = startTimer(run);
1497
1502
  }
1498
- const interval = getInterval(time);
1503
+ const interval = getNumberOrDefault(time, 0);
1499
1504
  const throttle = type === TIMER_THROTTLE;
1500
1505
  let args;
1501
1506
  let id;
@@ -1933,7 +1938,7 @@ async function asyncRetry(callback, options) {
1933
1938
  }
1934
1939
  }
1935
1940
  }
1936
- const { delay, times, when } = getRetryOptions(options);
1941
+ const { delay, times, when } = createRetryOptions(options);
1937
1942
  const timer = getTimer(TIMER_WAIT, handle, delay);
1938
1943
  let attempts = 0;
1939
1944
  let rejector;
@@ -1944,14 +1949,11 @@ async function asyncRetry(callback, options) {
1944
1949
  handle();
1945
1950
  });
1946
1951
  }
1947
- function getRetryNumber(value) {
1948
- return typeof value === "number" && value > 0 ? value : 0;
1949
- }
1950
- function getRetryOptions(input) {
1952
+ function createRetryOptions(input) {
1951
1953
  const options = isPlainObject(input) ? input : {};
1952
1954
  return {
1953
- delay: getRetryNumber(options.delay),
1954
- times: getRetryNumber(options.times),
1955
+ delay: getNumberOrDefault(options.delay, 0),
1956
+ times: getNumberOrDefault(options.times, 0),
1955
1957
  when: typeof options.when === "function" ? options.when : shouldRetry
1956
1958
  };
1957
1959
  }
@@ -1964,7 +1966,7 @@ function getRetryOptions(input) {
1964
1966
  */
1965
1967
  function retry(callback, options) {
1966
1968
  if (typeof callback !== "function") throw new TypeError(RETRY_MESSAGE_EXPECTATION);
1967
- const { times, when } = getRetryOptions(options);
1969
+ const { times, when } = createRetryOptions(options);
1968
1970
  let last;
1969
1971
  for (let index = 0; index <= times; index += 1) try {
1970
1972
  return callback();
@@ -2183,11 +2185,11 @@ var SizedMap = class extends Map {
2183
2185
  };
2184
2186
  //#endregion
2185
2187
  //#region src/internal/function/memoize.ts
2186
- function getMemoizationOptions(input) {
2188
+ function createMemoizationOptions(input) {
2187
2189
  const { cacheKey, cacheSize } = isPlainObject(input) ? input : {};
2188
2190
  return {
2189
2191
  cacheKey: typeof cacheKey === "function" ? cacheKey : void 0,
2190
- cacheSize: typeof cacheSize === "number" && cacheSize > 0 ? cacheSize : MEMOIZED_CACHE_SIZE_DEFAULT
2192
+ cacheSize: getNumberOrDefault(cacheSize, MEMOIZED_CACHE_SIZE_DEFAULT)
2191
2193
  };
2192
2194
  }
2193
2195
  /**
@@ -2202,7 +2204,7 @@ function memoize(callback, options) {
2202
2204
  const state = {
2203
2205
  cache: void 0,
2204
2206
  getter: void 0,
2205
- options: getMemoizationOptions(options)
2207
+ options: createMemoizationOptions(options)
2206
2208
  };
2207
2209
  state.cache = new SizedMap(state.options.cacheSize);
2208
2210
  state.getter = (...parameters) => {
@@ -2371,6 +2373,32 @@ let memoizedTitleCase;
2371
2373
  let memoizedUpperCase;
2372
2374
  //#endregion
2373
2375
  //#region src/internal/value/equal.ts
2376
+ function createEqualOptions(input) {
2377
+ const options = {
2378
+ ignoreCase: false,
2379
+ ignoreExpressions: {
2380
+ enabled: false,
2381
+ values: []
2382
+ },
2383
+ ignoreKeys: {
2384
+ enabled: false,
2385
+ values: /* @__PURE__ */ new Set()
2386
+ },
2387
+ relaxedNullish: false
2388
+ };
2389
+ if (typeof input === "boolean") {
2390
+ options.ignoreCase = input;
2391
+ return options;
2392
+ }
2393
+ if (isNonPlainObject(input)) return options;
2394
+ options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
2395
+ options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
2396
+ options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
2397
+ options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
2398
+ options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
2399
+ options.relaxedNullish = input.relaxedNullish === true;
2400
+ return options;
2401
+ }
2374
2402
  /**
2375
2403
  * Deregister a equality comparison handler for a specific class
2376
2404
  *
@@ -2388,9 +2416,9 @@ function filterKey(key, options) {
2388
2416
  return true;
2389
2417
  }
2390
2418
  function equal(first, second, options) {
2391
- return equalValue(first, second, getEqualOptions(options));
2419
+ return equalValue(first, second, createEqualOptions(options));
2392
2420
  }
2393
- equal.handlers = getCompareHandlers(equal, { callback: Object.is });
2421
+ equal.handlers = createCompareHandlers(equal, { callback: Object.is });
2394
2422
  equal.deregister = deregisterEqualizer;
2395
2423
  equal.initialize = initializeEqualizer;
2396
2424
  equal.register = registerEqualizer;
@@ -2485,32 +2513,6 @@ function equalValue(first, second, options) {
2485
2513
  default: return equal.handlers.handle(first, second, options);
2486
2514
  }
2487
2515
  }
2488
- function getEqualOptions(input) {
2489
- const options = {
2490
- ignoreCase: false,
2491
- ignoreExpressions: {
2492
- enabled: false,
2493
- values: []
2494
- },
2495
- ignoreKeys: {
2496
- enabled: false,
2497
- values: /* @__PURE__ */ new Set()
2498
- },
2499
- relaxedNullish: false
2500
- };
2501
- if (typeof input === "boolean") {
2502
- options.ignoreCase = input;
2503
- return options;
2504
- }
2505
- if (isNonPlainObject(input)) return options;
2506
- options.ignoreCase = typeof input.ignoreCase === "boolean" ? input.ignoreCase : false;
2507
- options.ignoreExpressions.values = (Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => key instanceof RegExp);
2508
- options.ignoreKeys.values = new Set((Array.isArray(input.ignoreKeys) ? input.ignoreKeys : [input.ignoreKeys]).filter((key) => typeof key === "string"));
2509
- options.ignoreExpressions.enabled = options.ignoreExpressions.values.length > 0;
2510
- options.ignoreKeys.enabled = options.ignoreKeys.values.size > 0;
2511
- options.relaxedNullish = input.relaxedNullish === true;
2512
- return options;
2513
- }
2514
2516
  /**
2515
2517
  * Create an equalizer with predefined options
2516
2518
  *
@@ -2520,7 +2522,7 @@ function getEqualOptions(input) {
2520
2522
  * @returns Equalizer function
2521
2523
  */
2522
2524
  function initializeEqualizer(options) {
2523
- const actual = getEqualOptions(options);
2525
+ const actual = createEqualOptions(options);
2524
2526
  const equalizer = (first, second) => equalValue(first, second, actual);
2525
2527
  equalizer.deregister = deregisterEqualizer;
2526
2528
  equalizer.register = registerEqualizer;
@@ -2592,14 +2594,6 @@ function createAborter(value, onAbort) {
2592
2594
  const ABORT_EVENT = "abort";
2593
2595
  const ABORT_OPTIONS = { once: true };
2594
2596
  //#endregion
2595
- //#region src/internal/defaults.ts
2596
- function getBooleanOrDefault(value, defaultValue) {
2597
- return typeof value === "boolean" ? value : defaultValue;
2598
- }
2599
- function getNumberOrDefault(value, defaultValue, minimum) {
2600
- return typeof value === "number" && !Number.isNaN(value) && value >= (minimum ?? 0) ? value : defaultValue;
2601
- }
2602
- //#endregion
2603
2597
  //#region src/promise/constants.ts
2604
2598
  const PROMISE_ERROR_NAME = "PromiseTimeoutError";
2605
2599
  const PROMISE_MESSAGE_EXPECTATION_ATTEMPT = "Attempt expected a function or a promise";
@@ -2646,7 +2640,7 @@ var PromiseTimeoutError = class extends Error {
2646
2640
  };
2647
2641
  //#endregion
2648
2642
  //#region src/promise/helpers.ts
2649
- function getPromiseOptions(input) {
2643
+ function createPromiseOptions(input) {
2650
2644
  if (typeof input === "number") return { time: getNumberOrDefault(input, 0) };
2651
2645
  if (input instanceof AbortSignal) return {
2652
2646
  signal: input,
@@ -2658,7 +2652,7 @@ function getPromiseOptions(input) {
2658
2652
  time: getNumberOrDefault(options.time, 0)
2659
2653
  };
2660
2654
  }
2661
- function getPromisesOptions(input) {
2655
+ function createPromisesOptions(input) {
2662
2656
  if (typeof input === "string") return { strategy: getStrategyOrDefault(input) };
2663
2657
  if (input instanceof AbortSignal) return {
2664
2658
  signal: input,
@@ -2752,7 +2746,7 @@ async function toResult(value) {
2752
2746
  //#endregion
2753
2747
  //#region src/promise/delay.ts
2754
2748
  function delay(options) {
2755
- const { signal, time } = getPromiseOptions(options);
2749
+ const { signal, time } = createPromiseOptions(options);
2756
2750
  if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
2757
2751
  const aborter = createAborter(signal, () => {
2758
2752
  timer.cancel();
@@ -2789,7 +2783,7 @@ async function getTimedPromise(promise, time, signal) {
2789
2783
  }
2790
2784
  async function timed(promise, options) {
2791
2785
  if (!(promise instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_TIMED));
2792
- const { signal, time } = getPromiseOptions(options);
2786
+ const { signal, time } = createPromiseOptions(options);
2793
2787
  if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
2794
2788
  return time > 0 ? getTimedPromise(promise, time, signal) : promise;
2795
2789
  }
@@ -2798,7 +2792,7 @@ async function timed(promise, options) {
2798
2792
  async function attemptPromise(value, options) {
2799
2793
  const isFunction = typeof value === "function";
2800
2794
  if (!isFunction && !(value instanceof Promise)) return Promise.reject(/* @__PURE__ */ new TypeError(PROMISE_MESSAGE_EXPECTATION_ATTEMPT));
2801
- const { signal, time } = getPromiseOptions(options);
2795
+ const { signal, time } = createPromiseOptions(options);
2802
2796
  if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
2803
2797
  const aborter = createAborter(signal, () => {
2804
2798
  rejector(signal?.reason);
@@ -2820,7 +2814,7 @@ async function attemptPromise(value, options) {
2820
2814
  return time > 0 ? getTimedPromise(promise, time, signal) : promise;
2821
2815
  }
2822
2816
  async function promises(items, options) {
2823
- const { signal, strategy } = getPromisesOptions(options);
2817
+ const { signal, strategy } = createPromisesOptions(options);
2824
2818
  if (signal?.aborted ?? false) return Promise.reject(signal?.reason);
2825
2819
  if (!Array.isArray(items)) return Promise.resolve([]);
2826
2820
  const actual = items.map((item) => typeof item === "function" ? item() : item).filter((item) => item instanceof Promise);
@@ -3001,20 +2995,7 @@ const MATCH_STARTS_WITH = "startsWith";
3001
2995
  const matchMemoizers = {};
3002
2996
  //#endregion
3003
2997
  //#region src/string/fuzzy.ts
3004
- function getHandler(input) {
3005
- if (input == null || input === getString) return getString;
3006
- switch (typeof input) {
3007
- case "function": return input;
3008
- case "string": return (item) => item[input];
3009
- default:
3010
- if (isPlainObject(input)) return getHandler(input.key ?? input.handler);
3011
- throw new TypeError(FUZZY_MESSAGE_HANDLER);
3012
- }
3013
- }
3014
- function getFuzzyItems(items) {
3015
- return items.sort((first, second) => first.haystack.localeCompare(second.haystack)).map(({ item }) => item);
3016
- }
3017
- function getFuzzyOptions(input, state) {
2998
+ function createFuzzyOptions(input, state) {
3018
2999
  const options = isPlainObject(input) ? input : {};
3019
3000
  const limit = typeof input === "number" ? input : options.limit;
3020
3001
  if (typeof limit === "number" && !Number.isNaN(limit) && limit >= 1) options.limit = Math.floor(limit);
@@ -3022,9 +3003,9 @@ function getFuzzyOptions(input, state) {
3022
3003
  options.tolerance = getTolerance(options.tolerance, state);
3023
3004
  return options;
3024
3005
  }
3025
- function getFuzzyState(items, input) {
3006
+ function createFuzzyState(items, input) {
3026
3007
  const handler = getHandler(input);
3027
- const options = getFuzzyOptions(input);
3008
+ const options = createFuzzyOptions(input);
3028
3009
  return {
3029
3010
  handler,
3030
3011
  items: items.slice(),
@@ -3033,14 +3014,27 @@ function getFuzzyState(items, input) {
3033
3014
  tolerance: options.tolerance
3034
3015
  };
3035
3016
  }
3017
+ function getHandler(input) {
3018
+ if (input == null || input === getString) return getString;
3019
+ switch (typeof input) {
3020
+ case "function": return input;
3021
+ case "string": return (item) => item[input];
3022
+ default:
3023
+ if (isPlainObject(input)) return getHandler(input.key ?? input.handler);
3024
+ throw new TypeError(FUZZY_MESSAGE_HANDLER);
3025
+ }
3026
+ }
3027
+ function getFuzzyItems(items) {
3028
+ return items.sort((first, second) => first.haystack.localeCompare(second.haystack)).map(({ item }) => item);
3029
+ }
3036
3030
  function getTolerance(input, state) {
3037
3031
  if (typeof input === "number" && !Number.isNaN(input)) return input < 0 ? 0 : Math.floor(input);
3038
3032
  return state?.tolerance ?? FUZZY_PROXIMITY_THRESHOLD;
3039
3033
  }
3040
3034
  function fuzzy(items, configuration) {
3041
3035
  if (!Array.isArray(items)) throw new TypeError(FUZZY_MESSAGE_ARRAY);
3042
- const state = getFuzzyState(items, configuration);
3043
- const instance = { search: (value, options) => search(state.items, state.strings, value, options == null ? state : getFuzzyOptions(options, state)) };
3036
+ const state = createFuzzyState(items, configuration);
3037
+ const instance = { search: (value, options) => search(state.items, state.strings, value, options == null ? state : createFuzzyOptions(options, state)) };
3044
3038
  Object.defineProperties(instance, {
3045
3039
  items: {
3046
3040
  enumerable: true,
@@ -3258,6 +3252,16 @@ const STRING_NUMERICAL_PREFIX_PATTERN = /^\d/;
3258
3252
  const STRING_ZERO = "0";
3259
3253
  //#endregion
3260
3254
  //#region src/string/normalize.ts
3255
+ function createNormalizeOptions(input) {
3256
+ const options = isPlainObject(input) ? input : {};
3257
+ return {
3258
+ deburr: options.deburr !== false,
3259
+ lowerCase: options.lowerCase !== false,
3260
+ special: options.special === true,
3261
+ trim: options.trim !== false,
3262
+ whitespace: options.whitespace !== false
3263
+ };
3264
+ }
3261
3265
  /**
3262
3266
  * Deburr a string, removing diacritical marks
3263
3267
  *
@@ -3273,16 +3277,6 @@ function deburr(value) {
3273
3277
  });
3274
3278
  return deburrMemoizer.run(value);
3275
3279
  }
3276
- function getNormalizeOptions(input) {
3277
- const options = isPlainObject(input) ? input : {};
3278
- return {
3279
- deburr: options.deburr !== false,
3280
- lowerCase: options.lowerCase !== false,
3281
- special: options.special === true,
3282
- trim: options.trim !== false,
3283
- whitespace: options.whitespace !== false
3284
- };
3285
- }
3286
3280
  /**
3287
3281
  * Initialize a string normalizer
3288
3282
  *
@@ -3292,7 +3286,7 @@ function getNormalizeOptions(input) {
3292
3286
  * @returns Normalizer function
3293
3287
  */
3294
3288
  function initializeNormalizer(options) {
3295
- const normalization = getNormalizeOptions(options);
3289
+ const normalization = createNormalizeOptions(options);
3296
3290
  return (value) => normalizeString(value, normalization);
3297
3291
  }
3298
3292
  /**
@@ -3305,7 +3299,7 @@ function initializeNormalizer(options) {
3305
3299
  * @returns Normalized string
3306
3300
  */
3307
3301
  function normalize(value, options) {
3308
- return normalizeString(value, getNormalizeOptions(options));
3302
+ return normalizeString(value, createNormalizeOptions(options));
3309
3303
  }
3310
3304
  function normalizeString(value, options) {
3311
3305
  if (typeof value !== "string") return "";
@@ -3362,18 +3356,18 @@ normalize.initialize = initializeNormalizer;
3362
3356
  Object.defineProperty(normalize, "initialize", { value: initializeNormalizer });
3363
3357
  //#endregion
3364
3358
  //#region src/string/template.ts
3365
- function getRenderer(strings, values) {
3366
- return (variables, options) => {
3367
- return template(interpolate(strings, values), variables, options);
3368
- };
3369
- }
3370
- function getTemplateOptions(input) {
3359
+ function createTemplateOptions(input) {
3371
3360
  const options = isPlainObject(input) ? input : {};
3372
3361
  return {
3373
3362
  ignoreCase: options.ignoreCase === true,
3374
3363
  pattern: options.pattern instanceof RegExp ? options.pattern : TEMPLATE_EXPRESSION_VARIABLE
3375
3364
  };
3376
3365
  }
3366
+ function getRenderer(strings, values) {
3367
+ return (variables, options) => {
3368
+ return template(interpolate(strings, values), variables, options);
3369
+ };
3370
+ }
3377
3371
  function handleTemplate(value, pattern, ignoreCase, variables) {
3378
3372
  if (typeof value !== "string") return "";
3379
3373
  if (typeof variables !== "object" || variables === null || Object.keys(variables).length === 0) return value;
@@ -3395,14 +3389,14 @@ function handleTemplate(value, pattern, ignoreCase, variables) {
3395
3389
  * @returns _Templater_ function
3396
3390
  */
3397
3391
  function initializeTemplater(options) {
3398
- const { ignoreCase, pattern } = getTemplateOptions(options);
3392
+ const { ignoreCase, pattern } = createTemplateOptions(options);
3399
3393
  return ((value, ...parameters) => {
3400
3394
  return isTemplateStringsArray(value) ? (variables) => handleTemplate(interpolate(value, parameters), pattern, ignoreCase, variables) : handleTemplate(value, pattern, ignoreCase, parameters[0]);
3401
3395
  });
3402
3396
  }
3403
3397
  function template(value, ...parameters) {
3404
3398
  if (isTemplateStringsArray(value)) return getRenderer(value, parameters);
3405
- const { ignoreCase, pattern } = getTemplateOptions(parameters[1]);
3399
+ const { ignoreCase, pattern } = createTemplateOptions(parameters[1]);
3406
3400
  return handleTemplate(value, pattern, ignoreCase, parameters[0]);
3407
3401
  }
3408
3402
  const TEMPLATE_EXPRESSION_VARIABLE = /{{([\s\S]+?)}}/g;
@@ -3412,33 +3406,22 @@ Object.defineProperty(template, "initialize", { value: initializeTemplater });
3412
3406
  //#region src/value/clone.ts
3413
3407
  const CLONE_NAME = "clone";
3414
3408
  function clone(value, options) {
3415
- switch (true) {
3416
- case value === null:
3417
- case value === void 0:
3418
- case typeof value === "bigint":
3419
- case typeof value === "boolean":
3420
- case typeof value === "number":
3421
- case typeof value === "string": return value;
3422
- case value instanceof Date: return new Date(value.getTime());
3423
- default: return cloneAny(value, getCloneParameters(options), 0);
3424
- }
3409
+ return cloneAny(value, { copy: false }, 0, options);
3425
3410
  }
3426
- clone.handlers = getSelfHandlers(clone, {
3427
- callback: tryStructuredClone,
3428
- method: CLONE_NAME
3429
- });
3430
- clone.deregister = deregisterCloner;
3431
- clone.register = registerCloner;
3432
- function cloneAny(value, parameters, depth) {
3411
+ function cloneAny(value, parameters, depth, options) {
3433
3412
  switch (true) {
3434
- case value == null:
3435
- case typeof value === "bigint":
3436
- case typeof value === "boolean":
3437
- case typeof value === "number":
3438
- case typeof value === "string": return value;
3413
+ case value === null || CLONE_PRIMITIVES[typeof value]: return value;
3439
3414
  case value instanceof Date: return new Date(value.getTime());
3440
- case typeof value === "function": return parameters.options?.copyFunctions ? value : void 0;
3441
- case typeof value === "symbol": return parameters.options?.copySymbols ? value : Symbol(value.description);
3415
+ case typeof value === "function":
3416
+ parameters.options ??= createCloneOptions(options);
3417
+ return parameters.options.copyFunctions ? value : void 0;
3418
+ case typeof value === "symbol":
3419
+ parameters.options ??= createCloneOptions(options);
3420
+ return parameters.options.copySymbols ? value : Symbol(value.description);
3421
+ }
3422
+ parameters.options ??= createCloneOptions(options);
3423
+ parameters.references ??= /* @__PURE__ */ new WeakMap();
3424
+ switch (true) {
3442
3425
  case parameters.references.has(value): return parameters.references.get(value);
3443
3426
  case value instanceof ArrayBuffer: return cloneArrayBuffer(value, parameters, depth);
3444
3427
  case value instanceof DataView: return cloneDataView(value, parameters, depth);
@@ -3448,18 +3431,18 @@ function cloneAny(value, parameters, depth) {
3448
3431
  case value instanceof Set: return cloneSet(value, parameters, depth);
3449
3432
  case isArrayOrPlainObject(value): return cloneObject(value, parameters, depth);
3450
3433
  case isTypedArray(value): return cloneTypedArray(value, parameters, depth);
3451
- default: return clone.handlers.handle(value, parameters, depth);
3434
+ default: return parameters.copy ? value : clone.handlers.handle(value, parameters, depth);
3452
3435
  }
3453
3436
  }
3454
3437
  function cloneArrayBuffer(value, parameters, depth) {
3455
- if (depth >= CLONE_MAX_DEPTH) return value;
3438
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3456
3439
  const cloned = new ArrayBuffer(value.byteLength);
3457
3440
  new Uint8Array(cloned).set(new Uint8Array(value));
3458
3441
  parameters.references.set(value, cloned);
3459
3442
  return cloned;
3460
3443
  }
3461
3444
  function cloneDataView(value, parameters, depth) {
3462
- if (depth >= CLONE_MAX_DEPTH) return value;
3445
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3463
3446
  const buffer = cloneArrayBuffer(value.buffer, parameters, depth);
3464
3447
  const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
3465
3448
  parameters.references.set(value, cloned);
@@ -3467,22 +3450,22 @@ function cloneDataView(value, parameters, depth) {
3467
3450
  }
3468
3451
  function cloneMap(map, parameters, depth) {
3469
3452
  if (depth >= CLONE_MAX_DEPTH) return map;
3470
- const flat = parameters.options?.flat;
3453
+ if (parameters.copy) return new Map(map);
3471
3454
  const cloned = /* @__PURE__ */ new Map();
3472
- const entries = map.entries();
3473
- for (const entry of entries) cloned.set(flat ? entry[0] : cloneAny(entry[0], parameters, depth + 1), flat ? entry[1] : cloneAny(entry[1], parameters, depth + 1));
3455
+ for (const [key, value] of map.entries()) cloned.set(cloneAny(key, parameters, depth + 1), cloneAny(value, parameters, depth + 1));
3474
3456
  parameters.references.set(map, cloned);
3475
3457
  return cloned;
3476
3458
  }
3477
3459
  function cloneNode(node, parameters, depth) {
3478
- if (depth >= CLONE_MAX_DEPTH) return node;
3460
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return node;
3479
3461
  const cloned = node.cloneNode(true);
3480
3462
  parameters.references.set(node, cloned);
3481
3463
  return cloned;
3482
3464
  }
3483
3465
  function cloneObject(value, parameters, depth) {
3466
+ if (depth >= CLONE_MAX_DEPTH) return value;
3484
3467
  const isArray = Array.isArray(value);
3485
- if (parameters.options?.flat || depth >= CLONE_MAX_DEPTH) return isArray ? value.slice() : { ...value };
3468
+ if (parameters.copy) return isArray ? value.slice() : { ...value };
3486
3469
  const cloned = isArray ? [] : {};
3487
3470
  const keys = isArray ? void 0 : Object.keys(value);
3488
3471
  const { length } = keys ?? value;
@@ -3494,7 +3477,7 @@ function cloneObject(value, parameters, depth) {
3494
3477
  return cloned;
3495
3478
  }
3496
3479
  function cloneRegularExpression(value, parameters, depth) {
3497
- if (depth >= CLONE_MAX_DEPTH) return value;
3480
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3498
3481
  const cloned = new RegExp(value.source, value.flags);
3499
3482
  cloned.lastIndex = value.lastIndex;
3500
3483
  parameters.references.set(value, cloned);
@@ -3502,30 +3485,31 @@ function cloneRegularExpression(value, parameters, depth) {
3502
3485
  }
3503
3486
  function cloneSet(set, parameters, depth) {
3504
3487
  if (depth >= CLONE_MAX_DEPTH) return set;
3488
+ if (parameters.copy) return new Set(set);
3505
3489
  const cloned = /* @__PURE__ */ new Set();
3506
- const values = [...set.values()];
3507
- const { length } = values;
3508
- for (let index = 0; index < length; index += 1) cloned.add(parameters.options?.flat ? values[index] : cloneAny(values[index], parameters, depth + 1));
3490
+ for (const value of set.values()) cloned.add(cloneAny(value, parameters, depth + 1));
3509
3491
  parameters.references.set(set, cloned);
3510
3492
  return cloned;
3511
3493
  }
3512
3494
  function cloneTypedArray(value, parameters, depth) {
3513
- if (depth >= CLONE_MAX_DEPTH) return value;
3495
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3514
3496
  const cloned = new value.constructor(value);
3515
3497
  parameters.references.set(value, cloned);
3516
3498
  return cloned;
3517
3499
  }
3518
- /**
3519
- * Copy any kind of value
3520
- *
3521
- * - Clones the value shallowly, without cloning nested values
3522
- * - To copy a value deeply, use `clone` instead
3523
- *
3524
- * @param value Value to copy
3525
- * @returns Copied value
3526
- */
3527
3500
  function copy(value) {
3528
- return clone(value, CLONE_COPY_OPTIONS);
3501
+ return cloneAny(value, {
3502
+ copy: true,
3503
+ options: CLONE_COPY_OPTIONS,
3504
+ references: void 0
3505
+ }, 0);
3506
+ }
3507
+ function createCloneOptions(input) {
3508
+ if (typeof input !== "object" || input === null) return CLONE_DEFAULT_OPTIONS;
3509
+ return {
3510
+ copyFunctions: input.copyFunctions === true,
3511
+ copySymbols: input.copySymbols === true
3512
+ };
3529
3513
  }
3530
3514
  /**
3531
3515
  * Deregister a clone handler for a specific class
@@ -3537,24 +3521,29 @@ function copy(value) {
3537
3521
  function deregisterCloner(constructor) {
3538
3522
  clone.handlers.deregister(constructor);
3539
3523
  }
3540
- function getCloneOptions(input) {
3541
- if (typeof input === "boolean") return {
3542
- copyFunctions: false,
3543
- copySymbols: false,
3544
- flat: input === true
3545
- };
3546
- if (typeof input !== "object" || input === null) return CLONE_DEFAULT_OPTIONS;
3547
- return {
3548
- copyFunctions: input.copyFunctions === true,
3549
- copySymbols: input.copySymbols === true,
3550
- flat: input.flat === true
3551
- };
3552
- }
3553
- function getCloneParameters(input) {
3554
- return {
3555
- options: getCloneOptions(input),
3556
- references: /* @__PURE__ */ new WeakMap()
3557
- };
3524
+ /**
3525
+ * Create a cloner with predefined options
3526
+ *
3527
+ * _Available as `initializeCloner` and `clone.initialize`_
3528
+ *
3529
+ * @param options Clone options
3530
+ * @returns Cloner function
3531
+ */
3532
+ function initializeCloner(options) {
3533
+ const opts = createCloneOptions(options);
3534
+ function cloner(value) {
3535
+ return cloneAny(value, {
3536
+ copy: false,
3537
+ options: opts
3538
+ }, 0);
3539
+ }
3540
+ cloner.deregister = deregisterCloner;
3541
+ cloner.register = registerCloner;
3542
+ Object.defineProperties(cloner, {
3543
+ deregister: { value: deregisterCloner },
3544
+ register: { value: registerCloner }
3545
+ });
3546
+ return cloner;
3558
3547
  }
3559
3548
  /**
3560
3549
  * Register a clone handler for a specific class
@@ -3571,24 +3560,46 @@ function tryStructuredClone(value, parameters, depth) {
3571
3560
  if (depth >= CLONE_MAX_DEPTH) return value;
3572
3561
  try {
3573
3562
  const cloned = structuredClone(value);
3574
- parameters.references?.set(value, cloned);
3563
+ parameters.references.set(value, cloned);
3575
3564
  return cloned;
3576
3565
  } catch {
3577
- parameters.references?.set(value, value);
3566
+ parameters.references.set(value, value);
3578
3567
  return value;
3579
3568
  }
3580
3569
  }
3581
3570
  const CLONE_COPY_OPTIONS = {
3582
3571
  copyFunctions: true,
3583
- copySymbols: true,
3584
- flat: true
3572
+ copySymbols: true
3585
3573
  };
3586
3574
  const CLONE_DEFAULT_OPTIONS = {
3587
3575
  copyFunctions: false,
3588
- copySymbols: false,
3589
- flat: false
3576
+ copySymbols: false
3590
3577
  };
3591
3578
  const CLONE_MAX_DEPTH = 100;
3579
+ const cloneHandlers = createSelfHandlers(clone, {
3580
+ callback: tryStructuredClone,
3581
+ method: CLONE_NAME
3582
+ });
3583
+ const CLONE_PRIMITIVES = {
3584
+ bigint: true,
3585
+ boolean: true,
3586
+ function: false,
3587
+ number: true,
3588
+ object: false,
3589
+ string: true,
3590
+ symbol: false,
3591
+ undefined: true
3592
+ };
3593
+ clone.deregister = deregisterCloner;
3594
+ clone.handlers = cloneHandlers;
3595
+ clone.initialize = initializeCloner;
3596
+ clone.register = registerCloner;
3597
+ Object.defineProperties(clone, {
3598
+ deregister: { value: deregisterCloner },
3599
+ handlers: { value: cloneHandlers },
3600
+ initialize: { value: initializeCloner },
3601
+ register: { value: registerCloner }
3602
+ });
3592
3603
  //#endregion
3593
3604
  //#region src/value/collection.ts
3594
3605
  function inMap(map, value, key) {
@@ -3937,11 +3948,11 @@ function unsmush(value) {
3937
3948
  * @returns Assigned value
3938
3949
  */
3939
3950
  function assign(to, from, options) {
3940
- const actual = getMergeOptions(options);
3951
+ const actual = createMergeOptions(options);
3941
3952
  actual.assignValues = true;
3942
3953
  return mergeValues([to, ...from], actual);
3943
3954
  }
3944
- function getMergeOptions(options) {
3955
+ function createMergeOptions(options) {
3945
3956
  const actual = {
3946
3957
  assignValues: false,
3947
3958
  replaceableObjects: void 0,
@@ -3968,7 +3979,7 @@ function getReplaceableObjects(value) {
3968
3979
  * @returns Assigner function
3969
3980
  */
3970
3981
  function initializeAssigner(options) {
3971
- const actual = getMergeOptions(options);
3982
+ const actual = createMergeOptions(options);
3972
3983
  actual.assignValues = true;
3973
3984
  return ((to, from) => mergeValues([to, ...from], actual));
3974
3985
  }
@@ -3981,7 +3992,7 @@ function initializeAssigner(options) {
3981
3992
  * @returns Merger function
3982
3993
  */
3983
3994
  function initializeMerger(options) {
3984
- const actual = getMergeOptions(options);
3995
+ const actual = createMergeOptions(options);
3985
3996
  return ((values) => mergeValues(values, actual));
3986
3997
  }
3987
3998
  /**
@@ -3992,7 +4003,7 @@ function initializeMerger(options) {
3992
4003
  * @returns Merged value
3993
4004
  */
3994
4005
  function merge(values, options) {
3995
- return mergeValues(values, getMergeOptions(options));
4006
+ return mergeValues(values, createMergeOptions(options));
3996
4007
  }
3997
4008
  function mergeObjects(values, options, destination, prefix) {
3998
4009
  const { length } = values;
@@ -4067,8 +4078,8 @@ Object.defineProperty(transform, "initialize", { value: initializeTransformer })
4067
4078
  //#endregion
4068
4079
  //#region src/internal/subscription.ts
4069
4080
  function addSubscription(subscriptions, subscription, state) {
4081
+ const { items, values } = subscriptions;
4070
4082
  const { key, value } = state.parameters;
4071
- const { items, values } = subscriptions.state;
4072
4083
  if (!isKey(key)) {
4073
4084
  items.any.add(subscription);
4074
4085
  values.from.any.set(value, subscription);
@@ -4102,7 +4113,8 @@ function clearSubscriptions(store) {
4102
4113
  for (const susbcription of store.values.to.any.keys()) susbcription.unsubscribe();
4103
4114
  if (store.values.to.keyed != null) for (const values of store.values.to.keyed.values()) for (const susbcription of values.keys()) susbcription.unsubscribe();
4104
4115
  }
4105
- function createSubscription(subscriptions, property, parameters) {
4116
+ function createSubscription(subscriptions, property, params) {
4117
+ const parameters = createSubscriptionParameters(params);
4106
4118
  if (parameters.signal?.aborted ?? false) throw new Error(parameters.signal?.reason);
4107
4119
  const state = {
4108
4120
  parameters,
@@ -4110,12 +4122,15 @@ function createSubscription(subscriptions, property, parameters) {
4110
4122
  };
4111
4123
  const existing = getExistingSubscription(subscriptions, state);
4112
4124
  if (existing != null) return [existing, true];
4113
- if (subscriptions.state.keys != null && isKey(parameters.key) && !subscriptions.state.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
4125
+ if (subscriptions.keys != null && isKey(parameters.key)) {
4126
+ if (subscriptions.keys === false) throw new Error(SUBSCRIPTION_DISALLOWED_KEY);
4127
+ else if (subscriptions.keys !== true && !subscriptions.keys.has(parameters.key)) throw new Error(SUBSCRIPTION_INVALID_KEY);
4128
+ }
4114
4129
  state.aborter = createAborter(parameters.signal, () => unsubscribe(subscriptions, instance, state));
4115
4130
  const instance = { unsubscribe: () => unsubscribe(subscriptions, instance, state) };
4116
4131
  Object.defineProperties(instance, {
4117
- [SUBSCRIPTION_PROPERTY]: { value: true },
4118
- [property.key]: { value: property.value ?? "subscription" },
4132
+ [SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_NAME },
4133
+ [property.key]: { value: property.value },
4119
4134
  active: {
4120
4135
  enumerable: true,
4121
4136
  get: () => (parameters.isActive?.() ?? true) && state.active
@@ -4124,36 +4139,56 @@ function createSubscription(subscriptions, property, parameters) {
4124
4139
  addSubscription(subscriptions, instance, state);
4125
4140
  return [Object.freeze(instance), false];
4126
4141
  }
4127
- function createSubscriptions(parameters) {
4128
- const { keys, property } = parameters;
4129
- const state = {
4142
+ function getExistingSubscription(subscriptions, state) {
4143
+ const { values } = subscriptions;
4144
+ const { parameters } = state;
4145
+ return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
4146
+ }
4147
+ function createSubscriptionParameters(input) {
4148
+ const values = isPlainObject(input) ? input : {};
4149
+ if (values.value == null) throw new Error(SUBSCRIPTION_INVALID_VALUE);
4150
+ return {
4151
+ isActive: typeof values.isActive === "function" ? values.isActive : void 0,
4152
+ key: isKey(values.key) ? values.key : void 0,
4153
+ signal: values.signal instanceof AbortSignal ? values.signal : void 0,
4154
+ value: values.value
4155
+ };
4156
+ }
4157
+ function createSubscriptionsParameters(input) {
4158
+ const values = isPlainObject(input) ? input : {};
4159
+ let keys;
4160
+ if (values.keys instanceof Set) keys = values.keys;
4161
+ else keys = typeof values.keys === "boolean" ? values.keys : false;
4162
+ return {
4163
+ keys,
4164
+ property: createSubscriptionsProperty(values.property)
4165
+ };
4166
+ }
4167
+ function createSubscriptionsProperty(input) {
4168
+ const values = isPlainObject(input) ? input : {};
4169
+ return {
4170
+ key: typeof values.key === "string" ? values.key : SUBSCRIPTION_PROPERTY,
4171
+ value: values.value == null ? SUBSCRIPTION_NAME : values.value
4172
+ };
4173
+ }
4174
+ function createSubscriptionsState(keys) {
4175
+ return {
4130
4176
  keys,
4131
4177
  items: {
4132
4178
  any: /* @__PURE__ */ new Set(),
4133
- keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
4179
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
4134
4180
  },
4135
4181
  values: {
4136
4182
  from: {
4137
4183
  any: /* @__PURE__ */ new Map(),
4138
- keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
4184
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
4139
4185
  },
4140
4186
  to: {
4141
4187
  any: /* @__PURE__ */ new Map(),
4142
- keyed: keys == null ? void 0 : /* @__PURE__ */ new Map()
4188
+ keyed: keys === false ? void 0 : /* @__PURE__ */ new Map()
4143
4189
  }
4144
4190
  }
4145
4191
  };
4146
- const instance = {
4147
- state,
4148
- clear: () => clearSubscriptions(state),
4149
- create: (parameters) => createSubscription(instance, property, parameters)
4150
- };
4151
- return instance;
4152
- }
4153
- function getExistingSubscription(subscriptions, state) {
4154
- const { parameters } = state;
4155
- const { values } = subscriptions.state;
4156
- return isKey(parameters.key) ? values.from.keyed?.get(parameters.key)?.get(parameters.value) : values.from.any.get(parameters.value);
4157
4192
  }
4158
4193
  /**
4159
4194
  * Is the value a subscription?
@@ -4162,7 +4197,19 @@ function getExistingSubscription(subscriptions, state) {
4162
4197
  * @returns `true` if the value is a subscription, otherwise `false`
4163
4198
  */
4164
4199
  function isSubscription(value) {
4165
- return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === true;
4200
+ return isSubscriptionInstance(value, SUBSCRIPTION_NAME);
4201
+ }
4202
+ function isSubscriptionInstance(value, name) {
4203
+ return isPlainObject(value) && SUBSCRIPTION_PROPERTY in value && value[SUBSCRIPTION_PROPERTY] === name;
4204
+ }
4205
+ /**
4206
+ * Is the value a subscriptions store?
4207
+ *
4208
+ * @param value Value to check
4209
+ * @returns `true` if the value is a subscriptions store, otherwise `false`
4210
+ */
4211
+ function isSubscriptions(value) {
4212
+ return isSubscriptionInstance(value, SUBSCRIPTION_STORE);
4166
4213
  }
4167
4214
  function removeFromStore(items, values, subscription, value, key) {
4168
4215
  items.delete(subscription);
@@ -4174,14 +4221,14 @@ function removeFromStore(items, values, subscription, value, key) {
4174
4221
  values.to.keyed?.get(key)?.delete(subscription);
4175
4222
  }
4176
4223
  }
4177
- function removeSubscription(subscriptions, subscription, state) {
4224
+ function removeSubscription(subscriptionsState, subscription, state) {
4178
4225
  if (!state.active) return;
4179
4226
  state.aborter = void 0;
4180
4227
  state.active = false;
4181
4228
  state.parameters.isActive = void 0;
4182
4229
  state.parameters.signal = void 0;
4230
+ const { items, values } = subscriptionsState;
4183
4231
  const { key, value } = state.parameters;
4184
- const { items, values } = subscriptions.state;
4185
4232
  if (!isKey(key)) {
4186
4233
  removeFromStore(items.any, values, subscription, value);
4187
4234
  return;
@@ -4194,12 +4241,42 @@ function removeSubscription(subscriptions, subscription, state) {
4194
4241
  removeFromStore(keyed, values, subscription, value, key);
4195
4242
  if (keyed.size === 0) items.keyed.delete(key);
4196
4243
  }
4197
- function unsubscribe(subscriptions, subscription, state) {
4244
+ /**
4245
+ * Create a subscription store
4246
+ *
4247
+ * @param parameters Store parameters
4248
+ * @returns Subscription store
4249
+ */
4250
+ function subscriptions(parameters) {
4251
+ const { keys, property } = createSubscriptionsParameters(parameters);
4252
+ const state = createSubscriptionsState(keys);
4253
+ const instance = {
4254
+ clear: () => clearSubscriptions(state),
4255
+ create: (parameters) => createSubscription(state, property, parameters)
4256
+ };
4257
+ Object.defineProperties(instance, {
4258
+ [SUBSCRIPTION_PROPERTY]: { value: SUBSCRIPTION_STORE },
4259
+ items: {
4260
+ enumerable: true,
4261
+ value: state.items
4262
+ },
4263
+ values: {
4264
+ enumerable: true,
4265
+ value: state.values
4266
+ }
4267
+ });
4268
+ return Object.freeze(instance);
4269
+ }
4270
+ function unsubscribe(subscriptionsState, subscription, state) {
4198
4271
  state.aborter?.cancel();
4199
- removeSubscription(subscriptions, subscription, state);
4272
+ removeSubscription(subscriptionsState, subscription, state);
4200
4273
  }
4274
+ const SUBSCRIPTION_DISALLOWED_KEY = "Disallowed key for subscription";
4201
4275
  const SUBSCRIPTION_INVALID_KEY = "Invalid key for subscription";
4202
- const SUBSCRIPTION_PROPERTY = "$subscription";
4276
+ const SUBSCRIPTION_INVALID_VALUE = "A subscription requires a non-null value to identify it";
4277
+ const SUBSCRIPTION_NAME = "subscription";
4278
+ const SUBSCRIPTION_PROPERTY = "$subscriptions";
4279
+ const SUBSCRIPTION_STORE = "subscriptions";
4203
4280
  //#endregion
4204
4281
  //#region src/beacon.ts
4205
4282
  /**
@@ -4214,8 +4291,8 @@ function beacon(value, options) {
4214
4291
  value,
4215
4292
  active: true,
4216
4293
  observable: void 0,
4217
- options: getBeaconOptions(options),
4218
- subscriptions: createSubscriptions({ property: beaconSubscription })
4294
+ options: createBeaconOptions(options),
4295
+ subscriptions: subscriptions({ property: beaconSubscription })
4219
4296
  };
4220
4297
  const instance = {
4221
4298
  deactivate: () => finishBeacon(state, false),
@@ -4240,28 +4317,32 @@ function beacon(value, options) {
4240
4317
  });
4241
4318
  return Object.freeze(instance);
4242
4319
  }
4243
- function finishBeacon(state, emit) {
4244
- if (!state.active) return;
4245
- state.active = false;
4246
- for (const [, observer] of state.subscriptions.state.values.to.any) if (emit) observer.complete?.();
4247
- state.subscriptions.clear();
4248
- state.observable?.deactivate();
4249
- state.observable = void 0;
4250
- }
4251
- function getBeaconOptions(input) {
4320
+ function createBeaconOptions(input) {
4252
4321
  const options = isPlainObject(input) ? input : {};
4253
4322
  options.equal = typeof options.equal === "function" ? options.equal : Object.is;
4254
4323
  return options;
4255
4324
  }
4256
- function getObservable(state) {
4257
- if (!state.active) throw new Error(BEACON_MESSAGE_RETRIEVE);
4258
- state.observable ??= observeBeacon(state);
4259
- return state.observable;
4260
- }
4261
- function getObservableCallback(value) {
4262
- return typeof value === "function" ? value : noop;
4325
+ function createObservable(beacon) {
4326
+ const state = {
4327
+ beacon,
4328
+ active: beacon.active
4329
+ };
4330
+ const instance = {
4331
+ deactivate: () => {
4332
+ state.active = false;
4333
+ },
4334
+ subscribe: (first, second, third) => subscribeToObservable(state, first, second, third)
4335
+ };
4336
+ Object.defineProperties(instance, {
4337
+ [BEACON_PROPERTY]: { value: BEACON_OBSERVABLE },
4338
+ active: {
4339
+ enumerable: true,
4340
+ get: () => beacon.active && state.active
4341
+ }
4342
+ });
4343
+ return Object.freeze(instance);
4263
4344
  }
4264
- function getObserver(first, second, third) {
4345
+ function createObserver(first, second, third) {
4265
4346
  let observer = { next: noop };
4266
4347
  if (typeof first === "function") observer = {
4267
4348
  error: getObservableCallback(second),
@@ -4275,6 +4356,22 @@ function getObserver(first, second, third) {
4275
4356
  }
4276
4357
  return observer;
4277
4358
  }
4359
+ function finishBeacon(state, emit) {
4360
+ if (!state.active) return;
4361
+ state.active = false;
4362
+ for (const [, observer] of state.subscriptions.values.to.any) if (emit) observer.complete?.();
4363
+ state.subscriptions.clear();
4364
+ state.observable?.deactivate();
4365
+ state.observable = void 0;
4366
+ }
4367
+ function getObservable(state) {
4368
+ if (!state.active) throw new Error(BEACON_MESSAGE_RETRIEVE);
4369
+ state.observable ??= createObservable(state);
4370
+ return state.observable;
4371
+ }
4372
+ function getObservableCallback(value) {
4373
+ return typeof value === "function" ? value : noop;
4374
+ }
4278
4375
  /**
4279
4376
  * Is the value a beacon?
4280
4377
  *
@@ -4305,29 +4402,9 @@ function isBeaconSubscription(value) {
4305
4402
  function isObservable(value) {
4306
4403
  return isBeaconInstance(BEACON_OBSERVABLE, value);
4307
4404
  }
4308
- function observeBeacon(beacon) {
4309
- const state = {
4310
- beacon,
4311
- active: beacon.active
4312
- };
4313
- const instance = {
4314
- deactivate: () => {
4315
- state.active = false;
4316
- },
4317
- subscribe: (first, second, third) => subscribeToObservable(state, first, second, third)
4318
- };
4319
- Object.defineProperties(instance, {
4320
- [BEACON_PROPERTY]: { value: BEACON_OBSERVABLE },
4321
- active: {
4322
- enumerable: true,
4323
- get: () => beacon.active && state.active
4324
- }
4325
- });
4326
- return Object.freeze(instance);
4327
- }
4328
4405
  function subscribeToObservable(state, first, second, third) {
4329
4406
  if (!state.beacon.active || !state.active) throw new Error(BEACON_MESSAGE_SUBSCRIBE);
4330
- const observer = getObserver(first, second, third);
4407
+ const observer = createObserver(first, second, third);
4331
4408
  const [subscription] = state.beacon.subscriptions.create({
4332
4409
  isActive: () => state.beacon.active && state.active,
4333
4410
  value: observer
@@ -4341,7 +4418,7 @@ function updateBeacon(type, state, value, finish) {
4341
4418
  if (state.options.equal(state.value, value)) return;
4342
4419
  state.value = value;
4343
4420
  }
4344
- for (const [, observer] of state.subscriptions.state.values.to.any) observer[type]?.(value);
4421
+ for (const [, observer] of state.subscriptions.values.to.any) observer[type]?.(value);
4345
4422
  if (finish === true) finishBeacon(state, true);
4346
4423
  }
4347
4424
  const BEACON_MESSAGE_RETRIEVE = "Cannot retrieve observable from a closed beacon";
@@ -4351,7 +4428,10 @@ const BEACON_NAME = "beacon";
4351
4428
  const BEACON_OBSERVABLE = "observable";
4352
4429
  const BEACON_TYPE_ERROR = "error";
4353
4430
  const BEACON_TYPE_NEXT = "next";
4354
- const beaconSubscription = { key: BEACON_PROPERTY };
4431
+ const beaconSubscription = {
4432
+ key: BEACON_PROPERTY,
4433
+ value: SUBSCRIPTION_NAME
4434
+ };
4355
4435
  //#endregion
4356
4436
  //#region src/internal/herald.ts
4357
4437
  function createEvents(herald, state) {
@@ -4360,34 +4440,34 @@ function createEvents(herald, state) {
4360
4440
  for (const key of state.keys) events[key] = (callback, signal) => herald.subscribe(key, callback, signal);
4361
4441
  return Object.freeze(events);
4362
4442
  }
4363
- function emitForHerald(state, event, ...parameters) {
4364
- const items = state.subscriptions.state.values.from.keyed?.get(event);
4365
- if (items == null || items.size === 0) return;
4366
- for (const [callback] of items) callback(...parameters);
4367
- }
4368
- function getHeraldSubscriptionProperty(input) {
4369
- if (input == null) return heraldSubscription;
4370
- const property = isPlainObject(input) ? input : {};
4371
- if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
4372
- return {
4373
- key: property.key,
4374
- value: property.value
4375
- };
4376
- }
4377
- function getHeraldState(input) {
4443
+ function createHeraldState(input) {
4378
4444
  const options = isPlainObject(input) ? input : {};
4379
4445
  if (!Array.isArray(options.names) || options.names.length === 0 || !options.names.every((name) => typeof name === "string")) throw new Error(HERALD_MESSAGE_ARRAY);
4380
4446
  if (options.onCreate != null && typeof options.onCreate !== "function") throw new Error(HERALD_MESSAGE_ONCREATE);
4381
4447
  const keys = new Set(options.names);
4382
4448
  return {
4383
4449
  keys,
4384
- subscriptions: createSubscriptions({
4450
+ store: subscriptions({
4385
4451
  keys,
4386
- property: getHeraldSubscriptionProperty(options.property)
4452
+ property: createHeraldSubscriptionProperty(options.property)
4387
4453
  }),
4388
4454
  onCreate: options.onCreate
4389
4455
  };
4390
4456
  }
4457
+ function createHeraldSubscriptionProperty(input) {
4458
+ if (input == null) return heraldSubscription;
4459
+ const property = isPlainObject(input) ? input : {};
4460
+ if (typeof property.key !== "string" || property.value != null && typeof property.value !== "string") throw new Error(HERALD_MESSAGE_PROPERTY);
4461
+ return {
4462
+ key: property.key,
4463
+ value: property.value
4464
+ };
4465
+ }
4466
+ function emitForHerald(state, event, ...parameters) {
4467
+ const items = state.store.values.from.keyed?.get(event);
4468
+ if (items == null || items.size === 0) return;
4469
+ for (const [callback] of items) callback(...parameters);
4470
+ }
4391
4471
  /**
4392
4472
  * Create a _Herald_ for announcing named events
4393
4473
  *
@@ -4396,11 +4476,11 @@ function getHeraldState(input) {
4396
4476
  * @returns _Herald_ instance
4397
4477
  */
4398
4478
  function herald(options) {
4399
- const state = getHeraldState(options);
4479
+ const state = createHeraldState(options);
4400
4480
  const instance = {
4401
- clear: () => state.subscriptions.clear(),
4481
+ clear: () => state.store.clear(),
4402
4482
  emit: (event, ...parameters) => emitForHerald(state, event, ...parameters),
4403
- observed: (event) => (state.subscriptions.state.items.keyed?.get(event)?.size ?? 0) > 0,
4483
+ observed: (event) => (state.store.items.keyed?.get(event)?.size ?? 0) > 0,
4404
4484
  subscribe: (key, callback, signal) => subscribeToHerald(state, key, callback, signal)
4405
4485
  };
4406
4486
  Object.defineProperties(instance, {
@@ -4443,7 +4523,7 @@ function isHeraldSubscription(value) {
4443
4523
  return isSubscription(value) && value[HERALD_PROPERTY] === "subscription";
4444
4524
  }
4445
4525
  function subscribeToHerald(state, key, callback, signal) {
4446
- const [subscription, existing] = state.subscriptions.create({
4526
+ const [subscription, existing] = state.store.create({
4447
4527
  key,
4448
4528
  signal,
4449
4529
  value: callback
@@ -4457,7 +4537,10 @@ const HERALD_MESSAGE_ONCREATE = `Herald requires a valid onCreate callback for s
4457
4537
  const HERALD_MESSAGE_PROPERTY = `Herald requires valid property information for subscription identification`;
4458
4538
  const HERALD_NAME_EVENTS = "events";
4459
4539
  const HERALD_NAME_HERALD = "herald";
4460
- const heraldSubscription = { key: HERALD_PROPERTY };
4540
+ const heraldSubscription = {
4541
+ key: HERALD_PROPERTY,
4542
+ value: SUBSCRIPTION_NAME
4543
+ };
4461
4544
  //#endregion
4462
4545
  //#region src/color/constants.ts
4463
4546
  const COLOR_ALPHA = {
@@ -5546,22 +5629,22 @@ function color(value) {
5546
5629
  enumerable: true,
5547
5630
  value: changes.events
5548
5631
  },
5549
- hex: getColorProperty(COLOR_TYPE.hex, instance, state, changes, false),
5550
- hexa: getColorProperty(COLOR_TYPE.hex, instance, state, changes, true),
5551
- hsl: getColorProperty(COLOR_TYPE.hsl, instance, state, changes, false),
5552
- hsla: getColorProperty(COLOR_TYPE.hsl, instance, state, changes, true),
5553
- hwb: getColorProperty(COLOR_TYPE.hwb, instance, state, changes, false),
5554
- hwba: getColorProperty(COLOR_TYPE.hwb, instance, state, changes, true),
5632
+ hex: createColorProperty(COLOR_TYPE.hex, instance, state, changes, false),
5633
+ hexa: createColorProperty(COLOR_TYPE.hex, instance, state, changes, true),
5634
+ hsl: createColorProperty(COLOR_TYPE.hsl, instance, state, changes, false),
5635
+ hsla: createColorProperty(COLOR_TYPE.hsl, instance, state, changes, true),
5636
+ hwb: createColorProperty(COLOR_TYPE.hwb, instance, state, changes, false),
5637
+ hwba: createColorProperty(COLOR_TYPE.hwb, instance, state, changes, true),
5555
5638
  origin: {
5556
5639
  enumerable: true,
5557
5640
  get: () => state.origin
5558
5641
  },
5559
- rgb: getColorProperty(COLOR_TYPE.rgb, instance, state, changes, false),
5560
- rgba: getColorProperty(COLOR_TYPE.rgb, instance, state, changes, true)
5642
+ rgb: createColorProperty(COLOR_TYPE.rgb, instance, state, changes, false),
5643
+ rgba: createColorProperty(COLOR_TYPE.rgb, instance, state, changes, true)
5561
5644
  });
5562
5645
  return Object.freeze(instance);
5563
5646
  }
5564
- function getColorProperty(space, color, state, changes, alpha) {
5647
+ function createColorProperty(space, color, state, changes, alpha) {
5565
5648
  const setValue = setters[space];
5566
5649
  return {
5567
5650
  enumerable: true,
@@ -5586,7 +5669,10 @@ function onCreateSubscription(instance, event, callback) {
5586
5669
  function setAlphaValue(state, value) {
5587
5670
  if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value, false);
5588
5671
  }
5589
- const colorSubscription = { key: COLOR_PROPERTY.name };
5672
+ const colorSubscription = {
5673
+ key: COLOR_PROPERTY.name,
5674
+ value: SUBSCRIPTION_NAME
5675
+ };
5590
5676
  const setters = {
5591
5677
  hex: setHexColor,
5592
5678
  hsl: setHSLColor,
@@ -6002,7 +6088,7 @@ function createQueue(callback, options, key) {
6002
6088
  handled: [],
6003
6089
  id: 0,
6004
6090
  items: [],
6005
- options: getOptions(options),
6091
+ options: createQueueOptions(options),
6006
6092
  paused: !getBooleanOrDefault(options?.autostart, true),
6007
6093
  runners: 0
6008
6094
  };
@@ -6052,7 +6138,7 @@ function createQueue(callback, options, key) {
6052
6138
  });
6053
6139
  return Object.freeze(instance);
6054
6140
  }
6055
- function getOptions(input) {
6141
+ function createQueueOptions(input) {
6056
6142
  const options = typeof input === "object" && input != null ? input : {};
6057
6143
  return {
6058
6144
  autostart: getBooleanOrDefault(options.autostart, true),
@@ -6130,7 +6216,7 @@ function keyedQueue(callback, options) {
6130
6216
  if (typeof callback !== "function") throw new TypeError(QUEUE_MESSAGE_CALLBACK);
6131
6217
  const state = {
6132
6218
  callback,
6133
- options: getOptions(options),
6219
+ options: createQueueOptions(options),
6134
6220
  queues: /* @__PURE__ */ new Map()
6135
6221
  };
6136
6222
  const instance = {
@@ -6383,4 +6469,4 @@ var SizedSet = class extends Set {
6383
6469
  }
6384
6470
  };
6385
6471
  //#endregion
6386
- export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
6472
+ export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeCloner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isSubscriptions, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, subscriptions, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };