react-native-mosquito-transport 0.0.38 → 0.0.39
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/TODO +1 -0
- package/package.json +1 -2
- package/src/helpers/basic_clone.js +212 -0
- package/src/helpers/utils.js +4 -5
- package/src/index.js +3 -3
- package/src/products/auth/accessor.js +4 -4
- package/src/products/auth/index.js +5 -5
- package/src/products/database/accessor.js +21 -21
- package/src/products/database/bson.js +3 -3
- package/src/products/database/index.js +19 -8
- package/src/products/http_callable/accessor.js +3 -3
- package/src/products/http_callable/index.js +11 -12
package/TODO
CHANGED
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.39",
|
|
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",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
"buffer": "^6.0.3",
|
|
32
32
|
"entity-serializer": "^1.0.3",
|
|
33
33
|
"guard-object": "^1.1.4",
|
|
34
|
-
"lodash": "^4.17.21",
|
|
35
34
|
"poke-object": "^1.0.1",
|
|
36
35
|
"simplify-error": "^1.0.1",
|
|
37
36
|
"socket.io-client": "^4.8.1",
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
import { Validator } from "guard-object";
|
|
3
|
+
import { BSONError, BSONOffsetError, BSONRegExp, BSONRuntimeError, BSONSymbol, BSONValue, BSONVersionError, Binary, Code, DBRef, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp, UUID } from '../vendor/bson';
|
|
4
|
+
|
|
5
|
+
const ErrorInstances = [
|
|
6
|
+
niceReturn(() => ReferenceError),
|
|
7
|
+
niceReturn(() => SyntaxError),
|
|
8
|
+
niceReturn(() => RangeError),
|
|
9
|
+
niceReturn(() => TypeError),
|
|
10
|
+
niceReturn(() => EvalError),
|
|
11
|
+
Error
|
|
12
|
+
].filter(v => v);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @template T
|
|
16
|
+
* @param {T} obj
|
|
17
|
+
* @returns {T}
|
|
18
|
+
*/
|
|
19
|
+
export function basicClone(obj) {
|
|
20
|
+
if ([NaN, undefined, Infinity, null].includes(obj)) {
|
|
21
|
+
return obj;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof obj === 'bigint')
|
|
25
|
+
return BigInt(obj);
|
|
26
|
+
|
|
27
|
+
if (
|
|
28
|
+
['number', 'string', 'boolean', 'function'].includes(typeof obj) ||
|
|
29
|
+
obj instanceof Promise
|
|
30
|
+
) return obj;
|
|
31
|
+
|
|
32
|
+
for (const e of [Date, RegExp]) {
|
|
33
|
+
if (isDirectInstance(obj, e))
|
|
34
|
+
return new e(obj);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isDirectInstance(obj, ArrayBuffer))
|
|
38
|
+
return obj.slice(0);
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
typeof SharedArrayBuffer !== 'undefined' &&
|
|
42
|
+
isDirectInstance(obj, SharedArrayBuffer)
|
|
43
|
+
) return obj.slice(0);
|
|
44
|
+
|
|
45
|
+
if (Buffer.isBuffer(obj)) return Buffer.from(obj);
|
|
46
|
+
|
|
47
|
+
for (const instance of ErrorInstances) {
|
|
48
|
+
if (isDirectInstance(obj, instance)) {
|
|
49
|
+
const n = new instance(obj.message);
|
|
50
|
+
n.stack = obj.stack;
|
|
51
|
+
// n.name = obj.name;
|
|
52
|
+
return n;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const e of [Map, Set]) {
|
|
57
|
+
if (isDirectInstance(obj, e))
|
|
58
|
+
return new e([...obj].map(basicClone));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (
|
|
62
|
+
const e of
|
|
63
|
+
[
|
|
64
|
+
Int8Array,
|
|
65
|
+
Uint8Array,
|
|
66
|
+
Uint8ClampedArray,
|
|
67
|
+
Int16Array,
|
|
68
|
+
Uint16Array,
|
|
69
|
+
Int32Array,
|
|
70
|
+
Uint32Array,
|
|
71
|
+
Float32Array,
|
|
72
|
+
Float64Array,
|
|
73
|
+
BigInt64Array,
|
|
74
|
+
BigUint64Array
|
|
75
|
+
]
|
|
76
|
+
) {
|
|
77
|
+
if (isDirectInstance(obj, e))
|
|
78
|
+
return new e(Buffer.from(obj));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isDirectInstance(obj, BSONOffsetError)) {
|
|
82
|
+
const n = new BSONOffsetError(obj.message, obj.offset);
|
|
83
|
+
// n.name = obj.name;
|
|
84
|
+
n.stack = obj.stack;
|
|
85
|
+
return n;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (
|
|
89
|
+
const instance of
|
|
90
|
+
[
|
|
91
|
+
BSONRuntimeError,
|
|
92
|
+
BSONVersionError,
|
|
93
|
+
BSONError
|
|
94
|
+
]
|
|
95
|
+
) {
|
|
96
|
+
if (isDirectInstance(obj, instance)) {
|
|
97
|
+
const n = new instance(obj.message);
|
|
98
|
+
n.stack = obj.stack;
|
|
99
|
+
// n.name = obj.name;
|
|
100
|
+
return n;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (
|
|
105
|
+
typeof Response !== 'undefined' &&
|
|
106
|
+
isDirectInstance(obj, Response)
|
|
107
|
+
) return obj.clone();
|
|
108
|
+
|
|
109
|
+
if (
|
|
110
|
+
typeof Headers !== 'undefined' &&
|
|
111
|
+
isDirectInstance(obj, Headers)
|
|
112
|
+
) return new Headers(obj);
|
|
113
|
+
|
|
114
|
+
if (
|
|
115
|
+
typeof Blob !== 'undefined' &&
|
|
116
|
+
isDirectInstance(obj, Blob)
|
|
117
|
+
) return obj.slice(0, obj.size, obj.type);
|
|
118
|
+
|
|
119
|
+
if (isDirectInstance(obj, BSONRegExp))
|
|
120
|
+
return new BSONRegExp(obj.pattern, obj.options);
|
|
121
|
+
|
|
122
|
+
if (isDirectInstance(obj, BSONSymbol))
|
|
123
|
+
return new BSONSymbol(obj.value);
|
|
124
|
+
|
|
125
|
+
if (isDirectInstance(obj, Binary))
|
|
126
|
+
return new Binary(obj.buffer, obj.sub_type);
|
|
127
|
+
|
|
128
|
+
if (isDirectInstance(obj, Code))
|
|
129
|
+
return new Code(obj.code, obj.scope);
|
|
130
|
+
|
|
131
|
+
if (isDirectInstance(obj, DBRef))
|
|
132
|
+
return new DBRef(obj.collection, obj.oid, obj.db, obj.fields);
|
|
133
|
+
|
|
134
|
+
if (isDirectInstance(obj, Decimal128))
|
|
135
|
+
return new Decimal128(obj.bytes);
|
|
136
|
+
|
|
137
|
+
if (isDirectInstance(obj, Double))
|
|
138
|
+
return new Double(obj.value);
|
|
139
|
+
|
|
140
|
+
if (isDirectInstance(obj, Int32))
|
|
141
|
+
return new Int32(obj.value);
|
|
142
|
+
|
|
143
|
+
if (isDirectInstance(obj, Long))
|
|
144
|
+
return new Long(obj.low, obj.high, obj.unsigned);
|
|
145
|
+
|
|
146
|
+
if (isDirectInstance(obj, Timestamp))
|
|
147
|
+
return new Timestamp({ t: obj.t, i: obj.i });
|
|
148
|
+
|
|
149
|
+
if (isDirectInstance(obj, MaxKey))
|
|
150
|
+
return new MaxKey();
|
|
151
|
+
|
|
152
|
+
if (isDirectInstance(obj, MinKey))
|
|
153
|
+
return new MinKey();
|
|
154
|
+
|
|
155
|
+
if (isDirectInstance(obj, ObjectId))
|
|
156
|
+
return new ObjectId(obj.id);
|
|
157
|
+
|
|
158
|
+
if (isDirectInstance(obj, UUID)) return new UUID(obj);
|
|
159
|
+
|
|
160
|
+
if (isDirectInstance(obj, BSONValue)) return obj;
|
|
161
|
+
|
|
162
|
+
if (Validator.ARRAY(obj))
|
|
163
|
+
return [...obj.map(basicClone)];
|
|
164
|
+
|
|
165
|
+
if (Validator.OBJECT(obj)) {
|
|
166
|
+
const newObj = {};
|
|
167
|
+
|
|
168
|
+
for (const key in obj) {
|
|
169
|
+
if (obj.hasOwnProperty(key)) {
|
|
170
|
+
newObj[key] = basicClone(obj[key]);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return newObj;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (ArrayBuffer.isView(obj)) return Buffer.from(obj);
|
|
178
|
+
|
|
179
|
+
if (obj instanceof Error) {
|
|
180
|
+
// general errors
|
|
181
|
+
try {
|
|
182
|
+
const n = new obj.constructor(obj.message);
|
|
183
|
+
n.stack = obj.stack;
|
|
184
|
+
return n;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
const n = new Error(obj.message);
|
|
187
|
+
n.stack = obj.stack;
|
|
188
|
+
try {
|
|
189
|
+
n.name = obj.name;
|
|
190
|
+
} catch (_) { }
|
|
191
|
+
return n;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
throw `${obj} cannot be cloned`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @template T
|
|
200
|
+
* @param {unknown} obj
|
|
201
|
+
* @param {new (...args: any[]) => T} Class
|
|
202
|
+
* @returns {obj is T}
|
|
203
|
+
*/
|
|
204
|
+
function isDirectInstance(obj, Class) {
|
|
205
|
+
return typeof obj === "object" && obj !== null && obj.constructor === Class;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function niceReturn(func) {
|
|
209
|
+
try {
|
|
210
|
+
return func();
|
|
211
|
+
} catch (_) { }
|
|
212
|
+
}
|
package/src/helpers/utils.js
CHANGED
|
@@ -5,15 +5,15 @@ import { DatastoreParser } from "../products/database/bson";
|
|
|
5
5
|
import { deserialize } from "entity-serializer";
|
|
6
6
|
import { breakDbMap, purgeRedundantRecords } from "./purger";
|
|
7
7
|
import { FS_PATH, getSystem } from "./fs_manager";
|
|
8
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
9
8
|
import { Buffer } from "buffer";
|
|
9
|
+
import { basicClone } from "./basic_clone";
|
|
10
10
|
|
|
11
11
|
const { FILE_NAME, TABLE_NAME } = FS_PATH;
|
|
12
12
|
|
|
13
13
|
const CacheKeys = Object.keys(CacheStore);
|
|
14
14
|
|
|
15
15
|
const prefillDatastore = (obj, caller) => {
|
|
16
|
-
obj =
|
|
16
|
+
obj = basicClone(obj);
|
|
17
17
|
breakDbMap(obj, (_projectUrl, _dbUrl, _dbName, _path, value) => {
|
|
18
18
|
Object.entries(value.instance).forEach(([access_id, obj]) => {
|
|
19
19
|
value.instance[access_id] = caller(obj);
|
|
@@ -28,7 +28,7 @@ const prefillDatastore = (obj, caller) => {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
const prefillFetcher = (store, encode) => {
|
|
31
|
-
store =
|
|
31
|
+
store = basicClone(store);
|
|
32
32
|
Object.values(store).forEach(accessIdObj => {
|
|
33
33
|
Object.values(accessIdObj).forEach(value => {
|
|
34
34
|
value.data.buffer = encode ?
|
|
@@ -54,7 +54,7 @@ export const updateCacheStore = async (node) => {
|
|
|
54
54
|
} = CacheStore;
|
|
55
55
|
|
|
56
56
|
const minimizePendingWrite = () => {
|
|
57
|
-
const obj =
|
|
57
|
+
const obj = basicClone(PendingWrites);
|
|
58
58
|
Object.values(obj).forEach(e => {
|
|
59
59
|
Object.values(e).forEach(b => {
|
|
60
60
|
if ('editions' in b) delete b.editions;
|
|
@@ -187,7 +187,6 @@ export const buildFetchInterface = async ({ body, authToken, method, uglify, ser
|
|
|
187
187
|
|
|
188
188
|
return [{
|
|
189
189
|
body: uglify ? plate : body,
|
|
190
|
-
// cache: 'no-cache',
|
|
191
190
|
headers: {
|
|
192
191
|
...extraHeaders,
|
|
193
192
|
'Content-type': uglify ? 'request/buffer' : 'application/json',
|
package/src/index.js
CHANGED
|
@@ -12,10 +12,10 @@ import { io } from "socket.io-client";
|
|
|
12
12
|
import { AUTH_PROVIDER_ID } from "./helpers/values";
|
|
13
13
|
import EngineApi from './helpers/engine_api';
|
|
14
14
|
import { Validator } from 'guard-object';
|
|
15
|
-
import cloneDeep from 'lodash/cloneDeep';
|
|
16
15
|
import { Buffer } from 'buffer';
|
|
17
16
|
import MTAuth, { purgePendingToken } from './products/auth';
|
|
18
17
|
import { BSON } from "./vendor/bson";
|
|
18
|
+
import { basicClone } from './helpers/basic_clone';
|
|
19
19
|
|
|
20
20
|
const {
|
|
21
21
|
_listenCollection,
|
|
@@ -58,7 +58,7 @@ class RNMT {
|
|
|
58
58
|
throw `initializeCache must be called before creating any ${this.constructor.name} instance`;
|
|
59
59
|
|
|
60
60
|
if (!Scoped.InitializedProject[projectUrl]) {
|
|
61
|
-
Scoped.InitializedProject[projectUrl] =
|
|
61
|
+
Scoped.InitializedProject[projectUrl] = basicClone(this.config);
|
|
62
62
|
Scoped.LastTokenRefreshRef[projectUrl] = 0;
|
|
63
63
|
triggerAuthToken(projectUrl);
|
|
64
64
|
initTokenRefresher({ ...this.config }, true);
|
|
@@ -95,7 +95,7 @@ class RNMT {
|
|
|
95
95
|
|
|
96
96
|
const manualCheckConnection = () => {
|
|
97
97
|
const ref = ++connectionIte;
|
|
98
|
-
fetch(_areYouOk(projectUrl), {
|
|
98
|
+
fetch(_areYouOk(projectUrl), { credentials: 'omit' }).then(async r => {
|
|
99
99
|
if ((await r.json()).status === 'yes') {
|
|
100
100
|
if (ref === connectionIte) onConnect();
|
|
101
101
|
} else throw null;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
2
1
|
import { doSignOut, revokeAuthIntance } from ".";
|
|
3
2
|
import EngineApi from "../../helpers/engine_api";
|
|
4
3
|
import { AuthTokenListener, TokenRefreshListener } from "../../helpers/listeners";
|
|
@@ -7,6 +6,7 @@ import { awaitStore, buildFetchInterface, buildFetchResult, getPrefferTime, upda
|
|
|
7
6
|
import { CacheStore, Scoped } from "../../helpers/variables";
|
|
8
7
|
import { simplifyError } from "simplify-error";
|
|
9
8
|
import { Validator } from "guard-object";
|
|
9
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
10
10
|
|
|
11
11
|
export const listenToken = (callback, projectUrl) =>
|
|
12
12
|
AuthTokenListener.listenTo(projectUrl, (t, n) => {
|
|
@@ -40,10 +40,10 @@ export const injectEmulatedAuth = async (config, emulatedURL) => {
|
|
|
40
40
|
|
|
41
41
|
if (emulatedURL === projectUrl) throw `auth instance for ${emulatedURL} cannot emulate itself`;
|
|
42
42
|
if (depended) throw `Chain Emulation Error: this auth instance (${projectUrl}) cannot be emulated as other auth instance (${depended[0]}) is already emulating it`;
|
|
43
|
-
const thisAuthStore =
|
|
43
|
+
const thisAuthStore = basicClone(CacheStore.AuthStore[projectUrl]);
|
|
44
44
|
revokeAuthIntance(config, thisAuthStore);
|
|
45
45
|
|
|
46
|
-
CacheStore.AuthStore[projectUrl] =
|
|
46
|
+
CacheStore.AuthStore[projectUrl] = basicClone(CacheStore.AuthStore[emulatedURL]);
|
|
47
47
|
Scoped.AuthJWTToken[projectUrl] = token;
|
|
48
48
|
CacheStore.EmulatedAuth[projectUrl] = emulatedURL;
|
|
49
49
|
|
|
@@ -155,7 +155,7 @@ const refreshToken = (builder, processRef, remainRetries = 1, isForceRefresh) =>
|
|
|
155
155
|
if (isForceRefresh) Scoped.InitiatedForcedToken[projectUrl] = true;
|
|
156
156
|
|
|
157
157
|
getEmulatedLinks(projectUrl).forEach(v => {
|
|
158
|
-
CacheStore.AuthStore[v] =
|
|
158
|
+
CacheStore.AuthStore[v] = basicClone(CacheStore.AuthStore[projectUrl]);
|
|
159
159
|
Scoped.AuthJWTToken[v] = f.result.token;
|
|
160
160
|
|
|
161
161
|
triggerAuthToken(v, isInit);
|
|
@@ -6,7 +6,7 @@ import { CacheStore, Scoped } from "../../helpers/variables";
|
|
|
6
6
|
import { awaitRefreshToken, getEmulatedLinks, initTokenRefresher, injectEmulatedAuth, injectFreshToken, listenToken, parseToken, triggerAuthToken } from "./accessor";
|
|
7
7
|
import { deserializeE2E, encodeBinary, serializeE2E } from "../../helpers/peripherals";
|
|
8
8
|
import { simplifyCaughtError, simplifyError } from "simplify-error";
|
|
9
|
-
import
|
|
9
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
_listenUserVerification,
|
|
@@ -171,7 +171,7 @@ const doCustomSignin = (builder, email, password) => new Promise(async (resolve,
|
|
|
171
171
|
|
|
172
172
|
try {
|
|
173
173
|
await awaitStore();
|
|
174
|
-
const thisAuthStore =
|
|
174
|
+
const thisAuthStore = basicClone(CacheStore.AuthStore[projectUrl]);
|
|
175
175
|
|
|
176
176
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
177
177
|
body: { data: `${encodeBinary(email)}.${encodeBinary(password)}` },
|
|
@@ -201,7 +201,7 @@ const doCustomSignup = (builder, email, password, name, metadata) => new Promise
|
|
|
201
201
|
|
|
202
202
|
try {
|
|
203
203
|
await awaitStore();
|
|
204
|
-
const thisAuthStore =
|
|
204
|
+
const thisAuthStore = basicClone(CacheStore.AuthStore[projectUrl]);
|
|
205
205
|
|
|
206
206
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
207
207
|
body: {
|
|
@@ -285,7 +285,7 @@ export const purgePendingToken = async (nodeId) => {
|
|
|
285
285
|
try {
|
|
286
286
|
let isConnected;
|
|
287
287
|
try {
|
|
288
|
-
isConnected = (await (await fetch(_areYouOk(projectUrl))).json(), {
|
|
288
|
+
isConnected = (await (await fetch(_areYouOk(projectUrl))).json(), { credentials: 'omit' }).status === 'yes';
|
|
289
289
|
} catch (_) { }
|
|
290
290
|
|
|
291
291
|
if (!isConnected)
|
|
@@ -312,7 +312,7 @@ const doGoogleSignin = (builder, token) => new Promise(async (resolve, reject) =
|
|
|
312
312
|
|
|
313
313
|
try {
|
|
314
314
|
await awaitStore();
|
|
315
|
-
const thisAuthStore =
|
|
315
|
+
const thisAuthStore = basicClone(CacheStore.AuthStore[projectUrl]);
|
|
316
316
|
|
|
317
317
|
const [reqBuilder, [privateKey]] = await buildFetchInterface({
|
|
318
318
|
body: { token },
|
|
@@ -3,7 +3,6 @@ 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
5
|
import { DatabaseRecordsListener } from "../../helpers/listeners";
|
|
6
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
7
6
|
import { BSONRegExp, ObjectId, Timestamp } from "../../vendor/bson";
|
|
8
7
|
import { niceGuard, Validator } from "guard-object";
|
|
9
8
|
import { TIMESTAMP } from "./types";
|
|
@@ -11,6 +10,7 @@ import { docSize, incrementDatabaseSize } from "./counter";
|
|
|
11
10
|
import { DatastoreParser, serializeToBase64 } from "./bson";
|
|
12
11
|
import { FS_PATH, getSystem, useFS } from "../../helpers/fs_manager";
|
|
13
12
|
import { grab, poke, unpoke } from "poke-object";
|
|
13
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
14
14
|
|
|
15
15
|
const { LIMITER_DATA, LIMITER_RESULT, DB_COUNT_QUERY } = FS_PATH;
|
|
16
16
|
|
|
@@ -77,9 +77,9 @@ export const getCountQuery = async (builder, access_id) => {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export const insertRecord = async (builder, config, accessIdWithoutLimit, value, episode = 0) => {
|
|
80
|
-
builder = builder &&
|
|
81
|
-
config = config &&
|
|
82
|
-
value = value &&
|
|
80
|
+
builder = builder && basicClone(builder);
|
|
81
|
+
config = config && basicClone(config);
|
|
82
|
+
value = value && basicClone(value);
|
|
83
83
|
|
|
84
84
|
await awaitStore();
|
|
85
85
|
const { io } = Scoped.ReleaseCacheData;
|
|
@@ -155,7 +155,7 @@ export const insertRecord = async (builder, config, accessIdWithoutLimit, value,
|
|
|
155
155
|
incrementDatabaseSize(builder, path, editionSizeOffset + resultSizeOffset);
|
|
156
156
|
|
|
157
157
|
poke(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'instance', accessIdWithoutLimit], newData);
|
|
158
|
-
if (isEpisode) poke(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`],
|
|
158
|
+
if (isEpisode) poke(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`], basicClone(newResultData));
|
|
159
159
|
updateCacheStore(['DatabaseStore', 'DatabaseStats']);
|
|
160
160
|
};
|
|
161
161
|
|
|
@@ -167,7 +167,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
|
|
|
167
167
|
const isEpisode = episode === 1;
|
|
168
168
|
|
|
169
169
|
const transformData = (data) => {
|
|
170
|
-
data =
|
|
170
|
+
data = basicClone(data);
|
|
171
171
|
if (random) {
|
|
172
172
|
data = shuffleArray(data);
|
|
173
173
|
} else if (sort) {
|
|
@@ -221,7 +221,7 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
|
|
|
221
221
|
const resultData = grab(CacheStore.DatabaseStore, [projectUrl, dbUrl, dbName, path, 'episode', accessIdWithoutLimit, `${limit}`]);
|
|
222
222
|
if (resultData) {
|
|
223
223
|
resultData.touched = Date.now();
|
|
224
|
-
return [
|
|
224
|
+
return [basicClone(resultData.data)];
|
|
225
225
|
}
|
|
226
226
|
return null;
|
|
227
227
|
}
|
|
@@ -242,8 +242,8 @@ export const getRecord = async (builder, accessIdWithoutLimit, episode = 0) => {
|
|
|
242
242
|
};
|
|
243
243
|
|
|
244
244
|
export const generateRecordID = (builder, config, removeLimit) => {
|
|
245
|
-
builder = builder &&
|
|
246
|
-
config = config &&
|
|
245
|
+
builder = builder && basicClone(builder);
|
|
246
|
+
config = config && basicClone(config);
|
|
247
247
|
|
|
248
248
|
const { command, path, countDoc } = builder;
|
|
249
249
|
const { extraction, excludeFields, returnOnly } = config || {};
|
|
@@ -269,7 +269,7 @@ export const generateRecordID = (builder, config, removeLimit) => {
|
|
|
269
269
|
};
|
|
270
270
|
|
|
271
271
|
const arrangeCommands = (c, removeLimit) => {
|
|
272
|
-
c =
|
|
272
|
+
c = basicClone(c);
|
|
273
273
|
const sortFind = f => {
|
|
274
274
|
['$and', '$or', '$nor'].forEach(n => {
|
|
275
275
|
if (f[n]) {
|
|
@@ -375,12 +375,12 @@ const WriteValidator = {
|
|
|
375
375
|
export const validateWriteValue = ({ type, find, value }) => WriteValidator[type]({ find, value, type });
|
|
376
376
|
|
|
377
377
|
export const addPendingWrites = async (builder, writeId, result) => {
|
|
378
|
-
builder = builder &&
|
|
379
|
-
result = result &&
|
|
378
|
+
builder = builder && basicClone(builder);
|
|
379
|
+
result = result && basicClone(result);
|
|
380
380
|
await awaitStore();
|
|
381
381
|
|
|
382
382
|
const { projectUrl } = builder;
|
|
383
|
-
const pendingSnapshot =
|
|
383
|
+
const pendingSnapshot = basicClone(result);
|
|
384
384
|
const { editions, linearWrite, pathChanges } = await syncCache(builder, result);
|
|
385
385
|
|
|
386
386
|
const isStaticWrite = !linearWrite.some(({ value, type }) => {
|
|
@@ -428,7 +428,7 @@ export const addPendingWrites = async (builder, writeId, result) => {
|
|
|
428
428
|
}
|
|
429
429
|
|
|
430
430
|
if (!wasShifted)
|
|
431
|
-
poke(CacheStore.PendingWrites, [projectUrl, writeId],
|
|
431
|
+
poke(CacheStore.PendingWrites, [projectUrl, writeId], basicClone({
|
|
432
432
|
builder: pureBuilder,
|
|
433
433
|
snapshot: pendingSnapshot,
|
|
434
434
|
editions,
|
|
@@ -453,7 +453,7 @@ const syncCache = async (builder, result) => {
|
|
|
453
453
|
)
|
|
454
454
|
: [{ ...result, find: builder.find, path: builder.path }];
|
|
455
455
|
|
|
456
|
-
const copiedWrite =
|
|
456
|
+
const copiedWrite = basicClone(linearWrite);
|
|
457
457
|
|
|
458
458
|
await Promise.all(linearWrite.map(async ({ value: writeObj, find, type, path }) => {
|
|
459
459
|
WriteValidator[type]({ find, value: writeObj });
|
|
@@ -506,7 +506,7 @@ const syncCache = async (builder, result) => {
|
|
|
506
506
|
const { extraction } = config || {};
|
|
507
507
|
|
|
508
508
|
const logChanges = (d) => {
|
|
509
|
-
editions.push(
|
|
509
|
+
editions.push(basicClone([entityId, d, path]));
|
|
510
510
|
const [b4, af] = d;
|
|
511
511
|
const offset = docSize(af) - docSize(b4);
|
|
512
512
|
dataObj.size += offset;
|
|
@@ -518,7 +518,7 @@ const syncCache = async (builder, result) => {
|
|
|
518
518
|
const accessExtraction = async obj => {
|
|
519
519
|
const buildAssignedExtraction = (data) => {
|
|
520
520
|
const d = (Array.isArray(extraction) ? extraction : [extraction]).map(thisExtraction => {
|
|
521
|
-
const query =
|
|
521
|
+
const query = basicClone(thisExtraction);
|
|
522
522
|
|
|
523
523
|
['find', 'findOne'].forEach(n => {
|
|
524
524
|
if (query[n])
|
|
@@ -570,7 +570,7 @@ const syncCache = async (builder, result) => {
|
|
|
570
570
|
return findOne ? scrapDocs[0] : scrapDocs;
|
|
571
571
|
}));
|
|
572
572
|
|
|
573
|
-
return
|
|
573
|
+
return basicClone(Array.isArray(extraction) ? scrapedProjection : scrapedProjection[0]);
|
|
574
574
|
}
|
|
575
575
|
|
|
576
576
|
if (['setOne', 'setMany'].includes(type)) {
|
|
@@ -582,7 +582,7 @@ const syncCache = async (builder, result) => {
|
|
|
582
582
|
|
|
583
583
|
if (instance_data.findIndex(v => CompareBson.equal(v._id, e._id)) === -1) {
|
|
584
584
|
const x = snipUpdate(obj);
|
|
585
|
-
instance_data.push(
|
|
585
|
+
instance_data.push(basicClone(x));
|
|
586
586
|
logChanges([undefined, x]);
|
|
587
587
|
} else if (!duplicateSets[e._id]) {
|
|
588
588
|
console.warn(`document with _id=${e._id} already exist locally with ${type}() operation, skipping to online commit`);
|
|
@@ -824,7 +824,7 @@ const snipDocument = (data, find, config) => {
|
|
|
824
824
|
if (!data || !config) return data;
|
|
825
825
|
const { returnOnly, excludeFields } = config || {};
|
|
826
826
|
|
|
827
|
-
let output =
|
|
827
|
+
let output = basicClone(data);
|
|
828
828
|
|
|
829
829
|
if (returnOnly) {
|
|
830
830
|
output = {};
|
|
@@ -967,7 +967,7 @@ const AtomicWriter = {
|
|
|
967
967
|
: [grab(object, destStage.slice(0, -1).join('.')), sourceStage.slice(-1)[0], destStage.slice(-1)[0]];
|
|
968
968
|
|
|
969
969
|
if (tipObj && tipSource in tipObj) {
|
|
970
|
-
tipObj[tipDest] =
|
|
970
|
+
tipObj[tipDest] = basicClone(tipObj[tipSource]);
|
|
971
971
|
delete tipObj[tipSource];
|
|
972
972
|
}
|
|
973
973
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
2
1
|
import { deserialize, serialize } from "../../vendor/bson";
|
|
3
2
|
import { Buffer } from "buffer";
|
|
3
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
4
4
|
|
|
5
5
|
export const deserializeBSON = (data, cast) => {
|
|
6
6
|
if (typeof data === 'string')
|
|
@@ -18,7 +18,7 @@ export const serializeToBase64 = doc => Buffer.from(serialize(doc)).toString('ba
|
|
|
18
18
|
|
|
19
19
|
export const DatastoreParser = {
|
|
20
20
|
encode: (obj) => {
|
|
21
|
-
obj =
|
|
21
|
+
obj = basicClone(obj);
|
|
22
22
|
const { command, config } = obj;
|
|
23
23
|
|
|
24
24
|
const serializeQuery = (e) =>
|
|
@@ -37,7 +37,7 @@ export const DatastoreParser = {
|
|
|
37
37
|
return obj;
|
|
38
38
|
},
|
|
39
39
|
decode: (obj, cast = true) => {
|
|
40
|
-
obj =
|
|
40
|
+
obj = basicClone(obj);
|
|
41
41
|
const { command, config } = obj;
|
|
42
42
|
|
|
43
43
|
const serializeQuery = (e) =>
|
|
@@ -11,8 +11,8 @@ import { DELIVERY, RETRIEVAL } from "../../helpers/values";
|
|
|
11
11
|
import { ObjectId } from "../../vendor/bson";
|
|
12
12
|
import { guardObject, Validator } from "guard-object";
|
|
13
13
|
import { simplifyCaughtError } from "simplify-error";
|
|
14
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
15
14
|
import { deserializeBSON, serializeToBase64 } from "./bson";
|
|
15
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
16
16
|
|
|
17
17
|
export class MTCollection {
|
|
18
18
|
constructor(config) {
|
|
@@ -136,6 +136,8 @@ const {
|
|
|
136
136
|
} = EngineApi;
|
|
137
137
|
|
|
138
138
|
const listenDocument = (callback, onError, builder, config) => {
|
|
139
|
+
builder = basicClone(builder);
|
|
140
|
+
config = basicClone(config);
|
|
139
141
|
const { projectUrl, wsPrefix, serverE2E_PublicKey, baseUrl, dbUrl, dbName, path, disableCache, command, uglify, extraHeaders, castBSON } = builder;
|
|
140
142
|
const { find, findOne, sort, direction, limit } = command;
|
|
141
143
|
const { disableAuth, episode } = config || {};
|
|
@@ -160,7 +162,7 @@ const listenDocument = (callback, onError, builder, config) => {
|
|
|
160
162
|
const thisSnapshotId = serializeToBase64({ _: s });
|
|
161
163
|
if (thisSnapshotId === lastSnapshot) return;
|
|
162
164
|
lastSnapshot = thisSnapshotId;
|
|
163
|
-
callback?.(
|
|
165
|
+
callback?.(basicClone(transformBSON(s, castBSON)));
|
|
164
166
|
};
|
|
165
167
|
|
|
166
168
|
if (shouldCache) {
|
|
@@ -255,6 +257,9 @@ const listenDocument = (callback, onError, builder, config) => {
|
|
|
255
257
|
};
|
|
256
258
|
|
|
257
259
|
const initOnDisconnectionTask = ({ builder, connectData, disconnectData }) => {
|
|
260
|
+
connectData = basicClone(connectData);
|
|
261
|
+
disconnectData = basicClone(disconnectData);
|
|
262
|
+
builder = basicClone(builder);
|
|
258
263
|
const { projectUrl, wsPrefix, baseUrl, serverE2E_PublicKey, dbUrl, dbName, extraHeaders, uglify } = builder;
|
|
259
264
|
const disableAuth = false;
|
|
260
265
|
|
|
@@ -344,6 +349,8 @@ const initOnDisconnectionTask = ({ builder, connectData, disconnectData }) => {
|
|
|
344
349
|
};
|
|
345
350
|
|
|
346
351
|
const countCollection = async (builder, config) => {
|
|
352
|
+
builder = basicClone(builder);
|
|
353
|
+
config = basicClone(config);
|
|
347
354
|
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, maxRetries = 1, uglify, extraHeaders, path, disableCache, command = {} } = builder;
|
|
348
355
|
const { find } = command;
|
|
349
356
|
const { disableAuth } = config || {};
|
|
@@ -445,10 +452,12 @@ const hydrateForeignDoc = ({ data, doc_holder }) => {
|
|
|
445
452
|
|
|
446
453
|
const transformBSON = (d, castBSON) => {
|
|
447
454
|
if (castBSON) return d && deserializeBSON(serializeToBase64({ _: d }), true)._;
|
|
448
|
-
return
|
|
455
|
+
return basicClone(d);
|
|
449
456
|
};
|
|
450
457
|
|
|
451
458
|
const findObject = async (builder, config) => {
|
|
459
|
+
builder = basicClone(builder);
|
|
460
|
+
config = basicClone(config);
|
|
452
461
|
const { projectUrl, serverE2E_PublicKey, dbUrl, dbName, maxRetries = 1, path, disableCache = false, uglify, extraHeaders, command, castBSON } = builder;
|
|
453
462
|
const pureConfig = stripRequestConfig(config);
|
|
454
463
|
validateFindObject(command);
|
|
@@ -476,8 +485,8 @@ const findObject = async (builder, config) => {
|
|
|
476
485
|
const res = (instantProcess && a) ? transformBSON(a[0] || undefined, castBSON) : a;
|
|
477
486
|
|
|
478
487
|
if (a) {
|
|
479
|
-
resolve(instantProcess ?
|
|
480
|
-
} else reject(instantProcess ?
|
|
488
|
+
resolve(instantProcess ? basicClone(res) : a);
|
|
489
|
+
} else reject(instantProcess ? basicClone(b) : b);
|
|
481
490
|
if (hasFinalize || !instantProcess) return;
|
|
482
491
|
hasFinalize = true;
|
|
483
492
|
|
|
@@ -498,8 +507,8 @@ const findObject = async (builder, config) => {
|
|
|
498
507
|
if (enableMinimizer) {
|
|
499
508
|
if (Scoped.PendingDbReadCollective[processAccessId]) {
|
|
500
509
|
Scoped.PendingDbReadCollective[processAccessId].push((a, b) => {
|
|
501
|
-
if (a) resolve(
|
|
502
|
-
else reject(
|
|
510
|
+
if (a) resolve(basicClone(a.result));
|
|
511
|
+
else reject(basicClone(b));
|
|
503
512
|
});
|
|
504
513
|
return;
|
|
505
514
|
}
|
|
@@ -596,7 +605,7 @@ const transformNullRecursively = obj => Object.fromEntries(
|
|
|
596
605
|
)
|
|
597
606
|
);
|
|
598
607
|
|
|
599
|
-
const cleanBatchWrite = (value) =>
|
|
608
|
+
const cleanBatchWrite = (value) => basicClone(value).map(v => {
|
|
600
609
|
if (Validator.OBJECT(v?.value)) {
|
|
601
610
|
v.value = transformNullRecursively(v.value);
|
|
602
611
|
} else if (Array.isArray(v?.value)) {
|
|
@@ -608,6 +617,8 @@ const cleanBatchWrite = (value) => cloneDeep(value).map(v => {
|
|
|
608
617
|
});
|
|
609
618
|
|
|
610
619
|
const commitData = async (builder, value, type, config) => {
|
|
620
|
+
builder = basicClone(builder);
|
|
621
|
+
config = basicClone(config);
|
|
611
622
|
// transform undefined
|
|
612
623
|
if (Validator.OBJECT(value)) {
|
|
613
624
|
value = value && deserializeBSON(serializeToBase64({ _: transformNullRecursively(value) }))._;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { updateCacheStore } from "../../helpers/utils";
|
|
2
2
|
import { CacheStore, Scoped } from "../../helpers/variables";
|
|
3
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
4
3
|
import { serialize } from "entity-serializer";
|
|
5
4
|
import { incrementFetcherSize } from "./counter";
|
|
6
5
|
import { FS_PATH, useFS } from "../../helpers/fs_manager";
|
|
6
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
7
7
|
|
|
8
8
|
const { FETCH_RESOURCES } = FS_PATH;
|
|
9
9
|
|
|
10
10
|
export const insertFetchResources = async (projectUrl, access_id, value) => {
|
|
11
|
-
value =
|
|
11
|
+
value = basicClone(value);
|
|
12
12
|
const dataSize = serialize(value).byteLength;
|
|
13
13
|
|
|
14
14
|
const { io } = Scoped.ReleaseCacheData;
|
|
@@ -41,7 +41,7 @@ export const getFetchResources = async (projectUrl, access_id) => {
|
|
|
41
41
|
const record = CacheStore.FetchedStore[projectUrl]?.[access_id];
|
|
42
42
|
if (record) record.touched = Date.now();
|
|
43
43
|
updateCacheStore(['FetchedStore']);
|
|
44
|
-
return record &&
|
|
44
|
+
return record && basicClone(record?.data);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const res = await useFS(FETCH_RESOURCES(projectUrl), access_id, 'httpFetch')(async fs => {
|
|
@@ -6,14 +6,14 @@ import { Scoped } from "../../helpers/variables";
|
|
|
6
6
|
import { awaitRefreshToken } from "../auth/accessor";
|
|
7
7
|
import { simplifyCaughtError } from "simplify-error";
|
|
8
8
|
import { guardObject, Validator } from "guard-object";
|
|
9
|
-
import cloneDeep from "lodash/cloneDeep";
|
|
10
9
|
import { serialize } from "entity-serializer";
|
|
11
10
|
import { getFetchResources, insertFetchResources } from "./accessor";
|
|
11
|
+
import { basicClone } from "../../helpers/basic_clone";
|
|
12
12
|
|
|
13
13
|
const buildFetchData = (data, extras) => {
|
|
14
14
|
const { ok, type, status, statusText, redirected, url, headers, size, buffer } = data;
|
|
15
15
|
|
|
16
|
-
const response = new Response(buffer, {
|
|
16
|
+
const response = new Response(Buffer.from(buffer), {
|
|
17
17
|
headers: new Headers(headers),
|
|
18
18
|
status,
|
|
19
19
|
statusText,
|
|
@@ -86,9 +86,9 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
86
86
|
const callFetch = () => new Promise(async (resolve, reject) => {
|
|
87
87
|
const retryProcess = ++retries;
|
|
88
88
|
|
|
89
|
-
const finalize = (a, b) => {
|
|
90
|
-
if (a) resolve(a);
|
|
91
|
-
else reject(b);
|
|
89
|
+
const finalize = (a, b, extras) => {
|
|
90
|
+
if (a) resolve(buildFetchData(a, extras));
|
|
91
|
+
else reject(basicClone(b));
|
|
92
92
|
if (hasFinalize || retryProcess !== 1) return;
|
|
93
93
|
hasFinalize = true;
|
|
94
94
|
|
|
@@ -99,14 +99,14 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
99
99
|
delete Scoped.PendingFetchCollective[processReqId];
|
|
100
100
|
|
|
101
101
|
resolutionList.forEach(e => {
|
|
102
|
-
e(a, b);
|
|
102
|
+
e(a && buildFetchData(a, extras), b && basicClone(b));
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
await awaitStore();
|
|
108
108
|
const resolveCache = (reqData) => {
|
|
109
|
-
finalize(
|
|
109
|
+
finalize(reqData, undefined, { fromCache: true });
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
try {
|
|
@@ -114,8 +114,8 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
114
114
|
if (enableMinimizer) {
|
|
115
115
|
if (Scoped.PendingFetchCollective[processReqId]) {
|
|
116
116
|
Scoped.PendingFetchCollective[processReqId].push((a, b) => {
|
|
117
|
-
if (a) resolve(
|
|
118
|
-
else reject(
|
|
117
|
+
if (a) resolve(a);
|
|
118
|
+
else reject(b);
|
|
119
119
|
});
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
@@ -142,11 +142,10 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
142
142
|
const [reqBuilder, [privateKey]] = uglified ? await serializeE2E(body, mtoken, serverE2E_PublicKey) : [null, []];
|
|
143
143
|
|
|
144
144
|
const f = await fetch(isLink ? input : `${projectUrl}/${normalizeRoute(input)}`, {
|
|
145
|
-
...
|
|
145
|
+
...hasBody ? { method: 'POST' } : {},
|
|
146
146
|
credentials: 'omit',
|
|
147
147
|
...init,
|
|
148
148
|
...uglified ? { body: reqBuilder } : encodeBody ? { body: serialize(body) } : {},
|
|
149
|
-
cache: 'no-cache',
|
|
150
149
|
headers: {
|
|
151
150
|
...extraHeaders,
|
|
152
151
|
...rawHeader,
|
|
@@ -185,7 +184,7 @@ export const mfetch = async (input = '', init, config) => {
|
|
|
185
184
|
|
|
186
185
|
if (shouldCache) insertFetchResources(projectUrl, reqId, resObj);
|
|
187
186
|
|
|
188
|
-
finalize(
|
|
187
|
+
finalize(resObj);
|
|
189
188
|
} catch (e) {
|
|
190
189
|
let thisRecord;
|
|
191
190
|
|