  

 \href{https://npmjs.org/package/klona}{\texttt{  }} \href{https://github.com/lukeed/klona/actions}{\texttt{  }} \href{https://npmjs.org/package/klona}{\texttt{  }} \href{https://codecov.io/gh/lukeed/klona}{\texttt{  }} 

A tiny (240B to 501B) and fast utility to \char`\"{}deep clone\char`\"{} Objects, Arrays, Dates, Reg\+Exps, and more!\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15808}{}\doxysubsection{Features}\label{md_sfcode_node_modules_klona_readme_autotoc_md15808}

\begin{DoxyItemize}
\item Super tiny and \href{\#benchmarks}{\texttt{ performant}}
\item Deep clone / recursive copies
\item Safely handles complex data types~\newline
 {\itshape Array, Date, Map, Object, Reg\+Exp, Set, Typed\+Array, and more}
\end{DoxyItemize}

Unlike a \char`\"{}shallow copy\char`\"{} (eg, {\ttfamily Object.\+assign}), a \char`\"{}deep clone\char`\"{} recursively traverses a source input and copies its {\itshape values} --- instead of {\itshape references} to its values --- into a new instance of that input. The result is a structurally equivalent clone that operates independently of the original source and controls its own values.

\begin{quote}
{\bfseries{Why \char`\"{}klona\char`\"{}?}} It\textquotesingle{}s \char`\"{}clone\char`\"{} in Swedish.~\newline
 {\bfseries{What\textquotesingle{}s with the sheep?}} \href{https://en.wikipedia.org/wiki/Dolly_(sheep)}{\texttt{ Dolly}}. \end{quote}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15809}{}\doxysubsection{Install}\label{md_sfcode_node_modules_klona_readme_autotoc_md15809}

\begin{DoxyCode}{0}
\DoxyCodeLine{\$ npm install -\/-\/save klona }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15810}{}\doxysubsection{Modes}\label{md_sfcode_node_modules_klona_readme_autotoc_md15810}
There are multiple \char`\"{}versions\char`\"{} of {\ttfamily klona} available, which allows you to bring only the functionality you need!\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15811}{}\doxyparagraph{$<$tt$>$klona/json$<$/tt$>$}\label{md_sfcode_node_modules_klona_readme_autotoc_md15811}
\begin{quote}
{\bfseries{Size (gzip)\+:}} 240 bytes~\newline
 {\bfseries{Availability\+:}} \href{https://unpkg.com/klona/json/index.js}{\texttt{ Common\+JS}}, \href{https://unpkg.com/klona/json/index.mjs}{\texttt{ ES Module}}, \href{https://unpkg.com/klona/json/index.min.js}{\texttt{ UMD}}~\newline
 {\bfseries{Ability\+:}} JSON data types \end{quote}

\begin{DoxyCode}{0}
\DoxyCodeLine{import \{ klona \} from 'klona/json'; }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15812}{}\doxyparagraph{$<$tt$>$klona/lite$<$/tt$>$}\label{md_sfcode_node_modules_klona_readme_autotoc_md15812}
\begin{quote}
{\bfseries{Size (gzip)\+:}} 354 bytes~\newline
 {\bfseries{Availability\+:}} \href{https://unpkg.com/klona/lite/index.js}{\texttt{ Common\+JS}}, \href{https://unpkg.com/klona/lite/index.mjs}{\texttt{ ES Module}}, \href{https://unpkg.com/klona/lite/index.min.js}{\texttt{ UMD}}~\newline
 {\bfseries{Ability\+:}} extends {\ttfamily klona/json} with support for custom class, Date, and Reg\+Exp \end{quote}

\begin{DoxyCode}{0}
\DoxyCodeLine{import \{ klona \} from 'klona/lite'; }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15813}{}\doxyparagraph{$<$tt$>$klona$<$/tt$>$}\label{md_sfcode_node_modules_klona_readme_autotoc_md15813}
\begin{quote}
{\bfseries{Size (gzip)\+:}} 451 bytes~\newline
 {\bfseries{Availability\+:}} \href{https://unpkg.com/klona/dist/index.js}{\texttt{ Common\+JS}}, \href{https://unpkg.com/klona/dist/index.mjs}{\texttt{ ES Module}}, \href{https://unpkg.com/klona/dist/index.min.js}{\texttt{ UMD}}~\newline
 {\bfseries{Ability\+:}} extends {\ttfamily klona/lite} with support for Map, Set, Data\+View, Array\+Buffer, Typed\+Array \end{quote}

\begin{DoxyCode}{0}
\DoxyCodeLine{import \{ klona \} from 'klona'; }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15814}{}\doxyparagraph{$<$tt$>$klona/full$<$/tt$>$}\label{md_sfcode_node_modules_klona_readme_autotoc_md15814}
\begin{quote}
{\bfseries{Size (gzip)\+:}} 501 bytes~\newline
 {\bfseries{Availability\+:}} \href{https://unpkg.com/klona/full/index.js}{\texttt{ Common\+JS}}, \href{https://unpkg.com/klona/full/index.mjs}{\texttt{ ES Module}}, \href{https://unpkg.com/klona/full/index.min.js}{\texttt{ UMD}}~\newline
 {\bfseries{Ability\+:}} extends {\ttfamily klona} with support for Symbol properties and and non-\/enumerable properties \end{quote}

\begin{DoxyCode}{0}
\DoxyCodeLine{import \{ klona \} from 'klona/full'; }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15815}{}\doxysubsection{Usage}\label{md_sfcode_node_modules_klona_readme_autotoc_md15815}

\begin{DoxyCode}{0}
\DoxyCodeLine{import \{ klona \} from 'klona';}
\DoxyCodeLine{}
\DoxyCodeLine{const input = \{}
\DoxyCodeLine{  foo: 1,}
\DoxyCodeLine{  bar: \{}
\DoxyCodeLine{    baz: 2,}
\DoxyCodeLine{    bat: \{}
\DoxyCodeLine{      hello: 'world'}
\DoxyCodeLine{    \}}
\DoxyCodeLine{  \}}
\DoxyCodeLine{\};}
\DoxyCodeLine{}
\DoxyCodeLine{const output = klona(input);}
\DoxyCodeLine{}
\DoxyCodeLine{// exact copy of original}
\DoxyCodeLine{assert.deepStrictEqual(input, output);}
\DoxyCodeLine{}
\DoxyCodeLine{// applying deep updates...}
\DoxyCodeLine{output.bar.bat.hola = 'mundo';}
\DoxyCodeLine{output.bar.baz = 99;}
\DoxyCodeLine{}
\DoxyCodeLine{// ...doesn't affect source!}
\DoxyCodeLine{console.log(}
\DoxyCodeLine{  JSON.stringify(input, null, 2)}
\DoxyCodeLine{);}
\DoxyCodeLine{// \{}
\DoxyCodeLine{//   "{}foo"{}: 1,}
\DoxyCodeLine{//   "{}bar"{}: \{}
\DoxyCodeLine{//     "{}baz"{}: 2,}
\DoxyCodeLine{//     "{}bat"{}: \{}
\DoxyCodeLine{//       "{}hello"{}: "{}world"{}}
\DoxyCodeLine{//     \}}
\DoxyCodeLine{//   \}}
\DoxyCodeLine{// \} }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15816}{}\doxysubsection{API}\label{md_sfcode_node_modules_klona_readme_autotoc_md15816}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15817}{}\doxysubsubsection{klona(input)}\label{md_sfcode_node_modules_klona_readme_autotoc_md15817}
Returns\+: {\ttfamily typeof input}

Returns a deep copy/clone of the input.\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15818}{}\doxysubsection{Benchmarks}\label{md_sfcode_node_modules_klona_readme_autotoc_md15818}
\begin{quote}
Running Node v12.\+18.\+3 \end{quote}
The benchmarks can be found in the \href{/bench}{\texttt{ {\ttfamily /bench}}} directory. They are separated into multiple categories\+:


\begin{DoxyItemize}
\item {\ttfamily JSON} – compares an array of objects comprised of JSON data types ({\ttfamily String}, {\ttfamily Number}, {\ttfamily null}, {\ttfamily Array}, {\ttfamily Object})
\item {\ttfamily LITE} – like {\ttfamily JSON}, but adds {\ttfamily Reg\+Exp}, {\ttfamily Date} and {\ttfamily undefined} values
\item {\ttfamily DEFAULT} – object with {\ttfamily Reg\+Exp}, {\ttfamily Date}, {\ttfamily Array}, {\ttfamily Map}, {\ttfamily Set}, custom class, {\ttfamily Int8\+Array}, {\ttfamily Data\+View}, {\ttfamily Buffer} values
\item {\ttfamily FULL} – like {\ttfamily DEFAULT}, but adds {\ttfamily Symbol} and non-\/enumerable properties
\end{DoxyItemize}

\begin{quote}
{\bfseries{Important\+:}} Only candidates that pass validation step(s) are listed. ~\newline
However, {\ttfamily lodash} and {\ttfamily clone} are kept to highlight important differences. \end{quote}
\begin{quote}
{\bfseries{Note\+:}} The {\ttfamily clone/include} candidate refers to its \href{https://www.npmjs.com/package/clone\#api}{\texttt{ {\ttfamily include\+Non\+Enumerable} option}} enabled. \end{quote}

\begin{DoxyCode}{0}
\DoxyCodeLine{Load times:}
\DoxyCodeLine{  lodash/clonedeep   29.257ms}
\DoxyCodeLine{  rfdc                0.511ms}
\DoxyCodeLine{  clone               0.576ms}
\DoxyCodeLine{  clone-\/deep          2.494ms}
\DoxyCodeLine{  deep-\/copy           0.451ms}
\DoxyCodeLine{  klona/full          0.408ms}
\DoxyCodeLine{  klona               0.265ms}
\DoxyCodeLine{  klona/lite          0.308ms}
\DoxyCodeLine{  klona/json          0.263ms}
\DoxyCodeLine{}
\DoxyCodeLine{Benchmark :: JSON}
\DoxyCodeLine{  JSON.stringify      x   53,899 ops/sec ±0.76\% (92 runs sampled)}
\DoxyCodeLine{  lodash              x   46,800 ops/sec ±0.86\% (90 runs sampled)}
\DoxyCodeLine{  rfdc                x  221,456 ops/sec ±0.88\% (92 runs sampled)}
\DoxyCodeLine{  clone               x   39,537 ops/sec ±0.68\% (92 runs sampled)}
\DoxyCodeLine{  clone/include       x   25,488 ops/sec ±1.06\% (88 runs sampled)}
\DoxyCodeLine{  clone-\/deep          x   99,998 ops/sec ±0.91\% (93 runs sampled)}
\DoxyCodeLine{  deep-\/copy           x  141,270 ops/sec ±0.95\% (92 runs sampled)}
\DoxyCodeLine{  klona/full          x   55,016 ops/sec ±0.68\% (94 runs sampled)}
\DoxyCodeLine{  klona               x  281,215 ops/sec ±0.77\% (93 runs sampled)}
\DoxyCodeLine{  klona/lite          x  318,481 ops/sec ±0.72\% (91 runs sampled)}
\DoxyCodeLine{  klona/json          x  334,932 ops/sec ±0.66\% (93 runs sampled)}
\DoxyCodeLine{}
\DoxyCodeLine{Benchmark :: LITE}
\DoxyCodeLine{  lodash              x   36,992 ops/sec ±0.65\% (91 runs sampled)}
\DoxyCodeLine{  clone               x   35,974 ops/sec ±1.13\% (88 runs sampled)}
\DoxyCodeLine{  clone/include       x   22,609 ops/sec ±1.02\% (91 runs sampled)}
\DoxyCodeLine{  clone-\/deep          x   92,846 ops/sec ±0.66\% (93 runs sampled)}
\DoxyCodeLine{  klona/full          x   47,873 ops/sec ±0.83\% (88 runs sampled)}
\DoxyCodeLine{  klona               x  226,638 ops/sec ±1.16\% (93 runs sampled)}
\DoxyCodeLine{  klona/lite          x  257,900 ops/sec ±0.82\% (93 runs sampled)}
\DoxyCodeLine{}
\DoxyCodeLine{Benchmark :: DEFAULT}
\DoxyCodeLine{  lodash              x   55,914 ops/sec ±0.75\% (93 runs sampled)}
\DoxyCodeLine{    ✘ Buffer}
\DoxyCodeLine{    ✘ Map keys}
\DoxyCodeLine{  clone               x   92,127 ops/sec ±0.83\% (94 runs sampled)}
\DoxyCodeLine{    ✘ DataView}
\DoxyCodeLine{  clone/include       x   62,052 ops/sec ±0.88\% (93 runs sampled)}
\DoxyCodeLine{    ✘ DataView}
\DoxyCodeLine{  klona/full          x   90,308 ops/sec ±0.68\% (89 runs sampled)}
\DoxyCodeLine{  klona               x  230,257 ops/sec ±0.71\% (91 runs sampled)}
\DoxyCodeLine{}
\DoxyCodeLine{Benchmark :: FULL}
\DoxyCodeLine{  lodash              x   60,361 ops/sec ±0.65\% (91 runs sampled)}
\DoxyCodeLine{    ✘ Buffer}
\DoxyCodeLine{    ✘ Map keys}
\DoxyCodeLine{    ✘ Missing non-\/enumerable Properties}
\DoxyCodeLine{  clone/include       x   47,263 ops/sec ±0.85\% (93 runs sampled)}
\DoxyCodeLine{    ✘ DataView}
\DoxyCodeLine{    ✘ Incorrect non-\/enumerable Properties}
\DoxyCodeLine{  klona/full          x   82,346 ops/sec ±0.62\% (93 runs sampled) }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15819}{}\doxysubsection{Related}\label{md_sfcode_node_modules_klona_readme_autotoc_md15819}

\begin{DoxyItemize}
\item \href{https://github.com/developit/dlv}{\texttt{ dlv}} –~safely {\bfseries{read}} from deep properties in 120 bytes
\item \href{https://github.com/lukeed/dset}{\texttt{ dset}} – safely {\bfseries{write}} into deep properties in 160 bytes
\item \href{https://github.com/lukeed/dequal}{\texttt{ dequal}} – safely check for deep equality in 304 to 489 bytes
\end{DoxyItemize}\hypertarget{md_sfcode_node_modules_klona_readme_autotoc_md15820}{}\doxysubsection{License}\label{md_sfcode_node_modules_klona_readme_autotoc_md15820}
MIT © \href{https://lukeed.com}{\texttt{ Luke Edwards}} 