react-native-mosquito-transport 0.0.21 → 0.0.23

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.
@@ -1,7 +1,7 @@
1
1
  import { guardArray, GuardError, guardObject, GuardSignal, niceGuard, Validator } from "guard-object";
2
2
  import { sameInstance } from "../../helpers/peripherals";
3
3
  import { RETRIEVAL } from "../../helpers/values";
4
- import getLodash from 'lodash.get';
4
+ import getLodash from 'lodash/get';
5
5
  import { Binary, BSONRegExp, BSONSymbol, Code, DBRef, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp, UUID } from 'bson';
6
6
  import { bboxPolygon, booleanIntersects, booleanWithin, circle, distance, polygon } from "@turf/turf";
7
7
 
@@ -0,0 +1,77 @@
1
+ import { updateCacheStore } from "../../helpers/utils";
2
+ import { CacheStore, Scoped } from "../../helpers/variables";
3
+ import cloneDeep from "lodash/cloneDeep";
4
+ import { serialize } from "entity-serializer";
5
+ import { SQLITE_COMMANDS, SQLITE_PATH, useSqliteLinearAccessId } from "../../helpers/sqlite_manager";
6
+ import { incrementFetcherSize } from "./counter";
7
+ import { getStoreID, handleBigData, parseBigData } from "../../helpers/fs_manager";
8
+
9
+ const { FETCH_RESOURCES } = SQLITE_PATH;
10
+
11
+ export const insertFetchResources = async (projectUrl, access_id, value) => {
12
+ value = cloneDeep(value);
13
+ const dataSize = serialize(value).byteLength;
14
+
15
+ const { io } = Scoped.ReleaseCacheData;
16
+ if (io) {
17
+ if (!CacheStore.FetchedStore[projectUrl])
18
+ CacheStore.FetchedStore[projectUrl] = {};
19
+ const b4 = CacheStore.FetchedStore[projectUrl][access_id];
20
+ incrementFetcherSize(projectUrl, dataSize - (b4?.size || 0));
21
+ CacheStore.FetchedStore[projectUrl][access_id] = {
22
+ touched: Date.now(),
23
+ data: value,
24
+ size: dataSize
25
+ };
26
+ } else {
27
+ const initNode = projectUrl;
28
+
29
+ await useSqliteLinearAccessId(FETCH_RESOURCES(projectUrl), access_id, 'httpFetch')(async (sqlite, db_filename) => {
30
+ if (!Scoped.initedSqliteInstances.httpFetch[initNode]) {
31
+ Scoped.initedSqliteInstances.httpFetch[initNode] = (async () => {
32
+ await sqlite.executeSql(`CREATE TABLE IF NOT EXISTS main ( access_id TEXT PRIMARY KEY, value BLOB, touched INTEGER, size INTEGER )`).catch(() => null);
33
+ await Promise.allSettled([
34
+ sqlite.executeSql(SQLITE_COMMANDS.CREATE_INDEX('main', ['access_id'])),
35
+ sqlite.executeSql(SQLITE_COMMANDS.CREATE_INDEX('main', ['touched']))
36
+ ]);
37
+ })();
38
+ }
39
+
40
+ await Scoped.initedSqliteInstances.httpFetch[initNode];
41
+ const b4Data = await sqlite.executeSql(`SELECT access_id, size FROM main WHERE access_id = ?`, [access_id]).then(r =>
42
+ r[0].rows.item(0)
43
+ );
44
+ const blobData = await handleBigData(getStoreID(db_filename, 'main', access_id), value);
45
+
46
+ await sqlite.executeSql(
47
+ SQLITE_COMMANDS.MERGE('main', ['access_id', 'value', 'touched', 'size']),
48
+ [access_id, blobData, Date.now(), dataSize]
49
+ );
50
+ incrementFetcherSize(projectUrl, dataSize - (b4Data?.size || 0));
51
+ });
52
+ }
53
+
54
+ updateCacheStore(undefined, ['FetchedStore']);
55
+ }
56
+
57
+ export const getFetchResources = async (projectUrl, access_id) => {
58
+ const { io } = Scoped.ReleaseCacheData;
59
+
60
+ if (io) {
61
+ const record = CacheStore.FetchedStore[projectUrl]?.[access_id];
62
+ if (record) record.touched = Date.now();
63
+ return record && cloneDeep(record?.data);
64
+ }
65
+
66
+ const res = await useSqliteLinearAccessId(FETCH_RESOURCES(projectUrl), access_id, 'httpFetch')(async sqlite => {
67
+ const query = await sqlite.executeSql('SELECT * FROM main WHERE access_id = ?', [access_id]).catch(() => null);
68
+
69
+ const rawData = query && query[0].rows.item(0).value;
70
+ if (!rawData) return null;
71
+
72
+ const data = await parseBigData(rawData);
73
+ await sqlite.executeSql(SQLITE_COMMANDS.UPDATE_COLUMNS('main', ['touched'], 'access_id = ?'), [Date.now(), access_id]);
74
+ return data;
75
+ });
76
+ return res;
77
+ }
@@ -0,0 +1,11 @@
1
+ import { CacheStore } from "../../helpers/variables";
2
+ import getLodash from 'lodash/get';
3
+ import setLodash from 'lodash/set';
4
+
5
+ export const incrementFetcherSize = (projectUrl, size = 0) => incrementFetcherSizeCore(CacheStore.DatabaseStats, projectUrl, size);
6
+
7
+ export const incrementFetcherSizeCore = (baseObj, projectUrl, size = 0) => {
8
+ baseObj._fetcher_size += size;
9
+ const b4 = getLodash(baseObj.fetchers, [projectUrl], 0);
10
+ setLodash(baseObj.fetchers, [projectUrl], b4 + size);
11
+ }
@@ -1,15 +1,16 @@
1
1
  import { Buffer } from "buffer";
