or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-operations.mddiffpatcher-class.mdformatters.mdindex.mdoptions-configuration.md
tile.json

options-configuration.mddocs/

0

# Options and Configuration

1

2

Comprehensive configuration system for customizing diff behavior including array handling, text diffing, property filtering, and output formatting.

3

4

## Capabilities

5

6

### Options Interface

7

8

Complete configuration interface for controlling diff, patch, and clone behavior.

9

10

```javascript { .api }

11

interface Options {

12

/** Custom hash function for object matching in arrays */

13

objectHash?: (item: object, index?: number) => string | undefined;

14

15

/** Match array items by position instead of content */

16

matchByPosition?: boolean;

17

18

/** Array-specific diffing options */

19

arrays?: {

20

/** Detect and represent item moves within arrays */

21

detectMove?: boolean;

22

/** Include moved item value in delta (not just index) */

23

includeValueOnMove?: boolean;

24

};

25

26

/** Text diffing configuration */

27

textDiff?: {

28

/** diff-match-patch instance for text diffing */

29

diffMatchPatch: typeof diff_match_patch;

30

/** Minimum string length to trigger text diffing */

31

minLength?: number;

32

};

33

34

/** Filter function to exclude properties from diffing */

35

propertyFilter?: (name: string, context: DiffContext) => boolean;

36

37

/** Control value cloning during diff operations */

38

cloneDiffValues?: boolean | ((value: unknown) => unknown);

39

40

/** Omit old values from deletion deltas */

41

omitRemovedValues?: boolean;

42

}

43

```

44

45

## Configuration Options

46

47

### Object Hash Function

48

49

Controls how objects are matched within arrays for optimal diff results.

50

51

```javascript { .api }

52

/**

53

* Custom hash function for object matching in arrays

54

* @param item - Object to generate hash for

55

* @param index - Position in array (optional)

56

* @returns Unique identifier string or undefined for position-based matching

57

*/

58

objectHash?: (item: object, index?: number) => string | undefined;

59

```

60

61

**Usage Examples:**

62

63

```javascript

64

import { create } from "jsondiffpatch";

65

66

// Match by ID field

67

const patcher = create({

68

objectHash: (obj) => obj.id ? String(obj.id) : undefined

69

});

70

71

const delta = patcher.diff(

72

[{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }],

73

[{ id: 2, name: "Bob", role: "admin" }, { id: 1, name: "Alice" }]

74

);

75

// Detects move of Alice and modification of Bob

76

77

// Multi-field hash

78

const complexPatcher = create({

79

objectHash: (obj, index) => {

80

if (obj.type === 'user' && obj.email) {

81

return `user:${obj.email}`;

82

}

83

if (obj.type === 'product' && obj.sku) {

84

return `product:${obj.sku}`;

85

}

86

return undefined; // Fall back to position matching

87

}

88

});

89

90

// Conditional hash based on context

91

const contextPatcher = create({

92

objectHash: (obj, index) => {

93

// Only use ID for large arrays to improve performance

94

if (index !== undefined && index > 100 && obj.id) {

95

return String(obj.id);

96

}

97

return undefined;

98

}

99

});

100

```

101

102

### Array Configuration

103

104

Controls array diffing behavior including move detection and value inclusion.

105

106

```javascript { .api }

107

arrays?: {

108

/** Detect and represent item moves within arrays */

109

detectMove?: boolean;

110

/** Include moved item value in delta (not just index) */

111

includeValueOnMove?: boolean;

112

};

113

```

114

115

**Usage Examples:**

116

117

```javascript

118

import { create } from "jsondiffpatch";

119

120

// Disable move detection for performance

121

const noMovePatcher = create({

122

arrays: {

123

detectMove: false

124

}

125

});

126

127

const delta1 = noMovePatcher.diff([1, 2, 3], [2, 3, 1]);

128

// Treats as delete + add instead of move

129

130

// Include values in move operations

131

const valueMovePatcher = create({

132

arrays: {

133

detectMove: true,

134

includeValueOnMove: true

135

}

136

});

137

138

const delta2 = valueMovePatcher.diff(

139

[{ name: "Alice" }, { name: "Bob" }],

140

[{ name: "Bob" }, { name: "Alice" }]

141

);

142

// Move delta includes the moved object value

143

144

// Position-based matching for simple arrays

145

const positionPatcher = create({

146

matchByPosition: true,

147

arrays: {

148

detectMove: false

149

}

150

});

151

152

const delta3 = positionPatcher.diff(["a", "b", "c"], ["x", "b", "c"]);

153

// Result: { 0: ["a", "x"] } - replaces first item

154

```

