@@ -11,8 +11,13 @@ import { deepEquals } from "../utils"
11
11
import type { StandardSchemaV1 } from "@standard-schema/spec"
12
12
import type {
13
13
ChangeMessage ,
14
+ < << << << HEAD
14
15
CleanupFn ,
15
16
CollectionConfig ,
17
+ = === ===
18
+ CollectionConfig ,
19
+ CleanupFn ,
20
+ > >>> >>> 684 c70ec ( Add onLoadMore callback and call it from the requestSnapshot methods )
16
21
OnLoadMoreOptions ,
17
22
SyncConfigRes ,
18
23
} from "../types"
@@ -94,6 +99,7 @@ export class CollectionSyncManager<
94
99
}
95
100
const key = this . config . getKey ( messageWithoutKey . value )
96
101
102
+ << < < < << HEAD
97
103
let messageType = messageWithoutKey . type
98
104
99
105
// Check if an item with this key already exists when inserting
@@ -171,6 +177,71 @@ export class CollectionSyncManager<
171
177
throw new SyncTransactionAlreadyCommittedWriteError ( )
172
178
}
173
179
180
+ = === ===
181
+ // Check if an item with this key already exists when inserting
182
+ if ( messageWithoutKey . type === `insert` ) {
183
+ const insertingIntoExistingSynced = this . state . syncedData . has ( key )
184
+ const hasPendingDeleteForKey =
185
+ pendingTransaction . deletedKeys . has ( key )
186
+ const isTruncateTransaction = pendingTransaction . truncate === true
187
+ // Allow insert after truncate in the same transaction even if it existed in syncedData
188
+ if (
189
+ insertingIntoExistingSynced &&
190
+ ! hasPendingDeleteForKey &&
191
+ ! isTruncateTransaction
192
+ ) {
193
+ throw new DuplicateKeySyncError ( key , this . id )
194
+ }
195
+ }
196
+
197
+ const message : ChangeMessage < TOutput > = {
198
+ ...messageWithoutKey ,
199
+ key,
200
+ }
201
+ pendingTransaction . operations . push ( message )
202
+
203
+ if ( messageWithoutKey . type === `delete` ) {
204
+ pendingTransaction . deletedKeys . add ( key )
205
+ }
206
+ } ,
207
+ commit : ( ) => {
208
+ const pendingTransaction =
209
+ this . state . pendingSyncedTransactions [
210
+ this . state . pendingSyncedTransactions . length - 1
211
+ ]
212
+ if ( ! pendingTransaction ) {
213
+ throw new NoPendingSyncTransactionCommitError ( )
214
+ }
215
+ if ( pendingTransaction . committed ) {
216
+ throw new SyncTransactionAlreadyCommittedError ( )
217
+ }
218
+
219
+ pendingTransaction . committed = true
220
+
221
+ // Update status to initialCommit when transitioning from loading
222
+ // This indicates we're in the process of committing the first transaction
223
+ if ( this . lifecycle . status === `loading` ) {
224
+ this . lifecycle . setStatus ( `initialCommit` )
225
+ }
226
+
227
+ this . state . commitPendingTransactions ( )
228
+ } ,
229
+ markReady : ( ) => {
230
+ this . lifecycle . markReady ( )
231
+ } ,
232
+ truncate : ( ) => {
233
+ const pendingTransaction =
234
+ this . state . pendingSyncedTransactions [
235
+ this . state . pendingSyncedTransactions . length - 1
236
+ ]
237
+ if ( ! pendingTransaction ) {
238
+ throw new NoPendingSyncTransactionWriteError ( )
239
+ }
240
+ if ( pendingTransaction . committed ) {
241
+ throw new SyncTransactionAlreadyCommittedWriteError ( )
242
+ }
243
+
244
+ > >>> >>> 684 c70ec ( Add onLoadMore callback and call it from the requestSnapshot methods )
174
245
// Clear all operations from the current transaction
175
246
pendingTransaction . operations = [ ]
176
247
pendingTransaction . deletedKeys . clear ( )
0 commit comments