PitchHut logo
Log in / Sign up
datum-merge
by alternative_plum_minne
Easily merge and diff deeply nested objects in TypeScript.
Pitch

datum-merge is a modern typescript library that simplifies merge and diff operations for deeply nested objects. Supports object configuration to customize the behavior for primitive, array and nested attributes including specific keys or key patterns.

Description

datum-merge is a modern typescript library that simplifies merge and diff operations for deeply nested objects.

Source Code : https://github.com/therohk/datum-merge

NPM library : https://www.npmjs.com/package/datum-merge


Sample Usage

Merge with default config:

import { merge, detailMerge, UpdateCode } from "datum-merge";
let changed = merge(target, source, UpdateCode.I, UpdateCode.XM, UpdateCode.B);
//same as
changed = customMerge(target, source, { 
    scalar: UpdateCode.I, 
    vector: UpdateCode.XM, 
    nested: UpdateCode.B 
});

Exact nestable config that ignores all other fields:

changed = detailMerge(target, source, {
    mykey: UpdateCode.I, 
    myarr: UpdateCode.XM, 
    anobj: UpdateCode.B,
    myobj: { myid: UpdateCode.I },
});

Deep merge with generic config patterns:

import { customMerge, MergeConfig, UpdateCode } from "datum-merge";
const conf: MergeConfig = {
    "*_id": UpdateCode.I,
    scalar: UpdateCode.B,
    field1: UpdateCode.D,
    "arr*": UpdateCode.XM,
    nested: UpdatedCode.N,
    obj1: {
        scalar: UpdateCode.B,
        vector: UpdateCode.XM,
    },
};
let diff = customMerge(target, source, conf);

Upcoming Features

  1. inline the unmaintained deep-diff library which contains serious bugs. (available)

  2. support merging for top level arrays or primitives.

  3. option to throw error if field datatype changes during merge.

  4. project should compile in strict mode.

  5. formalize config schema for deeply nested objects (for v1).

Code contributions are welcome via issues and pull requests.


Merge Strategy

This string code describes how modifications to an attribute for a PUT/UPDATE operation should be handled. It decides whether a change to the value of the field is allowed during a merge between two entities.

Strategy Codes

The same field within a source and target object is represented by s and t respectively. Whether the strategy requires data to be present for the field, is shown by { 0=no, 1=yes, X=irrelavant }. The value is migrated from the source field to the target field only if the predicate passes.

Code ValuePredicateMeaning
Cn/aalways create new instance
Tn/atouch datum ; empty merge
N0reject any change ; skip merge
YsX & tXaccept any change ; bypass merge
Bs1 & tXinsert or update, no delete
Hs1 & t1update only if exists
UsX & t1update or delete only, no insert
IsX & t0insert only, no update or delete
Ds0 & tXdelete only, no update or insert
XRsX & tXfull vector replacement
XMs ∪ tset union, vector merge
XDs - tset difference, delete given values
XIs ∩ tset intersection, delete missing values
XSt + spreserve order insert (allows dupes)
XFs + tinsert from start (allows dupes)

Diff Codes

Applying the merge results in one of these transitions per primitive value in the target object.

Code ValueMeaningTransitions
Znoop / ignorenull <-- null or non-null == non-null
Nnew / insertnull <-- non-null
Eedit / updatenon-null <-- non-null
Dunset / deletenon-null <-- null
ANarray size increase (tbd)non-null > non-null
ADarray size decrease (tbd)non-null < non-null

0 comments

No comments yet.

Sign in to be the first to comment.