[{"data":1,"prerenderedAt":1716},["ShallowReactive",2],{"navigation_docs_fr":3,"-fr-recipes-cancel-token":342,"-fr-recipes-cancel-token-surround":1711},[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":172,"body":344,"description":1704,"extension":1705,"links":1706,"meta":1707,"navigation":1708,"path":173,"seo":1709,"stem":174,"__hash__":1710},"docs_fr/fr/04.recipes/08.cancel-token.md",{"type":345,"value":346,"toc":1686},"minimark",[347,371,374,379,416,422,424,430,689,699,701,707,855,867,869,873,883,1092,1094,1098,1105,1368,1370,1376,1381,1393,1397,1440,1444,1473,1475,1480,1491,1530,1561,1563,1567,1576,1652,1654,1658,1682],[348,349,350,354,355,358,359,362,363,366,367,370],"p",{},[351,352,353],"code",{},"CancelToken"," est un signal d'annulation coopératif à usage unique. Le passer à ",[351,356,357],{},"fetchQuery",", ",[351,360,361],{},"watchQuery"," ou ",[351,364,365],{},"prefetch"," et appeler ",[351,368,369],{},"cancel()"," pour interrompre le fetch avant son démarrage ou pendant son exécution.",[372,373],"hr",{},[375,376,378],"h2",{"id":377},"créer-un-token","Créer un token",[380,381,387],"pre",{"className":382,"code":383,"filename":384,"language":385,"meta":386,"style":386},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","final token = CancelToken();\n","main.dart","dart","",[351,388,389],{"__ignoreMap":386},[390,391,394,398,402,406,410,413],"span",{"class":392,"line":393},"line",1,[390,395,397],{"class":396},"spNyl","final",[390,399,401],{"class":400},"sTEyZ"," token ",[390,403,405],{"class":404},"sMK4o","=",[390,407,409],{"class":408},"sBMFI"," CancelToken",[390,411,412],{"class":400},"()",[390,414,415],{"class":404},";\n",[348,417,418,419,421],{},"Un token ne peut être annulé qu'une seule fois. Appeler ",[351,420,369],{}," une deuxième fois est sans effet.",[372,423],{},[375,425,427,428],{"id":426},"annuler-un-fetchquery","Annuler un ",[351,429,357],{},[380,431,434],{"className":382,"code":432,"filename":433,"language":385,"meta":386,"style":386},"final token = CancelToken();\n\n// Démarrer le fetch\nfinal future = client.fetchQuery\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n  cancelToken: token,\n);\n\n// L'annuler (ex. l'utilisateur a navigué ailleurs)\ntoken.cancel();\n\ntry {\n  final user = await future;\n} on QoraCancelException catch (e) {\n  // e.key est la clé de requête encodée en chaîne\n  print('Fetch annulé : ${e.key}');\n}\n","user_repository.dart",[351,435,436,450,457,464,492,517,544,557,565,570,576,591,596,606,625,643,649,683],{"__ignoreMap":386},[390,437,438,440,442,444,446,448],{"class":392,"line":393},[390,439,397],{"class":396},[390,441,401],{"class":400},[390,443,405],{"class":404},[390,445,409],{"class":408},[390,447,412],{"class":400},[390,449,415],{"class":404},[390,451,453],{"class":392,"line":452},2,[390,454,456],{"emptyLinePlaceholder":455},true,"\n",[390,458,460],{"class":392,"line":459},3,[390,461,463],{"class":462},"sHwdD","// Démarrer le fetch\n",[390,465,467,469,472,474,477,480,483,486,489],{"class":392,"line":466},4,[390,468,397],{"class":396},[390,470,471],{"class":400}," future ",[390,473,405],{"class":404},[390,475,476],{"class":400}," client",[390,478,479],{"class":404},".",[390,481,357],{"class":482},"s2Zo4",[390,484,485],{"class":400},"\u003C",[390,487,488],{"class":408},"User",[390,490,491],{"class":400},">(\n",[390,493,495,498,501,504,508,511,514],{"class":392,"line":494},5,[390,496,497],{"class":400},"  key",[390,499,500],{"class":404},":",[390,502,503],{"class":400}," [",[390,505,507],{"class":506},"sfazB","'users'",[390,509,510],{"class":404},",",[390,512,513],{"class":400}," userId]",[390,515,516],{"class":404},",\n",[390,518,520,523,525,528,531,534,536,539,542],{"class":392,"line":519},6,[390,521,522],{"class":400},"  fetcher",[390,524,500],{"class":404},[390,526,527],{"class":400}," () ",[390,529,530],{"class":404},"=>",[390,532,533],{"class":400}," api",[390,535,479],{"class":404},[390,537,538],{"class":482},"getUser",[390,540,541],{"class":400},"(userId)",[390,543,516],{"class":404},[390,545,547,550,552,555],{"class":392,"line":546},7,[390,548,549],{"class":400},"  cancelToken",[390,551,500],{"class":404},[390,553,554],{"class":400}," token",[390,556,516],{"class":404},[390,558,560,563],{"class":392,"line":559},8,[390,561,562],{"class":400},")",[390,564,415],{"class":404},[390,566,568],{"class":392,"line":567},9,[390,569,456],{"emptyLinePlaceholder":455},[390,571,573],{"class":392,"line":572},10,[390,574,575],{"class":462},"// L'annuler (ex. l'utilisateur a navigué ailleurs)\n",[390,577,579,582,584,587,589],{"class":392,"line":578},11,[390,580,581],{"class":400},"token",[390,583,479],{"class":404},[390,585,586],{"class":482},"cancel",[390,588,412],{"class":400},[390,590,415],{"class":404},[390,592,594],{"class":392,"line":593},12,[390,595,456],{"emptyLinePlaceholder":455},[390,597,599,603],{"class":392,"line":598},13,[390,600,602],{"class":601},"s7zQu","try",[390,604,605],{"class":400}," {\n",[390,607,609,612,615,617,620,623],{"class":392,"line":608},14,[390,610,611],{"class":396},"  final",[390,613,614],{"class":400}," user ",[390,616,405],{"class":404},[390,618,619],{"class":601}," await",[390,621,622],{"class":400}," future",[390,624,415],{"class":404},[390,626,628,631,634,637,640],{"class":392,"line":627},15,[390,629,630],{"class":400},"} ",[390,632,633],{"class":601},"on",[390,635,636],{"class":408}," QoraCancelException",[390,638,639],{"class":601}," catch",[390,641,642],{"class":400}," (e) {\n",[390,644,646],{"class":392,"line":645},16,[390,647,648],{"class":462},"  // e.key est la clé de requête encodée en chaîne\n",[390,650,652,655,658,661,664,668,670,673,676,679,681],{"class":392,"line":651},17,[390,653,654],{"class":482},"  print",[390,656,657],{"class":400},"(",[390,659,660],{"class":506},"'Fetch annulé : ",[390,662,663],{"class":400},"${",[390,665,667],{"class":666},"sHdIc","e",[390,669,479],{"class":400},[390,671,672],{"class":666},"key",[390,674,675],{"class":400},"}",[390,677,678],{"class":506},"'",[390,680,562],{"class":400},[390,682,415],{"class":404},[390,684,686],{"class":392,"line":685},18,[390,687,688],{"class":400},"}\n",[348,690,691,692,694,695,698],{},"Quand annulé, ",[351,693,357],{}," lève ",[351,696,697],{},"QoraCancelException"," à l'appelant et restaure l'entrée de cache à son snapshot pré-fetch (aucun état partiel n'est laissé derrière).",[372,700],{},[375,702,704,705],{"id":703},"annuler-un-stream-watchquery","Annuler un stream ",[351,706,361],{},[380,708,711],{"className":382,"code":709,"filename":710,"language":385,"meta":386,"style":386},"final token = CancelToken();\n\nfinal sub = client.watchQuery\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n  cancelToken: token,\n).listen((state) { ... });\n\n// Au dispose du widget : annuler le fetch en cours\ntoken.cancel();\nawait sub.cancel();\n","user_page.dart",[351,712,713,727,731,752,768,788,798,818,822,827,839],{"__ignoreMap":386},[390,714,715,717,719,721,723,725],{"class":392,"line":393},[390,716,397],{"class":396},[390,718,401],{"class":400},[390,720,405],{"class":404},[390,722,409],{"class":408},[390,724,412],{"class":400},[390,726,415],{"class":404},[390,728,729],{"class":392,"line":452},[390,730,456],{"emptyLinePlaceholder":455},[390,732,733,735,738,740,742,744,746,748,750],{"class":392,"line":459},[390,734,397],{"class":396},[390,736,737],{"class":400}," sub ",[390,739,405],{"class":404},[390,741,476],{"class":400},[390,743,479],{"class":404},[390,745,361],{"class":482},[390,747,485],{"class":400},[390,749,488],{"class":408},[390,751,491],{"class":400},[390,753,754,756,758,760,762,764,766],{"class":392,"line":466},[390,755,497],{"class":400},[390,757,500],{"class":404},[390,759,503],{"class":400},[390,761,507],{"class":506},[390,763,510],{"class":404},[390,765,513],{"class":400},[390,767,516],{"class":404},[390,769,770,772,774,776,778,780,782,784,786],{"class":392,"line":494},[390,771,522],{"class":400},[390,773,500],{"class":404},[390,775,527],{"class":400},[390,777,530],{"class":404},[390,779,533],{"class":400},[390,781,479],{"class":404},[390,783,538],{"class":482},[390,785,541],{"class":400},[390,787,516],{"class":404},[390,789,790,792,794,796],{"class":392,"line":519},[390,791,549],{"class":400},[390,793,500],{"class":404},[390,795,554],{"class":400},[390,797,516],{"class":404},[390,799,800,802,804,807,810,813,816],{"class":392,"line":546},[390,801,562],{"class":400},[390,803,479],{"class":404},[390,805,806],{"class":482},"listen",[390,808,809],{"class":400},"((state) { ",[390,811,812],{"class":404},"...",[390,814,815],{"class":400}," })",[390,817,415],{"class":404},[390,819,820],{"class":392,"line":559},[390,821,456],{"emptyLinePlaceholder":455},[390,823,824],{"class":392,"line":567},[390,825,826],{"class":462},"// Au dispose du widget : annuler le fetch en cours\n",[390,828,829,831,833,835,837],{"class":392,"line":572},[390,830,581],{"class":400},[390,832,479],{"class":404},[390,834,586],{"class":482},[390,836,412],{"class":400},[390,838,415],{"class":404},[390,840,841,844,847,849,851,853],{"class":392,"line":578},[390,842,843],{"class":601},"await",[390,845,846],{"class":400}," sub",[390,848,479],{"class":404},[390,850,586],{"class":482},[390,852,412],{"class":400},[390,854,415],{"class":404},[856,857,858,859,862,863,866],"tip",{},"Annuler l'abonnement au stream est distinct de l'annulation du fetch. ",[351,860,861],{},"token.cancel()"," interrompt la requête HTTP ; ",[351,864,865],{},"sub.cancel()"," retire le listener d'état. Faire les deux au dispose pour un nettoyage propre.",[372,868],{},[375,870,872],{"id":871},"pattern-de-timeout","Pattern de timeout",[348,874,875,876,878,879,882],{},"Combiner ",[351,877,353],{}," avec ",[351,880,881],{},"Future.delayed"," pour implémenter un timeout de requête :",[380,884,886],{"className":382,"code":885,"filename":433,"language":385,"meta":386,"style":386},"Future\u003CUser> fetchWithTimeout(int userId, Duration timeout) async {\n  final token = CancelToken();\n\n  Timer(timeout, token.cancel);\n\n  try {\n    return await client.fetchQuery\u003CUser>(\n      key: ['users', userId],\n      fetcher: () => api.getUser(userId),\n      cancelToken: token,\n    );\n  } on QoraCancelException {\n    throw TimeoutException('Fetch utilisateur expiré après $timeout');\n  }\n}\n",[351,887,888,924,938,942,961,965,972,991,1008,1029,1040,1047,1058,1083,1088],{"__ignoreMap":386},[390,889,890,893,895,897,900,903,905,908,911,913,916,919,922],{"class":392,"line":393},[390,891,892],{"class":408},"Future",[390,894,485],{"class":400},[390,896,488],{"class":408},[390,898,899],{"class":400},"> ",[390,901,902],{"class":482},"fetchWithTimeout",[390,904,657],{"class":400},[390,906,907],{"class":408},"int",[390,909,910],{"class":400}," userId",[390,912,510],{"class":404},[390,914,915],{"class":408}," Duration",[390,917,918],{"class":400}," timeout) ",[390,920,921],{"class":601},"async",[390,923,605],{"class":400},[390,925,926,928,930,932,934,936],{"class":392,"line":452},[390,927,611],{"class":396},[390,929,401],{"class":400},[390,931,405],{"class":404},[390,933,409],{"class":408},[390,935,412],{"class":400},[390,937,415],{"class":404},[390,939,940],{"class":392,"line":459},[390,941,456],{"emptyLinePlaceholder":455},[390,943,944,947,950,952,954,956,959],{"class":392,"line":466},[390,945,946],{"class":408},"  Timer",[390,948,949],{"class":400},"(timeout",[390,951,510],{"class":404},[390,953,554],{"class":400},[390,955,479],{"class":404},[390,957,958],{"class":400},"cancel)",[390,960,415],{"class":404},[390,962,963],{"class":392,"line":494},[390,964,456],{"emptyLinePlaceholder":455},[390,966,967,970],{"class":392,"line":519},[390,968,969],{"class":601},"  try",[390,971,605],{"class":400},[390,973,974,977,979,981,983,985,987,989],{"class":392,"line":546},[390,975,976],{"class":601},"    return",[390,978,619],{"class":601},[390,980,476],{"class":400},[390,982,479],{"class":404},[390,984,357],{"class":482},[390,986,485],{"class":400},[390,988,488],{"class":408},[390,990,491],{"class":400},[390,992,993,996,998,1000,1002,1004,1006],{"class":392,"line":559},[390,994,995],{"class":400},"      key",[390,997,500],{"class":404},[390,999,503],{"class":400},[390,1001,507],{"class":506},[390,1003,510],{"class":404},[390,1005,513],{"class":400},[390,1007,516],{"class":404},[390,1009,1010,1013,1015,1017,1019,1021,1023,1025,1027],{"class":392,"line":567},[390,1011,1012],{"class":400},"      fetcher",[390,1014,500],{"class":404},[390,1016,527],{"class":400},[390,1018,530],{"class":404},[390,1020,533],{"class":400},[390,1022,479],{"class":404},[390,1024,538],{"class":482},[390,1026,541],{"class":400},[390,1028,516],{"class":404},[390,1030,1031,1034,1036,1038],{"class":392,"line":572},[390,1032,1033],{"class":400},"      cancelToken",[390,1035,500],{"class":404},[390,1037,554],{"class":400},[390,1039,516],{"class":404},[390,1041,1042,1045],{"class":392,"line":578},[390,1043,1044],{"class":400},"    )",[390,1046,415],{"class":404},[390,1048,1049,1052,1054,1056],{"class":392,"line":593},[390,1050,1051],{"class":400},"  } ",[390,1053,633],{"class":601},[390,1055,636],{"class":408},[390,1057,605],{"class":400},[390,1059,1060,1063,1066,1068,1071,1074,1077,1079,1081],{"class":392,"line":598},[390,1061,1062],{"class":601},"    throw",[390,1064,1065],{"class":408}," TimeoutException",[390,1067,657],{"class":400},[390,1069,1070],{"class":506},"'Fetch utilisateur expiré après ",[390,1072,1073],{"class":400},"$",[390,1075,1076],{"class":666},"timeout",[390,1078,678],{"class":506},[390,1080,562],{"class":400},[390,1082,415],{"class":404},[390,1084,1085],{"class":392,"line":608},[390,1086,1087],{"class":400},"  }\n",[390,1089,1090],{"class":392,"line":627},[390,1091,688],{"class":400},[372,1093],{},[375,1095,1097],{"id":1096},"annulation-à-la-navigation-dans-flutter","Annulation à la navigation dans Flutter",[348,1099,1100,1101,1104],{},"Dans un ",[351,1102,1103],{},"StatefulWidget",", lier le token au cycle de vie du widget :",[380,1106,1109],{"className":382,"code":1107,"filename":1108,"language":385,"meta":386,"style":386},"class _UserScreenState extends State\u003CUserScreen> {\n  CancelToken? _fetchToken;\n\n  Future\u003Cvoid> _loadUser() async {\n    _fetchToken = CancelToken();\n    try {\n      await context.qora.fetchQuery\u003CUser>(\n        key: ['users', widget.userId],\n        fetcher: () => api.getUser(widget.userId),\n        cancelToken: _fetchToken,\n      );\n    } on QoraCancelException {\n      // Widget disposé : ignorer\n    }\n  }\n\n  @override\n  void dispose() {\n    _fetchToken?.cancel();\n    super.dispose();\n  }\n}\n","user_screen.dart",[351,1110,1111,1133,1146,1150,1172,1185,1192,1215,1238,1265,1276,1283,1294,1299,1304,1308,1312,1317,1328,1343,1358,1363],{"__ignoreMap":386},[390,1112,1113,1116,1119,1122,1125,1127,1130],{"class":392,"line":393},[390,1114,1115],{"class":404},"class",[390,1117,1118],{"class":408}," _UserScreenState",[390,1120,1121],{"class":404}," extends",[390,1123,1124],{"class":408}," State",[390,1126,485],{"class":400},[390,1128,1129],{"class":408},"UserScreen",[390,1131,1132],{"class":400},"> {\n",[390,1134,1135,1138,1141,1144],{"class":392,"line":452},[390,1136,1137],{"class":408},"  CancelToken",[390,1139,1140],{"class":404},"?",[390,1142,1143],{"class":400}," _fetchToken",[390,1145,415],{"class":404},[390,1147,1148],{"class":392,"line":459},[390,1149,456],{"emptyLinePlaceholder":455},[390,1151,1152,1155,1157,1160,1162,1165,1168,1170],{"class":392,"line":466},[390,1153,1154],{"class":408},"  Future",[390,1156,485],{"class":400},[390,1158,1159],{"class":396},"void",[390,1161,899],{"class":400},[390,1163,1164],{"class":482},"_loadUser",[390,1166,1167],{"class":400},"() ",[390,1169,921],{"class":601},[390,1171,605],{"class":400},[390,1173,1174,1177,1179,1181,1183],{"class":392,"line":494},[390,1175,1176],{"class":400},"    _fetchToken ",[390,1178,405],{"class":404},[390,1180,409],{"class":408},[390,1182,412],{"class":400},[390,1184,415],{"class":404},[390,1186,1187,1190],{"class":392,"line":519},[390,1188,1189],{"class":601},"    try",[390,1191,605],{"class":400},[390,1193,1194,1197,1200,1202,1205,1207,1209,1211,1213],{"class":392,"line":546},[390,1195,1196],{"class":601},"      await",[390,1198,1199],{"class":400}," context",[390,1201,479],{"class":404},[390,1203,1204],{"class":400},"qora",[390,1206,479],{"class":404},[390,1208,357],{"class":482},[390,1210,485],{"class":400},[390,1212,488],{"class":408},[390,1214,491],{"class":400},[390,1216,1217,1220,1222,1224,1226,1228,1231,1233,1236],{"class":392,"line":559},[390,1218,1219],{"class":400},"        key",[390,1221,500],{"class":404},[390,1223,503],{"class":400},[390,1225,507],{"class":506},[390,1227,510],{"class":404},[390,1229,1230],{"class":400}," widget",[390,1232,479],{"class":404},[390,1234,1235],{"class":400},"userId]",[390,1237,516],{"class":404},[390,1239,1240,1243,1245,1247,1249,1251,1253,1255,1258,1260,1263],{"class":392,"line":567},[390,1241,1242],{"class":400},"        fetcher",[390,1244,500],{"class":404},[390,1246,527],{"class":400},[390,1248,530],{"class":404},[390,1250,533],{"class":400},[390,1252,479],{"class":404},[390,1254,538],{"class":482},[390,1256,1257],{"class":400},"(widget",[390,1259,479],{"class":404},[390,1261,1262],{"class":400},"userId)",[390,1264,516],{"class":404},[390,1266,1267,1270,1272,1274],{"class":392,"line":572},[390,1268,1269],{"class":400},"        cancelToken",[390,1271,500],{"class":404},[390,1273,1143],{"class":400},[390,1275,516],{"class":404},[390,1277,1278,1281],{"class":392,"line":578},[390,1279,1280],{"class":400},"      )",[390,1282,415],{"class":404},[390,1284,1285,1288,1290,1292],{"class":392,"line":593},[390,1286,1287],{"class":400},"    } ",[390,1289,633],{"class":601},[390,1291,636],{"class":408},[390,1293,605],{"class":400},[390,1295,1296],{"class":392,"line":598},[390,1297,1298],{"class":462},"      // Widget disposé : ignorer\n",[390,1300,1301],{"class":392,"line":608},[390,1302,1303],{"class":400},"    }\n",[390,1305,1306],{"class":392,"line":627},[390,1307,1087],{"class":400},[390,1309,1310],{"class":392,"line":645},[390,1311,456],{"emptyLinePlaceholder":455},[390,1313,1314],{"class":392,"line":651},[390,1315,1316],{"class":396},"  @override\n",[390,1318,1319,1322,1325],{"class":392,"line":685},[390,1320,1321],{"class":396},"  void",[390,1323,1324],{"class":482}," dispose",[390,1326,1327],{"class":400},"() {\n",[390,1329,1331,1334,1337,1339,1341],{"class":392,"line":1330},19,[390,1332,1333],{"class":400},"    _fetchToken",[390,1335,1336],{"class":404},"?.",[390,1338,586],{"class":482},[390,1340,412],{"class":400},[390,1342,415],{"class":404},[390,1344,1346,1349,1351,1354,1356],{"class":392,"line":1345},20,[390,1347,1348],{"class":400},"    super",[390,1350,479],{"class":404},[390,1352,1353],{"class":482},"dispose",[390,1355,412],{"class":400},[390,1357,415],{"class":404},[390,1359,1361],{"class":392,"line":1360},21,[390,1362,1087],{"class":400},[390,1364,1366],{"class":392,"line":1365},22,[390,1367,688],{"class":400},[372,1369],{},[375,1371,1373,1374],{"id":1372},"api-canceltoken","API ",[351,1375,353],{},[1377,1378,1380],"h3",{"id":1379},"constructeur","Constructeur",[380,1382,1384],{"className":382,"code":1383,"language":385,"meta":386,"style":386},"CancelToken()\n",[351,1385,1386],{"__ignoreMap":386},[390,1387,1388,1390],{"class":392,"line":393},[390,1389,353],{"class":408},[390,1391,1392],{"class":400},"()\n",[1377,1394,1396],{"id":1395},"propriétés","Propriétés",[1398,1399,1400,1416],"table",{},[1401,1402,1403],"thead",{},[1404,1405,1406,1410,1413],"tr",{},[1407,1408,1409],"th",{},"Propriété",[1407,1411,1412],{},"Type",[1407,1414,1415],{},"Description",[1417,1418,1419],"tbody",{},[1404,1420,1421,1427,1432],{},[1422,1423,1424],"td",{},[351,1425,1426],{},"isCancelled",[1422,1428,1429],{},[351,1430,1431],{},"bool",[1422,1433,1434,1437,1438,479],{},[351,1435,1436],{},"true"," après l'appel à ",[351,1439,369],{},[1377,1441,1443],{"id":1442},"méthodes","Méthodes",[1398,1445,1446,1458],{},[1401,1447,1448],{},[1404,1449,1450,1453,1456],{},[1407,1451,1452],{},"Méthode",[1407,1454,1455],{},"Signature",[1407,1457,1415],{},[1417,1459,1460],{},[1404,1461,1462,1466,1470],{},[1422,1463,1464],{},[351,1465,369],{},[1422,1467,1468],{},[351,1469,1159],{},[1422,1471,1472],{},"Marque le token comme annulé. Idempotent et sûr à appeler plusieurs fois.",[372,1474],{},[375,1476,1478],{"id":1477},"qoracancelexception",[351,1479,697],{},[348,1481,1482,1483,1485,1486,1488,1489,479],{},"Levée par ",[351,1484,357],{}," et ",[351,1487,365],{}," quand un fetch est annulé via ",[351,1490,353],{},[380,1492,1494],{"className":382,"code":1493,"language":385,"meta":386,"style":386},"class QoraCancelException implements Exception {\n  final String key; // clé de requête normalisée encodée en JSON\n}\n",[351,1495,1496,1510,1526],{"__ignoreMap":386},[390,1497,1498,1500,1502,1505,1508],{"class":392,"line":393},[390,1499,1115],{"class":404},[390,1501,636],{"class":408},[390,1503,1504],{"class":404}," implements",[390,1506,1507],{"class":408}," Exception",[390,1509,605],{"class":400},[390,1511,1512,1514,1517,1520,1523],{"class":392,"line":452},[390,1513,611],{"class":396},[390,1515,1516],{"class":408}," String",[390,1518,1519],{"class":400}," key",[390,1521,1522],{"class":404},";",[390,1524,1525],{"class":462}," // clé de requête normalisée encodée en JSON\n",[390,1527,1528],{"class":392,"line":459},[390,1529,688],{"class":400},[1398,1531,1532,1542],{},[1401,1533,1534],{},[1404,1535,1536,1538,1540],{},[1407,1537,1409],{},[1407,1539,1412],{},[1407,1541,1415],{},[1417,1543,1544],{},[1404,1545,1546,1550,1555],{},[1422,1547,1548],{},[351,1549,672],{},[1422,1551,1552],{},[351,1553,1554],{},"String",[1422,1556,1557,1558],{},"La clé de requête encodée en chaîne, ex. ",[351,1559,1560],{},"'[\"users\",1]'",[372,1562],{},[375,1564,1566],{"id":1565},"hook-du-tracker","Hook du tracker",[348,1568,1569,1572,1573,1575],{},[351,1570,1571],{},"QoraTracker.onQueryCancelled(String key)"," est appelé chaque fois qu'un fetch est annulé via ",[351,1574,353],{},". L'implémenter sur un tracker personnalisé pour journaliser ou mesurer les taux d'annulation :",[380,1577,1580],{"className":382,"code":1578,"filename":1579,"language":385,"meta":386,"style":386},"class AnalyticsTracker extends NoOpTracker {\n  @override\n  void onQueryCancelled(String key) {\n    analytics.track('query_cancelled', {'key': key});\n  }\n}\n","analytics_tracker.dart",[351,1581,1582,1596,1600,1614,1644,1648],{"__ignoreMap":386},[390,1583,1584,1586,1589,1591,1594],{"class":392,"line":393},[390,1585,1115],{"class":404},[390,1587,1588],{"class":408}," AnalyticsTracker",[390,1590,1121],{"class":404},[390,1592,1593],{"class":408}," NoOpTracker",[390,1595,605],{"class":400},[390,1597,1598],{"class":392,"line":452},[390,1599,1316],{"class":396},[390,1601,1602,1604,1607,1609,1611],{"class":392,"line":459},[390,1603,1321],{"class":396},[390,1605,1606],{"class":482}," onQueryCancelled",[390,1608,657],{"class":400},[390,1610,1554],{"class":408},[390,1612,1613],{"class":400}," key) {\n",[390,1615,1616,1619,1621,1624,1626,1629,1631,1634,1637,1639,1642],{"class":392,"line":466},[390,1617,1618],{"class":400},"    analytics",[390,1620,479],{"class":404},[390,1622,1623],{"class":482},"track",[390,1625,657],{"class":400},[390,1627,1628],{"class":506},"'query_cancelled'",[390,1630,510],{"class":404},[390,1632,1633],{"class":400}," {",[390,1635,1636],{"class":506},"'key'",[390,1638,500],{"class":404},[390,1640,1641],{"class":400}," key})",[390,1643,415],{"class":404},[390,1645,1646],{"class":392,"line":494},[390,1647,1087],{"class":400},[390,1649,1650],{"class":392,"line":519},[390,1651,688],{"class":400},[372,1653],{},[375,1655,1657],{"id":1656},"voir-aussi","Voir aussi",[1659,1660,1661,1676],"ul",{},[1662,1663,1664,1669,1670,358,1672,358,1674],"li",{},[1665,1666,1668],"a",{"href":1667},"../api-reference/qora-client","API QoraClient"," : Signatures de ",[351,1671,357],{},[351,1673,361],{},[351,1675,365],{},[1662,1677,1678,1681],{},[1665,1679,1680],{"href":1667},"QoraTracker"," : Hooks d'observabilité",[1683,1684,1685],"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 .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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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}",{"title":386,"searchDepth":452,"depth":452,"links":1687},[1688,1689,1691,1693,1694,1695,1701,1702,1703],{"id":377,"depth":452,"text":378},{"id":426,"depth":452,"text":1690},"Annuler un fetchQuery",{"id":703,"depth":452,"text":1692},"Annuler un stream watchQuery",{"id":871,"depth":452,"text":872},{"id":1096,"depth":452,"text":1097},{"id":1372,"depth":452,"text":1696,"children":1697},"API CancelToken",[1698,1699,1700],{"id":1379,"depth":459,"text":1380},{"id":1395,"depth":459,"text":1396},{"id":1442,"depth":459,"text":1443},{"id":1477,"depth":452,"text":697},{"id":1565,"depth":452,"text":1566},{"id":1656,"depth":452,"text":1657},"Utiliser CancelToken pour interrompre coopérativement les fetchs en cours : lors de la navigation, d'un timeout ou d'une action utilisateur.","md",null,{},{"icon":175},{"title":172,"description":1704},"attbG6wTJxij4IdH_n1Z2T9nRHBUtgdGAldkx4grgao",[1712,1714],{"title":167,"path":168,"stem":169,"description":1713,"icon":170,"children":-1},"Utiliser QoraOptions.dependsOn pour chaîner les requêtes de sorte qu'une ne se déclenche qu'après la résolution d'une autre.",{"title":177,"path":178,"stem":179,"description":1715,"icon":180,"children":-1},"Éliminer le flash de chargement sur les pages Flutter Web rendues côté serveur en injectant le cache serveur dans QoraClient via SsrHydrator.",1794040408838]