react-native-mosquito-transport 0.0.33 → 0.0.35

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.33",
3
+ "version": "0.0.35",
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",
@@ -40,8 +40,8 @@
40
40
  },
41
41
  "peerDependencies": {
42
42
  "react-native": "*",
43
- "react-native-fs": "*",
44
- "react-native-sha256": "*",
45
- "react-native-get-random-values": "*"
43
+ "react-native-file-access": "*",
44
+ "react-native-get-random-values": "*",
45
+ "react-native-sha256": "*"
46
46
  }
47
- }
47
+ }
@@ -1,8 +1,8 @@
1
1
  import { Scoped } from "./variables";
2
2
  import { Platform } from "react-native";
3
- import { writeFile, mkdir, MainBundlePath, readFile, unlink, DocumentDirectoryPath, readdir } from "react-native-fs";
3
+ import { Dirs, FileSystem } from "react-native-file-access";
4
4
 
5
- const PARENT_FOLDER = `${Platform.OS === 'android' ? DocumentDirectoryPath.split('/').slice(0, -1).join('/') : MainBundlePath}/mosquito_base`;
5
+ const PARENT_FOLDER = `${Platform.OS === 'android' ? Dirs.DocumentDir.split('/').slice(0, -1).join('/') : Dirs.MainBundleDir}/mosquito_base`;
6
6
 
