[{"data":1,"prerenderedAt":2233},["ShallowReactive",2],{"navigation_docs_fr":3,"-fr-examples-network-awareness":342,"-fr-examples-network-awareness-surround":2228},[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":315,"body":344,"description":2219,"extension":2220,"links":2221,"meta":2222,"navigation":2223,"path":316,"seo":2224,"stem":317,"__hash__":2227},"docs_fr/fr/08.examples/5.network-awareness.md",{"type":345,"value":346,"toc":2203},"minimark",[347,352,360,379,382,386,473,475,479,498,508,516,841,843,847,854,857,863,950,957,963,986,1546,1550,1561,1939,1960,1966,1969,2109,2112,2121,2123,2127,2133,2142,2144,2148,2199],[348,349,351],"h2",{"id":350},"objectif","Objectif",[353,354,355,359],"p",{},[356,357,358],"strong",{},"Contexte"," : Quand un appareil perd la connectivité, une implémentation naïve soit plante (exception réseau non capturée), soit gèle (spinner qui ne se résout jamais), soit abandonne silencieusement la dernière action de l'utilisateur (mutation perdue à jamais). Aucune de ces options n'est acceptable dans une app de production.",[353,361,362,363,366,367,370,371,374,375,378],{},"Cet exemple démontre la couche de conscience réseau de Qora : les requêtes se ",[356,364,365],{},"mettent automatiquement en pause"," hors ligne et ",[356,368,369],{},"rejouent"," à la reconnexion, les mutations sont ",[356,372,373],{},"mises en file"," et rejouées dans l'ordre FIFO, et le rejeu à la reconnexion utilise une ",[356,376,377],{},"concurrence contrôlée"," pour qu'un afflux soudain de requêtes en pause ne surcharge pas le serveur.",[380,381],"hr",{},[348,383,385],{"id":384},"fonctionnalités-démontrées","Fonctionnalités démontrées",[387,388,389,403,411,419,426,434,450,458],"ul",{},[390,391,392,398,399,402],"li",{},[356,393,394],{},[395,396,397],"code",{},"NetworkMode.online"," (défaut) : les requêtes se mettent en pause à ",[395,400,401],{},"FetchStatus.paused"," hors ligne ; rejouent automatiquement à la reconnexion",[390,404,405,410],{},[356,406,407],{},[395,408,409],{},"NetworkMode.offlineFirst"," : sert les données en cache immédiatement, planifie la revalidation en arrière-plan quand de retour en ligne",[390,412,413,418],{},[356,414,415],{},[395,416,417],{},"NetworkMode.always"," : contourne entièrement les vérifications de connectivité (pour les requêtes sauvegardées en base de données locale)",[390,420,421,425],{},[356,422,423],{},[395,424,401],{}," : expose l'état \"en attente de connexion\" à l'UI sans aucun booléen personnalisé",[390,427,428,433],{},[356,429,430],{},[395,431,432],{},"OfflineMutationQueue"," : file FIFO ; les mutations déclenchées hors ligne sont rejouées dans l'ordre à la reconnexion",[390,435,436,441,442,445,446,449],{},[356,437,438],{},[395,439,440],{},"ReconnectStrategy"," : ",[395,443,444],{},"maxConcurrent"," + ",[395,447,448],{},"jitter"," préviennent le thundering-herd quand des dizaines de requêtes reprennent simultanément",[390,451,452,457],{},[356,453,454],{},[395,455,456],{},"NetworkStatusIndicator"," : widget de bannière hors ligne automatique, zéro configuration",[390,459,460,465,466,469,470,472],{},[356,461,462],{},[395,463,464],{},"FlutterConnectivityManager"," : câble ",[395,467,468],{},"connectivity_plus"," dans ",[395,471,103],{}," en une seule ligne",[380,474],{},[348,476,478],{"id":477},"points-darchitecture","Points d'architecture",[353,480,481,482,485,486,489,490,493,494,497],{},"La conscience réseau est ",[356,483,484],{},"orthogonale"," à l'état des requêtes. Une requête peut être dans l'état ",[395,487,488],{},"Success"," (données visibles) pendant que ",[395,491,492],{},"FetchStatus"," est ",[395,495,496],{},"paused"," (connectivité perdue, revalidation en arrière-plan en attente). L'arbre de widgets n'est jamais bloqué : il a toujours quelque chose à rendre.",[499,500,506],"pre",{"className":501,"code":503,"language":504,"meta":505},[502],"language-text","main.dart\n└── QoraScope(\n      client: QoraClient(config: reconnectStrategy + networkMode)\n      connectivityManager: FlutterConnectivityManager()  ← branche connectivity_plus\n      lifecycleManager: FlutterLifecycleManager(...)     ← refetch à la reprise\n      child: NetworkStatusIndicator(                ← bannière hors ligne, zéro config\n        child: MyApp(),\n      ),\n    )\n","text","",[395,507,503],{"__ignoreMap":505},[353,509,510,512,513,515],{},[395,511,202],{}," est configuré avec une ",[395,514,440],{}," qui contrôle comment les requêtes en pause sont rejouées quand la connectivité revient :",[499,517,522],{"className":518,"code":519,"filename":520,"language":521,"meta":505,"style":505},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","final client = QoraClient(\n  config: QoraClientConfig(\n    defaultOptions: const QoraOptions(\n      networkMode: NetworkMode.online, // pause hors ligne, rejeu à la reconnexion\n      staleTime: Duration(minutes: 5),\n    ),\n    reconnectStrategy: const ReconnectStrategy(\n      maxConcurrent: 5, // rejouer 5 requêtes à la fois\n      jitter: Duration(milliseconds: 200), // délai aléatoire entre les lots\n    ),\n    debugMode: kDebugMode,\n  ),\n);\n\nrunApp(\n  QoraScope(\n    client: client,\n    connectivityManager: FlutterConnectivityManager(),\n    lifecycleManager:    FlutterLifecycleManager(qoraClient: client),\n    child: NetworkStatusIndicator(child: const MyApp()),\n  ),\n);\n","lib/main.dart","dart",[395,523,524,548,562,578,602,628,636,651,666,691,698,711,719,727,734,743,751,764,780,801,827,834],{"__ignoreMap":505},[525,526,529,533,537,541,545],"span",{"class":527,"line":528},"line",1,[525,530,532],{"class":531},"spNyl","final",[525,534,536],{"class":535},"sTEyZ"," client ",[525,538,540],{"class":539},"sMK4o","=",[525,542,544],{"class":543},"sBMFI"," QoraClient",[525,546,547],{"class":535},"(\n",[525,549,551,554,557,560],{"class":527,"line":550},2,[525,552,553],{"class":535},"  config",[525,555,556],{"class":539},":",[525,558,559],{"class":543}," QoraClientConfig",[525,561,547],{"class":535},[525,563,565,568,570,573,576],{"class":527,"line":564},3,[525,566,567],{"class":535},"    defaultOptions",[525,569,556],{"class":539},[525,571,572],{"class":531}," const",[525,574,575],{"class":543}," QoraOptions",[525,577,547],{"class":535},[525,579,581,584,586,589,592,595,598],{"class":527,"line":580},4,[525,582,583],{"class":535},"      networkMode",[525,585,556],{"class":539},[525,587,588],{"class":543}," NetworkMode",[525,590,591],{"class":539},".",[525,593,594],{"class":535},"online",[525,596,597],{"class":539},",",[525,599,601],{"class":600},"sHwdD"," // pause hors ligne, rejeu à la reconnexion\n",[525,603,605,608,610,613,616,618,622,625],{"class":527,"line":604},5,[525,606,607],{"class":535},"      staleTime",[525,609,556],{"class":539},[525,611,612],{"class":543}," Duration",[525,614,615],{"class":535},"(minutes",[525,617,556],{"class":539},[525,619,621],{"class":620},"sbssI"," 5",[525,623,624],{"class":535},")",[525,626,627],{"class":539},",\n",[525,629,631,634],{"class":527,"line":630},6,[525,632,633],{"class":535},"    )",[525,635,627],{"class":539},[525,637,639,642,644,646,649],{"class":527,"line":638},7,[525,640,641],{"class":535},"    reconnectStrategy",[525,643,556],{"class":539},[525,645,572],{"class":531},[525,647,648],{"class":543}," ReconnectStrategy",[525,650,547],{"class":535},[525,652,654,657,659,661,663],{"class":527,"line":653},8,[525,655,656],{"class":535},"      maxConcurrent",[525,658,556],{"class":539},[525,660,621],{"class":620},[525,662,597],{"class":539},[525,664,665],{"class":600}," // rejouer 5 requêtes à la fois\n",[525,667,669,672,674,676,679,681,684,686,688],{"class":527,"line":668},9,[525,670,671],{"class":535},"      jitter",[525,673,556],{"class":539},[525,675,612],{"class":543},[525,677,678],{"class":535},"(milliseconds",[525,680,556],{"class":539},[525,682,683],{"class":620}," 200",[525,685,624],{"class":535},[525,687,597],{"class":539},[525,689,690],{"class":600}," // délai aléatoire entre les lots\n",[525,692,694,696],{"class":527,"line":693},10,[525,695,633],{"class":535},[525,697,627],{"class":539},[525,699,701,704,706,709],{"class":527,"line":700},11,[525,702,703],{"class":535},"    debugMode",[525,705,556],{"class":539},[525,707,708],{"class":535}," kDebugMode",[525,710,627],{"class":539},[525,712,714,717],{"class":527,"line":713},12,[525,715,716],{"class":535},"  )",[525,718,627],{"class":539},[525,720,722,724],{"class":527,"line":721},13,[525,723,624],{"class":535},[525,725,726],{"class":539},";\n",[525,728,730],{"class":527,"line":729},14,[525,731,733],{"emptyLinePlaceholder":732},true,"\n",[525,735,737,741],{"class":527,"line":736},15,[525,738,740],{"class":739},"s2Zo4","runApp",[525,742,547],{"class":535},[525,744,746,749],{"class":527,"line":745},16,[525,747,748],{"class":543},"  QoraScope",[525,750,547],{"class":535},[525,752,754,757,759,762],{"class":527,"line":753},17,[525,755,756],{"class":535},"    client",[525,758,556],{"class":539},[525,760,761],{"class":535}," client",[525,763,627],{"class":539},[525,765,767,770,772,775,778],{"class":527,"line":766},18,[525,768,769],{"class":535},"    connectivityManager",[525,771,556],{"class":539},[525,773,774],{"class":543}," FlutterConnectivityManager",[525,776,777],{"class":535},"()",[525,779,627],{"class":539},[525,781,783,786,788,791,794,796,799],{"class":527,"line":782},19,[525,784,785],{"class":535},"    lifecycleManager",[525,787,556],{"class":539},[525,789,790],{"class":543},"    FlutterLifecycleManager",[525,792,793],{"class":535},"(qoraClient",[525,795,556],{"class":539},[525,797,798],{"class":535}," client)",[525,800,627],{"class":539},[525,802,804,807,809,812,815,817,819,822,825],{"class":527,"line":803},20,[525,805,806],{"class":535},"    child",[525,808,556],{"class":539},[525,810,811],{"class":543}," NetworkStatusIndicator",[525,813,814],{"class":535},"(child",[525,816,556],{"class":539},[525,818,572],{"class":531},[525,820,821],{"class":543}," MyApp",[525,823,824],{"class":535},"())",[525,826,627],{"class":539},[525,828,830,832],{"class":527,"line":829},21,[525,831,716],{"class":535},[525,833,627],{"class":539},[525,835,837,839],{"class":527,"line":836},22,[525,838,624],{"class":535},[525,840,726],{"class":539},[380,842],{},[348,844,846],{"id":845},"détails-dimplémentation","Détails d'implémentation",[848,849,851,853],"h3",{"id":850},"reconnectstrategy-prévention-du-thundering-herd",[395,852,440],{}," : prévention du thundering-herd",[353,855,856],{},"Considérez une app avec 20 requêtes actives sur 8 écrans. L'utilisateur prend le métro pendant 20 minutes : les 20 requêtes se mettent en pause. À la reconnexion, sans stratégie, 20 requêtes simultanées se déclenchent. Si 200 utilisateurs sortent de la même station de métro en même temps, le serveur reçoit 4 000 requêtes simultanées.",[353,858,859,862],{},[395,860,861],{},"ReconnectStrategy(maxConcurrent: 5, jitter: Duration(milliseconds: 200))"," étale le rejeu en lots de 5, avec un délai aléatoire (jusqu'à 200 ms) entre chaque lot :",[499,864,866],{"className":518,"code":865,"filename":520,"language":521,"meta":505,"style":505},"const ReconnectStrategy(\n  maxConcurrent: 5,\n  jitter: Duration(milliseconds: 200),\n)\n\n// Constructeurs nommés pour les configurations courantes :\nReconnectStrategy.instant() // tout à la fois : utile pour les tests\nReconnectStrategy.conservative() // maxConcurrent: 2, jitter: 500ms : économe en batterie\n",[395,867,868,877,888,907,912,916,921,936],{"__ignoreMap":505},[525,869,870,873,875],{"class":527,"line":528},[525,871,872],{"class":531},"const",[525,874,648],{"class":543},[525,876,547],{"class":535},[525,878,879,882,884,886],{"class":527,"line":550},[525,880,881],{"class":535},"  maxConcurrent",[525,883,556],{"class":539},[525,885,621],{"class":620},[525,887,627],{"class":539},[525,889,890,893,895,897,899,901,903,905],{"class":527,"line":564},[525,891,892],{"class":535},"  jitter",[525,894,556],{"class":539},[525,896,612],{"class":543},[525,898,678],{"class":535},[525,900,556],{"class":539},[525,902,683],{"class":620},[525,904,624],{"class":535},[525,906,627],{"class":539},[525,908,909],{"class":527,"line":580},[525,910,911],{"class":535},")\n",[525,913,914],{"class":527,"line":604},[525,915,733],{"emptyLinePlaceholder":732},[525,917,918],{"class":527,"line":630},[525,919,920],{"class":600},"// Constructeurs nommés pour les configurations courantes :\n",[525,922,923,925,927,930,933],{"class":527,"line":638},[525,924,440],{"class":543},[525,926,591],{"class":539},[525,928,929],{"class":739},"instant",[525,931,932],{"class":535},"() ",[525,934,935],{"class":600},"// tout à la fois : utile pour les tests\n",[525,937,938,940,942,945,947],{"class":527,"line":653},[525,939,440],{"class":543},[525,941,591],{"class":539},[525,943,944],{"class":739},"conservative",[525,946,932],{"class":535},[525,948,949],{"class":600},"// maxConcurrent: 2, jitter: 500ms : économe en batterie\n",[353,951,952,953,956],{},"Le jitter est ",[356,954,955],{},"aléatoire par instance de client"," : ainsi, même si 1 000 appareils se reconnectent simultanément, leurs fenêtres de rejeu sont réparties sur 200 ms, distribuant la charge.",[848,958,960,962],{"id":959},"fetchstatuspaused-état-ui-précis-sans-flags-personnalisés",[395,961,401],{}," : état UI précis sans flags personnalisés",[353,964,965,967,968,970,971,973,974,977,978,981,982,985],{},[395,966,108],{}," expose ",[395,969,492],{}," en tant que troisième argument du builder. ",[395,972,496],{}," signifie \"un fetch est en file mais attend la connectivité\", distinct de ",[395,975,976],{},"fetching"," (en cours d'exécution) et ",[395,979,980],{},"idle"," (rien en attente). Cela permet aux widgets de rendre un indicateur hors ligne précis sans un seul ",[395,983,984],{},"bool _isOffline"," :",[499,987,990],{"className":518,"code":988,"filename":989,"language":521,"meta":505,"style":505},"QoraBuilder\u003CList\u003CPost>>(\n  queryKey: const ['posts'],\n  fetcher: api.getPosts,\n  builder: (context, state, fetchStatus) {\n    return switch (state) {\n      // Premier chargement, hors ligne: rien à afficher encore\n      Initial() || Loading(previousData: null) when fetchStatus == FetchStatus.paused =>\n          const Center(\n            child: Column(\n              mainAxisAlignment: MainAxisAlignment.center,\n              children: [\n                Icon(Icons.wifi_off, size: 48, color: Colors.grey),\n                SizedBox(height: 12),\n                Text('Pas de connexion : connectez-vous pour charger les posts'),\n              ],\n            ),\n          ),\n\n      // Premier chargement, en ligne: spinner standard\n      Initial() || Loading(previousData: null) =>\n          const Center(child: CircularProgressIndicator()),\n\n      // Données disponibles: afficher le feed quelle que soit la connectivité\n      _ => Column(\n          children: [\n            // En pause: hors ligne mais données visibles\n            if (fetchStatus == FetchStatus.paused)\n              const _OfflineBanner(),\n            // En fetch : revalidation SWR en arrière-plan en cours\n            if (fetchStatus == FetchStatus.fetching)\n              const LinearProgressIndicator(minHeight: 2),\n            if (state is Failure\u003CList\u003CPost>>)\n              _ErrorBanner(error: state.error),\n            Expanded(child: PostList(posts: state.dataOrNull!)),\n          ],\n        ),\n    };\n  },\n)\n","lib/features/feed/ui/feed_screen.dart",[395,991,992,1010,1031,1048,1068,1080,1085,1129,1139,1151,1168,1178,1221,1238,1252,1259,1266,1273,1277,1282,1302,1319,1323,1329,1342,1352,1358,1376,1389,1395,1411,1431,1456,1476,1509,1517,1525,1533,1541],{"__ignoreMap":505},[525,993,994,996,999,1002,1004,1007],{"class":527,"line":528},[525,995,108],{"class":543},[525,997,998],{"class":535},"\u003C",[525,1000,1001],{"class":543},"List",[525,1003,998],{"class":535},[525,1005,1006],{"class":543},"Post",[525,1008,1009],{"class":535},">>(\n",[525,1011,1012,1015,1017,1019,1022,1026,1029],{"class":527,"line":550},[525,1013,1014],{"class":535},"  queryKey",[525,1016,556],{"class":539},[525,1018,572],{"class":531},[525,1020,1021],{"class":535}," [",[525,1023,1025],{"class":1024},"sfazB","'posts'",[525,1027,1028],{"class":535},"]",[525,1030,627],{"class":539},[525,1032,1033,1036,1038,1041,1043,1046],{"class":527,"line":564},[525,1034,1035],{"class":535},"  fetcher",[525,1037,556],{"class":539},[525,1039,1040],{"class":535}," api",[525,1042,591],{"class":539},[525,1044,1045],{"class":535},"getPosts",[525,1047,627],{"class":539},[525,1049,1050,1053,1055,1058,1060,1063,1065],{"class":527,"line":580},[525,1051,1052],{"class":535},"  builder",[525,1054,556],{"class":539},[525,1056,1057],{"class":535}," (context",[525,1059,597],{"class":539},[525,1061,1062],{"class":535}," state",[525,1064,597],{"class":539},[525,1066,1067],{"class":535}," fetchStatus) {\n",[525,1069,1070,1074,1077],{"class":527,"line":604},[525,1071,1073],{"class":1072},"s7zQu","    return",[525,1075,1076],{"class":1072}," switch",[525,1078,1079],{"class":535}," (state) {\n",[525,1081,1082],{"class":527,"line":630},[525,1083,1084],{"class":600},"      // Premier chargement, hors ligne: rien à afficher encore\n",[525,1086,1087,1090,1092,1095,1098,1101,1103,1106,1109,1112,1115,1118,1121,1123,1126],{"class":527,"line":638},[525,1088,1089],{"class":543},"      Initial",[525,1091,932],{"class":535},[525,1093,1094],{"class":539},"||",[525,1096,1097],{"class":543}," Loading",[525,1099,1100],{"class":535},"(previousData",[525,1102,556],{"class":539},[525,1104,1105],{"class":539}," null",[525,1107,1108],{"class":535},") ",[525,1110,1111],{"class":1072},"when",[525,1113,1114],{"class":535}," fetchStatus ",[525,1116,1117],{"class":539},"==",[525,1119,1120],{"class":543}," FetchStatus",[525,1122,591],{"class":539},[525,1124,1125],{"class":535},"paused ",[525,1127,1128],{"class":539},"=>\n",[525,1130,1131,1134,1137],{"class":527,"line":653},[525,1132,1133],{"class":531},"          const",[525,1135,1136],{"class":543}," Center",[525,1138,547],{"class":535},[525,1140,1141,1144,1146,1149],{"class":527,"line":668},[525,1142,1143],{"class":535},"            child",[525,1145,556],{"class":539},[525,1147,1148],{"class":543}," Column",[525,1150,547],{"class":535},[525,1152,1153,1156,1158,1161,1163,1166],{"class":527,"line":693},[525,1154,1155],{"class":535},"              mainAxisAlignment",[525,1157,556],{"class":539},[525,1159,1160],{"class":543}," MainAxisAlignment",[525,1162,591],{"class":539},[525,1164,1165],{"class":535},"center",[525,1167,627],{"class":539},[525,1169,1170,1173,1175],{"class":527,"line":700},[525,1171,1172],{"class":535},"              children",[525,1174,556],{"class":539},[525,1176,1177],{"class":535}," [\n",[525,1179,1180,1183,1186,1189,1191,1194,1196,1199,1201,1204,1206,1209,1211,1214,1216,1219],{"class":527,"line":713},[525,1181,1182],{"class":543},"                Icon",[525,1184,1185],{"class":535},"(",[525,1187,1188],{"class":543},"Icons",[525,1190,591],{"class":539},[525,1192,1193],{"class":535},"wifi_off",[525,1195,597],{"class":539},[525,1197,1198],{"class":535}," size",[525,1200,556],{"class":539},[525,1202,1203],{"class":620}," 48",[525,1205,597],{"class":539},[525,1207,1208],{"class":535}," color",[525,1210,556],{"class":539},[525,1212,1213],{"class":543}," Colors",[525,1215,591],{"class":539},[525,1217,1218],{"class":535},"grey)",[525,1220,627],{"class":539},[525,1222,1223,1226,1229,1231,1234,1236],{"class":527,"line":721},[525,1224,1225],{"class":543},"                SizedBox",[525,1227,1228],{"class":535},"(height",[525,1230,556],{"class":539},[525,1232,1233],{"class":620}," 12",[525,1235,624],{"class":535},[525,1237,627],{"class":539},[525,1239,1240,1243,1245,1248,1250],{"class":527,"line":729},[525,1241,1242],{"class":543},"                Text",[525,1244,1185],{"class":535},[525,1246,1247],{"class":1024},"'Pas de connexion : connectez-vous pour charger les posts'",[525,1249,624],{"class":535},[525,1251,627],{"class":539},[525,1253,1254,1257],{"class":527,"line":736},[525,1255,1256],{"class":535},"              ]",[525,1258,627],{"class":539},[525,1260,1261,1264],{"class":527,"line":745},[525,1262,1263],{"class":535},"            )",[525,1265,627],{"class":539},[525,1267,1268,1271],{"class":527,"line":753},[525,1269,1270],{"class":535},"          )",[525,1272,627],{"class":539},[525,1274,1275],{"class":527,"line":766},[525,1276,733],{"emptyLinePlaceholder":732},[525,1278,1279],{"class":527,"line":782},[525,1280,1281],{"class":600},"      // Premier chargement, en ligne: spinner standard\n",[525,1283,1284,1286,1288,1290,1292,1294,1296,1298,1300],{"class":527,"line":803},[525,1285,1089],{"class":543},[525,1287,932],{"class":535},[525,1289,1094],{"class":539},[525,1291,1097],{"class":543},[525,1293,1100],{"class":535},[525,1295,556],{"class":539},[525,1297,1105],{"class":539},[525,1299,1108],{"class":535},[525,1301,1128],{"class":539},[525,1303,1304,1306,1308,1310,1312,1315,1317],{"class":527,"line":829},[525,1305,1133],{"class":531},[525,1307,1136],{"class":543},[525,1309,814],{"class":535},[525,1311,556],{"class":539},[525,1313,1314],{"class":543}," CircularProgressIndicator",[525,1316,824],{"class":535},[525,1318,627],{"class":539},[525,1320,1321],{"class":527,"line":836},[525,1322,733],{"emptyLinePlaceholder":732},[525,1324,1326],{"class":527,"line":1325},23,[525,1327,1328],{"class":600},"      // Données disponibles: afficher le feed quelle que soit la connectivité\n",[525,1330,1332,1335,1338,1340],{"class":527,"line":1331},24,[525,1333,1334],{"class":535},"      _ ",[525,1336,1337],{"class":539},"=>",[525,1339,1148],{"class":543},[525,1341,547],{"class":535},[525,1343,1345,1348,1350],{"class":527,"line":1344},25,[525,1346,1347],{"class":535},"          children",[525,1349,556],{"class":539},[525,1351,1177],{"class":535},[525,1353,1355],{"class":527,"line":1354},26,[525,1356,1357],{"class":600},"            // En pause: hors ligne mais données visibles\n",[525,1359,1361,1364,1367,1369,1371,1373],{"class":527,"line":1360},27,[525,1362,1363],{"class":1072},"            if",[525,1365,1366],{"class":535}," (fetchStatus ",[525,1368,1117],{"class":539},[525,1370,1120],{"class":543},[525,1372,591],{"class":539},[525,1374,1375],{"class":535},"paused)\n",[525,1377,1379,1382,1385,1387],{"class":527,"line":1378},28,[525,1380,1381],{"class":531},"              const",[525,1383,1384],{"class":543}," _OfflineBanner",[525,1386,777],{"class":535},[525,1388,627],{"class":539},[525,1390,1392],{"class":527,"line":1391},29,[525,1393,1394],{"class":600},"            // En fetch : revalidation SWR en arrière-plan en cours\n",[525,1396,1398,1400,1402,1404,1406,1408],{"class":527,"line":1397},30,[525,1399,1363],{"class":1072},[525,1401,1366],{"class":535},[525,1403,1117],{"class":539},[525,1405,1120],{"class":543},[525,1407,591],{"class":539},[525,1409,1410],{"class":535},"fetching)\n",[525,1412,1414,1416,1419,1422,1424,1427,1429],{"class":527,"line":1413},31,[525,1415,1381],{"class":531},[525,1417,1418],{"class":543}," LinearProgressIndicator",[525,1420,1421],{"class":535},"(minHeight",[525,1423,556],{"class":539},[525,1425,1426],{"class":620}," 2",[525,1428,624],{"class":535},[525,1430,627],{"class":539},[525,1432,1434,1436,1439,1442,1445,1447,1449,1451,1453],{"class":527,"line":1433},32,[525,1435,1363],{"class":1072},[525,1437,1438],{"class":535}," (state ",[525,1440,1441],{"class":539},"is",[525,1443,1444],{"class":543}," Failure",[525,1446,998],{"class":535},[525,1448,1001],{"class":543},[525,1450,998],{"class":535},[525,1452,1006],{"class":543},[525,1454,1455],{"class":535},">>)\n",[525,1457,1459,1462,1465,1467,1469,1471,1474],{"class":527,"line":1458},33,[525,1460,1461],{"class":543},"              _ErrorBanner",[525,1463,1464],{"class":535},"(error",[525,1466,556],{"class":539},[525,1468,1062],{"class":535},[525,1470,591],{"class":539},[525,1472,1473],{"class":535},"error)",[525,1475,627],{"class":539},[525,1477,1479,1482,1484,1486,1489,1492,1494,1496,1498,1501,1504,1507],{"class":527,"line":1478},34,[525,1480,1481],{"class":543},"            Expanded",[525,1483,814],{"class":535},[525,1485,556],{"class":539},[525,1487,1488],{"class":543}," PostList",[525,1490,1491],{"class":535},"(posts",[525,1493,556],{"class":539},[525,1495,1062],{"class":535},[525,1497,591],{"class":539},[525,1499,1500],{"class":535},"dataOrNull",[525,1502,1503],{"class":539},"!",[525,1505,1506],{"class":535},"))",[525,1508,627],{"class":539},[525,1510,1512,1515],{"class":527,"line":1511},35,[525,1513,1514],{"class":535},"          ]",[525,1516,627],{"class":539},[525,1518,1520,1523],{"class":527,"line":1519},36,[525,1521,1522],{"class":535},"        )",[525,1524,627],{"class":539},[525,1526,1528,1531],{"class":527,"line":1527},37,[525,1529,1530],{"class":535},"    }",[525,1532,726],{"class":539},[525,1534,1536,1539],{"class":527,"line":1535},38,[525,1537,1538],{"class":535},"  }",[525,1540,627],{"class":539},[525,1542,1544],{"class":527,"line":1543},39,[525,1545,911],{"class":535},[848,1547,1549],{"id":1548},"file-de-mutations-hors-ligne-écrire-maintenant-synchroniser-plus-tard","File de mutations hors ligne : écrire maintenant, synchroniser plus tard",[353,1551,1552,1553,1556,1557,1560],{},"Les mutations déclenchées hors ligne sont mises en file et rejouées dans l'ordre FIFO à la reconnexion. Le flag ",[395,1554,1555],{},"isOptimistic"," sur ",[395,1558,1559],{},"MutationSuccess"," pilote un visuel \"synchronisation en attente\" pour que l'UI ne soit jamais trompeuse :",[499,1562,1565],{"className":518,"code":1563,"filename":1564,"language":521,"meta":505,"style":505},"QoraMutationBuilder\u003CPost, String, void>(\n  mutator: (content) => api.createPost(content),\n  options: MutationOptions(\n    offlineQueue: true,\n    optimisticResponse: (content) => Post.optimistic(content: content),\n    onSuccess: (_, __, ___) async =>\n        context.qora.invalidate(const ['posts']),\n  ),\n  builder: (context, state, mutate) {\n    final isQueued = state is MutationSuccess && state.isOptimistic;\n\n    return Column(\n      children: [\n        if (isQueued)\n          const _SyncPendingBanner(), // \"Se synchronisera quand en ligne\"\n        SubmitButton(\n          label: isQueued ? 'En file' : 'Publier',\n          icon: isQueued ? Icons.schedule : Icons.send,\n          onPressed: state.isPending ? null : () => mutate(_controller.text),\n        ),\n      ],\n    );\n  },\n)\n","lib/features/feed/ui/compose_screen.dart",[395,1566,1567,1589,1613,1625,1635,1664,1690,1718,1724,1741,1770,1774,1782,1791,1799,1813,1820,1842,1872,1910,1916,1923,1929,1935],{"__ignoreMap":505},[525,1568,1569,1571,1573,1575,1578,1581,1583,1586],{"class":527,"line":528},[525,1570,113],{"class":543},[525,1572,998],{"class":535},[525,1574,1006],{"class":543},[525,1576,1577],{"class":535},", ",[525,1579,1580],{"class":543},"String",[525,1582,1577],{"class":535},[525,1584,1585],{"class":531},"void",[525,1587,1588],{"class":535},">(\n",[525,1590,1591,1594,1596,1599,1601,1603,1605,1608,1611],{"class":527,"line":550},[525,1592,1593],{"class":535},"  mutator",[525,1595,556],{"class":539},[525,1597,1598],{"class":535}," (content) ",[525,1600,1337],{"class":539},[525,1602,1040],{"class":535},[525,1604,591],{"class":539},[525,1606,1607],{"class":739},"createPost",[525,1609,1610],{"class":535},"(content)",[525,1612,627],{"class":539},[525,1614,1615,1618,1620,1623],{"class":527,"line":564},[525,1616,1617],{"class":535},"  options",[525,1619,556],{"class":539},[525,1621,1622],{"class":543}," MutationOptions",[525,1624,547],{"class":535},[525,1626,1627,1630,1632],{"class":527,"line":580},[525,1628,1629],{"class":535},"    offlineQueue",[525,1631,556],{"class":539},[525,1633,1634],{"class":539}," true,\n",[525,1636,1637,1640,1642,1644,1646,1649,1651,1654,1657,1659,1662],{"class":527,"line":604},[525,1638,1639],{"class":535},"    optimisticResponse",[525,1641,556],{"class":539},[525,1643,1598],{"class":535},[525,1645,1337],{"class":539},[525,1647,1648],{"class":543}," Post",[525,1650,591],{"class":539},[525,1652,1653],{"class":739},"optimistic",[525,1655,1656],{"class":535},"(content",[525,1658,556],{"class":539},[525,1660,1661],{"class":535}," content)",[525,1663,627],{"class":539},[525,1665,1666,1669,1671,1674,1676,1679,1681,1684,1687],{"class":527,"line":630},[525,1667,1668],{"class":535},"    onSuccess",[525,1670,556],{"class":539},[525,1672,1673],{"class":535}," (_",[525,1675,597],{"class":539},[525,1677,1678],{"class":535}," __",[525,1680,597],{"class":539},[525,1682,1683],{"class":535}," ___) ",[525,1685,1686],{"class":1072},"async",[525,1688,1689],{"class":539}," =>\n",[525,1691,1692,1695,1697,1700,1702,1705,1707,1709,1711,1713,1716],{"class":527,"line":638},[525,1693,1694],{"class":535},"        context",[525,1696,591],{"class":539},[525,1698,1699],{"class":535},"qora",[525,1701,591],{"class":539},[525,1703,1704],{"class":739},"invalidate",[525,1706,1185],{"class":535},[525,1708,872],{"class":531},[525,1710,1021],{"class":535},[525,1712,1025],{"class":1024},[525,1714,1715],{"class":535},"])",[525,1717,627],{"class":539},[525,1719,1720,1722],{"class":527,"line":653},[525,1721,716],{"class":535},[525,1723,627],{"class":539},[525,1725,1726,1728,1730,1732,1734,1736,1738],{"class":527,"line":668},[525,1727,1052],{"class":535},[525,1729,556],{"class":539},[525,1731,1057],{"class":535},[525,1733,597],{"class":539},[525,1735,1062],{"class":535},[525,1737,597],{"class":539},[525,1739,1740],{"class":535}," mutate) {\n",[525,1742,1743,1746,1749,1751,1754,1756,1759,1762,1764,1766,1768],{"class":527,"line":693},[525,1744,1745],{"class":531},"    final",[525,1747,1748],{"class":535}," isQueued ",[525,1750,540],{"class":539},[525,1752,1753],{"class":535}," state ",[525,1755,1441],{"class":539},[525,1757,1758],{"class":543}," MutationSuccess",[525,1760,1761],{"class":539}," &&",[525,1763,1062],{"class":535},[525,1765,591],{"class":539},[525,1767,1555],{"class":535},[525,1769,726],{"class":539},[525,1771,1772],{"class":527,"line":700},[525,1773,733],{"emptyLinePlaceholder":732},[525,1775,1776,1778,1780],{"class":527,"line":713},[525,1777,1073],{"class":1072},[525,1779,1148],{"class":543},[525,1781,547],{"class":535},[525,1783,1784,1787,1789],{"class":527,"line":721},[525,1785,1786],{"class":535},"      children",[525,1788,556],{"class":539},[525,1790,1177],{"class":535},[525,1792,1793,1796],{"class":527,"line":729},[525,1794,1795],{"class":1072},"        if",[525,1797,1798],{"class":535}," (isQueued)\n",[525,1800,1801,1803,1806,1808,1810],{"class":527,"line":736},[525,1802,1133],{"class":531},[525,1804,1805],{"class":543}," _SyncPendingBanner",[525,1807,777],{"class":535},[525,1809,597],{"class":539},[525,1811,1812],{"class":600}," // \"Se synchronisera quand en ligne\"\n",[525,1814,1815,1818],{"class":527,"line":745},[525,1816,1817],{"class":543},"        SubmitButton",[525,1819,547],{"class":535},[525,1821,1822,1825,1827,1829,1832,1835,1837,1840],{"class":527,"line":753},[525,1823,1824],{"class":535},"          label",[525,1826,556],{"class":539},[525,1828,1748],{"class":535},[525,1830,1831],{"class":539},"?",[525,1833,1834],{"class":1024}," 'En file'",[525,1836,985],{"class":539},[525,1838,1839],{"class":1024}," 'Publier'",[525,1841,627],{"class":539},[525,1843,1844,1847,1849,1851,1853,1856,1858,1861,1863,1865,1867,1870],{"class":527,"line":766},[525,1845,1846],{"class":535},"          icon",[525,1848,556],{"class":539},[525,1850,1748],{"class":535},[525,1852,1831],{"class":539},[525,1854,1855],{"class":543}," Icons",[525,1857,591],{"class":539},[525,1859,1860],{"class":535},"schedule ",[525,1862,556],{"class":539},[525,1864,1855],{"class":543},[525,1866,591],{"class":539},[525,1868,1869],{"class":535},"send",[525,1871,627],{"class":539},[525,1873,1874,1877,1879,1881,1883,1886,1888,1890,1892,1895,1897,1900,1903,1905,1908],{"class":527,"line":782},[525,1875,1876],{"class":535},"          onPressed",[525,1878,556],{"class":539},[525,1880,1062],{"class":535},[525,1882,591],{"class":539},[525,1884,1885],{"class":535},"isPending ",[525,1887,1831],{"class":539},[525,1889,1105],{"class":539},[525,1891,985],{"class":539},[525,1893,1894],{"class":535}," () ",[525,1896,1337],{"class":539},[525,1898,1899],{"class":739}," mutate",[525,1901,1902],{"class":535},"(_controller",[525,1904,591],{"class":539},[525,1906,1907],{"class":535},"text)",[525,1909,627],{"class":539},[525,1911,1912,1914],{"class":527,"line":803},[525,1913,1522],{"class":535},[525,1915,627],{"class":539},[525,1917,1918,1921],{"class":527,"line":829},[525,1919,1920],{"class":535},"      ]",[525,1922,627],{"class":539},[525,1924,1925,1927],{"class":527,"line":836},[525,1926,633],{"class":535},[525,1928,726],{"class":539},[525,1930,1931,1933],{"class":527,"line":1325},[525,1932,1538],{"class":535},[525,1934,627],{"class":539},[525,1936,1937],{"class":527,"line":1331},[525,1938,911],{"class":535},[353,1940,1941,1942,1944,1945,1948,1949,1951,1952,1955,1956,1959],{},"À la reconnexion, ",[395,1943,202],{}," rejoue la file dans l'ordre FIFO automatiquement. Le callback ",[395,1946,1947],{},"onSuccess"," (qui appelle ",[395,1950,1704],{},") se déclenche uniquement pour les ",[356,1953,1954],{},"vraies"," confirmations serveur (",[395,1957,1958],{},"isOptimistic: false","), jamais pour l'écriture optimiste.",[848,1961,1963,1965],{"id":1962},"networkmodealways-pour-les-requêtes-de-base-de-données-locale",[395,1964,417],{}," pour les requêtes de base de données locale",[353,1967,1968],{},"Toutes les requêtes n'ont pas besoin de connectivité. Une requête sauvegardée par une boîte Hive locale ou SQLite ne doit jamais être mise en pause :",[499,1970,1973],{"className":518,"code":1971,"filename":1972,"language":521,"meta":505,"style":505},"QoraBuilder\u003CSettings>(\n  queryKey: const ['settings'],\n  fetcher: localDb.getSettings, // lit depuis Hive: pas de réseau nécessaire\n  options: const QoraOptions(\n    networkMode: NetworkMode.always, // ne se met jamais en pause, n'attend jamais la connectivité\n    staleTime: Duration(hours: 1),\n  ),\n  builder: (context, state, _) { /* ... */ },\n)\n","settings_screen.dart",[395,1974,1975,1986,2003,2022,2034,2053,2074,2080,2105],{"__ignoreMap":505},[525,1976,1977,1979,1981,1984],{"class":527,"line":528},[525,1978,108],{"class":543},[525,1980,998],{"class":535},[525,1982,1983],{"class":543},"Settings",[525,1985,1588],{"class":535},[525,1987,1988,1990,1992,1994,1996,1999,2001],{"class":527,"line":550},[525,1989,1014],{"class":535},[525,1991,556],{"class":539},[525,1993,572],{"class":531},[525,1995,1021],{"class":535},[525,1997,1998],{"class":1024},"'settings'",[525,2000,1028],{"class":535},[525,2002,627],{"class":539},[525,2004,2005,2007,2009,2012,2014,2017,2019],{"class":527,"line":564},[525,2006,1035],{"class":535},[525,2008,556],{"class":539},[525,2010,2011],{"class":535}," localDb",[525,2013,591],{"class":539},[525,2015,2016],{"class":535},"getSettings",[525,2018,597],{"class":539},[525,2020,2021],{"class":600}," // lit depuis Hive: pas de réseau nécessaire\n",[525,2023,2024,2026,2028,2030,2032],{"class":527,"line":580},[525,2025,1617],{"class":535},[525,2027,556],{"class":539},[525,2029,572],{"class":531},[525,2031,575],{"class":543},[525,2033,547],{"class":535},[525,2035,2036,2039,2041,2043,2045,2048,2050],{"class":527,"line":604},[525,2037,2038],{"class":535},"    networkMode",[525,2040,556],{"class":539},[525,2042,588],{"class":543},[525,2044,591],{"class":539},[525,2046,2047],{"class":535},"always",[525,2049,597],{"class":539},[525,2051,2052],{"class":600}," // ne se met jamais en pause, n'attend jamais la connectivité\n",[525,2054,2055,2058,2060,2062,2065,2067,2070,2072],{"class":527,"line":630},[525,2056,2057],{"class":535},"    staleTime",[525,2059,556],{"class":539},[525,2061,612],{"class":543},[525,2063,2064],{"class":535},"(hours",[525,2066,556],{"class":539},[525,2068,2069],{"class":620}," 1",[525,2071,624],{"class":535},[525,2073,627],{"class":539},[525,2075,2076,2078],{"class":527,"line":638},[525,2077,716],{"class":535},[525,2079,627],{"class":539},[525,2081,2082,2084,2086,2088,2090,2092,2094,2097,2100,2103],{"class":527,"line":653},[525,2083,1052],{"class":535},[525,2085,556],{"class":539},[525,2087,1057],{"class":535},[525,2089,597],{"class":539},[525,2091,1062],{"class":535},[525,2093,597],{"class":539},[525,2095,2096],{"class":535}," _) { ",[525,2098,2099],{"class":600},"/* ... */",[525,2101,2102],{"class":535}," }",[525,2104,627],{"class":539},[525,2106,2107],{"class":527,"line":668},[525,2108,911],{"class":535},[353,2110,2111],{},"Ce snippet ne fait pas partie de l'application d'exemple, qui ne parle qu'à une API distante.",[353,2113,2114,2115,2117,2118,2120],{},"Mélangez librement ",[395,2116,417],{}," (local) et ",[395,2119,397],{}," (distant) dans le même écran: Qora les gère indépendamment.",[380,2122],{},[348,2124,2126],{"id":2125},"code-source","Code source",[499,2128,2131],{"className":2129,"code":2130,"language":504,"meta":505},[502],"examples/ex_05_network_aware/\n├── lib/\n│   ├── main.dart                     ← QoraClient + ReconnectStrategy + QoraScope\n│   ├── features/\n│   │   └── feed/\n│   │       ├── data/feed_api.dart    ← couche HTTP\n│   │       ├── models/post.dart      ← modèle Post\n│   │       └── ui/\n│   │           ├── feed_screen.dart  ← gestion FetchStatus.paused\n│   │           └── compose_screen.dart ← OfflineMutationQueue + isOptimistic\n│   └── shared/\n│       ├── connectivity/simulated_connectivity_manager.dart ← bascule en ligne / hors-ligne pour la démo\n│       └── widgets/\n│           └── offline_banner.dart   ← bannière personnalisée autour de NetworkStatusIndicator\n└── pubspec.yaml\n",[395,2132,2130],{"__ignoreMap":505},[353,2134,2135],{},[2136,2137,2141],"a",{"href":2138,"rel":2139},"https://github.com/meragix/qora/tree/main/examples/ex_05_network_aware",[2140],"nofollow","Voir le code source complet",[380,2143],{},[348,2145,2147],{"id":2146},"voir-aussi","Voir aussi",[387,2149,2150,2168,2180,2187],{},[390,2151,2152,2156,2157,1577,2160,1577,2162,2164,2165,2167],{},[2136,2153,2155],{"href":2154},"../recipes/network-aware","Recette de conscience réseau",": ",[395,2158,2159],{},"NetworkMode",[395,2161,492],{},[395,2163,432],{}," et ",[395,2166,440],{}," en profondeur",[390,2169,2170,2174,2175,2164,2177],{},[2136,2171,2173],{"href":2172},"../flutter-integration/network-status","Statut réseau",": widgets ",[395,2176,456],{},[395,2178,2179],{},"NetworkStatusBuilder",[390,2181,2182,2186],{},[2136,2183,2185],{"href":2184},"./offline-first","Étude de cas Offline-First",": persistance entre redémarrages (préoccupation distincte de la conscience réseau)",[390,2188,2189,2156,2193,1577,2196],{},[2136,2190,2192],{"href":2191},"../api-reference/qora-options","API QoraOptions",[395,2194,2195],{},"networkMode",[395,2197,2198],{},"refetchOnReconnect",[2200,2201,2202],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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}",{"title":505,"searchDepth":550,"depth":550,"links":2204},[2205,2206,2207,2208,2217,2218],{"id":350,"depth":550,"text":351},{"id":384,"depth":550,"text":385},{"id":477,"depth":550,"text":478},{"id":845,"depth":550,"text":846,"children":2209},[2210,2212,2214,2215],{"id":850,"depth":564,"text":2211},"ReconnectStrategy : prévention du thundering-herd",{"id":959,"depth":564,"text":2213},"FetchStatus.paused : état UI précis sans flags personnalisés",{"id":1548,"depth":564,"text":1549},{"id":1962,"depth":564,"text":2216},"NetworkMode.always pour les requêtes de base de données locale",{"id":2125,"depth":550,"text":2126},{"id":2146,"depth":550,"text":2147},"Les requêtes se mettent automatiquement en pause hors ligne, les mutations se mettent en file pour plus tard, et tout rejoue à la reconnexion : avec prévention du thundering-herd intégrée.","md",null,{},{"icon":161},{"title":2225,"description":2226},"Étude de cas : Conscience réseau - Qora","Gestion offline/online de niveau production avec NetworkMode, FetchStatus, OfflineMutationQueue et ReconnectStrategy. Zéro intervention utilisateur à la reconnexion.","yXp3huj4KuFvLLrsq9E8uUySgjJ-WlEo3ozklYtGK9Q",[2229,2231],{"title":311,"path":312,"stem":313,"description":2230,"icon":90,"children":-1},"Une application de todos qui continue de fonctionner sans réseau : données sauvegardées au démarrage, requêtes en pause hors-ligne, écritures mises en file et rejouées dans l'ordre à la reconnexion.",{"title":319,"path":320,"stem":321,"description":2232,"icon":126,"children":-1},"Remplacer l'imbrication des builders QoraBuilder par des appels de hooks plats et composables : useQuery, useMutation, useInfiniteQuery et indicateurs de fetch globaux dans un HookWidget.",1794040411394]