@@ -9,6 +9,8 @@ import com.powersync.db.schema.Schema
99import com.powersync.sync.SyncOptions
1010import com.powersync.sync.SyncStatus
1111import com.powersync.utils.JsonParam
12+ import kotlinx.coroutines.flow.Flow
13+ import kotlinx.coroutines.flow.firstOrNull
1214import kotlin.coroutines.cancellation.CancellationException
1315
1416/* *
@@ -123,7 +125,7 @@ public interface PowerSyncDatabase : Queries {
123125 *
124126 * Returns null if there is no data to upload.
125127 *
126- * Use this from the [PowerSyncBackendConnector.uploadData]` callback.
128+ * Use this from the [PowerSyncBackendConnector.uploadData] callback.
127129 *
128130 * Once the data have been successfully uploaded, call [CrudTransaction.complete] before
129131 * requesting the next transaction.
@@ -132,7 +134,41 @@ public interface PowerSyncDatabase : Queries {
132134 * All data for the transaction is loaded into memory.
133135 */
134136 @Throws(PowerSyncException ::class , CancellationException ::class )
135- public suspend fun getNextCrudTransaction (): CrudTransaction ?
137+ public suspend fun getNextCrudTransaction (): CrudTransaction ? = getCrudTransactions().firstOrNull()
138+
139+ /* *
140+ * Obtains a flow of transactions with local data against the database.
141+
142+ * This is typically used from the [PowerSyncBackendConnector.uploadData] callback.
143+ * Each entry emitted by the returned flow is a full transaction containing all local writes
144+ * made while that transaction was active.
145+ *
146+ * Unlike [getNextCrudTransaction], which always returns the oldest transaction that hasn't
147+ * been [CrudTransaction.complete]d yet, this flow can be used to collect multiple transactions.
148+ * Calling [CrudTransaction.complete] will mark _all_ transactions emitted by the flow until
149+ * that point as completed.
150+ *
151+ * This can be used to upload multiple transactions in a single batch, e.g with:
152+ *
153+ * ```Kotlin
154+ * val batch = mutableListOf<CrudEntry>()
155+ * var lastTx: CrudTransaction? = null
156+ *
157+ * database.getCrudTransactions().takeWhile { batch.size < 10 }.collect {
158+ * batch.addAll(it.crud)
159+ * lastTx = it
160+ * }
161+ *
162+ * if (batch.isNotEmpty()) {
163+ * uploadChanges(batch)
164+ * lastTx!!.complete(null)
165+ * }
166+ * ````
167+ *
168+ * If there is no local data to upload, returns an empty flow.
169+ */
170+ @Throws(PowerSyncException ::class , CancellationException ::class )
171+ public suspend fun getCrudTransactions (): Flow <CrudTransaction >
136172
137173 /* *
138174 * Convenience method to get the current version of PowerSync.
0 commit comments