react-native-mosquito-transport 0.0.34 → 0.0.36

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.34",
3
+ "version": "0.0.36",
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",
@@ -28,11 +28,11 @@
28
28
  "homepage": "https://github.com/brainbehindx/react-native-mosquito-transport#readme",
29
29
  "dependencies": {
30
30
  "@turf/turf": "^7.2.0",
31
- "bson": "^6.8.0",
32
31
  "buffer": "^6.0.3",
33
32
  "entity-serializer": "^1.0.3",
34
33
  "guard-object": "^1.1.4",
35
34
  "lodash": "^4.17.21",
35
+ "poke-object": "^1.0.1",
36
36
  "simplify-error": "^1.0.1",
37
37
  "socket.io-client": "^4.8.1",
38
38
  "subscription-listener": "^1.1.2",
@@ -44,4 +44,4 @@
44
44
  "react-native-get-random-values": "*",
45
45
  "react-native-sha256": "*"
46
46
  }
47
- }
47
+ }
@@ -1,6 +1,8 @@
1
+ import { deserialize, serialize } from "entity-serializer";
1
2
  import { Scoped } from "./variables";
2
3
  import { Platform } from "react-native";
3
4
  import { Dirs, FileSystem } from "react-native-file-access";
5
+ import { Buffer } from "buffer";
4
6
 
5
7
  const PARENT_FOLDER = `${Platform.OS === 'android' ? Dirs.DocumentDir.split('/').slice(0, -1).join('/') : Dirs.MainBundleDir}/mosquito_base`;
6
8
 