155

156

### Text Diff Configuration

157

158

Enables automatic text diffing for long strings using diff-match-patch algorithm.

159

160

```javascript { .api }

161

textDiff?: {

162

/** diff-match-patch instance for text diffing */

163

diffMatchPatch: typeof diff_match_patch;

164

/** Minimum string length to trigger text diffing */

165

minLength?: number;

166

};

167

```

168

169

**Usage Examples:**

170

171

```javascript

172

import { create } from "jsondiffpatch";

173

import DiffMatchPatch from "diff-match-patch";

174

175

// Manual text diff configuration

176

const textPatcher = create({

177

textDiff: {

178

diffMatchPatch: DiffMatchPatch,

179

minLength: 50 // Only diff strings over 50 characters

180

}

181

});

182

183

const longText1 = "The quick brown fox jumps over the lazy dog. This is a longer text that will trigger text diffing.";

184

const longText2 = "The quick brown fox jumped over the lazy cat. This is a longer text that will trigger text diffing.";

185

186

const textDelta = textPatcher.diff({ content: longText1 }, { content: longText2 });

187

// Result includes text diff format instead of full string replacement

188

189

// Use with-text-diffs module for automatic setup

190

import { create as createWithText } from "jsondiffpatch/with-text-diffs";

191

192

const autoTextPatcher = createWithText({

193

textDiff: {

194

minLength: 30 // Override default minimum length

195

}

196

});

197

```

198

199

### Property Filtering

200

201

Excludes specific properties from diff operations based on custom logic.

202

203

```javascript { .api }

204

/**

205

* Filter function to exclude properties from diffing

206

* @param name - Property name being considered

207

* @param context - Diff context with left/right values and metadata

208

* @returns true to include property, false to exclude

209

*/

210

propertyFilter?: (name: string, context: DiffContext) => boolean;

211

```

212

213

**Usage Examples:**

214

215

```javascript

216

import { create } from "jsondiffpatch";

217

218

// Exclude private properties

219

const privatePatcher = create({

220

propertyFilter: (name) => !name.startsWith('_')

221

});

222

223

const delta1 = privatePatcher.diff(

224

{ name: "Alice", _internal: "secret1" },

225

{ name: "Bob", _internal: "secret2" }

226

);

227

// Result: { name: ["Alice", "Bob"] } - _internal ignored

228

229

// Contextual filtering

230

const contextPatcher = create({

231

propertyFilter: (name, context) => {

232

// Skip metadata for temporary objects

233

if (name === 'metadata' && context.left?.type === 'temp') {

234

return false;

235

}

236

237

// Skip computed properties that depend on other changes

238

if (name === 'computed' && (context.left?.dirty || context.right?.dirty)) {

239

return false;

240

}

241

242

// Skip large arrays in certain contexts

243

if (name === 'items' && Array.isArray(context.left?.[name]) &&

244

context.left[name].length > 1000) {

245

return false;

246

}

247

248

return true;

249

}

250

});

251

252

// Performance-focused filtering

253

const perfPatcher = create({

254

propertyFilter: (name, context) => {

255

// Skip deep object diffing for performance

256

const leftValue = context.left?.[name];

257

const rightValue = context.right?.[name];

258

259

if (typeof leftValue === 'object' && typeof rightValue === 'object' &&

260

leftValue && rightValue && Object.keys(leftValue).length > 50) {

261

return false;

262

}

263

264

return true;

265

}

266

});

267

```

268

269

### Clone Configuration

270

271

Controls how values are cloned during diff and patch operations.

272

273

