@oxyhq/services 28.0.0 → 29.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +10 -9
- package/README.md +65 -2
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt +178 -0
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionProvider.kt +99 -0
- package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionStore.kt +115 -0
- package/expo-module.config.json +1 -0
- package/lib/commonjs/index.js +60 -16
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/boot/runProviderColdBoot.js +7 -0
- package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/commonjs/ui/client.js +12 -7
- package/lib/commonjs/ui/client.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +10 -27
- package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +132 -44
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +4 -2
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/SurfaceScreen.js +31 -3
- package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +209 -84
- package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +25 -7
- package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/primitives.js +35 -22
- package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/commonjs/ui/components/authChooser/types.js +11 -0
- package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +257 -306
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +27 -37
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/oxyContextHelpers.js +0 -29
- package/lib/commonjs/ui/context/oxyContextHelpers.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +6 -17
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +42 -0
- package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -0
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +0 -19
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +57 -0
- package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -0
- package/lib/commonjs/ui/hooks/useI18n.js +22 -3
- package/lib/commonjs/ui/hooks/useI18n.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +46 -153
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/index.js +12 -7
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +85 -73
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/navigation/surfaces.js +8 -7
- package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
- package/lib/commonjs/ui/runtime/createOxyRuntime.js +433 -0
- package/lib/commonjs/ui/runtime/createOxyRuntime.js.map +1 -0
- package/lib/commonjs/ui/runtime/index.js +63 -0
- package/lib/commonjs/ui/runtime/index.js.map +1 -0
- package/lib/commonjs/ui/runtime/runtimeContext.js +83 -0
- package/lib/commonjs/ui/runtime/runtimeContext.js.map +1 -0
- package/lib/commonjs/ui/runtime/types.js +6 -0
- package/lib/commonjs/ui/runtime/types.js.map +1 -0
- package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js +57 -0
- package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js.map +1 -0
- package/lib/commonjs/ui/server.js +1 -2
- package/lib/commonjs/ui/server.js.map +1 -1
- package/lib/commonjs/ui/session/authStore.js +45 -9
- package/lib/commonjs/ui/session/authStore.js.map +1 -1
- package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js +306 -0
- package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +154 -55
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/utils/avatarUtils.js +2 -36
- package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
- package/lib/module/index.js +16 -8
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/boot/runProviderColdBoot.js +7 -0
- package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
- package/lib/module/ui/client.js +1 -2
- package/lib/module/ui/client.js.map +1 -1
- package/lib/module/ui/components/OxyAccountDialogScreen.js +10 -27
- package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +134 -44
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +5 -3
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/SurfaceScreen.js +33 -5
- package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
- package/lib/module/ui/components/authChooser/AccountsMenuView.js +210 -85
- package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
- package/lib/module/ui/components/authChooser/SignInEntryView.js +25 -7
- package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -1
- package/lib/module/ui/components/authChooser/primitives.js +35 -22
- package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
- package/lib/module/ui/components/authChooser/types.js +11 -0
- package/lib/module/ui/components/authChooser/types.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +251 -303
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +27 -37
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/oxyContextHelpers.js +0 -28
- package/lib/module/ui/context/oxyContextHelpers.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +6 -17
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/accountDialogSnapshot.js +38 -0
- package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -0
- package/lib/module/ui/hooks/mutations/useAccountMutations.js +0 -19
- package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/module/ui/hooks/useDeviceSwitcher.js +53 -0
- package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -0
- package/lib/module/ui/hooks/useI18n.js +24 -4
- package/lib/module/ui/hooks/useI18n.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +47 -155
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/index.js +1 -2
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +84 -72
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/navigation/surfaces.js +6 -6
- package/lib/module/ui/navigation/surfaces.js.map +1 -1
- package/lib/module/ui/runtime/createOxyRuntime.js +430 -0
- package/lib/module/ui/runtime/createOxyRuntime.js.map +1 -0
- package/lib/module/ui/runtime/index.js +15 -0
- package/lib/module/ui/runtime/index.js.map +1 -0
- package/lib/module/ui/runtime/runtimeContext.js +75 -0
- package/lib/module/ui/runtime/runtimeContext.js.map +1 -0
- package/lib/module/ui/runtime/types.js +4 -0
- package/lib/module/ui/runtime/types.js.map +1 -0
- package/lib/module/ui/runtime/useRuntimeSnapshot.js +52 -0
- package/lib/module/ui/runtime/useRuntimeSnapshot.js.map +1 -0
- package/lib/module/ui/server.js +0 -1
- package/lib/module/ui/server.js.map +1 -1
- package/lib/module/ui/session/authStore.js +46 -11
- package/lib/module/ui/session/authStore.js.map +1 -1
- package/lib/module/ui/session/sharedDeviceCredentialStore.js +302 -0
- package/lib/module/ui/session/sharedDeviceCredentialStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +154 -55
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/utils/avatarUtils.js +2 -35
- package/lib/module/ui/utils/avatarUtils.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +5 -3
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/client.d.ts +1 -2
- package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
- package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +3 -1
- package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +18 -6
- package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +33 -1
- package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +35 -4
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +8 -12
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts +0 -2
- package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +9 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -3
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +15 -0
- package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts +49 -0
- package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts +13 -0
- package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +23 -18
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +1 -2
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts +15 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts +144 -0
- package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/index.d.ts +16 -0
- package/lib/typescript/commonjs/ui/runtime/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts +43 -0
- package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/types.d.ts +89 -0
- package/lib/typescript/commonjs/ui/runtime/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
- package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/server.d.ts +0 -1
- package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/authStore.d.ts +60 -9
- package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
- package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/stores/authStore.d.ts +49 -5
- package/lib/typescript/commonjs/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +26 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts +2 -10
- package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +5 -3
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +1 -2
- package/lib/typescript/module/ui/client.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
- package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +3 -1
- package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +18 -6
- package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/authChooser/types.d.ts +33 -1
- package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts +35 -4
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +8 -12
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts +0 -2
- package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +9 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -3
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +15 -0
- package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts +49 -0
- package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
- package/lib/typescript/module/ui/hooks/useI18n.d.ts +13 -0
- package/lib/typescript/module/ui/hooks/useI18n.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +23 -18
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +1 -2
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts +15 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
- package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts +144 -0
- package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/index.d.ts +16 -0
- package/lib/typescript/module/ui/runtime/index.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/runtimeContext.d.ts +43 -0
- package/lib/typescript/module/ui/runtime/runtimeContext.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/types.d.ts +89 -0
- package/lib/typescript/module/ui/runtime/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
- package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
- package/lib/typescript/module/ui/server.d.ts +0 -1
- package/lib/typescript/module/ui/server.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/authStore.d.ts +60 -9
- package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
- package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
- package/lib/typescript/module/ui/stores/authStore.d.ts +49 -5
- package/lib/typescript/module/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +26 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/avatarUtils.d.ts +2 -10
- package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
- package/package.json +6 -7
- package/plugins/withSharedDeviceSessionProvider.js +102 -0
- package/plugins/withSharedDeviceSessionReader.js +57 -0
- package/src/__tests__/esmSourcePurity.test.ts +61 -0
- package/src/index.ts +31 -9
- package/src/ui/boot/runProviderColdBoot.ts +7 -0
- package/src/ui/client.ts +1 -2
- package/src/ui/components/OxyAccountDialogScreen.tsx +10 -29
- package/src/ui/components/OxyAuthChooser.tsx +149 -50
- package/src/ui/components/OxyProvider.tsx +7 -5
- package/src/ui/components/SurfaceScreen.tsx +28 -4
- package/src/ui/components/authChooser/AccountsMenuView.tsx +246 -96
- package/src/ui/components/authChooser/SignInEntryView.tsx +31 -8
- package/src/ui/components/authChooser/primitives.tsx +37 -23
- package/src/ui/components/authChooser/types.ts +34 -1
- package/src/ui/context/OxyContext.tsx +269 -324
- package/src/ui/context/hooks/useAuthOperations.ts +32 -35
- package/src/ui/context/oxyContextHelpers.ts +0 -30
- package/src/ui/context/oxyContextTypes.ts +9 -1
- package/src/ui/context/useOxyAccountGraph.ts +5 -19
- package/src/ui/hooks/accountDialogSnapshot.ts +37 -0
- package/src/ui/hooks/mutations/useAccountMutations.ts +0 -19
- package/src/ui/hooks/queries/__tests__/userCache.test.ts +12 -1
- package/src/ui/hooks/useDeviceSwitcher.ts +110 -0
- package/src/ui/hooks/useI18n.ts +23 -3
- package/src/ui/hooks/useSessionManagement.ts +62 -211
- package/src/ui/index.ts +1 -2
- package/src/ui/navigation/routes.ts +85 -75
- package/src/ui/navigation/surfaces.ts +6 -9
- package/src/ui/runtime/createOxyRuntime.ts +623 -0
- package/src/ui/runtime/index.ts +34 -0
- package/src/ui/runtime/runtimeContext.tsx +111 -0
- package/src/ui/runtime/types.ts +110 -0
- package/src/ui/runtime/useRuntimeSnapshot.ts +52 -0
- package/src/ui/server.ts +0 -1
- package/src/ui/session/__tests__/authStore.test.ts +90 -0
- package/src/ui/session/__tests__/sharedDeviceCredentialStore.test.ts +289 -0
- package/src/ui/session/authStore.ts +78 -9
- package/src/ui/session/sharedDeviceCredentialStore.ts +318 -0
- package/src/ui/stores/authStore.ts +171 -43
- package/src/ui/types/navigation.ts +26 -0
- package/src/ui/utils/avatarUtils.ts +2 -37
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +0 -64
- package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +0 -1
- package/lib/commonjs/ui/stores/accountStore.js +0 -221
- package/lib/commonjs/ui/stores/accountStore.js.map +0 -1
- package/lib/module/ui/hooks/useSwitchableAccounts.js +0 -60
- package/lib/module/ui/hooks/useSwitchableAccounts.js.map +0 -1
- package/lib/module/ui/stores/accountStore.js +0 -213
- package/lib/module/ui/stores/accountStore.js.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +0 -23
- package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/stores/accountStore.d.ts +0 -27
- package/lib/typescript/commonjs/ui/stores/accountStore.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +0 -23
- package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
- package/lib/typescript/module/ui/stores/accountStore.d.ts +0 -27
- package/lib/typescript/module/ui/stores/accountStore.d.ts.map +0 -1
- package/src/ui/hooks/useSwitchableAccounts.ts +0 -75
- package/src/ui/stores/accountStore.ts +0 -264
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
2
2
|
import { isDev, type ApiError, type User } from '@oxyhq/core';
|
|
3
3
|
import type { ClientSession } from '@oxyhq/core';
|
|
4
|
-
import { mergeSessions, normalizeAndSortSessions, sessionsArraysEqual } from '@oxyhq/core';
|
|
5
4
|
import { fetchSessionsWithFallback } from '../utils/sessionHelpers';
|
|
6
5
|
import { getStorageKeys, type StorageInterface } from '../utils/storageHelpers';
|
|
7
6
|
import { handleAuthError, isInvalidSessionError } from '../utils/errorHandlers';
|
|
@@ -10,109 +9,80 @@ import type { QueryClient } from '@tanstack/react-query';
|
|
|
10
9
|
import { clearQueryCache } from './queryClient';
|
|
11
10
|
import { isWebBrowser } from '../utils/isWebBrowser';
|
|
12
11
|
import { resetSessionScopedStores } from '../stores/resetSessionScopedStores';
|
|
12
|
+
import type { OxyRuntime } from '../runtime';
|
|
13
13
|
|
|
14
14
|
export interface UseSessionManagementOptions {
|
|
15
15
|
oxyServices: OxyServices;
|
|
16
|
+
/** The one owner of `sessions` / `activeSessionId` / the signed-in account. */
|
|
17
|
+
runtime: OxyRuntime;
|
|
16
18
|
storage: StorageInterface | null;
|
|
17
19
|
storageKeyPrefix?: string;
|
|
18
|
-
loginSuccess: (user: User) => void;
|
|
19
|
-
logoutStore: () => void;
|
|
20
20
|
onAuthStateChange?: (user: User | null) => void;
|
|
21
21
|
onError?: (error: ApiError) => void;
|
|
22
22
|
setAuthError?: (message: string | null) => void;
|
|
23
23
|
logger?: (message: string, error?: unknown) => void;
|
|
24
|
-
setTokenReady?: (ready: boolean) => void;
|
|
25
24
|
queryClient?: QueryClient | null;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export interface UseSessionManagementResult {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
/** Persist the projected session-id list. Handed to the runtime as its projection sink. */
|
|
29
|
+
saveSessionIds: (sessionIds: string[]) => void;
|
|
30
|
+
saveActiveSessionId: (sessionId: string) => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* The legacy `validateSession`-keyed switch. Reachable from exactly ONE
|
|
33
|
+
* caller: `performSignIn`'s same-user duplicate-session dedup. The switch a
|
|
34
|
+
* consumer sees on the context is the `SessionClient` one in `OxyContext`.
|
|
35
|
+
*/
|
|
33
36
|
switchSession: (sessionId: string) => Promise<User>;
|
|
34
|
-
|
|
37
|
+
/** Tear down the local session: runtime projection, caches, storage, tokens. */
|
|
35
38
|
clearSessionState: () => Promise<void>;
|
|
36
|
-
saveActiveSessionId: (sessionId: string) => Promise<void>;
|
|
37
|
-
trackRemovedSession: (sessionId: string) => void;
|
|
38
39
|
storageKeys: ReturnType<typeof getStorageKeys>;
|
|
39
|
-
isRefreshInFlight: boolean;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
const DEFAULT_SAVE_ERROR_MESSAGE = 'Failed to save session data';
|
|
43
43
|
const CLEAR_STORAGE_ERROR = 'Failed to clear storage';
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Session persistence and the one legacy switch left, over the runtime.
|
|
47
47
|
*
|
|
48
|
-
*
|
|
48
|
+
* This hook used to hold its OWN `sessions` / `activeSessionId` React state
|
|
49
|
+
* plus six refs mirroring them so its callbacks could avoid widening their
|
|
50
|
+
* dependency arrays. That made it a second owner of facts `SessionClient`
|
|
51
|
+
* already had, reconciled only by whichever `useEffect` ran last. Both are gone:
|
|
52
|
+
* the runtime owns them, this hook writes through it, and the refs mirrored
|
|
53
|
+
* nothing once there was nothing local to mirror.
|
|
54
|
+
*
|
|
55
|
+
* `refreshSessions`, `trackRemovedSession` and `isRefreshInFlight` are deleted
|
|
56
|
+
* outright — every one of them was dropped unread at the single call site.
|
|
49
57
|
*/
|
|
50
58
|
export const useSessionManagement = ({
|
|
51
59
|
oxyServices,
|
|
60
|
+
runtime,
|
|
52
61
|
storage,
|
|
53
62
|
storageKeyPrefix,
|
|
54
|
-
loginSuccess,
|
|
55
|
-
logoutStore,
|
|
56
63
|
onAuthStateChange,
|
|
57
64
|
onError,
|
|
58
65
|
setAuthError,
|
|
59
66
|
logger,
|
|
60
|
-
setTokenReady,
|
|
61
67
|
queryClient,
|
|
62
68
|
}: UseSessionManagementOptions): UseSessionManagementResult => {
|
|
63
|
-
const [sessions, setSessions] = useState<ClientSession[]>([]);
|
|
64
|
-
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
|
65
|
-
|
|
66
|
-
// Refs to avoid recreating callbacks when sessions/activeSessionId change
|
|
67
|
-
const sessionsRef = useRef(sessions);
|
|
68
|
-
sessionsRef.current = sessions;
|
|
69
|
-
const activeSessionIdRef = useRef(activeSessionId);
|
|
70
|
-
activeSessionIdRef.current = activeSessionId;
|
|
71
|
-
|
|
72
|
-
const refreshInFlightRef = useRef<Promise<void> | null>(null);
|
|
73
|
-
const removedSessionsRef = useRef<Set<string>>(new Set());
|
|
74
|
-
const lastRefreshRef = useRef<number>(0);
|
|
75
|
-
|
|
76
69
|
const storageKeys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
|
|
70
|
+
const runtimeRef = useRef(runtime);
|
|
71
|
+
runtimeRef.current = runtime;
|
|
77
72
|
|
|
78
73
|
const saveSessionIds = useCallback(
|
|
79
|
-
|
|
74
|
+
(sessionIds: string[]): void => {
|
|
80
75
|
if (!storage) return;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
await storage.setItem(storageKeys.sessionIds, JSON.stringify(uniqueIds));
|
|
84
|
-
} catch (error) {
|
|
76
|
+
const uniqueIds = Array.from(new Set(sessionIds));
|
|
77
|
+
storage.setItem(storageKeys.sessionIds, JSON.stringify(uniqueIds)).catch((error: unknown) => {
|
|
85
78
|
if (logger) {
|
|
86
79
|
logger(DEFAULT_SAVE_ERROR_MESSAGE, error);
|
|
87
80
|
} else if (isDev()) {
|
|
88
81
|
console.warn('Failed to save session IDs:', error);
|
|
89
82
|
}
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
[logger, storage, storageKeys.sessionIds],
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const updateSessions = useCallback(
|
|
96
|
-
(incoming: ClientSession[], options: { merge?: boolean; preserveSessionIds?: string[] } = {}): void => {
|
|
97
|
-
setSessions((prevSessions) => {
|
|
98
|
-
const processed = options.merge
|
|
99
|
-
? mergeSessions(prevSessions, incoming, activeSessionIdRef.current, false)
|
|
100
|
-
: normalizeAndSortSessions(incoming, activeSessionIdRef.current, false);
|
|
101
|
-
|
|
102
|
-
if (storage) {
|
|
103
|
-
void saveSessionIds([
|
|
104
|
-
...processed.map((session) => session.sessionId),
|
|
105
|
-
...(options.preserveSessionIds ?? []),
|
|
106
|
-
]);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (sessionsArraysEqual(prevSessions, processed)) {
|
|
110
|
-
return prevSessions;
|
|
111
|
-
}
|
|
112
|
-
return processed;
|
|
113
83
|
});
|
|
114
84
|
},
|
|
115
|
-
[
|
|
85
|
+
[logger, storage, storageKeys.sessionIds],
|
|
116
86
|
);
|
|
117
87
|
|
|
118
88
|
const saveActiveSessionId = useCallback(
|
|
@@ -133,27 +103,11 @@ export const useSessionManagement = ({
|
|
|
133
103
|
[logger, onError, setAuthError, storage, storageKeys.activeSessionId],
|
|
134
104
|
);
|
|
135
105
|
|
|
136
|
-
const removeActiveSessionId = useCallback(async (): Promise<void> => {
|
|
137
|
-
if (!storage) return;
|
|
138
|
-
try {
|
|
139
|
-
await storage.removeItem(storageKeys.activeSessionId);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
handleAuthError(error, {
|
|
142
|
-
defaultMessage: DEFAULT_SAVE_ERROR_MESSAGE,
|
|
143
|
-
code: 'SESSION_PERSISTENCE_ERROR',
|
|
144
|
-
onError,
|
|
145
|
-
setAuthError,
|
|
146
|
-
logger,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}, [logger, onError, setAuthError, storage, storageKeys.activeSessionId]);
|
|
150
|
-
|
|
151
106
|
const clearSessionStorage = useCallback(async (): Promise<void> => {
|
|
152
107
|
if (!storage) return;
|
|
153
108
|
try {
|
|
154
109
|
await storage.removeItem(storageKeys.activeSessionId);
|
|
155
110
|
await storage.removeItem(storageKeys.sessionIds);
|
|
156
|
-
// Note: Identity sync state ('oxy_identity_synced') is managed by accounts app
|
|
157
111
|
} catch (error) {
|
|
158
112
|
handleAuthError(error, {
|
|
159
113
|
defaultMessage: CLEAR_STORAGE_ERROR,
|
|
@@ -166,25 +120,21 @@ export const useSessionManagement = ({
|
|
|
166
120
|
}, [logger, onError, setAuthError, storage, storageKeys.activeSessionId, storageKeys.sessionIds]);
|
|
167
121
|
|
|
168
122
|
const clearSessionState = useCallback(async (): Promise<void> => {
|
|
169
|
-
|
|
170
|
-
setActiveSessionId(null);
|
|
171
|
-
logoutStore();
|
|
123
|
+
runtimeRef.current.clearSession();
|
|
172
124
|
resetSessionScopedStores();
|
|
173
125
|
|
|
174
|
-
// Clear the access token on the client instance. Without this the
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
//
|
|
126
|
+
// Clear the access token on the client instance. Without this the token
|
|
127
|
+
// store retained the stale bearer until the next 401, leaving the instance
|
|
128
|
+
// "logged in" at the HTTP layer and — via the provider's token mirror —
|
|
129
|
+
// leaking that stale token onto the shared `oxyClient` singleton after
|
|
130
|
+
// sign-out. Clearing here fires `onTokensChanged(null)`, propagating the
|
|
131
|
+
// logged-out state everywhere.
|
|
180
132
|
oxyServices.clearTokens();
|
|
181
133
|
|
|
182
|
-
// Clear TanStack Query cache (in-memory)
|
|
183
134
|
if (queryClient) {
|
|
184
135
|
queryClient.clear();
|
|
185
136
|
}
|
|
186
|
-
|
|
187
|
-
// Clear persisted query cache
|
|
137
|
+
|
|
188
138
|
if (storage) {
|
|
189
139
|
try {
|
|
190
140
|
await clearQueryCache(storage);
|
|
@@ -194,49 +144,19 @@ export const useSessionManagement = ({
|
|
|
194
144
|
}
|
|
195
145
|
}
|
|
196
146
|
}
|
|
197
|
-
|
|
147
|
+
|
|
198
148
|
await clearSessionStorage();
|
|
199
149
|
onAuthStateChange?.(null);
|
|
200
|
-
}, [clearSessionStorage,
|
|
201
|
-
|
|
202
|
-
const activateSession = useCallback(
|
|
203
|
-
async (sessionId: string, user: User): Promise<void> => {
|
|
204
|
-
setTokenReady?.(true);
|
|
205
|
-
setActiveSessionId(sessionId);
|
|
206
|
-
loginSuccess(user);
|
|
207
|
-
await saveActiveSessionId(sessionId);
|
|
208
|
-
onAuthStateChange?.(user);
|
|
209
|
-
},
|
|
210
|
-
[loginSuccess, onAuthStateChange, saveActiveSessionId, setTokenReady],
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
const removalTimerIdsRef = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());
|
|
214
|
-
|
|
215
|
-
const trackRemovedSession = useCallback((sessionId: string) => {
|
|
216
|
-
removedSessionsRef.current.add(sessionId);
|
|
217
|
-
const timerId = setTimeout(() => {
|
|
218
|
-
removedSessionsRef.current.delete(sessionId);
|
|
219
|
-
removalTimerIdsRef.current.delete(timerId);
|
|
220
|
-
}, 5000);
|
|
221
|
-
removalTimerIdsRef.current.add(timerId);
|
|
222
|
-
}, []);
|
|
223
|
-
|
|
224
|
-
useEffect(() => {
|
|
225
|
-
return () => {
|
|
226
|
-
removalTimerIdsRef.current.forEach(clearTimeout);
|
|
227
|
-
};
|
|
228
|
-
}, []);
|
|
150
|
+
}, [clearSessionStorage, onAuthStateChange, oxyServices, queryClient, storage, logger]);
|
|
229
151
|
|
|
230
152
|
const switchSession = useCallback(
|
|
231
153
|
async (sessionId: string): Promise<User> => {
|
|
232
154
|
try {
|
|
233
|
-
// On web
|
|
234
|
-
// `claimSessionByToken`, a cold-boot
|
|
155
|
+
// On web the bearer must already be in memory (planted by
|
|
156
|
+
// `claimSessionByToken`, a cold-boot restore step, or a prior
|
|
235
157
|
// `SessionClient` sync) before validating — there is no client-side
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
// arrives here only after a bearer has been planted by
|
|
239
|
-
// `claimSessionByToken` or secure shared-session restore.
|
|
158
|
+
// refresh-cookie slot to fall back on. The native path arrives here only
|
|
159
|
+
// after a bearer has been planted too.
|
|
240
160
|
if (isWebBrowser() && !oxyServices.getAccessToken()) {
|
|
241
161
|
throw new Error('Session is invalid or expired');
|
|
242
162
|
}
|
|
@@ -245,20 +165,26 @@ export const useSessionManagement = ({
|
|
|
245
165
|
if (!validation?.valid) {
|
|
246
166
|
throw new Error('Session is invalid or expired');
|
|
247
167
|
}
|
|
248
|
-
|
|
249
168
|
if (!validation.user) {
|
|
250
169
|
throw new Error('User data not available from session validation');
|
|
251
170
|
}
|
|
252
171
|
|
|
253
172
|
const user = validation.user as User;
|
|
254
|
-
|
|
173
|
+
const activeRuntime = runtimeRef.current;
|
|
174
|
+
activeRuntime.batch(() => {
|
|
175
|
+
activeRuntime.setTokenReady(true);
|
|
176
|
+
activeRuntime.setActiveSessionId(sessionId);
|
|
177
|
+
activeRuntime.setAccount(user);
|
|
178
|
+
});
|
|
179
|
+
await saveActiveSessionId(sessionId);
|
|
180
|
+
onAuthStateChange?.(user);
|
|
255
181
|
|
|
256
182
|
try {
|
|
257
183
|
const deviceSessions = await fetchSessionsWithFallback(oxyServices, sessionId, {
|
|
258
184
|
fallbackUserId: user.id,
|
|
259
185
|
logger,
|
|
260
186
|
});
|
|
261
|
-
|
|
187
|
+
activeRuntime.mergeSessions(deviceSessions, { merge: true });
|
|
262
188
|
} catch (error) {
|
|
263
189
|
if (isDev()) {
|
|
264
190
|
console.warn('Failed to synchronize sessions after switch:', error);
|
|
@@ -271,11 +197,12 @@ export const useSessionManagement = ({
|
|
|
271
197
|
|
|
272
198
|
if (invalidSession) {
|
|
273
199
|
// Server authority (`SessionClient` bootstrap/sync) reconciles which
|
|
274
|
-
// account is actually active — just drop the invalid session from
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
200
|
+
// account is actually active — just drop the invalid session from the
|
|
201
|
+
// local view rather than guessing at a replacement.
|
|
202
|
+
const remaining: ClientSession[] = runtimeRef.current
|
|
203
|
+
.getSnapshot()
|
|
204
|
+
.sessions.filter((session) => session.sessionId !== sessionId);
|
|
205
|
+
runtimeRef.current.mergeSessions(remaining, { merge: false });
|
|
279
206
|
}
|
|
280
207
|
|
|
281
208
|
handleAuthError(error, {
|
|
@@ -288,90 +215,14 @@ export const useSessionManagement = ({
|
|
|
288
215
|
throw error instanceof Error ? error : new Error('Failed to switch session');
|
|
289
216
|
}
|
|
290
217
|
},
|
|
291
|
-
[
|
|
292
|
-
activateSession,
|
|
293
|
-
logger,
|
|
294
|
-
onError,
|
|
295
|
-
oxyServices,
|
|
296
|
-
setAuthError,
|
|
297
|
-
updateSessions,
|
|
298
|
-
],
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
const refreshSessions = useCallback(
|
|
302
|
-
async (activeUserId?: string): Promise<void> => {
|
|
303
|
-
// Capture the active session id once so the async closure below uses a
|
|
304
|
-
// narrowed, non-null local instead of re-reading the ref (which the
|
|
305
|
-
// compiler cannot prove stays non-null across awaits).
|
|
306
|
-
const activeSessionId = activeSessionIdRef.current;
|
|
307
|
-
if (!activeSessionId) return;
|
|
308
|
-
|
|
309
|
-
if (refreshInFlightRef.current) {
|
|
310
|
-
await refreshInFlightRef.current;
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const now = Date.now();
|
|
315
|
-
if (now - lastRefreshRef.current < 500) {
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
lastRefreshRef.current = now;
|
|
319
|
-
|
|
320
|
-
const refreshPromise = (async () => {
|
|
321
|
-
try {
|
|
322
|
-
const deviceSessions = await fetchSessionsWithFallback(oxyServices, activeSessionId, {
|
|
323
|
-
fallbackUserId: activeUserId,
|
|
324
|
-
logger,
|
|
325
|
-
});
|
|
326
|
-
updateSessions(deviceSessions, { merge: true });
|
|
327
|
-
} catch (error) {
|
|
328
|
-
if (isInvalidSessionError(error)) {
|
|
329
|
-
// Server authority (`SessionClient` bootstrap/sync) reconciles
|
|
330
|
-
// which account is actually active — just clear local state
|
|
331
|
-
// rather than guessing at a replacement session.
|
|
332
|
-
await clearSessionState();
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
handleAuthError(error, {
|
|
337
|
-
defaultMessage: 'Failed to refresh sessions',
|
|
338
|
-
code: 'SESSION_REFRESH_ERROR',
|
|
339
|
-
onError,
|
|
340
|
-
setAuthError,
|
|
341
|
-
logger,
|
|
342
|
-
});
|
|
343
|
-
} finally {
|
|
344
|
-
refreshInFlightRef.current = null;
|
|
345
|
-
lastRefreshRef.current = Date.now();
|
|
346
|
-
}
|
|
347
|
-
})();
|
|
348
|
-
|
|
349
|
-
refreshInFlightRef.current = refreshPromise;
|
|
350
|
-
await refreshPromise;
|
|
351
|
-
},
|
|
352
|
-
[
|
|
353
|
-
clearSessionState,
|
|
354
|
-
logger,
|
|
355
|
-
onError,
|
|
356
|
-
oxyServices,
|
|
357
|
-
setAuthError,
|
|
358
|
-
updateSessions,
|
|
359
|
-
],
|
|
218
|
+
[logger, onAuthStateChange, onError, oxyServices, saveActiveSessionId, setAuthError],
|
|
360
219
|
);
|
|
361
220
|
|
|
362
|
-
const isRefreshInFlight = Boolean(refreshInFlightRef.current);
|
|
363
|
-
|
|
364
221
|
return {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
setActiveSessionId,
|
|
368
|
-
updateSessions,
|
|
222
|
+
saveSessionIds,
|
|
223
|
+
saveActiveSessionId,
|
|
369
224
|
switchSession,
|
|
370
|
-
refreshSessions,
|
|
371
225
|
clearSessionState,
|
|
372
|
-
saveActiveSessionId,
|
|
373
|
-
trackRemovedSession,
|
|
374
226
|
storageKeys,
|
|
375
|
-
isRefreshInFlight,
|
|
376
227
|
};
|
|
377
228
|
};
|
package/src/ui/index.ts
CHANGED
|
@@ -29,7 +29,7 @@ export { default as OxyPayButton } from './components/OxyPayButton';
|
|
|
29
29
|
export { default as ProfileButton } from './components/ProfileButton';
|
|
30
30
|
|
|
31
31
|
// Context + hooks
|
|
32
|
-
export { useOxy } from './context/OxyContext';
|
|
32
|
+
export { useOxy, useOptionalOxy, OxyProviderMissingError } from './context/OxyContext';
|
|
33
33
|
export { useAuth } from './hooks/useAuth';
|
|
34
34
|
export { useFollow, useSeedFollowStatuses } from './hooks/useFollow';
|
|
35
35
|
export { useStorage } from './hooks/useStorage';
|
|
@@ -44,7 +44,6 @@ export { default as AccountSettingsScreen } from './screens/AccountSettingsScree
|
|
|
44
44
|
|
|
45
45
|
// Stores
|
|
46
46
|
export { useAuthStore } from './stores/authStore';
|
|
47
|
-
export { useAccountStore } from './stores/accountStore';
|
|
48
47
|
|
|
49
48
|
// Error handlers (pure functions)
|
|
50
49
|
export {
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { lazy, type ComponentType } from 'react';
|
|
2
2
|
import type { BaseScreenProps } from '../types/navigation';
|
|
3
3
|
|
|
4
|
-
// Lazy loading: Screens are loaded on-demand to break require cycles
|
|
5
|
-
// This prevents screens (which import OxyContext) from being loaded
|
|
6
|
-
// before OxyContext is fully initialized
|
|
7
|
-
|
|
8
4
|
// Define all available route names
|
|
9
5
|
export type RouteName =
|
|
10
6
|
| 'ManageAccount' // Unified "Manage your Oxy Account" surface
|
|
@@ -46,85 +42,99 @@ export type RouteName =
|
|
|
46
42
|
| 'Preferences' // General user preferences (theme, reduce-motion, etc.)
|
|
47
43
|
| 'AccountDialog'; // Unified account switcher + sign-in surface (OxyAccountDialogScreen body)
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
45
|
+
/**
|
|
46
|
+
* The component for each route, loaded on demand.
|
|
47
|
+
*
|
|
48
|
+
* Every entry is `lazy(() => import(...))`: the screen module is fetched and
|
|
49
|
+
* evaluated the first time its surface is presented, never at import time. That
|
|
50
|
+
* matters twice over — screens import `OxyContext`, which reaches back here, so
|
|
51
|
+
* eager evaluation would run screens mid-cycle; and it keeps native-only screen
|
|
52
|
+
* dependencies out of the evaluation path of every consumer that merely touches
|
|
53
|
+
* the SDK.
|
|
54
|
+
*
|
|
55
|
+
* What defers the load must NOT be `require()`. `@oxyhq/services` ships an ESM
|
|
56
|
+
* build, and a `require()` in ESM output forces web bundlers into CommonJS
|
|
57
|
+
* interop: rolldown-vite defers every module in the required subgraph behind a
|
|
58
|
+
* lazy initializer and then hands a consumer that statically imported one of
|
|
59
|
+
* them the still-`undefined` binding. That is how `OxySignInRequestSurface`
|
|
60
|
+
* reached auth.oxy.so/authorize as `undefined` and blanked the page with React
|
|
61
|
+
* error #130 — this registry pulled `OxyAccountDialogScreen`, and the whole
|
|
62
|
+
* sign-in surface subgraph with it, through `require()`.
|
|
63
|
+
*
|
|
64
|
+
* The value type is `ComponentType<never>`, which every screen satisfies. A few
|
|
65
|
+
* screens (`Profile`, `PaymentGateway`, `UserLinks`, `FollowersList`,
|
|
66
|
+
* `FollowingList`) declare props BEYOND {@link BaseScreenProps} — `userId`,
|
|
67
|
+
* `amount` — that only reach them through the route's untyped props bag
|
|
68
|
+
* (`present(route, props)`), so this map cannot prove they are satisfied. The
|
|
69
|
+
* previous `require()` returned `any` and hid that entirely; stating it here
|
|
70
|
+
* confines the gap to one documented widening in {@link getScreenComponent}.
|
|
71
|
+
*/
|
|
72
|
+
const screenComponents: Record<RouteName, ComponentType<never>> = {
|
|
73
|
+
ManageAccount: lazy(() => import('../screens/ManageAccountScreen')),
|
|
74
|
+
AccountVerification: lazy(() => import('../screens/AccountVerificationScreen')),
|
|
75
|
+
PaymentGateway: lazy(() => import('../screens/PaymentGatewayScreen')),
|
|
76
|
+
Profile: lazy(() => import('../screens/ProfileScreen')),
|
|
77
|
+
LanguageSelector: lazy(() => import('../screens/LanguageSelectorScreen')),
|
|
78
|
+
PrivacySettings: lazy(() => import('../screens/PrivacySettingsScreen')),
|
|
79
|
+
SearchSettings: lazy(() => import('../screens/SearchSettingsScreen')),
|
|
80
|
+
FileManagement: lazy(() => import('../screens/FileManagementScreen')),
|
|
81
|
+
HelpSupport: lazy(() => import('../screens/HelpSupportScreen')),
|
|
82
|
+
FAQ: lazy(() => import('../screens/FAQScreen')),
|
|
83
|
+
Feedback: lazy(() => import('../screens/FeedbackScreen')),
|
|
84
|
+
LegalDocuments: lazy(() => import('../screens/LegalDocumentsScreen')),
|
|
85
|
+
AppInfo: lazy(() => import('../screens/AppInfoScreen')),
|
|
86
|
+
PremiumSubscription: lazy(() => import('../screens/PremiumSubscriptionScreen')),
|
|
87
|
+
WelcomeNewUser: lazy(() => import('../screens/WelcomeNewUserScreen')),
|
|
88
|
+
UserLinks: lazy(() => import('../screens/UserLinksScreen')),
|
|
89
|
+
HistoryView: lazy(() => import('../screens/HistoryViewScreen')),
|
|
90
|
+
SavesCollections: lazy(() => import('../screens/SavesCollectionsScreen')),
|
|
91
|
+
EditProfile: lazy(() => import('../screens/EditProfileScreen')),
|
|
92
|
+
EditProfileField: lazy(() => import('../screens/EditProfileFieldScreen')),
|
|
72
93
|
// Informational screens
|
|
73
|
-
LearnMoreUsernames: () =>
|
|
94
|
+
LearnMoreUsernames: lazy(() => import('../screens/LearnMoreUsernamesScreen')),
|
|
74
95
|
// Oxy Trust screens
|
|
75
|
-
TrustCenter: () =>
|
|
76
|
-
TrustLeaderboard: () =>
|
|
77
|
-
TrustRewards: () =>
|
|
78
|
-
TrustRules: () =>
|
|
79
|
-
AboutTrust: () =>
|
|
80
|
-
TrustFAQ: () =>
|
|
96
|
+
TrustCenter: lazy(() => import('../screens/trust/TrustCenterScreen')),
|
|
97
|
+
TrustLeaderboard: lazy(() => import('../screens/trust/TrustLeaderboardScreen')),
|
|
98
|
+
TrustRewards: lazy(() => import('../screens/trust/TrustRewardsScreen')),
|
|
99
|
+
TrustRules: lazy(() => import('../screens/trust/TrustRulesScreen')),
|
|
100
|
+
AboutTrust: lazy(() => import('../screens/trust/TrustAboutScreen')),
|
|
101
|
+
TrustFAQ: lazy(() => import('../screens/trust/TrustFAQScreen')),
|
|
81
102
|
// User list screens (followers/following)
|
|
82
|
-
FollowersList: () =>
|
|
83
|
-
FollowingList: () =>
|
|
84
|
-
CreateAccount: () =>
|
|
85
|
-
AccountMembers: () =>
|
|
86
|
-
AccountSettings: () =>
|
|
87
|
-
ChangeAvatar: () =>
|
|
88
|
-
AvatarCrop: () =>
|
|
89
|
-
Notifications: () =>
|
|
90
|
-
ConnectedApps: () =>
|
|
91
|
-
Preferences: () =>
|
|
103
|
+
FollowersList: lazy(() => import('../screens/FollowersListScreen')),
|
|
104
|
+
FollowingList: lazy(() => import('../screens/FollowingListScreen')),
|
|
105
|
+
CreateAccount: lazy(() => import('../screens/CreateAccountScreen')),
|
|
106
|
+
AccountMembers: lazy(() => import('../screens/AccountMembersScreen')),
|
|
107
|
+
AccountSettings: lazy(() => import('../screens/AccountSettingsScreen')),
|
|
108
|
+
ChangeAvatar: lazy(() => import('../screens/ChangeAvatarScreen')),
|
|
109
|
+
AvatarCrop: lazy(() => import('../screens/AvatarCropScreen')),
|
|
110
|
+
Notifications: lazy(() => import('../screens/NotificationsScreen')),
|
|
111
|
+
ConnectedApps: lazy(() => import('../screens/ConnectedAppsScreen')),
|
|
112
|
+
Preferences: lazy(() => import('../screens/PreferencesScreen')),
|
|
92
113
|
// Unified account switcher + sign-in surface. Its body lives in the
|
|
93
114
|
// `OxyAccountDialogScreen` component (folded from the standalone dialog); the
|
|
94
115
|
// surface stack provides the Dialog chrome around it.
|
|
95
|
-
AccountDialog: () =>
|
|
116
|
+
AccountDialog: lazy(() => import('../components/OxyAccountDialogScreen')),
|
|
96
117
|
};
|
|
97
118
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return component;
|
|
115
|
-
} catch (error) {
|
|
116
|
-
if (__DEV__) {
|
|
117
|
-
console.error(`[Routes] Failed to load screen: ${routeName}`, error);
|
|
118
|
-
}
|
|
119
|
-
return undefined;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return undefined;
|
|
124
|
-
};
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the component for a route.
|
|
121
|
+
*
|
|
122
|
+
* The map is total over {@link RouteName} — the compiler enforces that at its
|
|
123
|
+
* declaration — so this returns `undefined` only for a caller that reached here
|
|
124
|
+
* with an unchecked string; {@link isValidRoute} is how such a caller narrows.
|
|
125
|
+
*
|
|
126
|
+
* The surface host renders the result with {@link BaseScreenProps} merged with
|
|
127
|
+
* the route's own props bag, so that is the type it is handed back as. This one
|
|
128
|
+
* widening is where the gap documented on {@link screenComponents} lives: the map
|
|
129
|
+
* dispatches on a string key, so a screen's extra prop requirements are met at
|
|
130
|
+
* `present(route, props)` call sites, not provable here. No caching is needed —
|
|
131
|
+
* React memoizes each `lazy()` component's module after its first load.
|
|
132
|
+
*/
|
|
133
|
+
export const getScreenComponent = (routeName: RouteName): ComponentType<BaseScreenProps> | undefined =>
|
|
134
|
+
screenComponents[routeName] as ComponentType<BaseScreenProps>;
|
|
125
135
|
|
|
126
136
|
// Helper function to check if a route exists
|
|
127
|
-
// Uses the
|
|
137
|
+
// Uses the screenComponents map to check existence without loading the screen
|
|
128
138
|
export const isValidRoute = (routeName: string): routeName is RouteName => {
|
|
129
|
-
return routeName in
|
|
139
|
+
return routeName in screenComponents;
|
|
130
140
|
};
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type SurfaceRouteConfig,
|
|
14
14
|
} from './surfaceRegistry';
|
|
15
15
|
import { createSurfaceNavStack, type SurfaceNavStack } from './surfaceNavStack';
|
|
16
|
+
import SurfaceScreen from '../components/SurfaceScreen';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* The SDK's typed surface API — a route registry layered on top of Bloom's
|
|
@@ -153,15 +154,11 @@ function presentInternal<K extends RouteName>(
|
|
|
153
154
|
const config = getSurfaceConfig(route, props);
|
|
154
155
|
const bloomOpts: PresentOptions = { label: route, ...bloomOptionsFor(config), ...opts };
|
|
155
156
|
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// while presenting one renders a
|
|
159
|
-
//
|
|
160
|
-
// the
|
|
161
|
-
const SurfaceScreen = (
|
|
162
|
-
require('../components/SurfaceScreen') as typeof import('../components/SurfaceScreen')
|
|
163
|
-
).default;
|
|
164
|
-
|
|
157
|
+
// `SurfaceScreen` is statically imported but only READ here, at presentation
|
|
158
|
+
// time. That keeps the surfaces.ts <-> SurfaceScreen cycle safe (a mounted
|
|
159
|
+
// SurfaceScreen imports these presenters, while presenting one renders a
|
|
160
|
+
// SurfaceScreen) without a `require()` — which ESM output must never contain,
|
|
161
|
+
// see the note on `screenComponents` in `./routes`.
|
|
165
162
|
const result = bloomSurfaces.present<SurfaceResult<K>>((surface: SurfaceControls) =>
|
|
166
163
|
createElement(SurfaceScreen, {
|
|
167
164
|
navStack,
|