@augment-vir/common 31.67.1 → 31.68.1
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/augments/json/copy-through-json.d.ts +11 -6
- package/dist/augments/json/copy-through-json.js +23 -7
- package/dist/augments/number/truncate-number.js +2 -2
- package/dist/augments/object/constructor-instance-map.d.ts +36 -0
- package/dist/augments/object/constructor-instance-map.js +77 -0
- package/dist/augments/object/merge-deep.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +4 -4
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { type JsonCompatibleValue
|
|
1
|
+
import { type JsonCompatibleValue } from '@augment-vir/core';
|
|
2
2
|
import { type IsUnknown, type Jsonify, type Writable } from 'type-fest';
|
|
3
3
|
/**
|
|
4
4
|
* Deeply copy an object through JSON. This is the fastest deep copy, but the input must already be
|
|
5
5
|
* JSON serializable otherwise the copy will not match the original.
|
|
6
6
|
*
|
|
7
|
-
* Note that this will truncate inputs if they are not safe to serialize.
|
|
8
|
-
*
|
|
9
7
|
* @category JSON : Common
|
|
10
8
|
* @category Copy
|
|
11
9
|
* @category Package : @augment-vir/common
|
|
@@ -34,6 +32,13 @@ import { type IsUnknown, type Jsonify, type Writable } from 'type-fest';
|
|
|
34
32
|
*
|
|
35
33
|
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
36
34
|
*/
|
|
37
|
-
export declare function copyThroughJson<const T>(input: T
|
|
38
|
-
|
|
39
|
-
}
|
|
35
|
+
export declare function copyThroughJson<const T>(input: T): IsUnknown<T> extends true ? JsonCompatibleValue : Writable<Jsonify<T>>;
|
|
36
|
+
/**
|
|
37
|
+
* Same as {@link copyThroughJson} but this uses safe serialization from {@link safeJsonStringify}.
|
|
38
|
+
*
|
|
39
|
+
* @category JSON : Common
|
|
40
|
+
* @category Copy
|
|
41
|
+
* @category Package : @augment-vir/common
|
|
42
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
43
|
+
*/
|
|
44
|
+
export declare function safeCopyThroughJson<const T>(input: T): IsUnknown<T> extends true ? JsonCompatibleValue : Writable<Jsonify<T>>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
+
import { ensureErrorAndPrependMessage } from '@augment-vir/core';
|
|
1
2
|
import { safeJsonStringify } from './safe-json-stringify.js';
|
|
2
3
|
/**
|
|
3
4
|
* Deeply copy an object through JSON. This is the fastest deep copy, but the input must already be
|
|
4
5
|
* JSON serializable otherwise the copy will not match the original.
|
|
5
6
|
*
|
|
6
|
-
* Note that this will truncate inputs if they are not safe to serialize.
|
|
7
|
-
*
|
|
8
7
|
* @category JSON : Common
|
|
9
8
|
* @category Copy
|
|
10
9
|
* @category Package : @augment-vir/common
|
|
@@ -33,14 +32,31 @@ import { safeJsonStringify } from './safe-json-stringify.js';
|
|
|
33
32
|
*
|
|
34
33
|
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
35
34
|
*/
|
|
36
|
-
export function copyThroughJson(input
|
|
35
|
+
export function copyThroughJson(input) {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(JSON.stringify(input));
|
|
38
|
+
/* node:coverage ignore next 4 */
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error(`Failed to JSON copy for:`, input);
|
|
42
|
+
throw ensureErrorAndPrependMessage(error, 'Failed JSON copy');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Same as {@link copyThroughJson} but this uses safe serialization from {@link safeJsonStringify}.
|
|
47
|
+
*
|
|
48
|
+
* @category JSON : Common
|
|
49
|
+
* @category Copy
|
|
50
|
+
* @category Package : @augment-vir/common
|
|
51
|
+
* @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common)
|
|
52
|
+
*/
|
|
53
|
+
export function safeCopyThroughJson(input) {
|
|
37
54
|
try {
|
|
38
|
-
|
|
39
|
-
return JSON.parse(stringified);
|
|
55
|
+
return JSON.parse(safeJsonStringify(input));
|
|
40
56
|
/* node:coverage ignore next 4 */
|
|
41
57
|
}
|
|
42
58
|
catch (error) {
|
|
43
|
-
console.error(`Failed to JSON copy for
|
|
44
|
-
throw error;
|
|
59
|
+
console.error(`Failed to JSON copy for:`, input);
|
|
60
|
+
throw ensureErrorAndPrependMessage(error, 'Failed JSON copy');
|
|
45
61
|
}
|
|
46
62
|
}
|
|
@@ -158,9 +158,9 @@ export function truncateNumber(originalValue, { customSuffixes = defaultTruncati
|
|
|
158
158
|
// handle edge cases
|
|
159
159
|
if (isNaN(inputNumber) || inputNumber === Infinity) {
|
|
160
160
|
return String(inputNumber);
|
|
161
|
+
// handle too big or too small edge cases
|
|
161
162
|
}
|
|
162
|
-
|
|
163
|
-
if (requiresScientificNotation(inputNumber)) {
|
|
163
|
+
else if (requiresScientificNotation(inputNumber)) {
|
|
164
164
|
return truncateScientificNotation({
|
|
165
165
|
input: inputNumber,
|
|
166
166
|
maxLength,
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type AnyObject } from '@augment-vir/core';
|
|
2
|
+
import { type AbstractConstructor, type Constructor } from 'type-fest';
|
|
3
|
+
/**
|
|
4
|
+
* Map all ancestor constructors of an object to a set of objects.
|
|
5
|
+
*
|
|
6
|
+
* @category Internal
|
|
7
|
+
*/
|
|
8
|
+
export declare class ConstructorInstanceMap {
|
|
9
|
+
/**
|
|
10
|
+
* The top most constructor to allow in the map. If this constructor is ever reached, the
|
|
11
|
+
* recursive mapping stops.
|
|
12
|
+
*/
|
|
13
|
+
protected readonly topMostConstructor?: Function | undefined;
|
|
14
|
+
/** A map of constructors to their added instances. */
|
|
15
|
+
readonly map: Map<Function, Set<AnyObject>>;
|
|
16
|
+
readonly isDestroyed: boolean;
|
|
17
|
+
constructor(
|
|
18
|
+
/**
|
|
19
|
+
* The top most constructor to allow in the map. If this constructor is ever reached, the
|
|
20
|
+
* recursive mapping stops.
|
|
21
|
+
*/
|
|
22
|
+
topMostConstructor?: Function | undefined);
|
|
23
|
+
/**
|
|
24
|
+
* Add a new instance, mapping each of its ancestor constructors to it inside
|
|
25
|
+
* {@link ConstructorInstanceMap.map}.
|
|
26
|
+
*/
|
|
27
|
+
add(instance: AnyObject): void;
|
|
28
|
+
/** Gets all added instances of the given constructor. */
|
|
29
|
+
getInstances<T>(constructor: AbstractConstructor<T> | Constructor<T>): Set<T>;
|
|
30
|
+
/** Remove an instance, removing it from all mappings inside {@link ConstructorInstanceMap.map}. */
|
|
31
|
+
remove(instance: AnyObject): void;
|
|
32
|
+
/** Recursively map all ancestor prototypes to the given instance. */
|
|
33
|
+
protected traverseConstructors(instance: AnyObject, prototype: any, operation: 'add' | 'remove'): void;
|
|
34
|
+
/** Clean up the internal map. */
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
2
|
+
import { makeWritable } from '../type/writable.js';
|
|
3
|
+
import { getOrSetFromMap } from './get-or-set.js';
|
|
4
|
+
/**
|
|
5
|
+
* Map all ancestor constructors of an object to a set of objects.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
9
|
+
export class ConstructorInstanceMap {
|
|
10
|
+
topMostConstructor;
|
|
11
|
+
/** A map of constructors to their added instances. */
|
|
12
|
+
map = new Map();
|
|
13
|
+
isDestroyed = false;
|
|
14
|
+
constructor(
|
|
15
|
+
/**
|
|
16
|
+
* The top most constructor to allow in the map. If this constructor is ever reached, the
|
|
17
|
+
* recursive mapping stops.
|
|
18
|
+
*/
|
|
19
|
+
topMostConstructor) {
|
|
20
|
+
this.topMostConstructor = topMostConstructor;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add a new instance, mapping each of its ancestor constructors to it inside
|
|
24
|
+
* {@link ConstructorInstanceMap.map}.
|
|
25
|
+
*/
|
|
26
|
+
add(instance) {
|
|
27
|
+
if (this.isDestroyed) {
|
|
28
|
+
throw new Error('Cannot operate on destroyed ConstructorMap.');
|
|
29
|
+
}
|
|
30
|
+
this.traverseConstructors(instance, Object.getPrototypeOf(instance), 'add');
|
|
31
|
+
}
|
|
32
|
+
/** Gets all added instances of the given constructor. */
|
|
33
|
+
getInstances(constructor) {
|
|
34
|
+
if (this.isDestroyed) {
|
|
35
|
+
throw new Error('Cannot operate on destroyed ConstructorMap.');
|
|
36
|
+
}
|
|
37
|
+
return getOrSetFromMap(this.map, constructor, () => new Set());
|
|
38
|
+
}
|
|
39
|
+
/** Remove an instance, removing it from all mappings inside {@link ConstructorInstanceMap.map}. */
|
|
40
|
+
remove(instance) {
|
|
41
|
+
if (this.isDestroyed) {
|
|
42
|
+
throw new Error('Cannot operate on destroyed ConstructorMap.');
|
|
43
|
+
}
|
|
44
|
+
this.traverseConstructors(instance, Object.getPrototypeOf(instance), 'remove');
|
|
45
|
+
}
|
|
46
|
+
/** Recursively map all ancestor prototypes to the given instance. */
|
|
47
|
+
traverseConstructors(instance, prototype, operation) {
|
|
48
|
+
const constructor = prototype.constructor;
|
|
49
|
+
if (!constructor ||
|
|
50
|
+
constructor === Function ||
|
|
51
|
+
constructor === Object ||
|
|
52
|
+
constructor === this.topMostConstructor) {
|
|
53
|
+
/** Stop recursing into constructors. */
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (operation === 'add') {
|
|
57
|
+
const set = getOrSetFromMap(this.map, constructor, () => new Set());
|
|
58
|
+
set.add(instance);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const set = this.map.get(constructor);
|
|
62
|
+
if (set) {
|
|
63
|
+
set.delete(instance);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
this.traverseConstructors(instance, Object.getPrototypeOf(prototype), operation);
|
|
67
|
+
}
|
|
68
|
+
/** Clean up the internal map. */
|
|
69
|
+
destroy() {
|
|
70
|
+
if (this.isDestroyed) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
makeWritable(this).isDestroyed = true;
|
|
74
|
+
this.map.clear();
|
|
75
|
+
delete this.map;
|
|
76
|
+
}
|
|
77
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export * from './augments/number/round.js';
|
|
|
45
45
|
export * from './augments/number/scientific.js';
|
|
46
46
|
export * from './augments/number/truncate-number.js';
|
|
47
47
|
export * from './augments/number/wrap-number.js';
|
|
48
|
+
export * from './augments/object/constructor-instance-map.js';
|
|
48
49
|
export * from './augments/object/deep-copy.js';
|
|
49
50
|
export * from './augments/object/deep-value.js';
|
|
50
51
|
export * from './augments/object/diff.js';
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ export * from './augments/number/round.js';
|
|
|
45
45
|
export * from './augments/number/scientific.js';
|
|
46
46
|
export * from './augments/number/truncate-number.js';
|
|
47
47
|
export * from './augments/number/wrap-number.js';
|
|
48
|
+
export * from './augments/object/constructor-instance-map.js';
|
|
48
49
|
export * from './augments/object/deep-copy.js';
|
|
49
50
|
export * from './augments/object/deep-value.js';
|
|
50
51
|
export * from './augments/object/diff.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@augment-vir/common",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.68.1",
|
|
4
4
|
"description": "A collection of augments, helpers types, functions, and classes for any JavaScript environment.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"augment",
|
|
@@ -40,14 +40,14 @@
|
|
|
40
40
|
"test:web": "virmator --no-deps test web"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@augment-vir/assert": "^31.
|
|
44
|
-
"@augment-vir/core": "^31.
|
|
43
|
+
"@augment-vir/assert": "^31.68.1",
|
|
44
|
+
"@augment-vir/core": "^31.68.1",
|
|
45
45
|
"@date-vir/duration": "^8.2.0",
|
|
46
46
|
"ansi-styles": "^6.2.3",
|
|
47
47
|
"deepcopy-esm": "^2.1.1",
|
|
48
48
|
"json5": "^2.2.3",
|
|
49
49
|
"type-fest": "^5.4.4",
|
|
50
|
-
"typed-event-target": "^4.
|
|
50
|
+
"typed-event-target": "^4.3.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@web/dev-server-esbuild": "^1.0.5",
|