```javascript { .api }

274

/**

275

* Control value cloning during diff operations

276

* Can be boolean or custom clone function

277

*/

278

cloneDiffValues?: boolean | ((value: unknown) => unknown);

279

```

280

281

**Usage Examples:**

282

283

```javascript

284

import { create } from "jsondiffpatch";

285

286

// Disable cloning for performance (modifies original objects)

287

const noClonePatcher = create({

288

cloneDiffValues: false

289

});

290

291

// This will modify the original objects during patching

292

const original = { name: "Alice", tags: ["user"] };

293

const delta = { tags: { _t: "a", 1: ["admin"] } };

294

noClonePatcher.patch(original, delta);

295

console.log(original.tags); // ["user", "admin"] - original was modified

296

297

// Custom clone function

298

const customClonePatcher = create({

299

cloneDiffValues: (value) => {

300

// Custom cloning logic

301

if (value instanceof Date) {

302

return new Date(value.getTime());

303

}

304

if (Array.isArray(value)) {

305

return value.map(item => customClonePatcher.clone(item));

306

}

307

if (value && typeof value === 'object') {

308

const cloned = {};

309

for (const [key, val] of Object.entries(value)) {

310

if (key !== '_computed') { // Skip computed properties

311

cloned[key] = customClonePatcher.clone(val);

312

}

313

}

314

return cloned;

315

}

316

return value;

317

}

318

});

319

```

320

321

### Remove Value Configuration

322

323

Controls whether deleted values are included in deletion deltas.

324

325

```javascript { .api }

326

/**

327

* Omit old values from deletion deltas

328

* Reduces delta size at cost of losing delete value information

329

*/

330

omitRemovedValues?: boolean;

331

```

332

333

**Usage Examples:**

334

335

```javascript

336

import { create } from "jsondiffpatch";

337

338

// Standard behavior (includes removed values)

339

const standardPatcher = create();

340

const delta1 = standardPatcher.diff(

341

{ name: "Alice", age: 25, role: "user" },

342

{ name: "Alice", age: 26 }

343

);

344

// Result: { age: [25, 26], role: ["user", 0, 0] }

345

346

// Omit removed values for smaller deltas

347

const omitPatcher = create({

348

omitRemovedValues: true

349

});

350

const delta2 = omitPatcher.diff(

351

{ name: "Alice", age: 25, role: "user" },

352

{ name: "Alice", age: 26 }

353

);

354

// Result: { age: [25, 26], role: [0, 0] } - removed value not stored

355

356

// Useful for large objects where removed values are not needed

357

const largePatcher = create({

358

omitRemovedValues: true,

359

propertyFilter: (name) => !name.startsWith('temp_')

360

});

361

```

362

363

## Configuration Examples

364

365

### Performance-Optimized Configuration

366

367

```javascript

368

const perfPatcher = create({

369

arrays: {

370

detectMove: false // Disable expensive move detection

371

},

372

cloneDiffValues: false, // Disable cloning for speed

373

omitRemovedValues: true, // Reduce delta size

374

propertyFilter: (name) => {

375

// Skip expensive-to-diff properties

376

return !['computed', 'cache', 'metadata'].includes(name);

377

}

378

});

379

```

380

381

### Comprehensive Diff Configuration

382

383

```javascript

384

const comprehensivePatcher = create({

385

objectHash: (obj) => obj.id || obj.key || obj.name,

386

arrays: {

387

detectMove: true,

388

includeValueOnMove: true

389

},

390

textDiff: {

391

diffMatchPatch: DiffMatchPatch,

392

minLength: 40

393

},

394

cloneDiffValues: true,

395

propertyFilter: (name, context) => {

396

// Include all properties except truly private ones

397

return !name.startsWith('__');

398

}

399

});

400

```

401

402

### Minimal Delta Configuration

403

404

```javascript

405

const minimalPatcher = create({

406

omitRemovedValues: true,

407

arrays: {

408

detectMove: true,

409

includeValueOnMove: false // Omit values from moves

410

},

411

propertyFilter: (name, context) => {

412

// Only include changed properties that matter

413

const essential = ['id', 'name', 'status', 'value'];

414

return essential.includes(name) || !name.startsWith('meta');

415

}

416

});

417

```