diff --git a/docs/guides/mutations.md b/docs/guides/mutations.md index f81fea8e6..323aac56e 100644 --- a/docs/guides/mutations.md +++ b/docs/guides/mutations.md @@ -160,7 +160,7 @@ onUpdate: async ({ transaction }) => { ### Intent-Based Mutations with Custom Actions -For more complex scenarios, use `createOptimisticAction` or `createTransaction` to create **intent-based mutations** that capture specific user actions. +For more complex scenarios, use `createOptimisticAction` to create **intent-based mutations** that capture specific user actions. ```tsx // Intent: "like this post" @@ -197,7 +197,45 @@ Custom actions provide the cleanest way to capture specific types of mutations a - **Collection-level mutations** (`collection.update`): Simple CRUD operations on a single collection - **`createOptimisticAction`**: Intent-based operations, multi-collection mutations, immediately committed -- **`createTransaction`**: Fully custom transactions, delayed commits, multi-step workflows +- **Bypass the mutation system**: Use your existing mutation logic without rewriting + +### Bypass the Mutation System + +If you already have mutation logic in an existing system and don't want to rewrite it, you can **completely bypass** TanStack DB's mutation system and use your existing patterns. + +With this approach, you write to the server like normal using your existing logic, then use your collection's mechanism for refetching or syncing data to await the server write. After the sync completes, the collection will have the updated server data and you can render the new state, hide loading indicators, show success messages, navigate to a new page, etc. + +```tsx +// Call your backend directly with your existing logic +const handleUpdateTodo = async (todoId, changes) => { + await api.todos.update(todoId, changes) + + // Wait for the server change to load into the collection + await todoCollection.utils.refetch() + + // Now you know the new data is loaded and can render it or hide loaders +} + +// With Electric +const handleUpdateTodo = async (todoId, changes) => { + const { txid } = await api.todos.update(todoId, changes) + + // Wait for this specific transaction to sync into the collection + await todoCollection.utils.awaitTxId(txid) + + // Now the server change is loaded and you can update UI accordingly +} +``` + +Use this approach when: +- You have existing mutation logic you don't want to rewrite +- You're comfortable with your current mutation patterns +- You want to use TanStack DB only for queries and state management + +How to sync changes back: +- **QueryCollection**: Manually refetch with `collection.utils.refetch()` to reload data from the server +- **ElectricCollection**: Use `collection.utils.awaitTxId(txid)` to wait for a specific transaction to sync +- **Other sync systems**: Wait for your sync mechanism to update the collection ## Mutation Lifecycle