@oscarpalmer/atoms 0.197.0 → 0.198.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
@@ -3412,33 +3412,22 @@ Object.defineProperty(template, "initialize", { value: initializeTemplater });
3412
3412
  //#region src/value/clone.ts
3413
3413
  const CLONE_NAME = "clone";
3414
3414
  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
- }
3415
+ return cloneAny(value, { copy: false }, 0, options);
3425
3416
  }
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) {
3417
+ function cloneAny(value, parameters, depth, options) {
3433
3418
  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;
3419
+ case value === null || CLONE_PRIMITIVES[typeof value]: return value;
3439
3420
  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);
3421
+ case typeof value === "function":
3422
+ parameters.options ??= getCloneOptions(options);
3423
+ return parameters.options.copyFunctions ? value : void 0;
3424
+ case typeof value === "symbol":
3425
+ parameters.options ??= getCloneOptions(options);
3426
+ return parameters.options.copySymbols ? value : Symbol(value.description);
3427
+ }
3428
+ parameters.options ??= getCloneOptions(options);
3429
+ parameters.references ??= /* @__PURE__ */ new WeakMap();
3430
+ switch (true) {
3442
3431
  case parameters.references.has(value): return parameters.references.get(value);
3443
3432
  case value instanceof ArrayBuffer: return cloneArrayBuffer(value, parameters, depth);
3444
3433
  case value instanceof DataView: return cloneDataView(value, parameters, depth);
@@ -3448,18 +3437,18 @@ function cloneAny(value, parameters, depth) {
3448
3437
  case value instanceof Set: return cloneSet(value, parameters, depth);
3449
3438
  case isArrayOrPlainObject(value): return cloneObject(value, parameters, depth);
3450
3439
  case isTypedArray(value): return cloneTypedArray(value, parameters, depth);
3451
- default: return clone.handlers.handle(value, parameters, depth);
3440
+ default: return parameters.copy ? value : clone.handlers.handle(value, parameters, depth);
3452
3441
  }
3453
3442
  }
3454
3443
  function cloneArrayBuffer(value, parameters, depth) {
3455
- if (depth >= CLONE_MAX_DEPTH) return value;
3444
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3456
3445
  const cloned = new ArrayBuffer(value.byteLength);
3457
3446
  new Uint8Array(cloned).set(new Uint8Array(value));
3458
3447
  parameters.references.set(value, cloned);
3459
3448
  return cloned;
3460
3449
  }
3461
3450
  function cloneDataView(value, parameters, depth) {
3462
- if (depth >= CLONE_MAX_DEPTH) return value;
3451
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3463
3452
  const buffer = cloneArrayBuffer(value.buffer, parameters, depth);
3464
3453
  const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
3465
3454
  parameters.references.set(value, cloned);
@@ -3467,22 +3456,22 @@ function cloneDataView(value, parameters, depth) {
3467
3456
  }
3468
3457
  function cloneMap(map, parameters, depth) {
3469
3458
  if (depth >= CLONE_MAX_DEPTH) return map;
3470
- const flat = parameters.options?.flat;
3459
+ if (parameters.copy) return new Map(map);
3471
3460
  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));
3461
+ for (const [key, value] of map.entries()) cloned.set(cloneAny(key, parameters, depth + 1), cloneAny(value, parameters, depth + 1));
3474
3462
  parameters.references.set(map, cloned);
3475
3463
  return cloned;
3476
3464
  }
3477
3465
  function cloneNode(node, parameters, depth) {
3478
- if (depth >= CLONE_MAX_DEPTH) return node;
3466
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return node;
3479
3467
  const cloned = node.cloneNode(true);
3480
3468
  parameters.references.set(node, cloned);
3481
3469
  return cloned;
3482
3470
  }
