react-memory-optimization 0.0.119 → 0.0.121

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.
@@ -85,4 +85,37 @@ exports.PAYMENT_REQUEST_PATHS = {
85
85
  path: types_1.EApiPath.CreateProdDeposit,
86
86
  adapterFn: utils_1.restAdapterDeposit,
87
87
  },
88
+ // BetterBro BDT
89
+ [types_1.EPaymentRequestPath.BetterBroBkashDeposit]: {
90
+ path: types_1.EApiPath.CreateProdDeposit,
91
+ adapterFn: utils_1.restAdapterDeposit,
92
+ },
93
+ [types_1.EPaymentRequestPath.BetterBroBkashWithdraw]: {
94
+ path: types_1.EApiPath.CreateProdWithdraw,
95
+ adapterFn: utils_1.restAdapterDeposit,
96
+ },
97
+ [types_1.EPaymentRequestPath.BetterBroNagadDeposit]: {
98
+ path: types_1.EApiPath.CreateProdDeposit,
99
+ adapterFn: utils_1.restAdapterDeposit,
100
+ },
101
+ [types_1.EPaymentRequestPath.BetterBroNagadWithdraw]: {
102
+ path: types_1.EApiPath.CreateProdWithdraw,
103
+ adapterFn: utils_1.restAdapterWithdraw,
104
+ },
105
+ [types_1.EPaymentRequestPath.BetterBroEasypaisaDeposit]: {
106
+ path: types_1.EApiPath.CreateProdDeposit,
107
+ adapterFn: utils_1.restAdapterDeposit,
108
+ },
109
+ [types_1.EPaymentRequestPath.BetterBroEasypaisaWithdraw]: {
110
+ path: types_1.EApiPath.CreateProdWithdraw,
111
+ adapterFn: utils_1.restAdapterWithdraw,
112
+ },
113
+ [types_1.EPaymentRequestPath.BetterBroJazzCashDeposit]: {
114
+ path: types_1.EApiPath.CreateProdDeposit,
115
+ adapterFn: utils_1.restAdapterDeposit,
116
+ },
117
+ [types_1.EPaymentRequestPath.BetterBroJazzCashWithdraw]: {
118
+ path: types_1.EApiPath.CreateProdWithdraw,
119
+ adapterFn: utils_1.restAdapterWithdraw,
120
+ },
88
121
  };
@@ -35,7 +35,15 @@ export declare enum EPaymentRequestPath {
35
35
  PayinOnlineBankingMYRDepositDeposit = "prepare_data_for_payin_online_banking_myr",
36
36
  PayinOnlineBankingMYRDepositWithdraw = "prepare_data_for_payout_online_banking_myr",
37
37
  PayoutBankTransferMYRWithdraw = "payout_bank_transfer_myr_withdraw",
38
- PayinBankTransferMYRDeposit = "payin_bank_transfer_myr_deposit"
38
+ PayinBankTransferMYRDeposit = "payin_bank_transfer_myr_deposit",
39
+ BetterBroBkashDeposit = "better_bro_bkash_deposit",
40
+ BetterBroBkashWithdraw = "better_bro_bkash_withdraw",
41
+ BetterBroNagadDeposit = "better_bro_nagad_deposit",
42
+ BetterBroNagadWithdraw = "better_bro_nagad_withdraw",
43
+ BetterBroEasypaisaDeposit = "better_bro_easypaisa_deposit",
44
+ BetterBroEasypaisaWithdraw = "better_bro_easypaisa_withdraw",
45
+ BetterBroJazzCashDeposit = "better_bro_jazzcash_deposit",
46
+ BetterBroJazzCashWithdraw = "better_bro_jazzcash_withdraw"
39
47
  }
