Skip to content

Commit 4f9f9e6

Browse files
jonasnobileclaude
andcommitted
fix(bindx): prioritize RelationStore in MutationCollector create and handle temp entity inline creates
Check RelationStore first (set by $connect/$disconnect) before falling back to embedded snapshot data when collecting relation operations for new entities. Also generate inline creates for temp entities in has-one relations instead of bare connects. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 06218ee commit 4f9f9e6

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

packages/bindx/src/persistence/MutationCollector.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,9 @@ export class MutationCollector implements MutationDataCollector {
171171
const relationType = this.schemaProvider.getRelationType(entityType, fieldName)
172172

173173
if (relationType === 'hasOne') {
174+
// Check embedded data first, then fall back to RelationStore
174175
const relationOp = this.collectCreateOneRelation(value)
176+
?? this.collectHasOneOperation(entityType, entityId, fieldName)
175177
if (relationOp !== null) {
176178
createData[fieldName] = relationOp
177179
}
@@ -312,9 +314,15 @@ export class MutationCollector implements MutationDataCollector {
312314
// Check if current entity exists on server
313315
if (currentId && this.isExistingEntity(currentId)) {
314316
return { connect: { id: currentId } }
317+
} else if (currentId && isTempId(currentId)) {
318+
// Temp entity — generate inline create with its collected data
319+
const targetType = this.schemaProvider.getRelationTarget(entityType, fieldName)
320+
if (targetType) {
321+
const createData = this.collectCreateData(targetType, currentId)
322+
return { create: createData ?? {} }
323+
}
324+
return { create: {} }
315325
} else if (currentId) {
316-
// Entity doesn't exist - might need to create it
317-
// For now, just connect (the entity should be created separately)
318326
return { connect: { id: currentId } }
319327
}
320328
} else if (currentId && serverId && currentId === serverId) {

tests/mutationCollector.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,39 @@ describe('MutationCollector', () => {
496496
})
497497
})
498498

499+
test('should return create with connected relation from RelationStore', () => {
500+
store.setEntityData('Article', '__temp_456', {
501+
id: '__temp_456',
502+
title: 'New Article',
503+
}, false)
504+
store.setExistsOnServer('Article', '__temp_456', false)
505+
506+
// Connect author via RelationStore (same as $connect does)
507+
store.getOrCreateRelation('Article', '__temp_456', 'author', {
508+
currentId: 'auth-1',
509+
serverId: null,
510+
state: 'connected',
511+
serverState: 'disconnected',
512+
placeholderData: {},
513+
})
514+
515+
// Mark auth-1 as existing on server
516+
store.setEntityData('Author', 'auth-1', { id: 'auth-1', name: 'John' }, true)
517+
store.setExistsOnServer('Author', 'auth-1', true)
518+
519+
const result = collector.collectMutation('Article', '__temp_456')
520+
521+
expect(result).toEqual({
522+
type: 'create',
523+
entityType: 'Article',
524+
entityId: '__temp_456',
525+
data: {
526+
title: 'New Article',
527+
author: { connect: { id: 'auth-1' } },
528+
},
529+
})
530+
})
531+
499532
test('should return delete for entity scheduled for deletion', () => {
500533
store.setEntityData('Article', 'a-1', {
501534
id: 'a-1',

0 commit comments

Comments
 (0)