1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true
|
5 | });
|
6 | exports.default = deepCyclicCopyReplaceable;
|
7 |
|
8 | var _prettyFormat = require('pretty-format');
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | const builtInObject = [
|
17 | Array,
|
18 | Date,
|
19 | Float32Array,
|
20 | Float64Array,
|
21 | Int16Array,
|
22 | Int32Array,
|
23 | Int8Array,
|
24 | Map,
|
25 | Set,
|
26 | RegExp,
|
27 | Uint16Array,
|
28 | Uint32Array,
|
29 | Uint8Array,
|
30 | Uint8ClampedArray
|
31 | ];
|
32 |
|
33 | if (typeof Buffer !== 'undefined') {
|
34 | builtInObject.push(Buffer);
|
35 | }
|
36 |
|
37 | const isBuiltInObject = object => builtInObject.includes(object.constructor);
|
38 |
|
39 | const isMap = value => value.constructor === Map;
|
40 |
|
41 | function deepCyclicCopyReplaceable(value, cycles = new WeakMap()) {
|
42 | if (typeof value !== 'object' || value === null) {
|
43 | return value;
|
44 | } else if (cycles.has(value)) {
|
45 | return cycles.get(value);
|
46 | } else if (Array.isArray(value)) {
|
47 | return deepCyclicCopyArray(value, cycles);
|
48 | } else if (isMap(value)) {
|
49 | return deepCyclicCopyMap(value, cycles);
|
50 | } else if (isBuiltInObject(value)) {
|
51 | return value;
|
52 | } else if (_prettyFormat.plugins.DOMElement.test(value)) {
|
53 | return value.cloneNode(true);
|
54 | } else {
|
55 | return deepCyclicCopyObject(value, cycles);
|
56 | }
|
57 | }
|
58 |
|
59 | function deepCyclicCopyObject(object, cycles) {
|
60 | const newObject = Object.create(Object.getPrototypeOf(object));
|
61 | const descriptors = Object.getOwnPropertyDescriptors(object);
|
62 | cycles.set(object, newObject);
|
63 | const newDescriptors = [
|
64 | ...Object.keys(descriptors),
|
65 | ...Object.getOwnPropertySymbols(descriptors)
|
66 | ].reduce(
|
67 |
|
68 |
|
69 | (newDescriptors, key) => {
|
70 | const enumerable = descriptors[key].enumerable;
|
71 | newDescriptors[key] = {
|
72 | configurable: true,
|
73 | enumerable,
|
74 | value: deepCyclicCopyReplaceable(
|
75 |
|
76 |
|
77 | object[key],
|
78 | cycles
|
79 | ),
|
80 | writable: true
|
81 | };
|
82 | return newDescriptors;
|
83 | },
|
84 | {}
|
85 | );
|
86 |
|
87 |
|
88 | return Object.defineProperties(newObject, newDescriptors);
|
89 | }
|
90 |
|
91 | function deepCyclicCopyArray(array, cycles) {
|
92 | const newArray = new (Object.getPrototypeOf(array).constructor)(array.length);
|
93 | const length = array.length;
|
94 | cycles.set(array, newArray);
|
95 |
|
96 | for (let i = 0; i < length; i++) {
|
97 | newArray[i] = deepCyclicCopyReplaceable(array[i], cycles);
|
98 | }
|
99 |
|
100 | return newArray;
|
101 | }
|
102 |
|
103 | function deepCyclicCopyMap(map, cycles) {
|
104 | const newMap = new Map();
|
105 | cycles.set(map, newMap);
|
106 | map.forEach((value, key) => {
|
107 | newMap.set(key, deepCyclicCopyReplaceable(value, cycles));
|
108 | });
|
109 | return newMap;
|
110 | }
|