or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

children-utilities.mdcontext-api.mdcore-api.mdimmutability-helpers.mdindex.mdlegacy-apis.mdperformance-tools.mdrefs-system.mdserver-rendering.mdtransition-groups.md

immutability-helpers.mddocs/

0

# Immutability Helpers

1

2

Data update utilities for managing immutable state transformations safely and efficiently.

3

4

## Capabilities

5

6

### Update Function

7

8

Immutable update utility based on MongoDB's query language for safe state modifications.

9

10

```javascript { .api }

11

/**

12

* Immutably update nested data structures

13

* @param {any} object - Object to update

14

* @param {UpdateSpec} spec - Update specification

15

* @returns {any} New object with updates applied

16

*/

17

function update(object, spec);

18

19

/**

20

* Update specification object

21

*/

22

interface UpdateSpec {

23

/** Set a value */

24

$set?: any;

25

26

/** Merge an object (shallow merge) */

27

$merge?: object;

28

29

/** Push items to end of array */

30

$push?: Array<any>;

31

32

/** Add items to beginning of array */

33

$unshift?: Array<any>;

34

35

/** Splice array (remove/insert items) */

36

$splice?: Array<[number, number, ...any[]]>;

37

38

/** Apply function to transform value */

39

$apply?: (value: any) => any;

40

41

/** Toggle boolean value */

42

$toggle?: Array<string>;

43

44

/** Remove items from array by index */

45

$unset?: Array<string | number>;

46

47

/** Nested updates - any key can contain another UpdateSpec */

48

[key: string]: UpdateSpec | any;

49

}

50

```

51

52

**Usage Examples:**

53

54

```javascript

55

import update from 'preact-compat/lib/update';

56

57

// Initial state

58

const state = {

59

user: {

60

name: 'John',

61

profile: {

62

age: 30,

63

preferences: ['music', 'sports']

64

}

65

},

66

items: [1, 2, 3],

67

settings: {

68

theme: 'light',

69

notifications: true

70

}

71

};

72

73

// Update nested object

74

const newState1 = update(state, {

75

user: {

76

name: { $set: 'Jane' },

77

profile: {

78

age: { $set: 31 },

79

preferences: { $push: ['reading'] }

80

}

81

}

82

});

83

84

// Merge objects

85

const newState2 = update(state, {

86

settings: { $merge: { theme: 'dark', language: 'en' } }

87

});

88

89

// Array operations

90

const newState3 = update(state, {

91

items: { $splice: [[1, 1, 10, 11]] } // Remove 1 item at index 1, insert 10, 11

92

});

93

94

// Apply function transformation

95

const newState4 = update(state, {

96

user: {

97

profile: {

98

age: { $apply: age => age + 1 }

99

}

100

}

101

});

102

```

103

104

### Common Update Patterns

105

106

```javascript

107

import update from 'preact-compat/lib/update';

108

109

class TodoApp extends Component {

110

state = {

111

todos: [

112

{ id: 1, text: 'Learn React', completed: false },

113

{ id: 2, text: 'Build app', completed: false }

114

],

115

filter: 'all'

116

};

117

118

// Add new todo

119

addTodo = (text) => {

120

const newTodo = {

121

id: Date.now(),

122

text,

123

completed: false

124

};

125

126

this.setState(update(this.state, {

127

todos: { $push: [newTodo] }

128

}));

129

};

130

131

// Toggle todo completion

132

toggleTodo = (id) => {

133

const todoIndex = this.state.todos.findIndex(todo => todo.id === id);

134

135

this.setState(update(this.state, {

136

todos: {

137

[todoIndex]: {

138

completed: { $apply: completed => !completed }

139

}

140

}

141

}));

142

};

143

144

// Remove todo

145

removeTodo = (id) => {

146

const todoIndex = this.state.todos.findIndex(todo => todo.id === id);

147

148

this.setState(update(this.state, {

149

todos: { $splice: [[todoIndex, 1]] }

150

}));

151

};

152

153

// Update filter

154

setFilter = (filter) => {

155

this.setState(update(this.state, {

156

filter: { $set: filter }

157

}));

158

};

159

160

// Bulk operations

161

completeAll = () => {

162

this.setState(update(this.state, {

163

todos: { $apply: todos =>

164

todos.map(todo => ({ ...todo, completed: true }))

165

}

166

}));

167

};

168

169

render() {

170

const { todos, filter } = this.state;

171

172

return (

173

<div>

174

<input

175

onKeyPress={(e) => {

176

if (e.key === 'Enter') {

177

this.addTodo(e.target.value);

178

e.target.value = '';

179

}

180

}}

181

placeholder="Add todo..."

182

/>

183

<button onClick={this.completeAll}>Complete All</button>

184

185

{todos.map(todo => (

186

<div key={todo.id}>

187

<input

188

type="checkbox"

189

checked={todo.completed}

190

onChange={() => this.toggleTodo(todo.id)}

191

/>

192

<span style={{

193

textDecoration: todo.completed ? 'line-through' : 'none'

194

}}>

195

{todo.text}

196

</span>

197

<button onClick={() => this.removeTodo(todo.id)}>Remove</button>

198

</div>

199

))}

200

</div>

201

);

202

}

203

}

204

```

205

206

### Advanced Update Patterns

207

208

```javascript

209

import update from 'preact-compat/lib/update';

210

211

// Complex nested updates

212

const complexState = {

213

users: {

214

byId: {

215

1: { name: 'John', posts: [10, 20] },

216

2: { name: 'Jane', posts: [30] }

217

},

218

allIds: [1, 2]

219

},

220

posts: {

221

byId: {

222

10: { title: 'Post 1', likes: 5 },

223

20: { title: 'Post 2', likes: 3 },

224

30: { title: 'Post 3', likes: 8 }

225

},

226

allIds: [10, 20, 30]

227

}

228

};

229

230

// Add new user with post

231

function addUserWithPost(state, user, post) {

232

return update(state, {

233

users: {

234

byId: { $merge: { [user.id]: user } },

235

allIds: { $push: [user.id] }

236

},

237

posts: {

238

byId: { $merge: { [post.id]: post } },

239

allIds: { $push: [post.id] }

240

}

241

});

242

}

243

244

// Update multiple related entities

245

function likePost(state, postId, userId) {

246

return update(state, {

247

posts: {

248

byId: {

249

[postId]: {

250

likes: { $apply: likes => likes + 1 }

251

}

252

}

253

},

254

users: {

255

byId: {

256

[userId]: {

257

likedPosts: { $push: [postId] }

258

}

259

}

260

}

261

});

262

}

263

264

// Conditional updates

265

function updateUserIfExists(state, userId, updates) {

266

if (state.users.byId[userId]) {

267

return update(state, {

268

users: {

269

byId: {

270

[userId]: { $merge: updates }

271

}

272

}

273

});

274

}

275

return state;

276

}

277

```

278

279

## Import Patterns

280

281

```javascript

282

// Main import

283

import update from 'preact-compat/lib/update';

284

285

// CommonJS

286

const update = require('preact-compat/lib/update');

287

```

288

289

## Types

290

291

```javascript { .api }

292

interface UpdateSpec {

293

$set?: any;

294

$merge?: object;

295

$push?: Array<any>;

296

$unshift?: Array<any>;

297

$splice?: Array<SpliceOperation>;

298

$apply?: (value: any) => any;

299

$toggle?: Array<string>;

300

$unset?: Array<string | number>;

301

[key: string]: UpdateSpec | any;

302

}

303

304

type SpliceOperation = [number, number, ...any[]];

305

306

type UpdateFunction = <T>(object: T, spec: UpdateSpec) => T;

307

```