523
}
524
}
526
this._diffArray(transform, path, prev as unknown[], curr as unknown[], entries);
528
>
this._diffObject(transform.children, path, prev, curr, entries, transform.sealed as ((obj: unknown, wasSerialized: boolean) => boolean) | undefined);
529
>
} else {
530
throw new Error(`Unknown transform kind ${JSON.stringify(transform)}`);
531
}
533
534
private _diffObject(
536
>
path: ObjectPath,
537
>
prev: unknown,
538
>
curr: unknown,
539
>
entries: Entry[],
540
>
sealed?: (obj: unknown, wasSerialized: boolean) => boolean,
541
>
): void {
542
>
const prevObj = prev as Record<string, unknown> | undefined;
543
>
const currObj = curr as Record<string, unknown>;
544
>
545
>
// First check key fields (sorted to front) - if any key changed, replace the entire object
546
>
let i = 0;
547
>
for (; i < children.length; i++) {
548
>
const [key, transform] = children[i];
549
>
if (transform.kind !== TransformKind.Key) {
550
>
break; // Keys are sorted to front, so we can stop
551
>
}
552
>
if (!transform.equals(prevObj?.[key], currObj[key])) {
553
// Key changed, replace entire object
554
entries.push({ kind: EntryKind.Set, k: path.slice(), v: curr });
555
return;
556
}
558
>
559
>
// If both objects are sealed, we've already verified keys match above,
560
>
// so we can skip diffing the other properties since sealed objects don't change
561
>
if (sealed && sealed(prev, true) && sealed(curr, false)) {
562
return;
563
}
565
>
// Diff each property using mutable path
566
>
for (; i < children.length; i++) {
567
>
const [key, transform] = children[i];
568
>
path.push(key);
569
>
this._diff(transform, path, prevObj?.[key], currObj[key], entries);
570
>
path.pop();
571
>
}
572
>
}
573
574
private _diffArray<T, R>(