Fast, deep, scalable object cloning for JavaScript

Overview

@golden-ants/clone

Node.js CI npm version FOSSA Status install size License: MIT

A new approach to deep cloning. A simple library with no external dependencies gives you the opportunity to customize the cloning strategy.

Table of Contents

Installing

Using npm:

npm install --save @golden-ants/clone

Using yarn:

yarn add @golden-ants/clone

Usage

You need to create a switcher tree that simulates copying the contents of each object property.

Object.create({})), }, { /** For JavaScript objects created without a parent prototype.*/ if: and(isObject, createdBy(undefined)), handler: retryFor(() => Object.create(null)), }, //{ // /**We repeat the parent signature of the predicate in case // * none of the conditions are met to throw an exception. Another way is for the // * other objects to copy the value by reference. */ // if: isObject, // handler: (value) => { // /**This is the default behavior, if no condition is met, // * an exception will be thrown. */ // //throw new SwitcherNotFoundException(value) // no need to write this // // or // //return value // }, //}, ], }, ] export const deepClone = new Clone(switchers)">
const switchers: Switcher[] = [
  {
    if: not(isObject), // all primitive types
    handler: (val) => val, // copying by value
  },
  {
    if: isObject,
    then: [
      {
        // copying functions, but not constructor functions
        if: createdBy(Function), // (val) => val.constructor === Function
        handler: (val) => val, // copying by reference
      },
      {
        if: createdBy(Date), // (val) => val.constructor === Date
        handler: (val) => new Date(val as Date),
      },
      {
        if: instanceOf(Array), // (val) => val instanceof Array
        /** Copy the (value) to a new empty array by
         *  calling the cloning method with the same
         *  switcher scheme.*/
        handler: retryFor(() => Array.of()),
      },
      {
        /** For JavaScript objects created using standard methods.
         * We do not use "instanceOf(Object)" because we are not
         * sure that there will be no more instances of specific
         * classes in the input stream.
         */
        if: createdBy(Object),
        handler: retryFor(() => Object.create({})),
      },
      {
        /** For JavaScript objects created without a parent prototype.*/
        if: and(isObject, createdBy(undefined)),
        handler: retryFor(() => Object.create(null)),
      },
      //{
      //  /**We repeat the parent signature of the predicate in case
      //   * none of the conditions are met to throw an exception. Another way is for the
      //   * other objects to copy the value by reference. */
      //  if: isObject,
      //  handler: (value) => {
      //    /**This is the default behavior, if no condition is met,
      //     * an exception will be thrown. */
      //    //throw new SwitcherNotFoundException(value) // no need to write this
      //    // or
      //    //return value
      //  },
      //},
    ],
  },
]

export const deepClone = new Clone(switchers)

Calling the created deepClone for deep copying of objects or arrays.

Note: The target of copying can be an array or an object, but array elements or object property keys can only be those types that meet the conditions of the switchers.

import { deepClone } from ...

// object (array) of any nesting level
const foo = {
  nil: null,
  indefinite: undefined,
  foo() { return 'bar' },
  array: [
    { date: new Date(), storage: Object.create(null) },
    { date: new Date(), storage: Object.create(null) },
    { date: new Date(), storage: Object.create(null) },
  ],
}
const copied = deepClone.it({}, foo);

Switcher

Switchers are necessary for the unique processing of an object's property.

Each switcher contains an if property that accepts a predicate function, the second property can be either a handler or an array of nested switchers.

{
  if: [Predicate: (value) => boolean],
  handler: [Handler: (value, clone) => unknown)
}

or

{
  if: [Predicate: (value) => boolean],
  then: [Switchers]
}

Warning: If you define the then and handler properties in an Switcher, the consequences will be unpredictable

Clone

An instance of the Clone class contains a single public member - the it method.

Cloning occurs superficially, a handler is applied to each property of the source, the result of which is assigned to the target. But thanks to the hook, you can call the cloning again, but for a nested object.

const clone = new Clone(...)

const target = {}
const source = { foo: "bar" }

const copied = clone.it(target, source)

copied === target // true
copied === source // false

And so the handler can cause cloning for a nested object.

{
  if: isObject,
  handler: (value, clone) => clone.it({}, value),
  // handler: retryFor(() => ({}))
}

Functional utilities

Predicates

function createdBy(constructor) {}

function instanceOf(type) {}

// also: isObject, isRecord, isNull, isUndefined, isNumber, isString, isBoolean, isSymbol

Compose

function and(...fs: Predicates): Predicate {}

function or(...fs: Predicates): Predicate {}

function not(predicate: Predicate): Predicate {}

function xor(first: Predicate, second: Predicate): Predicate {}