3483
3471
  function cloneObject(value, parameters, depth) {
3472
+ if (depth >= CLONE_MAX_DEPTH) return value;
3484
3473
  const isArray = Array.isArray(value);
3485
- if (parameters.options?.flat || depth >= CLONE_MAX_DEPTH) return isArray ? value.slice() : { ...value };
3474
+ if (parameters.copy) return isArray ? value.slice() : { ...value };
3486
3475
  const cloned = isArray ? [] : {};
3487
3476
  const keys = isArray ? void 0 : Object.keys(value);
3488
3477
  const { length } = keys ?? value;
@@ -3494,7 +3483,7 @@ function cloneObject(value, parameters, depth) {
3494
3483
  return cloned;
3495
3484
  }
3496
3485
  function cloneRegularExpression(value, parameters, depth) {
3497
- if (depth >= CLONE_MAX_DEPTH) return value;
3486
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3498
3487
  const cloned = new RegExp(value.source, value.flags);
3499
3488
  cloned.lastIndex = value.lastIndex;
3500
3489
  parameters.references.set(value, cloned);
@@ -3502,30 +3491,24 @@ function cloneRegularExpression(value, parameters, depth) {
3502
3491
  }
3503
3492
  function cloneSet(set, parameters, depth) {
3504
3493
  if (depth >= CLONE_MAX_DEPTH) return set;
3494
+ if (parameters.copy) return new Set(set);
3505
3495
  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));
3496
+ for (const value of set.values()) cloned.add(cloneAny(value, parameters, depth + 1));
3509
3497
  parameters.references.set(set, cloned);
3510
3498
  return cloned;
3511
3499
  }
3512
3500
  function cloneTypedArray(value, parameters, depth) {
3513
- if (depth >= CLONE_MAX_DEPTH) return value;
3501
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
3514
3502
  const cloned = new value.constructor(value);
3515
3503
  parameters.references.set(value, cloned);
3516
3504
  return cloned;
3517
3505
  }
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
3506
  function copy(value) {
3528
- return clone(value, CLONE_COPY_OPTIONS);
3507
+ return cloneAny(value, {
3508
+ copy: true,
3509
+ options: CLONE_COPY_OPTIONS,
3510
+ references: void 0
3511
+ }, 0);
3529
3512
  }
3530
3513
  /**
3531
3514
  * Deregister a clone handler for a specific class
@@ -3538,23 +3521,35 @@ function deregisterCloner(constructor) {
3538
3521
  clone.handlers.deregister(constructor);
3539
3522
  }
3540
3523
  function getCloneOptions(input) {
3541
- if (typeof input === "boolean") return {
3542
- copyFunctions: false,
3543
- copySymbols: false,
3544
- flat: input === true
3545
- };
3546
3524
  if (typeof input !== "object" || input === null) return CLONE_DEFAULT_OPTIONS;
3547
3525
  return {
3548
3526
  copyFunctions: input.copyFunctions === true,
3549
- copySymbols: input.copySymbols === true,
3550
- flat: input.flat === true
3527
+ copySymbols: input.copySymbols === true
3551
3528
  };
3552
3529
  }
3553
- function getCloneParameters(input) {
3554
- return {
3555
- options: getCloneOptions(input),
3556
- references: /* @__PURE__ */ new WeakMap()
3557
- };
3530
+ /**
3531
+ * Create a cloner with predefined options
3532
+ *
3533
+ * _Available as `initializeCloner` and `clone.initialize`_
3534
+ *
3535
+ * @param options Clone options
3536
+ * @returns Cloner function
3537
+ */
3538
+ function initializeCloner(options) {
3539
+ const opts = getCloneOptions(options);
3540
+ function cloner(value) {
3541
+ return cloneAny(value, {
3542
+ copy: false,
3543
+ options: opts
3544
+ }, 0);
3545
+ }
3546
+ cloner.deregister = deregisterCloner;
3547
+ cloner.register = registerCloner;
3548
+ Object.defineProperties(cloner, {
3549
+ deregister: { value: deregisterCloner },
3550
+ register: { value: registerCloner }
3551
+ });
3552
+ return cloner;
3558
3553
  }
