@oxyhq/services 5.13.0 → 5.13.2
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/README.md +71 -0
- package/lib/commonjs/core/HttpClient.js +238 -0
- package/lib/commonjs/core/HttpClient.js.map +1 -0
- package/lib/commonjs/core/OxyServices.js +530 -332
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/RequestManager.js +199 -0
- package/lib/commonjs/core/RequestManager.js.map +1 -0
- package/lib/commonjs/core/index.js +38 -1
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/i18n/index.js +37 -1
- package/lib/commonjs/i18n/index.js.map +1 -1
- package/lib/commonjs/i18n/locales/ar-SA.json +128 -0
- package/lib/commonjs/i18n/locales/ca-ES.json +128 -0
- package/lib/commonjs/i18n/locales/de-DE.json +128 -0
- package/lib/commonjs/i18n/locales/en-US.json +85 -12
- package/lib/commonjs/i18n/locales/es-ES.json +58 -6
- package/lib/commonjs/i18n/locales/fr-FR.json +128 -0
- package/lib/commonjs/i18n/locales/it-IT.json +128 -0
- package/lib/commonjs/i18n/locales/ja-JP.json +127 -0
- package/lib/commonjs/i18n/locales/ko-KR.json +128 -0
- package/lib/commonjs/i18n/locales/pt-PT.json +128 -0
- package/lib/commonjs/i18n/locales/zh-CN.json +128 -0
- package/lib/commonjs/index.js +36 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/Avatar.js +94 -27
- package/lib/commonjs/ui/components/Avatar.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +1 -0
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/FontLoader.js +22 -42
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +5 -8
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.js +64 -44
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +14 -35
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +2 -2
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/internal/TextField.js +13 -8
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +443 -371
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js +80 -22
- package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/commonjs/ui/index.js +4 -1
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +32 -2
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +101 -59
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +3 -2
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +75 -117
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +43 -50
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +14 -16
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +188 -142
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +10 -10
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +2 -4
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +45 -25
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +88 -53
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +79 -58
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +61 -52
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +218 -39
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +77 -50
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +424 -71
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +55 -30
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +64 -46
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +84 -146
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +113 -34
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/stores/accountStore.js +237 -0
- package/lib/commonjs/ui/stores/accountStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +17 -20
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/styles/authStyles.js +16 -8
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/commonjs/ui/styles/index.js +11 -0
- package/lib/commonjs/ui/styles/index.js.map +1 -1
- package/lib/commonjs/ui/styles/spacing.js +51 -0
- package/lib/commonjs/ui/styles/spacing.js.map +1 -0
- package/lib/commonjs/utils/asyncUtils.js +9 -22
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/cache.js +259 -0
- package/lib/commonjs/utils/cache.js.map +1 -0
- package/lib/commonjs/utils/index.js +99 -0
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/utils/languageUtils.js +159 -0
- package/lib/commonjs/utils/languageUtils.js.map +1 -0
- package/lib/commonjs/utils/requestUtils.js +217 -0
- package/lib/commonjs/utils/requestUtils.js.map +1 -0
- package/lib/commonjs/utils/sessionUtils.js +191 -0
- package/lib/commonjs/utils/sessionUtils.js.map +1 -0
- package/lib/commonjs/utils/validationUtils.js +1 -1
- package/lib/module/core/HttpClient.js +232 -0
- package/lib/module/core/HttpClient.js.map +1 -0
- package/lib/module/core/OxyServices.js +528 -326
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/RequestManager.js +194 -0
- package/lib/module/core/RequestManager.js.map +1 -0
- package/lib/module/core/index.js +2 -0
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/i18n/index.js +37 -1
- package/lib/module/i18n/index.js.map +1 -1
- package/lib/module/i18n/locales/ar-SA.json +128 -0
- package/lib/module/i18n/locales/ca-ES.json +128 -0
- package/lib/module/i18n/locales/de-DE.json +128 -0
- package/lib/module/i18n/locales/en-US.json +85 -12
- package/lib/module/i18n/locales/es-ES.json +58 -6
- package/lib/module/i18n/locales/fr-FR.json +128 -0
- package/lib/module/i18n/locales/it-IT.json +128 -0
- package/lib/module/i18n/locales/ja-JP.json +127 -0
- package/lib/module/i18n/locales/ko-KR.json +128 -0
- package/lib/module/i18n/locales/pt-PT.json +128 -0
- package/lib/module/i18n/locales/zh-CN.json +128 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/Avatar.js +94 -27
- package/lib/module/ui/components/Avatar.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +1 -0
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/FontLoader.js +23 -43
- package/lib/module/ui/components/FontLoader.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +6 -8
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/StepBasedScreen.js +65 -45
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +14 -35
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +2 -2
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/internal/TextField.js +13 -8
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +442 -370
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useSessionSocket.js +80 -22
- package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/module/ui/index.js +4 -2
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +33 -2
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +102 -60
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +3 -2
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +73 -117
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +44 -51
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +14 -16
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +187 -143
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +10 -10
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +2 -4
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +45 -25
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +89 -54
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +80 -59
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +62 -53
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +219 -40
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInTotpStep.js +78 -51
- package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +426 -73
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +55 -30
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +65 -47
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +84 -146
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +114 -35
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/stores/accountStore.js +229 -0
- package/lib/module/ui/stores/accountStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +17 -20
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/styles/authStyles.js +16 -8
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/module/ui/styles/index.js +1 -0
- package/lib/module/ui/styles/index.js.map +1 -1
- package/lib/module/ui/styles/spacing.js +48 -0
- package/lib/module/ui/styles/spacing.js.map +1 -0
- package/lib/module/utils/asyncUtils.js +10 -22
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/cache.js +250 -0
- package/lib/module/utils/cache.js.map +1 -0
- package/lib/module/utils/index.js +7 -0
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/languageUtils.js +151 -0
- package/lib/module/utils/languageUtils.js.map +1 -0
- package/lib/module/utils/requestUtils.js +210 -0
- package/lib/module/utils/requestUtils.js.map +1 -0
- package/lib/module/utils/sessionUtils.js +180 -0
- package/lib/module/utils/sessionUtils.js.map +1 -0
- package/lib/module/utils/validationUtils.js +1 -1
- package/lib/typescript/core/HttpClient.d.ts +64 -0
- package/lib/typescript/core/HttpClient.d.ts.map +1 -0
- package/lib/typescript/core/OxyServices.d.ts +86 -73
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/RequestManager.d.ts +67 -0
- package/lib/typescript/core/RequestManager.d.ts.map +1 -0
- package/lib/typescript/core/index.d.ts +2 -0
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/i18n/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +15 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/models/session.d.ts +1 -0
- package/lib/typescript/models/session.d.ts.map +1 -1
- package/lib/typescript/ui/components/Avatar.d.ts +6 -7
- package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts +3 -3
- package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +2 -2
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +5 -0
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
- package/lib/typescript/ui/index.d.ts +2 -2
- package/lib/typescript/ui/index.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts +3 -3
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +2 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/stores/accountStore.d.ts +34 -0
- package/lib/typescript/ui/stores/accountStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/authStore.d.ts +7 -3
- package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
- package/lib/typescript/ui/styles/authStyles.d.ts +19 -2
- package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
- package/lib/typescript/ui/styles/index.d.ts +1 -0
- package/lib/typescript/ui/styles/index.d.ts.map +1 -1
- package/lib/typescript/ui/styles/spacing.d.ts +43 -0
- package/lib/typescript/ui/styles/spacing.d.ts.map +1 -0
- package/lib/typescript/utils/asyncUtils.d.ts +2 -0
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/cache.d.ts +128 -0
- package/lib/typescript/utils/cache.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +4 -0
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/lib/typescript/utils/languageUtils.d.ts +38 -0
- package/lib/typescript/utils/languageUtils.d.ts.map +1 -0
- package/lib/typescript/utils/requestUtils.d.ts +122 -0
- package/lib/typescript/utils/requestUtils.d.ts.map +1 -0
- package/lib/typescript/utils/sessionUtils.d.ts +55 -0
- package/lib/typescript/utils/sessionUtils.d.ts.map +1 -0
- package/lib/typescript/utils/validationUtils.d.ts +1 -1
- package/package.json +1 -1
- package/src/core/HttpClient.ts +277 -0
- package/src/core/OxyServices.ts +461 -352
- package/src/core/RequestManager.ts +240 -0
- package/src/core/index.ts +10 -0
- package/src/i18n/index.ts +36 -0
- package/src/i18n/locales/ar-SA.json +128 -0
- package/src/i18n/locales/ca-ES.json +128 -0
- package/src/i18n/locales/de-DE.json +128 -0
- package/src/i18n/locales/en-US.json +85 -12
- package/src/i18n/locales/es-ES.json +58 -6
- package/src/i18n/locales/fr-FR.json +128 -0
- package/src/i18n/locales/it-IT.json +128 -0
- package/src/i18n/locales/ja-JP.json +127 -0
- package/src/i18n/locales/ko-KR.json +128 -0
- package/src/i18n/locales/pt-PT.json +128 -0
- package/src/i18n/locales/zh-CN.json +128 -0
- package/src/index.ts +10 -0
- package/src/models/interfaces.ts +19 -0
- package/src/models/session.ts +1 -1
- package/src/ui/components/Avatar.tsx +151 -35
- package/src/ui/components/FollowButton.tsx +1 -0
- package/src/ui/components/FontLoader.tsx +17 -37
- package/src/ui/components/OxyProvider.tsx +14 -13
- package/src/ui/components/StepBasedScreen.tsx +66 -43
- package/src/ui/components/internal/GroupedPillButtons.tsx +15 -31
- package/src/ui/components/internal/PinInput.tsx +2 -2
- package/src/ui/components/internal/TextField.tsx +7 -6
- package/src/ui/context/OxyContext.tsx +441 -326
- package/src/ui/hooks/useSessionSocket.ts +72 -18
- package/src/ui/index.ts +4 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +34 -2
- package/src/ui/screens/AccountSwitcherScreen.tsx +102 -68
- package/src/ui/screens/FileManagementScreen.tsx +16 -16
- package/src/ui/screens/LanguageSelectorScreen.tsx +86 -143
- package/src/ui/screens/SignInScreen.tsx +59 -43
- package/src/ui/screens/SignUpScreen.tsx +14 -15
- package/src/ui/screens/WelcomeNewUserScreen.tsx +153 -105
- package/src/ui/screens/internal/SignInPasswordStep.tsx +4 -6
- package/src/ui/screens/internal/SignInUsernameStep.tsx +1 -1
- package/src/ui/screens/steps/RecoverRequestStep.tsx +34 -24
- package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +65 -36
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +71 -47
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +60 -50
- package/src/ui/screens/steps/SignInPasswordStep.tsx +190 -32
- package/src/ui/screens/steps/SignInTotpStep.tsx +68 -34
- package/src/ui/screens/steps/SignInUsernameStep.tsx +446 -63
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +49 -35
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +56 -39
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +99 -89
- package/src/ui/screens/steps/SignUpWelcomeStep.tsx +88 -20
- package/src/ui/stores/accountStore.ts +285 -0
- package/src/ui/stores/authStore.ts +16 -19
- package/src/ui/styles/authStyles.ts +16 -8
- package/src/ui/styles/index.ts +1 -0
- package/src/ui/styles/spacing.ts +46 -0
- package/src/utils/asyncUtils.ts +10 -24
- package/src/utils/cache.ts +264 -0
- package/src/utils/index.ts +19 -0
- package/src/utils/languageUtils.ts +174 -0
- package/src/utils/requestUtils.ts +234 -0
- package/src/utils/sessionUtils.ts +206 -0
- package/src/utils/validationUtils.ts +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized cache utility with TTL support
|
|
3
|
+
*
|
|
4
|
+
* This is a production-ready cache implementation used across the codebase
|
|
5
|
+
* for consistent caching behavior and performance optimization.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cache entry with expiration tracking
|
|
10
|
+
*/
|
|
11
|
+
interface CacheEntry<T> {
|
|
12
|
+
data: T;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
expiresAt: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Cache statistics
|
|
19
|
+
*/
|
|
20
|
+
export interface CacheStats {
|
|
21
|
+
size: number;
|
|
22
|
+
hits: number;
|
|
23
|
+
misses: number;
|
|
24
|
+
hitRate: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* TTL-based cache implementation
|
|
29
|
+
*
|
|
30
|
+
* Features:
|
|
31
|
+
* - Automatic expiration based on TTL
|
|
32
|
+
* - Manual cleanup of expired entries
|
|
33
|
+
* - Statistics tracking (hits, misses, hit rate)
|
|
34
|
+
* - Type-safe generic interface
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const cache = new TTLCache<string>(5 * 60 * 1000); // 5 minutes
|
|
39
|
+
*
|
|
40
|
+
* // Set with default TTL
|
|
41
|
+
* cache.set('key', 'value');
|
|
42
|
+
*
|
|
43
|
+
* // Set with custom TTL
|
|
44
|
+
* cache.set('key', 'value', 10 * 60 * 1000); // 10 minutes
|
|
45
|
+
*
|
|
46
|
+
* // Get value
|
|
47
|
+
* const value = cache.get('key');
|
|
48
|
+
*
|
|
49
|
+
* // Get statistics
|
|
50
|
+
* const stats = cache.getStats();
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export class TTLCache<T> {
|
|
54
|
+
private cache = new Map<string, CacheEntry<T>>();
|
|
55
|
+
private defaultTTL: number;
|
|
56
|
+
private hits = 0;
|
|
57
|
+
private misses = 0;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a new TTL cache
|
|
61
|
+
* @param defaultTTL Default TTL in milliseconds (default: 5 minutes)
|
|
62
|
+
*/
|
|
63
|
+
constructor(defaultTTL: number = 5 * 60 * 1000) {
|
|
64
|
+
this.defaultTTL = defaultTTL;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get a value from cache
|
|
69
|
+
* @param key Cache key
|
|
70
|
+
* @returns Cached value or null if not found or expired
|
|
71
|
+
*/
|
|
72
|
+
get(key: string): T | null {
|
|
73
|
+
const entry = this.cache.get(key);
|
|
74
|
+
if (!entry) {
|
|
75
|
+
this.misses++;
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const now = Date.now();
|
|
80
|
+
if (now > entry.expiresAt) {
|
|
81
|
+
this.cache.delete(key);
|
|
82
|
+
this.misses++;
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.hits++;
|
|
87
|
+
return entry.data;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Set a value in cache
|
|
92
|
+
* @param key Cache key
|
|
93
|
+
* @param data Data to cache
|
|
94
|
+
* @param ttl Optional TTL override (uses default if not provided)
|
|
95
|
+
*/
|
|
96
|
+
set(key: string, data: T, ttl?: number): void {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
const expiresAt = now + (ttl || this.defaultTTL);
|
|
99
|
+
this.cache.set(key, { data, timestamp: now, expiresAt });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Delete a specific cache entry
|
|
104
|
+
* @param key Cache key
|
|
105
|
+
* @returns true if entry was deleted, false if not found
|
|
106
|
+
*/
|
|
107
|
+
delete(key: string): boolean {
|
|
108
|
+
return this.cache.delete(key);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Clear all cache entries
|
|
113
|
+
*/
|
|
114
|
+
clear(): void {
|
|
115
|
+
this.cache.clear();
|
|
116
|
+
this.hits = 0;
|
|
117
|
+
this.misses = 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if a key exists and is not expired
|
|
122
|
+
* @param key Cache key
|
|
123
|
+
* @returns true if key exists and is valid
|
|
124
|
+
*/
|
|
125
|
+
has(key: string): boolean {
|
|
126
|
+
const entry = this.cache.get(key);
|
|
127
|
+
if (!entry) return false;
|
|
128
|
+
|
|
129
|
+
if (Date.now() > entry.expiresAt) {
|
|
130
|
+
this.cache.delete(key);
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get all valid cache keys
|
|
139
|
+
* @returns Array of valid cache keys
|
|
140
|
+
*/
|
|
141
|
+
keys(): string[] {
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
const validKeys: string[] = [];
|
|
144
|
+
|
|
145
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
146
|
+
if (now <= entry.expiresAt) {
|
|
147
|
+
validKeys.push(key);
|
|
148
|
+
} else {
|
|
149
|
+
this.cache.delete(key);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return validKeys;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Clean up expired entries
|
|
158
|
+
* @returns Number of entries removed
|
|
159
|
+
*/
|
|
160
|
+
cleanup(): number {
|
|
161
|
+
const now = Date.now();
|
|
162
|
+
let removed = 0;
|
|
163
|
+
|
|
164
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
165
|
+
if (now > entry.expiresAt) {
|
|
166
|
+
this.cache.delete(key);
|
|
167
|
+
removed++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return removed;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get cache size (number of entries)
|
|
176
|
+
*/
|
|
177
|
+
size(): number {
|
|
178
|
+
return this.cache.size;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get cache statistics
|
|
183
|
+
*/
|
|
184
|
+
getStats(): CacheStats {
|
|
185
|
+
const total = this.hits + this.misses;
|
|
186
|
+
return {
|
|
187
|
+
size: this.cache.size,
|
|
188
|
+
hits: this.hits,
|
|
189
|
+
misses: this.misses,
|
|
190
|
+
hitRate: total > 0 ? this.hits / total : 0,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Reset statistics (keeps cache entries)
|
|
196
|
+
*/
|
|
197
|
+
resetStats(): void {
|
|
198
|
+
this.hits = 0;
|
|
199
|
+
this.misses = 0;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Create a TTL cache instance (convenience function)
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* const cache = createCache<string>(5 * 60 * 1000);
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export function createCache<T>(ttl: number = 5 * 60 * 1000): TTLCache<T> {
|
|
212
|
+
return new TTLCache<T>(ttl);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Global cache cleanup interval (runs every minute)
|
|
217
|
+
* This helps prevent memory leaks from expired cache entries
|
|
218
|
+
*/
|
|
219
|
+
let cleanupInterval: NodeJS.Timeout | null = null;
|
|
220
|
+
const activeCaches = new Set<TTLCache<any>>();
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Register a cache for automatic cleanup
|
|
224
|
+
* @param cache Cache instance to register
|
|
225
|
+
*/
|
|
226
|
+
export function registerCacheForCleanup(cache: TTLCache<any>): void {
|
|
227
|
+
activeCaches.add(cache);
|
|
228
|
+
|
|
229
|
+
// Start cleanup interval if not already running
|
|
230
|
+
if (!cleanupInterval) {
|
|
231
|
+
cleanupInterval = setInterval(() => {
|
|
232
|
+
for (const cache of activeCaches) {
|
|
233
|
+
cache.cleanup();
|
|
234
|
+
}
|
|
235
|
+
}, 60000); // Every minute
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Unregister a cache from automatic cleanup
|
|
241
|
+
* @param cache Cache instance to unregister
|
|
242
|
+
*/
|
|
243
|
+
export function unregisterCacheFromCleanup(cache: TTLCache<any>): void {
|
|
244
|
+
activeCaches.delete(cache);
|
|
245
|
+
|
|
246
|
+
// Stop cleanup interval if no caches are registered
|
|
247
|
+
if (activeCaches.size === 0 && cleanupInterval) {
|
|
248
|
+
clearInterval(cleanupInterval);
|
|
249
|
+
cleanupInterval = null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Stop all cache cleanup intervals
|
|
255
|
+
* Useful for tests to prevent Jest from hanging
|
|
256
|
+
*/
|
|
257
|
+
export function stopAllCacheCleanup(): void {
|
|
258
|
+
if (cleanupInterval) {
|
|
259
|
+
clearInterval(cleanupInterval);
|
|
260
|
+
cleanupInterval = null;
|
|
261
|
+
}
|
|
262
|
+
activeCaches.clear();
|
|
263
|
+
}
|
|
264
|
+
|
package/src/utils/index.ts
CHANGED
|
@@ -1,2 +1,21 @@
|
|
|
1
1
|
export { DeviceManager } from './deviceManager';
|
|
2
2
|
export type { DeviceFingerprint, StoredDeviceInfo } from './deviceManager';
|
|
3
|
+
|
|
4
|
+
// Request utilities
|
|
5
|
+
export { RequestDeduplicator, RequestQueue, SimpleLogger } from './requestUtils';
|
|
6
|
+
|
|
7
|
+
// Cache utilities
|
|
8
|
+
export { TTLCache, createCache, registerCacheForCleanup, unregisterCacheFromCleanup, stopAllCacheCleanup } from './cache';
|
|
9
|
+
export type { CacheStats } from './cache';
|
|
10
|
+
|
|
11
|
+
// Session utilities
|
|
12
|
+
export {
|
|
13
|
+
normalizeSession,
|
|
14
|
+
sortSessions,
|
|
15
|
+
deduplicateSessions,
|
|
16
|
+
deduplicateSessionsByUserId,
|
|
17
|
+
normalizeAndSortSessions,
|
|
18
|
+
mergeSessions,
|
|
19
|
+
sessionsEqual,
|
|
20
|
+
sessionsArraysEqual
|
|
21
|
+
} from './sessionUtils';
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language utilities for OxyServices
|
|
3
|
+
* Provides access to supported languages and language metadata
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface LanguageMetadata {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
nativeName: string;
|
|
10
|
+
flag: string;
|
|
11
|
+
icon: string;
|
|
12
|
+
color: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Supported languages with their metadata
|
|
16
|
+
export const SUPPORTED_LANGUAGES: LanguageMetadata[] = [
|
|
17
|
+
{
|
|
18
|
+
id: 'en-US',
|
|
19
|
+
name: 'English',
|
|
20
|
+
nativeName: 'English',
|
|
21
|
+
flag: '🇺🇸',
|
|
22
|
+
icon: 'language-outline',
|
|
23
|
+
color: '#007AFF',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'es-ES',
|
|
27
|
+
name: 'Spanish',
|
|
28
|
+
nativeName: 'Español',
|
|
29
|
+
flag: '🇪🇸',
|
|
30
|
+
icon: 'language-outline',
|
|
31
|
+
color: '#FF3B30',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'ca-ES',
|
|
35
|
+
name: 'Catalan',
|
|
36
|
+
nativeName: 'Català',
|
|
37
|
+
flag: '🇪🇸',
|
|
38
|
+
icon: 'language-outline',
|
|
39
|
+
color: '#0CA678',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'fr-FR',
|
|
43
|
+
name: 'French',
|
|
44
|
+
nativeName: 'Français',
|
|
45
|
+
flag: '🇫🇷',
|
|
46
|
+
icon: 'language-outline',
|
|
47
|
+
color: '#5856D6',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'de-DE',
|
|
51
|
+
name: 'German',
|
|
52
|
+
nativeName: 'Deutsch',
|
|
53
|
+
flag: '🇩🇪',
|
|
54
|
+
icon: 'language-outline',
|
|
55
|
+
color: '#FF9500',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'it-IT',
|
|
59
|
+
name: 'Italian',
|
|
60
|
+
nativeName: 'Italiano',
|
|
61
|
+
flag: '🇮🇹',
|
|
62
|
+
icon: 'language-outline',
|
|
63
|
+
color: '#34C759',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'pt-PT',
|
|
67
|
+
name: 'Portuguese',
|
|
68
|
+
nativeName: 'Português',
|
|
69
|
+
flag: '🇵🇹',
|
|
70
|
+
icon: 'language-outline',
|
|
71
|
+
color: '#AF52DE',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'ja-JP',
|
|
75
|
+
name: 'Japanese',
|
|
76
|
+
nativeName: '日本語',
|
|
77
|
+
flag: '🇯🇵',
|
|
78
|
+
icon: 'language-outline',
|
|
79
|
+
color: '#FF2D92',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'ko-KR',
|
|
83
|
+
name: 'Korean',
|
|
84
|
+
nativeName: '한국어',
|
|
85
|
+
flag: '🇰🇷',
|
|
86
|
+
icon: 'language-outline',
|
|
87
|
+
color: '#32D74B',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'zh-CN',
|
|
91
|
+
name: 'Chinese',
|
|
92
|
+
nativeName: '中文',
|
|
93
|
+
flag: '🇨🇳',
|
|
94
|
+
icon: 'language-outline',
|
|
95
|
+
color: '#FF9F0A',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: 'ar-SA',
|
|
99
|
+
name: 'Arabic',
|
|
100
|
+
nativeName: 'العربية',
|
|
101
|
+
flag: '🇸🇦',
|
|
102
|
+
icon: 'language-outline',
|
|
103
|
+
color: '#30B0C7',
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
const FALLBACK_LANGUAGE = 'en-US';
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get language metadata by language code
|
|
111
|
+
* @param languageCode - BCP-47 language code (e.g., 'en-US', 'es-ES')
|
|
112
|
+
* @returns Language metadata or null if not found
|
|
113
|
+
*/
|
|
114
|
+
export function getLanguageMetadata(languageCode: string | null | undefined): LanguageMetadata | null {
|
|
115
|
+
if (!languageCode) return null;
|
|
116
|
+
|
|
117
|
+
// Direct match
|
|
118
|
+
const exactMatch = SUPPORTED_LANGUAGES.find(lang => lang.id === languageCode);
|
|
119
|
+
if (exactMatch) return exactMatch;
|
|
120
|
+
|
|
121
|
+
// Try to match base language code (e.g., 'en' matches 'en-US')
|
|
122
|
+
const baseCode = languageCode.split('-')[0];
|
|
123
|
+
const baseMatch = SUPPORTED_LANGUAGES.find(lang => lang.id.startsWith(baseCode + '-'));
|
|
124
|
+
if (baseMatch) return baseMatch;
|
|
125
|
+
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get language name by language code
|
|
131
|
+
* @param languageCode - BCP-47 language code (e.g., 'en-US', 'es-ES')
|
|
132
|
+
* @returns Language name (e.g., 'English') or the code if not found
|
|
133
|
+
*/
|
|
134
|
+
export function getLanguageName(languageCode: string | null | undefined): string {
|
|
135
|
+
const metadata = getLanguageMetadata(languageCode);
|
|
136
|
+
return metadata?.name || languageCode || FALLBACK_LANGUAGE;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get native language name by language code
|
|
141
|
+
* @param languageCode - BCP-47 language code (e.g., 'en-US', 'es-ES')
|
|
142
|
+
* @returns Native language name (e.g., 'Español') or the code if not found
|
|
143
|
+
*/
|
|
144
|
+
export function getNativeLanguageName(languageCode: string | null | undefined): string {
|
|
145
|
+
const metadata = getLanguageMetadata(languageCode);
|
|
146
|
+
return metadata?.nativeName || languageCode || FALLBACK_LANGUAGE;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Normalize language code to BCP-47 format
|
|
151
|
+
* @param lang - Language code (may be short like 'en' or full like 'en-US')
|
|
152
|
+
* @returns Normalized BCP-47 language code
|
|
153
|
+
*/
|
|
154
|
+
export function normalizeLanguageCode(lang?: string | null): string {
|
|
155
|
+
if (!lang) return FALLBACK_LANGUAGE;
|
|
156
|
+
if (lang.includes('-')) return lang;
|
|
157
|
+
|
|
158
|
+
const map: Record<string, string> = {
|
|
159
|
+
en: 'en-US',
|
|
160
|
+
es: 'es-ES',
|
|
161
|
+
ca: 'ca-ES',
|
|
162
|
+
fr: 'fr-FR',
|
|
163
|
+
de: 'de-DE',
|
|
164
|
+
it: 'it-IT',
|
|
165
|
+
pt: 'pt-PT',
|
|
166
|
+
ja: 'ja-JP',
|
|
167
|
+
ko: 'ko-KR',
|
|
168
|
+
zh: 'zh-CN',
|
|
169
|
+
ar: 'ar-SA',
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
return map[lang] || lang;
|
|
173
|
+
}
|
|
174
|
+
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request utilities for HTTP clients
|
|
3
|
+
*
|
|
4
|
+
* Provides reusable components for request deduplication, queuing, and logging
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Request deduplication - prevents duplicate concurrent requests
|
|
9
|
+
*
|
|
10
|
+
* When multiple requests with the same key are made simultaneously,
|
|
11
|
+
* only one request is executed and all callers receive the same result.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const deduplicator = new RequestDeduplicator();
|
|
16
|
+
*
|
|
17
|
+
* // Multiple calls with same key will share the same promise
|
|
18
|
+
* const promise1 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
19
|
+
* const promise2 = deduplicator.deduplicate('user-123', () => fetchUser('123'));
|
|
20
|
+
* // promise1 === promise2, only one API call is made
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class RequestDeduplicator {
|
|
24
|
+
private pendingRequests = new Map<string, Promise<any>>();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Deduplicate a request by key
|
|
28
|
+
* @param key Unique key for the request
|
|
29
|
+
* @param requestFn Function that returns a promise
|
|
30
|
+
* @returns Promise that will be shared if key already exists
|
|
31
|
+
*/
|
|
32
|
+
async deduplicate<T>(
|
|
33
|
+
key: string,
|
|
34
|
+
requestFn: () => Promise<T>
|
|
35
|
+
): Promise<T> {
|
|
36
|
+
const existing = this.pendingRequests.get(key);
|
|
37
|
+
if (existing) {
|
|
38
|
+
return existing;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const promise = requestFn()
|
|
42
|
+
.finally(() => {
|
|
43
|
+
this.pendingRequests.delete(key);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.pendingRequests.set(key, promise);
|
|
47
|
+
return promise;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Clear all pending requests
|
|
52
|
+
*/
|
|
53
|
+
clear(): void {
|
|
54
|
+
this.pendingRequests.clear();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get number of pending requests
|
|
59
|
+
*/
|
|
60
|
+
size(): number {
|
|
61
|
+
return this.pendingRequests.size;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Request queue with concurrency control
|
|
67
|
+
*
|
|
68
|
+
* Limits the number of concurrent requests and queues excess requests.
|
|
69
|
+
* Useful for rate limiting and preventing request flooding.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const queue = new RequestQueue(5, 100); // Max 5 concurrent, queue up to 100
|
|
74
|
+
*
|
|
75
|
+
* // All requests will be queued and processed with max 5 concurrent
|
|
76
|
+
* await queue.enqueue(() => fetchUser('1'));
|
|
77
|
+
* await queue.enqueue(() => fetchUser('2'));
|
|
78
|
+
* // ...
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export class RequestQueue {
|
|
82
|
+
private queue: Array<() => Promise<any>> = [];
|
|
83
|
+
private running = 0;
|
|
84
|
+
private maxConcurrent: number;
|
|
85
|
+
private maxQueueSize: number;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create a new request queue
|
|
89
|
+
* @param maxConcurrent Maximum number of concurrent requests (default: 10)
|
|
90
|
+
* @param maxQueueSize Maximum queue size (default: 100)
|
|
91
|
+
*/
|
|
92
|
+
constructor(maxConcurrent: number = 10, maxQueueSize: number = 100) {
|
|
93
|
+
this.maxConcurrent = maxConcurrent;
|
|
94
|
+
this.maxQueueSize = maxQueueSize;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Enqueue a request
|
|
99
|
+
* @param requestFn Function that returns a promise
|
|
100
|
+
* @returns Promise that resolves when request completes
|
|
101
|
+
*/
|
|
102
|
+
async enqueue<T>(requestFn: () => Promise<T>): Promise<T> {
|
|
103
|
+
if (this.queue.length >= this.maxQueueSize) {
|
|
104
|
+
throw new Error('Request queue is full');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return new Promise<T>((resolve, reject) => {
|
|
108
|
+
this.queue.push(async () => {
|
|
109
|
+
try {
|
|
110
|
+
const result = await requestFn();
|
|
111
|
+
resolve(result);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
reject(error);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
this.process();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Process queued requests
|
|
123
|
+
*/
|
|
124
|
+
private async process(): Promise<void> {
|
|
125
|
+
if (this.running >= this.maxConcurrent || this.queue.length === 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.running++;
|
|
130
|
+
const requestFn = this.queue.shift();
|
|
131
|
+
if (requestFn) {
|
|
132
|
+
try {
|
|
133
|
+
await requestFn();
|
|
134
|
+
} finally {
|
|
135
|
+
this.running--;
|
|
136
|
+
this.process();
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
this.running--;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Clear all queued requests
|
|
145
|
+
*/
|
|
146
|
+
clear(): void {
|
|
147
|
+
this.queue = [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get queue size
|
|
152
|
+
*/
|
|
153
|
+
size(): number {
|
|
154
|
+
return this.queue.length;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get number of currently running requests
|
|
159
|
+
*/
|
|
160
|
+
runningCount(): number {
|
|
161
|
+
return this.running;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Simple logger with level support
|
|
167
|
+
*
|
|
168
|
+
* Lightweight logger for HTTP clients and utilities.
|
|
169
|
+
* For more advanced logging, use loggerUtils.ts
|
|
170
|
+
*
|
|
171
|
+
* @example
|
|
172
|
+
* ```typescript
|
|
173
|
+
* const logger = new SimpleLogger(true, 'debug');
|
|
174
|
+
* logger.debug('Debug message');
|
|
175
|
+
* logger.info('Info message');
|
|
176
|
+
* logger.error('Error message');
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export class SimpleLogger {
|
|
180
|
+
private enabled: boolean;
|
|
181
|
+
private level: 'none' | 'error' | 'warn' | 'info' | 'debug';
|
|
182
|
+
private prefix: string;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Create a new simple logger
|
|
186
|
+
* @param enabled Whether logging is enabled
|
|
187
|
+
* @param level Minimum log level
|
|
188
|
+
* @param prefix Prefix for log messages (default: '')
|
|
189
|
+
*/
|
|
190
|
+
constructor(
|
|
191
|
+
enabled: boolean = false,
|
|
192
|
+
level: string = 'error',
|
|
193
|
+
prefix: string = ''
|
|
194
|
+
) {
|
|
195
|
+
this.enabled = enabled;
|
|
196
|
+
this.level = level as any;
|
|
197
|
+
this.prefix = prefix;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private shouldLog(level: string): boolean {
|
|
201
|
+
if (!this.enabled || this.level === 'none') return false;
|
|
202
|
+
const levels = ['none', 'error', 'warn', 'info', 'debug'];
|
|
203
|
+
return levels.indexOf(level) <= levels.indexOf(this.level);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private formatMessage(...args: any[]): any[] {
|
|
207
|
+
return this.prefix ? [`[${this.prefix}]`, ...args] : args;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
error(...args: any[]): void {
|
|
211
|
+
if (this.shouldLog('error')) {
|
|
212
|
+
console.error(...this.formatMessage(...args));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
warn(...args: any[]): void {
|
|
217
|
+
if (this.shouldLog('warn')) {
|
|
218
|
+
console.warn(...this.formatMessage(...args));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
info(...args: any[]): void {
|
|
223
|
+
if (this.shouldLog('info')) {
|
|
224
|
+
console.info(...this.formatMessage(...args));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
debug(...args: any[]): void {
|
|
229
|
+
if (this.shouldLog('debug')) {
|
|
230
|
+
console.log(...this.formatMessage(...args));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|