(object: T, objectDiff: ObjectDiff)
| 329 | * @internal |
| 330 | */ |
| 331 | export function applyObjectDiff<T extends object>(object: T, objectDiff: ObjectDiff): T { |
| 332 | // don't patch nulls |
| 333 | if (!object || typeof object !== 'object') return object |
| 334 | const isArray = Array.isArray(object) |
| 335 | let newObject: any | undefined = undefined |
| 336 | const set = (k: any, v: any) => { |
| 337 | if (!newObject) { |
| 338 | if (isArray) { |
| 339 | newObject = [...object] |
| 340 | } else { |
| 341 | newObject = { ...object } |
| 342 | } |
| 343 | } |
| 344 | if (isArray) { |
| 345 | newObject[Number(k)] = v |
| 346 | } else { |
| 347 | newObject[k] = v |
| 348 | } |
| 349 | } |
| 350 | for (const [key, op] of Object.entries(objectDiff)) { |
| 351 | switch (op[0]) { |
| 352 | case ValueOpType.Put: { |
| 353 | const value = op[1] |
| 354 | if (!isEqual(object[key as keyof T], value)) { |
| 355 | set(key, value) |
| 356 | } |
| 357 | break |
| 358 | } |
| 359 | case ValueOpType.Append: { |
| 360 | const value = op[1] |
| 361 | const offset = op[2] |
| 362 | const currentValue = object[key as keyof T] |
| 363 | if (Array.isArray(currentValue) && Array.isArray(value) && currentValue.length === offset) { |
| 364 | set(key, [...currentValue, ...value]) |
| 365 | } else if ( |
| 366 | typeof currentValue === 'string' && |
| 367 | typeof value === 'string' && |
| 368 | currentValue.length === offset |
| 369 | ) { |
| 370 | set(key, currentValue + value) |
| 371 | } |
| 372 | // If validation fails (type mismatch or length mismatch), silently ignore |
| 373 | break |
| 374 | } |
| 375 | case ValueOpType.Patch: { |
| 376 | if (object[key as keyof T] && typeof object[key as keyof T] === 'object') { |
| 377 | const diff = op[1] |
| 378 | const patched = applyObjectDiff(object[key as keyof T] as object, diff) |
| 379 | if (patched !== object[key as keyof T]) { |
| 380 | set(key, patched) |
| 381 | } |
| 382 | } |
| 383 | break |
| 384 | } |
| 385 | case ValueOpType.Delete: { |
| 386 | if (key in object) { |
| 387 | if (!newObject) { |
| 388 | if (isArray) { |
no test coverage detected
searching dependent graphs…