Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
npx @tessl/cli install tessl/npm-seamless-immutable@7.1.0Seamless 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.
npm install seamless-immutableconst 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";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}Seamless Immutable is built around several key principles:
merge, set, getIn for common operationsobj.method() and Immutable.method(obj) patterns supportedUse Static API (require("seamless-immutable").static) when:
Use Instance API (default) when:
Use Development Build when:
Use Production Build when:
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
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);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);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);/**
* 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;
}