# replicator

> Advanced JavaScript objects serialization.

Latest version **1.0.5** (published 2021-05-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install replicator
pnpm add replicator
yarn add replicator
bun add replicator
```

## Health

**Score 5/100 (F)** — status: abandoned.

Warnings: low downloads; no types; no esm support; has vulnerabilities.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.5 |
| Published | 2021-05-24 |
| First published | 2016-05-24 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 22.4 KB |
| Known vulnerabilities | 1 |
| Install scripts | no |
| GitHub stars | 25 |
| Author | Ivan Nikulin |
| Maintainers | inikulin, amoskovkin, belym.a.2105 |
| Keywords | JSON, serialization, deserialization, circular, circularJSON, structured-clone, structured, clone |

## Links

- npm: https://www.npmjs.com/package/replicator
- Repository: https://github.com/inikulin/replicator
- Homepage: https://github.com/inikulin/replicator#readme
- Issues: https://github.com/inikulin/replicator/issues
- npm.io page: https://npm.io/package/replicator

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 1.0.5 (latest) — 2021-05-24
- 1.0.4 — 2021-05-17
- 1.0.3 — 2018-12-17
- 1.0.2 — 2018-04-27
- 1.0.1 — 2016-07-11
- 1.0.0 — 2016-05-24

## README

<p align="center">
    <a href="https://github.com/inikulin/replicator">
        <img src="https://raw.github.com/inikulin/replicator/master/media/logo.png" alt="replicator" />
    </a>
</p>
<p align="center">
<i>Advanced JavaScript objects serialization</i>
</p>
<p align="center">
  <a href="https://github.com/inikulin/replicator/commits/master"><img alt="GitHub branch checks state" src="https://img.shields.io/github/checks-status/inikulin/replicator/master?label=tests"></a>
  <a href="https://www.npmjs.com/package/replicator"><img alt="NPM Version" src="https://img.shields.io/npm/v/replicator.svg"></a>
</p>

- Can serialize circular references
- In addition to JSON-serializable types can serialize:
  - `undefined`
  - `NaN`
  - `Date`
  - `RegExp`
  - `Error`<sup>[1](#note1)</sup>
  - `Map`<sup>[2](#note2)</sup>
  - `Set`<sup>[3](#note3)</sup>
  - `ArrayBuffer`<sup>[3](#note3)</sup>
  - Typed arrays<sup>[3](#note3)</sup>
- [Can be extended with custom type transforms](#adding-custom-types-support)
- [Can use any target serializer under the hood](#changing-serialization-format) (JSON, BSON, protobuf, etc.)

----
<a name="note1">1</a>: If decoding target platform doesn't support encoded error type, it will fallback to `Error` constructor.<br>
<a name="note2">2</a>: If decoding target platform doesn't support `Map`, it will be decoded as array of `[key, value]`.<br>
<a name="note3">3</a>: If decoding target platform doesn't support `Set`, `ArrayBuffer` or typed arrays, they will be decoded as array. <br>

## Install
```shell
npm install replicator
```

## Usage
```js
const Replicator = require('replicator');

const replicator = new Replicator();

const a = {};
a.b = a;

const str = replicator.encode({
    key1: new Set([1, 2, 3]),
    key2: /\s+/ig,
    key3: a
});

const obj = replicator.decode(str);
```


## Adding custom types support
You can extend `replicator` with custom type transform which will describe how to serialize/deserialize objects. You can
add transforms using `.addTransforms(transforms)` method. And remove them using `.removeTransforms(transforms)` method.
Both methods are chainable and accept single transform or array of transforms. You should add transforms to both encoding
and decoding instances of `replicator`.

Let's create transform which will encode `NodeList` of elements and decode it as array of objects with `tagName` property:
```js
const Replicator = require('replicator');

const replicator = new Replicator();

replicator.addTransforms([
    {
        type: 'NodeList',

        shouldTransform (type, val) {
            return typeof NodeList === 'function' && val instanceof NodeList;
        },

        toSerializable (nodeList) {
            // We should transform NodeList to primitive serializable object.
            // It's an array of HTMLElement in our case.
            // Note that it's not required to transform each element in
            // NodeList. We can add HTMLElement transform which
            // will transform NodeList items and individual elements as well.
            return Array.prototype.slice.call(nodeList);
        },

        fromSerializable (val){
            // Now we should describe how to restore NodeList from serializable object.
            // In our case we just need an array so we'll return it as is.
            // If you want to restore it as NodeList you can create document fragment, append
            // array contents to it and return result of `fragment.querySelectorAll('*')` .
            return val;
        }
    },

    {
        type: 'Element',

        shouldTransform (type, val){
            return typeof HTMLElement === 'function' && val instanceof HTMLElement;
        },

        toSerializable (element) {
            return element.tagName;
        },

        fromSerializable (val) {
            return { tagName: val };
        }
    }
]);

var str = replicator.encode(document.querySelectorAll('div'));

console.log(replicator.decode(str));
// > [ { tagName: 'div'}, { tagName: 'div'}, { tagName: 'div'}]
```

Built-in types support implemented using transforms, so you can take a look on `replicator` source code for more examples.

## Changing serialization format
By default `replicator` uses JSON under the hood. But you can use any serializer by passing serializer adapter to `Replicator`
constructor. E.g., let's use [BSON](https://www.npmjs.com/package/bson) as serializer:
```js
const Replicator = require('replicator');
const BSON       = require('bson');

const replicator = new Replicator({
    serialize (val) {
        return BSON.serialize(val, false, true, false);
    },

    deserialize: BSON.deserialize
});

replicator.encode(['yo', 42]);
// > <Buffer>
```

## Author
[Ivan Nikulin](https://github.com/inikulin) (ifaaan@gmail.com)

---
_Source: https://npm.io/package/replicator · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
