[{"data":1,"prerenderedAt":2234},["ShallowReactive",2],{"navigation_docs":3,"-core-concepts-architecture":265,"-core-concepts-architecture-surround":2229},[4,35,49,89,117,164,193,235,253,257,261],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"/getting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","/getting-started/introduction","1.getting-started/2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Installation","/getting-started/installation","1.getting-started/3.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","/getting-started/quick-start","1.getting-started/4.quick-start","i-lucide-rocket",{"title":26,"path":27,"stem":28,"icon":29},"Configuration","/getting-started/configuration","1.getting-started/5.configuration","i-lucide-sliders-horizontal",{"title":31,"path":32,"stem":33,"icon":34},"First Auth","/getting-started/first-auth","1.getting-started/6.first-auth","i-lucide-key-round",{"title":36,"path":37,"stem":38,"children":39,"page":6},"Migration","/migration","10.migration",[40,45],{"title":41,"path":42,"stem":43,"icon":44},"Migration depuis Firebase Auth","/migration/from-firebase","10.migration/1.from-firebase","i-lucide-arrow-right-left",{"title":46,"path":47,"stem":48,"icon":44},"Migration depuis Supabase Auth","/migration/from-supabase","10.migration/2.from-supabase",{"title":50,"path":51,"stem":52,"children":53,"page":6},"Core Concepts","/core-concepts","2.core-concepts",[54,59,64,69,74,79,84],{"title":55,"path":56,"stem":57,"icon":58},"Architecture","/core-concepts/architecture","2.core-concepts/1.architecture","i-lucide-layers",{"title":60,"path":61,"stem":62,"icon":63},"Providers","/core-concepts/providers","2.core-concepts/2.providers","i-lucide-plug",{"title":65,"path":66,"stem":67,"icon":68},"Sessions","/core-concepts/sessions","2.core-concepts/3.sessions","i-lucide-timer",{"title":70,"path":71,"stem":72,"icon":73},"Storage","/core-concepts/storage","2.core-concepts/4.storage","i-lucide-database",{"title":75,"path":76,"stem":77,"icon":78},"Reactivity","/core-concepts/reactivity","2.core-concepts/5.reactivity","i-lucide-activity",{"title":80,"path":81,"stem":82,"icon":83},"Callbacks","/core-concepts/callbacks","2.core-concepts/6.callbacks","i-lucide-shield-check",{"title":85,"path":86,"stem":87,"icon":88},"Events","/core-concepts/events","2.core-concepts/7.events","i-lucide-radio",{"title":60,"path":90,"stem":91,"children":92,"page":6},"/providers","3.providers",[93,97,101,105,109,113],{"title":94,"path":95,"stem":96},"Credentials Provider","/providers/credentials","3.providers/1.credentials",{"title":98,"path":99,"stem":100},"OAuth2 Provider","/providers/oauth2","3.providers/2.oauth2",{"title":102,"path":103,"stem":104},"Google Provider","/providers/google","3.providers/3.google",{"title":106,"path":107,"stem":108},"GitHub Provider","/providers/github","3.providers/4.github",{"title":110,"path":111,"stem":112},"Apple Provider","/providers/apple","3.providers/5.apple",{"title":114,"path":115,"stem":116},"Proxy OAuth Provider","/providers/proxy-oauth","3.providers/6.proxy-oauth",{"title":118,"path":119,"stem":120,"children":121,"page":6},"Guides","/guides","4.guides",[122,126,131,136,141,146,151,155,159],{"title":123,"path":124,"stem":125},"Email / Password Auth","/guides/email-auth","4.guides/1.email-auth",{"title":127,"path":128,"stem":129,"icon":130},"Custom OAuth2 Flow","/guides/oauth2-flow","4.guides/2.oauth2-flow","i-lucide-workflow",{"title":132,"path":133,"stem":134,"icon":135},"Deep Links & OAuth2 Callbacks","/guides/deep-links","4.guides/3.deep-links","i-lucide-link",{"title":137,"path":138,"stem":139,"icon":140},"Token Refresh","/guides/token-refresh","4.guides/4.token-refresh","i-lucide-refresh-cw",{"title":142,"path":143,"stem":144,"icon":145},"Multi-Account","/guides/multi-account","4.guides/5.multi-account","i-lucide-users",{"title":147,"path":148,"stem":149,"icon":150},"Route Protection","/guides/route-protection","4.guides/6.route-protection","i-lucide-lock",{"title":152,"path":153,"stem":154,"icon":63},"Custom Provider","/guides/custom-provider","4.guides/7.custom-provider",{"title":156,"path":157,"stem":158,"icon":73},"Custom Storage","/guides/custom-storage","4.guides/8.custom-storage",{"title":160,"path":161,"stem":162,"icon":163},"Testing","/guides/testing","4.guides/9.testing","i-lucide-flask-conical",{"title":165,"path":166,"stem":167,"children":168,"page":6},"Flutter","/flutter","5.flutter",[169,173,178,183,188],{"title":170,"path":171,"stem":172},"Flutter Setup","/flutter/setup","5.flutter/1.setup",{"title":174,"path":175,"stem":176,"icon":177},"Secure Storage","/flutter/secure-storage","5.flutter/2.secure-storage","i-lucide-vault",{"title":179,"path":180,"stem":181,"icon":182},"Widgets","/flutter/widgets","5.flutter/3.widgets","i-lucide-layout",{"title":184,"path":185,"stem":186,"icon":187},"Router Guard","/flutter/router-guard","5.flutter/4.router-guard","i-lucide-signpost",{"title":189,"path":190,"stem":191,"icon":192},"App Binding","/flutter/app-binding","5.flutter/5.app-binding","i-lucide-cpu",{"title":194,"path":195,"stem":196,"children":197,"page":6},"API Reference","/api-reference","6.api-reference",[198,202,206,211,216,221,225,230],{"title":199,"path":200,"stem":201},"AuthyraClient","/api-reference/authyra-client","6.api-reference/1.authyra-client",{"title":203,"path":204,"stem":205},"AuthyraInstance","/api-reference/authyra-instance","6.api-reference/2.authyra-instance",{"title":207,"path":208,"stem":209,"icon":210},"AccountManager","/api-reference/account-manager","6.api-reference/3.account-manager","i-lucide-users-round",{"title":212,"path":213,"stem":214,"icon":215},"AuthProvider","/api-reference/auth-provider","6.api-reference/4.auth-provider","i-lucide-plug-zap",{"title":217,"path":218,"stem":219,"icon":220},"AuthStorage","/api-reference/auth-storage","6.api-reference/5.auth-storage","i-lucide-hard-drive",{"title":222,"path":223,"stem":224,"icon":68},"AuthSession","/api-reference/auth-session","6.api-reference/6.auth-session",{"title":226,"path":227,"stem":228,"icon":229},"AuthState","/api-reference/auth-state","6.api-reference/7.auth-state","i-lucide-toggle-right",{"title":231,"path":232,"stem":233,"icon":234},"Exceptions","/api-reference/auth-exceptions","6.api-reference/8.auth-exceptions","i-lucide-triangle-alert",{"title":236,"path":237,"stem":238,"children":239,"page":6},"Examples","/examples","7.examples",[240,244,249],{"title":241,"path":242,"stem":243},"Flutter App Example","/examples/flutter-app","7.examples/1.flutter-app",{"title":245,"path":246,"stem":247,"icon":248},"Dart Backend","/examples/dart-backend","7.examples/2.dart-backend","i-lucide-server",{"title":250,"path":251,"stem":252,"icon":163},"Testing Setup","/examples/testing-setup","7.examples/3.testing-setup",{"title":254,"path":255,"stem":256},"Troubleshooting","/troubleshooting","8.troubleshooting",{"title":258,"path":259,"stem":260},"FAQ","/faq","9.faq",{"title":262,"path":263,"stem":264},"Changelog","/changelog","changelog",{"id":266,"title":55,"body":267,"description":2220,"extension":2221,"links":2222,"meta":2223,"navigation":2224,"path":56,"seo":2225,"stem":57,"__hash__":2228},"docs/2.core-concepts/1.architecture.md",{"type":268,"value":269,"toc":2190},"minimark",[270,275,279,286,301,311,314,318,321,331,345,351,353,357,363,369,416,418,422,426,442,640,645,749,752,766,924,927,930,1107,1110,1225,1228,1231,1284,1462,1466,1484,1487,1493,1629,1631,1635,1639,1645,1649,1655,1659,1665,1667,1671,1674,1799,1808,1811,1970,1974,2071,2073,2077,2081,2106,2110,2120,2129,2133,2155,2159,2162,2164,2168,2186],[271,272,274],"h2",{"id":273},"the-big-picture","The big picture",[276,277,278],"p",{},"Authyra is built on three core principles:",[276,280,281,285],{},[282,283,284],"strong",{},"1. Separation of concerns"," — authentication logic lives in pure Dart, completely independent of UI and navigation.",[276,287,288,291,292,296,297,300],{},[282,289,290],{},"2. Reactive by default"," — every state change is surfaced as a ",[293,294,295],"code",{},"Stream",". Wire it to anything: ",[293,298,299],{},"StreamBuilder",", Riverpod, Bloc, GoRouter, or your own listener.",[276,302,303,306,307,310],{},[282,304,305],{},"3. Platform agnostic"," — the core ",[293,308,309],{},"authyra"," package imports nothing from Flutter. It runs identically on mobile, web, desktop, backend (Shelf, Dart Frog), and CLI tools.",[312,313],"hr",{},[271,315,317],{"id":316},"two-package-split","Two-package split",[276,319,320],{},"The monorepo ships two packages with a strict dependency direction:",[322,323,329],"pre",{"className":324,"code":326,"language":327,"meta":328},[325],"language-text","┌──────────────────────────────────────────────────────────┐\n│  authyra  (pure Dart)                                    │\n│                                                          │\n│  AuthyraClient · AuthyraInstance · SessionManager        │\n│  AccountManager · CredentialsProvider                    │\n│  AuthProvider interface · AuthStorage interface          │\n│  InMemoryStorage                                         │\n└──────────────────────────────────────────────────────────┘\n                         ▲ depends on\n┌──────────────────────────────────────────────────────────┐\n│  authyra_flutter  (Flutter + re-exports authyra)         │\n│                                                          │\n│  OAuth2Provider · GoogleProvider · GitHubOAuth2Provider  │\n│  AppleProvider · ProxyOAuthProvider                      │\n│  SecureAuthStorage · OAuth2CallbackHandler               │\n└──────────────────────────────────────────────────────────┘\n","text","",[293,330,326],{"__ignoreMap":328},[276,332,333,344],{},[282,334,335,336,339,340,343],{},"Anything that touches Flutter platform APIs, ",[293,337,338],{},"url_launcher",", or native platform channels lives in ",[293,341,342],{},"authyra_flutter","."," The core is pure Dart and has no knowledge of Flutter.",[276,346,347,348,350],{},"Flutter apps import ",[293,349,342],{}," — it re-exports the entire core, so one import gives access to everything.",[312,352],{},[271,354,356],{"id":355},"two-layer-design-within-the-core","Two-layer design within the core",[276,358,359,360,362],{},"Within ",[293,361,309],{},", there are two distinct layers:",[322,364,367],{"className":365,"code":366,"language":327,"meta":328},[325],"┌─────────────────────────────────────────────────────────────┐\n│  AuthyraClient                                              │\n│  Stateless orchestrator — no global state, fully testable   │\n│                                                             │\n│  ┌───────────────┐  ┌──────────────┐  ┌──────────────────┐ │\n│  │  AuthProvider  │  │  AuthStorage │  │  SessionManager  │ │\n│  │  (interface)   │  │  (interface) │  │  multi-account   │ │\n│  └───────────────┘  └──────────────┘  └──────────────────┘ │\n└──────────────────────────────┬──────────────────────────────┘\n                               │ wrapped by\n┌──────────────────────────────▼──────────────────────────────┐\n│  AuthyraInstance  (typedef alias: Authyra)                  │\n│  Singleton — global access, sync state cache, streams       │\n│                                                             │\n│  currentUser        AuthUser?            (synchronous)      │\n│  currentState       AuthState            (synchronous)      │\n│  isAuthenticated    bool                 (synchronous)      │\n│  authStateChanges   Stream\u003CAuthState>    (broadcast)        │\n│  sessionStream      Stream\u003CAuthSession?> (broadcast)        │\n│  accounts           AccountManager       (multi-account)    │\n└─────────────────────────────────────────────────────────────┘\n",[293,368,366],{"__ignoreMap":328},[370,371,372,388],"table",{},[373,374,375],"thead",{},[376,377,378,382,385],"tr",{},[379,380,381],"th",{},"Layer",[379,383,384],{},"Role",[379,386,387],{},"Use when",[389,390,391,404],"tbody",{},[376,392,393,398,401],{},[394,395,396],"td",{},[293,397,199],{},[394,399,400],{},"Pure business logic, injectable",[394,402,403],{},"Tests, backend APIs, multiple independent auth contexts",[376,405,406,410,413],{},[394,407,408],{},[293,409,203],{},[394,411,412],{},"Singleton with reactive streams and sync cache",[394,414,415],{},"Flutter apps and Dart programs that need global auth state",[312,417],{},[271,419,421],{"id":420},"component-overview","Component overview",[423,424,199],"h3",{"id":425},"authyraclient",[276,427,428,429,431,432,435,436,438,439,441],{},"The core orchestrator. It registers ",[293,430,212],{}," instances by ",[293,433,434],{},"id"," slug, delegates sign-in/sign-out/refresh to the matching provider, persists sessions via ",[293,437,217],{},", and emits ",[293,440,226],{}," on a broadcast stream.",[322,443,447],{"className":444,"code":445,"language":446,"meta":328,"style":328},"language-dart shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import 'package:authyra/authyra.dart';\n\nfinal client = AuthyraClient(\n  providers: [\n    CredentialsProvider.withTokens(id: 'email', authorize: myCallback),\n  ],\n  storage: InMemoryStorage(),\n);\n\nawait client.initialize();\nfinal user = await client.signIn('email', params: {...});\n","dart",[293,448,449,466,473,494,506,540,548,564,572,577,596],{"__ignoreMap":328},[450,451,454,458,462],"span",{"class":452,"line":453},"line",1,[450,455,457],{"class":456},"sbssI","import",[450,459,461],{"class":460},"sfazB"," 'package:authyra/authyra.dart'",[450,463,465],{"class":464},"sMK4o",";\n",[450,467,469],{"class":452,"line":468},2,[450,470,472],{"emptyLinePlaceholder":471},true,"\n",[450,474,476,480,484,487,491],{"class":452,"line":475},3,[450,477,479],{"class":478},"spNyl","final",[450,481,483],{"class":482},"sTEyZ"," client ",[450,485,486],{"class":464},"=",[450,488,490],{"class":489},"sBMFI"," AuthyraClient",[450,492,493],{"class":482},"(\n",[450,495,497,500,503],{"class":452,"line":496},4,[450,498,499],{"class":482},"  providers",[450,501,502],{"class":464},":",[450,504,505],{"class":482}," [\n",[450,507,509,512,514,518,521,523,526,529,532,534,537],{"class":452,"line":508},5,[450,510,511],{"class":489},"    CredentialsProvider",[450,513,343],{"class":464},[450,515,517],{"class":516},"s2Zo4","withTokens",[450,519,520],{"class":482},"(id",[450,522,502],{"class":464},[450,524,525],{"class":460}," 'email'",[450,527,528],{"class":464},",",[450,530,531],{"class":482}," authorize",[450,533,502],{"class":464},[450,535,536],{"class":482}," myCallback)",[450,538,539],{"class":464},",\n",[450,541,543,546],{"class":452,"line":542},6,[450,544,545],{"class":482},"  ]",[450,547,539],{"class":464},[450,549,551,554,556,559,562],{"class":452,"line":550},7,[450,552,553],{"class":482},"  storage",[450,555,502],{"class":464},[450,557,558],{"class":489}," InMemoryStorage",[450,560,561],{"class":482},"()",[450,563,539],{"class":464},[450,565,567,570],{"class":452,"line":566},8,[450,568,569],{"class":482},")",[450,571,465],{"class":464},[450,573,575],{"class":452,"line":574},9,[450,576,472],{"emptyLinePlaceholder":471},[450,578,580,584,587,589,592,594],{"class":452,"line":579},10,[450,581,583],{"class":582},"s7zQu","await",[450,585,586],{"class":482}," client",[450,588,343],{"class":464},[450,590,591],{"class":516},"initialize",[450,593,561],{"class":482},[450,595,465],{"class":464},[450,597,599,601,604,606,609,611,613,616,619,622,624,627,629,632,635,638],{"class":452,"line":598},11,[450,600,479],{"class":478},[450,602,603],{"class":482}," user ",[450,605,486],{"class":464},[450,607,608],{"class":582}," await",[450,610,586],{"class":482},[450,612,343],{"class":464},[450,614,615],{"class":516},"signIn",[450,617,618],{"class":482},"(",[450,620,621],{"class":460},"'email'",[450,623,528],{"class":464},[450,625,626],{"class":482}," params",[450,628,502],{"class":464},[450,630,631],{"class":482}," {",[450,633,634],{"class":464},"...",[450,636,637],{"class":482},"})",[450,639,465],{"class":464},[276,641,642,643,502],{},"For OAuth2 providers, use ",[293,644,342],{},[322,646,648],{"className":444,"code":647,"language":446,"meta":328,"style":328},"import 'package:authyra_flutter/authyra_flutter.dart';\n\nfinal client = AuthyraClient(\n  providers: [\n    CredentialsProvider.withTokens(id: 'email', authorize: myCallback),\n    GoogleProvider(clientId: 'YOUR_CLIENT_ID'),\n  ],\n  storage: SecureAuthStorage(),\n);\n",[293,649,650,659,663,675,683,707,724,730,743],{"__ignoreMap":328},[450,651,652,654,657],{"class":452,"line":453},[450,653,457],{"class":456},[450,655,656],{"class":460}," 'package:authyra_flutter/authyra_flutter.dart'",[450,658,465],{"class":464},[450,660,661],{"class":452,"line":468},[450,662,472],{"emptyLinePlaceholder":471},[450,664,665,667,669,671,673],{"class":452,"line":475},[450,666,479],{"class":478},[450,668,483],{"class":482},[450,670,486],{"class":464},[450,672,490],{"class":489},[450,674,493],{"class":482},[450,676,677,679,681],{"class":452,"line":496},[450,678,499],{"class":482},[450,680,502],{"class":464},[450,682,505],{"class":482},[450,684,685,687,689,691,693,695,697,699,701,703,705],{"class":452,"line":508},[450,686,511],{"class":489},[450,688,343],{"class":464},[450,690,517],{"class":516},[450,692,520],{"class":482},[450,694,502],{"class":464},[450,696,525],{"class":460},[450,698,528],{"class":464},[450,700,531],{"class":482},[450,702,502],{"class":464},[450,704,536],{"class":482},[450,706,539],{"class":464},[450,708,709,712,715,717,720,722],{"class":452,"line":542},[450,710,711],{"class":489},"    GoogleProvider",[450,713,714],{"class":482},"(clientId",[450,716,502],{"class":464},[450,718,719],{"class":460}," 'YOUR_CLIENT_ID'",[450,721,569],{"class":482},[450,723,539],{"class":464},[450,725,726,728],{"class":452,"line":550},[450,727,545],{"class":482},[450,729,539],{"class":464},[450,731,732,734,736,739,741],{"class":452,"line":566},[450,733,553],{"class":482},[450,735,502],{"class":464},[450,737,738],{"class":489}," SecureAuthStorage",[450,740,561],{"class":482},[450,742,539],{"class":464},[450,744,745,747],{"class":452,"line":574},[450,746,569],{"class":482},[450,748,465],{"class":464},[423,750,203],{"id":751},"authyrainstance",[276,753,754,755,758,759,762,763,765],{},"Singleton wrapper. One per process. Access via ",[293,756,757],{},"Authyra.instance"," (the ",[293,760,761],{},"Authyra"," typedef is a short alias for ",[293,764,203],{},"):",[322,767,769],{"className":444,"code":768,"language":446,"meta":328,"style":328},"await Authyra.initialize(client: client);\n\n// Synchronous — safe to call in build() without await\nAuthyra.instance.currentUser        // AuthUser?\nAuthyra.instance.isAuthenticated    // bool\n\n// Async accessors\nawait Authyra.instance.getSession()       // AuthSession?\nawait Authyra.instance.getAccessToken()   // String?\n\n// Reactive\nAuthyra.instance.authStateChanges.listen((state) { ... });\n",[293,770,771,792,796,802,819,835,839,844,865,886,890,895],{"__ignoreMap":328},[450,772,773,775,778,780,782,785,787,790],{"class":452,"line":453},[450,774,583],{"class":582},[450,776,777],{"class":489}," Authyra",[450,779,343],{"class":464},[450,781,591],{"class":516},[450,783,784],{"class":482},"(client",[450,786,502],{"class":464},[450,788,789],{"class":482}," client)",[450,791,465],{"class":464},[450,793,794],{"class":452,"line":468},[450,795,472],{"emptyLinePlaceholder":471},[450,797,798],{"class":452,"line":475},[450,799,801],{"class":800},"sHwdD","// Synchronous — safe to call in build() without await\n",[450,803,804,806,808,811,813,816],{"class":452,"line":496},[450,805,761],{"class":489},[450,807,343],{"class":464},[450,809,810],{"class":482},"instance",[450,812,343],{"class":464},[450,814,815],{"class":482},"currentUser        ",[450,817,818],{"class":800},"// AuthUser?\n",[450,820,821,823,825,827,829,832],{"class":452,"line":508},[450,822,761],{"class":489},[450,824,343],{"class":464},[450,826,810],{"class":482},[450,828,343],{"class":464},[450,830,831],{"class":482},"isAuthenticated    ",[450,833,834],{"class":800},"// bool\n",[450,836,837],{"class":452,"line":542},[450,838,472],{"emptyLinePlaceholder":471},[450,840,841],{"class":452,"line":550},[450,842,843],{"class":800},"// Async accessors\n",[450,845,846,848,850,852,854,856,859,862],{"class":452,"line":566},[450,847,583],{"class":582},[450,849,777],{"class":489},[450,851,343],{"class":464},[450,853,810],{"class":482},[450,855,343],{"class":464},[450,857,858],{"class":516},"getSession",[450,860,861],{"class":482},"()       ",[450,863,864],{"class":800},"// AuthSession?\n",[450,866,867,869,871,873,875,877,880,883],{"class":452,"line":574},[450,868,583],{"class":582},[450,870,777],{"class":489},[450,872,343],{"class":464},[450,874,810],{"class":482},[450,876,343],{"class":464},[450,878,879],{"class":516},"getAccessToken",[450,881,882],{"class":482},"()   ",[450,884,885],{"class":800},"// String?\n",[450,887,888],{"class":452,"line":579},[450,889,472],{"emptyLinePlaceholder":471},[450,891,892],{"class":452,"line":598},[450,893,894],{"class":800},"// Reactive\n",[450,896,898,900,902,904,906,909,911,914,917,919,922],{"class":452,"line":897},12,[450,899,761],{"class":489},[450,901,343],{"class":464},[450,903,810],{"class":482},[450,905,343],{"class":464},[450,907,908],{"class":482},"authStateChanges",[450,910,343],{"class":464},[450,912,913],{"class":516},"listen",[450,915,916],{"class":482},"((state) { ",[450,918,634],{"class":464},[450,920,921],{"class":482}," })",[450,923,465],{"class":464},[423,925,212],{"id":926},"authprovider",[276,928,929],{},"The extension point. Every authentication strategy implements this interface:",[322,931,933],{"className":444,"code":932,"language":446,"meta":328,"style":328},"abstract class AuthProvider {\n  String get id;                    // unique slug, e.g. 'google'\n  bool get supportsRefresh => false;\n  bool get supportsSignOut => false;\n\n  Future\u003CAuthSignInResult?> signIn({Map\u003CString, dynamic>? params});\n  Future\u003Cvoid> signOut({String? userId}) async {}\n  Future\u003CAuthTokenResult?> refreshToken(String refreshToken) async => null;\n}\n",[293,934,935,949,966,982,995,999,1043,1073,1102],{"__ignoreMap":328},[450,936,937,940,943,946],{"class":452,"line":453},[450,938,939],{"class":464},"abstract",[450,941,942],{"class":464}," class",[450,944,945],{"class":489}," AuthProvider",[450,947,948],{"class":482}," {\n",[450,950,951,954,957,960,963],{"class":452,"line":468},[450,952,953],{"class":489},"  String",[450,955,956],{"class":464}," get",[450,958,959],{"class":482}," id",[450,961,962],{"class":464},";",[450,964,965],{"class":800},"                    // unique slug, e.g. 'google'\n",[450,967,968,971,973,976,979],{"class":452,"line":475},[450,969,970],{"class":489},"  bool",[450,972,956],{"class":464},[450,974,975],{"class":482}," supportsRefresh ",[450,977,978],{"class":464},"=>",[450,980,981],{"class":464}," false;\n",[450,983,984,986,988,991,993],{"class":452,"line":496},[450,985,970],{"class":489},[450,987,956],{"class":464},[450,989,990],{"class":482}," supportsSignOut ",[450,992,978],{"class":464},[450,994,981],{"class":464},[450,996,997],{"class":452,"line":508},[450,998,472],{"emptyLinePlaceholder":471},[450,1000,1001,1004,1007,1010,1013,1015,1018,1021,1023,1026,1029,1032,1035,1038,1041],{"class":452,"line":542},[450,1002,1003],{"class":489},"  Future",[450,1005,1006],{"class":482},"\u003C",[450,1008,1009],{"class":489},"AuthSignInResult",[450,1011,1012],{"class":482},"?> ",[450,1014,615],{"class":516},[450,1016,1017],{"class":482},"({",[450,1019,1020],{"class":489},"Map",[450,1022,1006],{"class":482},[450,1024,1025],{"class":489},"String",[450,1027,1028],{"class":482},", ",[450,1030,1031],{"class":489},"dynamic",[450,1033,1034],{"class":482},">",[450,1036,1037],{"class":464},"?",[450,1039,1040],{"class":482}," params})",[450,1042,465],{"class":464},[450,1044,1045,1047,1049,1052,1055,1058,1060,1062,1064,1067,1070],{"class":452,"line":550},[450,1046,1003],{"class":489},[450,1048,1006],{"class":482},[450,1050,1051],{"class":478},"void",[450,1053,1054],{"class":482},"> ",[450,1056,1057],{"class":516},"signOut",[450,1059,1017],{"class":482},[450,1061,1025],{"class":489},[450,1063,1037],{"class":464},[450,1065,1066],{"class":482}," userId}) ",[450,1068,1069],{"class":582},"async",[450,1071,1072],{"class":482}," {}\n",[450,1074,1075,1077,1079,1082,1084,1087,1089,1091,1094,1096,1099],{"class":452,"line":566},[450,1076,1003],{"class":489},[450,1078,1006],{"class":482},[450,1080,1081],{"class":489},"AuthTokenResult",[450,1083,1012],{"class":482},[450,1085,1086],{"class":516},"refreshToken",[450,1088,618],{"class":482},[450,1090,1025],{"class":489},[450,1092,1093],{"class":482}," refreshToken) ",[450,1095,1069],{"class":582},[450,1097,1098],{"class":464}," =>",[450,1100,1101],{"class":464}," null;\n",[450,1103,1104],{"class":452,"line":574},[450,1105,1106],{"class":482},"}\n",[276,1108,1109],{},"Built-in providers and their package:",[370,1111,1112,1125],{},[373,1113,1114],{},[376,1115,1116,1119,1122],{},[379,1117,1118],{},"Provider",[379,1120,1121],{},"Package",[379,1123,1124],{},"Strategy",[389,1126,1127,1141,1155,1169,1183,1197,1211],{},[376,1128,1129,1134,1138],{},[394,1130,1131],{},[293,1132,1133],{},"CredentialsProvider",[394,1135,1136],{},[293,1137,309],{},[394,1139,1140],{},"Email / password, any form-based flow",[376,1142,1143,1148,1152],{},[394,1144,1145],{},[293,1146,1147],{},"CredentialsProvider.withTokens",[394,1149,1150],{},[293,1151,309],{},[394,1153,1154],{},"JWT backend — stores access + refresh tokens",[376,1156,1157,1162,1166],{},[394,1158,1159],{},[293,1160,1161],{},"OAuth2Provider",[394,1163,1164],{},[293,1165,342],{},[394,1167,1168],{},"Authorization Code + PKCE (any IdP)",[376,1170,1171,1176,1180],{},[394,1172,1173],{},[293,1174,1175],{},"GoogleProvider",[394,1177,1178],{},[293,1179,342],{},[394,1181,1182],{},"Prebuilt Google Sign-In",[376,1184,1185,1190,1194],{},[394,1186,1187],{},[293,1188,1189],{},"GitHubOAuth2Provider",[394,1191,1192],{},[293,1193,342],{},[394,1195,1196],{},"Prebuilt GitHub OAuth",[376,1198,1199,1204,1208],{},[394,1200,1201],{},[293,1202,1203],{},"AppleProvider",[394,1205,1206],{},[293,1207,342],{},[394,1209,1210],{},"Sign in with Apple",[376,1212,1213,1218,1222],{},[394,1214,1215],{},[293,1216,1217],{},"ProxyOAuthProvider",[394,1219,1220],{},[293,1221,342],{},[394,1223,1224],{},"Backend-delegated — client secret never in app",[423,1226,217],{"id":1227},"authstorage",[276,1229,1230],{},"Pluggable persistence interface. Production implementations:",[370,1232,1233,1243],{},[373,1234,1235],{},[376,1236,1237,1240],{},[379,1238,1239],{},"Runtime",[379,1241,1242],{},"Implementation",[389,1244,1245,1261,1271],{},[376,1246,1247,1249],{},[394,1248,165],{},[394,1250,1251,1254,1255,1257,1258,569],{},[293,1252,1253],{},"SecureAuthStorage"," (in ",[293,1256,342],{},", wraps ",[293,1259,1260],{},"flutter_secure_storage",[376,1262,1263,1266],{},[394,1264,1265],{},"Dart backend",[394,1267,1268,1269],{},"Your own Redis / DB implementation of ",[293,1270,217],{},[376,1272,1273,1276],{},[394,1274,1275],{},"Tests",[394,1277,1278,1281,1282,569],{},[293,1279,1280],{},"InMemoryStorage"," (bundled in ",[293,1283,309],{},[322,1285,1287],{"className":444,"code":1286,"language":446,"meta":328,"style":328},"abstract class AuthStorage {\n  Future\u003Cvoid>         initialize();\n  Future\u003CString?>      read(String key);\n  Future\u003Cvoid>         write(String key, String value);\n  Future\u003Cbool>         delete(String key);\n  Future\u003Cvoid>         clear();\n  Future\u003Cbool>         containsKey(String key);\n  Future\u003CList\u003CString>> getKeysWithPrefix(String prefix);\n}\n",[293,1288,1289,1300,1317,1340,1370,1392,1409,1430,1458],{"__ignoreMap":328},[450,1290,1291,1293,1295,1298],{"class":452,"line":453},[450,1292,939],{"class":464},[450,1294,942],{"class":464},[450,1296,1297],{"class":489}," AuthStorage",[450,1299,948],{"class":482},[450,1301,1302,1304,1306,1308,1311,1313,1315],{"class":452,"line":468},[450,1303,1003],{"class":489},[450,1305,1006],{"class":482},[450,1307,1051],{"class":478},[450,1309,1310],{"class":482},">         ",[450,1312,591],{"class":516},[450,1314,561],{"class":482},[450,1316,465],{"class":464},[450,1318,1319,1321,1323,1325,1328,1331,1333,1335,1338],{"class":452,"line":475},[450,1320,1003],{"class":489},[450,1322,1006],{"class":482},[450,1324,1025],{"class":489},[450,1326,1327],{"class":482},"?>      ",[450,1329,1330],{"class":516},"read",[450,1332,618],{"class":482},[450,1334,1025],{"class":489},[450,1336,1337],{"class":482}," key)",[450,1339,465],{"class":464},[450,1341,1342,1344,1346,1348,1350,1353,1355,1357,1360,1362,1365,1368],{"class":452,"line":496},[450,1343,1003],{"class":489},[450,1345,1006],{"class":482},[450,1347,1051],{"class":478},[450,1349,1310],{"class":482},[450,1351,1352],{"class":516},"write",[450,1354,618],{"class":482},[450,1356,1025],{"class":489},[450,1358,1359],{"class":482}," key",[450,1361,528],{"class":464},[450,1363,1364],{"class":489}," String",[450,1366,1367],{"class":482}," value)",[450,1369,465],{"class":464},[450,1371,1372,1374,1376,1379,1381,1384,1386,1388,1390],{"class":452,"line":508},[450,1373,1003],{"class":489},[450,1375,1006],{"class":482},[450,1377,1378],{"class":489},"bool",[450,1380,1310],{"class":482},[450,1382,1383],{"class":516},"delete",[450,1385,618],{"class":482},[450,1387,1025],{"class":489},[450,1389,1337],{"class":482},[450,1391,465],{"class":464},[450,1393,1394,1396,1398,1400,1402,1405,1407],{"class":452,"line":542},[450,1395,1003],{"class":489},[450,1397,1006],{"class":482},[450,1399,1051],{"class":478},[450,1401,1310],{"class":482},[450,1403,1404],{"class":516},"clear",[450,1406,561],{"class":482},[450,1408,465],{"class":464},[450,1410,1411,1413,1415,1417,1419,1422,1424,1426,1428],{"class":452,"line":550},[450,1412,1003],{"class":489},[450,1414,1006],{"class":482},[450,1416,1378],{"class":489},[450,1418,1310],{"class":482},[450,1420,1421],{"class":516},"containsKey",[450,1423,618],{"class":482},[450,1425,1025],{"class":489},[450,1427,1337],{"class":482},[450,1429,465],{"class":464},[450,1431,1432,1434,1436,1439,1441,1443,1446,1449,1451,1453,1456],{"class":452,"line":566},[450,1433,1003],{"class":489},[450,1435,1006],{"class":482},[450,1437,1438],{"class":489},"List",[450,1440,1006],{"class":482},[450,1442,1025],{"class":489},[450,1444,1445],{"class":482},">> ",[450,1447,1448],{"class":516},"getKeysWithPrefix",[450,1450,618],{"class":482},[450,1452,1025],{"class":489},[450,1454,1455],{"class":482}," prefix)",[450,1457,465],{"class":464},[450,1459,1460],{"class":452,"line":574},[450,1461,1106],{"class":482},[423,1463,1465],{"id":1464},"sessionmanager","SessionManager",[276,1467,1468,1469,1472,1473,1475,1476,1479,1480,1483],{},"Internal component. Serialises/deserialises ",[293,1470,1471],{},"SessionRegistry"," to/from ",[293,1474,217],{},", uses a mutex to serialise concurrent writes, and exposes ",[293,1477,1478],{},"cleanExpiredSessions()"," (called via ",[293,1481,1482],{},"AccountManager.cleanExpired()",").",[423,1485,207],{"id":1486},"accountmanager",[276,1488,1489,1490,502],{},"Multi-account API, accessible via ",[293,1491,1492],{},"Authyra.instance.accounts",[322,1494,1496],{"className":444,"code":1495,"language":446,"meta":328,"style":328},"await Authyra.instance.accounts.getAll();          // List\u003CAuthUser>\nawait Authyra.instance.accounts.switchTo(userId);  // activate a different account\nawait Authyra.instance.accounts.signOut(userId);   // sign out one account\nawait Authyra.instance.accounts.signOutAll();      // clear every session\nawait Authyra.instance.accounts.cleanExpired();    // remove expired sessions\n",[293,1497,1498,1525,1552,1577,1603],{"__ignoreMap":328},[450,1499,1500,1502,1504,1506,1508,1510,1513,1515,1518,1520,1522],{"class":452,"line":453},[450,1501,583],{"class":582},[450,1503,777],{"class":489},[450,1505,343],{"class":464},[450,1507,810],{"class":482},[450,1509,343],{"class":464},[450,1511,1512],{"class":482},"accounts",[450,1514,343],{"class":464},[450,1516,1517],{"class":516},"getAll",[450,1519,561],{"class":482},[450,1521,962],{"class":464},[450,1523,1524],{"class":800},"          // List\u003CAuthUser>\n",[450,1526,1527,1529,1531,1533,1535,1537,1539,1541,1544,1547,1549],{"class":452,"line":468},[450,1528,583],{"class":582},[450,1530,777],{"class":489},[450,1532,343],{"class":464},[450,1534,810],{"class":482},[450,1536,343],{"class":464},[450,1538,1512],{"class":482},[450,1540,343],{"class":464},[450,1542,1543],{"class":516},"switchTo",[450,1545,1546],{"class":482},"(userId)",[450,1548,962],{"class":464},[450,1550,1551],{"class":800},"  // activate a different account\n",[450,1553,1554,1556,1558,1560,1562,1564,1566,1568,1570,1572,1574],{"class":452,"line":475},[450,1555,583],{"class":582},[450,1557,777],{"class":489},[450,1559,343],{"class":464},[450,1561,810],{"class":482},[450,1563,343],{"class":464},[450,1565,1512],{"class":482},[450,1567,343],{"class":464},[450,1569,1057],{"class":516},[450,1571,1546],{"class":482},[450,1573,962],{"class":464},[450,1575,1576],{"class":800},"   // sign out one account\n",[450,1578,1579,1581,1583,1585,1587,1589,1591,1593,1596,1598,1600],{"class":452,"line":496},[450,1580,583],{"class":582},[450,1582,777],{"class":489},[450,1584,343],{"class":464},[450,1586,810],{"class":482},[450,1588,343],{"class":464},[450,1590,1512],{"class":482},[450,1592,343],{"class":464},[450,1594,1595],{"class":516},"signOutAll",[450,1597,561],{"class":482},[450,1599,962],{"class":464},[450,1601,1602],{"class":800},"      // clear every session\n",[450,1604,1605,1607,1609,1611,1613,1615,1617,1619,1622,1624,1626],{"class":452,"line":508},[450,1606,583],{"class":582},[450,1608,777],{"class":489},[450,1610,343],{"class":464},[450,1612,810],{"class":482},[450,1614,343],{"class":464},[450,1616,1512],{"class":482},[450,1618,343],{"class":464},[450,1620,1621],{"class":516},"cleanExpired",[450,1623,561],{"class":482},[450,1625,962],{"class":464},[450,1627,1628],{"class":800},"    // remove expired sessions\n",[312,1630],{},[271,1632,1634],{"id":1633},"data-flow","Data flow",[423,1636,1638],{"id":1637},"sign-in-flow","Sign in flow",[322,1640,1643],{"className":1641,"code":1642,"language":327,"meta":328},[325],"signIn('email', params: {...})\n    │\n    ├─ _assertInitialized()\n    ├─ _providerMap['email'].signIn(params)        ← your callback\n    │      returns AuthSignInResult\n    ├─ Build AuthSession from result\n    ├─ SessionManager.saveSession(session)          ← persisted to AuthStorage\n    ├─ authStateStream.add(AuthState.authenticated(user))\n    └─ AuthyraInstance._currentState = new state\n           └─ authStateChanges emits\n",[293,1644,1642],{"__ignoreMap":328},[423,1646,1648],{"id":1647},"sign-out-flow","Sign out flow",[322,1650,1653],{"className":1651,"code":1652,"language":327,"meta":328},[325],"signOut()\n    │\n    ├─ SessionManager.getActiveSession()\n    ├─ provider.signOut(userId)  [only if supportsSignOut == true]\n    ├─ SessionManager.clearActiveSession()\n    └─ authStateStream.add(AuthState.unauthenticated())\n",[293,1654,1652],{"__ignoreMap":328},[423,1656,1658],{"id":1657},"token-refresh-flow","Token refresh flow",[322,1660,1663],{"className":1661,"code":1662,"language":327,"meta":328},[325],"refreshSession()\n    │\n    ├─ SessionManager.getActiveSession()\n    ├─ provider.refreshToken(session.refreshToken)\n    │      returns AuthTokenResult\n    ├─ session.refreshed(result) → new AuthSession\n    ├─ SessionManager.updateSession(userId, newSession)\n    └─ authStateStream.add(AuthState.authenticated(user))\n",[293,1664,1662],{"__ignoreMap":328},[312,1666],{},[271,1668,1670],{"id":1669},"key-models","Key models",[423,1672,226],{"id":1673},"authstate",[322,1675,1677],{"className":444,"code":1676,"language":446,"meta":328,"style":328},"enum AuthStateType { authenticated, unauthenticated, error }\n\nclass AuthState extends Equatable {\n  final AuthStateType type;\n  final AuthUser? user;    // non-null when authenticated\n  final String?   error;   // non-null when type == error\n\n  bool get isAuthenticated => type == AuthStateType.authenticated;\n}\n",[293,1678,1679,1700,1704,1720,1732,1749,1765,1769,1795],{"__ignoreMap":328},[450,1680,1681,1684,1687,1690,1692,1695,1697],{"class":452,"line":453},[450,1682,1683],{"class":464},"enum",[450,1685,1686],{"class":489}," AuthStateType",[450,1688,1689],{"class":482}," { authenticated",[450,1691,528],{"class":464},[450,1693,1694],{"class":482}," unauthenticated",[450,1696,528],{"class":464},[450,1698,1699],{"class":482}," error }\n",[450,1701,1702],{"class":452,"line":468},[450,1703,472],{"emptyLinePlaceholder":471},[450,1705,1706,1709,1712,1715,1718],{"class":452,"line":475},[450,1707,1708],{"class":464},"class",[450,1710,1711],{"class":489}," AuthState",[450,1713,1714],{"class":464}," extends",[450,1716,1717],{"class":489}," Equatable",[450,1719,948],{"class":482},[450,1721,1722,1725,1727,1730],{"class":452,"line":496},[450,1723,1724],{"class":478},"  final",[450,1726,1686],{"class":489},[450,1728,1729],{"class":482}," type",[450,1731,465],{"class":464},[450,1733,1734,1736,1739,1741,1744,1746],{"class":452,"line":508},[450,1735,1724],{"class":478},[450,1737,1738],{"class":489}," AuthUser",[450,1740,1037],{"class":464},[450,1742,1743],{"class":482}," user",[450,1745,962],{"class":464},[450,1747,1748],{"class":800},"    // non-null when authenticated\n",[450,1750,1751,1753,1755,1757,1760,1762],{"class":452,"line":542},[450,1752,1724],{"class":478},[450,1754,1364],{"class":489},[450,1756,1037],{"class":464},[450,1758,1759],{"class":482},"   error",[450,1761,962],{"class":464},[450,1763,1764],{"class":800},"   // non-null when type == error\n",[450,1766,1767],{"class":452,"line":550},[450,1768,472],{"emptyLinePlaceholder":471},[450,1770,1771,1773,1775,1778,1780,1783,1786,1788,1790,1793],{"class":452,"line":566},[450,1772,970],{"class":489},[450,1774,956],{"class":464},[450,1776,1777],{"class":482}," isAuthenticated ",[450,1779,978],{"class":464},[450,1781,1782],{"class":482}," type ",[450,1784,1785],{"class":464},"==",[450,1787,1686],{"class":489},[450,1789,343],{"class":464},[450,1791,1792],{"class":482},"authenticated",[450,1794,465],{"class":464},[450,1796,1797],{"class":452,"line":574},[450,1798,1106],{"class":482},[276,1800,1801,1804,1805,1807],{},[293,1802,1803],{},"Equatable"," ensures identical consecutive states are deduplicated — no spurious ",[293,1806,299],{}," rebuilds.",[423,1809,222],{"id":1810},"authsession",[322,1812,1814],{"className":444,"code":1813,"language":446,"meta":328,"style":328},"class AuthSession {\n  final AuthUser   user;\n  final String?    accessToken;\n  final String?    refreshToken;\n  final DateTime?  expiresAt;\n  final DateTime   createdAt;\n  final DateTime   lastUsedAt;\n\n  bool get isExpired     => expiresAt != null && DateTime.now().isAfter(expiresAt!);\n  bool get shouldRefresh => ...; // true when within the refresh threshold window\n}\n",[293,1815,1816,1825,1836,1849,1862,1876,1887,1898,1902,1949,1966],{"__ignoreMap":328},[450,1817,1818,1820,1823],{"class":452,"line":453},[450,1819,1708],{"class":464},[450,1821,1822],{"class":489}," AuthSession",[450,1824,948],{"class":482},[450,1826,1827,1829,1831,1834],{"class":452,"line":468},[450,1828,1724],{"class":478},[450,1830,1738],{"class":489},[450,1832,1833],{"class":482},"   user",[450,1835,465],{"class":464},[450,1837,1838,1840,1842,1844,1847],{"class":452,"line":475},[450,1839,1724],{"class":478},[450,1841,1364],{"class":489},[450,1843,1037],{"class":464},[450,1845,1846],{"class":482},"    accessToken",[450,1848,465],{"class":464},[450,1850,1851,1853,1855,1857,1860],{"class":452,"line":496},[450,1852,1724],{"class":478},[450,1854,1364],{"class":489},[450,1856,1037],{"class":464},[450,1858,1859],{"class":482},"    refreshToken",[450,1861,465],{"class":464},[450,1863,1864,1866,1869,1871,1874],{"class":452,"line":508},[450,1865,1724],{"class":478},[450,1867,1868],{"class":489}," DateTime",[450,1870,1037],{"class":464},[450,1872,1873],{"class":482},"  expiresAt",[450,1875,465],{"class":464},[450,1877,1878,1880,1882,1885],{"class":452,"line":542},[450,1879,1724],{"class":478},[450,1881,1868],{"class":489},[450,1883,1884],{"class":482},"   createdAt",[450,1886,465],{"class":464},[450,1888,1889,1891,1893,1896],{"class":452,"line":550},[450,1890,1724],{"class":478},[450,1892,1868],{"class":489},[450,1894,1895],{"class":482},"   lastUsedAt",[450,1897,465],{"class":464},[450,1899,1900],{"class":452,"line":566},[450,1901,472],{"emptyLinePlaceholder":471},[450,1903,1904,1906,1908,1911,1913,1916,1919,1922,1925,1927,1929,1932,1934,1936,1939,1942,1945,1947],{"class":452,"line":574},[450,1905,970],{"class":489},[450,1907,956],{"class":464},[450,1909,1910],{"class":482}," isExpired     ",[450,1912,978],{"class":464},[450,1914,1915],{"class":482}," expiresAt ",[450,1917,1918],{"class":464},"!=",[450,1920,1921],{"class":464}," null",[450,1923,1924],{"class":464}," &&",[450,1926,1868],{"class":489},[450,1928,343],{"class":464},[450,1930,1931],{"class":516},"now",[450,1933,561],{"class":482},[450,1935,343],{"class":464},[450,1937,1938],{"class":516},"isAfter",[450,1940,1941],{"class":482},"(expiresAt",[450,1943,1944],{"class":464},"!",[450,1946,569],{"class":482},[450,1948,465],{"class":464},[450,1950,1951,1953,1955,1958,1960,1963],{"class":452,"line":579},[450,1952,970],{"class":489},[450,1954,956],{"class":464},[450,1956,1957],{"class":482}," shouldRefresh ",[450,1959,978],{"class":464},[450,1961,1962],{"class":464}," ...;",[450,1964,1965],{"class":800}," // true when within the refresh threshold window\n",[450,1967,1968],{"class":452,"line":598},[450,1969,1106],{"class":482},[423,1971,1973],{"id":1972},"authuser","AuthUser",[322,1975,1977],{"className":444,"code":1976,"language":446,"meta":328,"style":328},"AuthUser(\n  id:        'usr_01j...',\n  email:     'alice@example.com',\n  name:      'Alice',\n  avatarUrl: 'https://...',\n  metadata:  {'role': 'admin', 'plan': 'pro'},\n)\n",[293,1978,1979,1985,1997,2009,2021,2033,2066],{"__ignoreMap":328},[450,1980,1981,1983],{"class":452,"line":453},[450,1982,1973],{"class":489},[450,1984,493],{"class":482},[450,1986,1987,1990,1992,1995],{"class":452,"line":468},[450,1988,1989],{"class":482},"  id",[450,1991,502],{"class":464},[450,1993,1994],{"class":460},"        'usr_01j...'",[450,1996,539],{"class":464},[450,1998,1999,2002,2004,2007],{"class":452,"line":475},[450,2000,2001],{"class":482},"  email",[450,2003,502],{"class":464},[450,2005,2006],{"class":460},"     'alice@example.com'",[450,2008,539],{"class":464},[450,2010,2011,2014,2016,2019],{"class":452,"line":496},[450,2012,2013],{"class":482},"  name",[450,2015,502],{"class":464},[450,2017,2018],{"class":460},"      'Alice'",[450,2020,539],{"class":464},[450,2022,2023,2026,2028,2031],{"class":452,"line":508},[450,2024,2025],{"class":482},"  avatarUrl",[450,2027,502],{"class":464},[450,2029,2030],{"class":460}," 'https://...'",[450,2032,539],{"class":464},[450,2034,2035,2038,2040,2043,2046,2048,2051,2053,2056,2058,2061,2064],{"class":452,"line":542},[450,2036,2037],{"class":482},"  metadata",[450,2039,502],{"class":464},[450,2041,2042],{"class":482},"  {",[450,2044,2045],{"class":460},"'role'",[450,2047,502],{"class":464},[450,2049,2050],{"class":460}," 'admin'",[450,2052,528],{"class":464},[450,2054,2055],{"class":460}," 'plan'",[450,2057,502],{"class":464},[450,2059,2060],{"class":460}," 'pro'",[450,2062,2063],{"class":482},"}",[450,2065,539],{"class":464},[450,2067,2068],{"class":452,"line":550},[450,2069,2070],{"class":482},")\n",[312,2072],{},[271,2074,2076],{"id":2075},"design-decisions","Design decisions",[423,2078,2080],{"id":2079},"why-no-flutter-dependency-in-the-core","Why no Flutter dependency in the core?",[2082,2083,2084,2092,2098],"ul",{},[2085,2086,2087,2088,2091],"li",{},"Tests run with plain ",[293,2089,2090],{},"dart test"," — no widget test runner, no platform channels.",[2085,2093,2094,2095,2097],{},"The same ",[293,2096,199],{}," can be shared between a Flutter app and a Dart backend in a monorepo.",[2085,2099,2100,2101,2103,2104,343],{},"The ",[293,2102,309],{}," pub.dev bundle stays small; Flutter-specific features are opt-in via ",[293,2105,342],{},[423,2107,2109],{"id":2108},"why-singleton-client","Why Singleton + Client?",[276,2111,2112,2115,2116,2119],{},[282,2113,2114],{},"Client"," = injectable, no side effects, ideal for tests and backend services.\n",[282,2117,2118],{},"Instance"," = convenient global access, sync state cache, reactive streams.",[276,2121,2122,2123,2125,2126,2128],{},"Both are available. Use ",[293,2124,199],{}," in tests; use ",[293,2127,757],{}," in your app.",[423,2130,2132],{"id":2131},"why-streams-instead-of-changenotifier","Why Streams instead of ChangeNotifier?",[2082,2134,2135,2138,2144],{},[2085,2136,2137],{},"Native to Dart — no framework dependency.",[2085,2139,2140,2141,2143],{},"Compatible with every state management library: ",[293,2142,299],{},", Riverpod, Bloc, RxDart.",[2085,2145,2146,2148,2149,2151,2152,2154],{},[293,2147,1803],{}," on ",[293,2150,226],{}," provides free deduplication without manual ",[293,2153,1785],{}," overrides.",[423,2156,2158],{"id":2157},"why-is-the-sessionregistry-immutable","Why is the SessionRegistry immutable?",[276,2160,2161],{},"Every mutation returns a new registry and atomically writes it to storage. There is no partial-write state, which eliminates a whole class of concurrency bugs.",[312,2163],{},[271,2165,2167],{"id":2166},"next-steps","Next steps",[2082,2169,2170,2176,2181],{},[2085,2171,2172],{},[2173,2174,2175],"a",{"href":200},"API Reference — AuthyraClient →",[2085,2177,2178],{},[2173,2179,2180],{"href":204},"API Reference — AuthyraInstance →",[2085,2182,2183],{},[2173,2184,2185],{"href":171},"Flutter Setup →",[2187,2188,2189],"style",{},"html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":328,"searchDepth":468,"depth":468,"links":2191},[2192,2193,2194,2195,2203,2208,2213,2219],{"id":273,"depth":468,"text":274},{"id":316,"depth":468,"text":317},{"id":355,"depth":468,"text":356},{"id":420,"depth":468,"text":421,"children":2196},[2197,2198,2199,2200,2201,2202],{"id":425,"depth":475,"text":199},{"id":751,"depth":475,"text":203},{"id":926,"depth":475,"text":212},{"id":1227,"depth":475,"text":217},{"id":1464,"depth":475,"text":1465},{"id":1486,"depth":475,"text":207},{"id":1633,"depth":468,"text":1634,"children":2204},[2205,2206,2207],{"id":1637,"depth":475,"text":1638},{"id":1647,"depth":475,"text":1648},{"id":1657,"depth":475,"text":1658},{"id":1669,"depth":468,"text":1670,"children":2209},[2210,2211,2212],{"id":1673,"depth":475,"text":226},{"id":1810,"depth":475,"text":222},{"id":1972,"depth":475,"text":1973},{"id":2075,"depth":468,"text":2076,"children":2214},[2215,2216,2217,2218],{"id":2079,"depth":475,"text":2080},{"id":2108,"depth":475,"text":2109},{"id":2131,"depth":475,"text":2132},{"id":2157,"depth":475,"text":2158},{"id":2166,"depth":468,"text":2167},"How the two packages, AuthyraClient, AuthyraInstance, and the provider/storage system fit together.","md",null,{},{"icon":58},{"title":2226,"description":2227},"Architecture | Authyra","Deep dive into Authyra's two-package, two-layer design, data flow, and key architectural decisions.","lWIMRKgcsL36W8gbia3_H7rKrh7fvLyNRKNbVuFY26Y",[2230,2232],{"title":46,"path":47,"stem":48,"description":2231,"icon":44,"children":-1},"Mapping Supabase Auth → Authyra — équivalences d'API, stratégie de migration et différences clés.",{"title":60,"path":61,"stem":62,"description":2233,"icon":63,"children":-1},"The AuthProvider interface — strategy types, sign-in, sign-out, and token refresh.",1782700506039]