@@ -58,12 +58,25 @@ The library uses proxies to create immutable snapshots and track changes:
5858The primary hook for interacting with collections in React components.
5959
6060``` typescript
61+ // Create a collection
6162const { data, insert, update, delete : deleteFn } = useCollection ({
6263 id: ' todos' ,
6364 sync: { /* sync configuration */ },
64- mutationFn: { /* mutation functions */ },
6565 schema: /* optional schema */
6666});
67+
68+ // Create a mutation
69+ const mutation = useOptimisticMutation ({
70+ mutationFn : async ({ mutations }) => {
71+ // Implement your mutation logic here
72+ // This function is called when mutations are committed
73+ }
74+ });
75+
76+ // Use the mutation with collection operations
77+ mutation .mutate (() => {
78+ insert ({ text: ' New todo' });
79+ });
6780```
6881
6982Returns:
@@ -167,10 +180,22 @@ const todoCollection = useCollection({
167180
168181## Transaction Management
169182
170- The library includes a robust transaction management system:
183+ The library includes a simple yet powerful transaction management system. Transactions are created using the ` createTransaction ` function:
184+
185+ ``` typescript
186+ const tx = createTransaction ({
187+ mutationFn : async ({ transaction }) => {
188+ // Implement your mutation logic here
189+ // This function is called when the transaction is committed
190+ },
191+ })
171192
172- - ` TransactionManager ` : Handles transaction lifecycle, persistence, and retry logic
173- - ` TransactionStore ` : Provides persistent storage for transactions using IndexedDB
193+ // Apply mutations within the transaction
194+ tx .mutate (() => {
195+ // All collection operations (insert/update/delete) within this callback
196+ // will be part of this transaction
197+ })
198+ ```
174199
175200Transactions progress through several states:
176201
@@ -204,35 +229,56 @@ const todosConfig = {
204229 primaryKey: [' id' ],
205230 }
206231 ),
207- // Persist mutations to ElectricSQL
208- mutationFn : async (mutations , transaction , config ) => {
209- const response = await fetch (` http://localhost:3001/api/mutations ` , {
210- method: ` POST ` ,
211- headers: {
212- " Content-Type" : ` application/json ` ,
213- },
214- body: JSON .stringify (transaction .mutations ),
232+ };
233+
234+ // In your component
235+ function TodoList() {
236+ const { data, insert, update, delete : deleteFn } = useCollection (todosConfig )
237+
238+ // Create a mutation for handling all todo operations
239+ const todoMutation = useOptimisticMutation ({
240+ mutationFn : async ({ transaction }) => {
241+ // Filter out collection from mutations before sending to server
242+ const payload = transaction .mutations .map (m => {
243+ const { collection, ... payload } = m
244+ return payload
245+ })
246+
247+ const response = await fetch (` http://localhost:3001/api/mutations ` , {
248+ method: ` POST ` ,
249+ headers: {
250+ " Content-Type" : ` application/json ` ,
251+ },
252+ body: JSON .stringify (payload ),
253+ })
254+ if (! response .ok ) {
255+ // Throwing an error will rollback the optimistic state.
256+ throw new Error (` HTTP error! Status: ${response .status } ` )
257+ }
258+
259+ const result = await response .json ()
260+
261+ try {
262+ // Use the awaitTxid function from the ElectricSync configuration
263+ // This waits for the specific transaction to be synced to the server
264+ await transaction .mutations [0 ].collection .config .sync .awaitTxid (result .txid )
265+ } catch (error ) {
266+ console .error (' Error waiting for transaction to sync:' , error );
267+ // Throwing an error will rollback the optimistic state.
268+ throw error ;
269+ }
270+ },
271+ })
272+
273+ // Use the mutation for any todo operations
274+ const addTodo = () => {
275+ todoMutation .mutate (() => {
276+ insert ({ title: ' New todo' , completed: false })
215277 })
216- if (! response .ok ) {
217- // Throwing an error will rollback the optimistic state.
218- throw new Error (` HTTP error! Status: ${response .status } ` )
219- }
278+ }
220279
221- const result = await response .json ()
222-
223- try {
224- // Use the awaitTxid function from the ElectricSync configuration
225- // This waits for the specific transaction to be synced to the server
226- // The second parameter is an optional timeout in milliseconds
227- await config .sync .awaitTxid (persistResult .txid , 10000 )
228- return true ;
229- } catch (error ) {
230- console .error (' Error waiting for transaction to sync:' , error );
231- // Throwing an error will rollback the optimistic state.
232- throw error ;
233- }
234- },
235- };
280+ // ... rest of your component
281+ }
236282
237283// In a route loader
238284export async function loader() {
0 commit comments