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.00
# Seamless Immutable
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: seamless-immutable
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install seamless-immutable`
10
11
## Core Imports
12
13
```javascript
14
const Immutable = require("seamless-immutable");
15
```
16
17
For static API (recommended to avoid method collision):
18
19
```javascript
20
const Immutable = require("seamless-immutable").static;
21
```
22
23
ES6 import:
24
25
```javascript
26
import Immutable from "seamless-immutable";
27
```
28
29
## Basic Usage
30
31
```javascript
32
const Immutable = require("seamless-immutable");
33
34
// Create immutable array - still works with for loops and JSON.stringify
35
const array = Immutable(["totally", "immutable", {hammer: "Can't Touch This"}]);
36
37
array[1] = "I'm going to mutate you!";
38
console.log(array[1]); // "immutable" - unchanged
39
40
// Works with for loops
41
for (let index in array) {
42
console.log(array[index]);
43
}
44
45
// Works with JSON serialization
46
JSON.stringify(array); // '["totally","immutable",{"hammer":"Can't Touch This"}]'
47
48
// Create immutable object with enhanced methods
49
const obj = Immutable({status: "good", hypothesis: "plausible", errors: 0});
50
const updated = obj.merge({status: "funky", hypothesis: "confirmed"});
51
// Returns: {status: "funky", hypothesis: "confirmed", errors: 0}
52
```
53
54
## Architecture
55
56
Seamless Immutable is built around several key principles:
57
58
- **Backwards Compatibility**: Immutable structures behave like regular Arrays and Objects
59
- **Non-Destructive Operations**: All mutations return new immutable instances
60
- **Enhanced Methods**: Additional methods like `merge`, `set`, `getIn` for common operations
61
- **Static and Instance APIs**: Both `obj.method()` and `Immutable.method(obj)` patterns supported
62
- **Development vs Production**: Development build includes freezing and helpful errors, production build optimized for performance
63
64
## Performance Characteristics
65
66
- **Structural Sharing**: Reuses existing nested objects rather than deep cloning, providing significant performance benefits for large nested structures
67
- **Development vs Production**: Production build offers ~2x performance improvement by removing freezing and defensive checks
68
- **Safari Consideration**: Frozen objects iterate more slowly in Safari; consider production build for performance-critical Safari applications
69
- **Memory Efficiency**: Only changed parts of data structures are copied, unchanged portions are shared between versions
70
71
## Usage Guidance
72
73
### When to Use Static vs Instance API
74
75
**Use Static API (`require("seamless-immutable").static`) when:**
76
- Avoiding method name pollution is important
77
- Working in a functional programming style
78
- Risk of conflicts with existing object methods
79
- Need consistent API across all data types
80
81
**Use Instance API (default) when:**
82
- Preferring concise, object-oriented syntax
83
- No concerns about method name conflicts
84
- Working with existing codebases expecting instance methods
85
86
### Development vs Production Builds
87
88
**Use Development Build when:**
89
- During development and testing
90
- Need helpful error messages for debugging
91
- Want guaranteed immutability enforcement
92
- Performance is not critical
93
94
**Use Production Build when:**
95
- In production environments
96
- Performance is critical (~2x faster)
97
- Bundle size matters
98
- Already confident in immutability usage
99
100
## Capabilities
101
102
### Core Constructor and Utilities
103
104
Primary entry point for creating immutable data structures, plus static utility methods for type checking and configuration.
105
106
```javascript { .api }
107
/**
108
* Creates an immutable version of the provided data structure
109
* @param {*} obj - Data to make immutable (Array, Object, Date, or primitive)
110
* @param {Object} [options] - Configuration options
111
* @param {Object} [options.prototype] - Custom prototype for objects
112
* @returns {*} Immutable version of the input
113
*/
114
function Immutable(obj, options);
115
116
/**
117
* Alias for Immutable() for linter compatibility
118
*/
119
Immutable.from = Immutable;
120
121
/**
122
* Checks if a value is immutable
123
* @param {*} target - Value to check
124
* @returns {boolean} True if the value is immutable
125
*/
126
function isImmutable(target);
127
128
/**
129
* Error class thrown when attempting to use mutating methods
130
*/
131
class ImmutableError extends Error;
132
133
/**
134
* Static API version that avoids method pollution
135
*/
136
const static;
137
```
138
139
[Core Constructor and Utilities](./core.md)
140
141
### Object Operations
142
143
Methods for working with immutable objects including merging, property manipulation, and nested updates.
144
145
```javascript { .api }
146
/**
147
* Merge objects immutably with configurable behavior
148
* @param {Object} obj - Target object
149
* @param {Object|Array} other - Object(s) to merge
150
* @param {Object} [config] - Merge configuration
151
* @param {boolean} [config.deep] - Deep merge nested objects
152
* @param {string} [config.mode] - Merge mode: 'merge'|'replace'
153
* @param {Function} [config.merger] - Custom merger function
154
* @returns {Object} New immutable object with merged properties
155
*/
156
function merge(obj, other, config);
157
158
/**
159
* Set a property on an object immutably
160
* @param {Object} obj - Target object
161
* @param {string} property - Property key to set
162
* @param {*} value - Value to set
163
* @param {Object} [config] - Configuration options
164
* @param {boolean} [config.deep] - Deep merge if value is object
165
* @returns {Object} New immutable object with property set
166
*/
167
function set(obj, property, value, config);
168
169
/**
170
* Remove properties from an object immutably
171
* @param {Object} obj - Target object
172
* @param {...string|Array|Function} keys - Keys to remove or predicate function
173
* @returns {Object} New immutable object without specified properties
174
*/
175
function without(obj, ...keys);
176
```
177
178
[Object Operations](./object-operations.md)
179
180
### Array Operations
181
182
Methods for working with immutable arrays including functional operations and specialized transformations.
183
184
```javascript { .api }
185
/**
186
* Maps and flattens array elements
187
* @param {Array} array - Source array
188
* @param {Function} iterator - Mapping function
189
* @returns {Array} New immutable array with mapped and flattened results
190
*/
191
function flatMap(array, iterator);
192
193
/**
194
* Convert array to object using key-value pairs
195
* @param {Array} array - Source array
196
* @param {Function} [iterator] - Function returning [key, value] pairs
197
* @returns {Object} New immutable object
198
*/
199
function asObject(array, iterator);
200
201
/**
202
* Set element at specific index
203
* @param {Array} array - Source array
204
* @param {number} idx - Index to set
205
* @param {*} value - Value to set
206
* @param {Object} [config] - Configuration options
207
* @param {boolean} [config.deep] - Deep merge if value is object
208
* @returns {Array} New immutable array with element set
209
*/
210
function set(array, idx, value, config);
211
```
212
213
[Array Operations](./array-operations.md)
214
215
### Nested Operations
216
217
Methods for working with nested data structures using path-based access patterns.
218
219
```javascript { .api }
220
/**
221
* Set nested property using path array
222
* @param {Object|Array} obj - Target object or array
223
* @param {Array} path - Path to nested property
224
* @param {*} value - Value to set
225
* @param {Object} [config] - Configuration options
226
* @returns {Object|Array} New immutable structure with nested property set
227
*/
228
function setIn(obj, path, value, config);
229
230
/**
231
* Get nested property using path array
232
* @param {Object|Array} obj - Target object or array
233
* @param {Array} path - Path to nested property
234
* @param {*} [defaultValue] - Default value if path not found
235
* @returns {*} Value at path or default value
236
*/
237
function getIn(obj, path, defaultValue);
238
239
/**
240
* Update nested property using updater function
241
* @param {Object|Array} obj - Target object or array
242
* @param {Array} path - Path to nested property
243
* @param {Function} updater - Function to update the value
244
* @param {...*} [args] - Additional arguments passed to updater
245
* @returns {Object|Array} New immutable structure with updated nested property
246
*/
247
function updateIn(obj, path, updater, ...args);
248
```
249
250
[Nested Operations](./nested-operations.md)
251
252
## Types
253
254
```javascript { .api }
255
/**
256
* Configuration options for merge operations
257
*/
258
interface MergeConfig {
259
/** Perform deep merge of nested objects */
260
deep?: boolean;
261
/** Merge mode: 'merge' preserves existing properties, 'replace' removes unlisted properties */
262
mode?: 'merge' | 'replace';
263
/** Custom merger function called for each property */
264
merger?: (currentValue: any, newValue: any, config: MergeConfig) => any;
265
}
266
267
/**
268
* Configuration options for set operations
269
*/
270
interface SetConfig {
271
/** Deep merge if setting an object value */
272
deep?: boolean;
273
}
274
275
/**
276
* Configuration options for asMutable operations
277
*/
278
interface AsMutableConfig {
279
/** Convert nested immutable structures to mutable recursively */
280
deep?: boolean;
281
}
282
283
/**
284
* Configuration options for Immutable constructor
285
*/
286
interface ImmutableOptions {
287
/** Custom prototype for created objects */
288
prototype?: Object;
289
}
290
```