or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdcore.mdindex.mdnested-operations.mdobject-operations.md
tile.json

tessl/npm-seamless-immutable

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

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/seamless-immutable@7.1.x

To install, run

npx @tessl/cli install tessl/npm-seamless-immutable@7.1.0

index.mddocs/

Seamless Immutable

Seamless Immutable provides backwards-compatible immutable data structures for JavaScript. Unlike other immutable libraries, seamless-immutable objects can be used in for loops, passed to functions expecting vanilla JavaScript data structures, and serialized with JSON.stringify. The library leverages ECMAScript 5 features like Object.defineProperty and Object.freeze to enforce immutability while preserving familiar JavaScript APIs.

Package Information

  • Package Name: seamless-immutable
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install seamless-immutable

Core Imports

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

For static API (recommended to avoid method collision):

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

ES6 import:

import Immutable from "seamless-immutable";

Basic Usage

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

// Create immutable array - still works with for loops and JSON.stringify
const array = Immutable(["totally", "immutable", {hammer: "Can't Touch This"}]);

array[1] = "I'm going to mutate you!";
console.log(array[1]); // "immutable" - unchanged

// Works with for loops
for (let index in array) {
  console.log(array[index]);
}

// Works with JSON serialization
JSON.stringify(array); // '["totally","immutable",{"hammer":"Can't Touch This"}]'

// Create immutable object with enhanced methods
const obj = Immutable({status: "good", hypothesis: "plausible", errors: 0});
const updated = obj.merge({status: "funky", hypothesis: "confirmed"});
// Returns: {status: "funky", hypothesis: "confirmed", errors: 0}

Architecture

Seamless Immutable is built around several key principles:

  • Backwards Compatibility: Immutable structures behave like regular Arrays and Objects
  • Non-Destructive Operations: All mutations return new immutable instances
  • Enhanced Methods: Additional methods like merge, set, getIn for common operations
  • Static and Instance APIs: Both obj.method() and Immutable.method(obj) patterns supported
  • Development vs Production: Development build includes freezing and helpful errors, production build optimized for performance

Performance Characteristics

  • Structural Sharing: Reuses existing nested objects rather than deep cloning, providing significant performance benefits for large nested structures
  • Development vs Production: Production build offers ~2x performance improvement by removing freezing and defensive checks
  • Safari Consideration: Frozen objects iterate more slowly in Safari; consider production build for performance-critical Safari applications
  • Memory Efficiency: Only changed parts of data structures are copied, unchanged portions are shared between versions

Usage Guidance

When to Use Static vs Instance API

Use Static API (require("seamless-immutable").static) when:

  • Avoiding method name pollution is important
  • Working in a functional programming style
  • Risk of conflicts with existing object methods
  • Need consistent API across all data types

Use Instance API (default) when:

  • Preferring concise, object-oriented syntax
  • No concerns about method name conflicts
  • Working with existing codebases expecting instance methods

Development vs Production Builds

Use Development Build when:

  • During development and testing
  • Need helpful error messages for debugging
  • Want guaranteed immutability enforcement
  • Performance is not critical

Use Production Build when:

  • In production environments
  • Performance is critical (~2x faster)
  • Bundle size matters
  • Already confident in immutability usage

Capabilities

Core Constructor and Utilities

Primary entry point for creating immutable data structures, plus static utility methods for type checking and configuration.

/**
 * Creates an immutable version of the provided data structure
 * @param {*} obj - Data to make immutable (Array, Object, Date, or primitive)
 * @param {Object} [options] - Configuration options
 * @param {Object} [options.prototype] - Custom prototype for objects
 * @returns {*} Immutable version of the input
 */
function Immutable(obj, options);

/**
 * Alias for Immutable() for linter compatibility
 */
Immutable.from = Immutable;

/**
 * Checks if a value is immutable
 * @param {*} target - Value to check
 * @returns {boolean} True if the value is immutable
 */
function isImmutable(target);

/**
 * Error class thrown when attempting to use mutating methods
 */
class ImmutableError extends Error;

/**
 * Static API version that avoids method pollution
 */
const static;

Core Constructor and Utilities

Object Operations

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

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

/**
 * 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 value is object
 * @returns {Object} New immutable object with property set
 */
function set(obj, property, value, config);

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

Object Operations

Array Operations

Methods for working with immutable arrays including functional operations and specialized transformations.

/**
 * Maps and flattens array elements
 * @param {Array} array - Source array
 * @param {Function} iterator - Mapping function
 * @returns {Array} New immutable array with mapped and flattened results
 */
function flatMap(array, iterator);

/**
 * Convert array to object using key-value pairs
 * @param {Array} array - Source array
 * @param {Function} [iterator] - Function returning [key, value] pairs
 * @returns {Object} New immutable object
 */
function asObject(array, iterator);

/**
 * Set element at specific index
 * @param {Array} array - Source array
 * @param {number} idx - Index to set
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @param {boolean} [config.deep] - Deep merge if value is object
 * @returns {Array} New immutable array with element set
 */
function set(array, idx, value, config);

Array Operations

Nested Operations

Methods for working with nested data structures using path-based access patterns.

/**
 * Set nested property using path array
 * @param {Object|Array} obj - Target object or array
 * @param {Array} path - Path to nested property
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @returns {Object|Array} New immutable structure with nested property set
 */
function setIn(obj, path, value, config);

/**
 * Get nested property using path array
 * @param {Object|Array} obj - Target object or array  
 * @param {Array} path - Path to nested property
 * @param {*} [defaultValue] - Default value if path not found
 * @returns {*} Value at path or default value
 */
function getIn(obj, path, defaultValue);

/**
 * Update nested property using updater function
 * @param {Object|Array} obj - Target object or array
 * @param {Array} path - Path to nested property
 * @param {Function} updater - Function to update the value
 * @param {...*} [args] - Additional arguments passed to updater
 * @returns {Object|Array} New immutable structure with updated nested property
 */
function updateIn(obj, path, updater, ...args);

Nested Operations

Types

/**
 * Configuration options for merge operations
 */
interface MergeConfig {
  /** Perform deep merge of nested objects */
  deep?: boolean;
  /** Merge mode: 'merge' preserves existing properties, 'replace' removes unlisted properties */
  mode?: 'merge' | 'replace';
  /** Custom merger function called for each property */
  merger?: (currentValue: any, newValue: any, config: MergeConfig) => any;
}

/**
 * Configuration options for set operations
 */
interface SetConfig {
  /** Deep merge if setting an object value */
  deep?: boolean;
}

/**
 * Configuration options for asMutable operations
 */
interface AsMutableConfig {
  /** Convert nested immutable structures to mutable recursively */
  deep?: boolean;
}

/**
 * Configuration options for Immutable constructor
 */
interface ImmutableOptions {
  /** Custom prototype for created objects */
  prototype?: Object;
}