npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

blitz-copy

v2.0.2

Published

Ultra fast ES6 deep copier.

Downloads

8

Readme

blitz-copy 2.0.1

This package provides deep copiers that handle all ES6 = ECMA-2015 data types, and supplies NPM's fastest deep copiers, but see the Speed section for caveats.

Currently, blitz-copy, and the author's deep-copy-system are the only true deep copier packages that are correct, as defined by this packages small test suite. However, a shout-out to true-clone, which is fully correct except for an obscure issue that previous versions of blitz-copy and deep-system-copy also missed.

Exports

|export|description| |---|---| |blitzCopy(x)| Equivalent to blitzCopyExt(x, {cd:true})| |blitzCopyExt(x, params)| has parameters for describing what is to be copied | ||| ||| |params fields|description (all fields if unspecified default to false)| |cd| If true, all circular and duplicate references are copied| |pd| If true, property descriptors are copied| |freeze| If true, frozen/sealed/extensible states are copied| |allProperties|If true, properties come from Object.getOwnPropertyNames. Otherwise from Object.keys the former gives all properties, the latter only the enumerable ones| |deepFreeze|For functional programmers who like their deep copies deep-frozen, set params.deepFreeze to true.| |warn_indices_config| If true gives warning that indices of Arrays may be reconfigured (array is whacked)| |warn_array_extras|If true gives warning that Arrays have been given extra non-index properties (array is whacked)|

So blitzCopyExt() is highly configurable, and you can create your own wrapper around it to set the properties you are most interested in. So for example true-clone and fast-copy would be equivalent to

function likeTrueClone(x)
{
    return blitzCopyExt(x, {cd:true, pd:true, warn_indices_config:true, 
        warn_array_extras:true})
}

function likeFastCopy(x)
{
    return blitzCopyExt(x, {cd:true})
}

Set cd, pd, allProperties, warn_indices_config, and warn_array_extras to false/unspecified whenever possible for significant speed gains. So blitzCopyExt(x) with no parameters specified is fastest.

Usage

    npm install blitz-coopy
    const {blitzCopy, blitzCopyExt} = require('blitz-copy')

    x = complicated object built from plain objects, secondary objects, 
        and ES6 data types. 
    
    const y = blitzCopy(x)  // y is deep copy of x
           
    x = complicated object built from plain objects, secondary objects, 
        and ES6 data types.
    
    const y = blitzCopy(x, {cd:false, pd:true, freezers:true, 
        allProperties:true,  warn_indices_config:true}
    
     /*   Explanation of Parameters:  
          
      cd:false -> CD (circular/duplicate) references are not handled 
        because one is sure that there are no such references. 
     
      pd:true -> PDs (property descriptors) are copied. 
     
      freezers:true -> Frozen/sealed/extensible states are copied. 
     
      deepFreeze:unspecified -> y will not be deep frozen
      unless x is.
     
      allProperties:true -> All properties, not just the enumerable 
        ones, are copied.       
     
      warn_indices_config:true ->  gives warning that indices of
      arrays/typed arrays may have been reconfigured.
     
      warn_array_extras:unspecified -> there are no array
      extras.
      */

A secondary object is an object created with Object.create().

Complicated for example means Booleans can have DataView properties, Sets can have members that are Maps and DataViews. Maps can have keys that are ArrayBufers, and TypedArrays, while having values that are Maps, Sets... whatever. The ends of circular or duplicate references can be the keys of Sets, or the keys and values of Maps

WeakSets, and WeakMaps are copy primitives, meaning copied as is since the programmer can't read their internal states. Promises are also copied as is.

Getters/Setters

If you want to copy getters/setters, then you must set params.pd to true because getters/setters are copied by copying property descriptors. If your getter/setter is not inlined but rather created with Object.defineProperty(), Object.defineProperties, or Object.create() where the enumerable flag is not set to true, then you must also set params.allProperties to true to ensure that properties come from Object.getOwnPropertyNames.

Speed

Currently, no other deep copier copies DataViews and Typed Arrays correctly: this includes previous versions of blitz-copy. It's tricky because you have to take into account that their buffers may be shared amongst themselves resulting in circular/duplicate array buffer references: these circular/duplicate references must themselves be copied. The correctness of blitzCopy() slows down the function so that blitzCopy() may be slower than a competitor when only typed arrays and data views are involved.

When Error classes are involved, some competitors may be faster because they don't actually copy the errors, but rather copy as is: Calling an Error class constructor is very-very-super expensive because it traces the call stack.

Copiers in review

Out of thirty-five copying packages examined, only eleven are deep copiers that supposedly handle ES6 data types. Some by design do not copy properties of the data-types and so are more like JSON deep copiers. E.g., if x is a Set and x.a = 7 then x.a is not copied because it is not examined. With the authors particular design in mind, nine are so buggy they aren't in the ball-park. The two exceptions are true-clone and fast-copy.

The second most correct true deep-copier package on NPM is true-clone. Except for blitz-copy, true-clone is the only package that passes this packages small test suite with flying colors. However, it doesn't deal with DataViews and Typed arrays correctly as described in the previous section. When data views and typed arrays are not involved, blitz-copy can be 27% faster.

The third most correct deep copier is fast-copy, though it is not a true deep copier because it is not designed to copy properties of data-types. Even so, without typed arrays involved, blitz-copy can still be faster: 11% faster is typical. fast-copy is not fully correct with its design in mind. If x = new String("cat") then fast copying x results in y where y.valueOf() isn't "cat" but rather to the empty string "". The fast copy of new Number(7) has valueOf equal to 0 not 7. Those are the only two bugs found in fast-copy other than dealing with typed-arrays/data-views as previously described.

Lastly an Example

    const x = [1,2,3];
        
    Object.defineProperty(x, "hamster", {
                value: "piper"
    });
    
    const z = blitzCopyExt(x, {warn_array_extras:true, 
        pd:true, allProperties:true,});
    
    In the object tree:
    
    there is a non-index property "hamster" on an array
    or typed array. so warn_array_extras  must be set to true.
    
    there is a property descriptor "hamster so pd must be true. 
   
    there is a non-enumerable property "hamster" so allProperties 
    must be set to true.    

Version History

|Version| Published|Description| |---|---|---| |1.0.0|3-27-2022|Derived from deep-copy-system for speed without the need to deep-copy ES5 and ES6 classes| |1.0.1| 3-28-2022|Rewrote code in the ReadMe file so the scroll bar wouldn't appear | |1.0.2 |3-28-2022|Edited the ReadMe file | |1.1.0 |3-31-2022|Client can now set params.nonStandardArrays = true to warn of non-standard arrays/typed-arrays. Not setting it, if possible, results in significant speed gains.| |2.0.0|4-1-2022|The nonStandardArrays property has been replaced with two properties warn_config_indices and warn_array_extras. If it is possible to set these last two to false there can be significant speed gains.| |2.0.1|5-6-2022|Fixed: didn't take into account the fact that array buffers can be shared amongst data views and typed arrays. This results in a slowdown, but blitzCopy() is still fastest.|