40
48
  export type ApiList = {
41
49
  [key: string]: {
@@ -42,6 +42,16 @@ var EPaymentRequestPath;
42
42
  EPaymentRequestPath["PayinOnlineBankingMYRDepositWithdraw"] = "prepare_data_for_payout_online_banking_myr";
43
43
  EPaymentRequestPath["PayoutBankTransferMYRWithdraw"] = "payout_bank_transfer_myr_withdraw";
44
44
  EPaymentRequestPath["PayinBankTransferMYRDeposit"] = "payin_bank_transfer_myr_deposit";
45
+ // BetterBro BDT
46
+ EPaymentRequestPath["BetterBroBkashDeposit"] = "better_bro_bkash_deposit";
47
+ EPaymentRequestPath["BetterBroBkashWithdraw"] = "better_bro_bkash_withdraw";
48
+ EPaymentRequestPath["BetterBroNagadDeposit"] = "better_bro_nagad_deposit";
49
+ EPaymentRequestPath["BetterBroNagadWithdraw"] = "better_bro_nagad_withdraw";
50
+ // BetterBro PKR
51
+ EPaymentRequestPath["BetterBroEasypaisaDeposit"] = "better_bro_easypaisa_deposit";
52
+ EPaymentRequestPath["BetterBroEasypaisaWithdraw"] = "better_bro_easypaisa_withdraw";
53
+ EPaymentRequestPath["BetterBroJazzCashDeposit"] = "better_bro_jazzcash_deposit";
54
+ EPaymentRequestPath["BetterBroJazzCashWithdraw"] = "better_bro_jazzcash_withdraw";
45
55
  })(EPaymentRequestPath || (exports.EPaymentRequestPath = EPaymentRequestPath = {}));
46
56
  // FlashPayUpiDeposit
47
57
  var EPaymentStatusCode;
@@ -4,16 +4,20 @@ import { ApiTransport } from './transport/api-transport';
4
4
  import { ShadowIntegrationSettings } from './types';
5
5
  import { Currencies } from './store/Currencies';
6
6
  import { User } from './store/User';