3559
3554
  /**
3560
3555
  * Register a clone handler for a specific class
@@ -3571,24 +3566,46 @@ function tryStructuredClone(value, parameters, depth) {
3571
3566
  if (depth >= CLONE_MAX_DEPTH) return value;
3572
3567
  try {
3573
3568
  const cloned = structuredClone(value);
3574
- parameters.references?.set(value, cloned);
3569
+ parameters.references.set(value, cloned);
3575
3570
  return cloned;
3576
3571
  } catch {
3577
- parameters.references?.set(value, value);
3572
+ parameters.references.set(value, value);
3578
3573
  return value;
3579
3574
  }
3580
3575
  }
3581
3576
  const CLONE_COPY_OPTIONS = {
3582
3577
  copyFunctions: true,
3583
- copySymbols: true,
3584
- flat: true
3578
+ copySymbols: true
3585
3579
  };
3586
3580
  const CLONE_DEFAULT_OPTIONS = {
3587
3581
  copyFunctions: false,
3588
- copySymbols: false,
3589
- flat: false
3582
+ copySymbols: false
3590
3583
  };
3591
3584
  const CLONE_MAX_DEPTH = 100;
3585
+ const cloneHandlers = getSelfHandlers(clone, {
3586
+ callback: tryStructuredClone,
3587
+ method: CLONE_NAME
3588
+ });
3589
+ const CLONE_PRIMITIVES = {
3590
+ bigint: true,
3591
+ boolean: true,
3592
+ function: false,
3593
+ number: true,
3594
+ object: false,
3595
+ string: true,
3596
+ symbol: false,
3597
+ undefined: true
3598
+ };
3599
+ clone.deregister = deregisterCloner;
3600
+ clone.handlers = cloneHandlers;
3601
+ clone.initialize = initializeCloner;
3602
+ clone.register = registerCloner;
3603
+ Object.defineProperties(clone, {
3604
+ deregister: { value: deregisterCloner },
3605
+ handlers: { value: cloneHandlers },
3606
+ initialize: { value: initializeCloner },
3607
+ register: { value: registerCloner }
3608
+ });
3592
3609
  //#endregion
3593
3610
  //#region src/value/collection.ts
3594
3611
  function inMap(map, value, key) {
@@ -6383,4 +6400,4 @@ var SizedSet = class extends Set {
6383
6400
  }
6384
6401
  };
6385
6402
  //#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 };
6403
+ 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, 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 };
@@ -9,19 +9,36 @@ type CloneOptions = {
9
9
  * Copy symbols instead of returning `Symbol(description)`? _(defaults to `false`)_
10
10
  */
11
11
  copySymbols?: boolean;
12
- /**
13
- * Clone only the value itself, without cloning nested values? _(defaults to `false`)_
14
- */
15
- flat?: boolean;
16
12
  };
17
13
  /**
18
- * Clone any kind of value _(shallowly)_
19
- *
20
- * @param value Value to clone
21
- * @param flat Clone only the value itself, without cloning nested values
22
- * @returns Cloned value
14
+ * A cloning function with predefined options
23
15
  */
24
- declare function clone<Value>(value: Value, flat: true): Value;
16
+ type Cloner = {
17
+ /**
18
+ * Clone any kind of value
19
+ *
20
+ * @param value Value to clone
21
+ * @returns Cloned value
22
+ */
23
+ <Value>(value: Value): Value;
24
+ /**
25
+ * Deregister a clone handler for a specific class
26
+ *
27
+ * _Available as `deregisterCloner` and `template.deregister`_
28
+ *
29
+ * @param constructor Class constructor
30
+ */
31
+ deregister: typeof deregisterCloner;
32
+ /**
33
+ * Register a clone handler for a specific class
34
+ *
35
+ * _Available as `registerCloner` and `template.register`_
36
+ *
37
+ * @param constructor Class constructor
38
+ * @param handler Method name or clone function _(defaults to method name `clone`)_
39
+ */
40
+ register: typeof registerCloner;
41
+ };
25
42
  /**
26
43
  * Clone any kind of value _(deeply, if needed)_
27
44
  *
@@ -31,18 +48,19 @@ declare function clone<Value>(value: Value, flat: true): Value;
31
48
  */
32
49
  declare function clone<Value>(value: Value, options?: CloneOptions): Value;
33
50
  declare namespace clone {
51
+ var deregister: typeof deregisterCloner;
34
52
  var handlers: {
35
53
  deregister(constructor: Constructor): void;
36
54
  handle(value: unknown, ...parameters: unknown[]): unknown;
37
55
  register(constructor: Constructor, handler?: string | GenericCallback): void;
38
56
  };
39
- var deregister: typeof deregisterCloner;
57
+ var initialize: typeof initializeCloner;
40
58
  var register: typeof registerCloner;
41
59
  }
42
60
  /**
43
61
  * Copy any kind of value
44
62
  *
45
- * - Clones the value shallowly, without cloning nested values
63
+ * - Copies the value shallowly _(if possible)_, without copying or cloning nested values
46
64
  * - To copy a value deeply, use `clone` instead
47
65
  *
48
66
  * @param value Value to copy
@@ -57,6 +75,15 @@ declare function copy<Value>(value: Value): Value;
57
75
  * @param constructor Class constructor
58
76
  */
