From 37a8d81bba5fa59a506c163efe748c06cdf0a1d0 Mon Sep 17 00:00:00 2001 From: IhorKaleniuk666 Date: Thu, 22 Jan 2026 17:13:20 +0200 Subject: [PATCH] update --- .../src/patch_manager/ModelWithPatches.ts | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/core/src/patch_manager/ModelWithPatches.ts b/packages/core/src/patch_manager/ModelWithPatches.ts index 7a8abdbf4..bd179c6d2 100644 --- a/packages/core/src/patch_manager/ModelWithPatches.ts +++ b/packages/core/src/patch_manager/ModelWithPatches.ts @@ -56,6 +56,16 @@ const createStableUid = () => { return typeof randomUUID === 'function' ? randomUUID.call(crypto) : createId(); }; +const stripUid = (attrs: Partial): Partial => { + const attrsAny = attrs as any; + if (attrsAny && typeof attrsAny === 'object' && 'uid' in attrsAny) { + const { uid: _uid, ...rest } = attrsAny; + return rest as Partial; + } + + return attrs; +}; + export default class ModelWithPatches extends Model { em?: EditorModel; patchObjectType?: string; @@ -80,41 +90,42 @@ export default class ModelWithPatches rest)(rawAttrs as any) : rawAttrs; + const immutableAttrs = hasExistingUid ? stripUid(rawAttrs) : rawAttrs; const pm = this.patchManager; if (!pm) { - return super.set(attrs as any, opts as any); + return super.set(immutableAttrs as any, opts as any); } - const uid = hasExistingUid ? existingUid : isValidPatchUid(incomingUid) ? incomingUid : pm.createId(); + // Never accept UID mutations via public `set` while tracking patches + const attrsNoUid = stripUid(immutableAttrs); - // Ensure UID exists before taking snapshots to avoid recording it inside patches + const beforeState = serialize(this.attributes || {}) as any; + const stateUid = beforeState.uid; + const uid = isValidPatchUid(stateUid) ? stateUid : hasExistingUid ? existingUid : pm.createId(); + beforeState.uid = uid; + + // Ensure UID exists before applying changes, but do not record it in patches if (!hasExistingUid && isValidPatchUid(uid)) { - super.set({ uid } as any, { silent: true }); + super.set({ uid } as any, { silent: true } as any); } - // Never track UID mutations via patches - const attrsNoUid = 'uid' in (attrs as any) ? (({ uid: _uid, ...rest }) => rest)(attrs as any) : attrs; - - const objectId = this.getPatchObjectId(); - - if (!isValidPatchUid(objectId)) { + if (!isValidPatchUid(uid)) { return super.set(attrsNoUid as any, opts as any); } - const beforeState = serialize(this.attributes || {}); + const result = super.set(attrsNoUid as any, opts as any); const afterState = serialize(this.attributes || {}); + (afterState as any).uid = uid; const [, patches, inversePatches] = produceWithPatches(beforeState, (draft: any) => { syncDraftToState(draft, afterState); }); if (patches.length || inversePatches.length) { - const prefix: PatchPath = [this.patchObjectType as string, objectId, 'attributes']; + const prefix: PatchPath = [this.patchObjectType as string, uid, 'attributes']; const activePatch = pm.createOrGetCurrentPatch(); activePatch.changes.push(...normalizePatchPaths(patches, prefix)); activePatch.reverseChanges.push(...normalizePatchPaths(inversePatches, prefix));