@@ -103,25 +103,6 @@ export function streamActionFactory(
103103 const pendingSnapshots : QuerySnapshot [ ] = [ ]
104104 let isProcessing = false
105105
106- const processDocChanges = ( querySnapshot : QuerySnapshot ) => {
107- querySnapshot
108- . docChanges ( )
109- . forEach ( ( docChange : DocumentChange < { [ key : string ] : unknown } > ) => {
110- const docSnapshot = docChange . doc
111- const docData = docSnapshot . data ( )
112- const docMetadata = docSnapshotToDocMetadata ( docSnapshot )
113- if ( docChange . type === 'added' && docData ) {
114- added ( docData , docMetadata )
115- }
116- if ( docChange . type === 'modified' && docData ) {
117- modified ( docData , docMetadata )
118- }
119- if ( docChange . type === 'removed' ) {
120- removed ( docData , docMetadata )
121- }
122- } )
123- }
124-
125106 closeStream = onSnapshot (
126107 query ,
127108 async ( querySnapshot : QuerySnapshot ) => {
@@ -142,13 +123,43 @@ export function streamActionFactory(
142123 await collectionWriteLock . promise
143124 }
144125
145- // Process all pending snapshots synchronously
126+ // Merge all pending snapshots into a single map of docId -> final state
127+ const mergedDocs = new Map <
128+ string ,
129+ {
130+ type : 'added' | 'modified' | 'removed'
131+ docData : { [ key : string ] : unknown }
132+ docMetadata : Parameters < typeof added > [ 1 ]
133+ }
134+ > ( )
135+
146136 let snapshot = pendingSnapshots . shift ( )
147137 while ( snapshot ) {
148- processDocChanges ( snapshot )
138+ snapshot
139+ . docChanges ( )
140+ . forEach ( ( docChange : DocumentChange < { [ key : string ] : unknown } > ) => {
141+ const docSnapshot = docChange . doc
142+ const docData = docSnapshot . data ( )
143+ const docMetadata = docSnapshotToDocMetadata ( docSnapshot )
144+ // Always overwrite with the latest state for this doc
145+ mergedDocs . set ( docSnapshot . id , { type : docChange . type , docData, docMetadata } )
146+ } )
149147 snapshot = pendingSnapshots . shift ( )
150148 }
151149
150+ // Process the merged final states
151+ for ( const { type, docData, docMetadata } of mergedDocs . values ( ) ) {
152+ if ( type === 'added' && docData ) {
153+ added ( docData , docMetadata )
154+ }
155+ if ( type === 'modified' && docData ) {
156+ modified ( docData , docMetadata )
157+ }
158+ if ( type === 'removed' ) {
159+ removed ( docData , docMetadata )
160+ }
161+ }
162+
152163 // Call onFirstData after processing (after write lock, whether collection has docs or not)
153164 if ( ! firstDataReceived && onFirstData ) {
154165 firstDataReceived = true
0 commit comments