[{"data":1,"prerenderedAt":1643},["ShallowReactive",2],{"navigation_docs_fr":3,"-fr-core-concepts-stale-while-revalidate":342,"-fr-core-concepts-stale-while-revalidate-surround":1638},[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":72,"body":344,"description":1631,"extension":1632,"links":1633,"meta":1634,"navigation":1635,"path":73,"seo":1636,"stem":74,"__hash__":1637},"docs_fr/fr/02.core-concepts/5.stale-while-revalidate.md",{"type":345,"value":346,"toc":1613},"minimark",[347,352,356,373,376,379,383,395,407,417,419,423,558,567,639,641,647,652,802,804,809,815,1192,1196,1202,1204,1208,1217,1308,1310,1314,1321,1441,1447,1449,1453,1456,1576,1578,1582,1609],[348,349,351],"h2",{"id":350},"le-problème-que-swr-résout","Le problème que SWR résout",[353,354,355],"p",{},"La récupération de données traditionnelle présente un arbitrage :",[357,358,359,367],"ul",{},[360,361,362,366],"li",{},[363,364,365],"strong",{},"Sans cache"," : les données sont toujours à jour, mais chaque navigation déclenche une requête réseau et affiche un spinner.",[360,368,369,372],{},[363,370,371],{},"Cache permanent"," : les réponses sont instantanées, mais les données deviennent périmées et l'UI reflète des informations obsolètes.",[353,374,375],{},"SWR (Stale-While-Revalidate) résout cet arbitrage.",[377,378],"hr",{},[348,380,382],{"id":381},"fonctionnement","Fonctionnement",[353,384,385,386,390,391,394],{},"Quand ",[387,388,389],"code",{},"fetchQuery"," ou ",[387,392,393],{},"watchQuery"," est appelé avec des données périmées en cache :",[396,397,398,401,404],"ol",{},[360,399,400],{},"Retourner les données périmées immédiatement. L'UI s'affiche sans spinner.",[360,402,403],{},"Déclencher une revalidation en arrière-plan. Le fetcher s'exécute silencieusement.",[360,405,406],{},"Mettre à jour le cache et tous les streams actifs quand les données fraîches arrivent.",[408,409,415],"pre",{"className":410,"code":412,"language":413,"meta":414},[411],"language-text","t=0:00  Success(user: Alice, updatedAt: 10:00)   ← staleTime : 5 min\nt=5:01  fetchQuery appelé\n         ├── retourne Alice immédiatement (données périmées)\n         └── déclenche un fetch en arrière-plan\nt=5:02  Success(user: Alice Martin, updatedAt: 10:05)   ← mis à jour\n         └── les streams watchQuery émettent le nouvel état\n","text","",[387,416,412],{"__ignoreMap":414},[377,418],{},[348,420,422],{"id":421},"configuration-du-stale-time","Configuration du stale time",[408,424,429],{"className":425,"code":426,"filename":427,"language":428,"meta":414,"style":414},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Défaut : Duration.zero : toujours périmé, revalide toujours\n// (sert quand même les données en cache instantanément à chaque appel)\noptions: QoraOptions(staleTime: Duration.zero),\n\n// Frais pendant 5 minutes : pas d'appel réseau dans la fenêtre\noptions: QoraOptions(staleTime: Duration(minutes: 5)),\n\n// Données de configuration : revalide uniquement toutes les heures\noptions: QoraOptions(staleTime: Duration(hours: 1)),\n","user_repository.dart","dart",[387,430,431,440,446,478,485,491,520,525,531],{"__ignoreMap":414},[432,433,436],"span",{"class":434,"line":435},"line",1,[432,437,439],{"class":438},"sHwdD","// Défaut : Duration.zero : toujours périmé, revalide toujours\n",[432,441,443],{"class":434,"line":442},2,[432,444,445],{"class":438},"// (sert quand même les données en cache instantanément à chaque appel)\n",[432,447,449,453,457,461,464,466,469,472,475],{"class":434,"line":448},3,[432,450,452],{"class":451},"sTEyZ","options",[432,454,456],{"class":455},"sMK4o",":",[432,458,460],{"class":459},"sBMFI"," QoraOptions",[432,462,463],{"class":451},"(staleTime",[432,465,456],{"class":455},[432,467,468],{"class":459}," Duration",[432,470,471],{"class":455},".",[432,473,474],{"class":451},"zero)",[432,476,477],{"class":455},",\n",[432,479,481],{"class":434,"line":480},4,[432,482,484],{"emptyLinePlaceholder":483},true,"\n",[432,486,488],{"class":434,"line":487},5,[432,489,490],{"class":438},"// Frais pendant 5 minutes : pas d'appel réseau dans la fenêtre\n",[432,492,494,496,498,500,502,504,506,509,511,515,518],{"class":434,"line":493},6,[432,495,452],{"class":451},[432,497,456],{"class":455},[432,499,460],{"class":459},[432,501,463],{"class":451},[432,503,456],{"class":455},[432,505,468],{"class":459},[432,507,508],{"class":451},"(minutes",[432,510,456],{"class":455},[432,512,514],{"class":513},"sbssI"," 5",[432,516,517],{"class":451},"))",[432,519,477],{"class":455},[432,521,523],{"class":434,"line":522},7,[432,524,484],{"emptyLinePlaceholder":483},[432,526,528],{"class":434,"line":527},8,[432,529,530],{"class":438},"// Données de configuration : revalide uniquement toutes les heures\n",[432,532,534,536,538,540,542,544,546,549,551,554,556],{"class":434,"line":533},9,[432,535,452],{"class":451},[432,537,456],{"class":455},[432,539,460],{"class":459},[432,541,463],{"class":451},[432,543,456],{"class":455},[432,545,468],{"class":459},[432,547,548],{"class":451},"(hours",[432,550,456],{"class":455},[432,552,553],{"class":513}," 1",[432,555,517],{"class":451},[432,557,477],{"class":455},[559,560,562,563,566],"h3",{"id":561},"choix-du-staletime-par-type-de-données","Choix du ",[387,564,565],{},"staleTime"," par type de données",[568,569,570,585],"table",{},[571,572,573],"thead",{},[574,575,576,580],"tr",{},[577,578,579],"th",{},"Type de données",[577,581,582,584],{},[387,583,565],{}," recommandé",[586,587,588,599,609,619,629],"tbody",{},[574,589,590,594],{},[591,592,593],"td",{},"Prix en direct, notifications",[591,595,596],{},[387,597,598],{},"Duration.zero",[574,600,601,604],{},[591,602,603],{},"Profil utilisateur, paramètres",[591,605,606],{},[387,607,608],{},"Duration(minutes: 5)",[574,610,611,614],{},[591,612,613],{},"Contenu de post / article",[591,615,616],{},[387,617,618],{},"Duration(minutes: 10)",[574,620,621,624],{},[591,622,623],{},"Configuration qui change rarement",[591,625,626],{},[387,627,628],{},"Duration(hours: 1)",[574,630,631,634],{},[591,632,633],{},"Données de référence statiques",[591,635,636],{},[387,637,638],{},"Duration(days: 1)",[377,640],{},[348,642,644,645],{"id":643},"swr-avec-fetchquery","SWR avec ",[387,646,389],{},[353,648,385,649,651],{},[387,650,389],{}," atteint une entrée de cache périmée, il retourne les données périmées de façon synchrone et déclenche une revalidation en arrière-plan. L'appel se résout immédiatement :",[408,653,655],{"className":425,"code":654,"filename":427,"language":428,"meta":414,"style":414},"// Retourne immédiatement avec les données en cache si disponibles\nfinal user = await client.fetchQuery\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n  options: QoraOptions(staleTime: Duration(minutes: 5)),\n);\n\n// Si les données étaient périmées :\n// - `user` est la valeur périmée (retournée instantanément)\n// - Un fetch en arrière-plan est déjà en cours\n// - Les streams watchQuery actifs recevront l'utilisateur mis à jour quand le fetch se termine\n",[387,656,657,662,695,717,743,768,776,780,785,790,796],{"__ignoreMap":414},[432,658,659],{"class":434,"line":435},[432,660,661],{"class":438},"// Retourne immédiatement avec les données en cache si disponibles\n",[432,663,664,668,671,674,678,681,683,686,689,692],{"class":434,"line":442},[432,665,667],{"class":666},"spNyl","final",[432,669,670],{"class":451}," user ",[432,672,673],{"class":455},"=",[432,675,677],{"class":676},"s7zQu"," await",[432,679,680],{"class":451}," client",[432,682,471],{"class":455},[432,684,389],{"class":685},"s2Zo4",[432,687,688],{"class":451},"\u003C",[432,690,691],{"class":459},"User",[432,693,694],{"class":451},">(\n",[432,696,697,700,702,705,709,712,715],{"class":434,"line":448},[432,698,699],{"class":451},"  key",[432,701,456],{"class":455},[432,703,704],{"class":451}," [",[432,706,708],{"class":707},"sfazB","'users'",[432,710,711],{"class":455},",",[432,713,714],{"class":451}," userId]",[432,716,477],{"class":455},[432,718,719,722,724,727,730,733,735,738,741],{"class":434,"line":480},[432,720,721],{"class":451},"  fetcher",[432,723,456],{"class":455},[432,725,726],{"class":451}," () ",[432,728,729],{"class":455},"=>",[432,731,732],{"class":451}," api",[432,734,471],{"class":455},[432,736,737],{"class":685},"getUser",[432,739,740],{"class":451},"(userId)",[432,742,477],{"class":455},[432,744,745,748,750,752,754,756,758,760,762,764,766],{"class":434,"line":487},[432,746,747],{"class":451},"  options",[432,749,456],{"class":455},[432,751,460],{"class":459},[432,753,463],{"class":451},[432,755,456],{"class":455},[432,757,468],{"class":459},[432,759,508],{"class":451},[432,761,456],{"class":455},[432,763,514],{"class":513},[432,765,517],{"class":451},[432,767,477],{"class":455},[432,769,770,773],{"class":434,"line":493},[432,771,772],{"class":451},")",[432,774,775],{"class":455},";\n",[432,777,778],{"class":434,"line":522},[432,779,484],{"emptyLinePlaceholder":483},[432,781,782],{"class":434,"line":527},[432,783,784],{"class":438},"// Si les données étaient périmées :\n",[432,786,787],{"class":434,"line":533},[432,788,789],{"class":438},"// - `user` est la valeur périmée (retournée instantanément)\n",[432,791,793],{"class":434,"line":792},10,[432,794,795],{"class":438},"// - Un fetch en arrière-plan est déjà en cours\n",[432,797,799],{"class":434,"line":798},11,[432,800,801],{"class":438},"// - Les streams watchQuery actifs recevront l'utilisateur mis à jour quand le fetch se termine\n",[377,803],{},[348,805,644,807],{"id":806},"swr-avec-watchquery",[387,808,393],{},[353,810,811,812,814],{},"Les streams ",[387,813,393],{}," sont l'interface principale pour le SWR. Les abonnés reçoivent le dernier état, y compris le résultat de la revalidation en arrière-plan :",[408,816,819],{"className":425,"code":817,"filename":818,"language":428,"meta":414,"style":414},"StreamBuilder\u003CQoraState\u003CUser>>(\n  stream: client.watchQuery\u003CUser>(\n    key: ['users', userId],\n    fetcher: () => api.getUser(userId),\n    options: QoraOptions(staleTime: Duration(minutes: 5)),\n  ),\n  builder: (context, snapshot) {\n    return switch (snapshot.data) {\n      // Affiche les données périmées instantanément pendant que Loading(previousData: user) est émis\n      Loading(:final previousData) when previousData != null =>\n        Stack(children: [\n          UserCard(previousData),\n          const LinearProgressIndicator(),\n        ]),\n      Success(:final data) => UserCard(data),\n      Failure(:final error, :final previousData) => Column(children: [\n          if (previousData != null) UserCard(previousData),\n          ErrorBanner('$error'),\n        ]),\n      _ => const CircularProgressIndicator(),\n    };\n  },\n)\n","user_page.dart",[387,820,821,837,856,873,894,919,926,941,957,962,992,1005,1016,1030,1038,1063,1098,1121,1145,1152,1170,1178,1186],{"__ignoreMap":414},[432,822,823,826,828,830,832,834],{"class":434,"line":435},[432,824,825],{"class":459},"StreamBuilder",[432,827,688],{"class":451},[432,829,211],{"class":459},[432,831,688],{"class":451},[432,833,691],{"class":459},[432,835,836],{"class":451},">>(\n",[432,838,839,842,844,846,848,850,852,854],{"class":434,"line":442},[432,840,841],{"class":451},"  stream",[432,843,456],{"class":455},[432,845,680],{"class":451},[432,847,471],{"class":455},[432,849,393],{"class":685},[432,851,688],{"class":451},[432,853,691],{"class":459},[432,855,694],{"class":451},[432,857,858,861,863,865,867,869,871],{"class":434,"line":448},[432,859,860],{"class":451},"    key",[432,862,456],{"class":455},[432,864,704],{"class":451},[432,866,708],{"class":707},[432,868,711],{"class":455},[432,870,714],{"class":451},[432,872,477],{"class":455},[432,874,875,878,880,882,884,886,888,890,892],{"class":434,"line":480},[432,876,877],{"class":451},"    fetcher",[432,879,456],{"class":455},[432,881,726],{"class":451},[432,883,729],{"class":455},[432,885,732],{"class":451},[432,887,471],{"class":455},[432,889,737],{"class":685},[432,891,740],{"class":451},[432,893,477],{"class":455},[432,895,896,899,901,903,905,907,909,911,913,915,917],{"class":434,"line":487},[432,897,898],{"class":451},"    options",[432,900,456],{"class":455},[432,902,460],{"class":459},[432,904,463],{"class":451},[432,906,456],{"class":455},[432,908,468],{"class":459},[432,910,508],{"class":451},[432,912,456],{"class":455},[432,914,514],{"class":513},[432,916,517],{"class":451},[432,918,477],{"class":455},[432,920,921,924],{"class":434,"line":493},[432,922,923],{"class":451},"  )",[432,925,477],{"class":455},[432,927,928,931,933,936,938],{"class":434,"line":522},[432,929,930],{"class":451},"  builder",[432,932,456],{"class":455},[432,934,935],{"class":451}," (context",[432,937,711],{"class":455},[432,939,940],{"class":451}," snapshot) {\n",[432,942,943,946,949,952,954],{"class":434,"line":527},[432,944,945],{"class":676},"    return",[432,947,948],{"class":676}," switch",[432,950,951],{"class":451}," (snapshot",[432,953,471],{"class":455},[432,955,956],{"class":451},"data) {\n",[432,958,959],{"class":434,"line":533},[432,960,961],{"class":438},"      // Affiche les données périmées instantanément pendant que Loading(previousData: user) est émis\n",[432,963,964,967,970,972,974,977,980,983,986,989],{"class":434,"line":792},[432,965,966],{"class":459},"      Loading",[432,968,969],{"class":451},"(",[432,971,456],{"class":455},[432,973,667],{"class":666},[432,975,976],{"class":451}," previousData) ",[432,978,979],{"class":676},"when",[432,981,982],{"class":451}," previousData ",[432,984,985],{"class":455},"!=",[432,987,988],{"class":455}," null",[432,990,991],{"class":455}," =>\n",[432,993,994,997,1000,1002],{"class":434,"line":798},[432,995,996],{"class":459},"        Stack",[432,998,999],{"class":451},"(children",[432,1001,456],{"class":455},[432,1003,1004],{"class":451}," [\n",[432,1006,1008,1011,1014],{"class":434,"line":1007},12,[432,1009,1010],{"class":459},"          UserCard",[432,1012,1013],{"class":451},"(previousData)",[432,1015,477],{"class":455},[432,1017,1019,1022,1025,1028],{"class":434,"line":1018},13,[432,1020,1021],{"class":666},"          const",[432,1023,1024],{"class":459}," LinearProgressIndicator",[432,1026,1027],{"class":451},"()",[432,1029,477],{"class":455},[432,1031,1033,1036],{"class":434,"line":1032},14,[432,1034,1035],{"class":451},"        ])",[432,1037,477],{"class":455},[432,1039,1041,1044,1046,1048,1050,1053,1055,1058,1061],{"class":434,"line":1040},15,[432,1042,1043],{"class":459},"      Success",[432,1045,969],{"class":451},[432,1047,456],{"class":455},[432,1049,667],{"class":666},[432,1051,1052],{"class":451}," data) ",[432,1054,729],{"class":455},[432,1056,1057],{"class":459}," UserCard",[432,1059,1060],{"class":451},"(data)",[432,1062,477],{"class":455},[432,1064,1066,1069,1071,1073,1075,1078,1080,1083,1085,1087,1089,1092,1094,1096],{"class":434,"line":1065},16,[432,1067,1068],{"class":459},"      Failure",[432,1070,969],{"class":451},[432,1072,456],{"class":455},[432,1074,667],{"class":666},[432,1076,1077],{"class":451}," error",[432,1079,711],{"class":455},[432,1081,1082],{"class":455}," :",[432,1084,667],{"class":666},[432,1086,976],{"class":451},[432,1088,729],{"class":455},[432,1090,1091],{"class":459}," Column",[432,1093,999],{"class":451},[432,1095,456],{"class":455},[432,1097,1004],{"class":451},[432,1099,1101,1104,1107,1109,1111,1114,1117,1119],{"class":434,"line":1100},17,[432,1102,1103],{"class":676},"          if",[432,1105,1106],{"class":451}," (previousData ",[432,1108,985],{"class":455},[432,1110,988],{"class":455},[432,1112,1113],{"class":451},") ",[432,1115,1116],{"class":459},"UserCard",[432,1118,1013],{"class":451},[432,1120,477],{"class":455},[432,1122,1124,1127,1129,1132,1135,1139,1141,1143],{"class":434,"line":1123},18,[432,1125,1126],{"class":459},"          ErrorBanner",[432,1128,969],{"class":451},[432,1130,1131],{"class":707},"'",[432,1133,1134],{"class":451},"$",[432,1136,1138],{"class":1137},"sHdIc","error",[432,1140,1131],{"class":707},[432,1142,772],{"class":451},[432,1144,477],{"class":455},[432,1146,1148,1150],{"class":434,"line":1147},19,[432,1149,1035],{"class":451},[432,1151,477],{"class":455},[432,1153,1155,1158,1160,1163,1166,1168],{"class":434,"line":1154},20,[432,1156,1157],{"class":451},"      _ ",[432,1159,729],{"class":455},[432,1161,1162],{"class":666}," const",[432,1164,1165],{"class":459}," CircularProgressIndicator",[432,1167,1027],{"class":451},[432,1169,477],{"class":455},[432,1171,1173,1176],{"class":434,"line":1172},21,[432,1174,1175],{"class":451},"    }",[432,1177,775],{"class":455},[432,1179,1181,1184],{"class":434,"line":1180},22,[432,1182,1183],{"class":451},"  }",[432,1185,477],{"class":455},[432,1187,1189],{"class":434,"line":1188},23,[432,1190,1191],{"class":451},")\n",[559,1193,1195],{"id":1194},"séquence-détats-au-montage-avec-cache-périmé","Séquence d'états au montage avec cache périmé",[408,1197,1200],{"className":1198,"code":1199,"language":413,"meta":414},[411],"Abonnement démarré\n  ↓ émet immédiatement\nLoading(previousData: Alice)    ← données périmées visibles, indicateur de chargement discret\n  ↓ fetch terminé\nSuccess(data: Alice Martin)     ← données fraîches, l'UI se met à jour sans rupture\n",[387,1201,1199],{"__ignoreMap":414},[377,1203],{},[348,1205,1207],{"id":1206},"refetch-au-montage","Refetch au montage",[353,1209,1210,1211,1213,1214,1082],{},"Par défaut, ",[387,1212,393],{}," déclenche un fetch au premier abonnement quand les données sont périmées. Ce comportement est contrôlé par ",[387,1215,1216],{},"refetchOnMount",[408,1218,1221],{"className":425,"code":1219,"filename":1220,"language":428,"meta":414,"style":414},"// Toujours refetcher au montage, même si les données en cache sont encore fraîches\n// (défaut quand QoraClientConfig.refetchOnMount est true)\noptions: QoraOptions(refetchOnMount: true),\n\n// Fetch uniquement si les données sont absentes ou périmées ; ignorer le refetch si fraîches\noptions: QoraOptions(refetchOnMount: false),\n\n// Hériter du paramètre global QoraClientConfig.refetchOnMount (défaut)\noptions: QoraOptions(refetchOnMount: null),\n","main.dart",[387,1222,1223,1228,1233,1253,1257,1262,1281,1285,1290],{"__ignoreMap":414},[432,1224,1225],{"class":434,"line":435},[432,1226,1227],{"class":438},"// Toujours refetcher au montage, même si les données en cache sont encore fraîches\n",[432,1229,1230],{"class":434,"line":442},[432,1231,1232],{"class":438},"// (défaut quand QoraClientConfig.refetchOnMount est true)\n",[432,1234,1235,1237,1239,1241,1244,1246,1249,1251],{"class":434,"line":448},[432,1236,452],{"class":451},[432,1238,456],{"class":455},[432,1240,460],{"class":459},[432,1242,1243],{"class":451},"(refetchOnMount",[432,1245,456],{"class":455},[432,1247,1248],{"class":455}," true",[432,1250,772],{"class":451},[432,1252,477],{"class":455},[432,1254,1255],{"class":434,"line":480},[432,1256,484],{"emptyLinePlaceholder":483},[432,1258,1259],{"class":434,"line":487},[432,1260,1261],{"class":438},"// Fetch uniquement si les données sont absentes ou périmées ; ignorer le refetch si fraîches\n",[432,1263,1264,1266,1268,1270,1272,1274,1277,1279],{"class":434,"line":493},[432,1265,452],{"class":451},[432,1267,456],{"class":455},[432,1269,460],{"class":459},[432,1271,1243],{"class":451},[432,1273,456],{"class":455},[432,1275,1276],{"class":455}," false",[432,1278,772],{"class":451},[432,1280,477],{"class":455},[432,1282,1283],{"class":434,"line":522},[432,1284,484],{"emptyLinePlaceholder":483},[432,1286,1287],{"class":434,"line":527},[432,1288,1289],{"class":438},"// Hériter du paramètre global QoraClientConfig.refetchOnMount (défaut)\n",[432,1291,1292,1294,1296,1298,1300,1302,1304,1306],{"class":434,"line":533},[432,1293,452],{"class":451},[432,1295,456],{"class":455},[432,1297,460],{"class":459},[432,1299,1243],{"class":451},[432,1301,456],{"class":455},[432,1303,988],{"class":455},[432,1305,772],{"class":451},[432,1307,477],{"class":455},[377,1309],{},[348,1311,1313],{"id":1312},"polling-revalidation-active","Polling (revalidation active)",[353,1315,1316,1317,1320],{},"Pour les données en direct, combiner le SWR avec ",[387,1318,1319],{},"refetchInterval"," pour rafraîchir continuellement le cache :",[408,1322,1325],{"className":425,"code":1323,"filename":1324,"language":428,"meta":414,"style":414},"client.watchQuery\u003CStats>(\n  key: ['dashboard', 'stats'],\n  fetcher: api.getDashboardStats,\n  options: QoraOptions(\n    staleTime: Duration(seconds: 10),\n    refetchInterval: Duration(seconds: 30),\n  ),\n)\n","dashboard_page.dart",[387,1326,1327,1343,1364,1379,1390,1411,1431,1437],{"__ignoreMap":414},[432,1328,1329,1332,1334,1336,1338,1341],{"class":434,"line":435},[432,1330,1331],{"class":451},"client",[432,1333,471],{"class":455},[432,1335,393],{"class":685},[432,1337,688],{"class":451},[432,1339,1340],{"class":459},"Stats",[432,1342,694],{"class":451},[432,1344,1345,1347,1349,1351,1354,1356,1359,1362],{"class":434,"line":442},[432,1346,699],{"class":451},[432,1348,456],{"class":455},[432,1350,704],{"class":451},[432,1352,1353],{"class":707},"'dashboard'",[432,1355,711],{"class":455},[432,1357,1358],{"class":707}," 'stats'",[432,1360,1361],{"class":451},"]",[432,1363,477],{"class":455},[432,1365,1366,1368,1370,1372,1374,1377],{"class":434,"line":448},[432,1367,721],{"class":451},[432,1369,456],{"class":455},[432,1371,732],{"class":451},[432,1373,471],{"class":455},[432,1375,1376],{"class":451},"getDashboardStats",[432,1378,477],{"class":455},[432,1380,1381,1383,1385,1387],{"class":434,"line":480},[432,1382,747],{"class":451},[432,1384,456],{"class":455},[432,1386,460],{"class":459},[432,1388,1389],{"class":451},"(\n",[432,1391,1392,1395,1397,1399,1402,1404,1407,1409],{"class":434,"line":487},[432,1393,1394],{"class":451},"    staleTime",[432,1396,456],{"class":455},[432,1398,468],{"class":459},[432,1400,1401],{"class":451},"(seconds",[432,1403,456],{"class":455},[432,1405,1406],{"class":513}," 10",[432,1408,772],{"class":451},[432,1410,477],{"class":455},[432,1412,1413,1416,1418,1420,1422,1424,1427,1429],{"class":434,"line":493},[432,1414,1415],{"class":451},"    refetchInterval",[432,1417,456],{"class":455},[432,1419,468],{"class":459},[432,1421,1401],{"class":451},[432,1423,456],{"class":455},[432,1425,1426],{"class":513}," 30",[432,1428,772],{"class":451},[432,1430,477],{"class":455},[432,1432,1433,1435],{"class":434,"line":522},[432,1434,923],{"class":451},[432,1436,477],{"class":455},[432,1438,1439],{"class":434,"line":527},[432,1440,1191],{"class":451},[353,1442,1443,1444,1446],{},"Le timer d'intervalle démarre quand le premier abonné s'attache, se déclenche toutes les ",[387,1445,1319],{},", et s'arrête quand le dernier abonné annule. Le polling ne s'applique pas aux requêtes hors écran.",[377,1448],{},[348,1450,1452],{"id":1451},"forcer-le-rafraîchissement","Forcer le rafraîchissement",[353,1454,1455],{},"Pour contourner la vérification de péremption et forcer une requête réseau immédiate, invalider d'abord la clé :",[408,1457,1459],{"className":425,"code":1458,"filename":1220,"language":428,"meta":414,"style":414},"// Forcer un fetch frais au prochain accès\nclient.invalidate(['users', userId]);\n\n// Ou précharger immédiatement des données fraîches\nawait client.prefetch\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),\n  options: QoraOptions(staleTime: Duration.zero),\n);\n",[387,1460,1461,1466,1487,1491,1496,1514,1530,1550,1570],{"__ignoreMap":414},[432,1462,1463],{"class":434,"line":435},[432,1464,1465],{"class":438},"// Forcer un fetch frais au prochain accès\n",[432,1467,1468,1470,1472,1475,1478,1480,1482,1485],{"class":434,"line":442},[432,1469,1331],{"class":451},[432,1471,471],{"class":455},[432,1473,1474],{"class":685},"invalidate",[432,1476,1477],{"class":451},"([",[432,1479,708],{"class":707},[432,1481,711],{"class":455},[432,1483,1484],{"class":451}," userId])",[432,1486,775],{"class":455},[432,1488,1489],{"class":434,"line":448},[432,1490,484],{"emptyLinePlaceholder":483},[432,1492,1493],{"class":434,"line":480},[432,1494,1495],{"class":438},"// Ou précharger immédiatement des données fraîches\n",[432,1497,1498,1501,1503,1505,1508,1510,1512],{"class":434,"line":487},[432,1499,1500],{"class":676},"await",[432,1502,680],{"class":451},[432,1504,471],{"class":455},[432,1506,1507],{"class":685},"prefetch",[432,1509,688],{"class":451},[432,1511,691],{"class":459},[432,1513,694],{"class":451},[432,1515,1516,1518,1520,1522,1524,1526,1528],{"class":434,"line":493},[432,1517,699],{"class":451},[432,1519,456],{"class":455},[432,1521,704],{"class":451},[432,1523,708],{"class":707},[432,1525,711],{"class":455},[432,1527,714],{"class":451},[432,1529,477],{"class":455},[432,1531,1532,1534,1536,1538,1540,1542,1544,1546,1548],{"class":434,"line":522},[432,1533,721],{"class":451},[432,1535,456],{"class":455},[432,1537,726],{"class":451},[432,1539,729],{"class":455},[432,1541,732],{"class":451},[432,1543,471],{"class":455},[432,1545,737],{"class":685},[432,1547,740],{"class":451},[432,1549,477],{"class":455},[432,1551,1552,1554,1556,1558,1560,1562,1564,1566,1568],{"class":434,"line":527},[432,1553,747],{"class":451},[432,1555,456],{"class":455},[432,1557,460],{"class":459},[432,1559,463],{"class":451},[432,1561,456],{"class":455},[432,1563,468],{"class":459},[432,1565,471],{"class":455},[432,1567,474],{"class":451},[432,1569,477],{"class":455},[432,1571,1572,1574],{"class":434,"line":533},[432,1573,772],{"class":451},[432,1575,775],{"class":455},[377,1577],{},[348,1579,1581],{"id":1580},"étapes-suivantes","Étapes suivantes",[357,1583,1584,1591,1603],{},[360,1585,1586,1590],{},[1587,1588,77],"a",{"href":1589},"./deduplication"," : Comment les appelants concurrents partagent une seule requête",[360,1592,1593,1596,1597,1600,1601],{},[1587,1594,67],{"href":1595},"./caching"," : LRU, GC et ",[387,1598,1599],{},"gcTime"," vs ",[387,1602,565],{},[360,1604,1605,1608],{},[1587,1606,1607],{"href":216},"API QoraOptions"," : Référence complète des options",[1610,1611,1612],"style",{},"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 .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 .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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .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":414,"searchDepth":442,"depth":442,"links":1614},[1615,1616,1617,1621,1623,1627,1628,1629,1630],{"id":350,"depth":442,"text":351},{"id":381,"depth":442,"text":382},{"id":421,"depth":442,"text":422,"children":1618},[1619],{"id":561,"depth":448,"text":1620},"Choix du staleTime par type de données",{"id":643,"depth":442,"text":1622},"SWR avec fetchQuery",{"id":806,"depth":442,"text":1624,"children":1625},"SWR avec watchQuery",[1626],{"id":1194,"depth":448,"text":1195},{"id":1206,"depth":442,"text":1207},{"id":1312,"depth":442,"text":1313},{"id":1451,"depth":442,"text":1452},{"id":1580,"depth":442,"text":1581},"Le SWR de Qora retourne les données en cache immédiatement et revalide en arrière-plan pour maintenir les UIs réactives et les données à jour.","md",null,{},{"icon":75},{"title":72,"description":1631},"wovyJEvInxHf8Bl5YBbxZw71YOW7og0b0HZs08A7Spg",[1639,1641],{"title":67,"path":68,"stem":69,"description":1640,"icon":70,"children":-1},"Le cache de Qora permet un accès instantané aux données. Apprenez comment les entrées de cache sont créées, vieillissent et sont collectées par le GC, comment le partage structurel évite les reconstructions inutiles, et comment contrôler chaque comportement.",{"title":77,"path":78,"stem":79,"description":1642,"icon":80,"children":-1},"Qora fusionne les requêtes concurrentes pour la même clé en un seul appel réseau, quel que soit le nombre d'appelants.",1794040406987]