Gathering detailed insights and metrics for @ibnlanre/clone
Gathering detailed insights and metrics for @ibnlanre/clone
Gathering detailed insights and metrics for @ibnlanre/clone
Gathering detailed insights and metrics for @ibnlanre/clone
A simple utility to clone primitive and reference types in JavaScript.
npm install @ibnlanre/clone
Typescript
Module System
Node Version
NPM Version
TypeScript (95.72%)
JavaScript (4.28%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
BSD-3-Clause License
29 Commits
1 Watchers
1 Branches
1 Contributors
Updated on Jul 14, 2025
Latest Version
0.4.0
Package Id
@ibnlanre/clone@0.4.0
Unpacked Size
129.49 kB
Size
27.15 kB
File Count
9
NPM Version
10.5.0
Node Version
20.12.1
Published on
Jul 14, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
27
A comprehensive deep cloning utility for JavaScript that handles primitive types, complex objects, and cyclic references with ease.
1npm install @ibnlanre/clone
1import clone from "@ibnlanre/clone"; 2 3const original = { name: "John", age: 30 }; 4const cloned = clone(original);
1const clone = require("@ibnlanre/clone"); 2 3const original = { name: "John", age: 30 }; 4const cloned = clone(original);
1<script src="https://unpkg.com/@ibnlanre/clone"></script> 2<script> 3 const cloned = clone({ name: "John", age: 30 }); 4</script>
All primitive types are handled correctly:
1clone(undefined); // → undefined 2clone(null); // → null 3clone(true); // → true 4clone(42); // → 42 5clone("hello"); // → "hello" 6clone(BigInt(123)); // → 123n 7clone(Symbol("id")); // → Symbol(id)
1// Plain objects 2const obj = { a: 1, b: { c: 2 } }; 3const clonedObj = clone(obj); 4 5// Arrays 6const arr = [1, [2, 3], { d: 4 }]; 7const clonedArr = clone(arr); 8 9// Nested structures 10const complex = { 11 users: [ 12 { id: 1, profile: { name: "Alice" } }, 13 { id: 2, profile: { name: "Bob" } }, 14 ], 15}; 16const clonedComplex = clone(complex);
Functions are cloned with all their properties preserved:
1function greet(name) { 2 return `Hello, ${name}!`; 3} 4greet.customProp = "custom value"; 5greet.prototype.sayGoodbye = () => "Goodbye!"; 6 7const clonedGreet = clone(greet); 8clonedGreet("World"); // → "Hello, World!" 9clonedGreet.customProp; // → "custom value" 10clonedGreet.prototype.sayGoodbye(); // → "Goodbye!" 11clonedGreet !== greet; // → true (different reference)
1const date = new Date("2023-12-25"); 2const clonedDate = clone(date); 3// → 2023-12-25T00:00:00.000Z
1const regex = /hello/gi; 2const clonedRegex = clone(regex); 3// → /hello/gi (with same flags)
1const map = new Map([ 2 ["key1", "value1"], 3 ["key2", { nested: "object" }], 4]); 5const clonedMap = clone(map); 6// → Map with deeply cloned keys and values
1const set = new Set([1, { a: 2 }, [3, 4]]); 2const clonedSet = clone(set); 3// → Set with deeply cloned values
1// ArrayBuffer 2const buffer = new ArrayBuffer(16); 3const clonedBuffer = clone(buffer); 4 5// Typed Arrays 6const int32Array = new Int32Array([1, 2, 3, 4]); 7const clonedInt32Array = clone(int32Array); 8 9// DataView 10const dataView = new DataView(buffer, 4, 8); 11const clonedDataView = clone(dataView);
1const error = new Error("Something went wrong"); 2error.code = "E001"; 3error.details = { timestamp: Date.now() }; 4 5const clonedError = clone(error); 6// → Error with message, stack, and custom properties cloned
1const url = new URL("https://example.com/path?query=value"); 2const clonedUrl = clone(url); 3 4const params = new URLSearchParams("a=1&b=2"); 5const clonedParams = clone(params);
Handles circular references without infinite loops:
1const obj = { name: "parent" }; 2obj.child = { name: "child", parent: obj }; 3obj.self = obj; 4 5const cloned = clone(obj); 6// → Properly cloned with circular references preserved 7cloned.child.parent === cloned; // → true 8cloned.self === cloned; // → true
Object prototypes and property descriptors are preserved:
1class Person { 2 constructor(name) { 3 this.name = name; 4 } 5 6 greet() { 7 return `Hello, I'm ${this.name}`; 8 } 9} 10 11const person = new Person("Alice"); 12const clonedPerson = clone(person); 13 14clonedPerson instanceof Person; // → true 15clonedPerson.greet(); // → "Hello, I'm Alice" 16clonedPerson !== person; // → true
clone<T>(value: T, visited?: WeakMap): T
Creates a deep clone of the provided value.
Parameters:
value
- The value to clonevisited
- (Optional) WeakMap for tracking circular referencesReturns:
Type Safety:
The library provides powerful customization capabilities through createCloneFunction
and the registry system. This allows you to handle custom types or modify existing behavior.
1import { createCloneFunction } from "@ibnlanre/clone"; 2 3// Create a custom clone function 4const customClone = createCloneFunction(); 5 6// Use it like the default clone 7const cloned = customClone(originalObject);
1import { createCloneFunction, CloneRegistry } from "@ibnlanre/clone"; 2 3// Define a custom class 4class MyCustomType { 5 constructor(data) { 6 this.data = data; 7 this.timestamp = Date.now(); 8 } 9} 10 11// Create a custom clone function with registry modifier 12const customClone = createCloneFunction((registry) => { 13 registry.setHandler(MyCustomType, (value, visited, clone) => { 14 // Custom cloning logic for MyCustomType 15 const result = new MyCustomType(clone(value.data, visited)); 16 result.timestamp = value.timestamp; // Preserve original timestamp 17 visited.set(value, result); 18 return result; 19 }); 20}); 21 22// Now MyCustomType instances are cloned with custom logic 23const original = new MyCustomType({ nested: { value: 42 } }); 24const cloned = customClone(original);
The CloneRegistry
class provides methods to manage type handlers:
1import { CloneRegistry, Handlers } from "@ibnlanre/clone"; 2 3const registry = new CloneRegistry(); 4 5// Check if a handler exists 6if (registry.hasHandler(MyCustomType)) { 7 console.log("Handler exists"); 8} 9 10// Set a custom handler 11registry.setHandler(MyCustomType, Handlers.Identity); // Use identity handler 12 13// Get a handler for a value 14const handler = registry.getHandler(someValue);
The library exports pre-built handlers you can reuse:
1import { createCloneFunction, Handlers } from "@ibnlanre/clone"; 2 3const customClone = createCloneFunction((registry) => { 4 // Use identity handler for custom types (no cloning) 5 registry.setHandler(MyImmutableType, Handlers.Identity); 6 7 // Use object handler for plain object-like types 8 registry.setHandler(MyPlainObjectType, Handlers.Object); 9 10 // Use array handler for array-like types 11 registry.setHandler(MyArrayLikeType, Handlers.Array); 12});
1import { createCloneFunction } from "@ibnlanre/clone"; 2 3class DatabaseModel { 4 constructor(id, data) { 5 this.id = id; 6 this.data = data; 7 this._metadata = { created: Date.now() }; 8 } 9} 10 11const dbClone = createCloneFunction((registry) => { 12 registry.setHandler(DatabaseModel, (value, visited, clone) => { 13 // Create new instance with cloned data but preserve ID 14 const result = new DatabaseModel( 15 value.id, // Keep original ID 16 clone(value.data, visited) // Deep clone data 17 ); 18 19 // Clone metadata separately 20 result._metadata = clone(value._metadata, visited); 21 visited.set(value, result); 22 return result; 23 }); 24}); 25 26// Usage 27const original = new DatabaseModel("user_123", { 28 name: "Alice", 29 preferences: { theme: "dark" }, 30}); 31 32const cloned = dbClone(original); 33// cloned.id === original.id (preserved) 34// cloned.data !== original.data (deep cloned)
Custom handlers receive three parameters:
1type CloneHandler<T> = ( 2 value: T, // The value to clone 3 visited: WeakMap<object, any>, // Circular reference tracker 4 clone: CloneFunction // The clone function for recursive cloning 5) => T;
Important: Always call visited.set(value, result)
before recursively cloning properties to prevent infinite loops with circular references.
You can override handlers for built-in types:
1const customClone = createCloneFunction((registry) => { 2 // Custom Date handler that rounds to nearest second 3 registry.setHandler(Date, (value) => { 4 const rounded = new Date(Math.round(value.getTime() / 1000) * 1000); 5 return rounded; 6 }); 7 8 // Custom Array handler that filters out null values 9 registry.setHandler(Array, (value, visited, clone) => { 10 const result = []; 11 visited.set(value, result); 12 13 for (let i = 0; i < value.length; i++) { 14 if (i in value && value[i] !== null) { 15 result[i] = clone(value[i], visited); 16 } 17 } 18 19 return result; 20 }); 21});
This clone utility delivers world-class performance across all JavaScript data types:
When compared to JSON.parse(JSON.stringify())
:
Critical advantage: JSON method fails on functions, dates become strings, no circular references, loses prototypes, etc.
Operation Type | Ops/Second | Avg Time (ms) | Use Case |
---|---|---|---|
Simple Objects | 2,569,159 | 0.0004 | Config, primitives |
Circular Refs | 1,641,419 | 0.0006 | Complex structures |
Functions | 2,305,586 | 0.0004 | Component cloning |
Comprehensive | 93,373 | 0.0107 | All data types |
Complex Objects | 25,396 | 0.0394 | Nested structures |
See PERFORMANCE_REPORT.md for detailed benchmarks and analysis.
WeakMap
for efficient circular reference trackingMIT © Ridwan Olanrewaju
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
13 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10
Reason
license file detected
Details
Reason
1 existing vulnerabilities detected
Details
Reason
Found 0/15 approved changesets -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
security policy file not detected
Details
Reason
branch protection not enabled on development/release branches
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More