Skip to content

Commit 79410d3

Browse files
authored
ADD error on bailout (#4272)
* ADD error on bailout * REPLACE fast-deep-equal because of epoberezkin/fast-deep-equal#105 * REPLACE object-path * UPDATE event-reduce
1 parent 3356260 commit 79410d3

File tree

15 files changed

+455
-56
lines changed

15 files changed

+455
-56
lines changed

config/webpack.config.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,20 @@ const TerserPlugin = require('terser-webpack-plugin');
33
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
44

55

6-
//console.log(process.env.NODE_ENV);
7-
//process.exit();
6+
/**
7+
* Throw on bailouts.
8+
* If a dependency is causing a bailout,
9+
* it must be replaced!
10+
*/
11+
const oldConsoleLog = console.log.bind(console);
12+
console.log = function (m1, m2, m3) {
13+
if (m1.includes('not an ECMAScript module')) {
14+
oldConsoleLog(m1);
15+
throw new Error('ERROR: A dependency of RxDB is causing an optimization bailout. This is not allowed.');
16+
} else {
17+
return oldConsoleLog(m1, m2, m3);
18+
}
19+
};
820

921

1022
const plugins = [];
@@ -30,6 +42,6 @@ module.exports = {
3042
* @link https://webpack.js.org/plugins/module-concatenation-plugin/#debugging-optimization-bailouts
3143
*/
3244
optimizationBailout: true,
33-
warnings: false
45+
warnings: true
3446
}
3547
};

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,6 @@
383383
"@types/cors": "2.8.13",
384384
"@types/express": "4.17.15",
385385
"@types/lokijs": "1.5.7",
386-
"@types/object-path": "0.11.1",
387386
"@types/simple-peer": "9.11.5",
388387
"@types/ws": "8.5.4",
389388
"ajv": "8.12.0",
@@ -393,8 +392,7 @@
393392
"crypto-js": "4.1.1",
394393
"custom-idle-queue": "3.0.1",
395394
"dexie": "4.0.0-alpha.4",
396-
"event-reduce-js": "2.0.4",
397-
"fast-deep-equal": "3.1.3",
395+
"event-reduce-js": "2.1.0",
398396
"firebase": "9.15.0",
399397
"get-graphql-from-jsonschema": "8.1.0",
400398
"graphql": "15.8.0",
@@ -406,7 +404,6 @@
406404
"lokijs": "1.5.12",
407405
"mingo": "6.2.5",
408406
"modifyjs": "0.3.1",
409-
"object-path": "0.11.8",
410407
"oblivious-set": "1.1.1",
411408
"pouchdb-selector-core": "7.3.1",
412409
"reconnecting-websocket": "4.4.0",

