stampit API
  • Introduction
  • Essentials
    • What is a Stamp
    • Installation
    • Specification
      • Merging algorithm
      • Object creation internals
    • FAQ
  • API
    • Quick start
    • Basics
    • Methods
    • Properties
    • Deep properties
    • Initializers
    • Static properties
    • Static deep properties
    • Configuration
    • Deep configuration
    • Composers
    • Property descriptors
    • Static property descriptors
    • Name
  • Ecosystem
    • Ecosystem Overview
    • @stamp/collision
    • @stamp/required
    • @stamp/privatize
    • @stamp/named (DEPRECATED)
    • @stamp/instanceof
Powered by GitBook
On this page
  • Array concatenation and deduplication
  • Deep merging algorithm
  1. Essentials
  2. Specification

Merging algorithm

PreviousSpecificationNextObject creation internals

Last updated 5 years ago

When composing stamps you actually merge their (aka metadata).

The Object.assign is used for these descriptor properties:

The special deep merging algorithm (see below) is used for these descriptor properties:

The array concatenation and deduplication (see below) is used for these descriptor properties:

Array concatenation and deduplication

This is how initializers and composers metadata gets merged.

const _ = require('lodash')

descriptor.initializers = _.uniq(_.concat(descriptor1.initializers, descriptor2.initializers))
descriptor.composers = _.uniq(_.concat(descriptor1.composers, descriptor2.composers))

Deep merging algorithm

  • Plain objects are (recursively) deep merged, including ES6 Symbol keys, ES5 getters and setters.

  • Arrays are concatenated.

  • Functions, Symbols, RegExp, etc. values are copied by reference.

  • The last object type overwrites previous object type.

const MyStamp1 = stampit()

const deepObject1 = {
  [Symbol('foo')]: { one: 'first' },                 // this plain object will be deep merged

  array: [0, 'bar', () => {}, { obj: 'my object' }], // this array will be concatenated with

  func: MyStamp1,                                    // this stamp will be replaced with another stamp

  something: [42],                                   // this array will be replaced with an object

  oldKey: 'some value'
}

const MyStamp2 = stampit()

const deepObject2 = {
  [Symbol('foo')]: { two: 'second' },

  array: [0, 'bar', { another: 'object' }],

  func: MyStamp2,

  something: { [0]: 42 },

  newKey: 'some value'
}

The merged result of the two objects above will be this:

const deepResult = {
  [Symbol('foo')]: { one: 'first', two: 'second' }, // contains properties from both objects

  array: [0, 'bar', () => {}, { obj: 'my object' }, 0, 'bar', { another: 'object' }], // both arrays are here

  func: MyStamp2,                                   // Stamp2 replaced the Stamp1

  something: { [0]: 42 },                           // the array was replaced with the object

  oldKey: 'some value',                             // these two were simply carried across
  newKey: 'some value'
}

See the of the reference implementation source code.

The standardized the deep merging algorithm to, basically, this:

See the of the reference implementation source code.

descriptors
methods
properties
propertyDescriptors
staticProperties
staticPropertyDescriptors
configuration
deepProperties
staticDeepProperties
deepConfiguration
initializers
composers
exact line
stamp specification
exact line