react-native-mosquito-transport 0.0.34 → 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 +3 -3
- package/src/helpers/fs_manager.js +6 -6
- package/src/helpers/peripherals.js +3 -3
- package/src/helpers/purger.js +5 -5
- package/src/helpers/utils.js +2 -7
- package/src/helpers/values.js +1 -1
- package/src/helpers/variables.js +2 -9
- package/src/index.js +1 -1
- package/src/products/auth/index.js +1 -1
- package/src/products/database/accessor.js +97 -53
- package/src/products/database/bson.js +1 -1
- package/src/products/database/counter.js +5 -6
- package/src/products/database/index.js +22 -11
- package/src/products/database/types.js +16 -11
- package/src/products/database/validator.js +5 -5
- package/src/products/http_callable/counter.js +3 -4
- package/src/vendor/bson.d.ts +1723 -0
- package/src/vendor/bson.js +4650 -0
- package/src/vendor/encoder.js +37 -0
- package/src/vendor/utf8-validator.js +60 -0
- package/src/vendor/utf8-validator.test.js +35 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-mosquito-transport",
|
|
3
|
-
"version": "0.0.
|
|
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",
|
|
@@ -44,4 +44,4 @@
|
|
|
44
44
|
"react-native-get-random-values": "*",
|
|
45
45
|
"react-native-sha256": "*"
|
|
46
46
|
}
|
|
47
|
-
}
|
|
47
|
+
}
|
|
@@ -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.
|
|
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.
|
|
32
|
-
delete Scoped.
|
|
31
|
+
if (Scoped.linearFsProcess[node][nodeId] === thisPromise)
|
|
32
|
+
delete Scoped.linearFsProcess[node][nodeId];
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
Scoped.
|
|
36
|
+
Scoped.linearFsProcess[node][nodeId] = thisPromise;
|
|
37
37
|
return (await thisPromise);
|
|
38
38
|
};
|
|
39
39
|
|
|
@@ -56,14 +56,14 @@ export const getSystem = (builder) => {
|
|
|
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 FileSystem.readFile(joinPath(path, node)
|
|
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
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
|
|
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];
|
|
@@ -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 =
|
|
63
|
-
right =
|
|
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
|
});
|
package/src/helpers/purger.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
93
|
+
unpoke(data.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', access_id, `${limit}`]);
|
|
94
94
|
} else {
|
|
95
|
-
|
|
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
|
-
|
|
125
|
+
unpoke(data.FetchedStore, [projectUrl, access_id]);
|
|
126
126
|
});
|
|
127
127
|
console.log('fetcher purging complete');
|
|
128
128
|
}
|
package/src/helpers/utils.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
};
|
package/src/helpers/values.js
CHANGED
|
@@ -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'
|
package/src/helpers/variables.js
CHANGED
|
@@ -20,21 +20,14 @@ export const Scoped = {
|
|
|
20
20
|
/**
|
|
21
21
|
* @type {Promise<any> | undefined}
|
|
22
22
|
*/
|
|
23
|
-
dispatchingWritesPromise:
|
|
24
|
-
|
|
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 "
|
|
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
|
-
|
|
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
|
-
|
|
54
|
+
poke(CacheStore.DatabaseStats.counters, [projectUrl, dbUrl, dbName, path], true);
|
|
57
55
|
});
|
|
58
56
|
updateCacheStore(['DatabaseStats']);
|
|
59
57
|
}
|
|
@@ -64,7 +62,7 @@ export const getCountQuery = async (builder, access_id) => {
|
|
|
64
62
|
const { io } = Scoped.ReleaseCacheData;
|
|
65
63
|
|
|
66
64
|
if (io) {
|
|
67
|
-
const data =
|
|
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 {
|
|
@@ -134,8 +132,8 @@ export const insertRecord = async (builder, config, accessIdWithoutLimit, value,
|
|
|
134
132
|
return;
|
|
135
133
|
}
|
|
136
134
|
|
|
137
|
-
const instanceData =
|
|
138
|
-
const resultData =
|
|
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}`]);
|
|
139
137
|
const isEpisode = episode === 1 || !!resultData;
|
|
140
138
|
|
|
141
139
|
const editionSizeOffset = thisSize - (instanceData?.size || 0);
|
|
@@ -157,8 +155,8 @@ export const insertRecord = async (builder, config, accessIdWithoutLimit, value,
|
|
|
157
155
|
|
|
158
156
|
incrementDatabaseSize(builder, path, editionSizeOffset + resultSizeOffset);
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
if (isEpisode)
|
|
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));
|
|
162
160
|
updateCacheStore(['DatabaseStore', 'DatabaseStats']);
|
|
163
161
|
};
|
|
164
162
|
|
|
@@ -221,7 +219,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
|
|
|
221
219
|
}
|
|
222
220
|
|
|
223
221
|
if (isEpisode) {
|
|
224
|
-
const resultData =
|
|
222
|
+
const resultData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`]);
|
|
225
223
|
if (resultData) {
|
|
226
224
|
resultData.touched = Date.now();
|
|
227
225
|
return [cloneDeep(resultData.data)];
|
|
@@ -229,7 +227,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
|
|
|
229
227
|
return null;
|
|
230
228
|
}
|
|
231
229
|
|
|
232
|
-
const instanceData =
|
|
230
|
+
const instanceData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit]);
|
|
233
231
|
if (!instanceData) return null;
|
|
234
232
|
const { latest_limiter, data } = instanceData;
|
|
235
233
|
|
|
@@ -389,19 +387,20 @@ export const addPendingWrites = async (builder, writeId, result) => {
|
|
|
389
387
|
const pathChanges = new Set([]);
|
|
390
388
|
const pendingSnapshot = cloneDeep(result);
|
|
391
389
|
|
|
392
|
-
|
|
390
|
+
const linearWrite =
|
|
393
391
|
result.type === 'batchWrite' ?
|
|
394
392
|
result.value.map(({ scope, value, find, path }) =>
|
|
395
393
|
({ type: scope, value, find, path })
|
|
396
394
|
)
|
|
397
|
-
: [{ ...result, path: builder.path }]
|
|
398
|
-
|
|
395
|
+
: [{ ...result, find: builder.find, path: builder.path }];
|
|
396
|
+
|
|
397
|
+
await Promise.all(linearWrite.map(async ({ value: writeObj, find, type, path }) => {
|
|
399
398
|
WriteValidator[type]({ find, value: writeObj });
|
|
400
399
|
validateCollectionName(path);
|
|
401
400
|
pathChanges.add(path);
|
|
402
401
|
|
|
403
402
|
if (io) {
|
|
404
|
-
const colObj =
|
|
403
|
+
const colObj = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance']);
|
|
405
404
|
|
|
406
405
|
if (colObj)
|
|
407
406
|
await Promise.all(
|
|
@@ -410,7 +409,7 @@ export const addPendingWrites = async (builder, writeId, result) => {
|
|
|
410
409
|
e,
|
|
411
410
|
path =>
|
|
412
411
|
Object.values(
|
|
413
|
-
|
|
412
|
+
grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance'], {})
|
|
414
413
|
).map(({ data }) => data).flat()
|
|
415
414
|
)
|
|
416
415
|
)
|
|
@@ -640,12 +639,57 @@ export const addPendingWrites = async (builder, writeId, result) => {
|
|
|
640
639
|
};
|
|
641
640
|
}));
|
|
642
641
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
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
|
+
}));
|
|
649
693
|
|
|
650
694
|
updateCacheStore(['DatabaseStore', 'PendingWrites', 'DatabaseStats']);
|
|
651
695
|
notifyDatabaseNodeChanges(builder, [...pathChanges]);
|
|
@@ -654,7 +698,7 @@ export const addPendingWrites = async (builder, writeId, result) => {
|
|
|
654
698
|
export const removePendingWrite = async (builder, writeId, revert) => {
|
|
655
699
|
await awaitStore();
|
|
656
700
|
const { projectUrl, dbUrl, dbName } = builder;
|
|
657
|
-
const pendingData =
|
|
701
|
+
const pendingData = grab(CacheStore.PendingWrites, [projectUrl, writeId]);
|
|
658
702
|
const { io } = Scoped.ReleaseCacheData;
|
|
659
703
|
|
|
660
704
|
if (!pendingData) return;
|
|
@@ -663,11 +707,11 @@ export const removePendingWrite = async (builder, writeId, revert) => {
|
|
|
663
707
|
if (revert) {
|
|
664
708
|
await Promise.all(pendingData.editions.map(async ([access_id, [b4Doc, afDoc], path]) => {
|
|
665
709
|
if (io) {
|
|
666
|
-
RevertMutation(
|
|
710
|
+
RevertMutation(grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', access_id]));
|
|
667
711
|
} else {
|
|
668
712
|
await useFS(builder, access_id, 'database')(async fs => {
|
|
669
713
|
const colObj = await fs.find(LIMITER_DATA(path), access_id, ['value'])
|
|
670
|
-
.then(v => deserializeBSON(v.value))
|
|
714
|
+
.then(v => deserializeBSON(v.value, true))
|
|
671
715
|
.catch(() => null);
|
|
672
716
|
if (!colObj) return;
|
|
673
717
|
RevertMutation(colObj);
|
|
@@ -717,7 +761,7 @@ export const removePendingWrite = async (builder, writeId, revert) => {
|
|
|
717
761
|
}));
|
|
718
762
|
}
|
|
719
763
|
|
|
720
|
-
|
|
764
|
+
unpoke(CacheStore.PendingWrites, [projectUrl, writeId]);
|
|
721
765
|
updateCacheStore(['PendingWrites', 'DatabaseStore', 'DatabaseStats']);
|
|
722
766
|
notifyDatabaseNodeChanges(builder, [...pathChanges]);
|
|
723
767
|
};
|
|
@@ -768,19 +812,19 @@ const snipDocument = (data, find, config) => {
|
|
|
768
812
|
if (returnOnly) {
|
|
769
813
|
output = {};
|
|
770
814
|
(Array.isArray(returnOnly) ? returnOnly : [returnOnly]).filter(v => v).forEach(e => {
|
|
771
|
-
const thisData =
|
|
772
|
-
if (thisData)
|
|
815
|
+
const thisData = grab(data, e);
|
|
816
|
+
if (thisData) poke(output, e, thisData);
|
|
773
817
|
});
|
|
774
818
|
} else if (excludeFields) {
|
|
775
819
|
(Array.isArray(excludeFields) ? excludeFields : [excludeFields]).filter(v => v).forEach(e => {
|
|
776
|
-
if (
|
|
820
|
+
if (grab(data, e) && e !== '_id') unpoke(output, e);
|
|
777
821
|
});
|
|
778
822
|
}
|
|
779
823
|
|
|
780
824
|
getFindFields(find).forEach(field => {
|
|
781
|
-
if (!
|
|
782
|
-
const mainData =
|
|
783
|
-
if (mainData !== undefined)
|
|
825
|
+
if (!grab(output, field)) {
|
|
826
|
+
const mainData = grab(data, field);
|
|
827
|
+
if (mainData !== undefined) poke(output, field, mainData);
|
|
784
828
|
}
|
|
785
829
|
});
|
|
786
830
|
|
|
@@ -850,10 +894,10 @@ const AtomicWriter = {
|
|
|
850
894
|
!isDate &&
|
|
851
895
|
!isTimestamp
|
|
852
896
|
) throw `invalid value at $currentDate.${field}, expected any of boolean (true), { $type: "timestamp" } or { $type: "date" } but got ${value}`;
|
|
853
|
-
|
|
897
|
+
poke(object, field, isDate ? new Date() : new Timestamp({ t: Math.floor(Date.now() / 1000), i: 0 }));
|
|
854
898
|
},
|
|
855
899
|
$inc: (field, value, object) => {
|
|
856
|
-
const current =
|
|
900
|
+
const current = grab(object, field);
|
|
857
901
|
if (current === null) {
|
|
858
902
|
console.warn(`cannot use $inc operator on a null value at ${field}`);
|
|
859
903
|
return;
|
|
@@ -863,29 +907,29 @@ const AtomicWriter = {
|
|
|
863
907
|
|
|
864
908
|
if (!Validator.NUMBER(castedValue)) throw `expected a number at $inc.${field} but got ${value}`;
|
|
865
909
|
|
|
866
|
-
|
|
910
|
+
poke(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent + castedValue, current) : value);
|
|
867
911
|
},
|
|
868
912
|
$min: (field, value, object) => {
|
|
869
|
-
const current =
|
|
913
|
+
const current = grab(object, field);
|
|
870
914
|
if (CompareBson.lesser(value, current)) {
|
|
871
|
-
|
|
915
|
+
poke(object, field, value);
|
|
872
916
|
}
|
|
873
917
|
},
|
|
874
918
|
$max: (field, value, object) => {
|
|
875
|
-
const current =
|
|
919
|
+
const current = grab(object, field);
|
|
876
920
|
if (CompareBson.greater(value, current)) {
|
|
877
|
-
|
|
921
|
+
poke(object, field, value);
|
|
878
922
|
}
|
|
879
923
|
},
|
|
880
924
|
$mul: (field, value, object) => {
|
|
881
|
-
const current =
|
|
925
|
+
const current = grab(object, field);
|
|
882
926
|
const castedValue = downcastBSON(value);
|
|
883
927
|
const castedCurrent = downcastBSON(current);
|
|
884
928
|
|
|
885
929
|
if (!Validator.NUMBER(castedValue))
|
|
886
930
|
throw `expected a number at $mul.${field} but got ${value}`;
|
|
887
931
|
|
|
888
|
-
|
|
932
|
+
poke(object, field, Validator.NUMBER(castedCurrent) ? defaultBSON(castedCurrent * castedValue, value) : 0);
|
|
889
933
|
},
|
|
890
934
|
$rename: (field, value, object) => {
|
|
891
935
|
if (!Validator.EMPTY_STRING(value))
|
|
@@ -903,7 +947,7 @@ const AtomicWriter = {
|
|
|
903
947
|
if (!e) throw `empty node for ${field}`;
|
|
904
948
|
});
|
|
905
949
|
const [tipObj, tipSource, tipDest] = destStage.length === 1 ? [object, field, value]
|
|
906
|
-
: [
|
|
950
|
+
: [grab(object, destStage.slice(0, -1).join('.')), sourceStage.slice(-1)[0], destStage.slice(-1)[0]];
|
|
907
951
|
|
|
908
952
|
if (tipObj && tipSource in tipObj) {
|
|
909
953
|
tipObj[tipDest] = cloneDeep(tipObj[tipSource]);
|
|
@@ -911,16 +955,16 @@ const AtomicWriter = {
|
|
|
911
955
|
}
|
|
912
956
|
},
|
|
913
957
|
$set: (field, value, object) => {
|
|
914
|
-
|
|
958
|
+
poke(object, field, value === undefined ? null : value);
|
|
915
959
|
},
|
|
916
960
|
$setOnInsert: (field, value, object, isNew) => {
|
|
917
961
|
if (isNew) AtomicWriter.$set(field, value, object);
|
|
918
962
|
},
|
|
919
963
|
$unset: (field, _, object) => {
|
|
920
|
-
|
|
964
|
+
unpoke(object, field);
|
|
921
965
|
},
|
|
922
966
|
$addToSet: (field, value, object) => {
|
|
923
|
-
const current =
|
|
967
|
+
const current = grab(object, field);
|
|
924
968
|
if (Array.isArray(current)) {
|
|
925
969
|
if (
|
|
926
970
|
Validator.OBJECT(value) &&
|
|
@@ -942,7 +986,7 @@ const AtomicWriter = {
|
|
|
942
986
|
},
|
|
943
987
|
$pop: (field, value, object) => {
|
|
944
988
|
if (![1, -1].includes(value)) throw `expected 1 or -1 at "$pop.${field}" but got ${value}`;
|
|
945
|
-
const current =
|
|
989
|
+
const current = grab(object, field);
|
|
946
990
|
if (
|
|
947
991
|
Array.isArray(current) &&
|
|
948
992
|
current.length
|
|
@@ -950,7 +994,7 @@ const AtomicWriter = {
|
|
|
950
994
|
},
|
|
951
995
|
$pull: (field, value, object) => {
|
|
952
996
|
// TODO: issues
|
|
953
|
-
const current =
|
|
997
|
+
const current = grab(object, field);
|
|
954
998
|
const isQueryObject = Validator.OBJECT(value);
|
|
955
999
|
|
|
956
1000
|
if (
|
|
@@ -972,11 +1016,11 @@ const AtomicWriter = {
|
|
|
972
1016
|
} catch (_) { }
|
|
973
1017
|
return true;
|
|
974
1018
|
});
|
|
975
|
-
|
|
1019
|
+
poke(object, field, remainingCurrent);
|
|
976
1020
|
}
|
|
977
1021
|
},
|
|
978
1022
|
$push: (field, value, object) => {
|
|
979
|
-
const current =
|
|
1023
|
+
const current = grab(object, field);
|
|
980
1024
|
|
|
981
1025
|
if (Array.isArray(current)) {
|
|
982
1026
|
if (Validator.OBJECT(value)) {
|
|
@@ -1023,13 +1067,13 @@ const AtomicWriter = {
|
|
|
1023
1067
|
if (!Array.isArray(value))
|
|
1024
1068
|
throw `expected an array at $pullAll.${field}`;
|
|
1025
1069
|
|
|
1026
|
-
const current =
|
|
1070
|
+
const current = grab(object, field);
|
|
1027
1071
|
|
|
1028
1072
|
if (Array.isArray(current)) {
|
|
1029
1073
|
const remainingCurrent = current.filter(v =>
|
|
1030
1074
|
!value.some(k => CompareBson.equal(v, k))
|
|
1031
1075
|
);
|
|
1032
|
-
|
|
1076
|
+
poke(object, field, remainingCurrent);
|
|
1033
1077
|
}
|
|
1034
1078
|
}
|
|
1035
1079
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import getLodash from "lodash/get";
|
|
2
|
-
import setLodash from 'lodash/set';
|
|
3
1
|
import { CacheStore } from "../../helpers/variables";
|
|
4
|
-
import {
|
|
2
|
+
import { grab, poke } from "poke-object";
|
|
3
|
+
import { calculateObjectSize } from '../../vendor/bson';
|
|
5
4
|
|
|
6
5
|
export const incrementDatabaseSize = (builder, path, size) => incrementDatabaseSizeCore(CacheStore.DatabaseStats, builder, path, size);
|
|
7
6
|
|
|
@@ -11,8 +10,8 @@ export const incrementDatabaseSizeCore = (baseObj, builder, path, size = 0) => {
|
|
|
11
10
|
|
|
12
11
|
const node = [projectUrl, dbUrl, dbName, path];
|
|
13
12
|
|
|
14
|
-
const b4 =
|
|
15
|
-
|
|
13
|
+
const b4 = grab(baseObj.database, node, 0);
|
|
14
|
+
poke(baseObj.database, node, b4 + size);
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export const docSize = doc => doc ?
|
|
17
|
+
export const docSize = doc => doc ? calculateObjectSize({ _: doc }) : 0;
|