2
2
  import { deserializeE2E, listenReachableServer, niceHash, normalizeRoute, serializeE2E } from "../../helpers/peripherals";
3
- import { awaitStore, getReachableServer, updateCacheStore } from "../../helpers/utils";
3
+ import { awaitStore, getReachableServer } from "../../helpers/utils";
4
4
  import { RETRIEVAL } from "../../helpers/values";
5
- import { CacheStore, Scoped } from "../../helpers/variables";
5
+ import { Scoped } from "../../helpers/variables";
6
6
  import { awaitRefreshToken } from "../auth/accessor";
7
7
  import { simplifyCaughtError } from "simplify-error";
8
8
  import { guardObject, Validator } from "guard-object";
9
- import cloneDeep from "lodash.clonedeep";
9
+ import cloneDeep from "lodash/cloneDeep";
10
10
  import { serialize } from "entity-serializer";
11
+ import { getFetchResources, insertFetchResources } from "./accessor";
11
12
 
12
- const buildFetchData = (data) => {
13
+ const buildFetchData = (data, extras) => {
13
14
  const { ok, type, status, statusText, redirected, url, headers, size, base64 } = data;
14
15
 
15
16
  const response = new Response(Buffer.from(base64, 'base64'), {
@@ -20,7 +21,7 @@ const buildFetchData = (data) => {
20
21
  size
21
22
  });
22
23
 
23
- Object.entries({ ok, type, url, redirected, size })
24
+ Object.entries({ ok, type, url, redirected, size, ...extras })
24
25
  .forEach(([k, v]) => {
25
26
  if (response[k] !== v)
26
27
  Object.defineProperty(response, k, {
@@ -33,7 +34,7 @@ const buildFetchData = (data) => {
33
34
  }
34
35
 
35
36
  export const mfetch = async (input = '', init, config) => {
36
- const { projectUrl, serverE2E_PublicKey, method, maxRetries = 7, disableCache, accessKey, uglify, extraHeaders } = config;
37
+ const { projectUrl, serverE2E_PublicKey, method, maxRetries = 1, disableCache = false, uglify, extraHeaders } = config;
37
38
  const { headers, body } = init || {};
38
39
 
39
40
  if (method !== undefined)
@@ -45,24 +46,22 @@ export const mfetch = async (input = '', init, config) => {
45
46
  }).validate(method);
46
47
 
47
48
  const { retrieval = RETRIEVAL.DEFAULT, enableMinimizer, rawApproach } = method || {};
48
- const isBaseUrl = Validator.LINK(input);
49
+ const isLink = Validator.LINK(input);
50
+ const isBaseUrl = isLink || rawApproach;
49
51
  const disableAuth = method?.disableAuth || isBaseUrl;
50
- const shouldCache = (retrieval !== RETRIEVAL.DEFAULT || !disableCache) &&
51
- retrieval !== RETRIEVAL.NO_CACHE_NO_AWAIT;
52
+ const hasBody = body !== undefined;
53
+ const shouldCache = (retrieval !== RETRIEVAL.DEFAULT || (config.disableCache === undefined ? !hasBody : !disableCache)) &&
54
+ ![RETRIEVAL.NO_CACHE_NO_AWAIT, RETRIEVAL.NO_CACHE_AWAIT].includes(retrieval);
52
55
  const uglified = !!(!isBaseUrl && uglify);
53
56
 
54
57
  const rawHeader = Object.fromEntries(
55
58
  [...new Headers(headers).entries()]
56
59
  );
57
60
 
58
- if ('mtoken' in rawHeader)
59
- throw '"mtoken" in header is a reserved prop';
60
-
61
- if ('uglified' in rawHeader)
62
- throw '"uglified" in header is a reserved prop';
63
-
64
- // if (isBaseUrl && !rawApproach)
65
- // throw `please set { rawApproach: true } if you're trying to access different endpoint at "${input}"`;
61
+ ['mtoken', 'uglified'].forEach(e => {
62
+ if ([e] in rawHeader)
63
+ throw `"${e}" in header is a reserved prop`;
64
+ });
66
65
 
67
66
  if (body !== undefined) {
68
67
  if (
@@ -80,6 +79,7 @@ export const mfetch = async (input = '', init, config) => {
80
79
  input
81
80
  ]).toString('base64')
82
81
  );
82
+ const processReqId = `${reqId}_${disableCache}_${retrieval}`;
83
83
 
84
84
  let retries = 0, hasFinalize;
85
85
 
@@ -93,44 +93,41 @@ export const mfetch = async (input = '', init, config) => {
93
93
  hasFinalize = true;
94
94
 
95
95
  if (enableMinimizer) {
96
- (Scoped.PendingFetchCollective.pendingResolution[reqId] || []).forEach(e => {
96
+ const resolutionList = (Scoped.PendingFetchCollective[processReqId] || []).slice(0);
97
+
98
+ if (Scoped.PendingFetchCollective[processReqId])
99
+ delete Scoped.PendingFetchCollective[processReqId];
100
+
101
+ resolutionList.forEach(e => {
97
102
  e(a, b);
98
103
  });
99
- if (Scoped.PendingFetchCollective.pendingResolution[reqId])
100
- delete Scoped.PendingFetchCollective.pendingResolution[reqId];
101
-
102
- if (Scoped.PendingFetchCollective.pendingProcess[reqId])
103
- delete Scoped.PendingFetchCollective.pendingProcess[reqId];
104
104
  }
105
105
  };
106
106
 
107
107
  await awaitStore();
108
- const reqData = CacheStore.FetchedStore[projectUrl]?.[reqId];
109
- const resolveCache = () => {
110
- finalize({
111
- ...buildFetchData(reqData),
112
- fromCache: true
113
- });
108
+ const resolveCache = (reqData) => {
109
+ finalize(buildFetchData(reqData), { fromCache: true });
114
110
  };
115
111
 
116
112
  try {
117
113
  if (retryProcess === 1) {
118
114
  if (enableMinimizer) {
119
- if (Scoped.PendingFetchCollective.pendingProcess[reqId]) {
120
- if (!Scoped.PendingFetchCollective.pendingResolution[reqId])
121
- Scoped.PendingFetchCollective.pendingResolution[reqId] = [];
122
-
123
- Scoped.PendingFetchCollective.pendingResolution[reqId].push((a, b) => {
115
+ if (Scoped.PendingFetchCollective[processReqId]) {
116
+ Scoped.PendingFetchCollective[processReqId].push((a, b) => {
124
117
  if (a) resolve(cloneDeep(a.result));
125
118
  else reject(cloneDeep(b));
126
119
  });
127
120
  return;
128
121
  }
129
- Scoped.PendingFetchCollective.pendingProcess[reqId] = true;
122
+ Scoped.PendingFetchCollective[processReqId] = [];
130
123
  }
131
124
 
132
- if (retrieval.startsWith('sticky') && reqData) {
133
- resolveCache();
125
+ let reqData;
126
+ if (
127
+ retrieval.startsWith('sticky') &&
128
+ (reqData = await getFetchResources(projectUrl, reqId))
129
+ ) {
130
+ resolveCache(reqData);
134
131
  if (retrieval !== RETRIEVAL.STICKY_RELOAD) return;
135
132
  }
136
133
  }
@@ -140,25 +137,26 @@ export const mfetch = async (input = '', init, config) => {
140
137
 
141
138
  const mtoken = Scoped.AuthJWTToken[projectUrl];
142
139
  const initType = rawHeader['content-type'];
140
+ const encodeBody = initType === undefined && hasBody && !isBaseUrl;
143
141
 
144
142
  const [reqBuilder, [privateKey]] = uglified ? await serializeE2E(body, mtoken, serverE2E_PublicKey) : [null, []];
145
143
 
146
- const f = await fetch(isBaseUrl ? input : `${projectUrl}/${normalizeRoute(input)}`, {
147
- ...isBaseUrl ? {} : { method: 'POST' },
144
+ const f = await fetch(isLink ? input : `${projectUrl}/${normalizeRoute(input)}`, {
145
+ ...(!isBaseUrl || hasBody) ? { method: 'POST' } : {},
148
146
  ...init,
149
- ...uglified ? { body: reqBuilder } : {},
150
- cache: 'no-cache',
147
+ ...uglified ? { body: reqBuilder } : encodeBody ? { body: serialize(body) } : {},
148
+ // cache: 'no-cache',
151
149
  headers: {
152
150
  ...extraHeaders,
153
- ...isBaseUrl ? {} : { 'content-type': 'application/json' },
154
151
  ...rawHeader,
155
152
  ...uglified ? {
156
153
  uglified,
157
154
  'content-type': 'request/buffer',
158
155
  ...initType ? { 'init-content-type': initType } : {}
159
- } : {},
160
- ...(disableAuth || !mtoken || uglified || isBaseUrl) ? {} : { mtoken },
161
- ...isBaseUrl ? {} : { authorization: `Bearer ${accessKey}` }
156
+ } : encodeBody
157
+ ? { 'content-type': 'request/buffer', 'entity-encoded': '1' }
158
+ : {},
159
+ ...(disableAuth || !mtoken || uglified || isBaseUrl) ? {} : { mtoken }
162
160
  }
163
161
  });
164
162
  const { ok, type, status, statusText, redirected, url, headers, size } = f;
@@ -184,46 +182,42 @@ export const mfetch = async (input = '', init, config) => {
184
182
  )
185
183
  };
186
184
 
187
- if (shouldCache) {
188
- if (!CacheStore.FetchedStore[projectUrl])
189
- CacheStore.FetchedStore[projectUrl] = {};
190
- CacheStore.FetchedStore[projectUrl][reqId] = cloneDeep(resObj);
191
- updateCacheStore();
192
- }
185
+ if (shouldCache) insertFetchResources(projectUrl, reqId, resObj);
193
186
 
194
187
  finalize(buildFetchData(resObj));
195
188
  } catch (e) {
189
+ let thisRecord;
190
+
191
+ const getThisRecord = async () => thisRecord ? thisRecord[0]
192
+ : (thisRecord = [await getFetchResources(projectUrl, reqId)])[0];
193
+
196
194
  if (e?.simpleError) {
197
195
  finalize(undefined, e.simpleError);
198
196
  } else if (
199
- (retrieval === RETRIEVAL.CACHE_NO_AWAIT && !reqData) ||
197
+ (retrieval === RETRIEVAL.CACHE_NO_AWAIT && !(await getThisRecord())) ||
200
198
  retrieval === RETRIEVAL.STICKY_NO_AWAIT ||
201
199
  retrieval === RETRIEVAL.NO_CACHE_NO_AWAIT
202
200
  ) {
203
201
  finalize(undefined, simplifyCaughtError(e).simpleError);
204
202
  } else if (
205
203
  shouldCache &&
206
- (retrieval === RETRIEVAL.DEFAULT || retrieval === RETRIEVAL.CACHE_NO_AWAIT) &&
207
- reqData
204
+ [
205
+ RETRIEVAL.DEFAULT,
206
+ RETRIEVAL.CACHE_NO_AWAIT,
207
+ RETRIEVAL.CACHE_AWAIT
208
+ ].includes(retrieval) &&
209
+ await getThisRecord()
208
210
  ) {
209
- resolveCache();
210
- } else if (retries >= maxRetries) {
211
+ resolveCache(await getThisRecord());
212
+ } else if (retries > maxRetries) {
211
213
  finalize(undefined, simplifyCaughtError(e).simpleError);
212
214
  } else {
213
215
  const listener = listenReachableServer(async online => {
214
216
  if (online) {
215
217
  listener();
216
218
  callFetch().then(
217
- e => {
218
- if (retryProcess === 1) {
219
- finalize(e);
220
- } else resolve(e);
221
- },
222
- e => {
223
- if (retryProcess === 1) {
224
- finalize(undefined, e);
225
- } else reject(e);
226
- }
219
+ e => finalize(e),
220
+ e => finalize(undefined, e)
227
221
  );
228
222
  }
229
223
  }, projectUrl);
@@ -231,5 +225,5 @@ export const mfetch = async (input = '', init, config) => {
231
225
  }
232
226
  });
233
227
 
234
- return await callFetch();
228
+ return (await callFetch());
235
229
  };
@@ -1,8 +1,8 @@
1
1
  import EngineApi from "../../helpers/engine_api";
2
- import { encodeBinary, prefixStoragePath } from "../../helpers/peripherals";
2
+ import { deserializeE2E, prefixStoragePath } from "../../helpers/peripherals";
3
3
  import { Scoped } from "../../helpers/variables";
4
4
  import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from 'react-native';
5
- import { awaitReachableServer, buildFetchInterface } from "../../helpers/utils";
5
+ import { awaitReachableServer, buildFetchInterface, buildFetchResult } from "../../helpers/utils";
6
6
  import { awaitRefreshToken } from "../auth/accessor";
7
7
  import { simplifyError } from "simplify-error";
8
8
 
@@ -31,7 +31,7 @@ export class MTStorage {
31
31
  const { awaitServer } = options || {};
32
32
  let hasFinished, isPaused, hasCancelled;
33
33
 
34
- const { projectUrl, accessKey, extraHeaders } = this.builder;
34
+ const { projectUrl, extraHeaders } = this.builder;
35
35
 
36
36
  if (destination && (typeof destination !== 'string' || !destination.trim())) {
37
37
  onComplete?.({ error: 'destination_invalid', message: 'destination must be a non-empty string' });
@@ -98,7 +98,6 @@ export class MTStorage {
98
98
  } : {},
99
99
  processID,
100
100
  urlName: link.split('/').pop(),
101
- authorization: `Bearer ${encodeBinary(accessKey)}`,
102
101
  extraHeaders: extraHeaders || {},
103
102
  });
104
103
  }
@@ -136,7 +135,7 @@ export class MTStorage {
136
135
 
137
136
  file = isAsset ? file.trim() : prefixStoragePath(file.trim());
138
137
 
139
- const { projectUrl, accessKey, uglify, extraHeaders } = this.builder;
138
+ const { projectUrl, uglify, extraHeaders } = this.builder;
140
139
  const processID = `${++Scoped.StorageProcessID}`;
141
140
 
142
141
  const init = async () => {
@@ -171,7 +170,6 @@ export class MTStorage {
171
170
  createHash: createHash ? 'yes' : 'no',
172
171
  destination,
173
172
  processID,
174
- authorization: `Bearer ${encodeBinary(accessKey)}`,
175
173
  extraHeaders: extraHeaders || {}
176
174
  });
177
175
  }
@@ -192,16 +190,25 @@ export class MTStorage {
192
190
  deleteFolder = (path) => deleteContent(this.builder, path, true);
193
191
  }
194
192
 
193
+ const { _deleteFile, _deleteFolder } = EngineApi;
194
+
195
195
  const deleteContent = async (builder, path, isFolder) => {
196
- const { projectUrl, accessKey, uglify } = builder;
196
+ const { projectUrl, uglify, extraHeaders, serverE2E_PublicKey } = builder;
197
197
 
198
198
  try {
199
- const r = await (await fetch(
200
- EngineApi[isFolder ? '_deleteFolder' : '_deleteFile'](projectUrl, uglify),
201
- await buildFetchInterface({ path }, accessKey, Scoped.AuthJWTToken[projectUrl], 'DELETE')
202
- )).json();
203
- if (r.simpleError) throw r;
204
- if (r.status !== 'success') throw 'operation not successful';
199
+ const [reqBuilder, [privateKey]] = await buildFetchInterface({
200
+ method: 'DELETE',
201
+ authToken: Scoped.AuthJWTToken[projectUrl],
202
+ body: { path },
203
+ extraHeaders,
204
+ serverE2E_PublicKey,
205
+ uglify
206
+ });
207
+
208
+ const data = await buildFetchResult(await fetch((isFolder ? _deleteFolder : _deleteFile)(projectUrl, uglify), reqBuilder), uglify);
209
+ const result = uglify ? await deserializeE2E(data, serverE2E_PublicKey, privateKey) : data;
210
+
211
+ if (result.status !== 'success') throw 'operation not successful';
205
212
  } catch (e) {
206
213
  if (e?.simpleError) throw e.simpleError;
207
214
  throw simplifyError('unexpected_error', `${e}`).simpleError;