@@ -16,7 +18,7 @@ export const useFS = (builder, access_id, node) => async (task) => {
16
18
  const { projectUrl, dbUrl, dbName } = builder;
17
19
  const nodeId = typeof builder === 'string' ? `${builder}_${access_id}` : `${projectUrl}_${dbUrl}_${dbName}_${access_id}`;
18
20
 
19
- const thatProcess = Scoped.linearSqliteProcess[node][nodeId];
21
+ const thatProcess = Scoped.linearFsProcess[node][nodeId];
20
22
 
21
23
  const thisPromise = new Promise(async (resolve, reject) => {
22
24
  try {
@@ -28,12 +30,12 @@ export const useFS = (builder, access_id, node) => async (task) => {
28
30
  console.error('useFS err:', error, ' builder:', builder);
29
31
  reject(error);
30
32
  } finally {
31
- if (Scoped.linearSqliteProcess[node][nodeId] === thisPromise)
32
- delete Scoped.linearSqliteProcess[node][nodeId];
33
+ if (Scoped.linearFsProcess[node][nodeId] === thisPromise)
34
+ delete Scoped.linearFsProcess[node][nodeId];
33
35
  }
34
36
  });
35
37
 
36
- Scoped.linearSqliteProcess[node][nodeId] = thisPromise;
38
+ Scoped.linearFsProcess[node][nodeId] = thisPromise;
37
39
  return (await thisPromise);
38
40
  };
39
41
 
@@ -48,7 +50,7 @@ export const getSystem = (builder) => {
48
50
  const path = conjoin(table, primary_key);
49
51
  await FileSystem.mkdir(path).catch(() => null);
50
52
  await Promise.all(Object.entries(value).map(([k, v]) =>
51
- FileSystem.writeFile(joinPath(path, k), JSON.stringify(v), 'utf8')
53
+ FileSystem.writeFile(joinPath(path, k), serialize(v).toString('base64'), 'base64')
52
54
  ));
53
55
  },
54
56
  delete: (table, primary_key) => FileSystem.unlink(conjoin(table, primary_key)),
@@ -56,14 +58,14 @@ export const getSystem = (builder) => {
56
58
  const path = conjoin(table, primary_key);
57
59
 
58
60
  const value_map = await Promise.all(extractions.map(async node =>
59
- [node, JSON.parse(await FileSystem.readFile(joinPath(path, node)), 'utf8')]
61
+ [node, deserialize(Buffer.from(await FileSystem.readFile(joinPath(path, node), 'base64'), 'base64'))]
60
62
  ));
61
63
  return Object.fromEntries(value_map);
62
64
  },
63
65
  list: async (table, extractions) => {
64
66
  const names = await FileSystem.ls(conjoin(table));
65
67
  const list_data = await Promise.all(names.map(async primary_key => {
66
- const obj = await system.find(table, primary_key, extractions)
68
+ const obj = await getSystem(builder).find(table, primary_key, extractions)
67
69
  .catch(() => null);
68
70
  if (!obj) return;
69
71
  return [primary_key, obj];
@@ -1,10 +1,10 @@
1
1
  import { Buffer } from "buffer";
2
2
  import { ServerReachableListener } from "./listeners";
3
3
  import naclPkg from 'tweetnacl';
4
- import getLodash from "lodash/get";
5
4
  import { deserialize, serialize } from "entity-serializer";
6
5
  import { sha256 } from 'react-native-sha256';
7
6
  import { purifyFilepath } from "./fs_manager";
7
+ import { grab } from "poke-object";
8
8
 
9
9
  const { box, randomBytes } = naclPkg;
10
10
 
@@ -59,8 +59,8 @@ export const shuffleArray = (n) => {
59
59
 
60
60
  export function sortArrayByObjectKey(arr = [], key) {
61
61
  return arr.sort(function (a, b) {
62
- const left = getLodash(a, key),
63
- right = getLodash(b, key);
62
+ const left = grab(a, key),
63
+ right = grab(b, key);
64
64
 
65
65
  return (left > right) ? 1 : (left < right) ? -1 : 0;
66
66
  });
@@ -1,8 +1,8 @@
1
1
  import { Validator } from "guard-object";
2
2
  import { incrementDatabaseSizeCore } from "../products/database/counter";
3
3
  import { incrementFetcherSizeCore } from "../products/http_callable/counter";
4
- import unsetLodash from 'lodash/unset';
5
4
  import { FS_PATH, getSystem } from "./fs_manager";
5
+ import { unpoke } from "poke-object";
6
6
 
7
7
  const { LIMITER_DATA, LIMITER_RESULT, DB_COUNT_QUERY, FETCH_RESOURCES } = FS_PATH;
8
8
 
@@ -86,13 +86,13 @@ export const purgeRedundantRecords = async (data, builder) => {
86
86
  }) => {
87
87
  const { projectUrl, dbUrl, dbName } = builder;
88
88
  if (isCount) {
89
- unsetLodash(data.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id]);
89
+ unpoke(data.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id]);
90
90
  } else {
91
91
  incrementDatabaseSizeCore(data.DatabaseStats, builder, path, -size);
92
92
  if (isEpisode) {
93
- unsetLodash(data.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', access_id, limit]);
93
+ unpoke(data.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', access_id, `${limit}`]);
94
94
  } else {
95
- unsetLodash(data.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]);
95
+ unpoke(data.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]);
96
96
  }
97
97
  }
98
98
  });
@@ -122,7 +122,7 @@ export const purgeRedundantRecords = async (data, builder) => {
122
122
  console.warn(`purging ${cuts} of ${redundantFetchRanking.length} fetcher entities`);
123
123
  redundantFetchRanking.slice(0, cuts).forEach(({ access_id, data: { size }, projectUrl }) => {
124
124
  incrementFetcherSizeCore(data.DatabaseStats, projectUrl, -size);
125
- unsetLodash(data.FetchedStore, [projectUrl, access_id]);
125
+ unpoke(data.FetchedStore, [projectUrl, access_id]);
126
126
  });
127
127
  console.log('fetcher purging complete');
128
128
  }
@@ -245,7 +245,7 @@ export const purgeRedundantRecords = async (data, builder) => {
245
245
  }
246
246
  }
247
247
 
248
- const breakDbMap = (obj, callback) =>
248
+ export const breakDbMap = (obj = {}, callback) =>
249
249
  Object.entries(obj).forEach(([projectUrl, dbUrlObj]) => {
250
250
  Object.entries(dbUrlObj).forEach(([dbUrl, dbNameObj]) => {
251
251
  Object.entries(dbNameObj).forEach(([dbName, pathObj]) => {
@@ -1,16 +1,31 @@
1
1
  import { ServerReachableListener, StoreReadyListener } from "./listeners";
2
2
  import { CacheStore, Scoped } from "./variables";
3
3
  import { serializeE2E } from "./peripherals";
4
- import { deserializeBSON, serializeToBase64 } from "../products/database/bson";
5
- import { trySendPendingWrite } from "../products/database";
6
- import { deserialize } from "entity-serializer";
7
- import { purgeRedundantRecords } from "./purger";
4
+ import { DatastoreParser } from "../products/database/bson";
5
+ import { deserialize, serialize } from "entity-serializer";
6
+ import { breakDbMap, purgeRedundantRecords } from "./purger";
8
7
  import { FS_PATH, getSystem } from "./fs_manager";
8
+ import cloneDeep from "lodash/cloneDeep";
9
9
 
10
10
  const { FILE_NAME, TABLE_NAME } = FS_PATH;
11
11
 
12
12
  const CacheKeys = Object.keys(CacheStore);
13
13
 
14
+ const prefillDatastore = (obj, caller) => {
15
+ obj = cloneDeep(obj);
16
+ breakDbMap(obj, (_projectUrl, _dbUrl, _dbName, _path, value) => {
17
+ Object.entries(value.instance).forEach(([access_id, obj]) => {
18
+ value.instance[access_id] = caller(obj);
19
+ });
20
+ Object.entries(value.episode).forEach(([_access_id, limitObj]) => {
21
+ Object.entries(limitObj).forEach(([limit, obj]) => {
22
+ limitObj[limit] = caller(obj);
23
+ });
24
+ });
25
+ });
26
+ return obj;
27
+ };
28
+
14
29
  export const updateCacheStore = async (node) => {
15
30
  const { io, promoteCache } = Scoped.ReleaseCacheData;
16
31
 
@@ -23,28 +38,38 @@ export const updateCacheStore = async (node) => {
23
38
  ...restStore
24
39
  } = CacheStore;
25
40
 
41
+ const minimizePendingWrite = () => {
42
+ const obj = cloneDeep(PendingWrites);
43
+ Object.values(obj).forEach(e => {
44
+ Object.values(e).forEach(b => {
45
+ if ('editions' in b) delete b.editions;
46
+ });
47
+ });
48
+ return obj;
49
+ }
50
+
26
51
  if (io) {
27
52
  const txt = JSON.stringify({
28
53
  AuthStore,
29
54
  EmulatedAuth,
30
55
  PendingAuthPurge,
31
56
  ...promoteCache ? {
32
- DatabaseStore: serializeToBase64(DatabaseStore),
33
- PendingWrites: serializeToBase64(PendingWrites)
57
+ DatabaseStore: prefillDatastore(DatabaseStore, DatastoreParser.encode),
58
+ PendingWrites: minimizePendingWrite()
34
59
  } : {},
35
60
  ...promoteCache ? restStore : {}
36
61
  });
37
62
 
38
63
  io.output(txt, node);
39
64
  } else {
40
- // use sqlite
65
+ // use fs
41
66
  const exclusion = ['DatabaseStore', 'DatabaseCountResult', 'FetchedStore'];
42
67
  const updationKey = (node ? Array.isArray(node) ? node : [node] : CacheKeys).filter(v => !exclusion.includes(v));
43
68
 
44
69
  if (!updationKey.length) return;
45
70
  await Promise.all(
46
71
  updationKey
47
- .map(v => [v, v === 'PendingWrites' ? serializeToBase64(CacheStore[v]) : CacheStore[v]])
72
+ .map(v => [v, v === 'PendingWrites' ? minimizePendingWrite() : CacheStore[v]])
48
73
  .map(([ref, value]) =>
49
74
  getSystem(FILE_NAME).set(TABLE_NAME, ref, { value })
50
75
  )
@@ -62,35 +87,31 @@ export const releaseCacheStore = async (builder) => {
62
87
  try {
63
88
  if (io) {
64
89
  data = JSON.parse((await io.input()) || '{}');
65
- } else {
66
- try {
67
- const query = await getSystem(FILE_NAME).list(TABLE_NAME, ['value']).catch(() => []);
68
- data = Object.fromEntries(
69
- query.map(([ref, { value }]) =>
70
- [ref, value]
71
- )
90
+
91
+ if (data.DatabaseStore)
92
+ data.DatabaseStore = prefillDatastore(
93
+ data.DatabaseStore,
94
+ r => DatastoreParser.decode(r, false)
72
95
  );
73
- } catch (error) {
74
- console.error('initializeCache sqlite data release err:', error);
75
- }
96
+ } else {
97
+ const query = await getSystem(FILE_NAME).list(TABLE_NAME, ['value']).catch(() => []);
98
+ data = Object.fromEntries(
99
+ query.map(([ref, { value }]) =>
100
+ [ref, value]
101
+ )
102
+ );
76
103
  }
77
104
  await purgeRedundantRecords(data, builder);
78
105
  } catch (e) {
79
- console.error('initializeCache data err:', e);
106
+ console.error('releaseCacheStore data err:', e);
80
107
  }
81
108
 
82
109
  Object.entries(data).forEach(([k, v]) => {
83
- if (['DatabaseStore', 'PendingWrites'].includes(k)) {
84
- CacheStore[k] = deserializeBSON(v);
85
- } else CacheStore[k] = v;
110
+ CacheStore[k] = v;
86
111
  });
87
112
  Object.entries(CacheStore.AuthStore).forEach(([key, value]) => {
88
113
  Scoped.AuthJWTToken[key] = value?.token;
89
114
  });
90
- Object.keys(CacheStore.PendingWrites).forEach(projectUrl => {
91
- if (Scoped.IS_CONNECTED[projectUrl])
92
- trySendPendingWrite(projectUrl);
93
- });
94
115
  Scoped.IsStoreReady = true;
95
116
  StoreReadyListener.dispatch('_', 'ready');
96
117
  };
@@ -12,7 +12,7 @@ export const RETRIEVAL = {
12
12
 
13
13
  export const DELIVERY = {
14
14
  DEFAULT: 'default',
15
- CACHE_AWAIT: 'cache-await',
15
+ CACHE_AWAIT: 'cache-await', // TODO: remove
16
16
  CACHE_NO_AWAIT: 'cache-no-await',
17
17
  NO_CACHE_NO_AWAIT: 'no-cache-no-await',
18
18
  NO_CACHE_AWAIT: 'no-cache-await'
@@ -20,21 +20,14 @@ export const Scoped = {
20
20
  /**
21
21
  * @type {Promise<any> | undefined}
22
22
  */
23
- dispatchingWritesPromise: undefined,
24
- linearSqliteProcess: {
23
+ dispatchingWritesPromise: {},
24
+ linearFsProcess: {
25
25
  database: {},
26
26
  dbQueryCount: {},
27
27
  httpFetch: {}
28
28
  }
29
29
  };
30
30
 
31
- export const SqliteCollective = {
32
- openedDb: {},
33
- openedDbProcess: {},
34
- closeDbPromises: {},
35
- openedDbReducerTimer: {}
36
- };
37
-
38
31
  export const CacheStore = {
39
32
  DatabaseStore: {},
40
33
  DatabaseCountResult: {},
package/src/index.js CHANGED
@@ -82,7 +82,7 @@ class RNMT {
82
82
  if (queuedToken) updateMountedToken(queuedToken.token);
83
83
  ServerReachableListener.dispatch(projectUrl, true);
84
84
  awaitStore().then(() => {
85
- trySendPendingWrite(projectUrl);
85
+ if (isConnected) trySendPendingWrite(projectUrl);
86
86
  });
87
87
  };
88
88
  const onDisconnect = () => {
@@ -237,7 +237,7 @@ const purgeCache = (url, isMain) => {
237
237
  'AuthStore',
238
238
  'PendingWrites'
239
239
  ].forEach(e => {
240
- if (e && CacheStore[e][url]) delete CacheStore[e][url];
240
+ if (e && CacheStore[e]?.[url]) delete CacheStore[e][url];
241
241
  });
242
242
  TokenRefreshListener.dispatch(url);
243
243
  triggerAuthToken(url);