[{"data":1,"prerenderedAt":2754},["ShallowReactive",2],{"navigation_docs_fr":3,"-fr-core-concepts-queries":342,"-fr-core-concepts-queries-surround":2749},[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":52,"body":344,"description":2742,"extension":2743,"links":2744,"meta":2745,"navigation":2746,"path":53,"seo":2747,"stem":54,"__hash__":2748},"docs_fr/fr/02.core-concepts/1.queries.md",{"type":345,"value":346,"toc":2718},"minimark",[347,352,356,549,552,557,565,578,712,727,735,737,741,752,866,878,880,884,889,1065,1070,1072,1076,1082,1089,1160,1163,1207,1209,1216,1222,1497,1500,1531,1533,1540,1543,1620,1623,1625,1629,1637,1643,1645,1649,1659,1757,1759,1763,1766,1934,1936,1940,2380,2382,2385,2389,2537,2541,2684,2686,2690,2714],[348,349,351],"h2",{"id":350},"anatomie-dune-requête","Anatomie d'une requête",[353,354,355],"p",{},"Toute requête Qora est composée de trois éléments :",[357,358,364],"pre",{"className":359,"code":360,"filename":361,"language":362,"meta":363,"style":363},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","await client.fetchQuery\u003CUser>(\n  // 1. Clé de requête : identifiant unique pour cette donnée\n  key: ['users', userId],\n\n  // 2. Fetcher : fonction asynchrone qui retourne la donnée\n  fetcher: () => api.getUser(userId),\n\n  // 3. Options (optionnel) : configuration par requête\n  options: QoraOptions(\n    staleTime: Duration(minutes: 5),\n    retryCount: 3,\n  ),\n);\n","user_repository.dart","dart","",[365,366,367,398,405,430,437,443,470,475,481,495,520,533,541],"code",{"__ignoreMap":363},[368,369,372,376,380,384,388,391,395],"span",{"class":370,"line":371},"line",1,[368,373,375],{"class":374},"s7zQu","await",[368,377,379],{"class":378},"sTEyZ"," client",[368,381,383],{"class":382},"sMK4o",".",[368,385,387],{"class":386},"s2Zo4","fetchQuery",[368,389,390],{"class":378},"\u003C",[368,392,394],{"class":393},"sBMFI","User",[368,396,397],{"class":378},">(\n",[368,399,401],{"class":370,"line":400},2,[368,402,404],{"class":403},"sHwdD","  // 1. Clé de requête : identifiant unique pour cette donnée\n",[368,406,408,411,414,417,421,424,427],{"class":370,"line":407},3,[368,409,410],{"class":378},"  key",[368,412,413],{"class":382},":",[368,415,416],{"class":378}," [",[368,418,420],{"class":419},"sfazB","'users'",[368,422,423],{"class":382},",",[368,425,426],{"class":378}," userId]",[368,428,429],{"class":382},",\n",[368,431,433],{"class":370,"line":432},4,[368,434,436],{"emptyLinePlaceholder":435},true,"\n",[368,438,440],{"class":370,"line":439},5,[368,441,442],{"class":403},"  // 2. Fetcher : fonction asynchrone qui retourne la donnée\n",[368,444,446,449,451,454,457,460,462,465,468],{"class":370,"line":445},6,[368,447,448],{"class":378},"  fetcher",[368,450,413],{"class":382},[368,452,453],{"class":378}," () ",[368,455,456],{"class":382},"=>",[368,458,459],{"class":378}," api",[368,461,383],{"class":382},[368,463,464],{"class":386},"getUser",[368,466,467],{"class":378},"(userId)",[368,469,429],{"class":382},[368,471,473],{"class":370,"line":472},7,[368,474,436],{"emptyLinePlaceholder":435},[368,476,478],{"class":370,"line":477},8,[368,479,480],{"class":403},"  // 3. Options (optionnel) : configuration par requête\n",[368,482,484,487,489,492],{"class":370,"line":483},9,[368,485,486],{"class":378},"  options",[368,488,413],{"class":382},[368,490,491],{"class":393}," QoraOptions",[368,493,494],{"class":378},"(\n",[368,496,498,501,503,506,509,511,515,518],{"class":370,"line":497},10,[368,499,500],{"class":378},"    staleTime",[368,502,413],{"class":382},[368,504,505],{"class":393}," Duration",[368,507,508],{"class":378},"(minutes",[368,510,413],{"class":382},[368,512,514],{"class":513},"sbssI"," 5",[368,516,517],{"class":378},")",[368,519,429],{"class":382},[368,521,523,526,528,531],{"class":370,"line":522},11,[368,524,525],{"class":378},"    retryCount",[368,527,413],{"class":382},[368,529,530],{"class":513}," 3",[368,532,429],{"class":382},[368,534,536,539],{"class":370,"line":535},12,[368,537,538],{"class":378},"  )",[368,540,429],{"class":382},[368,542,544,546],{"class":370,"line":543},13,[368,545,517],{"class":378},[368,547,548],{"class":382},";\n",[550,551],"hr",{},[553,554,556],"h3",{"id":555},"_1-clé-de-requête","1. Clé de requête",[353,558,559,560,564],{},"La ",[561,562,563],"strong",{},"clé de requête"," identifie la donnée de façon unique dans le cache. Elle pilote :",[566,567,568,572,575],"ul",{},[569,570,571],"li",{},"Les recherches dans le cache (hit / miss)",[569,573,574],{},"La revalidation en arrière-plan",[569,576,577],{},"L'invalidation ciblée après les mutations",[357,579,582],{"className":359,"code":580,"filename":581,"language":362,"meta":363,"style":363},"// Segment unique\n['users']\n\n// Entité + ID\n['users', userId]\n\n// Entité + filtres (map imbriquée)\n['posts', {'status': 'published', 'page': page}]\n\n// Wrapper typé (sémantique identique)\nQoraKey.withId('users', userId)\nQoraKey.withFilter('posts', {'status': 'published'})\n","keys.dart",[365,583,584,589,599,603,608,619,623,628,658,662,667,686],{"__ignoreMap":363},[368,585,586],{"class":370,"line":371},[368,587,588],{"class":403},"// Segment unique\n",[368,590,591,594,596],{"class":370,"line":400},[368,592,593],{"class":378},"[",[368,595,420],{"class":419},[368,597,598],{"class":378},"]\n",[368,600,601],{"class":370,"line":407},[368,602,436],{"emptyLinePlaceholder":435},[368,604,605],{"class":370,"line":432},[368,606,607],{"class":403},"// Entité + ID\n",[368,609,610,612,614,616],{"class":370,"line":439},[368,611,593],{"class":378},[368,613,420],{"class":419},[368,615,423],{"class":382},[368,617,618],{"class":378}," userId]\n",[368,620,621],{"class":370,"line":445},[368,622,436],{"emptyLinePlaceholder":435},[368,624,625],{"class":370,"line":472},[368,626,627],{"class":403},"// Entité + filtres (map imbriquée)\n",[368,629,630,632,635,637,640,643,645,648,650,653,655],{"class":370,"line":477},[368,631,593],{"class":378},[368,633,634],{"class":419},"'posts'",[368,636,423],{"class":382},[368,638,639],{"class":378}," {",[368,641,642],{"class":419},"'status'",[368,644,413],{"class":382},[368,646,647],{"class":419}," 'published'",[368,649,423],{"class":382},[368,651,652],{"class":419}," 'page'",[368,654,413],{"class":382},[368,656,657],{"class":378}," page}]\n",[368,659,660],{"class":370,"line":483},[368,661,436],{"emptyLinePlaceholder":435},[368,663,664],{"class":370,"line":497},[368,665,666],{"class":403},"// Wrapper typé (sémantique identique)\n",[368,668,669,671,673,676,679,681,683],{"class":370,"line":522},[368,670,207],{"class":393},[368,672,383],{"class":382},[368,674,675],{"class":386},"withId",[368,677,678],{"class":378},"(",[368,680,420],{"class":419},[368,682,423],{"class":382},[368,684,685],{"class":378}," userId)\n",[368,687,688,690,692,695,697,699,701,703,705,707,709],{"class":370,"line":535},[368,689,207],{"class":393},[368,691,383],{"class":382},[368,693,694],{"class":386},"withFilter",[368,696,678],{"class":378},[368,698,634],{"class":419},[368,700,423],{"class":382},[368,702,639],{"class":378},[368,704,642],{"class":419},[368,706,413],{"class":382},[368,708,647],{"class":419},[368,710,711],{"class":378},"})\n",[713,714,715,716,719,720,723,724,726],"tip",{},"Les clés utilisent l'",[561,717,718],{},"égalité structurelle profonde",". ",[365,721,722],{},"['users', 1]"," et ",[365,725,722],{}," sont identiques même s'ils sont créés indépendamment.",[353,728,729,730,734],{},"Voir ",[731,732,57],"a",{"href":733},"./query-keys"," pour le guide complet.",[550,736],{},[553,738,740],{"id":739},"_2-fetcher","2. Fetcher",[353,742,743,744,747,748,751],{},"Le ",[561,745,746],{},"fetcher"," est toute ",[365,749,750],{},"Future\u003CT> Function()"," qui retourne la donnée :",[357,753,755],{"className":359,"code":754,"filename":361,"language":362,"meta":363,"style":363},"// Inline : cas simple\nfetcher: () => api.getUser(userId),\n\n// Closure asynchrone avec dépendances\nfetcher: () async {\n  final token = await authService.getToken();\n  return api.getUser(userId, token: token);\n},\n",[365,756,757,762,782,786,791,805,833,859],{"__ignoreMap":363},[368,758,759],{"class":370,"line":371},[368,760,761],{"class":403},"// Inline : cas simple\n",[368,763,764,766,768,770,772,774,776,778,780],{"class":370,"line":400},[368,765,746],{"class":378},[368,767,413],{"class":382},[368,769,453],{"class":378},[368,771,456],{"class":382},[368,773,459],{"class":378},[368,775,383],{"class":382},[368,777,464],{"class":386},[368,779,467],{"class":378},[368,781,429],{"class":382},[368,783,784],{"class":370,"line":407},[368,785,436],{"emptyLinePlaceholder":435},[368,787,788],{"class":370,"line":432},[368,789,790],{"class":403},"// Closure asynchrone avec dépendances\n",[368,792,793,795,797,799,802],{"class":370,"line":439},[368,794,746],{"class":378},[368,796,413],{"class":382},[368,798,453],{"class":378},[368,800,801],{"class":374},"async",[368,803,804],{"class":378}," {\n",[368,806,807,811,814,817,820,823,825,828,831],{"class":370,"line":445},[368,808,810],{"class":809},"spNyl","  final",[368,812,813],{"class":378}," token ",[368,815,816],{"class":382},"=",[368,818,819],{"class":374}," await",[368,821,822],{"class":378}," authService",[368,824,383],{"class":382},[368,826,827],{"class":386},"getToken",[368,829,830],{"class":378},"()",[368,832,548],{"class":382},[368,834,835,838,840,842,844,847,849,852,854,857],{"class":370,"line":472},[368,836,837],{"class":374},"  return",[368,839,459],{"class":378},[368,841,383],{"class":382},[368,843,464],{"class":386},[368,845,846],{"class":378},"(userId",[368,848,423],{"class":382},[368,850,851],{"class":378}," token",[368,853,413],{"class":382},[368,855,856],{"class":378}," token)",[368,858,548],{"class":382},[368,860,861,864],{"class":370,"line":477},[368,862,863],{"class":378},"}",[368,865,429],{"class":382},[867,868,869,870,873,874,877],"warning",{},"Le fetcher doit lever une exception en cas d'échec. Retourner ",[365,871,872],{},"null"," ou ignorer les erreurs empêche Qora de passer à l'état ",[365,875,876],{},"Failure"," et de déclencher les retries.",[550,879],{},[553,881,883],{"id":882},"_3-options","3. Options",[353,885,886,888],{},[365,887,215],{}," configure le cache, les retries et le polling par requête :",[357,890,892],{"className":359,"code":891,"filename":361,"language":362,"meta":363,"style":363},"options: QoraOptions(\n  // Fenêtre de fraîcheur (0 = toujours périmé)\n  staleTime: Duration(minutes: 5),\n\n  // Durée de rétention des données inutilisées en cache\n  gcTime: Duration(minutes: 10),\n\n  // Retry automatique en cas d'échec\n  retryCount: 3,\n  retryDelay: Duration(seconds: 1), // délai de base pour le backoff exponentiel\n\n  // Désactiver la requête conditionnellement\n  enabled: userId != null,\n\n  // Intervalle de polling (watchQuery uniquement)\n  refetchInterval: Duration(seconds: 30),\n)\n",[365,893,894,905,910,929,933,938,958,962,967,978,1002,1006,1011,1027,1032,1038,1059],{"__ignoreMap":363},[368,895,896,899,901,903],{"class":370,"line":371},[368,897,898],{"class":378},"options",[368,900,413],{"class":382},[368,902,491],{"class":393},[368,904,494],{"class":378},[368,906,907],{"class":370,"line":400},[368,908,909],{"class":403},"  // Fenêtre de fraîcheur (0 = toujours périmé)\n",[368,911,912,915,917,919,921,923,925,927],{"class":370,"line":407},[368,913,914],{"class":378},"  staleTime",[368,916,413],{"class":382},[368,918,505],{"class":393},[368,920,508],{"class":378},[368,922,413],{"class":382},[368,924,514],{"class":513},[368,926,517],{"class":378},[368,928,429],{"class":382},[368,930,931],{"class":370,"line":432},[368,932,436],{"emptyLinePlaceholder":435},[368,934,935],{"class":370,"line":439},[368,936,937],{"class":403},"  // Durée de rétention des données inutilisées en cache\n",[368,939,940,943,945,947,949,951,954,956],{"class":370,"line":445},[368,941,942],{"class":378},"  gcTime",[368,944,413],{"class":382},[368,946,505],{"class":393},[368,948,508],{"class":378},[368,950,413],{"class":382},[368,952,953],{"class":513}," 10",[368,955,517],{"class":378},[368,957,429],{"class":382},[368,959,960],{"class":370,"line":472},[368,961,436],{"emptyLinePlaceholder":435},[368,963,964],{"class":370,"line":477},[368,965,966],{"class":403},"  // Retry automatique en cas d'échec\n",[368,968,969,972,974,976],{"class":370,"line":483},[368,970,971],{"class":378},"  retryCount",[368,973,413],{"class":382},[368,975,530],{"class":513},[368,977,429],{"class":382},[368,979,980,983,985,987,990,992,995,997,999],{"class":370,"line":497},[368,981,982],{"class":378},"  retryDelay",[368,984,413],{"class":382},[368,986,505],{"class":393},[368,988,989],{"class":378},"(seconds",[368,991,413],{"class":382},[368,993,994],{"class":513}," 1",[368,996,517],{"class":378},[368,998,423],{"class":382},[368,1000,1001],{"class":403}," // délai de base pour le backoff exponentiel\n",[368,1003,1004],{"class":370,"line":522},[368,1005,436],{"emptyLinePlaceholder":435},[368,1007,1008],{"class":370,"line":535},[368,1009,1010],{"class":403},"  // Désactiver la requête conditionnellement\n",[368,1012,1013,1016,1018,1021,1024],{"class":370,"line":543},[368,1014,1015],{"class":378},"  enabled",[368,1017,413],{"class":382},[368,1019,1020],{"class":378}," userId ",[368,1022,1023],{"class":382},"!=",[368,1025,1026],{"class":382}," null,\n",[368,1028,1030],{"class":370,"line":1029},14,[368,1031,436],{"emptyLinePlaceholder":435},[368,1033,1035],{"class":370,"line":1034},15,[368,1036,1037],{"class":403},"  // Intervalle de polling (watchQuery uniquement)\n",[368,1039,1041,1044,1046,1048,1050,1052,1055,1057],{"class":370,"line":1040},16,[368,1042,1043],{"class":378},"  refetchInterval",[368,1045,413],{"class":382},[368,1047,505],{"class":393},[368,1049,989],{"class":378},[368,1051,413],{"class":382},[368,1053,1054],{"class":513}," 30",[368,1056,517],{"class":378},[368,1058,429],{"class":382},[368,1060,1062],{"class":370,"line":1061},17,[368,1063,1064],{"class":378},")\n",[353,1066,729,1067,1069],{},[731,1068,215],{"href":216}," pour la liste complète des champs.",[550,1071],{},[348,1073,1075],{"id":1074},"deux-modes-de-récupération","Deux modes de récupération",[553,1077,1079,1081],{"id":1078},"fetchquery-récupération-ponctuelle",[365,1080,387],{}," : récupération ponctuelle",[353,1083,1084,1085,1088],{},"Retourne un ",[365,1086,1087],{},"Future\u003CT>",". Adapté aux appels impératifs (appui sur un bouton, chargement de page) :",[357,1090,1092],{"className":359,"code":1091,"filename":361,"language":362,"meta":363,"style":363},"final user = await client.fetchQuery\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n);\n",[365,1093,1094,1118,1134,1154],{"__ignoreMap":363},[368,1095,1096,1099,1102,1104,1106,1108,1110,1112,1114,1116],{"class":370,"line":371},[368,1097,1098],{"class":809},"final",[368,1100,1101],{"class":378}," user ",[368,1103,816],{"class":382},[368,1105,819],{"class":374},[368,1107,379],{"class":378},[368,1109,383],{"class":382},[368,1111,387],{"class":386},[368,1113,390],{"class":378},[368,1115,394],{"class":393},[368,1117,397],{"class":378},[368,1119,1120,1122,1124,1126,1128,1130,1132],{"class":370,"line":400},[368,1121,410],{"class":378},[368,1123,413],{"class":382},[368,1125,416],{"class":378},[368,1127,420],{"class":419},[368,1129,423],{"class":382},[368,1131,426],{"class":378},[368,1133,429],{"class":382},[368,1135,1136,1138,1140,1142,1144,1146,1148,1150,1152],{"class":370,"line":407},[368,1137,448],{"class":378},[368,1139,413],{"class":382},[368,1141,453],{"class":378},[368,1143,456],{"class":382},[368,1145,459],{"class":378},[368,1147,383],{"class":382},[368,1149,464],{"class":386},[368,1151,467],{"class":378},[368,1153,429],{"class":382},[368,1155,1156,1158],{"class":370,"line":432},[368,1157,517],{"class":378},[368,1159,548],{"class":382},[353,1161,1162],{},"Comportement du cache :",[1164,1165,1166,1179],"table",{},[1167,1168,1169],"thead",{},[1170,1171,1172,1176],"tr",{},[1173,1174,1175],"th",{},"État",[1173,1177,1178],{},"Action",[1180,1181,1182,1191,1199],"tbody",{},[1170,1183,1184,1188],{},[1185,1186,1187],"td",{},"Frais (non périmé)",[1185,1189,1190],{},"Retourne les données en cache, pas d'appel réseau",[1170,1192,1193,1196],{},[1185,1194,1195],{},"Périmé",[1185,1197,1198],{},"Retourne les données périmées immédiatement, refetch en arrière-plan",[1170,1200,1201,1204],{},[1185,1202,1203],{},"Absent",[1185,1205,1206],{},"Fetch, attend et retourne le résultat",[550,1208],{},[553,1210,1212,1215],{"id":1211},"watchquery-stream-réactif",[365,1213,1214],{},"watchQuery"," : stream réactif",[353,1217,1084,1218,1221],{},[365,1219,1220],{},"Stream\u003CQoraState\u003CT>>",". Adapté aux liaisons UI :",[357,1223,1226],{"className":359,"code":1224,"filename":1225,"language":362,"meta":363,"style":363},"StreamBuilder\u003CQoraState\u003CUser>>(\n  stream: client.watchQuery\u003CUser>(\n    key: ['users', userId],\n    fetcher: () => api.getUser(userId),\n  ),\n  builder: (context, snapshot) {\n    return switch (snapshot.data) {\n      null || Initial()            => const SizedBox.shrink(),\n      Loading(:final previousData) => previousData != null\n          ? UserCard(previousData)\n          : const CircularProgressIndicator(),\n      Success(:final data)         => UserCard(data),\n      Failure(:final error)        => Text('Erreur : $error'),\n    };\n  },\n)\n","user_page.dart",[365,1227,1228,1244,1263,1280,1301,1307,1322,1338,1369,1393,1404,1418,1441,1479,1486,1493],{"__ignoreMap":363},[368,1229,1230,1233,1235,1237,1239,1241],{"class":370,"line":371},[368,1231,1232],{"class":393},"StreamBuilder",[368,1234,390],{"class":378},[368,1236,211],{"class":393},[368,1238,390],{"class":378},[368,1240,394],{"class":393},[368,1242,1243],{"class":378},">>(\n",[368,1245,1246,1249,1251,1253,1255,1257,1259,1261],{"class":370,"line":400},[368,1247,1248],{"class":378},"  stream",[368,1250,413],{"class":382},[368,1252,379],{"class":378},[368,1254,383],{"class":382},[368,1256,1214],{"class":386},[368,1258,390],{"class":378},[368,1260,394],{"class":393},[368,1262,397],{"class":378},[368,1264,1265,1268,1270,1272,1274,1276,1278],{"class":370,"line":407},[368,1266,1267],{"class":378},"    key",[368,1269,413],{"class":382},[368,1271,416],{"class":378},[368,1273,420],{"class":419},[368,1275,423],{"class":382},[368,1277,426],{"class":378},[368,1279,429],{"class":382},[368,1281,1282,1285,1287,1289,1291,1293,1295,1297,1299],{"class":370,"line":432},[368,1283,1284],{"class":378},"    fetcher",[368,1286,413],{"class":382},[368,1288,453],{"class":378},[368,1290,456],{"class":382},[368,1292,459],{"class":378},[368,1294,383],{"class":382},[368,1296,464],{"class":386},[368,1298,467],{"class":378},[368,1300,429],{"class":382},[368,1302,1303,1305],{"class":370,"line":439},[368,1304,538],{"class":378},[368,1306,429],{"class":382},[368,1308,1309,1312,1314,1317,1319],{"class":370,"line":445},[368,1310,1311],{"class":378},"  builder",[368,1313,413],{"class":382},[368,1315,1316],{"class":378}," (context",[368,1318,423],{"class":382},[368,1320,1321],{"class":378}," snapshot) {\n",[368,1323,1324,1327,1330,1333,1335],{"class":370,"line":472},[368,1325,1326],{"class":374},"    return",[368,1328,1329],{"class":374}," switch",[368,1331,1332],{"class":378}," (snapshot",[368,1334,383],{"class":382},[368,1336,1337],{"class":378},"data) {\n",[368,1339,1340,1343,1346,1349,1352,1354,1357,1360,1362,1365,1367],{"class":370,"line":477},[368,1341,1342],{"class":382},"      null",[368,1344,1345],{"class":382}," ||",[368,1347,1348],{"class":393}," Initial",[368,1350,1351],{"class":378},"()            ",[368,1353,456],{"class":382},[368,1355,1356],{"class":809}," const",[368,1358,1359],{"class":393}," SizedBox",[368,1361,383],{"class":382},[368,1363,1364],{"class":386},"shrink",[368,1366,830],{"class":378},[368,1368,429],{"class":382},[368,1370,1371,1374,1376,1378,1380,1383,1385,1388,1390],{"class":370,"line":483},[368,1372,1373],{"class":393},"      Loading",[368,1375,678],{"class":378},[368,1377,413],{"class":382},[368,1379,1098],{"class":809},[368,1381,1382],{"class":378}," previousData) ",[368,1384,456],{"class":382},[368,1386,1387],{"class":378}," previousData ",[368,1389,1023],{"class":382},[368,1391,1392],{"class":382}," null\n",[368,1394,1395,1398,1401],{"class":370,"line":497},[368,1396,1397],{"class":382},"          ?",[368,1399,1400],{"class":393}," UserCard",[368,1402,1403],{"class":378},"(previousData)\n",[368,1405,1406,1409,1411,1414,1416],{"class":370,"line":522},[368,1407,1408],{"class":382},"          :",[368,1410,1356],{"class":809},[368,1412,1413],{"class":393}," CircularProgressIndicator",[368,1415,830],{"class":378},[368,1417,429],{"class":382},[368,1419,1420,1423,1425,1427,1429,1432,1434,1436,1439],{"class":370,"line":535},[368,1421,1422],{"class":393},"      Success",[368,1424,678],{"class":378},[368,1426,413],{"class":382},[368,1428,1098],{"class":809},[368,1430,1431],{"class":378}," data)         ",[368,1433,456],{"class":382},[368,1435,1400],{"class":393},[368,1437,1438],{"class":378},"(data)",[368,1440,429],{"class":382},[368,1442,1443,1446,1448,1450,1452,1455,1457,1460,1462,1465,1468,1472,1475,1477],{"class":370,"line":543},[368,1444,1445],{"class":393},"      Failure",[368,1447,678],{"class":378},[368,1449,413],{"class":382},[368,1451,1098],{"class":809},[368,1453,1454],{"class":378}," error)        ",[368,1456,456],{"class":382},[368,1458,1459],{"class":393}," Text",[368,1461,678],{"class":378},[368,1463,1464],{"class":419},"'Erreur : ",[368,1466,1467],{"class":378},"$",[368,1469,1471],{"class":1470},"sHdIc","error",[368,1473,1474],{"class":419},"'",[368,1476,517],{"class":378},[368,1478,429],{"class":382},[368,1480,1481,1484],{"class":370,"line":1029},[368,1482,1483],{"class":378},"    }",[368,1485,548],{"class":382},[368,1487,1488,1491],{"class":370,"line":1034},[368,1489,1490],{"class":378},"  }",[368,1492,429],{"class":382},[368,1494,1495],{"class":370,"line":1040},[368,1496,1064],{"class":378},[353,1498,1499],{},"Le stream :",[566,1501,1502,1505,1511,1521,1528],{},[569,1503,1504],{},"Émet immédiatement l'état courant du cache lors de l'abonnement",[569,1506,1507,1508,517],{},"Déclenche un fetch automatique si les données sont absentes ou périmées (contrôlé par ",[365,1509,1510],{},"refetchOnMount",[569,1512,1513,1514,1517,1518],{},"Propage les mises à jour depuis toute source : fetch, ",[365,1515,1516],{},"setQueryData",", ",[365,1519,1520],{},"invalidate",[569,1522,1523,1524,1527],{},"Effectue un polling quand ",[365,1525,1526],{},"refetchInterval"," est défini et le stream est actif",[569,1529,1530],{},"Planifie le GC quand le dernier abonné se désabonne",[550,1532],{},[553,1534,1536,1539],{"id":1535},"prefetch-préchargement-en-arrière-plan",[365,1537,1538],{},"prefetch"," : préchargement en arrière-plan",[353,1541,1542],{},"Alimente le cache avant que l'utilisateur ne navigue vers un écran :",[357,1544,1547],{"className":359,"code":1545,"filename":1546,"language":362,"meta":363,"style":363},"// Au survol / tap probable\nonEnter: (_) => client.prefetch\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n),\n","user_list_page.dart",[365,1548,1549,1554,1578,1594,1614],{"__ignoreMap":363},[368,1550,1551],{"class":370,"line":371},[368,1552,1553],{"class":403},"// Au survol / tap probable\n",[368,1555,1556,1559,1561,1564,1566,1568,1570,1572,1574,1576],{"class":370,"line":400},[368,1557,1558],{"class":378},"onEnter",[368,1560,413],{"class":382},[368,1562,1563],{"class":378}," (_) ",[368,1565,456],{"class":382},[368,1567,379],{"class":378},[368,1569,383],{"class":382},[368,1571,1538],{"class":386},[368,1573,390],{"class":378},[368,1575,394],{"class":393},[368,1577,397],{"class":378},[368,1579,1580,1582,1584,1586,1588,1590,1592],{"class":370,"line":407},[368,1581,410],{"class":378},[368,1583,413],{"class":382},[368,1585,416],{"class":378},[368,1587,420],{"class":419},[368,1589,423],{"class":382},[368,1591,426],{"class":378},[368,1593,429],{"class":382},[368,1595,1596,1598,1600,1602,1604,1606,1608,1610,1612],{"class":370,"line":432},[368,1597,448],{"class":378},[368,1599,413],{"class":382},[368,1601,453],{"class":378},[368,1603,456],{"class":382},[368,1605,459],{"class":378},[368,1607,383],{"class":382},[368,1609,464],{"class":386},[368,1611,467],{"class":378},[368,1613,429],{"class":382},[368,1615,1616,1618],{"class":370,"line":439},[368,1617,517],{"class":378},[368,1619,429],{"class":382},[353,1621,1622],{},"Sans effet si les données sont déjà fraîches. Ne crée pas de stream.",[550,1624],{},[348,1626,1628],{"id":1627},"cycle-de-vie-dune-requête","Cycle de vie d'une requête",[357,1630,1635],{"className":1631,"code":1633,"language":1634,"meta":363},[1632],"language-text","[Initial]\n    │  premier watchQuery / fetchQuery\n    ▼\n[Loading(previousData: null)]\n    │  fetcher réussit\n    ▼\n[Success(data, updatedAt)]\n    │  staleTime écoulé → refetch en arrière-plan\n    ▼\n[Loading(previousData: data)]   ← données périmées visibles pendant le rechargement\n    │  fetcher réussit\n    ▼\n[Success(newData, updatedAt)]\n    │  staleTime écoulé → fetcher échoue après tous les retries\n    ▼\n[Failure(error, previousData: data)]  ← données précédentes toujours accessibles\n","text",[365,1636,1633],{"__ignoreMap":363},[353,1638,729,1639,1642],{},[731,1640,62],{"href":1641},"./query-states"," pour la documentation complète.",[550,1644],{},[348,1646,1648],{"id":1647},"invalidation","Invalidation",[353,1650,1651,1652,1654,1655,1658],{},"Marquer les requêtes comme périmées après une mutation. Les streams ",[365,1653,1214],{}," actifs passent immédiatement à ",[365,1656,1657],{},"Loading"," :",[357,1660,1663],{"className":359,"code":1661,"filename":1662,"language":362,"meta":363,"style":363},"// Après la création d'un post\nawait api.createPost(payload);\n\n// Invalider une clé exacte\nclient.invalidate(['posts', postId]);\n\n// Invalider toutes les requêtes posts\nclient.invalidateWhere((key) => key.firstOrNull == 'posts');\n","post_repository.dart",[365,1664,1665,1670,1686,1690,1695,1716,1720,1725],{"__ignoreMap":363},[368,1666,1667],{"class":370,"line":371},[368,1668,1669],{"class":403},"// Après la création d'un post\n",[368,1671,1672,1674,1676,1678,1681,1684],{"class":370,"line":400},[368,1673,375],{"class":374},[368,1675,459],{"class":378},[368,1677,383],{"class":382},[368,1679,1680],{"class":386},"createPost",[368,1682,1683],{"class":378},"(payload)",[368,1685,548],{"class":382},[368,1687,1688],{"class":370,"line":407},[368,1689,436],{"emptyLinePlaceholder":435},[368,1691,1692],{"class":370,"line":432},[368,1693,1694],{"class":403},"// Invalider une clé exacte\n",[368,1696,1697,1700,1702,1704,1707,1709,1711,1714],{"class":370,"line":439},[368,1698,1699],{"class":378},"client",[368,1701,383],{"class":382},[368,1703,1520],{"class":386},[368,1705,1706],{"class":378},"([",[368,1708,634],{"class":419},[368,1710,423],{"class":382},[368,1712,1713],{"class":378}," postId])",[368,1715,548],{"class":382},[368,1717,1718],{"class":370,"line":445},[368,1719,436],{"emptyLinePlaceholder":435},[368,1721,1722],{"class":370,"line":472},[368,1723,1724],{"class":403},"// Invalider toutes les requêtes posts\n",[368,1726,1727,1729,1731,1734,1737,1739,1742,1744,1747,1750,1753,1755],{"class":370,"line":477},[368,1728,1699],{"class":378},[368,1730,383],{"class":382},[368,1732,1733],{"class":386},"invalidateWhere",[368,1735,1736],{"class":378},"((key) ",[368,1738,456],{"class":382},[368,1740,1741],{"class":378}," key",[368,1743,383],{"class":382},[368,1745,1746],{"class":378},"firstOrNull ",[368,1748,1749],{"class":382},"==",[368,1751,1752],{"class":419}," 'posts'",[368,1754,517],{"class":378},[368,1756,548],{"class":382},[550,1758],{},[348,1760,1762],{"id":1761},"mises-à-jour-manuelles-du-cache","Mises à jour manuelles du cache",[353,1764,1765],{},"Injecter des données directement dans le cache. Tous les streams actifs reçoivent la mise à jour instantanément :",[357,1767,1769],{"className":359,"code":1768,"filename":361,"language":362,"meta":363,"style":363},"// Snapshot avant mise à jour (pour rollback)\nfinal snapshot = client.getQueryData\u003CUser>(['users', userId]);\n\n// Mise à jour optimiste : l'UI reflète le changement immédiatement\nclient.setQueryData(['users', userId], user.copyWith(name: 'Alice'));\n\ntry {\n  await api.updateUser(userId, payload);\n} catch (_) {\n  // Rollback en cas d'échec\n  client.restoreQueryData(['users', userId], snapshot);\n}\n",[365,1770,1771,1776,1808,1812,1817,1856,1860,1867,1888,1899,1904,1929],{"__ignoreMap":363},[368,1772,1773],{"class":370,"line":371},[368,1774,1775],{"class":403},"// Snapshot avant mise à jour (pour rollback)\n",[368,1777,1778,1780,1783,1785,1787,1789,1792,1794,1796,1799,1801,1803,1806],{"class":370,"line":400},[368,1779,1098],{"class":809},[368,1781,1782],{"class":378}," snapshot ",[368,1784,816],{"class":382},[368,1786,379],{"class":378},[368,1788,383],{"class":382},[368,1790,1791],{"class":386},"getQueryData",[368,1793,390],{"class":378},[368,1795,394],{"class":393},[368,1797,1798],{"class":378},">([",[368,1800,420],{"class":419},[368,1802,423],{"class":382},[368,1804,1805],{"class":378}," userId])",[368,1807,548],{"class":382},[368,1809,1810],{"class":370,"line":407},[368,1811,436],{"emptyLinePlaceholder":435},[368,1813,1814],{"class":370,"line":432},[368,1815,1816],{"class":403},"// Mise à jour optimiste : l'UI reflète le changement immédiatement\n",[368,1818,1819,1821,1823,1825,1827,1829,1831,1833,1835,1838,1840,1843,1846,1848,1851,1854],{"class":370,"line":439},[368,1820,1699],{"class":378},[368,1822,383],{"class":382},[368,1824,1516],{"class":386},[368,1826,1706],{"class":378},[368,1828,420],{"class":419},[368,1830,423],{"class":382},[368,1832,426],{"class":378},[368,1834,423],{"class":382},[368,1836,1837],{"class":378}," user",[368,1839,383],{"class":382},[368,1841,1842],{"class":386},"copyWith",[368,1844,1845],{"class":378},"(name",[368,1847,413],{"class":382},[368,1849,1850],{"class":419}," 'Alice'",[368,1852,1853],{"class":378},"))",[368,1855,548],{"class":382},[368,1857,1858],{"class":370,"line":445},[368,1859,436],{"emptyLinePlaceholder":435},[368,1861,1862,1865],{"class":370,"line":472},[368,1863,1864],{"class":374},"try",[368,1866,804],{"class":378},[368,1868,1869,1872,1874,1876,1879,1881,1883,1886],{"class":370,"line":477},[368,1870,1871],{"class":374},"  await",[368,1873,459],{"class":378},[368,1875,383],{"class":382},[368,1877,1878],{"class":386},"updateUser",[368,1880,846],{"class":378},[368,1882,423],{"class":382},[368,1884,1885],{"class":378}," payload)",[368,1887,548],{"class":382},[368,1889,1890,1893,1896],{"class":370,"line":483},[368,1891,1892],{"class":378},"} ",[368,1894,1895],{"class":374},"catch",[368,1897,1898],{"class":378}," (_) {\n",[368,1900,1901],{"class":370,"line":497},[368,1902,1903],{"class":403},"  // Rollback en cas d'échec\n",[368,1905,1906,1909,1911,1914,1916,1918,1920,1922,1924,1927],{"class":370,"line":522},[368,1907,1908],{"class":378},"  client",[368,1910,383],{"class":382},[368,1912,1913],{"class":386},"restoreQueryData",[368,1915,1706],{"class":378},[368,1917,420],{"class":419},[368,1919,423],{"class":382},[368,1921,426],{"class":378},[368,1923,423],{"class":382},[368,1925,1926],{"class":378}," snapshot)",[368,1928,548],{"class":382},[368,1930,1931],{"class":370,"line":535},[368,1932,1933],{"class":378},"}\n",[550,1935],{},[348,1937,1939],{"id":1938},"exemple-complet","Exemple complet",[357,1941,1944],{"className":359,"code":1942,"filename":1943,"language":362,"meta":363,"style":363},"import 'package:qora/qora.dart';\n\nclass UserRepository {\n  final QoraClient _client;\n  final UserApi _api;\n\n  UserRepository(this._client, this._api);\n\n  Future\u003CUser> getUser(int userId) => _client.fetchQuery\u003CUser>(\n        key: ['users', userId],\n        fetcher: () => _api.getUser(userId),\n        options: const QoraOptions(staleTime: Duration(minutes: 5)),\n      );\n\n  Stream\u003CQoraState\u003CUser>> watchUser(int userId) => _client.watchQuery\u003CUser>(\n        key: ['users', userId],\n        fetcher: () => _api.getUser(userId),\n        options: const QoraOptions(\n          staleTime: Duration(minutes: 5),\n          refetchInterval: Duration(minutes: 1),\n        ),\n      );\n\n  void invalidateUser(int userId) => _client.invalidate(['users', userId]);\n\n  void patchLocally(User updated) =>\n      _client.setQueryData(['users', updated.id], updated);\n}\n","repositories/user_repository.dart",[365,1945,1946,1956,1960,1970,1982,1994,1998,2023,2027,2063,2080,2101,2129,2136,2140,2179,2195,2215,2228,2248,2268,2276,2283,2288,2321,2326,2344,2375],{"__ignoreMap":363},[368,1947,1948,1951,1954],{"class":370,"line":371},[368,1949,1950],{"class":513},"import",[368,1952,1953],{"class":419}," 'package:qora/qora.dart'",[368,1955,548],{"class":382},[368,1957,1958],{"class":370,"line":400},[368,1959,436],{"emptyLinePlaceholder":435},[368,1961,1962,1965,1968],{"class":370,"line":407},[368,1963,1964],{"class":382},"class",[368,1966,1967],{"class":393}," UserRepository",[368,1969,804],{"class":378},[368,1971,1972,1974,1977,1980],{"class":370,"line":432},[368,1973,810],{"class":809},[368,1975,1976],{"class":393}," QoraClient",[368,1978,1979],{"class":378}," _client",[368,1981,548],{"class":382},[368,1983,1984,1986,1989,1992],{"class":370,"line":439},[368,1985,810],{"class":809},[368,1987,1988],{"class":393}," UserApi",[368,1990,1991],{"class":378}," _api",[368,1993,548],{"class":382},[368,1995,1996],{"class":370,"line":445},[368,1997,436],{"emptyLinePlaceholder":435},[368,1999,2000,2003,2006,2008,2011,2013,2016,2018,2021],{"class":370,"line":472},[368,2001,2002],{"class":393},"  UserRepository",[368,2004,2005],{"class":378},"(this",[368,2007,383],{"class":382},[368,2009,2010],{"class":378},"_client",[368,2012,423],{"class":382},[368,2014,2015],{"class":378}," this",[368,2017,383],{"class":382},[368,2019,2020],{"class":378},"_api)",[368,2022,548],{"class":382},[368,2024,2025],{"class":370,"line":477},[368,2026,436],{"emptyLinePlaceholder":435},[368,2028,2029,2032,2034,2036,2039,2041,2043,2046,2049,2051,2053,2055,2057,2059,2061],{"class":370,"line":483},[368,2030,2031],{"class":393},"  Future",[368,2033,390],{"class":378},[368,2035,394],{"class":393},[368,2037,2038],{"class":378},"> ",[368,2040,464],{"class":386},[368,2042,678],{"class":378},[368,2044,2045],{"class":393},"int",[368,2047,2048],{"class":378}," userId) ",[368,2050,456],{"class":382},[368,2052,1979],{"class":378},[368,2054,383],{"class":382},[368,2056,387],{"class":386},[368,2058,390],{"class":378},[368,2060,394],{"class":393},[368,2062,397],{"class":378},[368,2064,2065,2068,2070,2072,2074,2076,2078],{"class":370,"line":497},[368,2066,2067],{"class":378},"        key",[368,2069,413],{"class":382},[368,2071,416],{"class":378},[368,2073,420],{"class":419},[368,2075,423],{"class":382},[368,2077,426],{"class":378},[368,2079,429],{"class":382},[368,2081,2082,2085,2087,2089,2091,2093,2095,2097,2099],{"class":370,"line":522},[368,2083,2084],{"class":378},"        fetcher",[368,2086,413],{"class":382},[368,2088,453],{"class":378},[368,2090,456],{"class":382},[368,2092,1991],{"class":378},[368,2094,383],{"class":382},[368,2096,464],{"class":386},[368,2098,467],{"class":378},[368,2100,429],{"class":382},[368,2102,2103,2106,2108,2110,2112,2115,2117,2119,2121,2123,2125,2127],{"class":370,"line":535},[368,2104,2105],{"class":378},"        options",[368,2107,413],{"class":382},[368,2109,1356],{"class":809},[368,2111,491],{"class":393},[368,2113,2114],{"class":378},"(staleTime",[368,2116,413],{"class":382},[368,2118,505],{"class":393},[368,2120,508],{"class":378},[368,2122,413],{"class":382},[368,2124,514],{"class":513},[368,2126,1853],{"class":378},[368,2128,429],{"class":382},[368,2130,2131,2134],{"class":370,"line":543},[368,2132,2133],{"class":378},"      )",[368,2135,548],{"class":382},[368,2137,2138],{"class":370,"line":1029},[368,2139,436],{"emptyLinePlaceholder":435},[368,2141,2142,2145,2147,2149,2151,2153,2156,2159,2161,2163,2165,2167,2169,2171,2173,2175,2177],{"class":370,"line":1034},[368,2143,2144],{"class":393},"  Stream",[368,2146,390],{"class":378},[368,2148,211],{"class":393},[368,2150,390],{"class":378},[368,2152,394],{"class":393},[368,2154,2155],{"class":378},">> ",[368,2157,2158],{"class":386},"watchUser",[368,2160,678],{"class":378},[368,2162,2045],{"class":393},[368,2164,2048],{"class":378},[368,2166,456],{"class":382},[368,2168,1979],{"class":378},[368,2170,383],{"class":382},[368,2172,1214],{"class":386},[368,2174,390],{"class":378},[368,2176,394],{"class":393},[368,2178,397],{"class":378},[368,2180,2181,2183,2185,2187,2189,2191,2193],{"class":370,"line":1040},[368,2182,2067],{"class":378},[368,2184,413],{"class":382},[368,2186,416],{"class":378},[368,2188,420],{"class":419},[368,2190,423],{"class":382},[368,2192,426],{"class":378},[368,2194,429],{"class":382},[368,2196,2197,2199,2201,2203,2205,2207,2209,2211,2213],{"class":370,"line":1061},[368,2198,2084],{"class":378},[368,2200,413],{"class":382},[368,2202,453],{"class":378},[368,2204,456],{"class":382},[368,2206,1991],{"class":378},[368,2208,383],{"class":382},[368,2210,464],{"class":386},[368,2212,467],{"class":378},[368,2214,429],{"class":382},[368,2216,2218,2220,2222,2224,2226],{"class":370,"line":2217},18,[368,2219,2105],{"class":378},[368,2221,413],{"class":382},[368,2223,1356],{"class":809},[368,2225,491],{"class":393},[368,2227,494],{"class":378},[368,2229,2231,2234,2236,2238,2240,2242,2244,2246],{"class":370,"line":2230},19,[368,2232,2233],{"class":378},"          staleTime",[368,2235,413],{"class":382},[368,2237,505],{"class":393},[368,2239,508],{"class":378},[368,2241,413],{"class":382},[368,2243,514],{"class":513},[368,2245,517],{"class":378},[368,2247,429],{"class":382},[368,2249,2251,2254,2256,2258,2260,2262,2264,2266],{"class":370,"line":2250},20,[368,2252,2253],{"class":378},"          refetchInterval",[368,2255,413],{"class":382},[368,2257,505],{"class":393},[368,2259,508],{"class":378},[368,2261,413],{"class":382},[368,2263,994],{"class":513},[368,2265,517],{"class":378},[368,2267,429],{"class":382},[368,2269,2271,2274],{"class":370,"line":2270},21,[368,2272,2273],{"class":378},"        )",[368,2275,429],{"class":382},[368,2277,2279,2281],{"class":370,"line":2278},22,[368,2280,2133],{"class":378},[368,2282,548],{"class":382},[368,2284,2286],{"class":370,"line":2285},23,[368,2287,436],{"emptyLinePlaceholder":435},[368,2289,2291,2294,2297,2299,2301,2303,2305,2307,2309,2311,2313,2315,2317,2319],{"class":370,"line":2290},24,[368,2292,2293],{"class":809},"  void",[368,2295,2296],{"class":386}," invalidateUser",[368,2298,678],{"class":378},[368,2300,2045],{"class":393},[368,2302,2048],{"class":378},[368,2304,456],{"class":382},[368,2306,1979],{"class":378},[368,2308,383],{"class":382},[368,2310,1520],{"class":386},[368,2312,1706],{"class":378},[368,2314,420],{"class":419},[368,2316,423],{"class":382},[368,2318,1805],{"class":378},[368,2320,548],{"class":382},[368,2322,2324],{"class":370,"line":2323},25,[368,2325,436],{"emptyLinePlaceholder":435},[368,2327,2329,2331,2334,2336,2338,2341],{"class":370,"line":2328},26,[368,2330,2293],{"class":809},[368,2332,2333],{"class":386}," patchLocally",[368,2335,678],{"class":378},[368,2337,394],{"class":393},[368,2339,2340],{"class":378}," updated) ",[368,2342,2343],{"class":382},"=>\n",[368,2345,2347,2350,2352,2354,2356,2358,2360,2363,2365,2368,2370,2373],{"class":370,"line":2346},27,[368,2348,2349],{"class":378},"      _client",[368,2351,383],{"class":382},[368,2353,1516],{"class":386},[368,2355,1706],{"class":378},[368,2357,420],{"class":419},[368,2359,423],{"class":382},[368,2361,2362],{"class":378}," updated",[368,2364,383],{"class":382},[368,2366,2367],{"class":378},"id]",[368,2369,423],{"class":382},[368,2371,2372],{"class":378}," updated)",[368,2374,548],{"class":382},[368,2376,2378],{"class":370,"line":2377},28,[368,2379,1933],{"class":378},[550,2381],{},[348,2383,133],{"id":2384},"bonnes-pratiques",[553,2386,2388],{"id":2387},"à-faire","À faire",[357,2390,2393],{"className":359,"code":2391,"filename":2392,"language":362,"meta":363,"style":363},"// Structure de clé cohérente : entité en premier, puis ID/filtres\n['users', userId]\n['posts', {'status': 'published', 'page': page}]\n\n// Toujours lever une exception : ne jamais retourner null\nfetcher: () => api.getUser(userId),\n\n// Traiter les quatre états de façon exhaustive\nswitch (state) {\n  case Initial():  ...\n  case Loading():  ...\n  case Success():  ...\n  case Failure():  ...\n}\n","main.dart",[365,2394,2395,2400,2410,2434,2438,2443,2463,2467,2472,2480,2494,2507,2520,2533],{"__ignoreMap":363},[368,2396,2397],{"class":370,"line":371},[368,2398,2399],{"class":403},"// Structure de clé cohérente : entité en premier, puis ID/filtres\n",[368,2401,2402,2404,2406,2408],{"class":370,"line":400},[368,2403,593],{"class":378},[368,2405,420],{"class":419},[368,2407,423],{"class":382},[368,2409,618],{"class":378},[368,2411,2412,2414,2416,2418,2420,2422,2424,2426,2428,2430,2432],{"class":370,"line":407},[368,2413,593],{"class":378},[368,2415,634],{"class":419},[368,2417,423],{"class":382},[368,2419,639],{"class":378},[368,2421,642],{"class":419},[368,2423,413],{"class":382},[368,2425,647],{"class":419},[368,2427,423],{"class":382},[368,2429,652],{"class":419},[368,2431,413],{"class":382},[368,2433,657],{"class":378},[368,2435,2436],{"class":370,"line":432},[368,2437,436],{"emptyLinePlaceholder":435},[368,2439,2440],{"class":370,"line":439},[368,2441,2442],{"class":403},"// Toujours lever une exception : ne jamais retourner null\n",[368,2444,2445,2447,2449,2451,2453,2455,2457,2459,2461],{"class":370,"line":445},[368,2446,746],{"class":378},[368,2448,413],{"class":382},[368,2450,453],{"class":378},[368,2452,456],{"class":382},[368,2454,459],{"class":378},[368,2456,383],{"class":382},[368,2458,464],{"class":386},[368,2460,467],{"class":378},[368,2462,429],{"class":382},[368,2464,2465],{"class":370,"line":472},[368,2466,436],{"emptyLinePlaceholder":435},[368,2468,2469],{"class":370,"line":477},[368,2470,2471],{"class":403},"// Traiter les quatre états de façon exhaustive\n",[368,2473,2474,2477],{"class":370,"line":483},[368,2475,2476],{"class":374},"switch",[368,2478,2479],{"class":378}," (state) {\n",[368,2481,2482,2485,2487,2489,2491],{"class":370,"line":497},[368,2483,2484],{"class":374},"  case",[368,2486,1348],{"class":393},[368,2488,830],{"class":378},[368,2490,413],{"class":382},[368,2492,2493],{"class":382},"  ...\n",[368,2495,2496,2498,2501,2503,2505],{"class":370,"line":522},[368,2497,2484],{"class":374},[368,2499,2500],{"class":393}," Loading",[368,2502,830],{"class":378},[368,2504,413],{"class":382},[368,2506,2493],{"class":382},[368,2508,2509,2511,2514,2516,2518],{"class":370,"line":535},[368,2510,2484],{"class":374},[368,2512,2513],{"class":393}," Success",[368,2515,830],{"class":378},[368,2517,413],{"class":382},[368,2519,2493],{"class":382},[368,2521,2522,2524,2527,2529,2531],{"class":370,"line":543},[368,2523,2484],{"class":374},[368,2525,2526],{"class":393}," Failure",[368,2528,830],{"class":378},[368,2530,413],{"class":382},[368,2532,2493],{"class":382},[368,2534,2535],{"class":370,"line":1029},[368,2536,1933],{"class":378},[553,2538,2540],{"id":2539},"à-éviter","À éviter",[357,2542,2544],{"className":359,"code":2543,"filename":2392,"language":362,"meta":363,"style":363},"// Ordre de clé incohérent\n['users', userId]\n[userId, 'users']  // Entrée de cache différente\n\n// Ignorer les erreurs\nfetcher: () async {\n  try { return await api.getUser(userId); }\n  catch (_) { return null; }  // Qora ne voit jamais l'échec\n},\n\n// Objets sans surcharge == dans les clés\n['users', UserFilter(status: 'active')]  // Toujours un cache miss\n",[365,2545,2546,2551,2561,2577,2581,2586,2598,2625,2644,2650,2654,2659],{"__ignoreMap":363},[368,2547,2548],{"class":370,"line":371},[368,2549,2550],{"class":403},"// Ordre de clé incohérent\n",[368,2552,2553,2555,2557,2559],{"class":370,"line":400},[368,2554,593],{"class":378},[368,2556,420],{"class":419},[368,2558,423],{"class":382},[368,2560,618],{"class":378},[368,2562,2563,2566,2568,2571,2574],{"class":370,"line":407},[368,2564,2565],{"class":378},"[userId",[368,2567,423],{"class":382},[368,2569,2570],{"class":419}," 'users'",[368,2572,2573],{"class":378},"]  ",[368,2575,2576],{"class":403},"// Entrée de cache différente\n",[368,2578,2579],{"class":370,"line":432},[368,2580,436],{"emptyLinePlaceholder":435},[368,2582,2583],{"class":370,"line":439},[368,2584,2585],{"class":403},"// Ignorer les erreurs\n",[368,2587,2588,2590,2592,2594,2596],{"class":370,"line":445},[368,2589,746],{"class":378},[368,2591,413],{"class":382},[368,2593,453],{"class":378},[368,2595,801],{"class":374},[368,2597,804],{"class":378},[368,2599,2600,2603,2606,2609,2611,2613,2615,2617,2619,2622],{"class":370,"line":472},[368,2601,2602],{"class":374},"  try",[368,2604,2605],{"class":378}," { ",[368,2607,2608],{"class":374},"return",[368,2610,819],{"class":374},[368,2612,459],{"class":378},[368,2614,383],{"class":382},[368,2616,464],{"class":386},[368,2618,467],{"class":378},[368,2620,2621],{"class":382},";",[368,2623,2624],{"class":378}," }\n",[368,2626,2627,2630,2633,2635,2638,2641],{"class":370,"line":477},[368,2628,2629],{"class":374},"  catch",[368,2631,2632],{"class":378}," (_) { ",[368,2634,2608],{"class":374},[368,2636,2637],{"class":382}," null;",[368,2639,2640],{"class":378}," }  ",[368,2642,2643],{"class":403},"// Qora ne voit jamais l'échec\n",[368,2645,2646,2648],{"class":370,"line":483},[368,2647,863],{"class":378},[368,2649,429],{"class":382},[368,2651,2652],{"class":370,"line":497},[368,2653,436],{"emptyLinePlaceholder":435},[368,2655,2656],{"class":370,"line":522},[368,2657,2658],{"class":403},"// Objets sans surcharge == dans les clés\n",[368,2660,2661,2663,2665,2667,2670,2673,2675,2678,2681],{"class":370,"line":535},[368,2662,593],{"class":378},[368,2664,420],{"class":419},[368,2666,423],{"class":382},[368,2668,2669],{"class":393}," UserFilter",[368,2671,2672],{"class":378},"(status",[368,2674,413],{"class":382},[368,2676,2677],{"class":419}," 'active'",[368,2679,2680],{"class":378},")]  ",[368,2682,2683],{"class":403},"// Toujours un cache miss\n",[550,2685],{},[348,2687,2689],{"id":2688},"étapes-suivantes","Étapes suivantes",[566,2691,2692,2697,2702,2708],{},[569,2693,2694,2696],{},[731,2695,57],{"href":733}," : Structure, égalité et patterns d'invalidation",[569,2698,2699,2701],{},[731,2700,62],{"href":1641}," : Exploration approfondie de la machine d'état scellée",[569,2703,2704,2707],{},[731,2705,67],{"href":2706},"./caching"," : LRU, stale time, GC et gestion du cache",[569,2709,2710,2713],{},[731,2711,72],{"href":2712},"./stale-while-revalidate"," : Fonctionnement de la revalidation en arrière-plan",[2715,2716,2717],"style",{},"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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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":363,"searchDepth":400,"depth":400,"links":2719},[2720,2725,2733,2734,2735,2736,2737,2741],{"id":350,"depth":400,"text":351,"children":2721},[2722,2723,2724],{"id":555,"depth":407,"text":556},{"id":739,"depth":407,"text":740},{"id":882,"depth":407,"text":883},{"id":1074,"depth":400,"text":1075,"children":2726},[2727,2729,2731],{"id":1078,"depth":407,"text":2728},"fetchQuery : récupération ponctuelle",{"id":1211,"depth":407,"text":2730},"watchQuery : stream réactif",{"id":1535,"depth":407,"text":2732},"prefetch : préchargement en arrière-plan",{"id":1627,"depth":400,"text":1628},{"id":1647,"depth":400,"text":1648},{"id":1761,"depth":400,"text":1762},{"id":1938,"depth":400,"text":1939},{"id":2384,"depth":400,"text":133,"children":2738},[2739,2740],{"id":2387,"depth":407,"text":2388},{"id":2539,"depth":407,"text":2540},{"id":2688,"depth":400,"text":2689},"Les requêtes sont le fondement de Qora. Une requête est une demande asynchrone liée à une clé, avec cache automatique, déduplication, retries et state réactif.","md",null,{},{"icon":55},{"title":52,"description":2742},"L4gzSSLQu6X42cl9sgU4MQM18vO3xGBVwWv0vxWY2l4",[2750,2752],{"title":40,"path":41,"stem":42,"description":2751,"icon":43,"children":-1},"Donner à Claude, Cursor, Copilot ou tout assistant de code le contexte nécessaire pour écrire du code Qora correct.",{"title":57,"path":58,"stem":59,"description":2753,"icon":60,"children":-1},"Les clés de requête sont le fondement du système de cache de Qora. Elles identifient les requêtes de façon unique et permettent la gestion automatique du cache, l'invalidation et le refetch.",1794040406842]