Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions packages/db/src/collection/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,9 @@ export class CollectionStateManager<
for (const transaction of committedSyncedTransactions) {
// Handle truncate operations first
if (transaction.truncate) {
console.log(
`[DEBUG] STATE: TRUNCATE starting, current syncedData size=${this.syncedData.size}`,
)
// TRUNCATE PHASE
// 1) Emit a delete for every visible key (synced + optimistic) so downstream listeners/indexes
// observe a clear-before-rebuild. We intentionally skip keys already in
Expand All @@ -507,6 +510,9 @@ export class CollectionStateManager<
...this.syncedData.keys(),
...(truncateOptimisticSnapshot?.upserts.keys() || []),
])
console.log(
`[DEBUG] STATE: TRUNCATE clearing ${visibleKeys.size} visible keys`,
)
for (const key of visibleKeys) {
if (truncateOptimisticSnapshot?.deletes.has(key)) continue
const previousValue =
Expand All @@ -522,6 +528,9 @@ export class CollectionStateManager<
this.syncedData.clear()
this.syncedMetadata.clear()
this.syncedKeys.clear()
console.log(
`[DEBUG] STATE: TRUNCATE complete, syncedData size=${this.syncedData.size}`,
)

// 3) Clear currentVisibleState for truncated keys to ensure subsequent operations
// are compared against the post-truncate state (undefined) rather than pre-truncate state
Expand Down Expand Up @@ -564,22 +573,48 @@ export class CollectionStateManager<
// Update synced data
switch (operation.type) {
case `insert`:
console.log(
`[DEBUG] STATE: INSERT key=${String(key)} value=${JSON.stringify(operation.value)}`,
)
this.syncedData.set(key, operation.value)
break
case `update`: {
const existingData = this.syncedData.get(key)
const hasExisting = existingData !== undefined

console.log(
`[DEBUG] STATE: UPDATE key=${String(key)} mode=${rowUpdateMode} hasExisting=${hasExisting}`,
)
console.log(
`[DEBUG] STATE: UPDATE existing=${JSON.stringify(existingData)}`,
)
console.log(
`[DEBUG] STATE: UPDATE incoming=${JSON.stringify(operation.value)}`,
)

if (!hasExisting) {
console.warn(
`[DEBUG] STATE: ⚠️ UPDATE on non-existent row! key=${String(key)} - this may cause partial data!`,
)
}

if (rowUpdateMode === `partial`) {
const updatedValue = Object.assign(
{},
this.syncedData.get(key),
operation.value,
)
console.log(
`[DEBUG] STATE: UPDATE merged=${JSON.stringify(updatedValue)}`,
)
this.syncedData.set(key, updatedValue)
} else {
this.syncedData.set(key, operation.value)
}
break
}
case `delete`:
console.log(`[DEBUG] STATE: DELETE key=${String(key)}`)
this.syncedData.delete(key)
break
}
Expand Down Expand Up @@ -781,6 +816,9 @@ export class CollectionStateManager<

// Update cached size after synced data changes
this.size = this.calculateSize()
console.log(
`[DEBUG] STATE: COMMIT complete - syncedData size=${this.syncedData.size}, total visible size=${this.size}, events emitted=${events.length}`,
)

// Update indexes for all events before emitting
if (events.length > 0) {
Expand Down
Loading
Loading