bunshin-clone 1.0.7 → 1.0.8
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/README.md +28 -12
- package/dist/index.cjs +19 -15
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,14 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
High-performance deep clone utility with descriptor support. Supports circular references and complex built-in types.
|
|
4
4
|
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Fast (no unnecessary overhead)
|
|
6
|
+
* Deep clone (no structural sharing)
|
|
7
|
+
* Supports circular ref
|
|
8
|
+
* Handles Map, Set, Array, TypedArray, Date, RegExp, etc.
|
|
9
|
+
* Optional descriptor preservation
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i bunshin-clone
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// npm
|
|
21
|
+
import bunshinClone from 'bunshin-clone';
|
|
22
|
+
|
|
23
|
+
// CDN
|
|
24
|
+
import bunshinClone from 'https://cdn.jsdelivr.net/npm/bunshin-clone/+esm';
|
|
25
|
+
```
|
|
26
|
+
|
|
13
27
|
## Usage
|
|
14
28
|
|
|
15
29
|
```ts
|
|
@@ -36,15 +50,15 @@ bunshinClone(target, options)
|
|
|
36
50
|
## Options
|
|
37
51
|
|
|
38
52
|
```ts
|
|
39
|
-
|
|
40
|
-
preserveDescriptors
|
|
41
|
-
strictDescriptors
|
|
53
|
+
BunshinCloneOptions {
|
|
54
|
+
preserveDescriptors: false;
|
|
55
|
+
strictDescriptors: false;
|
|
42
56
|
}
|
|
43
57
|
```
|
|
44
58
|
|
|
45
|
-
|
|
59
|
+
**preserveDescriptors**
|
|
46
60
|
|
|
47
|
-
* `false
|
|
61
|
+
* `false`: use standard merge (faster, ignores property descriptors)
|
|
48
62
|
* `true`: preserve property descriptors (getters/setters, etc.)
|
|
49
63
|
|
|
50
64
|
<details>
|
|
@@ -64,9 +78,9 @@ Object.getOwnPropertyDescriptor(result, 'x')?.get;
|
|
|
64
78
|
```
|
|
65
79
|
</details>
|
|
66
80
|
|
|
67
|
-
|
|
81
|
+
**strictDescriptors**
|
|
68
82
|
|
|
69
|
-
* `false
|
|
83
|
+
* `false`: skip incompatible descriptors
|
|
70
84
|
* `true`: throw if descriptor cannot be merged (e.g. non-configurable or non-writable)
|
|
71
85
|
|
|
72
86
|
<details>
|
|
@@ -80,6 +94,8 @@ bunshinClone(obj, { strictDescriptors: true });
|
|
|
80
94
|
```
|
|
81
95
|
</details>
|
|
82
96
|
|
|
97
|
+
---
|
|
98
|
+
|
|
83
99
|
## Supported Types
|
|
84
100
|
|
|
85
101
|
bunshin-clone correctly handles:
|
package/dist/index.cjs
CHANGED
|
@@ -85,9 +85,7 @@ function clone(node, options, ref) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
if (node instanceof Error || typeof DOMException !== "undefined" && node instanceof DOMException) {
|
|
88
|
-
|
|
89
|
-
ref.set(node, result);
|
|
90
|
-
return result;
|
|
88
|
+
return cloneError(node, options, ref);
|
|
91
89
|
}
|
|
92
90
|
if (typeof Blob !== "undefined" && node instanceof Blob) {
|
|
93
91
|
const result = node.slice(0, node.size, node.type);
|
|
@@ -120,10 +118,18 @@ function clone(node, options, ref) {
|
|
|
120
118
|
return node;
|
|
121
119
|
}
|
|
122
120
|
function cloneError(value, options, ref) {
|
|
121
|
+
if (value instanceof DOMException) {
|
|
122
|
+
const result2 = new DOMException(value.message, value.name);
|
|
123
|
+
ref.set(value, result2);
|
|
124
|
+
return result2;
|
|
125
|
+
}
|
|
123
126
|
const name = value.name || "Error";
|
|
124
127
|
const message = value.message || "";
|
|
125
128
|
let result;
|
|
126
129
|
switch (name) {
|
|
130
|
+
case "EvalError":
|
|
131
|
+
result = new EvalError(message);
|
|
132
|
+
break;
|
|
127
133
|
case "RangeError":
|
|
128
134
|
result = new RangeError(message);
|
|
129
135
|
break;
|
|
@@ -136,25 +142,20 @@ function cloneError(value, options, ref) {
|
|
|
136
142
|
case "TypeError":
|
|
137
143
|
result = new TypeError(message);
|
|
138
144
|
break;
|
|
145
|
+
case "URIError":
|
|
146
|
+
result = new URIError(message);
|
|
147
|
+
break;
|
|
139
148
|
default:
|
|
140
149
|
result = new Error(message);
|
|
141
150
|
result.name = name;
|
|
142
151
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
result.cause = clone(cause, options, ref);
|
|
147
|
-
}
|
|
152
|
+
ref.set(value, result);
|
|
153
|
+
if ("cause" in value && value.cause !== void 0) {
|
|
154
|
+
result.cause = clone(value.cause, options, ref);
|
|
148
155
|
}
|
|
149
156
|
if (value.stack) {
|
|
150
157
|
result.stack = value.stack;
|
|
151
158
|
}
|
|
152
|
-
for (const key of Object.keys(value)) {
|
|
153
|
-
if (key === "name" || key === "message" || key === "stack") {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
result[key] = value[key];
|
|
157
|
-
}
|
|
158
159
|
return result;
|
|
159
160
|
}
|
|
160
161
|
function cloneWithDescriptors(node, options, ref) {
|
|
@@ -164,6 +165,9 @@ function cloneWithDescriptors(node, options, ref) {
|
|
|
164
165
|
const keys = Reflect.ownKeys(descs);
|
|
165
166
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
166
167
|
const key = keys[i];
|
|
168
|
+
if (!key) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
167
171
|
if (isUnsafeKey(key)) {
|
|
168
172
|
continue;
|
|
169
173
|
}
|
|
@@ -195,7 +199,7 @@ function isUnsafeKey(key) {
|
|
|
195
199
|
* High-performance deep clone utility with descriptor support.
|
|
196
200
|
* Supports circular ref and complex built-in types.
|
|
197
201
|
*
|
|
198
|
-
* @version 1.0.
|
|
202
|
+
* @version 1.0.8
|
|
199
203
|
* @author Yusuke Kamiyamane
|
|
200
204
|
* @license MIT
|
|
201
205
|
* @copyright Copyright (c) 2026 Yusuke Kamiyamane
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -83,9 +83,7 @@ function clone(node, options, ref) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
if (node instanceof Error || typeof DOMException !== "undefined" && node instanceof DOMException) {
|
|
86
|
-
|
|
87
|
-
ref.set(node, result);
|
|
88
|
-
return result;
|
|
86
|
+
return cloneError(node, options, ref);
|
|
89
87
|
}
|
|
90
88
|
if (typeof Blob !== "undefined" && node instanceof Blob) {
|
|
91
89
|
const result = node.slice(0, node.size, node.type);
|
|
@@ -118,10 +116,18 @@ function clone(node, options, ref) {
|
|
|
118
116
|
return node;
|
|
119
117
|
}
|
|
120
118
|
function cloneError(value, options, ref) {
|
|
119
|
+
if (value instanceof DOMException) {
|
|
120
|
+
const result2 = new DOMException(value.message, value.name);
|
|
121
|
+
ref.set(value, result2);
|
|
122
|
+
return result2;
|
|
123
|
+
}
|
|
121
124
|
const name = value.name || "Error";
|
|
122
125
|
const message = value.message || "";
|
|
123
126
|
let result;
|
|
124
127
|
switch (name) {
|
|
128
|
+
case "EvalError":
|
|
129
|
+
result = new EvalError(message);
|
|
130
|
+
break;
|
|
125
131
|
case "RangeError":
|
|
126
132
|
result = new RangeError(message);
|
|
127
133
|
break;
|
|
@@ -134,25 +140,20 @@ function cloneError(value, options, ref) {
|
|
|
134
140
|
case "TypeError":
|
|
135
141
|
result = new TypeError(message);
|
|
136
142
|
break;
|
|
143
|
+
case "URIError":
|
|
144
|
+
result = new URIError(message);
|
|
145
|
+
break;
|
|
137
146
|
default:
|
|
138
147
|
result = new Error(message);
|
|
139
148
|
result.name = name;
|
|
140
149
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
result.cause = clone(cause, options, ref);
|
|
145
|
-
}
|
|
150
|
+
ref.set(value, result);
|
|
151
|
+
if ("cause" in value && value.cause !== void 0) {
|
|
152
|
+
result.cause = clone(value.cause, options, ref);
|
|
146
153
|
}
|
|
147
154
|
if (value.stack) {
|
|
148
155
|
result.stack = value.stack;
|
|
149
156
|
}
|
|
150
|
-
for (const key of Object.keys(value)) {
|
|
151
|
-
if (key === "name" || key === "message" || key === "stack") {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
result[key] = value[key];
|
|
155
|
-
}
|
|
156
157
|
return result;
|
|
157
158
|
}
|
|
158
159
|
function cloneWithDescriptors(node, options, ref) {
|
|
@@ -162,6 +163,9 @@ function cloneWithDescriptors(node, options, ref) {
|
|
|
162
163
|
const keys = Reflect.ownKeys(descs);
|
|
163
164
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
164
165
|
const key = keys[i];
|
|
166
|
+
if (!key) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
165
169
|
if (isUnsafeKey(key)) {
|
|
166
170
|
continue;
|
|
167
171
|
}
|
|
@@ -193,7 +197,7 @@ function isUnsafeKey(key) {
|
|
|
193
197
|
* High-performance deep clone utility with descriptor support.
|
|
194
198
|
* Supports circular ref and complex built-in types.
|
|
195
199
|
*
|
|
196
|
-
* @version 1.0.
|
|
200
|
+
* @version 1.0.8
|
|
197
201
|
* @author Yusuke Kamiyamane
|
|
198
202
|
* @license MIT
|
|
199
203
|
* @copyright Copyright (c) 2026 Yusuke Kamiyamane
|