[{"data":1,"prerenderedAt":3000},["ShallowReactive",2],{"navigation_docs_en":3,"-en-recipes-mutations":342,"-en-recipes-mutations-surround":2995},[4,45,91,137,195,236,257,291,327],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","/en/getting-started","en/01.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"What is Qora?","/en/getting-started/what-is-qora","en/01.getting-started/2.what-is-qora","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/en/getting-started/installation","en/01.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick Start","/en/getting-started/quick-start","en/01.getting-started/4.quick-start",{"title":25,"path":26,"stem":27,"icon":28},"Comparison","/en/getting-started/comparison","en/01.getting-started/5.comparison","i-lucide-scale",{"title":30,"path":31,"stem":32,"icon":33},"Coming from TanStack Query","/en/getting-started/coming-from-tanstack-query","en/01.getting-started/6.coming-from-tanstack-query","i-lucide-arrow-left-right",{"title":35,"path":36,"stem":37,"icon":38},"Migrating from Other Libraries","/en/getting-started/migrating-from-other-libraries","en/01.getting-started/7.migrating-from-other-libraries","i-lucide-arrow-right-left",{"title":40,"path":41,"stem":42,"icon":43},"AI Assistants","/en/getting-started/ai-assistants","en/01.getting-started/8.ai-assistants","i-lucide-sparkles",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Core Concepts","i-lucide-book-open","/en/core-concepts","en/02.core-concepts",[51,56,61,66,71,76,81,86],{"title":52,"path":53,"stem":54,"icon":55},"Queries","/en/core-concepts/queries","en/02.core-concepts/1.queries","i-lucide-database",{"title":57,"path":58,"stem":59,"icon":60},"Query Keys","/en/core-concepts/query-keys","en/02.core-concepts/2.query-keys","i-lucide-key-round",{"title":62,"path":63,"stem":64,"icon":65},"Query States","/en/core-concepts/query-states","en/02.core-concepts/3.query-states","i-lucide-activity",{"title":67,"path":68,"stem":69,"icon":70},"Caching","/en/core-concepts/caching","en/02.core-concepts/4.caching","i-lucide-layers-3",{"title":72,"path":73,"stem":74,"icon":75},"Stale-While-Revalidate","/en/core-concepts/stale-while-revalidate","en/02.core-concepts/5.stale-while-revalidate","i-lucide-timer-reset",{"title":77,"path":78,"stem":79,"icon":80},"Deduplication","/en/core-concepts/deduplication","en/02.core-concepts/6.deduplication","i-lucide-copy-minus",{"title":82,"path":83,"stem":84,"icon":85},"Mutations & Invalidation","/en/core-concepts/mutations","en/02.core-concepts/7.mutations","i-lucide-pencil-line",{"title":87,"path":88,"stem":89,"icon":90},"Offline & Network","/en/core-concepts/offline","en/02.core-concepts/8.offline","i-lucide-wifi-off",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":44},"Flutter Integration","i-lucide-smartphone","/en/flutter-integration","en/03.flutter-integration",[97,102,107,112,117,122,127,132],{"title":98,"path":99,"stem":100,"icon":101},"Setup","/en/flutter-integration/setup","en/03.flutter-integration/1.setup","i-lucide-wrench",{"title":103,"path":104,"stem":105,"icon":106},"QoraScope","/en/flutter-integration/qora-scope","en/03.flutter-integration/2.qora-scope","i-lucide-share-2",{"title":108,"path":109,"stem":110,"icon":111},"QoraBuilder","/en/flutter-integration/qora-builder","en/03.flutter-integration/3.qora-builder","i-lucide-blocks",{"title":113,"path":114,"stem":115,"icon":116},"QoraMutationBuilder","/en/flutter-integration/qora-mutation-builder","en/03.flutter-integration/4.qora-mutation-builder","i-lucide-pencil",{"title":118,"path":119,"stem":120,"icon":121},"InfiniteQueryBuilder","/en/flutter-integration/infinite-query-builder","en/03.flutter-integration/5.infinite-query-builder","i-lucide-infinity",{"title":123,"path":124,"stem":125,"icon":126},"Hooks (flutter_hooks)","/en/flutter-integration/hooks","en/03.flutter-integration/6.hooks","i-lucide-anchor",{"title":128,"path":129,"stem":130,"icon":131},"Network Status Widgets","/en/flutter-integration/network-status","en/03.flutter-integration/7.network-status","i-lucide-wifi",{"title":133,"path":134,"stem":135,"icon":136},"Best Practices","/en/flutter-integration/best-practices","en/03.flutter-integration/8.best-practices","i-lucide-badge-check",{"title":138,"icon":139,"path":140,"stem":141,"children":142,"page":44},"Recipes","i-lucide-chef-hat","/en/recipes","en/04.recipes",[143,147,152,157,162,166,171,176,181,186,191],{"title":144,"path":145,"stem":146,"icon":85},"Mutations","/en/recipes/mutations","en/04.recipes/02.mutations",{"title":148,"path":149,"stem":150,"icon":151},"Optimistic Updates","/en/recipes/optimistic-updates","en/04.recipes/03.optimistic-updates","i-lucide-zap",{"title":153,"path":154,"stem":155,"icon":156},"Persistence","/en/recipes/persistence","en/04.recipes/04.persistence","i-lucide-hard-drive",{"title":158,"path":159,"stem":160,"icon":161},"Network Aware","/en/recipes/network-aware","en/04.recipes/05.network-aware","i-lucide-signal",{"title":163,"path":164,"stem":165,"icon":121},"Infinite Queries","/en/recipes/infinite-queries","en/04.recipes/06.infinite-queries",{"title":167,"path":168,"stem":169,"icon":170},"Dependent Queries","/en/recipes/dependent-queries","en/04.recipes/07.dependent-queries","i-lucide-link-2",{"title":172,"path":173,"stem":174,"icon":175},"Cancellation","/en/recipes/cancel-token","en/04.recipes/08.cancel-token","i-lucide-circle-slash",{"title":177,"path":178,"stem":179,"icon":180},"SSR Hydration","/en/recipes/ssr-hydration","en/04.recipes/09.ssr-hydration","i-lucide-server",{"title":182,"path":183,"stem":184,"icon":185},"Error Handling","/en/recipes/error-handling","en/04.recipes/10.error-handling","i-lucide-shield-alert",{"title":187,"path":188,"stem":189,"icon":190},"Testing","/en/recipes/testing","en/04.recipes/11.testing","i-lucide-flask-conical",{"title":192,"path":193,"stem":194},"Route-Level Prefetching","/en/recipes/prefetch","en/04.recipes/12.prefetch",{"title":196,"icon":197,"path":198,"stem":199,"children":200,"page":44},"API Reference","i-lucide-file-code","/en/api-reference","en/05.api-reference",[201,206,210,214,219,224,228,232],{"title":202,"path":203,"stem":204,"icon":205},"QoraClient","/en/api-reference/qora-client","en/05.api-reference/1.qora-client","i-lucide-cpu",{"title":207,"path":208,"stem":209,"icon":60},"QoraKey","/en/api-reference/qora-key","en/05.api-reference/2.qora-key",{"title":211,"path":212,"stem":213,"icon":65},"QoraState","/en/api-reference/qora-state","en/05.api-reference/3.qora-state",{"title":215,"path":216,"stem":217,"icon":218},"QoraOptions","/en/api-reference/qora-options","en/05.api-reference/4.qora-options","i-lucide-sliders-horizontal",{"title":220,"path":221,"stem":222,"icon":223},"QoraClientConfig","/en/api-reference/qora-client-config","en/05.api-reference/5.qora-client-config","i-lucide-settings-2",{"title":225,"path":226,"stem":227,"icon":85},"Mutation API","/en/api-reference/qora-mutation","en/05.api-reference/6.qora-mutation",{"title":229,"path":230,"stem":231,"icon":156},"PersistQoraClient","/en/api-reference/persist-qora-client","en/05.api-reference/7.persist-qora-client",{"title":233,"path":234,"stem":235,"icon":121},"Infinite Query","/en/api-reference/infinite-query","en/05.api-reference/8.infinite-query",{"title":237,"icon":238,"path":239,"stem":240,"children":241,"page":44},"DevTools","i-lucide-bug","/en/devtools","en/06.devtools",[242,247,252],{"title":243,"path":244,"stem":245,"icon":246},"Overview","/en/devtools/overview","en/06.devtools/1.overview","i-lucide-layout-dashboard",{"title":248,"path":249,"stem":250,"icon":251},"In-App Overlay","/en/devtools/overlay","en/06.devtools/2.overlay","i-lucide-layers",{"title":253,"path":254,"stem":255,"icon":256},"Data Serialization","/en/devtools/data-display","en/06.devtools/4.data-display","i-lucide-eye",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":44},"Third Party","i-lucide-puzzle","/en/third-party","en/07.third-party",[263,268,272,277,282,286],{"title":264,"path":265,"stem":266,"icon":267},"With Provider","/en/third-party/with-provider","en/07.third-party/1.with-provider","i-lucide-plug",{"title":269,"path":270,"stem":271,"icon":111},"With BLoC","/en/third-party/with-bloc","en/07.third-party/2.with-bloc",{"title":273,"path":274,"stem":275,"icon":276},"With Riverpod","/en/third-party/with-riverpod","en/07.third-party/3.with-riverpod","i-lucide-droplets",{"title":278,"path":279,"stem":280,"icon":281},"With RxDart","/en/third-party/with-rxdart","en/07.third-party/4.with-rxdart","i-lucide-git-branch",{"title":283,"path":284,"stem":285},"With Dio","/en/third-party/with-dio","en/07.third-party/5.with-dio",{"title":287,"path":288,"stem":289,"icon":290},"With GraphQL","/en/third-party/with-graphql","en/07.third-party/6.with-graphql","i-lucide-binary",{"title":292,"icon":190,"path":293,"stem":294,"children":295,"page":44},"Examples","/en/examples","en/08.examples",[296,301,305,310,314,318,322],{"title":297,"path":298,"stem":299,"icon":300},"Case Study: User List & Detail","/en/examples/basic-query","en/08.examples/1.basic-query","i-lucide-play-circle",{"title":302,"path":303,"stem":304,"icon":151},"Case Study: Optimistic Mutations & Rollback","/en/examples/mutations-optimistic","en/08.examples/2.mutations-optimistic",{"title":306,"path":307,"stem":308,"icon":309},"Case Study: Infinite Scroll Feed","/en/examples/infinite-scroll","en/08.examples/3.infinite-scroll","i-lucide-scroll",{"title":311,"path":312,"stem":313,"icon":90},"Case Study: Offline-First Todo App","/en/examples/offline-first","en/08.examples/4.offline-first",{"title":315,"path":316,"stem":317,"icon":161},"Case Study: Network Awareness","/en/examples/network-awareness","en/08.examples/5.network-awareness",{"title":319,"path":320,"stem":321,"icon":126},"Case Study: Hooks Integration","/en/examples/hooks-integration","en/08.examples/6.hooks-integration",{"title":323,"path":324,"stem":325,"icon":326},"Case Study: Complete Todo App","/en/examples/complete-todo-app","en/08.examples/7.complete-todo-app","i-lucide-check-square",{"title":328,"icon":329,"path":330,"stem":331,"children":332,"page":44},"Help","i-lucide-life-buoy","/en/help","en/09.help",[333,338],{"title":334,"path":335,"stem":336,"icon":337},"FAQ","/en/help/faq","en/09.help/1.faq","i-lucide-circle-help",{"title":339,"path":340,"stem":341,"icon":101},"Troubleshooting","/en/help/troubleshooting","en/09.help/2.troubleshooting",{"id":343,"title":144,"body":344,"description":2986,"extension":2987,"links":2988,"meta":2989,"navigation":2990,"path":145,"seo":2991,"stem":146,"__hash__":2994},"docs_en/en/04.recipes/02.mutations.md",{"type":345,"value":346,"toc":2970},"minimark",[347,356,364,367,372,382,393,395,399,806,819,821,825,831,1160,1259,1273,1275,1279,1293,1343,1353,1429,1434,1437,1492,1513,1566,1591,1593,1596,1599,1602,1636,1961,1971,1973,1980,1992,2074,2077,2079,2083,2086,2151,2157,2159,2163,2175,2242,2244,2248,2264,2513,2522,2536,2538,2542,2551,2936,2938,2942,2966],[348,349,350,351,355],"p",{},"A ",[352,353,354],"strong",{},"mutation"," is any operation that changes server-side state, including create, update, and delete operations. Queries are read-only and cache-driven. Mutations are explicit write operations.",[348,357,358,359,363],{},"Qora manages mutations with ",[360,361,362],"code",{},"MutationController",", a standalone lifecycle controller with no cache key, no deduplication, and no SWR behavior.",[365,366],"hr",{},[368,369,371],"h2",{"id":370},"the-state-machine","The State Machine",[373,374,380],"pre",{"className":375,"code":377,"language":378,"meta":379},[376],"language-text","MutationIdle\n    │\n    │  mutate(variables)\n    ▼\nMutationPending\n    │\n    ├── success ──▶ MutationSuccess\n    │\n    └── failure ──▶ MutationFailure\n            │\n            └── reset() ──▶ MutationIdle\n","text","",[360,381,377],{"__ignoreMap":379},[348,383,384,385,388,389,392],{},"Every state carries ",[360,386,387],{},"variables",": the value that was passed to ",[360,390,391],{},"mutate()",". This makes it easy to display \"Creating post…\" or \"Failed to delete comment #42\" without extra local state.",[365,394],{},[368,396,398],{"id":397},"basic-usage","Basic Usage",[373,400,405],{"className":401,"code":402,"filename":403,"language":404,"meta":379,"style":379},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","final controller = MutationController\u003CPost, String, void>(\n  mutator: (title) => api.createPost(title),\n);\n\n// Trigger the mutation\nfinal post = await controller.mutate('Hello, Qora!');\n// Returns the Post on success, or null on failure.\n\n// Observe state transitions\ncontroller.stream.listen((state) {\n  switch (state) {\n    case MutationIdle():\n      print('Ready');\n    case MutationPending(:final variables):\n      print('Creating \"$variables\"…');\n    case MutationSuccess(:final data):\n      print('Created: ${data.title}');\n    case MutationFailure(:final error):\n      print('Failed: $error');\n  }\n});\n\n// Reset to idle after showing the result\ncontroller.reset();\n\n// Always dispose when done\ncontroller.dispose();\n","post_repository.dart","dart",[360,406,407,448,479,488,495,502,535,541,546,552,571,580,595,610,629,652,671,702,721,742,748,756,761,767,781,786,792],{"__ignoreMap":379},[408,409,412,416,420,424,428,431,434,437,440,442,445],"span",{"class":410,"line":411},"line",1,[408,413,415],{"class":414},"spNyl","final",[408,417,419],{"class":418},"sTEyZ"," controller ",[408,421,423],{"class":422},"sMK4o","=",[408,425,427],{"class":426},"sBMFI"," MutationController",[408,429,430],{"class":418},"\u003C",[408,432,433],{"class":426},"Post",[408,435,436],{"class":418},", ",[408,438,439],{"class":426},"String",[408,441,436],{"class":418},[408,443,444],{"class":414},"void",[408,446,447],{"class":418},">(\n",[408,449,451,454,457,460,463,466,469,473,476],{"class":410,"line":450},2,[408,452,453],{"class":418},"  mutator",[408,455,456],{"class":422},":",[408,458,459],{"class":418}," (title) ",[408,461,462],{"class":422},"=>",[408,464,465],{"class":418}," api",[408,467,468],{"class":422},".",[408,470,472],{"class":471},"s2Zo4","createPost",[408,474,475],{"class":418},"(title)",[408,477,478],{"class":422},",\n",[408,480,482,485],{"class":410,"line":481},3,[408,483,484],{"class":418},")",[408,486,487],{"class":422},";\n",[408,489,491],{"class":410,"line":490},4,[408,492,494],{"emptyLinePlaceholder":493},true,"\n",[408,496,498],{"class":410,"line":497},5,[408,499,501],{"class":500},"sHwdD","// Trigger the mutation\n",[408,503,505,507,510,512,516,519,521,524,527,531,533],{"class":410,"line":504},6,[408,506,415],{"class":414},[408,508,509],{"class":418}," post ",[408,511,423],{"class":422},[408,513,515],{"class":514},"s7zQu"," await",[408,517,518],{"class":418}," controller",[408,520,468],{"class":422},[408,522,523],{"class":471},"mutate",[408,525,526],{"class":418},"(",[408,528,530],{"class":529},"sfazB","'Hello, Qora!'",[408,532,484],{"class":418},[408,534,487],{"class":422},[408,536,538],{"class":410,"line":537},7,[408,539,540],{"class":500},"// Returns the Post on success, or null on failure.\n",[408,542,544],{"class":410,"line":543},8,[408,545,494],{"emptyLinePlaceholder":493},[408,547,549],{"class":410,"line":548},9,[408,550,551],{"class":500},"// Observe state transitions\n",[408,553,555,558,560,563,565,568],{"class":410,"line":554},10,[408,556,557],{"class":418},"controller",[408,559,468],{"class":422},[408,561,562],{"class":418},"stream",[408,564,468],{"class":422},[408,566,567],{"class":471},"listen",[408,569,570],{"class":418},"((state) {\n",[408,572,574,577],{"class":410,"line":573},11,[408,575,576],{"class":514},"  switch",[408,578,579],{"class":418}," (state) {\n",[408,581,583,586,589,592],{"class":410,"line":582},12,[408,584,585],{"class":514},"    case",[408,587,588],{"class":426}," MutationIdle",[408,590,591],{"class":418},"()",[408,593,594],{"class":422},":\n",[408,596,598,601,603,606,608],{"class":410,"line":597},13,[408,599,600],{"class":471},"      print",[408,602,526],{"class":418},[408,604,605],{"class":529},"'Ready'",[408,607,484],{"class":418},[408,609,487],{"class":422},[408,611,613,615,618,620,622,624,627],{"class":410,"line":612},14,[408,614,585],{"class":514},[408,616,617],{"class":426}," MutationPending",[408,619,526],{"class":418},[408,621,456],{"class":422},[408,623,415],{"class":414},[408,625,626],{"class":418}," variables)",[408,628,594],{"class":422},[408,630,632,634,636,639,642,645,648,650],{"class":410,"line":631},15,[408,633,600],{"class":471},[408,635,526],{"class":418},[408,637,638],{"class":529},"'Creating \"",[408,640,641],{"class":418},"$",[408,643,387],{"class":644},"sHdIc",[408,646,647],{"class":529},"\"…'",[408,649,484],{"class":418},[408,651,487],{"class":422},[408,653,655,657,660,662,664,666,669],{"class":410,"line":654},16,[408,656,585],{"class":514},[408,658,659],{"class":426}," MutationSuccess",[408,661,526],{"class":418},[408,663,456],{"class":422},[408,665,415],{"class":414},[408,667,668],{"class":418}," data)",[408,670,594],{"class":422},[408,672,674,676,678,681,684,687,689,692,695,698,700],{"class":410,"line":673},17,[408,675,600],{"class":471},[408,677,526],{"class":418},[408,679,680],{"class":529},"'Created: ",[408,682,683],{"class":418},"${",[408,685,686],{"class":644},"data",[408,688,468],{"class":418},[408,690,691],{"class":644},"title",[408,693,694],{"class":418},"}",[408,696,697],{"class":529},"'",[408,699,484],{"class":418},[408,701,487],{"class":422},[408,703,705,707,710,712,714,716,719],{"class":410,"line":704},18,[408,706,585],{"class":514},[408,708,709],{"class":426}," MutationFailure",[408,711,526],{"class":418},[408,713,456],{"class":422},[408,715,415],{"class":414},[408,717,718],{"class":418}," error)",[408,720,594],{"class":422},[408,722,724,726,728,731,733,736,738,740],{"class":410,"line":723},19,[408,725,600],{"class":471},[408,727,526],{"class":418},[408,729,730],{"class":529},"'Failed: ",[408,732,641],{"class":418},[408,734,735],{"class":644},"error",[408,737,697],{"class":529},[408,739,484],{"class":418},[408,741,487],{"class":422},[408,743,745],{"class":410,"line":744},20,[408,746,747],{"class":418},"  }\n",[408,749,751,754],{"class":410,"line":750},21,[408,752,753],{"class":418},"})",[408,755,487],{"class":422},[408,757,759],{"class":410,"line":758},22,[408,760,494],{"emptyLinePlaceholder":493},[408,762,764],{"class":410,"line":763},23,[408,765,766],{"class":500},"// Reset to idle after showing the result\n",[408,768,770,772,774,777,779],{"class":410,"line":769},24,[408,771,557],{"class":418},[408,773,468],{"class":422},[408,775,776],{"class":471},"reset",[408,778,591],{"class":418},[408,780,487],{"class":422},[408,782,784],{"class":410,"line":783},25,[408,785,494],{"emptyLinePlaceholder":493},[408,787,789],{"class":410,"line":788},26,[408,790,791],{"class":500},"// Always dispose when done\n",[408,793,795,797,799,802,804],{"class":410,"line":794},27,[408,796,557],{"class":418},[408,798,468],{"class":422},[408,800,801],{"class":471},"dispose",[408,803,591],{"class":418},[408,805,487],{"class":422},[348,807,808,810,811,814,815,818],{},[360,809,391],{}," never throws. Errors are captured in ",[360,812,813],{},"MutationFailure"," state and returned as ",[360,816,817],{},"null"," from the call site.",[365,820],{},[368,822,824],{"id":823},"lifecycle-callbacks","Lifecycle Callbacks",[348,826,827,830],{},[360,828,829],{},"MutationOptions"," provides four hooks that run around the mutation:",[373,832,834],{"className":401,"code":833,"filename":403,"language":404,"meta":379,"style":379},"final controller = MutationController\u003CPost, String, void>(\n  mutator: (title) => api.createPost(title),\n  options: MutationOptions(\n    invalidates: [['posts']], // Auto-refresh the posts list on success\n    onMutate: (title) async {\n      print('About to create \"$title\"');\n      // Return value becomes TContext: passed to onSuccess, onError, onSettled.\n    },\n    onSuccess: (post, title, _) async {\n      print('Created: ${post.id}');\n    },\n    onError: (error, title, _) async {\n      print('Failed to create \"$title\": $error');\n    },\n    onSettled: (post, error, title, _) async {\n      // Called regardless of outcome.\n      analytics.track('post_create_attempt', {'success': error == null});\n    },\n  ),\n);\n",[360,835,836,860,880,893,915,930,950,955,962,986,1012,1018,1040,1066,1072,1098,1103,1141,1147,1154],{"__ignoreMap":379},[408,837,838,840,842,844,846,848,850,852,854,856,858],{"class":410,"line":411},[408,839,415],{"class":414},[408,841,419],{"class":418},[408,843,423],{"class":422},[408,845,427],{"class":426},[408,847,430],{"class":418},[408,849,433],{"class":426},[408,851,436],{"class":418},[408,853,439],{"class":426},[408,855,436],{"class":418},[408,857,444],{"class":414},[408,859,447],{"class":418},[408,861,862,864,866,868,870,872,874,876,878],{"class":410,"line":450},[408,863,453],{"class":418},[408,865,456],{"class":422},[408,867,459],{"class":418},[408,869,462],{"class":422},[408,871,465],{"class":418},[408,873,468],{"class":422},[408,875,472],{"class":471},[408,877,475],{"class":418},[408,879,478],{"class":422},[408,881,882,885,887,890],{"class":410,"line":481},[408,883,884],{"class":418},"  options",[408,886,456],{"class":422},[408,888,889],{"class":426}," MutationOptions",[408,891,892],{"class":418},"(\n",[408,894,895,898,900,903,906,909,912],{"class":410,"line":490},[408,896,897],{"class":418},"    invalidates",[408,899,456],{"class":422},[408,901,902],{"class":418}," [[",[408,904,905],{"class":529},"'posts'",[408,907,908],{"class":418},"]]",[408,910,911],{"class":422},",",[408,913,914],{"class":500}," // Auto-refresh the posts list on success\n",[408,916,917,920,922,924,927],{"class":410,"line":497},[408,918,919],{"class":418},"    onMutate",[408,921,456],{"class":422},[408,923,459],{"class":418},[408,925,926],{"class":514},"async",[408,928,929],{"class":418}," {\n",[408,931,932,934,936,939,941,943,946,948],{"class":410,"line":504},[408,933,600],{"class":471},[408,935,526],{"class":418},[408,937,938],{"class":529},"'About to create \"",[408,940,641],{"class":418},[408,942,691],{"class":644},[408,944,945],{"class":529},"\"'",[408,947,484],{"class":418},[408,949,487],{"class":422},[408,951,952],{"class":410,"line":537},[408,953,954],{"class":500},"      // Return value becomes TContext: passed to onSuccess, onError, onSettled.\n",[408,956,957,960],{"class":410,"line":543},[408,958,959],{"class":418},"    }",[408,961,478],{"class":422},[408,963,964,967,969,972,974,977,979,982,984],{"class":410,"line":548},[408,965,966],{"class":418},"    onSuccess",[408,968,456],{"class":422},[408,970,971],{"class":418}," (post",[408,973,911],{"class":422},[408,975,976],{"class":418}," title",[408,978,911],{"class":422},[408,980,981],{"class":418}," _) ",[408,983,926],{"class":514},[408,985,929],{"class":418},[408,987,988,990,992,994,996,999,1001,1004,1006,1008,1010],{"class":410,"line":554},[408,989,600],{"class":471},[408,991,526],{"class":418},[408,993,680],{"class":529},[408,995,683],{"class":418},[408,997,998],{"class":644},"post",[408,1000,468],{"class":418},[408,1002,1003],{"class":644},"id",[408,1005,694],{"class":418},[408,1007,697],{"class":529},[408,1009,484],{"class":418},[408,1011,487],{"class":422},[408,1013,1014,1016],{"class":410,"line":573},[408,1015,959],{"class":418},[408,1017,478],{"class":422},[408,1019,1020,1023,1025,1028,1030,1032,1034,1036,1038],{"class":410,"line":582},[408,1021,1022],{"class":418},"    onError",[408,1024,456],{"class":422},[408,1026,1027],{"class":418}," (error",[408,1029,911],{"class":422},[408,1031,976],{"class":418},[408,1033,911],{"class":422},[408,1035,981],{"class":418},[408,1037,926],{"class":514},[408,1039,929],{"class":418},[408,1041,1042,1044,1046,1049,1051,1053,1056,1058,1060,1062,1064],{"class":410,"line":597},[408,1043,600],{"class":471},[408,1045,526],{"class":418},[408,1047,1048],{"class":529},"'Failed to create \"",[408,1050,641],{"class":418},[408,1052,691],{"class":644},[408,1054,1055],{"class":529},"\": ",[408,1057,641],{"class":418},[408,1059,735],{"class":644},[408,1061,697],{"class":529},[408,1063,484],{"class":418},[408,1065,487],{"class":422},[408,1067,1068,1070],{"class":410,"line":612},[408,1069,959],{"class":418},[408,1071,478],{"class":422},[408,1073,1074,1077,1079,1081,1083,1086,1088,1090,1092,1094,1096],{"class":410,"line":631},[408,1075,1076],{"class":418},"    onSettled",[408,1078,456],{"class":422},[408,1080,971],{"class":418},[408,1082,911],{"class":422},[408,1084,1085],{"class":418}," error",[408,1087,911],{"class":422},[408,1089,976],{"class":418},[408,1091,911],{"class":422},[408,1093,981],{"class":418},[408,1095,926],{"class":514},[408,1097,929],{"class":418},[408,1099,1100],{"class":410,"line":654},[408,1101,1102],{"class":500},"      // Called regardless of outcome.\n",[408,1104,1105,1108,1110,1113,1115,1118,1120,1123,1126,1128,1131,1134,1137,1139],{"class":410,"line":673},[408,1106,1107],{"class":418},"      analytics",[408,1109,468],{"class":422},[408,1111,1112],{"class":471},"track",[408,1114,526],{"class":418},[408,1116,1117],{"class":529},"'post_create_attempt'",[408,1119,911],{"class":422},[408,1121,1122],{"class":418}," {",[408,1124,1125],{"class":529},"'success'",[408,1127,456],{"class":422},[408,1129,1130],{"class":418}," error ",[408,1132,1133],{"class":422},"==",[408,1135,1136],{"class":422}," null",[408,1138,753],{"class":418},[408,1140,487],{"class":422},[408,1142,1143,1145],{"class":410,"line":704},[408,1144,959],{"class":418},[408,1146,478],{"class":422},[408,1148,1149,1152],{"class":410,"line":723},[408,1150,1151],{"class":418},"  )",[408,1153,478],{"class":422},[408,1155,1156,1158],{"class":410,"line":744},[408,1157,484],{"class":418},[408,1159,487],{"class":422},[1161,1162,1163,1179],"table",{},[1164,1165,1166],"thead",{},[1167,1168,1169,1173,1176],"tr",{},[1170,1171,1172],"th",{},"Hook",[1170,1174,1175],{},"When",[1170,1177,1178],{},"Receives",[1180,1181,1182,1198,1218,1237],"tbody",{},[1167,1183,1184,1190,1193],{},[1185,1186,1187],"td",{},[360,1188,1189],{},"onMutate(variables)",[1185,1191,1192],{},"Before the mutator starts",[1185,1194,1195],{},[360,1196,1197],{},"TVariables",[1167,1199,1200,1205,1208],{},[1185,1201,1202],{},[360,1203,1204],{},"onSuccess(data, variables, context)",[1185,1206,1207],{},"After a successful mutator",[1185,1209,1210,436,1213,436,1215],{},[360,1211,1212],{},"TData",[360,1214,1197],{},[360,1216,1217],{},"TContext?",[1167,1219,1220,1225,1228],{},[1185,1221,1222],{},[360,1223,1224],{},"onError(error, variables, context)",[1185,1226,1227],{},"After the mutator throws",[1185,1229,1230,436,1233,436,1235],{},[360,1231,1232],{},"Object",[360,1234,1197],{},[360,1236,1217],{},[1167,1238,1239,1244,1247],{},[1185,1240,1241],{},[360,1242,1243],{},"onSettled(data, error, variables, context)",[1185,1245,1246],{},"After either outcome",[1185,1248,1249,436,1252,436,1255,436,1257],{},[360,1250,1251],{},"TData?",[360,1253,1254],{},"Object?",[360,1256,1197],{},[360,1258,1217],{},[348,1260,1261,1262,1265,1266,1269,1270,1272],{},"The value returned by ",[360,1263,1264],{},"onMutate"," becomes ",[360,1267,1268],{},"TContext",": the third type parameter of ",[360,1271,362],{},". This is the mechanism behind optimistic update rollback.",[365,1274],{},[368,1276,1278],{"id":1277},"automatic-invalidation","Automatic Invalidation",[348,1280,1281,1282,1285,1286,1289,1290,456],{},"Instead of calling ",[360,1283,1284],{},"client.invalidate()"," manually inside ",[360,1287,1288],{},"onSuccess",", declare the query keys upfront with ",[360,1291,1292],{},"invalidates",[373,1294,1296],{"className":401,"code":1295,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  invalidates: [['posts'], ['users', userId]],\n)\n",[360,1297,1298,1309,1338],{"__ignoreMap":379},[408,1299,1300,1303,1305,1307],{"class":410,"line":411},[408,1301,1302],{"class":418},"options",[408,1304,456],{"class":422},[408,1306,889],{"class":426},[408,1308,892],{"class":418},[408,1310,1311,1314,1316,1318,1320,1323,1325,1328,1331,1333,1336],{"class":410,"line":450},[408,1312,1313],{"class":418},"  invalidates",[408,1315,456],{"class":422},[408,1317,902],{"class":418},[408,1319,905],{"class":529},[408,1321,1322],{"class":418},"]",[408,1324,911],{"class":422},[408,1326,1327],{"class":418}," [",[408,1329,1330],{"class":529},"'users'",[408,1332,911],{"class":422},[408,1334,1335],{"class":418}," userId]]",[408,1337,478],{"class":422},[408,1339,1340],{"class":410,"line":481},[408,1341,1342],{"class":418},")\n",[348,1344,1345,1346,1349,1350,1352],{},"Each key is invalidated automatically after the mutation succeeds, whether it runs immediately or is replayed from the offline queue. Invalidations happen ",[352,1347,1348],{},"after"," ",[360,1351,1288],{}," completes, so the cache is freshened after any manual side-effects.",[373,1354,1356],{"className":401,"code":1355,"language":404,"meta":379,"style":379},"// Before: manual\nonSuccess: (_, __, ___) async { client.invalidate(['posts']); }\n\n// After: automatic\ninvalidates: [['posts']],\n",[360,1357,1358,1363,1406,1410,1415],{"__ignoreMap":379},[408,1359,1360],{"class":410,"line":411},[408,1361,1362],{"class":500},"// Before: manual\n",[408,1364,1365,1367,1369,1372,1374,1377,1379,1382,1384,1387,1389,1392,1395,1397,1400,1403],{"class":410,"line":450},[408,1366,1288],{"class":418},[408,1368,456],{"class":422},[408,1370,1371],{"class":418}," (_",[408,1373,911],{"class":422},[408,1375,1376],{"class":418}," __",[408,1378,911],{"class":422},[408,1380,1381],{"class":418}," ___) ",[408,1383,926],{"class":514},[408,1385,1386],{"class":418}," { client",[408,1388,468],{"class":422},[408,1390,1391],{"class":471},"invalidate",[408,1393,1394],{"class":418},"([",[408,1396,905],{"class":529},[408,1398,1399],{"class":418},"])",[408,1401,1402],{"class":422},";",[408,1404,1405],{"class":418}," }\n",[408,1407,1408],{"class":410,"line":481},[408,1409,494],{"emptyLinePlaceholder":493},[408,1411,1412],{"class":410,"line":490},[408,1413,1414],{"class":500},"// After: automatic\n",[408,1416,1417,1419,1421,1423,1425,1427],{"class":410,"line":497},[408,1418,1292],{"class":418},[408,1420,456],{"class":422},[408,1422,902],{"class":418},[408,1424,905],{"class":529},[408,1426,908],{"class":418},[408,1428,478],{"class":422},[1430,1431,1433],"h3",{"id":1432},"tag-based-invalidation","Tag-based invalidation",[348,1435,1436],{},"You can also invalidate queries by tag, completely decoupling from query-key structure:",[373,1438,1440],{"className":401,"code":1439,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  invalidatesTags: [QueryTag('post'), QueryTag('user', userId)],\n)\n",[360,1441,1442,1452,1488],{"__ignoreMap":379},[408,1443,1444,1446,1448,1450],{"class":410,"line":411},[408,1445,1302],{"class":418},[408,1447,456],{"class":422},[408,1449,889],{"class":426},[408,1451,892],{"class":418},[408,1453,1454,1457,1459,1461,1464,1466,1469,1471,1473,1476,1478,1481,1483,1486],{"class":410,"line":450},[408,1455,1456],{"class":418},"  invalidatesTags",[408,1458,456],{"class":422},[408,1460,1327],{"class":418},[408,1462,1463],{"class":426},"QueryTag",[408,1465,526],{"class":418},[408,1467,1468],{"class":529},"'post'",[408,1470,484],{"class":418},[408,1472,911],{"class":422},[408,1474,1475],{"class":426}," QueryTag",[408,1477,526],{"class":418},[408,1479,1480],{"class":529},"'user'",[408,1482,911],{"class":422},[408,1484,1485],{"class":418}," userId)]",[408,1487,478],{"class":422},[408,1489,1490],{"class":410,"line":481},[408,1491,1342],{"class":418},[348,1493,1494,1495,1498,1499,1502,1503,1505,1506,1509,1510,468],{},"Every query whose ",[360,1496,1497],{},"QoraOptions.providesTags"," includes a matching tag is automatically refetched. Wildcard matching: ",[360,1500,1501],{},"QueryTag('post')"," refetches all queries providing any ",[360,1504,1468],{}," tag regardless of id. Specific matching: ",[360,1507,1508],{},"QueryTag('post', '123')"," refetches only queries providing exactly ",[360,1511,1512],{},"'post':'123'",[373,1514,1516],{"className":401,"code":1515,"language":404,"meta":379,"style":379},"// Before: key-based\ninvalidates: [['posts']],\n\n// After: tag-based\ninvalidatesTags: [QueryTag('post')],\n",[360,1517,1518,1523,1537,1541,1546],{"__ignoreMap":379},[408,1519,1520],{"class":410,"line":411},[408,1521,1522],{"class":500},"// Before: key-based\n",[408,1524,1525,1527,1529,1531,1533,1535],{"class":410,"line":450},[408,1526,1292],{"class":418},[408,1528,456],{"class":422},[408,1530,902],{"class":418},[408,1532,905],{"class":529},[408,1534,908],{"class":418},[408,1536,478],{"class":422},[408,1538,1539],{"class":410,"line":481},[408,1540,494],{"emptyLinePlaceholder":493},[408,1542,1543],{"class":410,"line":490},[408,1544,1545],{"class":500},"// After: tag-based\n",[408,1547,1548,1551,1553,1555,1557,1559,1561,1564],{"class":410,"line":497},[408,1549,1550],{"class":418},"invalidatesTags",[408,1552,456],{"class":422},[408,1554,1327],{"class":418},[408,1556,1463],{"class":426},[408,1558,526],{"class":418},[408,1560,1468],{"class":529},[408,1562,1563],{"class":418},")]",[408,1565,478],{"class":422},[348,1567,1568,1569,436,1571,1574,1575,1577,1578,1580,1581,1584,1585,1587,1588,1590],{},"Works with ",[360,1570,113],{},[360,1572,1573],{},"useMutation",", and raw ",[360,1576,362],{}," as long as a ",[360,1579,202],{}," or ",[360,1582,1583],{},"invalidateQuery"," callback is wired. Both ",[360,1586,1292],{}," and ",[360,1589,1550],{}," can be used together; tag invalidation runs after key-based invalidation.",[365,1592],{},[368,1594,148],{"id":1595},"optimistic-updates",[348,1597,1598],{},"Optimistic updates apply a change to the local cache immediately: before the server confirms it. If the server rejects the change, the previous data is restored.",[348,1600,1601],{},"The pattern has three steps:",[1603,1604,1605,1615,1629],"ol",{},[1606,1607,1608,1612,1613],"li",{},[352,1609,1610],{},[360,1611,1264],{},": snapshot the current cache data, apply the optimistic change, return the snapshot as ",[360,1614,1268],{},[1606,1616,1617,1622,1623,1625,1626],{},[352,1618,1619],{},[360,1620,1621],{},"onError",": use the snapshot (",[360,1624,1268],{},") to roll back via ",[360,1627,1628],{},"client.restoreQueryData()",[1606,1630,1631,1635],{},[352,1632,1633],{},[360,1634,1288],{},": invalidate the query to pull the confirmed server data",[373,1637,1639],{"className":401,"code":1638,"filename":403,"language":404,"meta":379,"style":379},"final controller = MutationController\u003CPost, String, List\u003CPost>?>(\n  // TContext = List\u003CPost>?: the snapshot we'll use for rollback\n  mutator: (title) => api.createPost(title),\n  options: MutationOptions(\n    invalidates: [['posts']], // 4️⃣ Confirm: replace optimistic data with real server data\n    onMutate: (title) async {\n      // 1️⃣ Snapshot\n      final previous = client.getQueryData\u003CList\u003CPost>>(['posts']);\n\n      // 2️⃣ Optimistic update: UI reflects change immediately\n      client.setQueryData\u003CList\u003CPost>>(\n        ['posts'],\n        [...?previous, Post.optimistic(title)],\n      );\n\n      return previous; // Becomes TContext\n    },\n    onError: (error, title, previous) async {\n      // 3️⃣ Rollback: restore the snapshot on failure\n      client.restoreQueryData(['posts'], previous);\n    },\n  ),\n);\n\nawait controller.mutate('New Post');\n",[360,1640,1641,1671,1676,1696,1706,1723,1735,1740,1775,1779,1784,1805,1816,1841,1848,1852,1865,1871,1892,1897,1919,1925,1931,1937,1941],{"__ignoreMap":379},[408,1642,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661,1664,1666,1668],{"class":410,"line":411},[408,1644,415],{"class":414},[408,1646,419],{"class":418},[408,1648,423],{"class":422},[408,1650,427],{"class":426},[408,1652,430],{"class":418},[408,1654,433],{"class":426},[408,1656,436],{"class":418},[408,1658,439],{"class":426},[408,1660,436],{"class":418},[408,1662,1663],{"class":426},"List",[408,1665,430],{"class":418},[408,1667,433],{"class":426},[408,1669,1670],{"class":418},">?>(\n",[408,1672,1673],{"class":410,"line":450},[408,1674,1675],{"class":500},"  // TContext = List\u003CPost>?: the snapshot we'll use for rollback\n",[408,1677,1678,1680,1682,1684,1686,1688,1690,1692,1694],{"class":410,"line":481},[408,1679,453],{"class":418},[408,1681,456],{"class":422},[408,1683,459],{"class":418},[408,1685,462],{"class":422},[408,1687,465],{"class":418},[408,1689,468],{"class":422},[408,1691,472],{"class":471},[408,1693,475],{"class":418},[408,1695,478],{"class":422},[408,1697,1698,1700,1702,1704],{"class":410,"line":490},[408,1699,884],{"class":418},[408,1701,456],{"class":422},[408,1703,889],{"class":426},[408,1705,892],{"class":418},[408,1707,1708,1710,1712,1714,1716,1718,1720],{"class":410,"line":497},[408,1709,897],{"class":418},[408,1711,456],{"class":422},[408,1713,902],{"class":418},[408,1715,905],{"class":529},[408,1717,908],{"class":418},[408,1719,911],{"class":422},[408,1721,1722],{"class":500}," // 4️⃣ Confirm: replace optimistic data with real server data\n",[408,1724,1725,1727,1729,1731,1733],{"class":410,"line":504},[408,1726,919],{"class":418},[408,1728,456],{"class":422},[408,1730,459],{"class":418},[408,1732,926],{"class":514},[408,1734,929],{"class":418},[408,1736,1737],{"class":410,"line":537},[408,1738,1739],{"class":500},"      // 1️⃣ Snapshot\n",[408,1741,1742,1745,1748,1750,1753,1755,1758,1760,1762,1764,1766,1769,1771,1773],{"class":410,"line":543},[408,1743,1744],{"class":414},"      final",[408,1746,1747],{"class":418}," previous ",[408,1749,423],{"class":422},[408,1751,1752],{"class":418}," client",[408,1754,468],{"class":422},[408,1756,1757],{"class":471},"getQueryData",[408,1759,430],{"class":418},[408,1761,1663],{"class":426},[408,1763,430],{"class":418},[408,1765,433],{"class":426},[408,1767,1768],{"class":418},">>([",[408,1770,905],{"class":529},[408,1772,1399],{"class":418},[408,1774,487],{"class":422},[408,1776,1777],{"class":410,"line":548},[408,1778,494],{"emptyLinePlaceholder":493},[408,1780,1781],{"class":410,"line":554},[408,1782,1783],{"class":500},"      // 2️⃣ Optimistic update: UI reflects change immediately\n",[408,1785,1786,1789,1791,1794,1796,1798,1800,1802],{"class":410,"line":573},[408,1787,1788],{"class":418},"      client",[408,1790,468],{"class":422},[408,1792,1793],{"class":471},"setQueryData",[408,1795,430],{"class":418},[408,1797,1663],{"class":426},[408,1799,430],{"class":418},[408,1801,433],{"class":426},[408,1803,1804],{"class":418},">>(\n",[408,1806,1807,1810,1812,1814],{"class":410,"line":582},[408,1808,1809],{"class":418},"        [",[408,1811,905],{"class":529},[408,1813,1322],{"class":418},[408,1815,478],{"class":422},[408,1817,1818,1820,1823,1826,1828,1831,1833,1836,1839],{"class":410,"line":597},[408,1819,1809],{"class":418},[408,1821,1822],{"class":422},"...?",[408,1824,1825],{"class":418},"previous",[408,1827,911],{"class":422},[408,1829,1830],{"class":426}," Post",[408,1832,468],{"class":422},[408,1834,1835],{"class":471},"optimistic",[408,1837,1838],{"class":418},"(title)]",[408,1840,478],{"class":422},[408,1842,1843,1846],{"class":410,"line":612},[408,1844,1845],{"class":418},"      )",[408,1847,487],{"class":422},[408,1849,1850],{"class":410,"line":631},[408,1851,494],{"emptyLinePlaceholder":493},[408,1853,1854,1857,1860,1862],{"class":410,"line":654},[408,1855,1856],{"class":514},"      return",[408,1858,1859],{"class":418}," previous",[408,1861,1402],{"class":422},[408,1863,1864],{"class":500}," // Becomes TContext\n",[408,1866,1867,1869],{"class":410,"line":673},[408,1868,959],{"class":418},[408,1870,478],{"class":422},[408,1872,1873,1875,1877,1879,1881,1883,1885,1888,1890],{"class":410,"line":704},[408,1874,1022],{"class":418},[408,1876,456],{"class":422},[408,1878,1027],{"class":418},[408,1880,911],{"class":422},[408,1882,976],{"class":418},[408,1884,911],{"class":422},[408,1886,1887],{"class":418}," previous) ",[408,1889,926],{"class":514},[408,1891,929],{"class":418},[408,1893,1894],{"class":410,"line":723},[408,1895,1896],{"class":500},"      // 3️⃣ Rollback: restore the snapshot on failure\n",[408,1898,1899,1901,1903,1906,1908,1910,1912,1914,1917],{"class":410,"line":744},[408,1900,1788],{"class":418},[408,1902,468],{"class":422},[408,1904,1905],{"class":471},"restoreQueryData",[408,1907,1394],{"class":418},[408,1909,905],{"class":529},[408,1911,1322],{"class":418},[408,1913,911],{"class":422},[408,1915,1916],{"class":418}," previous)",[408,1918,487],{"class":422},[408,1920,1921,1923],{"class":410,"line":750},[408,1922,959],{"class":418},[408,1924,478],{"class":422},[408,1926,1927,1929],{"class":410,"line":758},[408,1928,1151],{"class":418},[408,1930,478],{"class":422},[408,1932,1933,1935],{"class":410,"line":763},[408,1934,484],{"class":418},[408,1936,487],{"class":422},[408,1938,1939],{"class":410,"line":769},[408,1940,494],{"emptyLinePlaceholder":493},[408,1942,1943,1946,1948,1950,1952,1954,1957,1959],{"class":410,"line":783},[408,1944,1945],{"class":514},"await",[408,1947,518],{"class":418},[408,1949,468],{"class":422},[408,1951,523],{"class":471},[408,1953,526],{"class":418},[408,1955,1956],{"class":529},"'New Post'",[408,1958,484],{"class":418},[408,1960,487],{"class":422},[1962,1963,1964,1967,1968,1970],"tip",{},[360,1965,1966],{},"client.restoreQueryData(key, null)"," removes the query from the cache entirely: useful when the snapshot was ",[360,1969,817],{}," (the list didn't exist yet).",[365,1972],{},[368,1974,1976,1977,1979],{"id":1975},"handling-onmutate-failure","Handling ",[360,1978,1264],{}," Failure",[348,1981,1982,1983,1985,1986,1989,1990,468],{},"If ",[360,1984,1264],{}," throws (e.g. a pre-flight validation fails), the mutator is ",[352,1987,1988],{},"not called",". The controller transitions directly to ",[360,1991,813],{},[373,1993,1995],{"className":401,"code":1994,"filename":403,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  onMutate: (title) async {\n    if (title.isEmpty) throw ArgumentError('Title cannot be empty');\n    // Mutator will never run if this throws\n    return null;\n  },\n),\n",[360,1996,1997,2007,2020,2048,2053,2061,2068],{"__ignoreMap":379},[408,1998,1999,2001,2003,2005],{"class":410,"line":411},[408,2000,1302],{"class":418},[408,2002,456],{"class":422},[408,2004,889],{"class":426},[408,2006,892],{"class":418},[408,2008,2009,2012,2014,2016,2018],{"class":410,"line":450},[408,2010,2011],{"class":418},"  onMutate",[408,2013,456],{"class":422},[408,2015,459],{"class":418},[408,2017,926],{"class":514},[408,2019,929],{"class":418},[408,2021,2022,2025,2028,2030,2033,2036,2039,2041,2044,2046],{"class":410,"line":481},[408,2023,2024],{"class":514},"    if",[408,2026,2027],{"class":418}," (title",[408,2029,468],{"class":422},[408,2031,2032],{"class":418},"isEmpty) ",[408,2034,2035],{"class":514},"throw",[408,2037,2038],{"class":426}," ArgumentError",[408,2040,526],{"class":418},[408,2042,2043],{"class":529},"'Title cannot be empty'",[408,2045,484],{"class":418},[408,2047,487],{"class":422},[408,2049,2050],{"class":410,"line":490},[408,2051,2052],{"class":500},"    // Mutator will never run if this throws\n",[408,2054,2055,2058],{"class":410,"line":497},[408,2056,2057],{"class":514},"    return",[408,2059,2060],{"class":422}," null;\n",[408,2062,2063,2066],{"class":410,"line":504},[408,2064,2065],{"class":418},"  }",[408,2067,478],{"class":422},[408,2069,2070,2072],{"class":410,"line":537},[408,2071,484],{"class":418},[408,2073,478],{"class":422},[348,2075,2076],{},"This is useful for client-side validation that should block the network call entirely.",[365,2078],{},[368,2080,2082],{"id":2081},"retry","Retry",[348,2084,2085],{},"By default mutations do not retry (unlike queries, retrying a write can have side effects). Enable retry explicitly:",[373,2087,2089],{"className":401,"code":2088,"filename":403,"language":404,"meta":379,"style":379},"options: const MutationOptions(\n  retryCount: 2,                       // 1 initial + 2 retries = 3 total attempts\n  retryDelay: Duration(seconds: 1),    // Exponential backoff: 1s, 2s\n),\n",[360,2090,2091,2104,2120,2145],{"__ignoreMap":379},[408,2092,2093,2095,2097,2100,2102],{"class":410,"line":411},[408,2094,1302],{"class":418},[408,2096,456],{"class":422},[408,2098,2099],{"class":414}," const",[408,2101,889],{"class":426},[408,2103,892],{"class":418},[408,2105,2106,2109,2111,2115,2117],{"class":410,"line":450},[408,2107,2108],{"class":418},"  retryCount",[408,2110,456],{"class":422},[408,2112,2114],{"class":2113},"sbssI"," 2",[408,2116,911],{"class":422},[408,2118,2119],{"class":500},"                       // 1 initial + 2 retries = 3 total attempts\n",[408,2121,2122,2125,2127,2130,2133,2135,2138,2140,2142],{"class":410,"line":481},[408,2123,2124],{"class":418},"  retryDelay",[408,2126,456],{"class":422},[408,2128,2129],{"class":426}," Duration",[408,2131,2132],{"class":418},"(seconds",[408,2134,456],{"class":422},[408,2136,2137],{"class":2113}," 1",[408,2139,484],{"class":418},[408,2141,911],{"class":422},[408,2143,2144],{"class":500},"    // Exponential backoff: 1s, 2s\n",[408,2146,2147,2149],{"class":410,"line":490},[408,2148,484],{"class":418},[408,2150,478],{"class":422},[348,2152,2153,2154,2156],{},"Retry only applies to the mutator. If ",[360,2155,1264],{}," throws, no retry occurs.",[365,2158],{},[368,2160,2162],{"id":2161},"standalone-mode","Standalone Mode",[348,2164,2165,2167,2168,2170,2171,2174],{},[360,2166,362],{}," works without any ",[360,2169,202],{},". Pass ",[360,2172,2173],{},"tracker: null"," (the default) to operate in standalone mode with no global observability:",[373,2176,2179],{"className":401,"code":2177,"filename":2178,"language":404,"meta":379,"style":379},"// No client required: mutations work anywhere\nfinal controller = MutationController\u003COrder, Cart, void>(\n  mutator: (cart) => paymentApi.checkout(cart),\n);\n","checkout_service.dart",[360,2180,2181,2186,2212,2236],{"__ignoreMap":379},[408,2182,2183],{"class":410,"line":411},[408,2184,2185],{"class":500},"// No client required: mutations work anywhere\n",[408,2187,2188,2190,2192,2194,2196,2198,2201,2203,2206,2208,2210],{"class":410,"line":450},[408,2189,415],{"class":414},[408,2191,419],{"class":418},[408,2193,423],{"class":422},[408,2195,427],{"class":426},[408,2197,430],{"class":418},[408,2199,2200],{"class":426},"Order",[408,2202,436],{"class":418},[408,2204,2205],{"class":426},"Cart",[408,2207,436],{"class":418},[408,2209,444],{"class":414},[408,2211,447],{"class":418},[408,2213,2214,2216,2218,2221,2223,2226,2228,2231,2234],{"class":410,"line":481},[408,2215,453],{"class":418},[408,2217,456],{"class":422},[408,2219,2220],{"class":418}," (cart) ",[408,2222,462],{"class":422},[408,2224,2225],{"class":418}," paymentApi",[408,2227,468],{"class":422},[408,2229,2230],{"class":471},"checkout",[408,2232,2233],{"class":418},"(cart)",[408,2235,478],{"class":422},[408,2237,2238,2240],{"class":410,"line":490},[408,2239,484],{"class":418},[408,2241,487],{"class":422},[365,2243],{},[368,2245,2247],{"id":2246},"devtools-observability","DevTools Observability",[348,2249,2250,2251,2253,2254,2257,2258,1587,2261,468],{},"Wire a controller into ",[360,2252,202],{}," by passing ",[360,2255,2256],{},"tracker: client",". The client then exposes all mutation activity via ",[360,2259,2260],{},"mutationEvents",[360,2262,2263],{},"activeMutations",[373,2265,2267],{"className":401,"code":2266,"filename":403,"language":404,"meta":379,"style":379},"final controller = MutationController\u003CPost, String, void>(\n  mutator: (title) => api.createPost(title),\n  tracker: client,\n\n  // Optional: label this controller for DevTools filtering\n  metadata: {'category': 'content', 'resource': 'post'},\n);\n\n// Listen to all mutation activity across all tracked controllers\nclient.mutationEvents.listen((event) {\n  if (event.isError) {\n    logger.error('[${event.mutatorId}] Failed', event.error);\n  }\n});\n\n// Snapshot of currently running mutations (only Pending entries)\nfinal running = client.activeMutations;\nprint('${running.length} mutation(s) in flight');\n",[360,2268,2269,2293,2313,2324,2328,2333,2364,2370,2374,2379,2395,2408,2449,2453,2459,2463,2468,2485],{"__ignoreMap":379},[408,2270,2271,2273,2275,2277,2279,2281,2283,2285,2287,2289,2291],{"class":410,"line":411},[408,2272,415],{"class":414},[408,2274,419],{"class":418},[408,2276,423],{"class":422},[408,2278,427],{"class":426},[408,2280,430],{"class":418},[408,2282,433],{"class":426},[408,2284,436],{"class":418},[408,2286,439],{"class":426},[408,2288,436],{"class":418},[408,2290,444],{"class":414},[408,2292,447],{"class":418},[408,2294,2295,2297,2299,2301,2303,2305,2307,2309,2311],{"class":410,"line":450},[408,2296,453],{"class":418},[408,2298,456],{"class":422},[408,2300,459],{"class":418},[408,2302,462],{"class":422},[408,2304,465],{"class":418},[408,2306,468],{"class":422},[408,2308,472],{"class":471},[408,2310,475],{"class":418},[408,2312,478],{"class":422},[408,2314,2315,2318,2320,2322],{"class":410,"line":481},[408,2316,2317],{"class":418},"  tracker",[408,2319,456],{"class":422},[408,2321,1752],{"class":418},[408,2323,478],{"class":422},[408,2325,2326],{"class":410,"line":490},[408,2327,494],{"emptyLinePlaceholder":493},[408,2329,2330],{"class":410,"line":497},[408,2331,2332],{"class":500},"  // Optional: label this controller for DevTools filtering\n",[408,2334,2335,2338,2340,2342,2345,2347,2350,2352,2355,2357,2360,2362],{"class":410,"line":504},[408,2336,2337],{"class":418},"  metadata",[408,2339,456],{"class":422},[408,2341,1122],{"class":418},[408,2343,2344],{"class":529},"'category'",[408,2346,456],{"class":422},[408,2348,2349],{"class":529}," 'content'",[408,2351,911],{"class":422},[408,2353,2354],{"class":529}," 'resource'",[408,2356,456],{"class":422},[408,2358,2359],{"class":529}," 'post'",[408,2361,694],{"class":418},[408,2363,478],{"class":422},[408,2365,2366,2368],{"class":410,"line":537},[408,2367,484],{"class":418},[408,2369,487],{"class":422},[408,2371,2372],{"class":410,"line":543},[408,2373,494],{"emptyLinePlaceholder":493},[408,2375,2376],{"class":410,"line":548},[408,2377,2378],{"class":500},"// Listen to all mutation activity across all tracked controllers\n",[408,2380,2381,2384,2386,2388,2390,2392],{"class":410,"line":554},[408,2382,2383],{"class":418},"client",[408,2385,468],{"class":422},[408,2387,2260],{"class":418},[408,2389,468],{"class":422},[408,2391,567],{"class":471},[408,2393,2394],{"class":418},"((event) {\n",[408,2396,2397,2400,2403,2405],{"class":410,"line":573},[408,2398,2399],{"class":514},"  if",[408,2401,2402],{"class":418}," (event",[408,2404,468],{"class":422},[408,2406,2407],{"class":418},"isError) {\n",[408,2409,2410,2413,2415,2417,2419,2422,2424,2427,2429,2432,2434,2437,2439,2442,2444,2447],{"class":410,"line":582},[408,2411,2412],{"class":418},"    logger",[408,2414,468],{"class":422},[408,2416,735],{"class":471},[408,2418,526],{"class":418},[408,2420,2421],{"class":529},"'[",[408,2423,683],{"class":418},[408,2425,2426],{"class":644},"event",[408,2428,468],{"class":418},[408,2430,2431],{"class":644},"mutatorId",[408,2433,694],{"class":418},[408,2435,2436],{"class":529},"] Failed'",[408,2438,911],{"class":422},[408,2440,2441],{"class":418}," event",[408,2443,468],{"class":422},[408,2445,2446],{"class":418},"error)",[408,2448,487],{"class":422},[408,2450,2451],{"class":410,"line":597},[408,2452,747],{"class":418},[408,2454,2455,2457],{"class":410,"line":612},[408,2456,753],{"class":418},[408,2458,487],{"class":422},[408,2460,2461],{"class":410,"line":631},[408,2462,494],{"emptyLinePlaceholder":493},[408,2464,2465],{"class":410,"line":654},[408,2466,2467],{"class":500},"// Snapshot of currently running mutations (only Pending entries)\n",[408,2469,2470,2472,2475,2477,2479,2481,2483],{"class":410,"line":673},[408,2471,415],{"class":414},[408,2473,2474],{"class":418}," running ",[408,2476,423],{"class":422},[408,2478,1752],{"class":418},[408,2480,468],{"class":422},[408,2482,2263],{"class":418},[408,2484,487],{"class":422},[408,2486,2487,2490,2492,2494,2496,2499,2501,2504,2506,2509,2511],{"class":410,"line":704},[408,2488,2489],{"class":471},"print",[408,2491,526],{"class":418},[408,2493,697],{"class":529},[408,2495,683],{"class":418},[408,2497,2498],{"class":644},"running",[408,2500,468],{"class":418},[408,2502,2503],{"class":644},"length",[408,2505,694],{"class":418},[408,2507,2508],{"class":529}," mutation(s) in flight'",[408,2510,484],{"class":418},[408,2512,487],{"class":422},[1962,2514,2515,2517,2518,2521],{},[360,2516,2263],{}," only contains ",[360,2519,2520],{},"MutationPending"," entries: finished mutations (Success or Failure) are auto-purged. This prevents memory accumulation and makes the map a reliable \"currently in-flight\" indicator.",[348,2523,2524,2525,2527,2528,2531,2532,2535],{},"When using ",[360,2526,113],{}," in Flutter, ",[360,2529,2530],{},"tracker"," is set to ",[360,2533,2534],{},"QoraScope.maybeOf(context)"," automatically: no manual wiring needed.",[365,2537],{},[368,2539,2541],{"id":2540},"multi-query-optimistic-updates","Multi-Query Optimistic Updates",[348,2543,2544,2545,2547,2548,2550],{},"A single mutation can touch multiple queries. Each ",[360,2546,1793],{}," call triggers a reactive update in any ",[360,2549,108],{}," subscribed to that key:",[373,2552,2554],{"className":401,"code":2553,"filename":403,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  onMutate: (postId) async {\n    // Snapshot both queries\n    final posts = client.getQueryData\u003CList\u003CPost>>(['posts']);\n    final user = client.getQueryData\u003CUser>(['users', currentUserId]);\n\n    // Update both optimistically\n    client.setQueryData\u003CList\u003CPost>>(\n      ['posts'],\n      posts?.where((p) => p.id != postId).toList(),\n    );\n    client.setQueryData\u003CUser>(\n      ['users', currentUserId],\n      user?.copyWith(postCount: (user.postCount ?? 1) - 1),\n    );\n\n    return (posts: posts, user: user); // TContext is a record\n  },\n  onError: (error, postId, snapshots) async {\n    // Roll back both\n    client.restoreQueryData(['posts'], snapshots?.posts);\n    client.restoreQueryData(['users', currentUserId], snapshots?.user);\n  },\n),\n",[360,2555,2556,2566,2579,2584,2616,2648,2652,2657,2676,2687,2726,2733,2747,2760,2800,2806,2810,2837,2843,2866,2871,2897,2924,2930],{"__ignoreMap":379},[408,2557,2558,2560,2562,2564],{"class":410,"line":411},[408,2559,1302],{"class":418},[408,2561,456],{"class":422},[408,2563,889],{"class":426},[408,2565,892],{"class":418},[408,2567,2568,2570,2572,2575,2577],{"class":410,"line":450},[408,2569,2011],{"class":418},[408,2571,456],{"class":422},[408,2573,2574],{"class":418}," (postId) ",[408,2576,926],{"class":514},[408,2578,929],{"class":418},[408,2580,2581],{"class":410,"line":481},[408,2582,2583],{"class":500},"    // Snapshot both queries\n",[408,2585,2586,2589,2592,2594,2596,2598,2600,2602,2604,2606,2608,2610,2612,2614],{"class":410,"line":490},[408,2587,2588],{"class":414},"    final",[408,2590,2591],{"class":418}," posts ",[408,2593,423],{"class":422},[408,2595,1752],{"class":418},[408,2597,468],{"class":422},[408,2599,1757],{"class":471},[408,2601,430],{"class":418},[408,2603,1663],{"class":426},[408,2605,430],{"class":418},[408,2607,433],{"class":426},[408,2609,1768],{"class":418},[408,2611,905],{"class":529},[408,2613,1399],{"class":418},[408,2615,487],{"class":422},[408,2617,2618,2620,2623,2625,2627,2629,2631,2633,2636,2639,2641,2643,2646],{"class":410,"line":497},[408,2619,2588],{"class":414},[408,2621,2622],{"class":418}," user ",[408,2624,423],{"class":422},[408,2626,1752],{"class":418},[408,2628,468],{"class":422},[408,2630,1757],{"class":471},[408,2632,430],{"class":418},[408,2634,2635],{"class":426},"User",[408,2637,2638],{"class":418},">([",[408,2640,1330],{"class":529},[408,2642,911],{"class":422},[408,2644,2645],{"class":418}," currentUserId])",[408,2647,487],{"class":422},[408,2649,2650],{"class":410,"line":504},[408,2651,494],{"emptyLinePlaceholder":493},[408,2653,2654],{"class":410,"line":537},[408,2655,2656],{"class":500},"    // Update both optimistically\n",[408,2658,2659,2662,2664,2666,2668,2670,2672,2674],{"class":410,"line":543},[408,2660,2661],{"class":418},"    client",[408,2663,468],{"class":422},[408,2665,1793],{"class":471},[408,2667,430],{"class":418},[408,2669,1663],{"class":426},[408,2671,430],{"class":418},[408,2673,433],{"class":426},[408,2675,1804],{"class":418},[408,2677,2678,2681,2683,2685],{"class":410,"line":548},[408,2679,2680],{"class":418},"      [",[408,2682,905],{"class":529},[408,2684,1322],{"class":418},[408,2686,478],{"class":422},[408,2688,2689,2692,2695,2698,2701,2703,2706,2708,2711,2714,2717,2719,2722,2724],{"class":410,"line":554},[408,2690,2691],{"class":418},"      posts",[408,2693,2694],{"class":422},"?.",[408,2696,2697],{"class":471},"where",[408,2699,2700],{"class":418},"((p) ",[408,2702,462],{"class":422},[408,2704,2705],{"class":418}," p",[408,2707,468],{"class":422},[408,2709,2710],{"class":418},"id ",[408,2712,2713],{"class":422},"!=",[408,2715,2716],{"class":418}," postId)",[408,2718,468],{"class":422},[408,2720,2721],{"class":471},"toList",[408,2723,591],{"class":418},[408,2725,478],{"class":422},[408,2727,2728,2731],{"class":410,"line":573},[408,2729,2730],{"class":418},"    )",[408,2732,487],{"class":422},[408,2734,2735,2737,2739,2741,2743,2745],{"class":410,"line":582},[408,2736,2661],{"class":418},[408,2738,468],{"class":422},[408,2740,1793],{"class":471},[408,2742,430],{"class":418},[408,2744,2635],{"class":426},[408,2746,447],{"class":418},[408,2748,2749,2751,2753,2755,2758],{"class":410,"line":597},[408,2750,2680],{"class":418},[408,2752,1330],{"class":529},[408,2754,911],{"class":422},[408,2756,2757],{"class":418}," currentUserId]",[408,2759,478],{"class":422},[408,2761,2762,2765,2767,2770,2773,2775,2778,2780,2783,2786,2788,2791,2794,2796,2798],{"class":410,"line":612},[408,2763,2764],{"class":418},"      user",[408,2766,2694],{"class":422},[408,2768,2769],{"class":471},"copyWith",[408,2771,2772],{"class":418},"(postCount",[408,2774,456],{"class":422},[408,2776,2777],{"class":418}," (user",[408,2779,468],{"class":422},[408,2781,2782],{"class":418},"postCount ",[408,2784,2785],{"class":422},"??",[408,2787,2137],{"class":2113},[408,2789,2790],{"class":418},") ",[408,2792,2793],{"class":422},"-",[408,2795,2137],{"class":2113},[408,2797,484],{"class":418},[408,2799,478],{"class":422},[408,2801,2802,2804],{"class":410,"line":631},[408,2803,2730],{"class":418},[408,2805,487],{"class":422},[408,2807,2808],{"class":410,"line":654},[408,2809,494],{"emptyLinePlaceholder":493},[408,2811,2812,2814,2817,2819,2822,2824,2827,2829,2832,2834],{"class":410,"line":673},[408,2813,2057],{"class":514},[408,2815,2816],{"class":418}," (posts",[408,2818,456],{"class":422},[408,2820,2821],{"class":418}," posts",[408,2823,911],{"class":422},[408,2825,2826],{"class":418}," user",[408,2828,456],{"class":422},[408,2830,2831],{"class":418}," user)",[408,2833,1402],{"class":422},[408,2835,2836],{"class":500}," // TContext is a record\n",[408,2838,2839,2841],{"class":410,"line":704},[408,2840,2065],{"class":418},[408,2842,478],{"class":422},[408,2844,2845,2848,2850,2852,2854,2857,2859,2862,2864],{"class":410,"line":723},[408,2846,2847],{"class":418},"  onError",[408,2849,456],{"class":422},[408,2851,1027],{"class":418},[408,2853,911],{"class":422},[408,2855,2856],{"class":418}," postId",[408,2858,911],{"class":422},[408,2860,2861],{"class":418}," snapshots) ",[408,2863,926],{"class":514},[408,2865,929],{"class":418},[408,2867,2868],{"class":410,"line":744},[408,2869,2870],{"class":500},"    // Roll back both\n",[408,2872,2873,2875,2877,2879,2881,2883,2885,2887,2890,2892,2895],{"class":410,"line":750},[408,2874,2661],{"class":418},[408,2876,468],{"class":422},[408,2878,1905],{"class":471},[408,2880,1394],{"class":418},[408,2882,905],{"class":529},[408,2884,1322],{"class":418},[408,2886,911],{"class":422},[408,2888,2889],{"class":418}," snapshots",[408,2891,2694],{"class":422},[408,2893,2894],{"class":418},"posts)",[408,2896,487],{"class":422},[408,2898,2899,2901,2903,2905,2907,2909,2911,2913,2915,2917,2919,2922],{"class":410,"line":758},[408,2900,2661],{"class":418},[408,2902,468],{"class":422},[408,2904,1905],{"class":471},[408,2906,1394],{"class":418},[408,2908,1330],{"class":529},[408,2910,911],{"class":422},[408,2912,2757],{"class":418},[408,2914,911],{"class":422},[408,2916,2889],{"class":418},[408,2918,2694],{"class":422},[408,2920,2921],{"class":418},"user)",[408,2923,487],{"class":422},[408,2925,2926,2928],{"class":410,"line":763},[408,2927,2065],{"class":418},[408,2929,478],{"class":422},[408,2931,2932,2934],{"class":410,"line":769},[408,2933,484],{"class":418},[408,2935,478],{"class":422},[365,2937],{},[368,2939,2941],{"id":2940},"next-steps","Next Steps",[2943,2944,2945,2953,2959],"ul",{},[1606,2946,2947,2952],{},[2948,2949,2951],"a",{"href":2950},"../flutter-integration/qora-mutation-builder","MutationBuilder",": Bind mutations to Flutter UI",[1606,2954,2955,2958],{},[2948,2956,148],{"href":2957},"./optimistic-updates",": Deep dive into rollback patterns",[1606,2960,2961,2965],{},[2948,2962,2964],{"href":2963},"../api-reference/qora-mutation","Mutation API Reference",": Full API documentation",[2967,2968,2969],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":379,"searchDepth":450,"depth":450,"links":2971},[2972,2973,2974,2975,2978,2979,2981,2982,2983,2984,2985],{"id":370,"depth":450,"text":371},{"id":397,"depth":450,"text":398},{"id":823,"depth":450,"text":824},{"id":1277,"depth":450,"text":1278,"children":2976},[2977],{"id":1432,"depth":481,"text":1433},{"id":1595,"depth":450,"text":148},{"id":1975,"depth":450,"text":2980},"Handling onMutate Failure",{"id":2081,"depth":450,"text":2082},{"id":2161,"depth":450,"text":2162},{"id":2246,"depth":450,"text":2247},{"id":2540,"depth":450,"text":2541},{"id":2940,"depth":450,"text":2941},"Perform write operations (POST, PUT, DELETE) with full lifecycle support: optimistic updates, automatic rollback, retry, and DevTools observability.","md",null,{},{"icon":85},{"title":2992,"description":2993},"Mutations - Qora","Perform write operations with MutationController. Full lifecycle support with optimistic updates, automatic rollback, retry, and DevTools observability.","o9AUJ_EJOf82VVOaMzMpA_KjJb8O6Ay89sCPQiFYYHM",[2996,2998],{"title":133,"path":134,"stem":135,"description":2997,"icon":136,"children":-1},"Patterns and conventions for building reliable Flutter apps with Qora: keys, query placement, mutation wiring, and performance.",{"title":148,"path":149,"stem":150,"description":2999,"icon":151,"children":-1},"Update the UI instantly while mutations are in flight, and roll back safely on failure: with no extra libraries.",1794040396278]