7
7
  /**
8
8
  * this method linearize read/write for individual access_id on the file system ensuring consistency across concurrent operations
@@ -16,7 +16,7 @@ export const useFS = (builder, access_id, node) => async (task) => {
16
16
  const { projectUrl, dbUrl, dbName } = builder;
17
17
  const nodeId = typeof builder === 'string' ? `${builder}_${access_id}` : `${projectUrl}_${dbUrl}_${dbName}_${access_id}`;
18
18
 
19
- const thatProcess = Scoped.linearSqliteProcess[node][nodeId];
19
+ const thatProcess = Scoped.linearFsProcess[node][nodeId];
20
20
 
21
21
  const thisPromise = new Promise(async (resolve, reject) => {
22
22
  try {
@@ -28,12 +28,12 @@ export const useFS = (builder, access_id, node) => async (task) => {
28
28
  console.error('useFS err:', error, ' builder:', builder);
29
29
  reject(error);
30
30
  } finally {
31
- if (Scoped.linearSqliteProcess[node][nodeId] === thisPromise)
32
- delete Scoped.linearSqliteProcess[node][nodeId];
31
+ if (Scoped.linearFsProcess[node][nodeId] === thisPromise)
32
+ delete Scoped.linearFsProcess[node][nodeId];
33
33
  }
34
34
  });
35
35
 
36
- Scoped.linearSqliteProcess[node][nodeId] = thisPromise;
36
+ Scoped.linearFsProcess[node][nodeId] = thisPromise;
37
37
  return (await thisPromise);
38
38
  };
39
39
 
@@ -46,24 +46,24 @@ export const getSystem = (builder) => {
46
46
  return {
47
47
  set: async (table, primary_key, value) => {
48
48
  const path = conjoin(table, primary_key);
49
- await mkdir(path).catch(() => null);
49
+ await FileSystem.mkdir(path).catch(() => null);
50
50
  await Promise.all(Object.entries(value).map(([k, v]) =>
51
- writeFile(joinPath(path, k), JSON.stringify(v), 'utf8')
51
+ FileSystem.writeFile(joinPath(path, k), JSON.stringify(v), 'utf8')
52
52
  ));
53
53
  },
54
- delete: (table, primary_key) => unlink(conjoin(table, primary_key)),
54
+ delete: (table, primary_key) => FileSystem.unlink(conjoin(table, primary_key)),
55
55
  find: async (table, primary_key, extractions) => {
56
56
  const path = conjoin(table, primary_key);
57
57
 
58
58
  const value_map = await Promise.all(extractions.map(async node =>
59
- [node, JSON.parse(await readFile(joinPath(path, node)), 'utf8')]
59
+ [node, JSON.parse(await FileSystem.readFile(joinPath(path, node), 'utf8'))]
60
60
  ));
61
61
  return Object.fromEntries(value_map);
62
62
  },
63
63
  list: async (table, extractions) => {
64
- const names = await readdir(conjoin(table));
64
+ const names = await FileSystem.ls(conjoin(table));
65
65
  const list_data = await Promise.all(names.map(async primary_key => {
66
- const obj = await system.find(table, primary_key, extractions)
66
+ const obj = await getSystem(builder).find(table, primary_key, extractions)
67
67
  .catch(() => null);
68
68
  if (!obj) return;
69
69
  return [primary_key, obj];
@@ -74,7 +74,7 @@ export const getSystem = (builder) => {
74
74
  };
75
75
  };
76
76
 
77
- function purifyFilepath(filename) {
77
+ export function purifyFilepath(filename) {
78
78
  if (!filename || typeof filename !== 'string')
79
79
  throw `invalid filename:${filename}`;
80
80
 
@@ -1,9 +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';
6
+ import { purifyFilepath } from "./fs_manager";
7
+ import { grab } from "poke-object";
7
8
 
8
9
  const { box, randomBytes } = naclPkg;
9
10
 
@@ -58,8 +59,8 @@ export const shuffleArray = (n) => {
58
59
 
59
60
  export function sortArrayByObjectKey(arr = [], key) {
60
61
  return arr.sort(function (a, b) {
61
- const left = getLodash(a, key),
62
- right = getLodash(b, key);
62
+ const left = grab(a, key),
63
+ right = grab(b, key);
63
64
 
64
65
  return (left > right) ? 1 : (left < right) ? -1 : 0;
65
66
  });
@@ -67,8 +68,7 @@ export function sortArrayByObjectKey(arr = [], key) {
67
68
 
68
69
  export async function niceHash(str = '') {
69
70
  const hash = Buffer.from(await sha256(str), 'hex').toString('base64');
70
- if (hash.length > str.length) return encodeBinary(str);
71
- return hash;
71
+ return purifyFilepath(hash);
72
72
  };
73
73
 
74
74
  export const sameInstance = (var1, var2) => {
@@ -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
  }
@@ -2,7 +2,6 @@ import { ServerReachableListener, StoreReadyListener } from "./listeners";
2
2
  import { CacheStore, Scoped } from "./variables";
3
3
  import { serializeE2E } from "./peripherals";
4
4
  import { deserializeBSON, serializeToBase64 } from "../products/database/bson";
5
- import { trySendPendingWrite } from "../products/database";
6
5
  import { deserialize } from "entity-serializer";
7
6
  import { purgeRedundantRecords } from "./purger";
8
7
  import { FS_PATH, getSystem } from "./fs_manager";
@@ -37,7 +36,7 @@ export const updateCacheStore = async (node) => {
37
36
 
38
37
  io.output(txt, node);
39
38
  } else {
40
- // use sqlite
39
+ // use fs
41
40
  const exclusion = ['DatabaseStore', 'DatabaseCountResult', 'FetchedStore'];
42
41
  const updationKey = (node ? Array.isArray(node) ? node : [node] : CacheKeys).filter(v => !exclusion.includes(v));
43
42
 
@@ -71,7 +70,7 @@ export const releaseCacheStore = async (builder) => {
71
70
  )
72
71
  );
73
72
  } catch (error) {
74
- console.error('initializeCache sqlite data release err:', error);
73
+ console.error('initializeCache data release err:', error);
75
74
  }
76
75
  }
77
76
  await purgeRedundantRecords(data, builder);
@@ -87,10 +86,6 @@ export const releaseCacheStore = async (builder) => {
87
86
  Object.entries(CacheStore.AuthStore).forEach(([key, value]) => {
88
87
  Scoped.AuthJWTToken[key] = value?.token;
89
88
  });
90
- Object.keys(CacheStore.PendingWrites).forEach(projectUrl => {
91
- if (Scoped.IS_CONNECTED[projectUrl])
92
- trySendPendingWrite(projectUrl);
93
- });
94
89
  Scoped.IsStoreReady = true;
95
90
  StoreReadyListener.dispatch('_', 'ready');
96
91
  };
@@ -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);
@@ -2,17 +2,15 @@ import { niceHash, shuffleArray, sortArrayByObjectKey } from "../../helpers/peri
2
2
  import { awaitStore, updateCacheStore } from "../../helpers/utils";
3
3
  import { CacheStore, Scoped } from "../../helpers/variables";
4
4
  import { assignExtractionFind, CompareBson, confirmFilterDoc, defaultBSON, downcastBSON, validateCollectionName, validateFilter } from "./validator";
5
- import getLodash from 'lodash/get';
6
- import setLodash from 'lodash/set';
7
- import unsetLodash from 'lodash/unset';
8
5
  import { DatabaseRecordsListener } from "../../helpers/listeners";
9
6
  import cloneDeep from "lodash/cloneDeep";
10
- import { BSONRegExp, ObjectId, Timestamp } from "bson/lib/bson.rn.cjs";
7
+ import { BSONRegExp, ObjectId, Timestamp } from "../../vendor/bson";
11
8
  import { niceGuard, Validator } from "guard-object";
12
9
  import { TIMESTAMP } from "../..";
13
10
  import { docSize, incrementDatabaseSize } from "./counter";
14
11
  import { deserializeBSON, serializeToBase64 } from "./bson";
15
12
  import { FS_PATH, getSystem, useFS } from "../../helpers/fs_manager";
13
+ import { grab, poke, unpoke } from "poke-object";
16
14
 
17
15
  const { LIMITER_DATA, LIMITER_RESULT, DB_COUNT_QUERY } = FS_PATH;
18
16
 
@@ -48,12 +46,12 @@ export const insertCountQuery = async (builder, access_id, value) => {
48
46
 
49
47
  const { io } = Scoped.ReleaseCacheData;
50
48
  if (io) {
51
- setLodash(CacheStore.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id], { value, touched: Date.now() });
49
+ poke(CacheStore.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id], { value, touched: Date.now() });
52
50
  updateCacheStore(['DatabaseCountResult']);
53
51
  } else {
54
52
  await useFS(builder, access_id, 'dbQueryCount')(async fs => {
55
53
  await fs.set(DB_COUNT_QUERY(path), access_id, { value, touched: Date.now() });
56
- setLodash(CacheStore.DatabaseStats.counters, [projectUrl, dbUrl, dbName, path], true);
54
+ poke(CacheStore.DatabaseStats.counters, [projectUrl, dbUrl, dbName, path], true);
57
55
  });
58
56
  updateCacheStore(['DatabaseStats']);
59
57
  }
@@ -64,15 +62,17 @@ export const getCountQuery = async (builder, access_id) => {
64
62
  const { io } = Scoped.ReleaseCacheData;
65
63
 
66
64
  if (io) {
67
- const data = getLodash(CacheStore.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id]);
65
+ const data = grab(CacheStore.DatabaseCountResult, [projectUrl, dbUrl, dbName, path, access_id]);
68
66
  if (data) data.touched = Date.now();
69
67
  return data && data.value;
70
68
  } else {
71
69
  return useFS(builder, access_id, 'dbQueryCount')(async fs => {
72
- const { value } = await fs.find(DB_COUNT_QUERY(path), access_id, ['value']);
73
- await fs.set(DB_COUNT_QUERY(path), access_id, { touched: Date.now() });
74
- return value;
75
- }).catch(() => undefined);
70
+ const data = await fs.find(DB_COUNT_QUERY(path), access_id, ['value']).catch(() => null);
71
+ if (data) {
72
+ await fs.set(DB_COUNT_QUERY(path), access_id, { touched: Date.now() });
73
+ return data.value;
74
+ }
75
+ });
76
76
  }
77
77
  }
78
78
 
@@ -132,8 +132,8 @@ export const insertRecord = async (builder, config, accessIdWithoutLimit, value,
132
132
  return;
133
133
  }
134
134
 
135
- const instanceData = getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit]);
136
- const resultData = getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, limit]);
135
+ const instanceData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit]);
136
+ const resultData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`]);
137
137
  const isEpisode = episode === 1 || !!resultData;
138
138
 
139
139
  const editionSizeOffset = thisSize - (instanceData?.size || 0);
@@ -155,8 +155,8 @@ export const insertRecord = async (builder, config, accessIdWithoutLimit, value,
155
155
 
156
156
  incrementDatabaseSize(builder, path, editionSizeOffset + resultSizeOffset);
157
157
 
158
- setLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit], newData);
159
- if (isEpisode) setLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, limit], cloneDeep(newResultData));
158
+ poke(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit], newData);
159
+ if (isEpisode) poke(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`], cloneDeep(newResultData));
160
160
  updateCacheStore(['DatabaseStore', 'DatabaseStats']);
161
161
  };
162
162
 
@@ -219,7 +219,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
219
219
  }
220
220
 
221
221
  if (isEpisode) {
222
- const resultData = getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, limit]);
222
+ const resultData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`]);
223
223
  if (resultData) {
224
224
  resultData.touched = Date.now();
225
225
  return [cloneDeep(resultData.data)];
@@ -227,7 +227,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
227
227
  return null;
228
228
  }
229
229
 
230
- const instanceData = getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit]);
230
+ const instanceData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit]);
231
231
  if (!instanceData) return null;
232
232
  const { latest_limiter, data } = instanceData;
233
233
 
@@ -387,19 +387,20 @@ export const addPendingWrites = async (builder, writeId, result) => {
387
387
  const pathChanges = new Set([]);
388
388
  const pendingSnapshot = cloneDeep(result);
389
389
 
390
- await Promise.all((
390
+ const linearWrite =
391
391
  result.type === 'batchWrite' ?
392
392
  result.value.map(({ scope, value, find, path }) =>
393
393
  ({ type: scope, value, find, path })
394
394
  )
395
- : [{ ...result, path: builder.path }]
396
- ).map(async ({ value: writeObj, find, type, path }) => {
395
+ : [{ ...result, find: builder.find, path: builder.path }];
396
+
397
+ await Promise.all(linearWrite.map(async ({ value: writeObj, find, type, path }) => {
397
398
  WriteValidator[type]({ find, value: writeObj });
398
399
  validateCollectionName(path);
399
400
  pathChanges.add(path);
400
401
 
401
402
  if (io) {
402
- const colObj = getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance']);
403
+ const colObj = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance']);
403
404
 
404
405
  if (colObj)
405
406
  await Promise.all(
@@ -408,7 +409,7 @@ export const addPendingWrites = async (builder, writeId, result) => {
408
409
  e,
409
410
  path =>
410
411
  Object.values(
411
- getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance'], {})
412
+ grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance'], {})
412
413
  ).map(({ data }) => data).flat()
413
414
  )
414
415
  )
@@ -638,12 +639,57 @@ export const addPendingWrites = async (builder, writeId, result) => {
638
639
  };
639
640
  }));
640
641
 
641
- setLodash(CacheStore.PendingWrites, [projectUrl, writeId], cloneDeep({
642
- builder,
643
- snapshot: pendingSnapshot,
644
- editions,
645
- addedOn: Date.now()
646
- }));
642
+ const isStaticWrite = !linearWrite.some(({ value, type }) => {
643
+ if (
644
+ [
645
+ 'updateOne',
646
+ 'updateMany',
647
+ 'mergeOne',
648
+ 'mergeMany'
649
+ ].includes(type)
650
+ ) {
651
+ const operators = Object.keys(value);
652
+ return ['$inc', '$min', '$max', '$mul', '$pop', '$pull', '$push', '$rename'].includes(operators);
653
+ }
654
+ });
655
+ const pureBuilder = {};
656
+
657
+ ['path', 'dbUrl', 'dbName', 'find', 'extraHeaders'].forEach(v => {
658
+ if (builder[v] !== undefined) pureBuilder[v] = builder[v];
659
+ });
660
+ pureBuilder.find = serializeToBase64({ _: pureBuilder.find });
661
+ pendingSnapshot.value = serializeToBase64({ _: pendingSnapshot.value });
662
+
663
+ let wasShifted;
664
+
665
+ if (isStaticWrite) {
666
+ // find previously matching pending write
667
+ const entries = Object.entries(CacheStore.PendingWrites[projectUrl] || {});
668
+
669
+ for (const [writeId, obj] of entries) {
670
+ if (!Scoped.OutgoingWrites[writeId]) {
671
+ if (
672
+ niceGuard(
673
+ { builder: obj.builder, snapshot: obj.snapshot },
674
+ { builder: pureBuilder, snapshot: pendingSnapshot }
675
+ )
676
+ ) {
677
+ // shift it to the front
678
+ obj.addedOn = Date.now();
679
+ wasShifted = true;
680
+ break;
681
+ }
682
+ }
683
+ }
684
+ }
685
+
686
+ if (!wasShifted)
687
+ poke(CacheStore.PendingWrites, [projectUrl, writeId], cloneDeep({
688
+ builder: pureBuilder,
689
+ snapshot: pendingSnapshot,
690
+ editions,
691
+ addedOn: Date.now()
692
+ }));
647
693
 
648
694
  updateCacheStore(['DatabaseStore', 'PendingWrites', 'DatabaseStats']);
649
695
  notifyDatabaseNodeChanges(builder, [...pathChanges]);
@@ -652,7 +698,7 @@ export const addPendingWrites = async (builder, writeId, result) => {
652
698
  export const removePendingWrite = async (builder, writeId, revert) => {
653
699
  await awaitStore();
654
700
  const { projectUrl, dbUrl, dbName } = builder;
655
- const pendingData = getLodash(CacheStore.PendingWrites, [projectUrl, writeId]);
701
+ const pendingData = grab(CacheStore.PendingWrites, [projectUrl, writeId]);
656
702
  const { io } = Scoped.ReleaseCacheData;
657
703
 
658
704
  if (!pendingData) return;
@@ -661,11 +707,11 @@ export const removePendingWrite = async (builder, writeId, revert) => {
661
707
  if (revert) {
662
708
  await Promise.all(pendingData.editions.map(async ([access_id, [b4Doc, afDoc], path]) => {
663
709
  if (io) {
664
- RevertMutation(getLodash(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]));
710
+ RevertMutation(grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]));
665
711
  } else {
666
712
  await useFS(builder, access_id, 'database')(async fs => {
667
713
  const colObj = await fs.find(LIMITER_DATA(path), access_id, ['value'])
668
- .then(v => deserializeBSON(v.value))
714
+ .then(v => deserializeBSON(v.value, true))
669
715
  .catch(() => null);
670
716
  if (!colObj) return;
671
717
  RevertMutation(colObj);
@@ -715,7 +761,7 @@ export const removePendingWrite = async (builder, writeId, revert) => {
715
761
  }));
716
762
  }
717
763
 
718
- unsetLodash(CacheStore.PendingWrites, [projectUrl, writeId]);
764
+ unpoke(CacheStore.PendingWrites, [projectUrl, writeId]);
719
765
  updateCacheStore(['PendingWrites', 'DatabaseStore', 'DatabaseStats']);
720
766
  notifyDatabaseNodeChanges(builder, [...pathChanges]);
721
767
  };
@@ -766,19 +812,19 @@ const snipDocument = (data, find, config) => {
766
812
  if (returnOnly) {
767
813
  output = {};
768
814
  (Array.isArray(returnOnly) ? returnOnly : [returnOnly]).filter(v => v).forEach(e => {
769
- const thisData = getLodash(data, e);
770
- if (thisData) setLodash(output, e, thisData);
815
+ const thisData = grab(data, e);
816
+ if (thisData) poke(output, e, thisData);
771
817
  });
772
818
  } else if (excludeFields) {
773
819
  (Array.isArray(excludeFields) ? excludeFields : [excludeFields]).filter(v => v).forEach(e => {
774
- if (getLodash(data, e) && e !== '_id') unsetLodash(output, e);
820
+ if (grab(data, e) && e !== '_id') unpoke(output, e);
775
821
  });
776
822
  }
777
823
 
778
824
  getFindFields(find).forEach(field => {
779
- if (!getLodash(output, field)) {
780
- const mainData = getLodash(data, field);
781
- if (mainData !== undefined) setLodash(output, field, mainData);
825
+ if (!grab(output, field)) {
826
+ const mainData = grab(data, field);
827
+ if (mainData !== undefined) poke(output, field, mainData);
782
828
  }
783
829
  });
784
830
 
@@ -848,10 +894,10 @@ const AtomicWriter = {
848
894
  !isDate &&
849
895
  !isTimestamp
850
896
  ) throw `invalid value at $currentDate.${field}, expected any of boolean (true), { $type: "timestamp" } or { $type: "date" } but got ${value}`;
851
- setLodash(object, field, isDate ? new Date() : new Timestamp({ t: Math.floor(Date.now() / 1000), i: 0 }));
897
+ poke(object, field, isDate ? new Date() : new Timestamp({ t: Math.floor(Date.now() / 1000), i: 0 }));
852
898
  },
853
899
  $inc: (field, value, object) => {
854
- const current = getLodash(object, field);
900
+ const current = grab(object, field);
855
901
  if (current === null) {
856
902
  console.warn(`cannot use $inc operator on a null value at ${field}`);
857
903
  return;
@@ -861,29 +907,29 @@ const AtomicWriter = {
861
907
 
862
908
  if (!Validator.NUMBER(castedValue)) throw `expected a number at $inc.${field} but got ${value}`;
863
909
 
864
- setLodash(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent + castedValue, current) : value);
910
+ poke(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent + castedValue, current) : value);
865
911
  },
866
912
  $min: (field, value, object) => {
867
- const current = getLodash(object, field);
913
+ const current = grab(object, field);
868
914
  if (CompareBson.lesser(value, current)) {
869
- setLodash(object, field, value);
915
+ poke(object, field, value);
870
916
  }
871
917
  },
872
918
  $max: (field, value, object) => {
873
- const current = getLodash(object, field);
919
+ const current = grab(object, field);
874
920
  if (CompareBson.greater(value, current)) {
875
- setLodash(object, field, value);
921
+ poke(object, field, value);
876
922
  }
877
923
  },
878
924
  $mul: (field, value, object) => {
879
- const current = getLodash(object, field);
925
+ const current = grab(object, field);
880
926
  const castedValue = downcastBSON(value);
881
927
  const castedCurrent = downcastBSON(current);
882
928
 
883
929
  if (!Validator.NUMBER(castedValue))
884
930
  throw `expected a number at $mul.${field} but got ${value}`;
885
931
 
886
- setLodash(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent * castedValue, value) : 0);
932
+ poke(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent * castedValue, value) : 0);
887
933
  },
888
934
  $rename: (field, value, object) => {
889
935
  if (!Validator.EMPTY_STRING(value))
@@ -901,7 +947,7 @@ const AtomicWriter = {
901
947
  if (!e) throw `empty node for ${field}`;
902
948
  });
903
949
  const [tipObj, tipSource, tipDest] = destStage.length === 1 ? [object, field, value]
904
- : [getLodash(object, destStage.slice(0, -1).join('.')), sourceStage.slice(-1)[0], destStage.slice(-1)[0]];
950
+ : [grab(object, destStage.slice(0, -1).join('.')), sourceStage.slice(-1)[0], destStage.slice(-1)[0]];
905
951
 
906
952
  if (tipObj && tipSource in tipObj) {
907
953
  tipObj[tipDest] = cloneDeep(tipObj[tipSource]);
@@ -909,16 +955,16 @@ const AtomicWriter = {
909
955
  }
910
956
  },
911
957
  $set: (field, value, object) => {
912
- setLodash(object, field, value === undefined ? null : value);
958
+ poke(object, field, value === undefined ? null : value);
913
959
  },
914
960
  $setOnInsert: (field, value, object, isNew) => {
915
961
  if (isNew) AtomicWriter.$set(field, value, object);
916
962
  },
917
963
  $unset: (field, _, object) => {
918
- unsetLodash(object, field);
964
+ unpoke(object, field);
919
965
  },
920
966
  $addToSet: (field, value, object) => {
921
- const current = getLodash(object, field);
967
+ const current = grab(object, field);
922
968
  if (Array.isArray(current)) {
923
969
  if (
924
970
  Validator.OBJECT(value) &&
@@ -940,7 +986,7 @@ const AtomicWriter = {
940
986
  },
941
987
  $pop: (field, value, object) => {
942
988
  if (![1, -1].includes(value)) throw `expected 1 or -1 at "$pop.${field}" but got ${value}`;
943
- const current = getLodash(object, field);
989
+ const current = grab(object, field);
944
990
  if (
945
991
  Array.isArray(current) &&
946
992
  current.length
@@ -948,7 +994,7 @@ const AtomicWriter = {
948
994
  },
949
995
  $pull: (field, value, object) => {
950
996
  // TODO: issues
951
- const current = getLodash(object, field);
997
+ const current = grab(object, field);
952
998
  const isQueryObject = Validator.OBJECT(value);
953
999
 
954
1000
  if (
@@ -970,11 +1016,11 @@ const AtomicWriter = {
970
1016
  } catch (_) { }
971
1017
  return true;
972
1018
  });
973
- setLodash(object, field, remainingCurrent);
1019
+ poke(object, field, remainingCurrent);
974
1020
  }
975
1021
  },
976
1022
  $push: (field, value, object) => {
977
- const current = getLodash(object, field);
1023
+ const current = grab(object, field);
978
1024
 
979
1025
  if (Array.isArray(current)) {
980
1026
  if (Validator.OBJECT(value)) {
@@ -1021,13 +1067,13 @@ const AtomicWriter = {
1021
1067
  if (!Array.isArray(value))
1022
1068
  throw `expected an array at $pullAll.${field}`;
1023
1069
 
1024
- const current = getLodash(object, field);
1070
+ const current = grab(object, field);
1025
1071
 
1026
1072
  if (Array.isArray(current)) {
1027
1073
  const remainingCurrent = current.filter(v =>
1028
1074
  !value.some(k => CompareBson.equal(v, k))
1029
1075
  );
1030
- setLodash(object, field, remainingCurrent);
1076
+ poke(object, field, remainingCurrent);
1031
1077
  }
1032
1078
  }
1033
1079
  };
@@ -1,4 +1,4 @@
1
- import { deserialize, serialize } from "bson/lib/bson.rn.cjs";
1
+ import { deserialize, serialize } from "../../vendor/bson";
2
2
  import { Buffer } from "buffer";
3
3
 
4
4
  export const deserializeBSON = (data, cast) => {