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 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
- * ⚡ 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
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
- interface BunshinCloneOptions {
40
- preserveDescriptors?: boolean;
41
- strictDescriptors?: boolean;
53
+ BunshinCloneOptions {
54
+ preserveDescriptors: false;
55
+ strictDescriptors: false;
42
56
  }
43
57
  ```
44
58
 
45
- ### preserveDescriptors
59
+ **preserveDescriptors**
46
60
 
47
- * `false` (default): use standard merge (faster, ignores property descriptors)
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
- ### strictDescriptors
81
+ **strictDescriptors**
68
82
 
69
- * `false` (default): skip incompatible descriptors
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
- const result = cloneError(node, options, ref);
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
- if (!options.preserveDescriptors && "cause" in value) {
144
- const cause = value.cause;
145
- if (cause !== void 0) {
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.7
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
@@ -3,7 +3,7 @@
3
3
  * High-performance deep clone utility with descriptor support.
4
4
  * Supports circular ref and complex built-in types.
5
5
  *
6
- * @version 1.0.7
6
+ * @version 1.0.8
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) 2026 Yusuke Kamiyamane
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * High-performance deep clone utility with descriptor support.
4
4
  * Supports circular ref and complex built-in types.
5
5
  *
6
- * @version 1.0.7
6
+ * @version 1.0.8
7
7
  * @author Yusuke Kamiyamane
8
8
  * @license MIT
9
9
  * @copyright Copyright (c) 2026 Yusuke Kamiyamane
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
- const result = cloneError(node, options, ref);
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
- if (!options.preserveDescriptors && "cause" in value) {
142
- const cause = value.cause;
143
- if (cause !== void 0) {
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.7
200
+ * @version 1.0.8
197
201
  * @author Yusuke Kamiyamane
198
202
  * @license MIT
199
203
  * @copyright Copyright (c) 2026 Yusuke Kamiyamane
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bunshin-clone",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "High-performance deep clone utility with descriptor support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",