Handlers

function retryFor(producer: () => object): Handler {}

License

FOSSA Status

You might also like...

Create a deep copy of a set of matched elements with the dynamic state of all form elements copied to the cloned elements.

jq-deepest-copy FUNCTION: Create a deep copy of a set of matched elements while preserving the dynamic state of any matched form elements. Example Use

Oct 28, 2022

Simple shopping cart prototype which shows how React components and Redux can be used to build a friendly user experience with instant visual updates and scalable code in e-commerce applications.

Simple shopping cart prototype which shows how React components and Redux can be used to build a friendly user experience with instant visual updates and scalable code in e-commerce applications.

This simple shopping cart prototype shows how React components and Redux can be used to build a friendly user experience with instant visual updates a

Feb 8, 2022

Inferrd makes Machine Learning deployment easy and scalable.

Inferrd makes Machine Learning deployment easy and scalable.

Introduction ML Deployment made simple, scalable and collaborative The new open-source standard to deploy, monitor and secure Machine Learning service

Dec 16, 2022

Set up and build a Node.js REST API using Typescript, Express, Mongoose with a maintainable and scalable structure.

Introduction Create a maintainable and scalable Node.js REST API with TypeScript, Express and Mongoose. The project structure is based on MVC and foll

Nov 18, 2022

Toolkit for building scalable web applications with TypeScript, React, Redux and Apollo-Client

Toolkit for building scalable web applications with TypeScript, React, Redux and Apollo-Client

TsToolbox Toolkit for building scalable web applications with TypeScript, React, Redux and Apollo-Client (inspired by ReKit) ⚠ ⚠ ⚠ Work in Progress ⚠

Apr 14, 2022

A socially-scalable music NFT indexer.

neume-network-core installation Prerequsites neume-network-core is dependent on an Ethereum full node JSON-RPC interface. Consider running your own no

Nov 17, 2022

Create a maintainable and scalable Node.js GraphQL API with TypeScript, Express, Mongoose and Apollo Server.

Set up and build a Node.js GraphQL API using Typescript, Express, Mongoose with a maintainable and scalable structure

Nov 4, 2022

Scalable Backend Framework for Node.Js

Scalable Backend Framework for Node.Js

Promethium A Backend Web Framework for TypeScript/Node.js This project was generated using Nx. 🔎 Smart, Fast and Extensible Build System Adding capab

Nov 4, 2022

Horizontally scalable blockchain using STARK's and partitioned transactional memory

Horizontally scalable blockchain using STARK's and partitioned transactional memory

quark quark - quick STARK! A decentralized horizontally-scaled state machine that can transfer 1,000,000 unique tokens on Uniswap in a single atomic t

Nov 25, 2022
Owner
Egor Efimenko
Egor Efimenko
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A utility for cloning all your repos, including issues, discussions, stargazers and more!

github-takeout A utility for cloning all your repos, including issues, discussions, stargazers and more! The tool gives you the ability to download a

Lukas Bach 5 Oct 26, 2022
Types generator will help user to create TS types from JSON. Just paste your single object JSON the Types generator will auto-generate the interfaces for you. You can give a name for the root object

Types generator Types generator is a utility tool that will help User to create TS Interfaces from JSON. All you have to do is paste your single objec

Vineeth.TR 16 Dec 6, 2022
Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more

Apache MXNet (incubating) for Deep Learning Apache MXNet is a deep learning framework designed for both efficiency and flexibility. It allows you to m

The Apache Software Foundation 20.2k Jan 5, 2023
Defacement detection with deep learning

In0ri is a defacement detection system utilizing a image-classification convolutional neural network. Introduction When monitoring a website, In0ri wi

Just4Fun Security 47 Nov 30, 2022
clubhouse + google deep voice + gpt3

Omega This repo is code for a machine learning social "turing" test run on Clubhouse. It's a conversational bot that leverages GPT-3 to reply contextu

Thomas Davis 37 Nov 17, 2022
A command-line tool to convert Project Zomboid map data into Deep Zoom format

pzmap2dzi pzmap2dzi is a command-line tool running on Windows to convert Project Zomboid map data into Deep Zoom format. Features Supports both python

Min Xiang 14 Dec 31, 2022
jQuery Address - Deep linking for the masses

jQuery Address The jQuery Address plugin provides powerful deep linking capabilities and allows the creation of unique virtual addresses that can poin

Rostislav Hristov 820 Oct 20, 2022
🌊 Deep dive NextJS

Next 101 ?? Deep dive NextJS Contents Intro Intermediate Advanced Getting Started clone this repo # install dependencies > npm i # or > npm install >

Beatriz Oliveira 7 Dec 12, 2022