7
+ import { Games } from './store/Games';
7
8
  export declare class NewFlowEntity {
8
9
  _settings: ShadowIntegrationSettings;
9
- _uiEntities: UIEntities | null;
10
10
  _apiTransport: ApiTransport;
11
11
  _socketInstance: Socket;
12
+ _uiEntities: UIEntities | null;
12
13
  _currencies: Currencies | null;
13
14
  _user: User | null;
15
+ _games: Games | null;
14
16
  constructor(socketInstance: Socket, settings?: ShadowIntegrationSettings);
15
17
  set user(user: User);
16
18
  get user(): User | null;
19
+ set games(games: Games);
20
+ get games(): Games | null;
17
21
  set apiTransport(apiTransport: ApiTransport);
18
22
  get apiTransport(): ApiTransport;
19
23
  set settings(settings: ShadowIntegrationSettings);
@@ -0,0 +1,26 @@
1
+ import { ObservableEntity } from 'service/observableEntity';
2
+ import { GamesService } from './service';
3
+ import { NewFlowEntity } from 'store/new-flow';
4
+ import { CasinoGamesInfo, CasinoGamesRequestInfo, CasinoGamesRequestStatus } from './types';
5
+ import { BaseObservableSubscriber, UpdateData } from 'service/observable/type';
6
+ export declare class Games extends ObservableEntity<undefined> {
7
+ _games: {
8
+ [key: string]: CasinoGamesInfo;
9
+ };
10
+ _status: CasinoGamesRequestInfo;
11
+ services: GamesService;
12
+ root: NewFlowEntity;
13
+ constructor(root: NewFlowEntity);
14
+ set status(status: CasinoGamesRequestInfo);
15
+ get status(): CasinoGamesRequestInfo;
16
+ set games(games: {
17
+ [key: string]: CasinoGamesInfo;
18
+ });
19
+ get games(): {
20
+ [key: string]: CasinoGamesInfo;
21
+ };
22
+ updateRequestStatus(key: string, status: CasinoGamesRequestStatus, info?: unknown): void;
23
+ sendUpdateEntity(d: BaseObservableSubscriber & {
24
+ [key: string]: unknown;
25
+ }): UpdateData | null;
26
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseObservableSubscriber } from 'service/observable/type';
2
+ import { Games } from '..';
3
+ export declare class GamesService {
4
+ parent: Games;
5
+ constructor(parent: Games);
6
+ getUniqKey(d: BaseObservableSubscriber & {
7
+ [key: string]: unknown;
8
+ }): string;
9
+ private adaptingGames;
10
+ private mergeGames;
11
+ getGamesByCategory(key: string): Promise<null>;
12
+ }
@@ -0,0 +1,30 @@
1
+ export type ResponseCasinoGamesRequest = {
2
+ items: ResponseCasinoGame[];
3
+ nextCursor: string;
4
+ };
5
+ export type ResponseCasinoGame = {
6
+ hasFreespins: boolean;
7
+ id: string;
8
+ images: {
9
+ url: string;
10
+ }[];
11
+ isMobile: boolean;
12
+ label: string;
13
+ name: string;
14
+ type: string;
15
+ };
16
+ export type CasinoGame = Omit<ResponseCasinoGame, 'type'> & {
17
+ imageUrl: string;
18
+ type?: undefined;
19
+ };
20
+ export type CasinoGamesRequestInfo = {
21
+ [key: string]: {
22
+ status: CasinoGamesRequestStatus;
23
+ data: unknown;
24
+ };
25
+ };
26
+ export type CasinoGamesRequestStatus = 'idle' | 'loading' | 'success' | 'error';
27
+ export type CasinoGamesInfo = {
28
+ games: CasinoGame[];
29
+ nextCursor: string;
30
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -5,10 +5,14 @@ export declare class ApiTransport {
5
5
  _baseUrl: string;
6
6
  _isConfigured: boolean;
7
7
  baseHeaders: Record<string, string>;
8
- _requestQueue: RequestQueue[];
8
+ _requestQueue: Map<string, RequestQueue>;
9
9
  _accessToken: string;
10
10
  _refreshToken: string;
11
11
  _meInfo: UserInfo | null;
12
+ private _isRefreshing;
13
+ private _refreshPromise;
14
+ private _isProcessingQueue;
15
+ private _inFlightRequests;
12
16
  constructor();
13
17
  set meInfo(meInfo: UserInfo);
14
18
  get meInfo(): UserInfo | null;
@@ -16,19 +20,31 @@ export declare class ApiTransport {
16
20
  get accessToken(): string;
17
21
  set refreshToken(refreshToken: string);
18
22
  get refreshToken(): string;
19
- set requestQueue(requestQueue: RequestQueue[]);
20
- get requestQueue(): RequestQueue[];
23
+ set requestQueue(requestQueue: Map<string, RequestQueue>);
24
+ get requestQueue(): Map<string, RequestQueue>;
21
25
  set isConfigured(isConfigured: boolean);
22
26
  get isConfigured(): boolean;
23
27
  set baseUrl(baseUrl: string);
24
28
  get baseUrl(): string;
25
29
  me(): Promise<void>;
30
+ /**
31
+ * Выполняет рефреш токена с защитой от параллельных запросов.
32
+ * Если рефреш уже выполняется - возвращает существующий промис.
33
+ */
26
34
  private refreshingToken;
35
+ /**
36
+ * Непосредственно выполняет запрос на обновление токена
37
+ */
38
+ private executeRefresh;
39
+ /**
40
+ * Обработка ошибки авторизации - очистка токенов
41
+ */
42
+ private handleAuthError;
27
43
  get<T>(path: string): Promise<T | null>;
28
44
  post<T>(path: string, data: any): Promise<T | null>;
29
45
  private authFlow;
30
46
  configure(settings: ShadowIntegrationSettings): void;
31
47
  subscribe(props: RequestQueue): void;
32
- processRequestQueue(): void;
48
+ processRequestQueue(): Promise<void>;
33
49
  }
34
50
  export declare const apiTransport: ApiTransport;
@@ -7,6 +7,10 @@ class ApiTransport {
7
7
  constructor() {
8
8
  this._accessToken = '';
9
9
  this._refreshToken = '';
10
+ this._isRefreshing = false;
11
+ this._refreshPromise = null;
12
+ this._isProcessingQueue = false;
13
+ this._inFlightRequests = new Set();
10
14
  this._baseUrl = '';
11
15
  this.baseHeaders = {
12
16
  'Content-Type': 'application/json',
@@ -19,7 +23,7 @@ class ApiTransport {
19
23
  this.accessToken = localStorage.getItem(constants_1.ACCESS_TOKEN_KEY) || '';
20
24
  this.refreshToken = localStorage.getItem(constants_1.REFRESH_TOKEN_KEY) || '';
21
25
  this._isConfigured = false;
22
- this._requestQueue = [];
26
+ this._requestQueue = new Map();
23
27
  this._meInfo = null;
24
28
  }
25
29
  set meInfo(meInfo) {
@@ -77,18 +81,65 @@ class ApiTransport {
77
81
  }
78
82
  this.meInfo = res;
79
83
  }
84
+ /**
85
+ * Выполняет рефреш токена с защитой от параллельных запросов.
86
+ * Если рефреш уже выполняется - возвращает существующий промис.
87
+ */
80
88
  async refreshingToken() {
81
- // eslint-disable-next-line no-debugger
82
- debugger;
83
- const response = await this.post(types_1.ETransportPath.RefreshToken, {
84
- refreshToken: this.refreshToken,
85
- });
86
- if (!response) {
89
+ // Если рефреш уже идёт - ждём его результат
90
+ if (this._isRefreshing && this._refreshPromise) {
91
+ return this._refreshPromise;
92
+ }
93
+ this._isRefreshing = true;
94
+ this._refreshPromise = this.executeRefresh();
95
+ try {
96
+ return await this._refreshPromise;
97
+ }
98
+ finally {
99
+ this._isRefreshing = false;
100
+ this._refreshPromise = null;
101
+ }
102
+ }
103
+ /**
104
+ * Непосредственно выполняет запрос на обновление токена
105
+ */
106
+ async executeRefresh() {
107
+ try {
108
+ const response = await fetch(`${this.baseUrl}${types_1.ETransportPath.RefreshToken}`, {
109
+ method: 'POST',
110
+ body: JSON.stringify({ refreshToken: this.refreshToken }),
111
+ headers: {
112
+ 'Content-Type': 'application/json',
113
+ 'x-brand-prefix': this.baseHeaders['x-brand-prefix'],
114
+ 'x-forwarded-host': this.baseHeaders['x-forwarded-host'],
115
+ },
116
+ });
117
+ if (!response.ok) {
118
+ this.handleAuthError();
119
+ return false;
120
+ }
121
+ const data = await response.json();
122
+ this.accessToken = data.accessToken;
123
+ this.refreshToken = data.refreshToken;
124
+ return true;
125
+ }
126
+ catch (error) {
127
+ console.error('Refresh token error:', error);
128
+ this.handleAuthError();
87
129
  return false;
88
130
  }
89
- this.accessToken = response.accessToken;
90
- this.refreshToken = response.refreshToken;
91
- return true;
131
+ }
132
+ /**
133
+ * Обработка ошибки авторизации - очистка токенов
134
+ */
135
+ handleAuthError() {
136
+ this._accessToken = '';
137
+ this._refreshToken = '';
138
+ this.baseHeaders.Authorization = '';
139
+ this.baseHeaders['x-refresh-token'] = '';
140
+ localStorage.removeItem(constants_1.ACCESS_TOKEN_KEY);
141
+ localStorage.removeItem(constants_1.REFRESH_TOKEN_KEY);
142
+ this._meInfo = null;
92
143
  }
93
144
  async get(path) {
94
145
  try {
@@ -97,10 +148,11 @@ class ApiTransport {
97
148
  headers: Object.assign(Object.assign({}, this.baseHeaders), { 'Content-Type': 'application/json' }),
98
149
  });
99
150
  if (response.status === 401) {
100
- const responseRefresh = this.refreshingToken();
101
- if (!responseRefresh) {
151
+ const refreshSuccess = await this.refreshingToken();
152
+ if (!refreshSuccess) {
102
153
  return null;
103
154
  }
155
+ // Повторяем запрос с новым токеном
104
156
  return this.get(path);
105
157
  }
106
158
  if (!response.ok) {
@@ -114,12 +166,25 @@ class ApiTransport {
114
166
  }
115
167
  }
116
168
  async post(path, data) {
169
+ // Не применяем рефреш для auth эндпоинтов
170
+ const isAuthPath = path === types_1.ETransportPath.SignIn ||
171
+ path === types_1.ETransportPath.SignUp ||
172
+ path === types_1.ETransportPath.RefreshToken ||
173
+ path === types_1.ETransportPath.TokenSignIn;
117
174
  try {
118
- const response = await fetch(`${this._baseUrl}${path}`, {
175
+ const response = await fetch(`${this.baseUrl}${path}`, {
119
176
  method: 'POST',
120
177
  body: JSON.stringify(data),
121
178
  headers: Object.assign(Object.assign({}, this.baseHeaders), { 'Content-Type': 'application/json' }),
122
179
  });
180
+ if (response.status === 401 && !isAuthPath) {
181
+ const refreshSuccess = await this.refreshingToken();
182
+ if (!refreshSuccess) {
183
+ return null;
184
+ }
185
+ // Повторяем запрос с новым токеном
186
+ return this.post(path, data);
187
+ }
123
188
  if (!response.ok) {
124
189
  return null;
125
190
  }
@@ -146,17 +211,42 @@ class ApiTransport {
146
211
  this.baseUrl = settings.baseUrl;
147
212
  }
148
213
  subscribe(props) {
149
- this.requestQueue.push(props);
214
+ const key = props.uid;
215
+ // Пропускаем дубликат: проверяем и очередь, и "в полёте"
216
+ if (this._requestQueue.has(key) || this._inFlightRequests.has(key)) {
217
+ return;
218
+ }
219
+ this._requestQueue.set(key, props);
150
220
  this.processRequestQueue();
151
221
  }
152
- processRequestQueue() {
153
- if (!this.isConfigured) {
222
+ async processRequestQueue() {
223
+ if (!this.isConfigured || this._isProcessingQueue) {
224
+ return;
225
+ }
226
+ if (this._requestQueue.size === 0) {
154
227
  return;
155
228
  }
156
- this.requestQueue.forEach((request) => {
157
- request.fn(request.fnProps);
158
- });
159
- this.requestQueue = [];
229
+ this._isProcessingQueue = true;
230
+ // Забираем текущую очередь
231
+ const requests = Array.from(this._requestQueue.entries());
232
+ // Переносим ключи в "в полёте" и очищаем очередь
233
+ requests.forEach(([key]) => this._inFlightRequests.add(key));
234
+ this._requestQueue = new Map();
235
+ // Выполняем все запросы параллельно
236
+ await Promise.all(requests.map(async ([key, request]) => {
237
+ try {
238
+ await request.fn(request.fnProps);
239
+ }
240
+ finally {
241
+ // Удаляем из "в полёте" после завершения
242
+ this._inFlightRequests.delete(key);
243
+ }
244
+ }));
245
+ this._isProcessingQueue = false;
246
+ // Проверяем, не накопились ли новые запросы
247
+ if (this._requestQueue.size > 0) {
248
+ this.processRequestQueue();
249
+ }
160
250
  }
161
251
  }
162
252
  exports.ApiTransport = ApiTransport;
@@ -8,10 +8,13 @@ export declare enum ETransportPath {
8
8
  HomeBanners = "/casino/banners",
9
9
  Categories = "/casino/categories",
10
10
  Currencies = "/casino/currencies",
11
+ GamesByCategory = "/casino/categories/games",
11
12
  SignUp = "/auth/sign-up",
12
13
  SignIn = "/auth/sign-in/client",
13
14
  TokenSignIn = "/auth/sign-in/token",
14
- RefreshToken = "/auth/sign-in/refresh-token"
15
+ RefreshToken = "/auth/sign-in/refresh-token",
16
+ RecoveryPassword = "/recovery-password/email",
17
+ SubmitCode = "/recovery-password/set-new-password"
15
18
  }
16
19
  export type SignInResponse = {
17
20
  accessToken: string;
@@ -6,8 +6,11 @@ var ETransportPath;
6
6
  ETransportPath["HomeBanners"] = "/casino/banners";
7
7
  ETransportPath["Categories"] = "/casino/categories";
8
8
  ETransportPath["Currencies"] = "/casino/currencies";
9
+ ETransportPath["GamesByCategory"] = "/casino/categories/games";
9
10
  ETransportPath["SignUp"] = "/auth/sign-up";
10
11
  ETransportPath["SignIn"] = "/auth/sign-in/client";
11
12
  ETransportPath["TokenSignIn"] = "/auth/sign-in/token";
12
13
  ETransportPath["RefreshToken"] = "/auth/sign-in/refresh-token";
14
+ ETransportPath["RecoveryPassword"] = "/recovery-password/email";
15
+ ETransportPath["SubmitCode"] = "/recovery-password/set-new-password";
13
16
  })(ETransportPath || (exports.ETransportPath = ETransportPath = {}));
@@ -194,6 +194,10 @@ export declare enum PaymentChannelType {
194
194
  PayinGrabpayMYR = 101,
195
195
  Rocket = 103,
196
196
  PayinDuitNowMYR = 104,
197
+ BetterBroBkash = 106,
198
+ BetterBroNagad = 107,
199
+ BetterBroEasypaisa = 108,
200
+ BetterBroJazzCash = 109,
197
201
  PayinOnlineBankingMYR = 105,
198
202
  BkashMonetics = 126,
199
203
  NagadMonetics = 127,
@@ -86,6 +86,10 @@ var PaymentChannelType;
86
86
  // - Mpay end ( not full )
87
87
  PaymentChannelType[PaymentChannelType["Rocket"] = 103] = "Rocket";
88
88
  PaymentChannelType[PaymentChannelType["PayinDuitNowMYR"] = 104] = "PayinDuitNowMYR";
89
+ PaymentChannelType[PaymentChannelType["BetterBroBkash"] = 106] = "BetterBroBkash";
90
+ PaymentChannelType[PaymentChannelType["BetterBroNagad"] = 107] = "BetterBroNagad";
91
+ PaymentChannelType[PaymentChannelType["BetterBroEasypaisa"] = 108] = "BetterBroEasypaisa";
92
+ PaymentChannelType[PaymentChannelType["BetterBroJazzCash"] = 109] = "BetterBroJazzCash";
89
93
  PaymentChannelType[PaymentChannelType["PayinOnlineBankingMYR"] = 105] = "PayinOnlineBankingMYR";
90
94
  PaymentChannelType[PaymentChannelType["BkashMonetics"] = 126] = "BkashMonetics";
91
95
  PaymentChannelType[PaymentChannelType["NagadMonetics"] = 127] = "NagadMonetics";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-memory-optimization",
3
- "version": "0.0.119",
3
+ "version": "0.0.121",
4
4
  "description": "react memory optimization library",
5
5
  "sideEffects": false,
6
6
  "files": [