CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.

Pending
Overview
Eval results
Files

object-operations.mddocs/

Object Operations

Methods for working with immutable objects including merging, property manipulation, and transformations.

Capabilities

merge

Merges objects immutably, with priority given to the provided object's values.

/**
 * Merge objects immutably with configurable behavior
 * @param {Object} obj - Target object to merge into
 * @param {Object|Array} other - Object or array of objects to merge
 * @param {Object} [config] - Merge configuration options
 * @param {boolean} [config.deep] - Perform deep merge of nested objects
 * @param {string} [config.mode] - Merge mode: 'merge' (default) or 'replace'
 * @param {Function} [config.merger] - Custom merger function for property conflicts
 * @returns {Object} New immutable object with merged properties
 */
function merge(obj, other, config);

Usage Examples:

const Immutable = require("seamless-immutable");

const obj = Immutable({status: "good", hypothesis: "plausible", errors: 0});

// Basic merge
const merged = obj.merge({status: "funky", hypothesis: "confirmed"});
// Result: {status: "funky", hypothesis: "confirmed", errors: 0}

// Merge multiple objects using array
const multiMerged = obj.merge([
  {status: "funky", errors: 1}, 
  {status: "groovy", errors: 2}, 
  {status: "sweet"}
]);
// Result: {status: "sweet", errors: 2, hypothesis: "plausible"}

// Deep merge nested objects
const nested = Immutable({
  user: {name: "Alice", age: 30},
  settings: {theme: "dark", lang: "en"}
});
const deepMerged = nested.merge({
  user: {age: 31, city: "NYC"}
}, {deep: true});
// Result: {user: {name: "Alice", age: 31, city: "NYC"}, settings: {theme: "dark", lang: "en"}}

// Replace mode - removes properties not in the new object
const replaced = obj.merge({status: "new"}, {mode: 'replace'});
// Result: {status: "new"} - other properties removed

// Custom merger function
const customMerged = obj.merge({errors: 5}, {
  merger: (oldVal, newVal) => {
    if (typeof oldVal === 'number' && typeof newVal === 'number') {
      return oldVal + newVal; // Add numbers instead of replacing
    }
    return newVal;
  }
});
// Result: {status: "good", hypothesis: "plausible", errors: 5} (0 + 5)

replace

Replaces object properties entirely, equivalent to merge with {mode: 'replace'}.

/**
 * Replace object properties entirely
 * @param {Object} obj - Target object
 * @param {Object} value - New properties to replace with
 * @param {Object} [config] - Configuration options
 * @param {boolean} [config.deep] - Perform deep comparison and preserve identical nested objects
 * @returns {Object} New immutable object containing only the replacement properties
 */
function replace(obj, value, config);

Usage Examples:

const Immutable = require("seamless-immutable");

const obj1 = Immutable({a: {b: 'test'}, c: 'test'});
const obj2 = obj1.replace({a: {b: 'test'}});
// Result: {a: {b: 'test'}} - property 'c' removed

// With deep option - preserves identical nested objects for performance
const obj3 = obj1.replace({a: {b: 'test'}}, {deep: true});
console.log(obj1.a === obj3.a); // true - same nested object reference preserved

set

Sets a single property on an object immutably.

/**
 * Set a property on an object immutably
 * @param {Object} obj - Target object
 * @param {string} property - Property key to set
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @param {boolean} [config.deep] - Deep merge if setting an object value
 * @returns {Object} New immutable object with property set
 */
function set(obj, property, value, config);

Usage Examples:

const Immutable = require("seamless-immutable");

const obj = Immutable({type: "parrot", subtype: "Norwegian Blue", status: "alive"});

// Basic property setting
const updated = obj.set("status", "dead");
// Result: {type: "parrot", subtype: "Norwegian Blue", status: "dead"}

// Deep merge when setting object values
const withAddress = obj.set("address", {city: "London", country: "UK"}, {deep: true});

// Static method usage
const staticUpdate = Immutable.set(obj, "status", "sleeping");

without

Removes properties from an object immutably.

