[{"data":1,"prerenderedAt":3000},["ShallowReactive",2],{"navigation_docs_fr":3,"-fr-recipes-mutations":342,"-fr-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},"Prise en main","i-lucide-rocket","/fr/getting-started","fr/01.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"Qu'est-ce que Qora ?","/fr/getting-started/what-is-qora","fr/01.getting-started/2.what-is-qora","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/fr/getting-started/installation","fr/01.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Démarrage rapide","/fr/getting-started/quick-start","fr/01.getting-started/4.quick-start",{"title":25,"path":26,"stem":27,"icon":28},"Comparaison","/fr/getting-started/comparison","fr/01.getting-started/5.comparison","i-lucide-scale",{"title":30,"path":31,"stem":32,"icon":33},"Venant de TanStack Query","/fr/getting-started/coming-from-tanstack-query","fr/01.getting-started/6.coming-from-tanstack-query","i-lucide-arrow-left-right",{"title":35,"path":36,"stem":37,"icon":38},"Migrer depuis d'Autres Librairies","/fr/getting-started/migrating-from-other-libraries","fr/01.getting-started/7.migrating-from-other-libraries","i-lucide-arrow-right-left",{"title":40,"path":41,"stem":42,"icon":43},"Assistants IA","/fr/getting-started/ai-assistants","fr/01.getting-started/8.ai-assistants","i-lucide-sparkles",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Concepts clés","i-lucide-book-open","/fr/core-concepts","fr/02.core-concepts",[51,56,61,66,71,76,81,86],{"title":52,"path":53,"stem":54,"icon":55},"Requêtes","/fr/core-concepts/queries","fr/02.core-concepts/1.queries","i-lucide-database",{"title":57,"path":58,"stem":59,"icon":60},"Clés de requête","/fr/core-concepts/query-keys","fr/02.core-concepts/2.query-keys","i-lucide-key-round",{"title":62,"path":63,"stem":64,"icon":65},"États des requêtes","/fr/core-concepts/query-states","fr/02.core-concepts/3.query-states","i-lucide-activity",{"title":67,"path":68,"stem":69,"icon":70},"Cache","/fr/core-concepts/caching","fr/02.core-concepts/4.caching","i-lucide-layers-3",{"title":72,"path":73,"stem":74,"icon":75},"Stale-While-Revalidate","/fr/core-concepts/stale-while-revalidate","fr/02.core-concepts/5.stale-while-revalidate","i-lucide-timer-reset",{"title":77,"path":78,"stem":79,"icon":80},"Déduplication","/fr/core-concepts/deduplication","fr/02.core-concepts/6.deduplication","i-lucide-copy-minus",{"title":82,"path":83,"stem":84,"icon":85},"Mutations et invalidation","/fr/core-concepts/mutations","fr/02.core-concepts/7.mutations","i-lucide-pencil-line",{"title":87,"path":88,"stem":89,"icon":90},"Hors-ligne et réseau","/fr/core-concepts/offline","fr/02.core-concepts/8.offline","i-lucide-wifi-off",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":44},"Usage avec Flutter","i-lucide-smartphone","/fr/flutter-integration","fr/03.flutter-integration",[97,102,107,112,117,122,127,132],{"title":98,"path":99,"stem":100,"icon":101},"Configuration","/fr/flutter-integration/setup","fr/03.flutter-integration/1.setup","i-lucide-wrench",{"title":103,"path":104,"stem":105,"icon":106},"QoraScope","/fr/flutter-integration/qora-scope","fr/03.flutter-integration/2.qora-scope","i-lucide-share-2",{"title":108,"path":109,"stem":110,"icon":111},"QoraBuilder","/fr/flutter-integration/qora-builder","fr/03.flutter-integration/3.qora-builder","i-lucide-blocks",{"title":113,"path":114,"stem":115,"icon":116},"QoraMutationBuilder","/fr/flutter-integration/qora-mutation-builder","fr/03.flutter-integration/4.qora-mutation-builder","i-lucide-pencil",{"title":118,"path":119,"stem":120,"icon":121},"InfiniteQueryBuilder","/fr/flutter-integration/infinite-query-builder","fr/03.flutter-integration/5.infinite-query-builder","i-lucide-infinity",{"title":123,"path":124,"stem":125,"icon":126},"Hooks (flutter_hooks)","/fr/flutter-integration/hooks","fr/03.flutter-integration/6.hooks","i-lucide-anchor",{"title":128,"path":129,"stem":130,"icon":131},"Widgets de statut réseau","/fr/flutter-integration/network-status","fr/03.flutter-integration/7.network-status","i-lucide-wifi",{"title":133,"path":134,"stem":135,"icon":136},"Bonnes pratiques","/fr/flutter-integration/best-practices","fr/03.flutter-integration/8.best-practices","i-lucide-badge-check",{"title":138,"icon":139,"path":140,"stem":141,"children":142,"page":44},"Guides Pratiques","i-lucide-chef-hat","/fr/recipes","fr/04.recipes",[143,147,152,157,162,166,171,176,181,186,191],{"title":144,"path":145,"stem":146,"icon":85},"Mutations","/fr/recipes/mutations","fr/04.recipes/02.mutations",{"title":148,"path":149,"stem":150,"icon":151},"Mises à jour optimistes","/fr/recipes/optimistic-updates","fr/04.recipes/03.optimistic-updates","i-lucide-zap",{"title":153,"path":154,"stem":155,"icon":156},"Persistance","/fr/recipes/persistence","fr/04.recipes/04.persistence","i-lucide-hard-drive",{"title":158,"path":159,"stem":160,"icon":161},"Réseau adaptatif","/fr/recipes/network-aware","fr/04.recipes/05.network-aware","i-lucide-signal",{"title":163,"path":164,"stem":165,"icon":121},"Requêtes infinies","/fr/recipes/infinite-queries","fr/04.recipes/06.infinite-queries",{"title":167,"path":168,"stem":169,"icon":170},"Requêtes dépendantes","/fr/recipes/dependent-queries","fr/04.recipes/07.dependent-queries","i-lucide-link-2",{"title":172,"path":173,"stem":174,"icon":175},"Annulation","/fr/recipes/cancel-token","fr/04.recipes/08.cancel-token","i-lucide-circle-slash",{"title":177,"path":178,"stem":179,"icon":180},"Hydratation SSR","/fr/recipes/ssr-hydration","fr/04.recipes/09.ssr-hydration","i-lucide-server",{"title":182,"path":183,"stem":184,"icon":185},"Gestion des erreurs","/fr/recipes/error-handling","fr/04.recipes/10.error-handling","i-lucide-shield-alert",{"title":187,"path":188,"stem":189,"icon":190},"Tests","/fr/recipes/testing","fr/04.recipes/11.testing","i-lucide-flask-conical",{"title":192,"path":193,"stem":194},"Prefetch au Niveau des Routes","/fr/recipes/prefetch","fr/04.recipes/12.prefetch",{"title":196,"icon":197,"path":198,"stem":199,"children":200,"page":44},"Référence de l'API","i-lucide-file-code","/fr/api-reference","fr/05.api-reference",[201,206,210,214,219,224,228,232],{"title":202,"path":203,"stem":204,"icon":205},"QoraClient","/fr/api-reference/qora-client","fr/05.api-reference/1.qora-client","i-lucide-cpu",{"title":207,"path":208,"stem":209,"icon":60},"QoraKey","/fr/api-reference/qora-key","fr/05.api-reference/2.qora-key",{"title":211,"path":212,"stem":213,"icon":65},"QoraState","/fr/api-reference/qora-state","fr/05.api-reference/3.qora-state",{"title":215,"path":216,"stem":217,"icon":218},"QoraOptions","/fr/api-reference/qora-options","fr/05.api-reference/4.qora-options","i-lucide-sliders-horizontal",{"title":220,"path":221,"stem":222,"icon":223},"QoraClientConfig","/fr/api-reference/qora-client-config","fr/05.api-reference/5.qora-client-config","i-lucide-settings-2",{"title":225,"path":226,"stem":227,"icon":85},"API Mutation","/fr/api-reference/qora-mutation","fr/05.api-reference/6.qora-mutation",{"title":229,"path":230,"stem":231,"icon":156},"PersistQoraClient","/fr/api-reference/persist-qora-client","fr/05.api-reference/7.persist-qora-client",{"title":233,"path":234,"stem":235,"icon":121},"Requête infinie","/fr/api-reference/infinite-query","fr/05.api-reference/8.infinite-query",{"title":237,"icon":238,"path":239,"stem":240,"children":241,"page":44},"Outils de debug","i-lucide-bug","/fr/devtools","fr/06.devtools",[242,247,252],{"title":243,"path":244,"stem":245,"icon":246},"Vue d'ensemble","/fr/devtools/overview","fr/06.devtools/1.overview","i-lucide-layout-dashboard",{"title":248,"path":249,"stem":250,"icon":251},"Overlay intégré","/fr/devtools/overlay","fr/06.devtools/2.overlay","i-lucide-layers",{"title":253,"path":254,"stem":255,"icon":256},"Sérialisation des données","/fr/devtools/data-display","fr/06.devtools/4.data-display","i-lucide-eye",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":44},"Intégrations tierces","i-lucide-puzzle","/fr/third-party","fr/07.third-party",[263,268,272,277,282,286],{"title":264,"path":265,"stem":266,"icon":267},"Avec Provider","/fr/third-party/with-provider","fr/07.third-party/1.with-provider","i-lucide-plug",{"title":269,"path":270,"stem":271,"icon":111},"Avec BLoC","/fr/third-party/with-bloc","fr/07.third-party/2.with-bloc",{"title":273,"path":274,"stem":275,"icon":276},"Avec Riverpod","/fr/third-party/with-riverpod","fr/07.third-party/3.with-riverpod","i-lucide-droplets",{"title":278,"path":279,"stem":280,"icon":281},"Avec RxDart","/fr/third-party/with-rxdart","fr/07.third-party/4.with-rxdart","i-lucide-git-branch",{"title":283,"path":284,"stem":285},"Avec Dio","/fr/third-party/with-dio","fr/07.third-party/5.with-dio",{"title":287,"path":288,"stem":289,"icon":290},"Avec GraphQL","/fr/third-party/with-graphql","fr/07.third-party/6.with-graphql","i-lucide-binary",{"title":292,"icon":190,"path":293,"stem":294,"children":295,"page":44},"Exemples","/fr/examples","fr/08.examples",[296,301,305,310,314,318,322],{"title":297,"path":298,"stem":299,"icon":300},"Étude de cas : Liste et détail utilisateur","/fr/examples/basic-query","fr/08.examples/1.basic-query","i-lucide-play-circle",{"title":302,"path":303,"stem":304,"icon":151},"Étude de cas : Mutations optimistes et rollback","/fr/examples/mutations-optimistic","fr/08.examples/2.mutations-optimistic",{"title":306,"path":307,"stem":308,"icon":309},"Étude de cas : Feed à défilement infini","/fr/examples/infinite-scroll","fr/08.examples/3.infinite-scroll","i-lucide-scroll",{"title":311,"path":312,"stem":313,"icon":90},"Étude de cas : Application Todo offline-first","/fr/examples/offline-first","fr/08.examples/4.offline-first",{"title":315,"path":316,"stem":317,"icon":161},"Étude de cas : Conscience réseau","/fr/examples/network-awareness","fr/08.examples/5.network-awareness",{"title":319,"path":320,"stem":321,"icon":126},"Étude de cas : Intégration des hooks","/fr/examples/hooks-integration","fr/08.examples/6.hooks-integration",{"title":323,"path":324,"stem":325,"icon":326},"Étude de cas : Application Todo complète","/fr/examples/complete-todo-app","fr/08.examples/7.complete-todo-app","i-lucide-check-square",{"title":328,"icon":329,"path":330,"stem":331,"children":332,"page":44},"Aide","i-lucide-life-buoy","/fr/help","fr/09.help",[333,338],{"title":334,"path":335,"stem":336,"icon":337},"FAQ","/fr/help/faq","fr/09.help/1.faq","i-lucide-circle-help",{"title":339,"path":340,"stem":341,"icon":101},"Dépannage","/fr/help/troubleshooting","fr/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_fr/fr/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,1294,1344,1354,1430,1435,1438,1493,1514,1567,1592,1594,1597,1600,1603,1637,1962,1972,1974,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",{},"Une ",[352,353,354],"strong",{},"mutation"," est toute opération qui modifie l'état côté serveur, y compris les opérations de création, mise à jour et suppression. Les requêtes sont en lecture seule et pilotées par le cache. Les mutations sont des opérations d'écriture explicites.",[348,357,358,359,363],{},"Qora gère les mutations avec ",[360,361,362],"code",{},"MutationController",", un contrôleur de cycle de vie autonome sans clé de cache, sans déduplication et sans comportement SWR.",[365,366],"hr",{},[368,369,371],"h2",{"id":370},"la-machine-détat","La machine d'état",[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],{},"Chaque état porte ",[360,386,387],{},"variables"," : la valeur passée à ",[360,390,391],{},"mutate()",". Cela facilite l'affichage de \"Création du post…\" ou \"Échec de la suppression du commentaire #42\" sans état local supplémentaire.",[365,394],{},[368,396,398],{"id":397},"utilisation-de-base","Utilisation de base",[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// Déclencher la mutation\nfinal post = await controller.mutate('Bonjour, Qora !');\n// Retourne le Post en cas de succès, ou null en cas d'échec.\n\n// Observer les transitions d'état\ncontroller.stream.listen((state) {\n  switch (state) {\n    case MutationIdle():\n      print('Prêt');\n    case MutationPending(:final variables):\n      print('Création de \"$variables\"…');\n    case MutationSuccess(:final data):\n      print('Créé : ${data.title}');\n    case MutationFailure(:final error):\n      print('Échec : $error');\n  }\n});\n\n// Réinitialiser à idle après affichage du résultat\ncontroller.reset();\n\n// Toujours disposer quand terminé\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","// Déclencher la 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","'Bonjour, Qora !'",[408,532,484],{"class":418},[408,534,487],{"class":422},[408,536,538],{"class":410,"line":537},7,[408,539,540],{"class":500},"// Retourne le Post en cas de succès, ou null en cas d'échec.\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},"// Observer les transitions d'état\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},"'Prêt'",[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},"'Création de \"",[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},"'Créé : ",[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},"'Échec : ",[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},"// Réinitialiser à idle après affichage du résultat\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},"// Toujours disposer quand terminé\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],{}," ne lève jamais d'exception. Les erreurs sont capturées dans l'état ",[360,812,813],{},"MutationFailure"," et retournées sous forme de ",[360,816,817],{},"null"," au site d'appel.",[365,820],{},[368,822,824],{"id":823},"callbacks-de-cycle-de-vie","Callbacks de cycle de vie",[348,826,827,830],{},[360,828,829],{},"MutationOptions"," fournit quatre hooks qui s'exécutent autour de la 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']], // Rafraîchir automatique la liste des posts en cas de succès\n    onMutate: (title) async {\n      print('Sur le point de créer \"$title\"');\n      // La valeur de retour devient TContext : passée à onSuccess, onError, onSettled.\n    },\n    onSuccess: (post, title, _) async {\n      print('Créé : ${post.id}');\n    },\n    onError: (error, title, _) async {\n      print('Échec de la création de \"$title\" : $error');\n    },\n    onSettled: (post, error, title, _) async {\n      // Appelé quel que soit le résultat.\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}," // Rafraîchir automatique la liste des posts en cas de succès\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},"'Sur le point de créer \"",[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},"      // La valeur de retour devient TContext : passée à 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},"'Échec de la création de \"",[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},"      // Appelé quel que soit le résultat.\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],{},"Quand",[1170,1177,1178],{},"Reçoit",[1180,1181,1182,1198,1218,1237],"tbody",{},[1167,1183,1184,1190,1193],{},[1185,1186,1187],"td",{},[360,1188,1189],{},"onMutate(variables)",[1185,1191,1192],{},"Avant le démarrage du mutator",[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],{},"Après un mutator réussi",[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],{},"Après une exception du mutator",[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],{},"Après l'un ou l'autre résultat",[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],{},"La valeur retournée par ",[360,1263,1264],{},"onMutate"," devient ",[360,1267,1268],{},"TContext"," : le troisième paramètre de type de ",[360,1271,362],{},". C'est le mécanisme derrière le rollback des mises à jour optimistes.",[365,1274],{},[368,1276,1278],{"id":1277},"invalidation-automatique","Invalidation automatique",[348,1280,1281,1282,1285,1286,1289,1290,1293],{},"Au lieu d'appeler ",[360,1283,1284],{},"client.invalidate()"," manuellement dans ",[360,1287,1288],{},"onSuccess",", déclarez les clés de requête à l'avance avec ",[360,1291,1292],{},"invalidates"," :",[373,1295,1297],{"className":401,"code":1296,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  invalidates: [['posts'], ['users', userId]],\n)\n",[360,1298,1299,1310,1339],{"__ignoreMap":379},[408,1300,1301,1304,1306,1308],{"class":410,"line":411},[408,1302,1303],{"class":418},"options",[408,1305,456],{"class":422},[408,1307,889],{"class":426},[408,1309,892],{"class":418},[408,1311,1312,1315,1317,1319,1321,1324,1326,1329,1332,1334,1337],{"class":410,"line":450},[408,1313,1314],{"class":418},"  invalidates",[408,1316,456],{"class":422},[408,1318,902],{"class":418},[408,1320,905],{"class":529},[408,1322,1323],{"class":418},"]",[408,1325,911],{"class":422},[408,1327,1328],{"class":418}," [",[408,1330,1331],{"class":529},"'users'",[408,1333,911],{"class":422},[408,1335,1336],{"class":418}," userId]]",[408,1338,478],{"class":422},[408,1340,1341],{"class":410,"line":481},[408,1342,1343],{"class":418},")\n",[348,1345,1346,1347,1350,1351,1353],{},"Chaque clé est invalidée automatiquement après la réussite de la mutation, qu'elle s'exécute immédiatement ou soit rejouée depuis la file hors-ligne. Les invalidations ont lieu ",[352,1348,1349],{},"après"," l'exécution de ",[360,1352,1288],{},", afin que le cache soit rafraîchi après les effets de bord manuels.",[373,1355,1357],{"className":401,"code":1356,"language":404,"meta":379,"style":379},"// Avant : manuel\nonSuccess: (_, __, ___) async { client.invalidate(['posts']); }\n\n// Après : automatique\ninvalidates: [['posts']],\n",[360,1358,1359,1364,1407,1411,1416],{"__ignoreMap":379},[408,1360,1361],{"class":410,"line":411},[408,1362,1363],{"class":500},"// Avant : manuel\n",[408,1365,1366,1368,1370,1373,1375,1378,1380,1383,1385,1388,1390,1393,1396,1398,1401,1404],{"class":410,"line":450},[408,1367,1288],{"class":418},[408,1369,456],{"class":422},[408,1371,1372],{"class":418}," (_",[408,1374,911],{"class":422},[408,1376,1377],{"class":418}," __",[408,1379,911],{"class":422},[408,1381,1382],{"class":418}," ___) ",[408,1384,926],{"class":514},[408,1386,1387],{"class":418}," { client",[408,1389,468],{"class":422},[408,1391,1392],{"class":471},"invalidate",[408,1394,1395],{"class":418},"([",[408,1397,905],{"class":529},[408,1399,1400],{"class":418},"])",[408,1402,1403],{"class":422},";",[408,1405,1406],{"class":418}," }\n",[408,1408,1409],{"class":410,"line":481},[408,1410,494],{"emptyLinePlaceholder":493},[408,1412,1413],{"class":410,"line":490},[408,1414,1415],{"class":500},"// Après : automatique\n",[408,1417,1418,1420,1422,1424,1426,1428],{"class":410,"line":497},[408,1419,1292],{"class":418},[408,1421,456],{"class":422},[408,1423,902],{"class":418},[408,1425,905],{"class":529},[408,1427,908],{"class":418},[408,1429,478],{"class":422},[1431,1432,1434],"h3",{"id":1433},"invalidation-par-tags","Invalidation par tags",[348,1436,1437],{},"Vous pouvez aussi invalider les requêtes par tag, en les découplant complètement de la structure des clés :",[373,1439,1441],{"className":401,"code":1440,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  invalidatesTags: [QueryTag('post'), QueryTag('user', userId)],\n)\n",[360,1442,1443,1453,1489],{"__ignoreMap":379},[408,1444,1445,1447,1449,1451],{"class":410,"line":411},[408,1446,1303],{"class":418},[408,1448,456],{"class":422},[408,1450,889],{"class":426},[408,1452,892],{"class":418},[408,1454,1455,1458,1460,1462,1465,1467,1470,1472,1474,1477,1479,1482,1484,1487],{"class":410,"line":450},[408,1456,1457],{"class":418},"  invalidatesTags",[408,1459,456],{"class":422},[408,1461,1328],{"class":418},[408,1463,1464],{"class":426},"QueryTag",[408,1466,526],{"class":418},[408,1468,1469],{"class":529},"'post'",[408,1471,484],{"class":418},[408,1473,911],{"class":422},[408,1475,1476],{"class":426}," QueryTag",[408,1478,526],{"class":418},[408,1480,1481],{"class":529},"'user'",[408,1483,911],{"class":422},[408,1485,1486],{"class":418}," userId)]",[408,1488,478],{"class":422},[408,1490,1491],{"class":410,"line":481},[408,1492,1343],{"class":418},[348,1494,1495,1496,1499,1500,1503,1504,1506,1507,1510,1511,468],{},"Toute requête dont ",[360,1497,1498],{},"QoraOptions.providesTags"," contient un tag correspondant est automatiquement revalidée. Correspondance générique : ",[360,1501,1502],{},"QueryTag('post')"," revalide toutes les requêtes fournissant un tag ",[360,1505,1469],{}," quel que soit l'identifiant. Correspondance spécifique : ",[360,1508,1509],{},"QueryTag('post', '123')"," revalide uniquement les requêtes fournissant exactement ",[360,1512,1513],{},"'post':'123'",[373,1515,1517],{"className":401,"code":1516,"language":404,"meta":379,"style":379},"// Avant : par clé\ninvalidates: [['posts']],\n\n// Après : par tag\ninvalidatesTags: [QueryTag('post')],\n",[360,1518,1519,1524,1538,1542,1547],{"__ignoreMap":379},[408,1520,1521],{"class":410,"line":411},[408,1522,1523],{"class":500},"// Avant : par clé\n",[408,1525,1526,1528,1530,1532,1534,1536],{"class":410,"line":450},[408,1527,1292],{"class":418},[408,1529,456],{"class":422},[408,1531,902],{"class":418},[408,1533,905],{"class":529},[408,1535,908],{"class":418},[408,1537,478],{"class":422},[408,1539,1540],{"class":410,"line":481},[408,1541,494],{"emptyLinePlaceholder":493},[408,1543,1544],{"class":410,"line":490},[408,1545,1546],{"class":500},"// Après : par tag\n",[408,1548,1549,1552,1554,1556,1558,1560,1562,1565],{"class":410,"line":497},[408,1550,1551],{"class":418},"invalidatesTags",[408,1553,456],{"class":422},[408,1555,1328],{"class":418},[408,1557,1464],{"class":426},[408,1559,526],{"class":418},[408,1561,1469],{"class":529},[408,1563,1564],{"class":418},")]",[408,1566,478],{"class":422},[348,1568,1569,1570,436,1572,1575,1576,1578,1579,1581,1582,1585,1586,1588,1589,1591],{},"Fonctionne avec ",[360,1571,113],{},[360,1573,1574],{},"useMutation"," et le ",[360,1577,362],{}," bru, tant qu'un ",[360,1580,202],{}," ou un callback ",[360,1583,1584],{},"invalidateQuery"," est câblé. ",[360,1587,1292],{}," et ",[360,1590,1551],{}," peuvent être utilisés ensemble ; l'invalidation par tag s'exécute après celle par clé.",[365,1593],{},[368,1595,148],{"id":1596},"mises-à-jour-optimistes",[348,1598,1599],{},"Les mises à jour optimistes appliquent un changement au cache local immédiatement : avant que le serveur le confirme. Si le serveur rejette le changement, les données précédentes sont restaurées.",[348,1601,1602],{},"Le pattern comporte trois étapes :",[1604,1605,1606,1616,1630],"ol",{},[1607,1608,1609,1613,1614],"li",{},[352,1610,1611],{},[360,1612,1264],{}," : snapshot des données actuelles du cache, application du changement optimiste, retour du snapshot en tant que ",[360,1615,1268],{},[1607,1617,1618,1623,1624,1626,1627],{},[352,1619,1620],{},[360,1621,1622],{},"onError"," : utilisation du snapshot (",[360,1625,1268],{},") pour le rollback via ",[360,1628,1629],{},"client.restoreQueryData()",[1607,1631,1632,1636],{},[352,1633,1634],{},[360,1635,1288],{}," : invalidation de la requête pour récupérer les données confirmées par le serveur",[373,1638,1640],{"className":401,"code":1639,"filename":403,"language":404,"meta":379,"style":379},"final controller = MutationController\u003CPost, String, List\u003CPost>?>(\n  // TContext = List\u003CPost>? : le snapshot utilisé pour le rollback\n  mutator: (title) => api.createPost(title),\n  options: MutationOptions(\n    invalidates: [['posts']], // 4️⃣ Confirmation : remplacer les données optimistes par les vraies données serveur\n    onMutate: (title) async {\n      // 1️⃣ Snapshot\n      final previous = client.getQueryData\u003CList\u003CPost>>(['posts']);\n\n      // 2️⃣ Mise à jour optimiste : l'UI reflète le changement immédiatement\n      client.setQueryData\u003CList\u003CPost>>(\n        ['posts'],\n        [...?previous, Post.optimistic(title)],\n      );\n\n      return previous; // Devient TContext\n    },\n    onError: (error, title, previous) async {\n      // 3️⃣ Rollback : restaurer le snapshot en cas d'échec\n      client.restoreQueryData(['posts'], previous);\n    },\n  ),\n);\n\nawait controller.mutate('Nouveau Post');\n",[360,1641,1642,1672,1677,1697,1707,1724,1736,1741,1776,1780,1785,1806,1817,1842,1849,1853,1866,1872,1893,1898,1920,1926,1932,1938,1942],{"__ignoreMap":379},[408,1643,1644,1646,1648,1650,1652,1654,1656,1658,1660,1662,1665,1667,1669],{"class":410,"line":411},[408,1645,415],{"class":414},[408,1647,419],{"class":418},[408,1649,423],{"class":422},[408,1651,427],{"class":426},[408,1653,430],{"class":418},[408,1655,433],{"class":426},[408,1657,436],{"class":418},[408,1659,439],{"class":426},[408,1661,436],{"class":418},[408,1663,1664],{"class":426},"List",[408,1666,430],{"class":418},[408,1668,433],{"class":426},[408,1670,1671],{"class":418},">?>(\n",[408,1673,1674],{"class":410,"line":450},[408,1675,1676],{"class":500},"  // TContext = List\u003CPost>? : le snapshot utilisé pour le rollback\n",[408,1678,1679,1681,1683,1685,1687,1689,1691,1693,1695],{"class":410,"line":481},[408,1680,453],{"class":418},[408,1682,456],{"class":422},[408,1684,459],{"class":418},[408,1686,462],{"class":422},[408,1688,465],{"class":418},[408,1690,468],{"class":422},[408,1692,472],{"class":471},[408,1694,475],{"class":418},[408,1696,478],{"class":422},[408,1698,1699,1701,1703,1705],{"class":410,"line":490},[408,1700,884],{"class":418},[408,1702,456],{"class":422},[408,1704,889],{"class":426},[408,1706,892],{"class":418},[408,1708,1709,1711,1713,1715,1717,1719,1721],{"class":410,"line":497},[408,1710,897],{"class":418},[408,1712,456],{"class":422},[408,1714,902],{"class":418},[408,1716,905],{"class":529},[408,1718,908],{"class":418},[408,1720,911],{"class":422},[408,1722,1723],{"class":500}," // 4️⃣ Confirmation : remplacer les données optimistes par les vraies données serveur\n",[408,1725,1726,1728,1730,1732,1734],{"class":410,"line":504},[408,1727,919],{"class":418},[408,1729,456],{"class":422},[408,1731,459],{"class":418},[408,1733,926],{"class":514},[408,1735,929],{"class":418},[408,1737,1738],{"class":410,"line":537},[408,1739,1740],{"class":500},"      // 1️⃣ Snapshot\n",[408,1742,1743,1746,1749,1751,1754,1756,1759,1761,1763,1765,1767,1770,1772,1774],{"class":410,"line":543},[408,1744,1745],{"class":414},"      final",[408,1747,1748],{"class":418}," previous ",[408,1750,423],{"class":422},[408,1752,1753],{"class":418}," client",[408,1755,468],{"class":422},[408,1757,1758],{"class":471},"getQueryData",[408,1760,430],{"class":418},[408,1762,1664],{"class":426},[408,1764,430],{"class":418},[408,1766,433],{"class":426},[408,1768,1769],{"class":418},">>([",[408,1771,905],{"class":529},[408,1773,1400],{"class":418},[408,1775,487],{"class":422},[408,1777,1778],{"class":410,"line":548},[408,1779,494],{"emptyLinePlaceholder":493},[408,1781,1782],{"class":410,"line":554},[408,1783,1784],{"class":500},"      // 2️⃣ Mise à jour optimiste : l'UI reflète le changement immédiatement\n",[408,1786,1787,1790,1792,1795,1797,1799,1801,1803],{"class":410,"line":573},[408,1788,1789],{"class":418},"      client",[408,1791,468],{"class":422},[408,1793,1794],{"class":471},"setQueryData",[408,1796,430],{"class":418},[408,1798,1664],{"class":426},[408,1800,430],{"class":418},[408,1802,433],{"class":426},[408,1804,1805],{"class":418},">>(\n",[408,1807,1808,1811,1813,1815],{"class":410,"line":582},[408,1809,1810],{"class":418},"        [",[408,1812,905],{"class":529},[408,1814,1323],{"class":418},[408,1816,478],{"class":422},[408,1818,1819,1821,1824,1827,1829,1832,1834,1837,1840],{"class":410,"line":597},[408,1820,1810],{"class":418},[408,1822,1823],{"class":422},"...?",[408,1825,1826],{"class":418},"previous",[408,1828,911],{"class":422},[408,1830,1831],{"class":426}," Post",[408,1833,468],{"class":422},[408,1835,1836],{"class":471},"optimistic",[408,1838,1839],{"class":418},"(title)]",[408,1841,478],{"class":422},[408,1843,1844,1847],{"class":410,"line":612},[408,1845,1846],{"class":418},"      )",[408,1848,487],{"class":422},[408,1850,1851],{"class":410,"line":631},[408,1852,494],{"emptyLinePlaceholder":493},[408,1854,1855,1858,1861,1863],{"class":410,"line":654},[408,1856,1857],{"class":514},"      return",[408,1859,1860],{"class":418}," previous",[408,1862,1403],{"class":422},[408,1864,1865],{"class":500}," // Devient TContext\n",[408,1867,1868,1870],{"class":410,"line":673},[408,1869,959],{"class":418},[408,1871,478],{"class":422},[408,1873,1874,1876,1878,1880,1882,1884,1886,1889,1891],{"class":410,"line":704},[408,1875,1022],{"class":418},[408,1877,456],{"class":422},[408,1879,1027],{"class":418},[408,1881,911],{"class":422},[408,1883,976],{"class":418},[408,1885,911],{"class":422},[408,1887,1888],{"class":418}," previous) ",[408,1890,926],{"class":514},[408,1892,929],{"class":418},[408,1894,1895],{"class":410,"line":723},[408,1896,1897],{"class":500},"      // 3️⃣ Rollback : restaurer le snapshot en cas d'échec\n",[408,1899,1900,1902,1904,1907,1909,1911,1913,1915,1918],{"class":410,"line":744},[408,1901,1789],{"class":418},[408,1903,468],{"class":422},[408,1905,1906],{"class":471},"restoreQueryData",[408,1908,1395],{"class":418},[408,1910,905],{"class":529},[408,1912,1323],{"class":418},[408,1914,911],{"class":422},[408,1916,1917],{"class":418}," previous)",[408,1919,487],{"class":422},[408,1921,1922,1924],{"class":410,"line":750},[408,1923,959],{"class":418},[408,1925,478],{"class":422},[408,1927,1928,1930],{"class":410,"line":758},[408,1929,1151],{"class":418},[408,1931,478],{"class":422},[408,1933,1934,1936],{"class":410,"line":763},[408,1935,484],{"class":418},[408,1937,487],{"class":422},[408,1939,1940],{"class":410,"line":769},[408,1941,494],{"emptyLinePlaceholder":493},[408,1943,1944,1947,1949,1951,1953,1955,1958,1960],{"class":410,"line":783},[408,1945,1946],{"class":514},"await",[408,1948,518],{"class":418},[408,1950,468],{"class":422},[408,1952,523],{"class":471},[408,1954,526],{"class":418},[408,1956,1957],{"class":529},"'Nouveau Post'",[408,1959,484],{"class":418},[408,1961,487],{"class":422},[1963,1964,1965,1968,1969,1971],"tip",{},[360,1966,1967],{},"client.restoreQueryData(key, null)"," supprime entièrement la requête du cache : utile quand le snapshot était ",[360,1970,817],{}," (la liste n'existait pas encore).",[365,1973],{},[368,1975,1977,1978],{"id":1976},"gestion-des-échecs-de-onmutate","Gestion des échecs de ",[360,1979,1264],{},[348,1981,1982,1983,1985,1986,1989,1990,468],{},"Si ",[360,1984,1264],{}," lève une exception (par exemple une validation pré-appel échoue), le mutator ",[352,1987,1988],{},"n'est pas appelé",". Le contrôleur passe directement à ",[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('Le titre ne peut pas être vide');\n    // Le mutator ne s'exécutera jamais si cela lève une exception\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,1303],{"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},"'Le titre ne peut pas être vide'",[408,2045,484],{"class":418},[408,2047,487],{"class":422},[408,2049,2050],{"class":410,"line":490},[408,2051,2052],{"class":500},"    // Le mutator ne s'exécutera jamais si cela lève une exception\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],{},"Utile pour les validations côté client qui doivent bloquer entièrement l'appel réseau.",[365,2078],{},[368,2080,2082],{"id":2081},"retry","Retry",[348,2084,2085],{},"Par défaut, les mutations ne font pas de retry (contrairement aux requêtes, relancer une écriture peut avoir des effets secondaires). Activer le retry explicitement :",[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 tentatives au total\n  retryDelay: Duration(seconds: 1),    // Backoff exponentiel : 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,1303],{"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 tentatives au total\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},"    // Backoff exponentiel : 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],{},"Le retry s'applique uniquement au mutator. Si ",[360,2155,1264],{}," lève une exception, aucun retry ne se produit.",[365,2158],{},[368,2160,2162],{"id":2161},"mode-autonome","Mode autonome",[348,2164,2165,2167,2168,2170,2171,2174],{},[360,2166,362],{}," fonctionne sans ",[360,2169,202],{},". Passer ",[360,2172,2173],{},"tracker: null"," (valeur par défaut) pour opérer en mode autonome sans observabilité globale :",[373,2176,2179],{"className":401,"code":2177,"filename":2178,"language":404,"meta":379,"style":379},"// Pas de client requis : les mutations fonctionnent partout\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},"// Pas de client requis : les mutations fonctionnent partout\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},"observabilité-devtools","Observabilité DevTools",[348,2249,2250,2251,2253,2254,2257,2258,1588,2261,468],{},"Câbler un contrôleur dans ",[360,2252,202],{}," en passant ",[360,2255,2256],{},"tracker: client",". Le client expose alors toute l'activité des mutations 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  // Optionnel : étiqueter ce contrôleur pour le filtrage DevTools\n  metadata: {'category': 'content', 'resource': 'post'},\n);\n\n// Écouter toute l'activité des mutations sur tous les contrôleurs suivis\nclient.mutationEvents.listen((event) {\n  if (event.isError) {\n    logger.error('[${event.mutatorId}] Échec', event.error);\n  }\n});\n\n// Snapshot des mutations en cours (uniquement les entrées Pending)\nfinal running = client.activeMutations;\nprint('${running.length} mutation(s) en cours');\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,1753],{"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},"  // Optionnel : étiqueter ce contrôleur pour le filtrage DevTools\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},"// Écouter toute l'activité des mutations sur tous les contrôleurs suivis\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},"] Échec'",[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 des mutations en cours (uniquement les entrées Pending)\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,1753],{"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) en cours'",[408,2510,484],{"class":418},[408,2512,487],{"class":422},[1963,2514,2515,2517,2518,2521],{},[360,2516,2263],{}," ne contient que les entrées ",[360,2519,2520],{},"MutationPending"," : les mutations terminées (Success ou Failure) sont purgées automatiquement. Cela prévient l'accumulation mémoire et fait de la map un indicateur fiable \"actuellement en vol\".",[348,2523,2524,2525,2527,2528,2531,2532,2535],{},"Lors de l'utilisation de ",[360,2526,113],{}," dans Flutter, ",[360,2529,2530],{},"tracker"," est automatiquement défini à ",[360,2533,2534],{},"QoraScope.maybeOf(context)"," : aucun câblage manuel n'est nécessaire.",[365,2537],{},[368,2539,2541],{"id":2540},"mises-à-jour-optimistes-multi-requêtes","Mises à jour optimistes multi-requêtes",[348,2543,2544,2545,2547,2548,2550],{},"Une seule mutation peut toucher plusieurs requêtes. Chaque appel à ",[360,2546,1794],{}," déclenche une mise à jour réactive dans tout ",[360,2549,108],{}," abonné à cette clé :",[373,2552,2554],{"className":401,"code":2553,"filename":403,"language":404,"meta":379,"style":379},"options: MutationOptions(\n  onMutate: (postId) async {\n    // Snapshot des deux requêtes\n    final posts = client.getQueryData\u003CList\u003CPost>>(['posts']);\n    final user = client.getQueryData\u003CUser>(['users', currentUserId]);\n\n    // Mise à jour optimiste des deux\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 est un record\n  },\n  onError: (error, postId, snapshots) async {\n    // Rollback des deux\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,1303],{"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 des deux requêtes\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,1753],{"class":418},[408,2597,468],{"class":422},[408,2599,1758],{"class":471},[408,2601,430],{"class":418},[408,2603,1664],{"class":426},[408,2605,430],{"class":418},[408,2607,433],{"class":426},[408,2609,1769],{"class":418},[408,2611,905],{"class":529},[408,2613,1400],{"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,1753],{"class":418},[408,2628,468],{"class":422},[408,2630,1758],{"class":471},[408,2632,430],{"class":418},[408,2634,2635],{"class":426},"User",[408,2637,2638],{"class":418},">([",[408,2640,1331],{"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},"    // Mise à jour optimiste des deux\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,1794],{"class":471},[408,2667,430],{"class":418},[408,2669,1664],{"class":426},[408,2671,430],{"class":418},[408,2673,433],{"class":426},[408,2675,1805],{"class":418},[408,2677,2678,2681,2683,2685],{"class":410,"line":548},[408,2679,2680],{"class":418},"      [",[408,2682,905],{"class":529},[408,2684,1323],{"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,1794],{"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,1331],{"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,1403],{"class":422},[408,2835,2836],{"class":500}," // TContext est un 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},"    // Rollback des deux\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,1906],{"class":471},[408,2880,1395],{"class":418},[408,2882,905],{"class":529},[408,2884,1323],{"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,1906],{"class":471},[408,2906,1395],{"class":418},[408,2908,1331],{"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},"étapes-suivantes","Étapes suivantes",[2943,2944,2945,2953,2959],"ul",{},[1607,2946,2947,2952],{},[2948,2949,2951],"a",{"href":2950},"../flutter-integration/qora-mutation-builder","MutationBuilder"," : Lier les mutations à l'UI Flutter",[1607,2954,2955,2958],{},[2948,2956,148],{"href":2957},"./optimistic-updates"," : Exploration approfondie des patterns de rollback",[1607,2960,2961,2965],{},[2948,2962,2964],{"href":2963},"../api-reference/qora-mutation","Référence API Mutation"," : Documentation API complète",[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":1433,"depth":481,"text":1434},{"id":1596,"depth":450,"text":148},{"id":1976,"depth":450,"text":2980},"Gestion des échecs de onMutate",{"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},"Effectuer des opérations d'écriture (POST, PUT, DELETE) avec un support complet du cycle de vie : mises à jour optimistes, rollback automatique, retry et observabilité DevTools.","md",null,{},{"icon":85},{"title":2992,"description":2993},"Mutations - Qora","Effectuer des opérations d'écriture avec MutationController. Support complet du cycle de vie avec mises à jour optimistes, rollback automatique, retry et observabilité DevTools.","iIwxow-BIqWwN6U3Z6NdFsF7U4WKdHltFeDbP1-_uxo",[2996,2998],{"title":133,"path":134,"stem":135,"description":2997,"icon":136,"children":-1},"Patterns et conventions pour construire des applications Flutter fiables avec Qora : clés, placement des requêtes, câblage des mutations et performance.",{"title":148,"path":149,"stem":150,"description":2999,"icon":151,"children":-1},"Mettre à jour l'UI instantanément pendant que les mutations sont en cours, et effectuer un rollback sécurisé en cas d'échec : sans bibliothèques supplémentaires.",1794040408667]