@@ -131,7 +131,7 @@ describe('Outbox tests', () => {
131131 expect ( head . modelId ) . toEqual ( modelId ) ;
132132 expect ( head . operation ) . toEqual ( TransformerMutationType . UPDATE ) ;
133133 expect ( modelData . field1 ) . toEqual ( 'another value' ) ;
134- const modelDefinition = getModelDefinition ( last ) ;
134+ const modelDefinition = getModelDefinition ( Model ) ;
135135 const mutationsForModel = await outbox . getForModel (
136136 s ,
137137 last ,
@@ -155,7 +155,7 @@ describe('Outbox tests', () => {
155155
156156 await outbox . enqueue ( Storage , await createMutationEvent ( updatedModel3 ) ) ;
157157
158- const modelDefinition = getModelDefinition ( last ) ;
158+ const modelDefinition = getModelDefinition ( Model ) ;
159159
160160 // model2 should get deleted when model3 is enqueued, so we're expecting to see
161161 // 2 items in the queue for this Model total (including the in progress record - updatedModel1)
@@ -243,7 +243,7 @@ describe('Outbox tests', () => {
243243 expect ( head . operation ) . toEqual ( TransformerMutationType . UPDATE ) ;
244244 expect ( modelData . field1 ) . toEqual ( 'another value' ) ;
245245
246- const modelDefinition = getModelDefinition ( last ) ;
246+ const modelDefinition = getModelDefinition ( Model ) ;
247247 const mutationsForModel = await outbox . getForModel (
248248 s ,
249249 last ,
@@ -259,7 +259,7 @@ describe('Outbox tests', () => {
259259 } ) ;
260260
261261 await outbox . enqueue ( Storage , await createMutationEvent ( updatedModel2 ) ) ;
262- const modelDefinition = getModelDefinition ( last ) ;
262+ const modelDefinition = getModelDefinition ( Model ) ;
263263
264264 // 2 items in the queue for this Model total (including the in progress record - updatedModel1)
265265 const mutationsForModel = await outbox . getForModel (
@@ -348,6 +348,73 @@ describe('Outbox tests', () => {
348348 expect ( headData . optionalField1 ) . toEqual ( optionalField1 ) ;
349349 } ) ;
350350 } ) ;
351+
352+ it ( 'Should NOT sync the _version across different model types with the same ID' , async ( ) => {
353+ // Verifies fix for #13412: mutations for different model types sharing the
354+ // same primary key must not have their _version cross-contaminated.
355+
356+ const model1 = new Model ( {
357+ field1 : 'model1 value' ,
358+ dateCreated : new Date ( ) . toISOString ( ) ,
359+ } ) ;
360+
361+ await DataStore . save ( model1 ) ;
362+
363+ const updatedModel1 = Model . copyOf ( model1 , updated => {
364+ updated . field1 = 'updated model1 value' ;
365+ } ) ;
366+
367+ const mutationEvent1 = await createMutationEvent ( updatedModel1 ) ;
368+ await outbox . enqueue ( Storage , mutationEvent1 ) ;
369+
370+ // Insert a mutation for a different model type sharing the same modelId
371+ const MutationEventConstructor = syncClasses [
372+ 'MutationEvent'
373+ ] as PersistentModelConstructor < MutationEvent > ;
374+
375+ await Storage . save (
376+ new MutationEventConstructor ( {
377+ id : 'diff-model-mutation' ,
378+ model : 'DifferentModel' ,
379+ modelId : model1 . id ,
380+ operation : TransformerMutationType . UPDATE ,
381+ data : JSON . stringify ( {
382+ id : model1 . id ,
383+ someField : 'different model value' ,
384+ _version : 5 ,
385+ } ) ,
386+ condition : JSON . stringify ( null ) ,
387+ } ) ,
388+ ) ;
389+
390+ const response1 = {
391+ ...updatedModel1 ,
392+ _version : 20 ,
393+ _lastChangedAt : Date . now ( ) ,
394+ _deleted : false ,
395+ } ;
396+
397+ await Storage . runExclusive ( async s => {
398+ await processMutationResponse (
399+ s ,
400+ response1 ,
401+ TransformerMutationType . UPDATE ,
402+ ) ;
403+
404+ const allMutations = await s . query ( MutationEventConstructor ) ;
405+ const differentModelMutations = allMutations . filter (
406+ m => m . model === 'DifferentModel' ,
407+ ) ;
408+
409+ expect ( differentModelMutations . length ) . toBeGreaterThan ( 0 ) ;
410+
411+ const differentModelData = JSON . parse (
412+ differentModelMutations [ 0 ] . data ,
413+ ) ;
414+ expect ( differentModelData . _version ) . toEqual ( 5 ) ;
415+ } ) ;
416+ } ) ;
417+
351418} ) ;
352419
353420// performs all the required dependency injection
@@ -415,6 +482,6 @@ async function processMutationResponse(
415482
416483 const modelConstructor = Model as unknown as PersistentModelConstructor < any > ;
417484 const model = modelInstanceCreator ( modelConstructor , record ) ;
418- const modelDefinition = getModelDefinition ( model ) ;
485+ const modelDefinition = getModelDefinition ( modelConstructor ) ;
419486 await merger . merge ( storage , model , modelDefinition ) ;
420487}
0 commit comments