/**
 * Remove properties from an object immutably
 * @param {Object} obj - Target object
 * @param {...string|Array|Function} keys - Property keys to remove, array of keys, or predicate function
 * @returns {Object} New immutable object without specified properties
 */
function without(obj, ...keys);

Usage Examples:

const Immutable = require("seamless-immutable");

const obj = Immutable({the: "forests", will: "echo", with: "laughter"});

// Remove single property
const without1 = obj.without("with");
// Result: {the: "forests", will: "echo"}

// Remove multiple properties as separate arguments
const without2 = obj.without("will", "with");
// Result: {the: "forests"}

// Remove multiple properties as array
const without3 = obj.without(["will", "with"]);
// Result: {the: "forests"}

// Remove using predicate function
const without4 = obj.without((value, key) => key === "the" || value === "echo");
// Result: {with: "laughter"}

// Numeric keys are handled correctly
const objWithNumbers = Immutable({0: "zero", 1: "one", name: "test"});
const withoutNumbers = objWithNumbers.without(0, 1);
// Result: {name: "test"}

update

Updates a property using an updater function.

/**
 * Update a property using an updater function
 * @param {Object} obj - Target object
 * @param {string} property - Property key to update
 * @param {Function} updater - Function that receives current value and returns new value
 * @param {...*} [args] - Additional arguments passed to updater function
 * @returns {Object} New immutable object with updated property
 */
function update(obj, property, updater, ...args);

Usage Examples:

const Immutable = require("seamless-immutable");

// Simple increment
function inc(x) { return x + 1; }
const obj = Immutable({foo: 1});
const incremented = obj.update("foo", inc);
// Result: {foo: 2}

// Updater with additional arguments  
function add(x, y) { return x + y; }
const added = obj.update("foo", add, 10);
// Result: {foo: 11}

// String manipulation
const user = Immutable({name: "alice"});
const capitalized = user.update("name", name => name.toUpperCase());
// Result: {name: "ALICE"}

// Working with arrays
const data = Immutable({items: [1, 2, 3]});
const withNewItem = data.update("items", items => items.concat(4));
// Result: {items: [1, 2, 3, 4]}

asMutable (Object-specific)

Converts an immutable object to a mutable copy.

/**
 * Convert immutable object to mutable copy
 * @param {Object} obj - Immutable object to convert
 * @param {Object} [options] - Conversion options
 * @param {boolean} [options.deep] - Recursively convert nested immutable structures
 * @returns {Object} Mutable copy of the object
 */
function asMutable(obj, options);

Usage Examples:

const Immutable = require("seamless-immutable");

const obj = Immutable({when: "the", levee: "breaks"});
const mutableObject = obj.asMutable();

// Now can mutate directly
mutableObject.have = "no place to go";
console.log(mutableObject); // {when: "the", levee: "breaks", have: "no place to go"}

// Deep conversion for nested structures
const nested = Immutable({
  user: {name: "Alice"},
  hobbies: ["reading", "coding"]
});

const shallowMutable = nested.asMutable();
// shallowMutable.user.name = "Bob"; // Would still throw - nested objects still immutable

const deepMutable = nested.asMutable({deep: true});
deepMutable.user.name = "Bob"; // Works - all nested structures are now mutable
deepMutable.hobbies.push("gaming"); // Also works

Instance vs Static Methods

All object methods are available in both instance and static forms:

const Immutable = require("seamless-immutable");
const obj = Immutable({name: "Alice", age: 30});

// Instance methods (default API)
const merged1 = obj.merge({age: 31});
const updated1 = obj.set("status", "active");
const filtered1 = obj.without("age");

// Static methods (static API - avoids method pollution)
const Immutable = require("seamless-immutable").static;
const merged2 = Immutable.merge(obj, {age: 31});
const updated2 = Immutable.set(obj, "status", "active");  
const filtered2 = Immutable.without(obj, "age");

Both approaches are functionally identical - choose based on your preference for avoiding method name collisions or preferring shorter syntax.

Install with Tessl CLI

npx tessl i tessl/npm-seamless-immutable

docs

array-operations.md

core.md

index.md

nested-operations.md

object-operations.md

tile.json