[{"data":1,"prerenderedAt":2822},["ShallowReactive",2],{"navigation_docs_en":3,"-en-core-concepts-caching":342,"-en-core-concepts-caching-surround":2817},[4,45,91,137,195,236,257,291,327],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":44},"Getting Started","i-lucide-rocket","/en/getting-started","en/01.getting-started",[10,15,20,24,29,34,39],{"title":11,"path":12,"stem":13,"icon":14},"What is Qora?","/en/getting-started/what-is-qora","en/01.getting-started/2.what-is-qora","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/en/getting-started/installation","en/01.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":6},"Quick Start","/en/getting-started/quick-start","en/01.getting-started/4.quick-start",{"title":25,"path":26,"stem":27,"icon":28},"Comparison","/en/getting-started/comparison","en/01.getting-started/5.comparison","i-lucide-scale",{"title":30,"path":31,"stem":32,"icon":33},"Coming from TanStack Query","/en/getting-started/coming-from-tanstack-query","en/01.getting-started/6.coming-from-tanstack-query","i-lucide-arrow-left-right",{"title":35,"path":36,"stem":37,"icon":38},"Migrating from Other Libraries","/en/getting-started/migrating-from-other-libraries","en/01.getting-started/7.migrating-from-other-libraries","i-lucide-arrow-right-left",{"title":40,"path":41,"stem":42,"icon":43},"AI Assistants","/en/getting-started/ai-assistants","en/01.getting-started/8.ai-assistants","i-lucide-sparkles",false,{"title":46,"icon":47,"path":48,"stem":49,"children":50,"page":44},"Core Concepts","i-lucide-book-open","/en/core-concepts","en/02.core-concepts",[51,56,61,66,71,76,81,86],{"title":52,"path":53,"stem":54,"icon":55},"Queries","/en/core-concepts/queries","en/02.core-concepts/1.queries","i-lucide-database",{"title":57,"path":58,"stem":59,"icon":60},"Query Keys","/en/core-concepts/query-keys","en/02.core-concepts/2.query-keys","i-lucide-key-round",{"title":62,"path":63,"stem":64,"icon":65},"Query States","/en/core-concepts/query-states","en/02.core-concepts/3.query-states","i-lucide-activity",{"title":67,"path":68,"stem":69,"icon":70},"Caching","/en/core-concepts/caching","en/02.core-concepts/4.caching","i-lucide-layers-3",{"title":72,"path":73,"stem":74,"icon":75},"Stale-While-Revalidate","/en/core-concepts/stale-while-revalidate","en/02.core-concepts/5.stale-while-revalidate","i-lucide-timer-reset",{"title":77,"path":78,"stem":79,"icon":80},"Deduplication","/en/core-concepts/deduplication","en/02.core-concepts/6.deduplication","i-lucide-copy-minus",{"title":82,"path":83,"stem":84,"icon":85},"Mutations & Invalidation","/en/core-concepts/mutations","en/02.core-concepts/7.mutations","i-lucide-pencil-line",{"title":87,"path":88,"stem":89,"icon":90},"Offline & Network","/en/core-concepts/offline","en/02.core-concepts/8.offline","i-lucide-wifi-off",{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":44},"Flutter Integration","i-lucide-smartphone","/en/flutter-integration","en/03.flutter-integration",[97,102,107,112,117,122,127,132],{"title":98,"path":99,"stem":100,"icon":101},"Setup","/en/flutter-integration/setup","en/03.flutter-integration/1.setup","i-lucide-wrench",{"title":103,"path":104,"stem":105,"icon":106},"QoraScope","/en/flutter-integration/qora-scope","en/03.flutter-integration/2.qora-scope","i-lucide-share-2",{"title":108,"path":109,"stem":110,"icon":111},"QoraBuilder","/en/flutter-integration/qora-builder","en/03.flutter-integration/3.qora-builder","i-lucide-blocks",{"title":113,"path":114,"stem":115,"icon":116},"QoraMutationBuilder","/en/flutter-integration/qora-mutation-builder","en/03.flutter-integration/4.qora-mutation-builder","i-lucide-pencil",{"title":118,"path":119,"stem":120,"icon":121},"InfiniteQueryBuilder","/en/flutter-integration/infinite-query-builder","en/03.flutter-integration/5.infinite-query-builder","i-lucide-infinity",{"title":123,"path":124,"stem":125,"icon":126},"Hooks (flutter_hooks)","/en/flutter-integration/hooks","en/03.flutter-integration/6.hooks","i-lucide-anchor",{"title":128,"path":129,"stem":130,"icon":131},"Network Status Widgets","/en/flutter-integration/network-status","en/03.flutter-integration/7.network-status","i-lucide-wifi",{"title":133,"path":134,"stem":135,"icon":136},"Best Practices","/en/flutter-integration/best-practices","en/03.flutter-integration/8.best-practices","i-lucide-badge-check",{"title":138,"icon":139,"path":140,"stem":141,"children":142,"page":44},"Recipes","i-lucide-chef-hat","/en/recipes","en/04.recipes",[143,147,152,157,162,166,171,176,181,186,191],{"title":144,"path":145,"stem":146,"icon":85},"Mutations","/en/recipes/mutations","en/04.recipes/02.mutations",{"title":148,"path":149,"stem":150,"icon":151},"Optimistic Updates","/en/recipes/optimistic-updates","en/04.recipes/03.optimistic-updates","i-lucide-zap",{"title":153,"path":154,"stem":155,"icon":156},"Persistence","/en/recipes/persistence","en/04.recipes/04.persistence","i-lucide-hard-drive",{"title":158,"path":159,"stem":160,"icon":161},"Network Aware","/en/recipes/network-aware","en/04.recipes/05.network-aware","i-lucide-signal",{"title":163,"path":164,"stem":165,"icon":121},"Infinite Queries","/en/recipes/infinite-queries","en/04.recipes/06.infinite-queries",{"title":167,"path":168,"stem":169,"icon":170},"Dependent Queries","/en/recipes/dependent-queries","en/04.recipes/07.dependent-queries","i-lucide-link-2",{"title":172,"path":173,"stem":174,"icon":175},"Cancellation","/en/recipes/cancel-token","en/04.recipes/08.cancel-token","i-lucide-circle-slash",{"title":177,"path":178,"stem":179,"icon":180},"SSR Hydration","/en/recipes/ssr-hydration","en/04.recipes/09.ssr-hydration","i-lucide-server",{"title":182,"path":183,"stem":184,"icon":185},"Error Handling","/en/recipes/error-handling","en/04.recipes/10.error-handling","i-lucide-shield-alert",{"title":187,"path":188,"stem":189,"icon":190},"Testing","/en/recipes/testing","en/04.recipes/11.testing","i-lucide-flask-conical",{"title":192,"path":193,"stem":194},"Route-Level Prefetching","/en/recipes/prefetch","en/04.recipes/12.prefetch",{"title":196,"icon":197,"path":198,"stem":199,"children":200,"page":44},"API Reference","i-lucide-file-code","/en/api-reference","en/05.api-reference",[201,206,210,214,219,224,228,232],{"title":202,"path":203,"stem":204,"icon":205},"QoraClient","/en/api-reference/qora-client","en/05.api-reference/1.qora-client","i-lucide-cpu",{"title":207,"path":208,"stem":209,"icon":60},"QoraKey","/en/api-reference/qora-key","en/05.api-reference/2.qora-key",{"title":211,"path":212,"stem":213,"icon":65},"QoraState","/en/api-reference/qora-state","en/05.api-reference/3.qora-state",{"title":215,"path":216,"stem":217,"icon":218},"QoraOptions","/en/api-reference/qora-options","en/05.api-reference/4.qora-options","i-lucide-sliders-horizontal",{"title":220,"path":221,"stem":222,"icon":223},"QoraClientConfig","/en/api-reference/qora-client-config","en/05.api-reference/5.qora-client-config","i-lucide-settings-2",{"title":225,"path":226,"stem":227,"icon":85},"Mutation API","/en/api-reference/qora-mutation","en/05.api-reference/6.qora-mutation",{"title":229,"path":230,"stem":231,"icon":156},"PersistQoraClient","/en/api-reference/persist-qora-client","en/05.api-reference/7.persist-qora-client",{"title":233,"path":234,"stem":235,"icon":121},"Infinite Query","/en/api-reference/infinite-query","en/05.api-reference/8.infinite-query",{"title":237,"icon":238,"path":239,"stem":240,"children":241,"page":44},"DevTools","i-lucide-bug","/en/devtools","en/06.devtools",[242,247,252],{"title":243,"path":244,"stem":245,"icon":246},"Overview","/en/devtools/overview","en/06.devtools/1.overview","i-lucide-layout-dashboard",{"title":248,"path":249,"stem":250,"icon":251},"In-App Overlay","/en/devtools/overlay","en/06.devtools/2.overlay","i-lucide-layers",{"title":253,"path":254,"stem":255,"icon":256},"Data Serialization","/en/devtools/data-display","en/06.devtools/4.data-display","i-lucide-eye",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":44},"Third Party","i-lucide-puzzle","/en/third-party","en/07.third-party",[263,268,272,277,282,286],{"title":264,"path":265,"stem":266,"icon":267},"With Provider","/en/third-party/with-provider","en/07.third-party/1.with-provider","i-lucide-plug",{"title":269,"path":270,"stem":271,"icon":111},"With BLoC","/en/third-party/with-bloc","en/07.third-party/2.with-bloc",{"title":273,"path":274,"stem":275,"icon":276},"With Riverpod","/en/third-party/with-riverpod","en/07.third-party/3.with-riverpod","i-lucide-droplets",{"title":278,"path":279,"stem":280,"icon":281},"With RxDart","/en/third-party/with-rxdart","en/07.third-party/4.with-rxdart","i-lucide-git-branch",{"title":283,"path":284,"stem":285},"With Dio","/en/third-party/with-dio","en/07.third-party/5.with-dio",{"title":287,"path":288,"stem":289,"icon":290},"With GraphQL","/en/third-party/with-graphql","en/07.third-party/6.with-graphql","i-lucide-binary",{"title":292,"icon":190,"path":293,"stem":294,"children":295,"page":44},"Examples","/en/examples","en/08.examples",[296,301,305,310,314,318,322],{"title":297,"path":298,"stem":299,"icon":300},"Case Study: User List & Detail","/en/examples/basic-query","en/08.examples/1.basic-query","i-lucide-play-circle",{"title":302,"path":303,"stem":304,"icon":151},"Case Study: Optimistic Mutations & Rollback","/en/examples/mutations-optimistic","en/08.examples/2.mutations-optimistic",{"title":306,"path":307,"stem":308,"icon":309},"Case Study: Infinite Scroll Feed","/en/examples/infinite-scroll","en/08.examples/3.infinite-scroll","i-lucide-scroll",{"title":311,"path":312,"stem":313,"icon":90},"Case Study: Offline-First Todo App","/en/examples/offline-first","en/08.examples/4.offline-first",{"title":315,"path":316,"stem":317,"icon":161},"Case Study: Network Awareness","/en/examples/network-awareness","en/08.examples/5.network-awareness",{"title":319,"path":320,"stem":321,"icon":126},"Case Study: Hooks Integration","/en/examples/hooks-integration","en/08.examples/6.hooks-integration",{"title":323,"path":324,"stem":325,"icon":326},"Case Study: Complete Todo App","/en/examples/complete-todo-app","en/08.examples/7.complete-todo-app","i-lucide-check-square",{"title":328,"icon":329,"path":330,"stem":331,"children":332,"page":44},"Help","i-lucide-life-buoy","/en/help","en/09.help",[333,338],{"title":334,"path":335,"stem":336,"icon":337},"FAQ","/en/help/faq","en/09.help/1.faq","i-lucide-circle-help",{"title":339,"path":340,"stem":341,"icon":101},"Troubleshooting","/en/help/troubleshooting","en/09.help/2.troubleshooting",{"id":343,"title":67,"body":344,"description":2810,"extension":2811,"links":2812,"meta":2813,"navigation":2814,"path":68,"seo":2815,"stem":69,"__hash__":2816},"docs_en/en/02.core-concepts/4.caching.md",{"type":345,"value":346,"toc":2776},"minimark",[347,352,365,392,402,405,409,415,421,424,426,436,439,486,568,579,581,587,592,636,642,748,750,755,760,780,816,827,829,833,836,843,1014,1019,1022,1058,1158,1162,1165,1185,1189,1192,1220,1222,1226,1236,1243,1254,1380,1387,1399,1503,1505,1509,1523,1530,1660,1673,1675,1679,1689,1708,1753,1770,1772,1776,1780,1907,1911,2085,2089,2225,2242,2294,2306,2310,2361,2363,2370,2373,2465,2467,2471,2539,2541,2545,2556,2746,2748,2752,2772],[348,349,351],"h2",{"id":350},"how-the-cache-works","How the Cache Works",[353,354,355,356,360,361,364],"p",{},"Every query result is stored as a ",[357,358,359],"code",{},"CacheEntry\u003CT>"," in an in-memory ",[357,362,363],{},"QueryCache"," keyed by the normalised query key. The cache drives:",[366,367,368,376,382],"ul",{},[369,370,371,375],"li",{},[372,373,374],"strong",{},"Instant responses",": fresh data is returned without a network call",[369,377,378,381],{},[372,379,380],{},"SWR",": stale data is returned immediately while fresh data is fetched in the background",[369,383,384,387,388,391],{},[372,385,386],{},"Reactive updates",": every ",[357,389,390],{},"CacheEntry"," holds a broadcast stream; any state change reaches all active subscribers instantly",[393,394,400],"pre",{"className":395,"code":397,"language":398,"meta":399},[396],"language-text","fetchQuery(['users', 1])\n  │\n  ├─ Cache HIT  (fresh)  → return data immediately\n  ├─ Cache HIT  (stale)  → return stale data + revalidate in background\n  └─ Cache MISS          → fetch → store → return data\n","text","",[357,401,397],{"__ignoreMap":399},[403,404],"hr",{},[348,406,408],{"id":407},"cache-entry-lifecycle","Cache Entry Lifecycle",[353,410,411,412,414],{},"A ",[357,413,359],{}," goes through the following stages:",[393,416,419],{"className":417,"code":418,"language":398,"meta":399},[396],"Created (Initial)\n  │  fetchQuery / watchQuery triggered\n  ▼\nLoading → Success / Failure\n  │  staleTime elapsed\n  ▼\nStale (still in cache, accessible as previousData)\n  │  last subscriber unsubscribes\n  ▼\nGC timer starts (= gcTime)\n  │  timer fires, no active subscribers\n  ▼\nEvicted (removed from cache)\n",[357,420,418],{"__ignoreMap":399},[353,422,423],{},"A background eviction sweep also runs every minute to remove expired inactive entries.",[403,425],{},[348,427,429,432,433],{"id":428},"staletime-vs-gctime",[357,430,431],{},"staleTime"," vs ",[357,434,435],{},"gcTime",[353,437,438],{},"These two durations control independent behaviors:",[440,441,442,458],"table",{},[443,444,445],"thead",{},[446,447,448,452,455],"tr",{},[449,450,451],"th",{},"Property",[449,453,454],{},"Default",[449,456,457],{},"Controls",[459,460,461,474],"tbody",{},[446,462,463,468,471],{},[464,465,466],"td",{},[357,467,431],{},[464,469,470],{},"0 (zero)",[464,472,473],{},"When to trigger a background revalidation",[446,475,476,480,483],{},[464,477,478],{},[357,479,435],{},[464,481,482],{},"5 minutes",[464,484,485],{},"When to remove an unused entry from the cache",[393,487,492],{"className":488,"code":489,"filename":490,"language":491,"meta":399,"style":399},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","QoraOptions(\n  staleTime: Duration(minutes: 5),   // data is fresh for 5 minutes\n  gcTime: Duration(minutes: 10),  // unused data stays in cache for 10 min\n)\n","main.dart","dart",[357,493,494,506,538,562],{"__ignoreMap":399},[495,496,499,502],"span",{"class":497,"line":498},"line",1,[495,500,215],{"class":501},"sBMFI",[495,503,505],{"class":504},"sTEyZ","(\n",[495,507,509,512,516,519,522,524,528,531,534],{"class":497,"line":508},2,[495,510,511],{"class":504},"  staleTime",[495,513,515],{"class":514},"sMK4o",":",[495,517,518],{"class":501}," Duration",[495,520,521],{"class":504},"(minutes",[495,523,515],{"class":514},[495,525,527],{"class":526},"sbssI"," 5",[495,529,530],{"class":504},")",[495,532,533],{"class":514},",",[495,535,537],{"class":536},"sHwdD","   // data is fresh for 5 minutes\n",[495,539,541,544,546,548,550,552,555,557,559],{"class":497,"line":540},3,[495,542,543],{"class":504},"  gcTime",[495,545,515],{"class":514},[495,547,518],{"class":501},[495,549,521],{"class":504},[495,551,515],{"class":514},[495,553,554],{"class":526}," 10",[495,556,530],{"class":504},[495,558,533],{"class":514},[495,560,561],{"class":536},"  // unused data stays in cache for 10 min\n",[495,563,565],{"class":497,"line":564},4,[495,566,567],{"class":504},")\n",[569,570,571,574,575,578],"tip",{},[357,572,573],{},"staleTime: Duration.zero"," (the default) means data is ",[372,576,577],{},"always"," considered stale. Qora still serves cached data immediately; it also revalidates in the background on every access.",[403,580],{},[348,582,584,586],{"id":583},"staletime-in-detail",[357,585,431],{}," in Detail",[353,588,589,591],{},[357,590,431],{}," defines the freshness window. During this window, data is returned from cache without any network activity:",[393,593,595],{"className":488,"code":594,"filename":490,"language":491,"meta":399,"style":399},"// staleTime: 5 minutes\n\n// t = 0:00 → fetch triggers, Success stored\n// t = 0:01 → fetchQuery → Cache HIT (fresh): no network call\n// t = 5:01 → fetchQuery → Cache HIT (stale): returns cached data + revalidates\n// t = 5:01 → network request fires in background\n// t = 5:02 → Success updated, stream subscribers notified\n",[357,596,597,602,608,613,618,624,630],{"__ignoreMap":399},[495,598,599],{"class":497,"line":498},[495,600,601],{"class":536},"// staleTime: 5 minutes\n",[495,603,604],{"class":497,"line":508},[495,605,607],{"emptyLinePlaceholder":606},true,"\n",[495,609,610],{"class":497,"line":540},[495,611,612],{"class":536},"// t = 0:00 → fetch triggers, Success stored\n",[495,614,615],{"class":497,"line":564},[495,616,617],{"class":536},"// t = 0:01 → fetchQuery → Cache HIT (fresh): no network call\n",[495,619,621],{"class":497,"line":620},5,[495,622,623],{"class":536},"// t = 5:01 → fetchQuery → Cache HIT (stale): returns cached data + revalidates\n",[495,625,627],{"class":497,"line":626},6,[495,628,629],{"class":536},"// t = 5:01 → network request fires in background\n",[495,631,633],{"class":497,"line":632},7,[495,634,635],{"class":536},"// t = 5:02 → Success updated, stream subscribers notified\n",[353,637,638,639,641],{},"Set a long ",[357,640,431],{}," for data that rarely changes:",[393,643,645],{"className":488,"code":644,"filename":490,"language":491,"meta":399,"style":399},"// Configuration data: valid for 1 hour\noptions: QoraOptions(staleTime: Duration(hours: 1)),\n\n// User profile: valid for 10 minutes\noptions: QoraOptions(staleTime: Duration(minutes: 10)),\n\n// Live prices: always stale (default)\noptions: QoraOptions(staleTime: Duration.zero),\n",[357,646,647,652,683,687,692,716,720,725],{"__ignoreMap":399},[495,648,649],{"class":497,"line":498},[495,650,651],{"class":536},"// Configuration data: valid for 1 hour\n",[495,653,654,657,659,662,665,667,669,672,674,677,680],{"class":497,"line":508},[495,655,656],{"class":504},"options",[495,658,515],{"class":514},[495,660,661],{"class":501}," QoraOptions",[495,663,664],{"class":504},"(staleTime",[495,666,515],{"class":514},[495,668,518],{"class":501},[495,670,671],{"class":504},"(hours",[495,673,515],{"class":514},[495,675,676],{"class":526}," 1",[495,678,679],{"class":504},"))",[495,681,682],{"class":514},",\n",[495,684,685],{"class":497,"line":540},[495,686,607],{"emptyLinePlaceholder":606},[495,688,689],{"class":497,"line":564},[495,690,691],{"class":536},"// User profile: valid for 10 minutes\n",[495,693,694,696,698,700,702,704,706,708,710,712,714],{"class":497,"line":620},[495,695,656],{"class":504},[495,697,515],{"class":514},[495,699,661],{"class":501},[495,701,664],{"class":504},[495,703,515],{"class":514},[495,705,518],{"class":501},[495,707,521],{"class":504},[495,709,515],{"class":514},[495,711,554],{"class":526},[495,713,679],{"class":504},[495,715,682],{"class":514},[495,717,718],{"class":497,"line":626},[495,719,607],{"emptyLinePlaceholder":606},[495,721,722],{"class":497,"line":632},[495,723,724],{"class":536},"// Live prices: always stale (default)\n",[495,726,728,730,732,734,736,738,740,743,746],{"class":497,"line":727},8,[495,729,656],{"class":504},[495,731,515],{"class":514},[495,733,661],{"class":501},[495,735,664],{"class":504},[495,737,515],{"class":514},[495,739,518],{"class":501},[495,741,742],{"class":514},".",[495,744,745],{"class":504},"zero)",[495,747,682],{"class":514},[403,749],{},[348,751,753,586],{"id":752},"gctime-in-detail",[357,754,435],{},[353,756,757,759],{},[357,758,435],{}," determines how long inactive data lingers in cache after all subscribers leave. It preserves data for fast re-navigation:",[393,761,763],{"className":488,"code":762,"filename":490,"language":491,"meta":399,"style":399},"// User navigates away → last subscriber cancels → GC timer starts\n// User navigates back within gcTime → entry still in cache → instant display\n// User navigates back after gcTime → entry evicted → full fetch required\n",[357,764,765,770,775],{"__ignoreMap":399},[495,766,767],{"class":497,"line":498},[495,768,769],{"class":536},"// User navigates away → last subscriber cancels → GC timer starts\n",[495,771,772],{"class":497,"line":508},[495,773,774],{"class":536},"// User navigates back within gcTime → entry still in cache → instant display\n",[495,776,777],{"class":497,"line":540},[495,778,779],{"class":536},"// User navigates back after gcTime → entry evicted → full fetch required\n",[393,781,783],{"className":488,"code":782,"filename":490,"language":491,"meta":399,"style":399},"// Posts list: keep in cache for 2 minutes after leaving the page\noptions: QoraOptions(gcTime: Duration(minutes: 2)),\n",[357,784,785,790],{"__ignoreMap":399},[495,786,787],{"class":497,"line":498},[495,788,789],{"class":536},"// Posts list: keep in cache for 2 minutes after leaving the page\n",[495,791,792,794,796,798,801,803,805,807,809,812,814],{"class":497,"line":508},[495,793,656],{"class":504},[495,795,515],{"class":514},[495,797,661],{"class":501},[495,799,800],{"class":504},"(gcTime",[495,802,515],{"class":514},[495,804,518],{"class":501},[495,806,521],{"class":504},[495,808,515],{"class":514},[495,810,811],{"class":526}," 2",[495,813,679],{"class":504},[495,815,682],{"class":514},[817,818,819,822,823,826],"warning",{},[357,820,821],{},"gcTime: Duration.zero"," removes the entry as soon as all subscribers leave. The next visit always starts from ",[357,824,825],{},"Initial",". This is the correct behavior for sensitive data that must not outlive the current session.",[403,828],{},[348,830,832],{"id":831},"structural-sharing","Structural Sharing",[353,834,835],{},"Structural sharing preserves referential equality for unchanged nested data across fetches. When a fetch returns data that is deeply equal to the existing cached data, Qora keeps the previous data reference instead of replacing it.",[353,837,838,839,842],{},"This is enabled by default (",[357,840,841],{},"QoraOptions.structuralSharing: true","). It directly addresses unnecessary widget rebuilds in deeply nested UIs:",[393,844,846],{"className":488,"code":845,"filename":490,"language":491,"meta":399,"style":399},"// Without structural sharing: every fetch creates a new data reference,\n// causing all widgets consuming this query to rebuild.\n//\n// With structural sharing (default): if the returned data is structurally\n// identical to the cached data, the old reference is preserved. Widgets\n// that check identical(oldData, newData) or == skip re-rendering.\n\nfinal client = QoraClient();\nawait client.fetchQuery\u003CMap\u003CString, dynamic>>(\n  key: ['config'],\n  fetcher: () => api.getConfig(),\n  options: QoraOptions(structuralSharing: true),\n);\n",[357,847,848,853,858,863,868,873,878,882,903,939,959,985,1007],{"__ignoreMap":399},[495,849,850],{"class":497,"line":498},[495,851,852],{"class":536},"// Without structural sharing: every fetch creates a new data reference,\n",[495,854,855],{"class":497,"line":508},[495,856,857],{"class":536},"// causing all widgets consuming this query to rebuild.\n",[495,859,860],{"class":497,"line":540},[495,861,862],{"class":536},"//\n",[495,864,865],{"class":497,"line":564},[495,866,867],{"class":536},"// With structural sharing (default): if the returned data is structurally\n",[495,869,870],{"class":497,"line":620},[495,871,872],{"class":536},"// identical to the cached data, the old reference is preserved. Widgets\n",[495,874,875],{"class":497,"line":626},[495,876,877],{"class":536},"// that check identical(oldData, newData) or == skip re-rendering.\n",[495,879,880],{"class":497,"line":632},[495,881,607],{"emptyLinePlaceholder":606},[495,883,884,888,891,894,897,900],{"class":497,"line":727},[495,885,887],{"class":886},"spNyl","final",[495,889,890],{"class":504}," client ",[495,892,893],{"class":514},"=",[495,895,896],{"class":501}," QoraClient",[495,898,899],{"class":504},"()",[495,901,902],{"class":514},";\n",[495,904,906,910,913,915,919,922,925,927,930,933,936],{"class":497,"line":905},9,[495,907,909],{"class":908},"s7zQu","await",[495,911,912],{"class":504}," client",[495,914,742],{"class":514},[495,916,918],{"class":917},"s2Zo4","fetchQuery",[495,920,921],{"class":504},"\u003C",[495,923,924],{"class":501},"Map",[495,926,921],{"class":504},[495,928,929],{"class":501},"String",[495,931,932],{"class":504},", ",[495,934,935],{"class":501},"dynamic",[495,937,938],{"class":504},">>(\n",[495,940,942,945,947,950,954,957],{"class":497,"line":941},10,[495,943,944],{"class":504},"  key",[495,946,515],{"class":514},[495,948,949],{"class":504}," [",[495,951,953],{"class":952},"sfazB","'config'",[495,955,956],{"class":504},"]",[495,958,682],{"class":514},[495,960,962,965,967,970,973,976,978,981,983],{"class":497,"line":961},11,[495,963,964],{"class":504},"  fetcher",[495,966,515],{"class":514},[495,968,969],{"class":504}," () ",[495,971,972],{"class":514},"=>",[495,974,975],{"class":504}," api",[495,977,742],{"class":514},[495,979,980],{"class":917},"getConfig",[495,982,899],{"class":504},[495,984,682],{"class":514},[495,986,988,991,993,995,998,1000,1003,1005],{"class":497,"line":987},12,[495,989,990],{"class":504},"  options",[495,992,515],{"class":514},[495,994,661],{"class":501},[495,996,997],{"class":504},"(structuralSharing",[495,999,515],{"class":514},[495,1001,1002],{"class":514}," true",[495,1004,530],{"class":504},[495,1006,682],{"class":514},[495,1008,1010,1012],{"class":497,"line":1009},13,[495,1011,530],{"class":504},[495,1013,902],{"class":514},[1015,1016,1018],"h3",{"id":1017},"how-it-works","How It Works",[353,1020,1021],{},"The deep equality comparison is recursive:",[366,1023,1024,1029,1035,1041],{},[369,1025,1026,1028],{},[372,1027,924],{},": compares key presence and values recursively",[369,1030,1031,1034],{},[372,1032,1033],{},"List",": compares element count and elements recursively",[369,1036,1037,1040],{},[372,1038,1039],{},"Set",": compares membership",[369,1042,1043,1046,1047,1050,1051,1053,1054,1057],{},[372,1044,1045],{},"Other types",": uses ",[357,1048,1049],{},"=="," (override ",[357,1052,1049],{}," and ",[357,1055,1056],{},"hashCode"," on custom model classes for best results)",[393,1059,1061],{"className":488,"code":1060,"filename":490,"language":491,"meta":399,"style":399},"final oldData = {'user': {'name': 'Alice', 'roles': ['admin']}};\nfinal newData = {'user': {'name': 'Alice', 'roles': ['admin']}};\n\n// structuralShare returns oldData: they are deeply equal.\n// Any widget holding oldData will see identical(oldData, newData) == true.\n",[357,1062,1063,1107,1144,1148,1153],{"__ignoreMap":399},[495,1064,1065,1067,1070,1072,1075,1078,1080,1082,1085,1087,1090,1092,1095,1097,1099,1102,1105],{"class":497,"line":498},[495,1066,887],{"class":886},[495,1068,1069],{"class":504}," oldData ",[495,1071,893],{"class":514},[495,1073,1074],{"class":504}," {",[495,1076,1077],{"class":952},"'user'",[495,1079,515],{"class":514},[495,1081,1074],{"class":504},[495,1083,1084],{"class":952},"'name'",[495,1086,515],{"class":514},[495,1088,1089],{"class":952}," 'Alice'",[495,1091,533],{"class":514},[495,1093,1094],{"class":952}," 'roles'",[495,1096,515],{"class":514},[495,1098,949],{"class":504},[495,1100,1101],{"class":952},"'admin'",[495,1103,1104],{"class":504},"]}}",[495,1106,902],{"class":514},[495,1108,1109,1111,1114,1116,1118,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138,1140,1142],{"class":497,"line":508},[495,1110,887],{"class":886},[495,1112,1113],{"class":504}," newData ",[495,1115,893],{"class":514},[495,1117,1074],{"class":504},[495,1119,1077],{"class":952},[495,1121,515],{"class":514},[495,1123,1074],{"class":504},[495,1125,1084],{"class":952},[495,1127,515],{"class":514},[495,1129,1089],{"class":952},[495,1131,533],{"class":514},[495,1133,1094],{"class":952},[495,1135,515],{"class":514},[495,1137,949],{"class":504},[495,1139,1101],{"class":952},[495,1141,1104],{"class":504},[495,1143,902],{"class":514},[495,1145,1146],{"class":497,"line":540},[495,1147,607],{"emptyLinePlaceholder":606},[495,1149,1150],{"class":497,"line":564},[495,1151,1152],{"class":536},"// structuralShare returns oldData: they are deeply equal.\n",[495,1154,1155],{"class":497,"line":620},[495,1156,1157],{"class":536},"// Any widget holding oldData will see identical(oldData, newData) == true.\n",[1015,1159,1161],{"id":1160},"when-to-disable","When to Disable",[353,1163,1164],{},"Disable structural sharing only when the deep-equality check is a measured bottleneck with very large data structures:",[393,1166,1168],{"className":488,"code":1167,"filename":490,"language":491,"meta":399,"style":399},"QoraOptions(structuralSharing: false),\n",[357,1169,1170],{"__ignoreMap":399},[495,1171,1172,1174,1176,1178,1181,1183],{"class":497,"line":498},[495,1173,215],{"class":501},[495,1175,997],{"class":504},[495,1177,515],{"class":514},[495,1179,1180],{"class":514}," false",[495,1182,530],{"class":504},[495,1184,682],{"class":514},[1015,1186,1188],{"id":1187},"scopes","Scopes",[353,1190,1191],{},"Structural sharing applies to all cache write paths:",[366,1193,1194,1199,1205,1214],{},[369,1195,1196,1198],{},[357,1197,918],{}," after a successful network response",[369,1200,1201,1204],{},[357,1202,1203],{},"setQueryData"," for manual cache writes",[369,1206,1207,1053,1210,1213],{},[357,1208,1209],{},"setInfiniteQueryData",[357,1211,1212],{},"updateInfiniteQueryState"," for infinite queries",[369,1215,1216,1219],{},[357,1217,1218],{},"hydrateQuery"," when restoring persisted data into a non-initial entry",[403,1221],{},[348,1223,1225],{"id":1224},"transformation-pipeline","Transformation Pipeline",[353,1227,1228,1229,1053,1232,1235],{},"Qora lets you decouple data transformation from the fetcher via ",[357,1230,1231],{},"QoraOptions.transform",[357,1233,1234],{},"QoraOptions.transformError",". This keeps the fetcher simple (raw API call) and the transformation pure (testable in isolation).",[1015,1237,1239,1242],{"id":1238},"transform-success-path",[357,1240,1241],{},"transform",": success path",[353,1244,1245,1246,1249,1250,1253],{},"Called ",[372,1247,1248],{},"after"," the fetcher succeeds but ",[372,1251,1252],{},"before"," the data enters the cache (and before structural sharing). The transformed value is what gets cached and returned to callers.",[393,1255,1258],{"className":488,"code":1256,"filename":1257,"language":491,"meta":399,"style":399},"fetchQuery\u003CUser>(\n  key: ['users', userId],\n  fetcher: () => api.getUser(userId),  // returns Map\u003CString, dynamic>\n  options: QoraOptions(\n    transform: (raw) => User.fromJson(raw as Map\u003CString, dynamic>),\n  ),\n);\n","user_repository.dart",[357,1259,1260,1272,1290,1315,1325,1367,1374],{"__ignoreMap":399},[495,1261,1262,1264,1266,1269],{"class":497,"line":498},[495,1263,918],{"class":917},[495,1265,921],{"class":504},[495,1267,1268],{"class":501},"User",[495,1270,1271],{"class":504},">(\n",[495,1273,1274,1276,1278,1280,1283,1285,1288],{"class":497,"line":508},[495,1275,944],{"class":504},[495,1277,515],{"class":514},[495,1279,949],{"class":504},[495,1281,1282],{"class":952},"'users'",[495,1284,533],{"class":514},[495,1286,1287],{"class":504}," userId]",[495,1289,682],{"class":514},[495,1291,1292,1294,1296,1298,1300,1302,1304,1307,1310,1312],{"class":497,"line":540},[495,1293,964],{"class":504},[495,1295,515],{"class":514},[495,1297,969],{"class":504},[495,1299,972],{"class":514},[495,1301,975],{"class":504},[495,1303,742],{"class":514},[495,1305,1306],{"class":917},"getUser",[495,1308,1309],{"class":504},"(userId)",[495,1311,533],{"class":514},[495,1313,1314],{"class":536},"  // returns Map\u003CString, dynamic>\n",[495,1316,1317,1319,1321,1323],{"class":497,"line":564},[495,1318,990],{"class":504},[495,1320,515],{"class":514},[495,1322,661],{"class":501},[495,1324,505],{"class":504},[495,1326,1327,1330,1332,1335,1337,1340,1342,1345,1348,1351,1354,1356,1358,1360,1362,1365],{"class":497,"line":620},[495,1328,1329],{"class":504},"    transform",[495,1331,515],{"class":514},[495,1333,1334],{"class":504}," (raw) ",[495,1336,972],{"class":514},[495,1338,1339],{"class":501}," User",[495,1341,742],{"class":514},[495,1343,1344],{"class":917},"fromJson",[495,1346,1347],{"class":504},"(raw ",[495,1349,1350],{"class":514},"as",[495,1352,1353],{"class":501}," Map",[495,1355,921],{"class":504},[495,1357,929],{"class":501},[495,1359,932],{"class":504},[495,1361,935],{"class":501},[495,1363,1364],{"class":504},">)",[495,1366,682],{"class":514},[495,1368,1369,1372],{"class":497,"line":626},[495,1370,1371],{"class":504},"  )",[495,1373,682],{"class":514},[495,1375,1376,1378],{"class":497,"line":632},[495,1377,530],{"class":504},[495,1379,902],{"class":514},[1015,1381,1383,1386],{"id":1382},"transformerror-error-path",[357,1384,1385],{},"transformError",": error path",[353,1388,1245,1389,1391,1392,1394,1395,1398],{},[372,1390,1248],{}," all retries fail but ",[372,1393,1252],{}," the error enters the cache and before ",[357,1396,1397],{},"QoraClientConfig.errorMapper",". Use it to normalise error types at the query level.",[393,1400,1403],{"className":488,"code":1401,"filename":1402,"language":491,"meta":399,"style":399},"fetchQuery\u003CPost>(\n  key: ['post', postId],\n  fetcher: () => api.getPost(postId),\n  options: QoraOptions(\n    transformError: (error) => AppError.fromException(error),\n  ),\n);\n","post_repository.dart",[357,1404,1405,1416,1434,1456,1466,1491,1497],{"__ignoreMap":399},[495,1406,1407,1409,1411,1414],{"class":497,"line":498},[495,1408,918],{"class":917},[495,1410,921],{"class":504},[495,1412,1413],{"class":501},"Post",[495,1415,1271],{"class":504},[495,1417,1418,1420,1422,1424,1427,1429,1432],{"class":497,"line":508},[495,1419,944],{"class":504},[495,1421,515],{"class":514},[495,1423,949],{"class":504},[495,1425,1426],{"class":952},"'post'",[495,1428,533],{"class":514},[495,1430,1431],{"class":504}," postId]",[495,1433,682],{"class":514},[495,1435,1436,1438,1440,1442,1444,1446,1448,1451,1454],{"class":497,"line":540},[495,1437,964],{"class":504},[495,1439,515],{"class":514},[495,1441,969],{"class":504},[495,1443,972],{"class":514},[495,1445,975],{"class":504},[495,1447,742],{"class":514},[495,1449,1450],{"class":917},"getPost",[495,1452,1453],{"class":504},"(postId)",[495,1455,682],{"class":514},[495,1457,1458,1460,1462,1464],{"class":497,"line":564},[495,1459,990],{"class":504},[495,1461,515],{"class":514},[495,1463,661],{"class":501},[495,1465,505],{"class":504},[495,1467,1468,1471,1473,1476,1478,1481,1483,1486,1489],{"class":497,"line":620},[495,1469,1470],{"class":504},"    transformError",[495,1472,515],{"class":514},[495,1474,1475],{"class":504}," (error) ",[495,1477,972],{"class":514},[495,1479,1480],{"class":501}," AppError",[495,1482,742],{"class":514},[495,1484,1485],{"class":917},"fromException",[495,1487,1488],{"class":504},"(error)",[495,1490,682],{"class":514},[495,1492,1493,1495],{"class":497,"line":626},[495,1494,1371],{"class":504},[495,1496,682],{"class":514},[495,1498,1499,1501],{"class":497,"line":632},[495,1500,530],{"class":504},[495,1502,902],{"class":514},[403,1504],{},[348,1506,1508],{"id":1507},"keep-previous-data","Keep Previous Data",[353,1510,1511,1512,1515,1516,1519,1520,1522],{},"Use ",[357,1513,1514],{},"QoraOptions.keepPreviousData"," to suppress the loading flash during refetches. The entry stays in ",[357,1517,1518],{},"Success"," state with the previous data while the fetch is in progress, then transitions to ",[357,1521,1518],{}," with fresh data when the fetch completes.",[353,1524,1525,1526,1529],{},"This is especially useful for ",[372,1527,1528],{},"offset-based pagination",", where changing the page parameter triggers a fetch but you want the current page visible until the next one is ready:",[393,1531,1534],{"className":488,"code":1532,"filename":1533,"language":491,"meta":399,"style":399},"fetchQuery\u003CList\u003CPost>>(\n  key: ['posts', 'page', page],\n  fetcher: () => api.getPosts(page: page, limit: 20),\n  options: QoraOptions(\n    keepPreviousData: true,\n    staleTime: Duration.zero,\n  ),\n);\n","post_list.dart",[357,1535,1536,1550,1573,1612,1622,1632,1648,1654],{"__ignoreMap":399},[495,1537,1538,1540,1542,1544,1546,1548],{"class":497,"line":498},[495,1539,918],{"class":917},[495,1541,921],{"class":504},[495,1543,1033],{"class":501},[495,1545,921],{"class":504},[495,1547,1413],{"class":501},[495,1549,938],{"class":504},[495,1551,1552,1554,1556,1558,1561,1563,1566,1568,1571],{"class":497,"line":508},[495,1553,944],{"class":504},[495,1555,515],{"class":514},[495,1557,949],{"class":504},[495,1559,1560],{"class":952},"'posts'",[495,1562,533],{"class":514},[495,1564,1565],{"class":952}," 'page'",[495,1567,533],{"class":514},[495,1569,1570],{"class":504}," page]",[495,1572,682],{"class":514},[495,1574,1575,1577,1579,1581,1583,1585,1587,1590,1593,1595,1598,1600,1603,1605,1608,1610],{"class":497,"line":540},[495,1576,964],{"class":504},[495,1578,515],{"class":514},[495,1580,969],{"class":504},[495,1582,972],{"class":514},[495,1584,975],{"class":504},[495,1586,742],{"class":514},[495,1588,1589],{"class":917},"getPosts",[495,1591,1592],{"class":504},"(page",[495,1594,515],{"class":514},[495,1596,1597],{"class":504}," page",[495,1599,533],{"class":514},[495,1601,1602],{"class":504}," limit",[495,1604,515],{"class":514},[495,1606,1607],{"class":526}," 20",[495,1609,530],{"class":504},[495,1611,682],{"class":514},[495,1613,1614,1616,1618,1620],{"class":497,"line":564},[495,1615,990],{"class":504},[495,1617,515],{"class":514},[495,1619,661],{"class":501},[495,1621,505],{"class":504},[495,1623,1624,1627,1629],{"class":497,"line":620},[495,1625,1626],{"class":504},"    keepPreviousData",[495,1628,515],{"class":514},[495,1630,1631],{"class":514}," true,\n",[495,1633,1634,1637,1639,1641,1643,1646],{"class":497,"line":626},[495,1635,1636],{"class":504},"    staleTime",[495,1638,515],{"class":514},[495,1640,518],{"class":501},[495,1642,742],{"class":514},[495,1644,1645],{"class":504},"zero",[495,1647,682],{"class":514},[495,1649,1650,1652],{"class":497,"line":632},[495,1651,1371],{"class":504},[495,1653,682],{"class":514},[495,1655,1656,1658],{"class":497,"line":727},[495,1657,530],{"class":504},[495,1659,902],{"class":514},[353,1661,1662,1663,1665,1666,1669,1670,1672],{},"On fetch failure, the entry stays in ",[357,1664,1518],{}," with the previous data instead of transitioning to ",[357,1667,1668],{},"Failure",". The error is still propagated to imperative callers (",[357,1671,918],{},") so error handling (e.g. toasts, retry buttons) works as usual.",[403,1674],{},[348,1676,1678],{"id":1677},"lru-eviction","LRU Eviction",[353,1680,1681,1682,1685,1686,1688],{},"When ",[357,1683,1684],{},"maxCacheSize"," is set on ",[357,1687,220],{},", the cache enforces a limit using an LRU (Least Recently Used) strategy:",[366,1690,1691,1702],{},[369,1692,1693,1694,1697,1698,1701],{},"The entry that has been ",[372,1695,1696],{},"accessed least recently"," and has ",[372,1699,1700],{},"no active subscribers"," is evicted to make room",[369,1703,1704,1705],{},"Active entries (with subscribers) are ",[372,1706,1707],{},"never forcibly evicted",[393,1709,1711],{"className":488,"code":1710,"filename":490,"language":491,"meta":399,"style":399},"final client = QoraClient(\n  config: QoraClientConfig(maxCacheSize: 100),\n);\n",[357,1712,1713,1725,1747],{"__ignoreMap":399},[495,1714,1715,1717,1719,1721,1723],{"class":497,"line":498},[495,1716,887],{"class":886},[495,1718,890],{"class":504},[495,1720,893],{"class":514},[495,1722,896],{"class":501},[495,1724,505],{"class":504},[495,1726,1727,1730,1732,1735,1738,1740,1743,1745],{"class":497,"line":508},[495,1728,1729],{"class":504},"  config",[495,1731,515],{"class":514},[495,1733,1734],{"class":501}," QoraClientConfig",[495,1736,1737],{"class":504},"(maxCacheSize",[495,1739,515],{"class":514},[495,1741,1742],{"class":526}," 100",[495,1744,530],{"class":504},[495,1746,682],{"class":514},[495,1748,1749,1751],{"class":497,"line":540},[495,1750,530],{"class":504},[495,1752,902],{"class":514},[353,1754,1755,1756,932,1758,1761,1762,1765,1766,1769],{},"Each call to ",[357,1757,918],{},[357,1759,1760],{},"watchQuery",", or ",[357,1763,1764],{},"getQueryData"," updates ",[357,1767,1768],{},"lastAccessedAt",", keeping entries alive in the LRU ranking.",[403,1771],{},[348,1773,1775],{"id":1774},"manual-cache-control","Manual Cache Control",[1015,1777,1779],{"id":1778},"read-the-cache","Read the cache",[393,1781,1783],{"className":488,"code":1782,"filename":490,"language":491,"meta":399,"style":399},"// Get just the data (null if not Success / no previousData)\nfinal user = client.getQueryData\u003CUser>(['users', userId]);\n\n// Get the full state\nfinal state = client.getQueryState\u003CUser>(['users', userId]);\n\n// Inspect all cached keys\nfor (final key in client.cachedKeys) {\n  print(key);\n}\n",[357,1784,1785,1790,1821,1825,1830,1860,1864,1869,1892,1902],{"__ignoreMap":399},[495,1786,1787],{"class":497,"line":498},[495,1788,1789],{"class":536},"// Get just the data (null if not Success / no previousData)\n",[495,1791,1792,1794,1797,1799,1801,1803,1805,1807,1809,1812,1814,1816,1819],{"class":497,"line":508},[495,1793,887],{"class":886},[495,1795,1796],{"class":504}," user ",[495,1798,893],{"class":514},[495,1800,912],{"class":504},[495,1802,742],{"class":514},[495,1804,1764],{"class":917},[495,1806,921],{"class":504},[495,1808,1268],{"class":501},[495,1810,1811],{"class":504},">([",[495,1813,1282],{"class":952},[495,1815,533],{"class":514},[495,1817,1818],{"class":504}," userId])",[495,1820,902],{"class":514},[495,1822,1823],{"class":497,"line":540},[495,1824,607],{"emptyLinePlaceholder":606},[495,1826,1827],{"class":497,"line":564},[495,1828,1829],{"class":536},"// Get the full state\n",[495,1831,1832,1834,1837,1839,1841,1843,1846,1848,1850,1852,1854,1856,1858],{"class":497,"line":620},[495,1833,887],{"class":886},[495,1835,1836],{"class":504}," state ",[495,1838,893],{"class":514},[495,1840,912],{"class":504},[495,1842,742],{"class":514},[495,1844,1845],{"class":917},"getQueryState",[495,1847,921],{"class":504},[495,1849,1268],{"class":501},[495,1851,1811],{"class":504},[495,1853,1282],{"class":952},[495,1855,533],{"class":514},[495,1857,1818],{"class":504},[495,1859,902],{"class":514},[495,1861,1862],{"class":497,"line":626},[495,1863,607],{"emptyLinePlaceholder":606},[495,1865,1866],{"class":497,"line":632},[495,1867,1868],{"class":536},"// Inspect all cached keys\n",[495,1870,1871,1874,1877,1879,1882,1885,1887,1889],{"class":497,"line":727},[495,1872,1873],{"class":908},"for",[495,1875,1876],{"class":504}," (",[495,1878,887],{"class":886},[495,1880,1881],{"class":504}," key ",[495,1883,1884],{"class":908},"in",[495,1886,912],{"class":504},[495,1888,742],{"class":514},[495,1890,1891],{"class":504},"cachedKeys) {\n",[495,1893,1894,1897,1900],{"class":497,"line":905},[495,1895,1896],{"class":917},"  print",[495,1898,1899],{"class":504},"(key)",[495,1901,902],{"class":514},[495,1903,1904],{"class":497,"line":941},[495,1905,1906],{"class":504},"}\n",[1015,1908,1910],{"id":1909},"write-to-the-cache","Write to the cache",[393,1912,1914],{"className":488,"code":1913,"filename":490,"language":491,"meta":399,"style":399},"// Inject data directly: all active watchQuery streams are notified\nclient.setQueryData\u003CUser>(['users', userId], updatedUser);\n\n// Roll back to a previous snapshot\nfinal snapshot = client.getQueryData\u003CUser>(['users', userId]);\nclient.setQueryData(['users', userId], optimisticUser);\n\ntry {\n  await api.updateUser(userId, payload);\n} catch (_) {\n  client.restoreQueryData(['users', userId], snapshot);\n}\n",[357,1915,1916,1921,1949,1953,1958,1987,2011,2015,2023,2045,2056,2081],{"__ignoreMap":399},[495,1917,1918],{"class":497,"line":498},[495,1919,1920],{"class":536},"// Inject data directly: all active watchQuery streams are notified\n",[495,1922,1923,1926,1928,1930,1932,1934,1936,1938,1940,1942,1944,1947],{"class":497,"line":508},[495,1924,1925],{"class":504},"client",[495,1927,742],{"class":514},[495,1929,1203],{"class":917},[495,1931,921],{"class":504},[495,1933,1268],{"class":501},[495,1935,1811],{"class":504},[495,1937,1282],{"class":952},[495,1939,533],{"class":514},[495,1941,1287],{"class":504},[495,1943,533],{"class":514},[495,1945,1946],{"class":504}," updatedUser)",[495,1948,902],{"class":514},[495,1950,1951],{"class":497,"line":540},[495,1952,607],{"emptyLinePlaceholder":606},[495,1954,1955],{"class":497,"line":564},[495,1956,1957],{"class":536},"// Roll back to a previous snapshot\n",[495,1959,1960,1962,1965,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985],{"class":497,"line":620},[495,1961,887],{"class":886},[495,1963,1964],{"class":504}," snapshot ",[495,1966,893],{"class":514},[495,1968,912],{"class":504},[495,1970,742],{"class":514},[495,1972,1764],{"class":917},[495,1974,921],{"class":504},[495,1976,1268],{"class":501},[495,1978,1811],{"class":504},[495,1980,1282],{"class":952},[495,1982,533],{"class":514},[495,1984,1818],{"class":504},[495,1986,902],{"class":514},[495,1988,1989,1991,1993,1995,1998,2000,2002,2004,2006,2009],{"class":497,"line":626},[495,1990,1925],{"class":504},[495,1992,742],{"class":514},[495,1994,1203],{"class":917},[495,1996,1997],{"class":504},"([",[495,1999,1282],{"class":952},[495,2001,533],{"class":514},[495,2003,1287],{"class":504},[495,2005,533],{"class":514},[495,2007,2008],{"class":504}," optimisticUser)",[495,2010,902],{"class":514},[495,2012,2013],{"class":497,"line":632},[495,2014,607],{"emptyLinePlaceholder":606},[495,2016,2017,2020],{"class":497,"line":727},[495,2018,2019],{"class":908},"try",[495,2021,2022],{"class":504}," {\n",[495,2024,2025,2028,2030,2032,2035,2038,2040,2043],{"class":497,"line":905},[495,2026,2027],{"class":908},"  await",[495,2029,975],{"class":504},[495,2031,742],{"class":514},[495,2033,2034],{"class":917},"updateUser",[495,2036,2037],{"class":504},"(userId",[495,2039,533],{"class":514},[495,2041,2042],{"class":504}," payload)",[495,2044,902],{"class":514},[495,2046,2047,2050,2053],{"class":497,"line":941},[495,2048,2049],{"class":504},"} ",[495,2051,2052],{"class":908},"catch",[495,2054,2055],{"class":504}," (_) {\n",[495,2057,2058,2061,2063,2066,2068,2070,2072,2074,2076,2079],{"class":497,"line":961},[495,2059,2060],{"class":504},"  client",[495,2062,742],{"class":514},[495,2064,2065],{"class":917},"restoreQueryData",[495,2067,1997],{"class":504},[495,2069,1282],{"class":952},[495,2071,533],{"class":514},[495,2073,1287],{"class":504},[495,2075,533],{"class":514},[495,2077,2078],{"class":504}," snapshot)",[495,2080,902],{"class":514},[495,2082,2083],{"class":497,"line":987},[495,2084,1906],{"class":504},[1015,2086,2088],{"id":2087},"invalidate-mark-stale","Invalidate (mark stale)",[393,2090,2092],{"className":488,"code":2091,"filename":490,"language":491,"meta":399,"style":399},"// Single key: active streams transition to Loading immediately\nclient.invalidate(['users', userId]);\n\n// Multiple keys via predicate\nclient.invalidateWhere((key) => key.firstOrNull == 'users');\n\n// Tag-based: refetch all queries providing the 'post' tag\nclient.invalidateTags([QueryTag('post')]);\n\n// Specific resource: refetch only queries providing QueryTag('post', '123')\nclient.invalidateTags([QueryTag('post', '123')]);\n",[357,2093,2094,2099,2118,2122,2127,2158,2162,2167,2191,2195,2200],{"__ignoreMap":399},[495,2095,2096],{"class":497,"line":498},[495,2097,2098],{"class":536},"// Single key: active streams transition to Loading immediately\n",[495,2100,2101,2103,2105,2108,2110,2112,2114,2116],{"class":497,"line":508},[495,2102,1925],{"class":504},[495,2104,742],{"class":514},[495,2106,2107],{"class":917},"invalidate",[495,2109,1997],{"class":504},[495,2111,1282],{"class":952},[495,2113,533],{"class":514},[495,2115,1818],{"class":504},[495,2117,902],{"class":514},[495,2119,2120],{"class":497,"line":540},[495,2121,607],{"emptyLinePlaceholder":606},[495,2123,2124],{"class":497,"line":564},[495,2125,2126],{"class":536},"// Multiple keys via predicate\n",[495,2128,2129,2131,2133,2136,2139,2141,2144,2146,2149,2151,2154,2156],{"class":497,"line":620},[495,2130,1925],{"class":504},[495,2132,742],{"class":514},[495,2134,2135],{"class":917},"invalidateWhere",[495,2137,2138],{"class":504},"((key) ",[495,2140,972],{"class":514},[495,2142,2143],{"class":504}," key",[495,2145,742],{"class":514},[495,2147,2148],{"class":504},"firstOrNull ",[495,2150,1049],{"class":514},[495,2152,2153],{"class":952}," 'users'",[495,2155,530],{"class":504},[495,2157,902],{"class":514},[495,2159,2160],{"class":497,"line":626},[495,2161,607],{"emptyLinePlaceholder":606},[495,2163,2164],{"class":497,"line":632},[495,2165,2166],{"class":536},"// Tag-based: refetch all queries providing the 'post' tag\n",[495,2168,2169,2171,2173,2176,2178,2181,2184,2186,2189],{"class":497,"line":727},[495,2170,1925],{"class":504},[495,2172,742],{"class":514},[495,2174,2175],{"class":917},"invalidateTags",[495,2177,1997],{"class":504},[495,2179,2180],{"class":501},"QueryTag",[495,2182,2183],{"class":504},"(",[495,2185,1426],{"class":952},[495,2187,2188],{"class":504},")])",[495,2190,902],{"class":514},[495,2192,2193],{"class":497,"line":905},[495,2194,607],{"emptyLinePlaceholder":606},[495,2196,2197],{"class":497,"line":941},[495,2198,2199],{"class":536},"// Specific resource: refetch only queries providing QueryTag('post', '123')\n",[495,2201,2202,2204,2206,2208,2210,2212,2214,2216,2218,2221,2223],{"class":497,"line":961},[495,2203,1925],{"class":504},[495,2205,742],{"class":514},[495,2207,2175],{"class":917},[495,2209,1997],{"class":504},[495,2211,2180],{"class":501},[495,2213,2183],{"class":504},[495,2215,1426],{"class":952},[495,2217,533],{"class":514},[495,2219,2220],{"class":952}," '123'",[495,2222,2188],{"class":504},[495,2224,902],{"class":514},[353,2226,2227,2228,2231,2232,2234,2235,2231,2238,2241],{},"Tag-based invalidation is the most flexible approach. Queries declare tags via ",[357,2229,2230],{},"providesTags"," in ",[357,2233,215],{},". Mutations declare tags via ",[357,2236,2237],{},"invalidatesTags",[357,2239,2240],{},"MutationOptions",". Tags decouple invalidation from query-key structure: you can invalidate queries across different key patterns with a single tag.",[393,2243,2245],{"className":488,"code":2244,"filename":490,"language":491,"meta":399,"style":399},"options: QoraOptions(\n  providesTags: [QueryTag('post'), QueryTag('user', userId)],\n)\n",[357,2246,2247,2257,2290],{"__ignoreMap":399},[495,2248,2249,2251,2253,2255],{"class":497,"line":498},[495,2250,656],{"class":504},[495,2252,515],{"class":514},[495,2254,661],{"class":501},[495,2256,505],{"class":504},[495,2258,2259,2262,2264,2266,2268,2270,2272,2274,2276,2279,2281,2283,2285,2288],{"class":497,"line":508},[495,2260,2261],{"class":504},"  providesTags",[495,2263,515],{"class":514},[495,2265,949],{"class":504},[495,2267,2180],{"class":501},[495,2269,2183],{"class":504},[495,2271,1426],{"class":952},[495,2273,530],{"class":504},[495,2275,533],{"class":514},[495,2277,2278],{"class":501}," QueryTag",[495,2280,2183],{"class":504},[495,2282,1077],{"class":952},[495,2284,533],{"class":514},[495,2286,2287],{"class":504}," userId)]",[495,2289,682],{"class":514},[495,2291,2292],{"class":497,"line":540},[495,2293,567],{"class":504},[353,2295,2296,2297,1053,2302,742],{},"See ",[2298,2299,2301],"a",{"href":2300},"../api-reference/qora-mutation#invalidatestags","MutationOptions.invalidatesTags",[2298,2303,2305],{"href":2304},"../api-reference/qora-options#providestags","QoraOptions.providesTags",[1015,2307,2309],{"id":2308},"remove-and-clear","Remove and clear",[393,2311,2313],{"className":488,"code":2312,"filename":490,"language":491,"meta":399,"style":399},"// Remove a single entry (GC is immediate)\nclient.removeQuery(['users', userId]);\n\n// Wipe the entire cache (e.g. on logout)\nclient.clear();\n",[357,2314,2315,2320,2339,2343,2348],{"__ignoreMap":399},[495,2316,2317],{"class":497,"line":498},[495,2318,2319],{"class":536},"// Remove a single entry (GC is immediate)\n",[495,2321,2322,2324,2326,2329,2331,2333,2335,2337],{"class":497,"line":508},[495,2323,1925],{"class":504},[495,2325,742],{"class":514},[495,2327,2328],{"class":917},"removeQuery",[495,2330,1997],{"class":504},[495,2332,1282],{"class":952},[495,2334,533],{"class":514},[495,2336,1818],{"class":504},[495,2338,902],{"class":514},[495,2340,2341],{"class":497,"line":540},[495,2342,607],{"emptyLinePlaceholder":606},[495,2344,2345],{"class":497,"line":564},[495,2346,2347],{"class":536},"// Wipe the entire cache (e.g. on logout)\n",[495,2349,2350,2352,2354,2357,2359],{"class":497,"line":620},[495,2351,1925],{"class":504},[495,2353,742],{"class":514},[495,2355,2356],{"class":917},"clear",[495,2358,899],{"class":504},[495,2360,902],{"class":514},[403,2362],{},[348,2364,2366,2369],{"id":2365},"oncacheevict-callback",[357,2367,2368],{},"onCacheEvict"," Callback",[353,2371,2372],{},"React to cache evictions for logging or storage sync:",[393,2374,2376],{"className":488,"code":2375,"filename":490,"language":491,"meta":399,"style":399},"final client = QoraClient(\n  config: QoraClientConfig(\n    onCacheEvict: (key) {\n      analytics.track('cache_evict', {'key': key.toString()});\n    },\n  ),\n);\n",[357,2377,2378,2390,2400,2410,2446,2453,2459],{"__ignoreMap":399},[495,2379,2380,2382,2384,2386,2388],{"class":497,"line":498},[495,2381,887],{"class":886},[495,2383,890],{"class":504},[495,2385,893],{"class":514},[495,2387,896],{"class":501},[495,2389,505],{"class":504},[495,2391,2392,2394,2396,2398],{"class":497,"line":508},[495,2393,1729],{"class":504},[495,2395,515],{"class":514},[495,2397,1734],{"class":501},[495,2399,505],{"class":504},[495,2401,2402,2405,2407],{"class":497,"line":540},[495,2403,2404],{"class":504},"    onCacheEvict",[495,2406,515],{"class":514},[495,2408,2409],{"class":504}," (key) {\n",[495,2411,2412,2415,2417,2420,2422,2425,2427,2429,2432,2434,2436,2438,2441,2444],{"class":497,"line":564},[495,2413,2414],{"class":504},"      analytics",[495,2416,742],{"class":514},[495,2418,2419],{"class":917},"track",[495,2421,2183],{"class":504},[495,2423,2424],{"class":952},"'cache_evict'",[495,2426,533],{"class":514},[495,2428,1074],{"class":504},[495,2430,2431],{"class":952},"'key'",[495,2433,515],{"class":514},[495,2435,2143],{"class":504},[495,2437,742],{"class":514},[495,2439,2440],{"class":917},"toString",[495,2442,2443],{"class":504},"()})",[495,2445,902],{"class":514},[495,2447,2448,2451],{"class":497,"line":620},[495,2449,2450],{"class":504},"    }",[495,2452,682],{"class":514},[495,2454,2455,2457],{"class":497,"line":626},[495,2456,1371],{"class":504},[495,2458,682],{"class":514},[495,2460,2461,2463],{"class":497,"line":632},[495,2462,530],{"class":504},[495,2464,902],{"class":514},[403,2466],{},[348,2468,2470],{"id":2469},"debug-snapshot","Debug Snapshot",[393,2472,2474],{"className":488,"code":2473,"filename":490,"language":491,"meta":399,"style":399},"print(client.debugInfo());\n// {\n//   total_queries: 12,\n//   active_queries: 3,\n//   inactive_queries: 9,\n//   non_success_queries: 1,\n//   pending_requests: 2,\n//   max_size: 100,\n//   keys: [['users', 1], ['posts'], ...]\n// }\n",[357,2475,2476,2494,2499,2504,2509,2514,2519,2524,2529,2534],{"__ignoreMap":399},[495,2477,2478,2481,2484,2486,2489,2492],{"class":497,"line":498},[495,2479,2480],{"class":917},"print",[495,2482,2483],{"class":504},"(client",[495,2485,742],{"class":514},[495,2487,2488],{"class":917},"debugInfo",[495,2490,2491],{"class":504},"())",[495,2493,902],{"class":514},[495,2495,2496],{"class":497,"line":508},[495,2497,2498],{"class":536},"// {\n",[495,2500,2501],{"class":497,"line":540},[495,2502,2503],{"class":536},"//   total_queries: 12,\n",[495,2505,2506],{"class":497,"line":564},[495,2507,2508],{"class":536},"//   active_queries: 3,\n",[495,2510,2511],{"class":497,"line":620},[495,2512,2513],{"class":536},"//   inactive_queries: 9,\n",[495,2515,2516],{"class":497,"line":626},[495,2517,2518],{"class":536},"//   non_success_queries: 1,\n",[495,2520,2521],{"class":497,"line":632},[495,2522,2523],{"class":536},"//   pending_requests: 2,\n",[495,2525,2526],{"class":497,"line":727},[495,2527,2528],{"class":536},"//   max_size: 100,\n",[495,2530,2531],{"class":497,"line":905},[495,2532,2533],{"class":536},"//   keys: [['users', 1], ['posts'], ...]\n",[495,2535,2536],{"class":497,"line":941},[495,2537,2538],{"class":536},"// }\n",[403,2540],{},[348,2542,2544],{"id":2543},"global-vs-per-query-config","Global vs Per-query Config",[353,2546,2547,1053,2549,2551,2552,2555],{},[357,2548,435],{},[357,2550,431],{}," can be set globally via ",[357,2553,2554],{},"QoraClientConfig.defaultOptions"," and overridden per query:",[393,2557,2559],{"className":488,"code":2558,"filename":490,"language":491,"meta":399,"style":399},"final client = QoraClient(\n  config: QoraClientConfig(\n    defaultOptions: QoraOptions(\n      staleTime: Duration(minutes: 5),  // global default\n      gcTime: Duration(minutes: 10),\n    ),\n  ),\n);\n\n// This query overrides staleTime only\nawait client.fetchQuery\u003CConfig>(\n  key: ['config'],\n  fetcher: api.getConfig,\n  options: QoraOptions(staleTime: Duration(hours: 1)),\n  // gcTime still inherits 10 minutes from global\n);\n",[357,2560,2561,2573,2583,2594,2616,2635,2642,2648,2654,2658,2663,2680,2694,2708,2733,2739],{"__ignoreMap":399},[495,2562,2563,2565,2567,2569,2571],{"class":497,"line":498},[495,2564,887],{"class":886},[495,2566,890],{"class":504},[495,2568,893],{"class":514},[495,2570,896],{"class":501},[495,2572,505],{"class":504},[495,2574,2575,2577,2579,2581],{"class":497,"line":508},[495,2576,1729],{"class":504},[495,2578,515],{"class":514},[495,2580,1734],{"class":501},[495,2582,505],{"class":504},[495,2584,2585,2588,2590,2592],{"class":497,"line":540},[495,2586,2587],{"class":504},"    defaultOptions",[495,2589,515],{"class":514},[495,2591,661],{"class":501},[495,2593,505],{"class":504},[495,2595,2596,2599,2601,2603,2605,2607,2609,2611,2613],{"class":497,"line":564},[495,2597,2598],{"class":504},"      staleTime",[495,2600,515],{"class":514},[495,2602,518],{"class":501},[495,2604,521],{"class":504},[495,2606,515],{"class":514},[495,2608,527],{"class":526},[495,2610,530],{"class":504},[495,2612,533],{"class":514},[495,2614,2615],{"class":536},"  // global default\n",[495,2617,2618,2621,2623,2625,2627,2629,2631,2633],{"class":497,"line":620},[495,2619,2620],{"class":504},"      gcTime",[495,2622,515],{"class":514},[495,2624,518],{"class":501},[495,2626,521],{"class":504},[495,2628,515],{"class":514},[495,2630,554],{"class":526},[495,2632,530],{"class":504},[495,2634,682],{"class":514},[495,2636,2637,2640],{"class":497,"line":626},[495,2638,2639],{"class":504},"    )",[495,2641,682],{"class":514},[495,2643,2644,2646],{"class":497,"line":632},[495,2645,1371],{"class":504},[495,2647,682],{"class":514},[495,2649,2650,2652],{"class":497,"line":727},[495,2651,530],{"class":504},[495,2653,902],{"class":514},[495,2655,2656],{"class":497,"line":905},[495,2657,607],{"emptyLinePlaceholder":606},[495,2659,2660],{"class":497,"line":941},[495,2661,2662],{"class":536},"// This query overrides staleTime only\n",[495,2664,2665,2667,2669,2671,2673,2675,2678],{"class":497,"line":961},[495,2666,909],{"class":908},[495,2668,912],{"class":504},[495,2670,742],{"class":514},[495,2672,918],{"class":917},[495,2674,921],{"class":504},[495,2676,2677],{"class":501},"Config",[495,2679,1271],{"class":504},[495,2681,2682,2684,2686,2688,2690,2692],{"class":497,"line":987},[495,2683,944],{"class":504},[495,2685,515],{"class":514},[495,2687,949],{"class":504},[495,2689,953],{"class":952},[495,2691,956],{"class":504},[495,2693,682],{"class":514},[495,2695,2696,2698,2700,2702,2704,2706],{"class":497,"line":1009},[495,2697,964],{"class":504},[495,2699,515],{"class":514},[495,2701,975],{"class":504},[495,2703,742],{"class":514},[495,2705,980],{"class":504},[495,2707,682],{"class":514},[495,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729,2731],{"class":497,"line":2710},14,[495,2712,990],{"class":504},[495,2714,515],{"class":514},[495,2716,661],{"class":501},[495,2718,664],{"class":504},[495,2720,515],{"class":514},[495,2722,518],{"class":501},[495,2724,671],{"class":504},[495,2726,515],{"class":514},[495,2728,676],{"class":526},[495,2730,679],{"class":504},[495,2732,682],{"class":514},[495,2734,2736],{"class":497,"line":2735},15,[495,2737,2738],{"class":536},"  // gcTime still inherits 10 minutes from global\n",[495,2740,2742,2744],{"class":497,"line":2741},16,[495,2743,530],{"class":504},[495,2745,902],{"class":514},[403,2747],{},[348,2749,2751],{"id":2750},"next-steps","Next Steps",[366,2753,2754,2760,2766],{},[369,2755,2756,2759],{},[2298,2757,72],{"href":2758},"./stale-while-revalidate",": How background revalidation works",[369,2761,2762,2765],{},[2298,2763,77],{"href":2764},"./deduplication",": One network request for many callers",[369,2767,2768,2771],{},[2298,2769,2770],{"href":221},"QoraClientConfig API",": Full configuration reference",[2773,2774,2775],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .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}",{"title":399,"searchDepth":508,"depth":508,"links":2777},[2778,2779,2780,2782,2784,2786,2791,2797,2798,2799,2805,2807,2808,2809],{"id":350,"depth":508,"text":351},{"id":407,"depth":508,"text":408},{"id":428,"depth":508,"text":2781},"staleTime vs gcTime",{"id":583,"depth":508,"text":2783},"staleTime in Detail",{"id":752,"depth":508,"text":2785},"gcTime in Detail",{"id":831,"depth":508,"text":832,"children":2787},[2788,2789,2790],{"id":1017,"depth":540,"text":1018},{"id":1160,"depth":540,"text":1161},{"id":1187,"depth":540,"text":1188},{"id":1224,"depth":508,"text":1225,"children":2792},[2793,2795],{"id":1238,"depth":540,"text":2794},"transform: success path",{"id":1382,"depth":540,"text":2796},"transformError: error path",{"id":1507,"depth":508,"text":1508},{"id":1677,"depth":508,"text":1678},{"id":1774,"depth":508,"text":1775,"children":2800},[2801,2802,2803,2804],{"id":1778,"depth":540,"text":1779},{"id":1909,"depth":540,"text":1910},{"id":2087,"depth":540,"text":2088},{"id":2308,"depth":540,"text":2309},{"id":2365,"depth":508,"text":2806},"onCacheEvict Callback",{"id":2469,"depth":508,"text":2470},{"id":2543,"depth":508,"text":2544},{"id":2750,"depth":508,"text":2751},"Qora's cache enables instant data access. Learn how cache entries are created, aged, and garbage collected, how structural sharing prevents unnecessary rebuilds, and how to control each behavior.","md",null,{},{"icon":70},{"title":67,"description":2810},"myQ6LqMF1pTL4AzRxW6epFgkMLRZKMo2yCCt7uZbhkM",[2818,2820],{"title":62,"path":63,"stem":64,"description":2819,"icon":65,"children":-1},"Query states represent the lifecycle of your data fetching operations. Qora uses sealed classes to provide exhaustive, type-safe state handling that eliminates entire categories of runtime errors.",{"title":72,"path":73,"stem":74,"description":2821,"icon":75,"children":-1},"Qora SWR returns cached data immediately and revalidates in the background to keep UIs responsive and data current.",1794040396863]