src/plugins/crdt/index.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { newRxError } from '../../rx-error';
2-
import objectPath from 'object-path';
32
import type {
43
CRDTDocumentField,
54
CRDTEntry,
@@ -19,8 +18,10 @@ import {
1918
clone,
2019
deepEqual,
2120
ensureNotFalsy,
21+
getProperty,
2222
now,
2323
objectPathMonad,
24+
setProperty,
2425
toArray
2526
} from '../../plugins/utils';
2627
import modifyjs from 'modifyjs';
@@ -50,7 +51,7 @@ export async function updateCRDT<RxDocType>(
5051
const storageToken = await this.collection.database.storageToken;
5152

5253
return this.incrementalModify((docData) => {
53-
const crdtDocField: CRDTDocumentField<RxDocType> = clone(objectPath.get(docData as any, crdtOptions.field));
54+
const crdtDocField: CRDTDocumentField<RxDocType> = clone(getProperty(docData as any, crdtOptions.field));
5455
const operation: CRDTOperation<RxDocType> = {
5556
body: toArray(entry),
5657
creator: storageToken,
@@ -71,7 +72,7 @@ export async function updateCRDT<RxDocType>(
7172
docData,
7273
operation
7374
);
74-
objectPath.set(docData, crdtOptions.field, crdtDocField);
75+
setProperty(docData, crdtOptions.field, crdtDocField);
7576
return docData;
7677
}, RX_CRDT_CONTEXT);
7778
}
@@ -109,7 +110,7 @@ export async function insertCRDT<RxDocType>(
109110
operations: [],
110111
hash: ''
111112
};
112-
objectPath.set(insertData as any, crdtOptions.field, crdtDocField);
113+
setProperty(insertData as any, crdtOptions.field, crdtDocField);
113114

114115
const lastAr: CRDTOperation<RxDocType>[] = [operation];
115116
crdtDocField.operations.push(lastAr);
@@ -288,7 +289,7 @@ export function rebuildFromCRDT<RxDocType>(
288289
let base: WithDeleted<RxDocType> = {
289290
_deleted: false
290291
} as any;
291-
objectPath.set(base, ensureNotFalsy(schema.crdt).field, crdts);
292+
setProperty(base, ensureNotFalsy(schema.crdt).field, crdts);
292293
crdts.operations.forEach(operations => {
293294
operations.forEach(op => {
294295
base = runOperationOnDocument(
@@ -502,7 +503,7 @@ export const RxDBcrdtPlugin: RxPlugin = {
502503
hash: ''
503504
};
504505
crdtOperations.hash = hashCRDTOperations(collection.database.hashFunction, crdtOperations);
505-
objectPath.set(docData, crdtOptions.field, crdtOperations);
506+
setProperty(docData, crdtOptions.field, crdtOperations);
506507
return docData;
507508
});
508509
return bulkInsertBefore(useDocsData);

src/plugins/dev-mode/check-schema.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
* does additional checks over the schema-json
33
* to ensure nothing is broken or not supported
44
*/
5-
6-
import objectPath from 'object-path';
75
import {
86
newRxError
97
} from '../../rx-error';
@@ -16,7 +14,7 @@ import type {
1614
TopLevelProperty
1715
} from '../../types';
1816
import {
19-
flattenObject, isMaybeReadonlyArray,
17+
flattenObject, getProperty, isMaybeReadonlyArray,
2018
trimDots
2119
} from '../../plugins/utils';
2220
import { rxDocumentProperties } from './entity-properties';
@@ -458,8 +456,8 @@ export function checkSchema(jsonSchema: RxJsonSchema<any>) {
458456
.filter(key => key !== '')
459457
.filter((elem, pos, arr) => arr.indexOf(elem) === pos) // unique
460458
.filter(key => { // check if this path defines an index
461-
const value = objectPath.get(jsonSchema, key);
462-
return !!value.index;
459+
const value = getProperty(jsonSchema, key);
460+
return value && !!value.index;
463461
})
464462
.forEach(key => { // replace inner properties
465463
key = key.replace('properties.', ''); // first
@@ -483,7 +481,7 @@ export function checkSchema(jsonSchema: RxJsonSchema<any>) {
483481
.filter((elem, pos, arr) => arr.indexOf(elem) === pos) // from now on working only with unique indexes
484482
.map(indexPath => {
485483
const realPath = getSchemaPropertyRealPath(indexPath); // real path in the collection schema
486-
const schemaObj = objectPath.get(jsonSchema, realPath); // get the schema of the indexed property
484+
const schemaObj = getProperty(jsonSchema, realPath); // get the schema of the indexed property
487485
if (!schemaObj || typeof schemaObj !== 'object') {
488486
throw newRxError('SC21', {
489487
index: indexPath,
@@ -524,8 +522,8 @@ export function checkSchema(jsonSchema: RxJsonSchema<any>) {
524522
.filter((elem, pos, arr) => arr.indexOf(elem) === pos) // unique
525523
.filter(key => {
526524
// check if this path defines an encrypted field
527-
const value = objectPath.get(jsonSchema, key);
528-
return !!value.encrypted;
525+
const value = getProperty(jsonSchema, key);
526+
return value && !!value.encrypted;
529527
})
530528
.forEach(key => { // replace inner properties
531529
key = key.replace('properties.', ''); // first
@@ -543,7 +541,7 @@ export function checkSchema(jsonSchema: RxJsonSchema<any>) {
543541
// real path in the collection schema
544542
const realPath = getSchemaPropertyRealPath(propPath);
545543
// get the schema of the indexed property
546-
const schemaObj = objectPath.get(jsonSchema, realPath);
544+
const schemaObj = getProperty(jsonSchema, realPath);
547545
if (!schemaObj || typeof schemaObj !== 'object') {
548546
throw newRxError('SC28', {
549547
field: propPath,

src/plugins/encryption/index.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
import AES from 'crypto-js/aes';
77
import * as cryptoEnc from 'crypto-js/enc-utf8';
8-
import objectPath from 'object-path';
98
import { wrapRxStorageInstance } from '../../plugin-helpers';
109
import {
1110
INTERNAL_STORE_SCHEMA_TITLE
@@ -26,7 +25,9 @@ import {
2625
b64EncodeUnicode,
2726
clone,
2827
ensureNotFalsy,
29-
flatClone
28+
flatClone,
29+
getProperty,
30+
setProperty
3031
} from '../../plugins/utils';
3132

3233
export const MINIMUM_PASSWORD_LENGTH: 8 = 8;
@@ -121,14 +122,14 @@ export function wrappedKeyEncryptionStorage<Internals, InstanceCreationOptions>(
121122
docData = cloneWithoutAttachments(docData);
122123
ensureNotFalsy(params.schema.encrypted)
123124
.forEach(path => {
124-
const value = objectPath.get(docData, path);
125+
const value = getProperty(docData, path);
125126
if (typeof value === 'undefined') {
126127
return;
127128
}
128129

129130
const stringValue = JSON.stringify(value);
130131
const encrypted = encryptString(stringValue, password);
131-
objectPath.set(docData, path, encrypted);
132+
setProperty(docData, path, encrypted);
132133
});
133134

134135
// handle attachments
@@ -153,13 +154,13 @@ export function wrappedKeyEncryptionStorage<Internals, InstanceCreationOptions>(
153154
docData = cloneWithoutAttachments(docData);
154155
ensureNotFalsy(params.schema.encrypted)
155156
.forEach(path => {
156-
const value = objectPath.get(docData, path);
157+
const value = getProperty(docData, path);
157158
if (typeof value === 'undefined') {
158159
return;
159160
}
160161
const decrypted = decryptString(value, password);
161162
const decryptedParsed = JSON.parse(decrypted);
162-
objectPath.set(docData, path, decryptedParsed);
163+
setProperty(docData, path, decryptedParsed);
163164
});
164165
return docData;
165166
}

src/plugins/local-documents/rx-local-document.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import objectPath from 'object-path';
21
import { Observable } from 'rxjs';
32
import {
43
distinctUntilChanged,
@@ -34,6 +33,7 @@ import {
3433
getDefaultRxDocumentMeta,
3534
getFromMapOrThrow,
3635
getFromObjectOrThrow,
36+
getProperty,
3737
RXJS_SHARE_REPLAY_DEFAULTS
3838
} from '../../plugins/utils';
3939
import { getLocalDocStateByParent, LOCAL_DOC_STATE_BY_PARENT_RESOLVED } from './local-documents-helper';
@@ -100,7 +100,7 @@ const RxLocalDocumentPrototype: any = {
100100
});
101101
}
102102

103-
let valueObj = objectPath.get(this._data, objPath);
103+
let valueObj = getProperty(this._data, objPath);
104104
valueObj = overwritable.deepFreezeWhenDevMode(valueObj);
105105
return valueObj;
106106
},
@@ -119,7 +119,7 @@ const RxLocalDocumentPrototype: any = {
119119
}
120120
return this.$
121121
.pipe(
122-
map(data => objectPath.get(data, objPath)),
122+
map(data => getProperty(data, objPath)),
123123
distinctUntilChanged()
124124
);
125125
},

src/plugins/replication-graphql/index.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
* this plugin adds the RxCollection.syncGraphQl()-function to rxdb
33
* you can use it to sync collections with a remote graphql endpoint.
44
*/
5-
import objectPath from 'object-path';
65
import {
76
ensureNotFalsy,
8-
fastUnsecureHash
7+
fastUnsecureHash,
8+
getProperty
99
} from '../../plugins/utils';
1010

1111
import {
@@ -127,10 +127,8 @@ export function replicateGraphQL<RxDocType, CheckpointType>(
127127
if (result.errors) {
128128
throw result.errors;
129129
}
130-
131130
const dataPath = pull.dataPath || ['data', Object.keys(result.data)[0]];
132-
let data: any = objectPath.get(result, dataPath);
133-
131+
let data: any = getProperty(result, dataPath);
134132
if (pull.responseModifier) {
135133
data = await pull.responseModifier(
136134
data,
@@ -165,7 +163,7 @@ export function replicateGraphQL<RxDocType, CheckpointType>(
165163
throw result.errors;
166164
}
167165
const dataPath = Object.keys(result.data)[0];
168-
const data: any = objectPath.get(result.data, dataPath);
166+
const data: any = getProperty(result.data, dataPath);
169167
return data;
170168
},
171169
batchSize: push.batchSize,

src/plugins/storage-lokijs/lokijs-helper.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ import {
1515
add as unloadAdd,
1616
AddReturn
1717
} from 'unload';
18-
import { ensureNotFalsy, flatClone, promiseWait, randomCouchString } from '../utils';
18+
import { ensureNotFalsy, flatClone, getProperty, promiseWait, randomCouchString } from '../utils';
1919
import { LokiSaveQueue } from './loki-save-queue';
2020
import type { DeterministicSortComparator } from 'event-reduce-js';
2121
import { newRxError } from '../../rx-error';
22-
import objectPath from 'object-path';
2322
import {
2423
LeaderElector,
2524
OnMessageHandler
@@ -225,8 +224,8 @@ export function getLokiSortComparator<RxDocType>(
225224
const fieldName: string = Object.keys(sortPart)[0];
226225
const direction: MangoQuerySortDirection = Object.values(sortPart)[0];
227226
const directionMultiplier = direction === 'asc' ? 1 : -1;
228-
const valueA: any = objectPath.get(a as any, fieldName);
229-
const valueB: any = objectPath.get(b as any, fieldName);
227+
const valueA: any = getProperty(a as any, fieldName);
228+
const valueB: any = getProperty(b as any, fieldName);
230229
if (valueA === valueB) {
231230
return false;
232231
} else {

src/plugins/utils/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export * from './utils-document';
66
export * from './utils-hash';
77
export * from './utils-promise';
88
export * from './utils-string';
9+
export * from './utils-object-deep-equal';
10+
export * from './utils-object-dot-prop';
911
export * from './utils-object';
1012
export * from './utils-error';
1113
export * from './utils-time';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
/**
3+
* Copied from the fast-deep-equal package
4+
* because it does not support es modules and causes optimization bailouts.
5+
* TODO use the npm package again when this is merged:
6+
* @link https://github.com/epoberezkin/fast-deep-equal/pull/105
7+
*/
8+
export function deepEqual(a: any, b: any): boolean {
9+
if (a === b) return true;
10+
11+
if (a && b && typeof a == 'object' && typeof b == 'object') {
12+
if (a.constructor !== b.constructor) return false;
13+
14+
let length;
15+
let i;
16+
if (Array.isArray(a)) {
17+
length = a.length;
18+
if (length !== b.length) return false;
19+
for (i = length; i-- !== 0;)
20+
if (!deepEqual(a[i], b[i])) return false;
21+
return true;
22+
}
23+
24+
25+
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
26+
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
27+
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
28+
29+
const keys = Object.keys(a);
30+
length = keys.length;
31+
if (length !== Object.keys(b).length) return false;
32+
33+
for (i = length; i-- !== 0;)
34+
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
35+
36+
for (i = length; i-- !== 0;) {
37+
const key = keys[i];
38+
if (!deepEqual(a[key], b[key])) return false;
39+
}
40+
41+
return true;
42+
}
43+
44+
// true if both NaN, false otherwise
45+
return a !== a && b !== b;
46+
}

0 commit comments

Comments
 (0)