react-native-mosquito-transport 0.0.54 → 0.0.56

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mosquito-transport",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "description": "React native javascript sdk for mosquito-transport (https://github.com/brainbehindx/mosquito-transport)",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -155,14 +155,27 @@ export const awaitStore = () => new Promise(resolve => {
155
155
  });
156
156
  });
157
157
 
158
- export const checkAreYouOk = (projectUrl) => {
159
- if (!Scoped.AreYouOkPromise[projectUrl]) {
158
+ export const checkAreYouOk = (projectUrl, refresh) => {
159
+ if (!Scoped.AreYouOkPromise[projectUrl] || refresh) {
160
+ Scoped.IS_CONNECTED[projectUrl] = undefined;
161
+ ServerReachableListener.dispatchPersist(projectUrl, undefined);
162
+
163
+ const thatState = AppState.currentState;
164
+
160
165
  const promise = fetch(engine_api._areYouOk(projectUrl), { credentials: 'omit' })
161
166
  .then(async r => (await r.json()).status === 'yes')
162
167
  .catch(() => false)
163
168
  .then(async connected => {
164
- Scoped.IS_CONNECTED[projectUrl] = connected;
165
- ServerReachableListener.dispatchPersist(projectUrl, connected);
169
+ const thatPromise = Scoped.AreYouOkPromise[projectUrl];
170
+ if (thatPromise !== promise) {
171
+ if (thatPromise) return thatPromise;
172
+ return Scoped.IS_CONNECTED[projectUrl];
173
+ }
174
+
175
+ if (thatState === AppState.currentState) {
176
+ Scoped.IS_CONNECTED[projectUrl] = connected;
177
+ ServerReachableListener.dispatchPersist(projectUrl, connected);
178
+ }
166
179
 
167
180
  delete Scoped.AreYouOkPromise[projectUrl];
168
181
  return connected;
@@ -177,30 +190,38 @@ export const checkAreYouOk = (projectUrl) => {
177
190
  export const listenReachableServer = (callback, projectUrl) => {
178
191
  let lastValue;
179
192
  return ServerReachableListener.listenToPersist(projectUrl, t => {
180
- if (typeof t === 'boolean' && t !== lastValue) callback?.(t);
181
- lastValue = t;
193
+ if (typeof t === 'boolean' && t !== lastValue) {
194
+ callback?.(t);
195
+ lastValue = t;
196
+ }
182
197
  });
183
198
  };
184
199
 
185
- export const awaitReachableServer = (projectUrl) =>
186
- new Promise(async resolve => {
187
- if (AppState.currentState !== 'active') {
188
- if (await checkAreYouOk(projectUrl)) {
200
+ export const awaitReachableServer = (projectUrl, pauseForRetry) =>
201
+ new Promise(resolve => {
202
+ const check = async () => {
203
+ if (AppState.currentState !== 'active') {
204
+ if (await checkAreYouOk(projectUrl)) {
205
+ resolve();
206
+ return;
207
+ }
208
+ }
209
+
210
+ if (Scoped.IS_CONNECTED[projectUrl]) {
189
211
  resolve();
190
212
  return;
191
213
  }
192
- }
193
214
 
194
- if (Scoped.IS_CONNECTED[projectUrl]) {
195
- resolve();
196
- return;
215
+ const l = listenReachableServer(t => {
216
+ if (!t) return;
217
+ resolve();
218
+ l();
219
+ }, projectUrl);
197
220
  }
198
221
 
199
- const l = listenReachableServer(t => {
200
- if (!t) return;
201
- resolve();
202
- l();
203
- }, projectUrl);
222
+ if (pauseForRetry) {
223
+ setTimeout(check, Number.isInteger(pauseForRetry) ? pauseForRetry : 500);
224
+ } else check();
204
225
  });
205
226
 
206
227
  export const getReachableServer = (projectUrl) =>
package/src/index.d.ts CHANGED
@@ -297,6 +297,14 @@ export interface FetchHttpConfig {
297
297
  disableAuth?: boolean;
298
298
  enableMinimizer?: boolean;
299
299
  rawApproach?: boolean;
300
+ /**
301
+ * Wait for the server to come online if the response does not include a header with status 200.
302
+ *
303
+ * This ensures that the fetchHttp method only resolves when a response with status 200 is received; otherwise, it rejects if the server is online but continues returning a non-200 status
304
+ *
305
+ * @default false
306
+ */
307
+ enforce200?: boolean;
300
308
  }
301
309
 
302
310
  type Delievery = 'default' | 'cache-no-await' | 'no-cache-no-await' | 'no-cache-await';
package/src/index.js CHANGED
@@ -89,10 +89,10 @@ class RNMT {
89
89
  });
90
90
  };
91
91
 
92
- const manualCheckConnection = () => {
92
+ const manualCheckConnection = (refresh) => {
93
93
  const ref = ++connectionIte;
94
94
 
95
- checkAreYouOk(projectUrl).then(ok => {
95
+ checkAreYouOk(projectUrl, refresh).then(ok => {
96
96
  if (ref !== connectionIte) return;
97
97
  if (ok) {
98
98
  onConnect();
@@ -111,11 +111,11 @@ class RNMT {
111
111
 
112
112
  socket.on('connect', onConnect);
113
113
  socket.on('disconnect', () => {
114
- manualCheckConnection();
114
+ manualCheckConnection(true);
115
115
  });
116
116
 
117
117
  AppState.addEventListener('change', s => {
118
- manualCheckConnection();
118
+ if (s === 'active') manualCheckConnection();
119
119
  });
120
120
 
121
121
  const updateMountedToken = () => {
@@ -342,9 +342,7 @@ class RNMT {
342
342
  }
343
343
 
344
344
  if (AppState.currentState === 'active') {
345
- setTimeout(() => {
346
- awaitReachableServer(projectUrl).then(reloadIntance);
347
- }, timeout);
345
+ awaitReachableServer(projectUrl, timeout).then(reloadIntance);
348
346
  } else {
349
347
  foregroundListener = AppState.addEventListener('change', s => {
350
348
  if (s === 'active') {
@@ -375,7 +373,7 @@ class RNMT {
375
373
  clearSocket();
376
374
  if (r === 'io client disconnect' || r === 'io server disconnect') {
377
375
  resultant.destroy();
378
- } else reconnect(0);
376
+ } else reconnect(true);
379
377
  });
380
378
 
381
379
  clientPrivateKey = privateKey;
@@ -168,7 +168,7 @@ export const getEmulatedLinks = (projectUrl) =>
168
168
  .filter(([_, v]) => v === projectUrl)
169
169
  .map(v => v[0]);
170
170
 
171
- const refreshToken = (builder, remainRetries = 1, isForceRefresh) =>
171
+ const refreshToken = (builder, remainRetries = 3) =>
172
172
  new Promise(async (resolve, reject) => {
173
173
  const { projectUrl, serverE2E_PublicKey, uglify, extraHeaders } = builder;
174
174
 
@@ -206,7 +206,7 @@ const refreshToken = (builder, remainRetries = 1, isForceRefresh) =>
206
206
  Scoped.AuthJWTToken[v] = f.result.token;
207
207
 
208
208
  triggerAuthToken(v, isInit);
209
- if (isForceRefresh) Scoped.InitiatedForcedToken[v] = true;
209
+ if (isInit) Scoped.InitiatedForcedToken[v] = true;
210
210
  });
211
211
  updateCacheStore(['AuthStore']);
212
212
  initTokenRefresher({ config: builder });
@@ -221,8 +221,8 @@ const refreshToken = (builder, remainRetries = 1, isForceRefresh) =>
221
221
  );
222
222
  console.error(`refreshToken retry limit exceeded err:`, e);
223
223
  } else {
224
- awaitReachableServer(projectUrl).then(() => {
225
- refreshToken(builder, remainRetries - 1, isForceRefresh).then(resolve, reject);
224
+ awaitReachableServer(projectUrl, true).then(() => {
225
+ refreshToken(builder, remainRetries - 1).then(resolve, reject);
226
226
  });
227
227
  }
228
228
  }
@@ -262,9 +262,7 @@ const listenDocument = (callback, onError, builder, config) => {
262
262
  }
263
263
 
264
264
  if (AppState.currentState === 'active') {
265
- setTimeout(() => {
266
- awaitReachableServer(projectUrl).then(reloadIntance);
267
- }, timeout);
265
+ awaitReachableServer(projectUrl, timeout).then(reloadIntance);
268
266
  } else {
269
267
  foregroundListener = AppState.addEventListener('change', s => {
270
268
  if (s === 'active') {
@@ -289,7 +287,7 @@ const listenDocument = (callback, onError, builder, config) => {
289
287
  clearSocket();
290
288
  if (r === 'io client disconnect' || r === 'io server disconnect') {
291
289
  canceller();
292
- } else reconnect(0);
290
+ } else reconnect(true);
293
291
  });
294
292
  };
295
293
 
@@ -420,9 +418,7 @@ const initOnDisconnectionTask = ({ builder, connectData, disconnectData }) => {
420
418
  }
421
419
 
422
420
  if (AppState.currentState === 'active') {
423
- setTimeout(() => {
424
- awaitReachableServer(projectUrl).then(reloadIntance);
425
- }, timeout);
421
+ awaitReachableServer(projectUrl, timeout).then(reloadIntance);
426
422
  } else {
427
423
  foregroundListener = AppState.addEventListener('change', s => {
428
424
  if (s === 'active') {
@@ -447,7 +443,7 @@ const initOnDisconnectionTask = ({ builder, connectData, disconnectData }) => {
447
443
  clearSocket();
448
444
  if (r === 'io client disconnect' || r === 'io server disconnect') {
449
445
  canceller();
450
- } else reconnect(0);
446
+ } else reconnect(true);
451
447
  });
452
448
  };
453
449
 
@@ -558,7 +554,7 @@ const countCollection = async (builder, config) => {
558
554
  } else if (retries > maxRetries) {
559
555
  finalize(undefined, { error: 'retry_limit_exceeded', message: `retry exceed limit(${maxRetries})` });
560
556
  } else {
561
- awaitReachableServer(projectUrl).then(() => {
557
+ awaitReachableServer(projectUrl, true).then(() => {
562
558
  readValue().then(
563
559
  e => { finalize(e); },
564
560
  e => { finalize(undefined, e); }
@@ -732,7 +728,7 @@ const findObject = async (builder, initConfig) => {
732
728
  } else if (retries > maxRetries) {
733
729
  finalize(undefined, { error: 'retry_limit_exceeded', message: `retry exceed limit(${maxRetries})` });
734
730
  } else {
735
- awaitReachableServer(projectUrl).then(() => {
731
+ awaitReachableServer(projectUrl, true).then(() => {
736
732
  if (intruder) {
737
733
  intruder.resolve = undefined;
738
734
  intruder.reject = undefined;
@@ -878,7 +874,7 @@ const commitData = async (builder, value, type, config) => {
878
874
  );
879
875
  } else {
880
876
  if (delivery === DELIVERY.NO_CACHE_AWAIT) {
881
- awaitReachableServer(projectUrl).then(() => {
877
+ awaitReachableServer(projectUrl, true).then(() => {
882
878
  sendValue().then(
883
879
  e => { finalize(e.a, undefined, e.c); },
884
880
  e => { finalize(undefined, e.b, e.c); }
@@ -42,10 +42,11 @@ export const mfetch = async (input = '', init, config) => {
42
42
  enableMinimizer: t => t === undefined || Validator.BOOLEAN(t),
43
43
  rawApproach: t => t === undefined || Validator.BOOLEAN(t),
44
44
  disableAuth: t => t === undefined || Validator.BOOLEAN(t),
45
- retrieval: t => t === undefined || Object.values(RETRIEVAL).includes(t)
45
+ retrieval: t => t === undefined || Object.values(RETRIEVAL).includes(t),
46
+ enforce200: t => t === undefined || Validator.BOOLEAN(t)
46
47
  }).validate(method);
47
48
 
48
- const { retrieval = RETRIEVAL.DEFAULT, enableMinimizer, rawApproach } = method || {};
49
+ const { retrieval = RETRIEVAL.DEFAULT, enableMinimizer, rawApproach, enforce200 } = method || {};
49
50
  const isLink = Validator.LINK(input);
50
51
  const isBaseUrl = isLink || rawApproach;
51
52
  const disableAuth = method?.disableAuth === undefined ? isBaseUrl : method?.disableAuth;
@@ -163,6 +164,8 @@ export const mfetch = async (input = '', init, config) => {
163
164
  const { ok, type, status, statusText, redirected, url, headers, size } = f;
164
165
  const simple = headers.get('simple_error');
165
166
 
167
+ if (enforce200 && status !== 200)
168
+ throw `expected response status to be 200 but got ${status}`;
166
169
  if (!isLink && simple) throw { simpleError: JSON.parse(simple) };
167
170
 
168
171
  const buffer = uglified ?
@@ -215,7 +218,7 @@ export const mfetch = async (input = '', init, config) => {
215
218
  } else if (retries > maxRetries) {
216
219
  finalize(undefined, simplifyCaughtError(e).simpleError);
217
220
  } else {
218
- awaitReachableServer(projectUrl).then(() => {
221
+ awaitReachableServer(projectUrl, true).then(() => {
219
222
  callFetch().then(
220
223
  e => finalize(e),
221
224
  e => finalize(undefined, e)