react-native-mosquito-transport 0.0.36 → 0.0.38

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.36",
3
+ "version": "0.0.38",
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",
@@ -12,7 +12,7 @@ const inlineFsData = (arr, access_id_node = 'access_id') =>
12
12
  return obj;
13
13
  });
14
14
 
15
- export const purgeRedundantRecords = async (data, builder) => {
15
+ export const purgeRedundantRecords = async (data, builder, willPurge) => {
16
16
  const { io, maxLocalDatabaseSize = 10485760, maxLocalFetchHttpSize = 10485760 } = builder;
17
17
 
18
18
  /**
@@ -20,9 +20,15 @@ export const purgeRedundantRecords = async (data, builder) => {
20
20
  */
21
21
  const { _db_size, _fetcher_size, counters, database, fetchers } = data.DatabaseStats || {};
22
22
 
23
+ const shouldPurgeDb = Validator.POSITIVE_NUMBER(_db_size) && maxLocalDatabaseSize && _db_size >= maxLocalDatabaseSize;
24
+ const shouldPurgeFetcher = Validator.POSITIVE_NUMBER(_fetcher_size) && maxLocalFetchHttpSize && _fetcher_size >= maxLocalFetchHttpSize;
25
+
26
+ if (shouldPurgeDb) willPurge(['DatabaseStore', 'DatabaseCountResult', 'DatabaseStats']);
27
+ if (shouldPurgeFetcher) willPurge(['FetchedStore', 'DatabaseStats']);
28
+
23
29
  if (io) {
24
30
  const purgeDatabase = () => {
25
- if (!Validator.POSITIVE_NUMBER(_db_size) || !maxLocalDatabaseSize || _db_size < maxLocalDatabaseSize) return;
31
+ if (!shouldPurgeDb) return;
26
32
  const DbListing = [];
27
33
 
28
34
  breakDbMap(data.DatabaseStore, (projectUrl, dbUrl, dbName, path, value) => {
@@ -98,7 +104,7 @@ export const purgeRedundantRecords = async (data, builder) => {
98
104
  });
99
105
  }
100
106
  const purgeFetcher = () => {
101
- if (!Validator.POSITIVE_NUMBER(_fetcher_size) || !maxLocalFetchHttpSize || _fetcher_size < maxLocalFetchHttpSize) return;
107
+ if (!shouldPurgeFetcher) return;
102
108
  const redundantFetchRanking = Object.entries(data.FetchedStore).map(([projectUrl, access_id_Obj]) =>
103
109
  Object.entries(access_id_Obj).map(([access_id, data]) => ({
104
110
  access_id,
@@ -133,7 +139,7 @@ export const purgeRedundantRecords = async (data, builder) => {
133
139
  await Promise.allSettled([
134
140
  (async () => {
135
141
  try {
136
- if (!Validator.POSITIVE_NUMBER(_db_size) || !maxLocalDatabaseSize || _db_size < maxLocalDatabaseSize) return;
142
+ if (!shouldPurgeDb) return;
137
143
  const instances = [];
138
144
 
139
145
  [database, counters].forEach((map, i) => {
@@ -204,7 +210,7 @@ export const purgeRedundantRecords = async (data, builder) => {
204
210
  })(),
205
211
  (async () => {
206
212
  try {
207
- if (!Validator.POSITIVE_NUMBER(_fetcher_size) || !maxLocalFetchHttpSize || _fetcher_size < maxLocalFetchHttpSize) return;
213
+ if (!shouldPurgeFetcher) return;
208
214
 
209
215
  const redundantFetchRanking = await Promise.all(
210
216
  Object.entries(fetchers).map(async ([projectUrl]) => {
@@ -2,10 +2,11 @@ import { ServerReachableListener, StoreReadyListener } from "./listeners";
2
2
  import { CacheStore, Scoped } from "./variables";
3
3
  import { serializeE2E } from "./peripherals";
4
4
  import { DatastoreParser } from "../products/database/bson";
5
- import { deserialize, serialize } from "entity-serializer";
5
+ import { deserialize } from "entity-serializer";
6
6
  import { breakDbMap, purgeRedundantRecords } from "./purger";
7
7
  import { FS_PATH, getSystem } from "./fs_manager";
8
8
  import cloneDeep from "lodash/cloneDeep";
9
+ import { Buffer } from "buffer";
9
10
 
10
11
  const { FILE_NAME, TABLE_NAME } = FS_PATH;
11
12
 
@@ -26,7 +27,20 @@ const prefillDatastore = (obj, caller) => {
26
27
  return obj;
27
28
  };
28
29
 
30
+ const prefillFetcher = (store, encode) => {
31
+ store = cloneDeep(store);
32
+ Object.values(store).forEach(accessIdObj => {
33
+ Object.values(accessIdObj).forEach(value => {
34
+ value.data.buffer = encode ?
35
+ Buffer.from(value.data.buffer).toString('base64')
36
+ : Buffer.from(value.data.buffer, 'base64');
37
+ });
38
+ });
39
+ return store;
40
+ }
41
+
29
42
  export const updateCacheStore = async (node) => {
43
+ node = node && node.filter((v, i, a) => a.indexOf(v) === i);
30
44
  const { io, promoteCache } = Scoped.ReleaseCacheData;
31
45
 
32
46
  const {
@@ -35,6 +49,7 @@ export const updateCacheStore = async (node) => {
35
49
  PendingAuthPurge,
36
50
  DatabaseStore,
37
51
  PendingWrites,
52
+ FetchedStore,
38
53
  ...restStore
39
54
  } = CacheStore;
40
55
 
@@ -55,7 +70,8 @@ export const updateCacheStore = async (node) => {
55
70
  PendingAuthPurge,
56
71
  ...promoteCache ? {
57
72
  DatabaseStore: prefillDatastore(DatabaseStore, DatastoreParser.encode),
58
- PendingWrites: minimizePendingWrite()
73
+ PendingWrites: minimizePendingWrite(),
74
+ FetchedStore: prefillFetcher(FetchedStore, true)
59
75
  } : {},
60
76
  ...promoteCache ? restStore : {}
61
77
  });
@@ -83,6 +99,7 @@ export const releaseCacheStore = async (builder) => {
83
99
  const { io } = builder;
84
100
 
85
101
  let data = {};
102
+ const tobePurged = [];
86
103
 
87
104
  try {
88
105
  if (io) {
@@ -93,6 +110,8 @@ export const releaseCacheStore = async (builder) => {
93
110
  data.DatabaseStore,
94
111
  r => DatastoreParser.decode(r, false)
95
112
  );
113
+ if (data.FetchedStore)
114
+ data.FetchedStore = prefillFetcher(data.FetchedStore, false);
96
115
  } else {
97
116
  const query = await getSystem(FILE_NAME).list(TABLE_NAME, ['value']).catch(() => []);
98
117
  data = Object.fromEntries(
@@ -101,7 +120,9 @@ export const releaseCacheStore = async (builder) => {
101
120
  )
102
121
  );
103
122
  }
104
- await purgeRedundantRecords(data, builder);
123
+ await purgeRedundantRecords(data, builder, purgeNodes => {
124
+ tobePurged.push(...purgeNodes);
125
+ });
105
126
  } catch (e) {
106
127
  console.error('releaseCacheStore data err:', e);
107
128
  }
@@ -114,6 +135,9 @@ export const releaseCacheStore = async (builder) => {
114
135
  });
115
136
  Scoped.IsStoreReady = true;
116
137
  StoreReadyListener.dispatch('_', 'ready');
138
+ setTimeout(() => {
139
+ if (tobePurged.length) updateCacheStore(tobePurged);
140
+ }, 0);
117
141
  };
118
142
 
119
143
  export const getPrefferTime = () => Date.now() + (Scoped.serverTimeOffset || 0);
@@ -12,7 +12,6 @@ export const RETRIEVAL = {
12
12
 
13
13
  export const DELIVERY = {
14
14
  DEFAULT: 'default',
15
- CACHE_AWAIT: 'cache-await', // TODO: remove
16
15
  CACHE_NO_AWAIT: 'cache-no-await',
17
16
  NO_CACHE_NO_AWAIT: 'no-cache-no-await',
18
17
  NO_CACHE_AWAIT: 'no-cache-await'
package/src/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { BSON } from "./vendor/bson";
2
+
1
3
  interface RNMTConfig {
2
4
  dbName?: string;
3
5
  dbUrl?: string;
@@ -75,6 +77,8 @@ export class DoNotEncrypt {
75
77
  value: any;
76
78
  }
77
79
 
80
+ export { BSON }
81
+
78
82
  interface auth_provider_id {
79
83
  GOOGLE: 'google';
80
84
  FACEBOOK: 'facebook';
@@ -289,7 +293,7 @@ interface FetchHttpConfig {
289
293
  rawApproach?: boolean;
290
294
  }
291
295
 
292
- type Delievery = 'default' | 'no-cache' | 'no-await' | 'no-await-no-cache' | 'await-no-cache' | 'cache-no-await';
296
+ type Delievery = 'default' | 'cache-no-await' | 'no-cache-no-await' | 'no-cache-await';
293
297
 
294
298
  interface WriteConfig {
295
299
  /**
@@ -297,21 +301,9 @@ interface WriteConfig {
297
301
  */
298
302
  disableAuth?: boolean;
299
303
 
300
- DEFAULT: 'default',
301
- CACHE_AWAIT: 'cache-await',
302
- CACHE_NO_AWAIT: 'cache-no-await',
303
- NO_CACHE_NO_AWAIT: 'no-cache-no-await',
304
- NO_CACHE_AWAIT: 'no-cache-await'
305
-
306
304
  /**
307
305
  * This property determines how the write will be dispatch to the remote server
308
306
  * TODO:
309
- *
310
- * `default`:
311
- * `cache-await`:
312
- * `cache-no-await`:
313
- * `no-cache-no-await`:
314
- * `no-cache-await`:
315
307
  */
316
308
  delivery?: Delievery;
317
309
  }
package/src/index.js CHANGED
@@ -15,6 +15,7 @@ import { Validator } from 'guard-object';
15
15
  import cloneDeep from 'lodash/cloneDeep';
16
16
  import { Buffer } from 'buffer';
17
17
  import MTAuth, { purgePendingToken } from './products/auth';
18
+ import { BSON } from "./vendor/bson";
18
19
 
19
20
  const {
20
21
  _listenCollection,
@@ -426,7 +427,7 @@ const validateReleaseCacheProp = (prop) => {
426
427
  throw `Invalid value supplied to "io.${k}", expected a function but got "${v}"`;
427
428
  } else throw `Unexpected property named "io.${k}"`;
428
429
  });
429
- if (!v?.input && !v?.output) throw '"input" and "output" are required when "io" is provided';
430
+ if (!v?.input || !v?.output) throw '"input" and "output" are required when "io" is provided';
430
431
  } else if (k === 'promoteCache') {
431
432
  if (typeof v !== 'boolean') throw 'promoteCache should be a boolean';
432
433
  } else if (['maxLocalDatabaseSize', 'maxLocalFetchHttpSize'].includes(k)) {
@@ -507,7 +508,8 @@ export {
507
508
  DOCUMENT_EXTRACTION,
508
509
  FIND_GEO_JSON,
509
510
  GEO_JSON,
510
- AUTH_PROVIDER_ID
511
+ AUTH_PROVIDER_ID,
512
+ BSON
511
513
  };
512
514
 
513
515
  export default RNMT;
@@ -6,7 +6,7 @@ import { DatabaseRecordsListener } from "../../helpers/listeners";
6
6
  import cloneDeep from "lodash/cloneDeep";
7
7
  import { BSONRegExp, ObjectId, Timestamp } from "../../vendor/bson";
8
8
  import { niceGuard, Validator } from "guard-object";
9
- import { TIMESTAMP } from "../..";
9
+ import { TIMESTAMP } from "./types";
10
10
  import { docSize, incrementDatabaseSize } from "./counter";
11
11
  import { DatastoreParser, serializeToBase64 } from "./bson";
12
12
  import { FS_PATH, getSystem, useFS } from "../../helpers/fs_manager";
@@ -18,7 +18,7 @@ export const listenQueryEntry = (callback, { accessId, builder, config, processI
18
18
  const { projectUrl, dbName, dbUrl, path } = builder;
19
19
  const { episode = 0 } = config || {};
20
20
 
21
- const nodeID = `${projectUrl}${dbName}${dbUrl}${path}`;
21
+ const nodeID = `${projectUrl}_${dbName}_${dbUrl}_${path}`;
22
22
 
23
23
  if (!Scoped.ActiveDatabaseListeners[nodeID])
24
24
  Scoped.ActiveDatabaseListeners[nodeID] = {};
@@ -379,12 +379,72 @@ export const addPendingWrites = async (builder, writeId, result) => {
379
379
  result = result && cloneDeep(result);
380
380
  await awaitStore();
381
381
 
382
+ const { projectUrl } = builder;
383
+ const pendingSnapshot = cloneDeep(result);
384
+ const { editions, linearWrite, pathChanges } = await syncCache(builder, result);
385
+
386
+ const isStaticWrite = !linearWrite.some(({ value, type }) => {
387
+ if (
388
+ [
389
+ 'updateOne',
390
+ 'updateMany',
391
+ 'mergeOne',
392
+ 'mergeMany'
393
+ ].includes(type)
394
+ ) {
395
+ const operators = Object.keys(value);
396
+ return ['$inc', '$min', '$max', '$mul', '$pop', '$pull', '$push', '$rename'].includes(operators);
397
+ }
398
+ });
399
+ const pureBuilder = {};
400
+
401
+ ['path', 'dbUrl', 'dbName', 'find', 'extraHeaders', 'maxRetries'].forEach(v => {
402
+ if (builder[v] !== undefined) pureBuilder[v] = builder[v];
403
+ });
404
+ pureBuilder.find = serializeToBase64({ _: pureBuilder.find });
405
+ pendingSnapshot.value = serializeToBase64({ _: pendingSnapshot.value });
406
+
407
+ let wasShifted;
408
+
409
+ if (isStaticWrite) {
410
+ // find previously matching pending write
411
+ const entries = Object.entries(CacheStore.PendingWrites[projectUrl] || {});
412
+
413
+ for (const [writeId, obj] of entries) {
414
+ if (!Scoped.OutgoingWrites[writeId]) {
415
+ if (
416
+ niceGuard(
417
+ { builder: obj.builder, snapshot: obj.snapshot },
418
+ { builder: pureBuilder, snapshot: pendingSnapshot }
419
+ )
420
+ ) {
421
+ // shift it to the back
422
+ obj.addedOn = Date.now();
423
+ wasShifted = true;
424
+ break;
425
+ }
426
+ }
427
+ }
428
+ }
429
+
430
+ if (!wasShifted)
431
+ poke(CacheStore.PendingWrites, [projectUrl, writeId], cloneDeep({
432
+ builder: pureBuilder,
433
+ snapshot: pendingSnapshot,
434
+ editions,
435
+ addedOn: Date.now()
436
+ }));
437
+
438
+ updateCacheStore(['DatabaseStore', 'PendingWrites', 'DatabaseStats']);
439
+ notifyDatabaseNodeChanges(builder, [...pathChanges]);
440
+ };
441
+
442
+ const syncCache = async (builder, result) => {
382
443
  const { io } = Scoped.ReleaseCacheData;
383
444
  const { projectUrl, dbUrl, dbName } = builder;
384
- const editions = [];
385
445
  const duplicateSets = {};
446
+ const editions = [];
386
447
  const pathChanges = new Set([]);
387
- const pendingSnapshot = cloneDeep(result);
388
448
 
389
449
  const linearWrite =
390
450
  result.type === 'batchWrite' ?
@@ -393,6 +453,8 @@ export const addPendingWrites = async (builder, writeId, result) => {
393
453
  )
394
454
  : [{ ...result, find: builder.find, path: builder.path }];
395
455
 
456
+ const copiedWrite = cloneDeep(linearWrite);
457
+
396
458
  await Promise.all(linearWrite.map(async ({ value: writeObj, find, type, path }) => {
397
459
  WriteValidator[type]({ find, value: writeObj });
398
460
  validateCollectionName(path);
@@ -638,138 +700,94 @@ export const addPendingWrites = async (builder, writeId, result) => {
638
700
  };
639
701
  }));
640
702
 
641
- const isStaticWrite = !linearWrite.some(({ value, type }) => {
642
- if (
643
- [
644
- 'updateOne',
645
- 'updateMany',
646
- 'mergeOne',
647
- 'mergeMany'
648
- ].includes(type)
649
- ) {
650
- const operators = Object.keys(value);
651
- return ['$inc', '$min', '$max', '$mul', '$pop', '$pull', '$push', '$rename'].includes(operators);
652
- }
653
- });
654
- const pureBuilder = {};
655
-
656
- ['path', 'dbUrl', 'dbName', 'find', 'extraHeaders', 'maxRetries'].forEach(v => {
657
- if (builder[v] !== undefined) pureBuilder[v] = builder[v];
658
- });
659
- pureBuilder.find = serializeToBase64({ _: pureBuilder.find });
660
- pendingSnapshot.value = serializeToBase64({ _: pendingSnapshot.value });
661
-
662
- let wasShifted;
703
+ return {
704
+ editions,
705
+ pathChanges: [...pathChanges],
706
+ linearWrite: copiedWrite
707
+ };
708
+ }
663
709
 
664
- if (isStaticWrite) {
665
- // find previously matching pending write
666
- const entries = Object.entries(CacheStore.PendingWrites[projectUrl] || {});
710
+ export const removePendingWrite = async (builder, writeId, revert) => {
711
+ await awaitStore();
712
+ const { projectUrl } = builder;
713
+ const pendingData = grab(CacheStore.PendingWrites, [projectUrl, writeId]);
714
+ if (!pendingData) return;
667
715
 
668
- for (const [writeId, obj] of entries) {
669
- if (!Scoped.OutgoingWrites[writeId]) {
670
- if (
671
- niceGuard(
672
- { builder: obj.builder, snapshot: obj.snapshot },
673
- { builder: pureBuilder, snapshot: pendingSnapshot }
674
- )
675
- ) {
676
- // shift it to the front
677
- obj.addedOn = Date.now();
678
- wasShifted = true;
679
- break;
680
- }
681
- }
682
- }
683
- }
716
+ const pathChanges = revert ? await revertChanges(builder, pendingData.editions) : [];
684
717
 
685
- if (!wasShifted)
686
- poke(CacheStore.PendingWrites, [projectUrl, writeId], cloneDeep({
687
- builder: pureBuilder,
688
- snapshot: pendingSnapshot,
689
- editions,
690
- addedOn: Date.now()
691
- }));
692
-
693
- updateCacheStore(['DatabaseStore', 'PendingWrites', 'DatabaseStats']);
718
+ unpoke(CacheStore.PendingWrites, [projectUrl, writeId]);
719
+ updateCacheStore(['PendingWrites', 'DatabaseStore', 'DatabaseStats']);
694
720
  notifyDatabaseNodeChanges(builder, [...pathChanges]);
695
721
  };
696
722
 
697
- export const removePendingWrite = async (builder, writeId, revert) => {
698
- await awaitStore();
699
- const { projectUrl, dbUrl, dbName } = builder;
700
- const pendingData = grab(CacheStore.PendingWrites, [projectUrl, writeId]);
723
+ const revertChanges = async (builder, pendingData) => {
701
724
  const { io } = Scoped.ReleaseCacheData;
702
-
703
- if (!pendingData) return;
725
+ const { projectUrl, dbUrl, dbName } = builder;
704
726
  const pathChanges = new Set([]);
705
727
 
706
- if (revert) {
707
- await Promise.all(pendingData.editions.map(async ([access_id, [b4Doc, afDoc], path]) => {
708
- if (io) {
709
- RevertMutation(grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]));
710
- } else {
711
- await useFS(builder, access_id, 'database')(async fs => {
712
- const colObj = await fs.find(LIMITER_DATA(path), access_id, ['value'])
713
- .then(v => DatastoreParser.decode(v.value))
714
- .catch(() => null);
715
- if (!colObj) return;
716
- RevertMutation(colObj);
717
- await fs.set(LIMITER_DATA(path), access_id, {
718
- value: DatastoreParser.encode(colObj),
719
- touched: Date.now(),
720
- size: colObj.size
721
- });
728
+ await Promise.all(pendingData.map(async ([access_id, [b4Doc, afDoc], path]) => {
729
+ if (io) {
730
+ RevertMutation(grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]));
731
+ } else {
732
+ await useFS(builder, access_id, 'database')(async fs => {
733
+ const colObj = await fs.find(LIMITER_DATA(path), access_id, ['value'])
734
+ .then(v => DatastoreParser.decode(v.value))
735
+ .catch(() => null);
736
+ if (!colObj) return;
737
+ RevertMutation(colObj);
738
+ await fs.set(LIMITER_DATA(path), access_id, {
739
+ value: DatastoreParser.encode(colObj),
740
+ touched: Date.now(),
741
+ size: colObj.size
722
742
  });
723
- }
743
+ });
744
+ }
724
745
 
725
- function RevertMutation(colObj) {
726
- const colList = colObj?.data;
746
+ function RevertMutation(colObj) {
747
+ const colList = colObj?.data;
727
748
 
728
- const updateSize = (b4, af) => {
729
- const offset = docSize(af) - docSize(b4);
730
- colObj.size += offset;
731
- incrementDatabaseSize(builder, path, offset);
732
- }
749
+ const updateSize = (b4, af) => {
750
+ const offset = docSize(af) - docSize(b4);
751
+ colObj.size += offset;
752
+ incrementDatabaseSize(builder, path, offset);
753
+ }
733
754
 
734
- if (colList) {
735
- if (afDoc) {
736
- const editedIndex = colList.findIndex(e => CompareBson.equal(e._id, afDoc._id));
737
- if (editedIndex !== -1) {
738
- if (
739
- serializeToBase64(afDoc) === serializeToBase64(colList[editedIndex])
740
- ) {
741
- if (b4Doc) {
742
- colList[editedIndex] = b4Doc;
743
- updateSize(afDoc, b4Doc);
744
- } else {
745
- colList.splice(editedIndex, 1);
746
- updateSize(afDoc, undefined);
747
- }
755
+ if (colList) {
756
+ if (afDoc) {
757
+ const editedIndex = colList.findIndex(e => CompareBson.equal(e._id, afDoc._id));
758
+ if (editedIndex !== -1) {
759
+ if (
760
+ serializeToBase64(afDoc) === serializeToBase64(colList[editedIndex])
761
+ ) {
762
+ if (b4Doc) {
763
+ colList[editedIndex] = b4Doc;
764
+ updateSize(afDoc, b4Doc);
765
+ } else {
766
+ colList.splice(editedIndex, 1);
767
+ updateSize(afDoc, undefined);
748
768
  }
749
769
  }
750
- } else if (
751
- b4Doc &&
752
- colList.findIndex(e => CompareBson.equal(e._id, b4Doc._id)) === -1
753
- ) {
754
- colList.push(b4Doc);
755
- updateSize(undefined, b4Doc);
756
770
  }
771
+ } else if (
772
+ b4Doc &&
773
+ colList.findIndex(e => CompareBson.equal(e._id, b4Doc._id)) === -1
774
+ ) {
775
+ colList.push(b4Doc);
776
+ updateSize(undefined, b4Doc);
757
777
  }
758
- pathChanges.add(path);
759
778
  }
760
- }));
761
- }
779
+ pathChanges.add(path);
780
+ }
781
+ }));
762
782
 
763
- unpoke(CacheStore.PendingWrites, [projectUrl, writeId]);
764
- updateCacheStore(['PendingWrites', 'DatabaseStore', 'DatabaseStats']);
765
- notifyDatabaseNodeChanges(builder, [...pathChanges]);
766
- };
783
+ return [...pendingData];
784
+ }
767
785
 
768
786
  const notifyDatabaseNodeChanges = (builder, changedCollections = []) => {
769
787
  const { projectUrl, dbName, dbUrl } = builder;
770
788
 
771
789
  changedCollections.forEach(path => {
772
- const nodeID = `${projectUrl}${dbName}${dbUrl}${path}`;
790
+ const nodeID = `${projectUrl}_${dbName}_${dbUrl}_${path}`;
773
791
  Object.entries(Scoped.ActiveDatabaseListeners[nodeID] || {})
774
792
  .sort((a, b) => a[1] - b[1])
775
793
  .forEach(([processId]) => {
@@ -1,4 +1,4 @@
1
- import { cloneDeep } from "lodash";
1
+ import cloneDeep from "lodash/cloneDeep";
2
2
  import { deserialize, serialize } from "../../vendor/bson";
3
3
  import { Buffer } from "buffer";
4
4
 
@@ -721,44 +721,47 @@ const commitData = async (builder, value, type, config) => {
721
721
  return (await sendValue());
722
722
  };
723
723
 
724
- export const trySendPendingWrite = (projectUrl) => {
724
+ export const trySendPendingWrite = async (projectUrl) => {
725
725
  if (Scoped.dispatchingWritesPromise[projectUrl]) return;
726
726
 
727
+ let resolveCallback;
727
728
  Scoped.dispatchingWritesPromise[projectUrl] = new Promise(async resolve => {
728
- const sortedWrite = Object.entries(CacheStore.PendingWrites[projectUrl] || {})
729
- .filter(([k]) => !Scoped.OutgoingWrites[k])
730
- .sort((a, b) => a[1].addedOn - b[1].addedOn);
731
- let resolveCounts = 0;
732
-
733
- for (const [writeId, { snapshot, builder, attempts = 1 }] of sortedWrite) {
734
- try {
735
- await commitData(
736
- { ...Scoped.InitializedProject[projectUrl], ...builder, find: deserializeBSON(builder.find, true)._ },
737
- deserializeBSON(snapshot.value, true)._,
738
- snapshot.type,
739
- { ...snapshot.config, delivery: DELIVERY.NO_CACHE_NO_AWAIT }
740
- );
729
+ resolveCallback = resolve;
730
+ });
731
+
732
+ const sortedWrite = Object.entries(CacheStore.PendingWrites[projectUrl] || {})
733
+ .filter(([k]) => !Scoped.OutgoingWrites[k])
734
+ .sort((a, b) => a[1].addedOn - b[1].addedOn);
735
+ let resolveCounts = 0;
741
736
 
737
+ for (const [writeId, { snapshot, builder, attempts = 1 }] of sortedWrite) {
738
+ try {
739
+ await commitData(
740
+ { ...Scoped.InitializedProject[projectUrl], ...builder, find: deserializeBSON(builder.find, true)._ },
741
+ deserializeBSON(snapshot.value, true)._,
742
+ snapshot.type,
743
+ { ...snapshot.config, delivery: DELIVERY.NO_CACHE_NO_AWAIT }
744
+ );
745
+
746
+ delete CacheStore.PendingWrites[projectUrl][writeId];
747
+ ++resolveCounts;
748
+ } catch (err) {
749
+ const { maxRetries } = builder;
750
+ if (err?.ack || !maxRetries || attempts >= maxRetries) {
742
751
  delete CacheStore.PendingWrites[projectUrl][writeId];
743
752
  ++resolveCounts;
744
- } catch (err) {
745
- const { maxRetries } = builder;
746
- if (err?.ack || !maxRetries || attempts >= maxRetries) {
747
- delete CacheStore.PendingWrites[projectUrl][writeId];
748
- ++resolveCounts;
749
- } else if (CacheStore.PendingWrites[projectUrl]?.[writeId]) {
750
- CacheStore.PendingWrites[projectUrl][writeId].attempts = attempts + 1;
751
- }
753
+ } else if (CacheStore.PendingWrites[projectUrl]?.[writeId]) {
754
+ CacheStore.PendingWrites[projectUrl][writeId].attempts = attempts + 1;
752
755
  }
753
756
  }
754
- resolve();
755
- if (projectUrl in Scoped.dispatchingWritesPromise)
756
- delete Scoped.dispatchingWritesPromise[projectUrl];
757
- updateCacheStore(['PendingWrites']);
758
-
759
- if (
760
- (sortedWrite.length - resolveCounts) &&
761
- await getReachableServer(projectUrl)
762
- ) trySendPendingWrite(projectUrl);
763
- });
757
+ }
758
+ resolveCallback();
759
+ if (Scoped.dispatchingWritesPromise[projectUrl])
760
+ delete Scoped.dispatchingWritesPromise[projectUrl];
761
+ updateCacheStore(['PendingWrites']);
762
+
763
+ if (
764
+ (sortedWrite.length - resolveCounts) &&
765
+ await getReachableServer(projectUrl)
766
+ ) trySendPendingWrite(projectUrl);
764
767
  };
@@ -1,4 +1,4 @@
1
- import { guardObject, GuardSignal, niceGuard } from "guard-object";
1
+ import { niceGuard } from "guard-object";
2
2
 
3
3
  export const TIMESTAMP = { $timestamp: "now" };
4
4
  export const TIMESTAMP_OFFSET = (v) => ({ $timestamp_offset: v });
@@ -12,17 +12,13 @@ export const GEO_JSON = (lat, lng) => ({
12
12
  coordinates: [lng, lat],
13
13
  });
14
14
 
15
- export const FIND_GEO_JSON = (location, offSetMeters, centerMeters) => {
16
- guardObject(GuardSignal.COORDINATE.LAT_LNG_INT).validate(location);
17
-
18
- return {
19
- $nearSphere: {
20
- $geometry: {
21
- type: "Point",
22
- coordinates: location.slice(0).reverse()
23
- },
24
- $minDistance: centerMeters || 0,
25
- $maxDistance: offSetMeters
26
- }
27
- };
28
- };
15
+ export const FIND_GEO_JSON = (location, offSetMeters, centerMeters) => ({
16
+ $nearSphere: {
17
+ $geometry: {
18
+ type: "Point",
19
+ coordinates: location.slice(0).reverse()
20
+ },
21
+ $minDistance: centerMeters || 0,
22
+ $maxDistance: offSetMeters
23
+ }
24
+ });
@@ -40,6 +40,7 @@ export const getFetchResources = async (projectUrl, access_id) => {
40
40
  if (io) {
41
41
  const record = CacheStore.FetchedStore[projectUrl]?.[access_id];
42
42
  if (record) record.touched = Date.now();
43
+ updateCacheStore(['FetchedStore']);
43
44
  return record && cloneDeep(record?.data);
44
45
  }
45
46
 
@@ -11,9 +11,9 @@ import { serialize } from "entity-serializer";
11
11
  import { getFetchResources, insertFetchResources } from "./accessor";
12
12
 
13
13
  const buildFetchData = (data, extras) => {
14
- const { ok, type, status, statusText, redirected, url, headers, size, base64 } = data;
14
+ const { ok, type, status, statusText, redirected, url, headers, size, buffer } = data;
15
15
 
16
- const response = new Response(Buffer.from(base64, 'base64'), {
16
+ const response = new Response(buffer, {
17
17
  headers: new Headers(headers),
18
18
  status,
19
19
  statusText,
@@ -146,7 +146,7 @@ export const mfetch = async (input = '', init, config) => {
146
146
  credentials: 'omit',
147
147
  ...init,
148
148
  ...uglified ? { body: reqBuilder } : encodeBody ? { body: serialize(body) } : {},
149
- // cache: 'no-cache',
149
+ cache: 'no-cache',
150
150
  headers: {
151
151
  ...extraHeaders,
152
152
  ...rawHeader,
@@ -165,12 +165,12 @@ export const mfetch = async (input = '', init, config) => {
165
165
 
166
166
  if (!isLink && simple) throw { simpleError: JSON.parse(simple) };
167
167
 
168
- const base64 = uglified ?
169
- Buffer.from(await deserializeE2E(await f.arrayBuffer(), serverE2E_PublicKey, privateKey)).toString('base64') :
170
- Buffer.from(await f.arrayBuffer()).toString('base64');
168
+ const buffer = uglified ?
169
+ Buffer.from(await deserializeE2E(await f.arrayBuffer(), serverE2E_PublicKey, privateKey)) :
170
+ Buffer.from(await f.arrayBuffer());
171
171
 
172
172
  const resObj = {
173
- base64,
173
+ buffer,
174
174
  type,
175
175
  status,
176
176
  statusText,