bunshin-clone 1.7.1 → 1.8.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/README.md +6 -1
- package/dist/index.cjs +36 -16
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +36 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ bunshinClone<T>(value, options);
|
|
|
36
36
|
interface BunshinCloneOptions {
|
|
37
37
|
preserveBufferSharing: boolean; // default: false
|
|
38
38
|
preserveDescriptors: boolean; // default: false
|
|
39
|
+
preserveSymbolKeys: boolean; // default: false
|
|
39
40
|
strictDescriptors: boolean; // default: false
|
|
40
41
|
}
|
|
41
42
|
```
|
|
@@ -48,9 +49,13 @@ If `true`, preserves shared backing buffers between TypedArray and DataView inst
|
|
|
48
49
|
|
|
49
50
|
If `true`, preserves property descriptors (getters/setters, etc.).
|
|
50
51
|
|
|
52
|
+
### `preserveSymbolKeys`
|
|
53
|
+
|
|
54
|
+
If `true`, preserves symbol keys (slower).
|
|
55
|
+
|
|
51
56
|
### `strictDescriptors`
|
|
52
57
|
|
|
53
|
-
If `true`, throws if descriptor cannot be merged (e.g. non-configurable or non-writable)
|
|
58
|
+
If `true`, throws if descriptor cannot be merged (e.g. non-configurable or non-writable).
|
|
54
59
|
|
|
55
60
|
## 📖 Details
|
|
56
61
|
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
var EMPTY_OPTIONS = {};
|
|
5
|
-
var { propertyIsEnumerable: IS_ENUMERABLE } = Object.prototype;
|
|
5
|
+
var { hasOwnProperty: HAS_OWN, propertyIsEnumerable: IS_ENUMERABLE } = Object.prototype;
|
|
6
6
|
function bunshinClone(value, options = EMPTY_OPTIONS, refs = /* @__PURE__ */ new WeakMap()) {
|
|
7
7
|
return clone(value, resolveOptions(options), refs);
|
|
8
8
|
}
|
|
@@ -18,7 +18,7 @@ function clone(value, settings, refs) {
|
|
|
18
18
|
return cloneWithDescriptors(value, settings, refs);
|
|
19
19
|
}
|
|
20
20
|
if (Array.isArray(value)) {
|
|
21
|
-
if (
|
|
21
|
+
if (isShallowArray(value)) {
|
|
22
22
|
const result2 = value.slice();
|
|
23
23
|
refs.set(value, result2);
|
|
24
24
|
return result2;
|
|
@@ -34,11 +34,20 @@ function clone(value, settings, refs) {
|
|
|
34
34
|
if (isPlainObject(value)) {
|
|
35
35
|
const result = Object.create(Object.getPrototypeOf(value));
|
|
36
36
|
refs.set(value, result);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if (!settings.preserveSymbolKeys) {
|
|
38
|
+
for (const key in value) {
|
|
39
|
+
if (isUnsafeKey(key) || !HAS_OWN.call(value, key)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
result[key] = clone(value[key], settings, refs);
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
46
|
+
if (isUnsafeKey(key) || !IS_ENUMERABLE.call(value, key)) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
result[key] = clone(value[key], settings, refs);
|
|
40
50
|
}
|
|
41
|
-
result[key] = clone(value[key], settings, refs);
|
|
42
51
|
}
|
|
43
52
|
return result;
|
|
44
53
|
}
|
|
@@ -209,14 +218,6 @@ function createErrorInstance(error, settings, refs) {
|
|
|
209
218
|
result.name = name;
|
|
210
219
|
return result;
|
|
211
220
|
}
|
|
212
|
-
function isShallowClonableArray(array) {
|
|
213
|
-
for (let i = 0, l = array.length; i < l; i++) {
|
|
214
|
-
if (isObject(array[i])) {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
221
|
function forEachOwnKey(object, callback) {
|
|
221
222
|
for (const key of Object.keys(object)) {
|
|
222
223
|
callback(key);
|
|
@@ -235,6 +236,14 @@ function isPlainObject(value) {
|
|
|
235
236
|
const proto = Object.getPrototypeOf(value);
|
|
236
237
|
return proto === Object.prototype || proto === null;
|
|
237
238
|
}
|
|
239
|
+
function isShallowArray(array) {
|
|
240
|
+
for (let i = 0, l = array.length; i < l; i++) {
|
|
241
|
+
if (isObject(array[i])) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
238
247
|
function isUnsafeKey(key) {
|
|
239
248
|
return typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
|
|
240
249
|
}
|
|
@@ -242,8 +251,13 @@ function resolveOptions(options) {
|
|
|
242
251
|
let {
|
|
243
252
|
preserveBufferSharing = false,
|
|
244
253
|
preserveDescriptors = false,
|
|
245
|
-
strictDescriptors = false
|
|
254
|
+
strictDescriptors = false,
|
|
255
|
+
preserveSymbolKeys = false
|
|
246
256
|
} = options;
|
|
257
|
+
if (typeof preserveSymbolKeys !== "boolean") {
|
|
258
|
+
console.warn("Invalid preserveSymbolKeys option. Fallback: false.");
|
|
259
|
+
preserveSymbolKeys = false;
|
|
260
|
+
}
|
|
247
261
|
if (typeof preserveBufferSharing !== "boolean") {
|
|
248
262
|
console.warn("Invalid preserveBufferSharing option. Fallback: false.");
|
|
249
263
|
preserveBufferSharing = false;
|
|
@@ -256,11 +270,17 @@ function resolveOptions(options) {
|
|
|
256
270
|
console.warn("Invalid strictDescriptors option. Fallback: false.");
|
|
257
271
|
strictDescriptors = false;
|
|
258
272
|
}
|
|
259
|
-
return {
|
|
273
|
+
return {
|
|
274
|
+
preserveBufferSharing,
|
|
275
|
+
preserveDescriptors,
|
|
276
|
+
preserveSymbolKeys,
|
|
277
|
+
strictDescriptors
|
|
278
|
+
};
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
exports.bunshinClone = bunshinClone;
|
|
263
282
|
exports.forEachOwnKey = forEachOwnKey;
|
|
264
283
|
exports.isObject = isObject;
|
|
265
284
|
exports.isPlainObject = isPlainObject;
|
|
285
|
+
exports.isShallowArray = isShallowArray;
|
|
266
286
|
exports.isUnsafeKey = isUnsafeKey;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
interface BunshinCloneOptions {
|
|
2
2
|
preserveBufferSharing: boolean;
|
|
3
3
|
preserveDescriptors: boolean;
|
|
4
|
+
preserveSymbolKeys: boolean;
|
|
4
5
|
strictDescriptors: boolean;
|
|
5
6
|
}
|
|
6
7
|
type PlainObject = Record<PropertyKey, unknown>;
|
|
@@ -9,6 +10,7 @@ declare function bunshinClone<T>(value: T, options?: Partial<BunshinCloneOptions
|
|
|
9
10
|
declare function forEachOwnKey(object: PlainObject, callback: (key: string | symbol) => void): void;
|
|
10
11
|
declare function isObject(value: unknown): value is object;
|
|
11
12
|
declare function isPlainObject(value: unknown): value is PlainObject;
|
|
13
|
+
declare function isShallowArray(array: unknown[]): boolean;
|
|
12
14
|
declare function isUnsafeKey(key: PropertyKey): boolean;
|
|
13
15
|
|
|
14
|
-
export { type BunshinCloneOptions, bunshinClone, forEachOwnKey, isObject, isPlainObject, isUnsafeKey };
|
|
16
|
+
export { type BunshinCloneOptions, bunshinClone, forEachOwnKey, isObject, isPlainObject, isShallowArray, isUnsafeKey };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
interface BunshinCloneOptions {
|
|
2
2
|
preserveBufferSharing: boolean;
|
|
3
3
|
preserveDescriptors: boolean;
|
|
4
|
+
preserveSymbolKeys: boolean;
|
|
4
5
|
strictDescriptors: boolean;
|
|
5
6
|
}
|
|
6
7
|
type PlainObject = Record<PropertyKey, unknown>;
|
|
@@ -9,6 +10,7 @@ declare function bunshinClone<T>(value: T, options?: Partial<BunshinCloneOptions
|
|
|
9
10
|
declare function forEachOwnKey(object: PlainObject, callback: (key: string | symbol) => void): void;
|
|
10
11
|
declare function isObject(value: unknown): value is object;
|
|
11
12
|
declare function isPlainObject(value: unknown): value is PlainObject;
|
|
13
|
+
declare function isShallowArray(array: unknown[]): boolean;
|
|
12
14
|
declare function isUnsafeKey(key: PropertyKey): boolean;
|
|
13
15
|
|
|
14
|
-
export { type BunshinCloneOptions, bunshinClone, forEachOwnKey, isObject, isPlainObject, isUnsafeKey };
|
|
16
|
+
export { type BunshinCloneOptions, bunshinClone, forEachOwnKey, isObject, isPlainObject, isShallowArray, isUnsafeKey };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
var EMPTY_OPTIONS = {};
|
|
3
|
-
var { propertyIsEnumerable: IS_ENUMERABLE } = Object.prototype;
|
|
3
|
+
var { hasOwnProperty: HAS_OWN, propertyIsEnumerable: IS_ENUMERABLE } = Object.prototype;
|
|
4
4
|
function bunshinClone(value, options = EMPTY_OPTIONS, refs = /* @__PURE__ */ new WeakMap()) {
|
|
5
5
|
return clone(value, resolveOptions(options), refs);
|
|
6
6
|
}
|
|
@@ -16,7 +16,7 @@ function clone(value, settings, refs) {
|
|
|
16
16
|
return cloneWithDescriptors(value, settings, refs);
|
|
17
17
|
}
|
|
18
18
|
if (Array.isArray(value)) {
|
|
19
|
-
if (
|
|
19
|
+
if (isShallowArray(value)) {
|
|
20
20
|
const result2 = value.slice();
|
|
21
21
|
refs.set(value, result2);
|
|
22
22
|
return result2;
|
|
@@ -32,11 +32,20 @@ function clone(value, settings, refs) {
|
|
|
32
32
|
if (isPlainObject(value)) {
|
|
33
33
|
const result = Object.create(Object.getPrototypeOf(value));
|
|
34
34
|
refs.set(value, result);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
if (!settings.preserveSymbolKeys) {
|
|
36
|
+
for (const key in value) {
|
|
37
|
+
if (isUnsafeKey(key) || !HAS_OWN.call(value, key)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
result[key] = clone(value[key], settings, refs);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
44
|
+
if (isUnsafeKey(key) || !IS_ENUMERABLE.call(value, key)) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
result[key] = clone(value[key], settings, refs);
|
|
38
48
|
}
|
|
39
|
-
result[key] = clone(value[key], settings, refs);
|
|
40
49
|
}
|
|
41
50
|
return result;
|
|
42
51
|
}
|
|
@@ -207,14 +216,6 @@ function createErrorInstance(error, settings, refs) {
|
|
|
207
216
|
result.name = name;
|
|
208
217
|
return result;
|
|
209
218
|
}
|
|
210
|
-
function isShallowClonableArray(array) {
|
|
211
|
-
for (let i = 0, l = array.length; i < l; i++) {
|
|
212
|
-
if (isObject(array[i])) {
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
219
|
function forEachOwnKey(object, callback) {
|
|
219
220
|
for (const key of Object.keys(object)) {
|
|
220
221
|
callback(key);
|
|
@@ -233,6 +234,14 @@ function isPlainObject(value) {
|
|
|
233
234
|
const proto = Object.getPrototypeOf(value);
|
|
234
235
|
return proto === Object.prototype || proto === null;
|
|
235
236
|
}
|
|
237
|
+
function isShallowArray(array) {
|
|
238
|
+
for (let i = 0, l = array.length; i < l; i++) {
|
|
239
|
+
if (isObject(array[i])) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
236
245
|
function isUnsafeKey(key) {
|
|
237
246
|
return typeof key === "string" && (key === "__proto__" || key === "prototype" || key === "constructor");
|
|
238
247
|
}
|
|
@@ -240,8 +249,13 @@ function resolveOptions(options) {
|
|
|
240
249
|
let {
|
|
241
250
|
preserveBufferSharing = false,
|
|
242
251
|
preserveDescriptors = false,
|
|
243
|
-
strictDescriptors = false
|
|
252
|
+
strictDescriptors = false,
|
|
253
|
+
preserveSymbolKeys = false
|
|
244
254
|
} = options;
|
|
255
|
+
if (typeof preserveSymbolKeys !== "boolean") {
|
|
256
|
+
console.warn("Invalid preserveSymbolKeys option. Fallback: false.");
|
|
257
|
+
preserveSymbolKeys = false;
|
|
258
|
+
}
|
|
245
259
|
if (typeof preserveBufferSharing !== "boolean") {
|
|
246
260
|
console.warn("Invalid preserveBufferSharing option. Fallback: false.");
|
|
247
261
|
preserveBufferSharing = false;
|
|
@@ -254,7 +268,12 @@ function resolveOptions(options) {
|
|
|
254
268
|
console.warn("Invalid strictDescriptors option. Fallback: false.");
|
|
255
269
|
strictDescriptors = false;
|
|
256
270
|
}
|
|
257
|
-
return {
|
|
271
|
+
return {
|
|
272
|
+
preserveBufferSharing,
|
|
273
|
+
preserveDescriptors,
|
|
274
|
+
preserveSymbolKeys,
|
|
275
|
+
strictDescriptors
|
|
276
|
+
};
|
|
258
277
|
}
|
|
259
278
|
|
|
260
|
-
export { bunshinClone, forEachOwnKey, isObject, isPlainObject, isUnsafeKey };
|
|
279
|
+
export { bunshinClone, forEachOwnKey, isObject, isPlainObject, isShallowArray, isUnsafeKey };
|