59
77
  declare function deregisterCloner<Instance>(constructor: Constructor<Instance>): void;
78
+ /**
79
+ * Create a cloner with predefined options
80
+ *
81
+ * _Available as `initializeCloner` and `clone.initialize`_
82
+ *
83
+ * @param options Clone options
84
+ * @returns Cloner function
85
+ */
86
+ declare function initializeCloner(options?: CloneOptions): Cloner;
60
87
  /**
61
88
  * Register a clone handler for a specific class
62
89
  *
@@ -67,4 +94,4 @@ declare function deregisterCloner<Instance>(constructor: Constructor<Instance>):
67
94
  */
68
95
  declare function registerCloner<Instance>(constructor: Constructor<Instance>, handler?: string | ((value: Instance) => Instance)): void;
69
96
  //#endregion
70
- export { CloneOptions, clone, copy, deregisterCloner, registerCloner };
97
+ export { CloneOptions, Cloner, clone, copy, deregisterCloner, initializeCloner, registerCloner };
@@ -3,33 +3,22 @@ import { getSelfHandlers } from "../internal/value/handlers.mjs";
3
3
  //#region src/value/clone.ts
4
4
  const CLONE_NAME = "clone";
5
5
  function clone(value, options) {
6
+ return cloneAny(value, { copy: false }, 0, options);
7
+ }
8
+ function cloneAny(value, parameters, depth, options) {
6
9
  switch (true) {
7
- case value === null:
8
- case value === void 0:
9
- case typeof value === "bigint":
10
- case typeof value === "boolean":
11
- case typeof value === "number":
12
- case typeof value === "string": return value;
10
+ case value === null || CLONE_PRIMITIVES[typeof value]: return value;
13
11
  case value instanceof Date: return new Date(value.getTime());
14
- default: return cloneAny(value, getCloneParameters(options), 0);
12
+ case typeof value === "function":
13
+ parameters.options ??= getCloneOptions(options);
14
+ return parameters.options.copyFunctions ? value : void 0;
15
+ case typeof value === "symbol":
16
+ parameters.options ??= getCloneOptions(options);
17
+ return parameters.options.copySymbols ? value : Symbol(value.description);
15
18
  }
16
- }
17
- clone.handlers = getSelfHandlers(clone, {
18
- callback: tryStructuredClone,
19
- method: CLONE_NAME
20
- });
21
- clone.deregister = deregisterCloner;
22
- clone.register = registerCloner;
23
- function cloneAny(value, parameters, depth) {
19
+ parameters.options ??= getCloneOptions(options);
20
+ parameters.references ??= /* @__PURE__ */ new WeakMap();
24
21
  switch (true) {
25
- case value == null:
26
- case typeof value === "bigint":
27
- case typeof value === "boolean":
28
- case typeof value === "number":
29
- case typeof value === "string": return value;
30
- case value instanceof Date: return new Date(value.getTime());
31
- case typeof value === "function": return parameters.options?.copyFunctions ? value : void 0;
32
- case typeof value === "symbol": return parameters.options?.copySymbols ? value : Symbol(value.description);
33
22
  case parameters.references.has(value): return parameters.references.get(value);
34
23
  case value instanceof ArrayBuffer: return cloneArrayBuffer(value, parameters, depth);
35
24
  case value instanceof DataView: return cloneDataView(value, parameters, depth);
@@ -39,18 +28,18 @@ function cloneAny(value, parameters, depth) {
39
28
  case value instanceof Set: return cloneSet(value, parameters, depth);
40
29
  case isArrayOrPlainObject(value): return cloneObject(value, parameters, depth);
41
30
  case isTypedArray(value): return cloneTypedArray(value, parameters, depth);
42
- default: return clone.handlers.handle(value, parameters, depth);
31
+ default: return parameters.copy ? value : clone.handlers.handle(value, parameters, depth);
43
32
  }
44
33
  }
45
34
  function cloneArrayBuffer(value, parameters, depth) {
46
- if (depth >= CLONE_MAX_DEPTH) return value;
35
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
47
36
  const cloned = new ArrayBuffer(value.byteLength);
48
37
  new Uint8Array(cloned).set(new Uint8Array(value));
49
38
  parameters.references.set(value, cloned);
50
39
  return cloned;
51
40
  }
52
41
  function cloneDataView(value, parameters, depth) {
53
- if (depth >= CLONE_MAX_DEPTH) return value;
42
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
54
43
  const buffer = cloneArrayBuffer(value.buffer, parameters, depth);
55
44
  const cloned = new DataView(buffer, value.byteOffset, value.byteLength);
56
45
  parameters.references.set(value, cloned);
@@ -58,22 +47,22 @@ function cloneDataView(value, parameters, depth) {
58
47
  }
59
48
  function cloneMap(map, parameters, depth) {
60
49
  if (depth >= CLONE_MAX_DEPTH) return map;
61
- const flat = parameters.options?.flat;
50
+ if (parameters.copy) return new Map(map);
62
51
  const cloned = /* @__PURE__ */ new Map();
63
- const entries = map.entries();
64
- 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));
52
+ for (const [key, value] of map.entries()) cloned.set(cloneAny(key, parameters, depth + 1), cloneAny(value, parameters, depth + 1));
65
53
  parameters.references.set(map, cloned);
66
54
  return cloned;
67
55
  }
68
56
  function cloneNode(node, parameters, depth) {
69
- if (depth >= CLONE_MAX_DEPTH) return node;
57
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return node;
70
58
  const cloned = node.cloneNode(true);
71
59
  parameters.references.set(node, cloned);
72
60
  return cloned;
73
61
  }
74
62
  function cloneObject(value, parameters, depth) {
63
+ if (depth >= CLONE_MAX_DEPTH) return value;
75
64
  const isArray = Array.isArray(value);
76
- if (parameters.options?.flat || depth >= CLONE_MAX_DEPTH) return isArray ? value.slice() : { ...value };
65
+ if (parameters.copy) return isArray ? value.slice() : { ...value };
77
66
  const cloned = isArray ? [] : {};
78
67
  const keys = isArray ? void 0 : Object.keys(value);
79
68
  const { length } = keys ?? value;
@@ -85,7 +74,7 @@ function cloneObject(value, parameters, depth) {
85
74
  return cloned;
86
75
  }
87
76
  function cloneRegularExpression(value, parameters, depth) {
88
- if (depth >= CLONE_MAX_DEPTH) return value;
77
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
89
78
  const cloned = new RegExp(value.source, value.flags);
90
79
  cloned.lastIndex = value.lastIndex;
91
80
  parameters.references.set(value, cloned);
@@ -93,30 +82,24 @@ function cloneRegularExpression(value, parameters, depth) {
93
82
  }
94
83
  function cloneSet(set, parameters, depth) {
95
84
  if (depth >= CLONE_MAX_DEPTH) return set;
85
+ if (parameters.copy) return new Set(set);
96
86
  const cloned = /* @__PURE__ */ new Set();
97
- const values = [...set.values()];
98
- const { length } = values;
99
- for (let index = 0; index < length; index += 1) cloned.add(parameters.options?.flat ? values[index] : cloneAny(values[index], parameters, depth + 1));
87
+ for (const value of set.values()) cloned.add(cloneAny(value, parameters, depth + 1));
100
88
  parameters.references.set(set, cloned);
101
89
  return cloned;
102
90
  }
103
91
  function cloneTypedArray(value, parameters, depth) {
104
- if (depth >= CLONE_MAX_DEPTH) return value;
92
+ if (parameters.copy || depth >= CLONE_MAX_DEPTH) return value;
105
93
  const cloned = new value.constructor(value);
106
94
  parameters.references.set(value, cloned);
107
95
  return cloned;
108
96
  }
109
- /**
110
- * Copy any kind of value
111
- *
112
- * - Clones the value shallowly, without cloning nested values
113
- * - To copy a value deeply, use `clone` instead
114
- *
115
- * @param value Value to copy
116
- * @returns Copied value
117
- */
118
97
  function copy(value) {
119
- return clone(value, CLONE_COPY_OPTIONS);
98
+ return cloneAny(value, {
99
+ copy: true,
100
+ options: CLONE_COPY_OPTIONS,
101
+ references: void 0
102
+ }, 0);
120
103
  }
121
104
  /**
122
105
  * Deregister a clone handler for a specific class
@@ -129,23 +112,35 @@ function deregisterCloner(constructor) {
129
112
  clone.handlers.deregister(constructor);
130
113
  }
131
114
  function getCloneOptions(input) {
132
- if (typeof input === "boolean") return {
133
- copyFunctions: false,
134
- copySymbols: false,
135
- flat: input === true
136
- };
137
115
  if (typeof input !== "object" || input === null) return CLONE_DEFAULT_OPTIONS;
138
116
  return {
139
117
  copyFunctions: input.copyFunctions === true,
140
- copySymbols: input.copySymbols === true,
141
- flat: input.flat === true
118
+ copySymbols: input.copySymbols === true
142
119
  };
143
120
  }
144
- function getCloneParameters(input) {
145
- return {
146
- options: getCloneOptions(input),
147
- references: /* @__PURE__ */ new WeakMap()
148
- };
121
+ /**
122
+ * Create a cloner with predefined options
123
+ *
124
+ * _Available as `initializeCloner` and `clone.initialize`_
125
+ *
126
+ * @param options Clone options
127
+ * @returns Cloner function
128
+ */
129
+ function initializeCloner(options) {
130
+ const opts = getCloneOptions(options);
131
+ function cloner(value) {
132
+ return cloneAny(value, {
133
+ copy: false,
134
+ options: opts
135
+ }, 0);
136
+ }
137
+ cloner.deregister = deregisterCloner;
138
+ cloner.register = registerCloner;
139
+ Object.defineProperties(cloner, {
140
+ deregister: { value: deregisterCloner },
141
+ register: { value: registerCloner }
142
+ });
143
+ return cloner;
149
144
  }
150
145
  /**
151
146
  * Register a clone handler for a specific class
@@ -162,23 +157,45 @@ function tryStructuredClone(value, parameters, depth) {
162
157
  if (depth >= CLONE_MAX_DEPTH) return value;
163
158
  try {
164
159
  const cloned = structuredClone(value);
165
- parameters.references?.set(value, cloned);
160
+ parameters.references.set(value, cloned);
166
161
  return cloned;
167
162
  } catch {
168
- parameters.references?.set(value, value);
163
+ parameters.references.set(value, value);
169
164
  return value;
170
165
  }
171
166
  }
172
167
  const CLONE_COPY_OPTIONS = {
173
168
  copyFunctions: true,
174
- copySymbols: true,
175
- flat: true
169
+ copySymbols: true
176
170
  };
177
171
  const CLONE_DEFAULT_OPTIONS = {
178
172
  copyFunctions: false,
179
- copySymbols: false,
180
- flat: false
173
+ copySymbols: false
181
174
  };
182
175
  const CLONE_MAX_DEPTH = 100;
176
+ const cloneHandlers = getSelfHandlers(clone, {
177
+ callback: tryStructuredClone,
178
+ method: CLONE_NAME
179
+ });
180
+ const CLONE_PRIMITIVES = {
181
+ bigint: true,
182
+ boolean: true,
183
+ function: false,
184
+ number: true,
185
+ object: false,
186
+ string: true,
187
+ symbol: false,
188
+ undefined: true
189
+ };
190
+ clone.deregister = deregisterCloner;
191
+ clone.handlers = cloneHandlers;
192
+ clone.initialize = initializeCloner;
193
+ clone.register = registerCloner;
194
+ Object.defineProperties(clone, {
195
+ deregister: { value: deregisterCloner },
196
+ handlers: { value: cloneHandlers },
197
+ initialize: { value: initializeCloner },
198
+ register: { value: registerCloner }
199
+ });
183
200
  //#endregion
184
- export { clone, copy, deregisterCloner, registerCloner };
201
+ export { clone, copy, deregisterCloner, initializeCloner, registerCloner };
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.197.0",
3
+ "version": "0.198.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "array",
7
+ "clone",
7
8
  "color",
8
9
  "helper",
9
10
  "observable",
@@ -282,7 +283,7 @@
282
283
  "@vitest/coverage-istanbul": "^4.1",
283
284
  "eslint": "^10.9",
284
285
  "jsdom": "^30",
285
- "tsdown": "^0.22",
286
+ "tsdown": "^0.23",
286
287
  "typescript": "^6",
287
288
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
288
289
  "vite-plus": "latest",