@lossless.org/client 0.1.0
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/.smartconfig.json +37 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.losslessorgclient.d.ts +32 -0
- package/dist_ts/classes.losslessorgclient.js +103 -0
- package/dist_ts/core/classes.error.d.ts +16 -0
- package/dist_ts/core/classes.error.js +29 -0
- package/dist_ts/core/classes.operation.d.ts +17 -0
- package/dist_ts/core/classes.operation.js +70 -0
- package/dist_ts/core/interfaces.d.ts +18 -0
- package/dist_ts/core/interfaces.js +2 -0
- package/dist_ts/index.d.ts +4 -0
- package/dist_ts/index.js +3 -0
- package/dist_ts/nosqldb/classes.atomicdelete.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicdelete.js +44 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +27 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +86 -0
- package/dist_ts/nosqldb/classes.atomicupdate.d.ts +26 -0
- package/dist_ts/nosqldb/classes.atomicupdate.js +55 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.d.ts +14 -0
- package/dist_ts/nosqldb/classes.bootstraprecord.js +80 -0
- package/dist_ts/nosqldb/classes.bsonassertion.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonassertion.js +29 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.d.ts +2 -0
- package/dist_ts/nosqldb/classes.bsonobjectid.js +50 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.d.ts +3 -0
- package/dist_ts/nosqldb/classes.bsonsnapshot.js +126 -0
- package/dist_ts/nosqldb/classes.cached-document.d.ts +27 -0
- package/dist_ts/nosqldb/classes.cached-document.js +112 -0
- package/dist_ts/nosqldb/classes.collection.d.ts +302 -0
- package/dist_ts/nosqldb/classes.collection.js +1568 -0
- package/dist_ts/nosqldb/classes.collectionfactory.d.ts +30 -0
- package/dist_ts/nosqldb/classes.collectionfactory.js +65 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.d.ts +4 -0
- package/dist_ts/nosqldb/classes.collectionlifecycle.js +15 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.d.ts +34 -0
- package/dist_ts/nosqldb/classes.collectionpreparation.js +134 -0
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +47 -0
- package/dist_ts/nosqldb/classes.collectiontopology.js +388 -0
- package/dist_ts/nosqldb/classes.connection.d.ts +18 -0
- package/dist_ts/nosqldb/classes.connection.js +23 -0
- package/dist_ts/nosqldb/classes.convenience.d.ts +1 -0
- package/dist_ts/nosqldb/classes.convenience.js +5 -0
- package/dist_ts/nosqldb/classes.cursor.d.ts +15 -0
- package/dist_ts/nosqldb/classes.cursor.js +82 -0
- package/dist_ts/nosqldb/classes.cursoroperation.d.ts +7 -0
- package/dist_ts/nosqldb/classes.cursoroperation.js +36 -0
- package/dist_ts/nosqldb/classes.db.d.ts +98 -0
- package/dist_ts/nosqldb/classes.db.js +434 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.d.ts +52 -0
- package/dist_ts/nosqldb/classes.distributedcoordinator.js +314 -0
- package/dist_ts/nosqldb/classes.doc.d.ts +722 -0
- package/dist_ts/nosqldb/classes.doc.js +2976 -0
- package/dist_ts/nosqldb/classes.easystore.d.ts +42 -0
- package/dist_ts/nosqldb/classes.easystore.js +199 -0
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +141 -0
- package/dist_ts/nosqldb/classes.exactpersistence.js +1110 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.d.ts +173 -0
- package/dist_ts/nosqldb/classes.lucene.adapter.js +623 -0
- package/dist_ts/nosqldb/classes.mongoadministration.d.ts +73 -0
- package/dist_ts/nosqldb/classes.mongoadministration.js +497 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.d.ts +42 -0
- package/dist_ts/nosqldb/classes.namespaceinspection.js +138 -0
- package/dist_ts/nosqldb/classes.operationbudget.d.ts +22 -0
- package/dist_ts/nosqldb/classes.operationbudget.js +65 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.d.ts +18 -0
- package/dist_ts/nosqldb/classes.ordinarypersistence.js +71 -0
- package/dist_ts/nosqldb/classes.persistence.d.ts +14 -0
- package/dist_ts/nosqldb/classes.persistence.js +34 -0
- package/dist_ts/nosqldb/classes.session.d.ts +28 -0
- package/dist_ts/nosqldb/classes.session.js +246 -0
- package/dist_ts/nosqldb/classes.storedinspection.d.ts +44 -0
- package/dist_ts/nosqldb/classes.storedinspection.js +100 -0
- package/dist_ts/nosqldb/classes.testdatabase.d.ts +56 -0
- package/dist_ts/nosqldb/classes.testdatabase.js +250 -0
- package/dist_ts/nosqldb/classes.watcher.d.ts +37 -0
- package/dist_ts/nosqldb/classes.watcher.js +98 -0
- package/dist_ts/nosqldb/index.d.ts +27 -0
- package/dist_ts/nosqldb/index.js +18 -0
- package/dist_ts/nosqldb/logging.d.ts +2 -0
- package/dist_ts/nosqldb/logging.js +3 -0
- package/dist_ts/nosqldb/plugins.d.ts +17 -0
- package/dist_ts/nosqldb/plugins.js +20 -0
- package/dist_ts/nosqldb/shim.d.ts +1 -0
- package/dist_ts/nosqldb/shim.js +8 -0
- package/dist_ts/nosqldb/testsupport.d.ts +3 -0
- package/dist_ts/nosqldb/testsupport.js +3 -0
- package/dist_ts/objectstorage/classes.bucket.d.ts +227 -0
- package/dist_ts/objectstorage/classes.bucket.js +939 -0
- package/dist_ts/objectstorage/classes.connection.d.ts +21 -0
- package/dist_ts/objectstorage/classes.connection.js +27 -0
- package/dist_ts/objectstorage/classes.directory.d.ts +124 -0
- package/dist_ts/objectstorage/classes.directory.js +335 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactpathpurgeerror.js +18 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.d.ts +5 -0
- package/dist_ts/objectstorage/classes.exactuploaderror.js +19 -0
- package/dist_ts/objectstorage/classes.file.d.ts +91 -0
- package/dist_ts/objectstorage/classes.file.js +255 -0
- package/dist_ts/objectstorage/classes.listcursor.d.ts +41 -0
- package/dist_ts/objectstorage/classes.listcursor.js +67 -0
- package/dist_ts/objectstorage/classes.metadata.d.ts +57 -0
- package/dist_ts/objectstorage/classes.metadata.js +113 -0
- package/dist_ts/objectstorage/classes.smartbucket.d.ts +57 -0
- package/dist_ts/objectstorage/classes.smartbucket.js +357 -0
- package/dist_ts/objectstorage/classes.trash.d.ts +11 -0
- package/dist_ts/objectstorage/classes.trash.js +22 -0
- package/dist_ts/objectstorage/classes.watcher.d.ts +79 -0
- package/dist_ts/objectstorage/classes.watcher.js +249 -0
- package/dist_ts/objectstorage/helpers.d.ts +25 -0
- package/dist_ts/objectstorage/helpers.js +215 -0
- package/dist_ts/objectstorage/index.d.ts +13 -0
- package/dist_ts/objectstorage/index.js +13 -0
- package/dist_ts/objectstorage/interfaces.d.ts +276 -0
- package/dist_ts/objectstorage/interfaces.js +2 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1069 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +40 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.js +382 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.d.ts +11 -0
- package/dist_ts/objectstorage/internal.exactupload.operations.js +1104 -0
- package/dist_ts/objectstorage/internal.multipart.planner.d.ts +8 -0
- package/dist_ts/objectstorage/internal.multipart.planner.js +63 -0
- package/dist_ts/objectstorage/internal.multipart.stream.d.ts +17 -0
- package/dist_ts/objectstorage/internal.multipart.stream.js +440 -0
- package/dist_ts/objectstorage/internal.multipart.types.d.ts +82 -0
- package/dist_ts/objectstorage/internal.multipart.types.js +2 -0
- package/dist_ts/objectstorage/plugins.d.ts +17 -0
- package/dist_ts/objectstorage/plugins.js +23 -0
- package/dist_ts/plugins.d.ts +4 -0
- package/dist_ts/plugins.js +5 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +39 -0
- package/dist_ts/sqldb/classes.clickhouseconnection.js +225 -0
- package/dist_ts/sqldb/classes.sqlconnection.d.ts +50 -0
- package/dist_ts/sqldb/classes.sqlconnection.js +376 -0
- package/dist_ts/sqldb/classes.sqltable.d.ts +29 -0
- package/dist_ts/sqldb/classes.sqltable.js +70 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.d.ts +27 -0
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +89 -0
- package/dist_ts/sqldb/clickhouse/index.d.ts +9 -0
- package/dist_ts/sqldb/clickhouse/index.js +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.d.ts +88 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +304 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +28 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +46 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.d.ts +43 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +155 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.d.ts +13 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.resultset.js +36 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.d.ts +49 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +106 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.d.ts +51 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +96 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.d.ts +5 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.plugins.js +6 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.d.ts +53 -0
- package/dist_ts/sqldb/clickhouse/smartclickhouse.types.js +41 -0
- package/dist_ts/sqldb/index.d.ts +6 -0
- package/dist_ts/sqldb/index.js +6 -0
- package/dist_ts/sqldb/interfaces.d.ts +53 -0
- package/dist_ts/sqldb/interfaces.js +19 -0
- package/dist_ts/sqldb/internal.sqlpool.d.ts +51 -0
- package/dist_ts/sqldb/internal.sqlpool.js +214 -0
- package/dist_ts/sqldb/plugins.clickhouse.d.ts +4 -0
- package/dist_ts/sqldb/plugins.clickhouse.js +5 -0
- package/dist_ts/sqldb/plugins.mariadb.d.ts +4 -0
- package/dist_ts/sqldb/plugins.mariadb.js +5 -0
- package/docs/source/smartbucket/license.md +19 -0
- package/docs/source/smartclickhouse/license.md +19 -0
- package/license.md +21 -0
- package/package.json +101 -0
- package/readme.md +157 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.losslessorgclient.ts +104 -0
- package/ts/core/classes.error.ts +31 -0
- package/ts/core/classes.operation.ts +60 -0
- package/ts/core/interfaces.ts +24 -0
- package/ts/index.ts +4 -0
- package/ts/nosqldb/classes.atomicdelete.ts +81 -0
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +152 -0
- package/ts/nosqldb/classes.atomicupdate.ts +99 -0
- package/ts/nosqldb/classes.bootstraprecord.ts +107 -0
- package/ts/nosqldb/classes.bsonassertion.ts +25 -0
- package/ts/nosqldb/classes.bsonobjectid.ts +45 -0
- package/ts/nosqldb/classes.bsonsnapshot.ts +105 -0
- package/ts/nosqldb/classes.cached-document.ts +67 -0
- package/ts/nosqldb/classes.collection.ts +2399 -0
- package/ts/nosqldb/classes.collectionfactory.ts +87 -0
- package/ts/nosqldb/classes.collectionlifecycle.ts +24 -0
- package/ts/nosqldb/classes.collectionpreparation.ts +164 -0
- package/ts/nosqldb/classes.collectiontopology.ts +645 -0
- package/ts/nosqldb/classes.connection.ts +31 -0
- package/ts/nosqldb/classes.convenience.ts +5 -0
- package/ts/nosqldb/classes.cursor.ts +88 -0
- package/ts/nosqldb/classes.cursoroperation.ts +38 -0
- package/ts/nosqldb/classes.db.ts +637 -0
- package/ts/nosqldb/classes.distributedcoordinator.ts +305 -0
- package/ts/nosqldb/classes.doc.ts +4928 -0
- package/ts/nosqldb/classes.easystore.ts +154 -0
- package/ts/nosqldb/classes.exactpersistence.ts +1974 -0
- package/ts/nosqldb/classes.lucene.adapter.ts +780 -0
- package/ts/nosqldb/classes.mongoadministration.ts +867 -0
- package/ts/nosqldb/classes.namespaceinspection.ts +199 -0
- package/ts/nosqldb/classes.operationbudget.ts +75 -0
- package/ts/nosqldb/classes.ordinarypersistence.ts +84 -0
- package/ts/nosqldb/classes.persistence.ts +62 -0
- package/ts/nosqldb/classes.session.ts +389 -0
- package/ts/nosqldb/classes.storedinspection.ts +151 -0
- package/ts/nosqldb/classes.testdatabase.ts +272 -0
- package/ts/nosqldb/classes.watcher.ts +96 -0
- package/ts/nosqldb/index.ts +51 -0
- package/ts/nosqldb/logging.ts +3 -0
- package/ts/nosqldb/plugins.ts +37 -0
- package/ts/nosqldb/shim.ts +6 -0
- package/ts/nosqldb/testsupport.ts +13 -0
- package/ts/objectstorage/classes.bucket.ts +1114 -0
- package/ts/objectstorage/classes.connection.ts +36 -0
- package/ts/objectstorage/classes.directory.ts +425 -0
- package/ts/objectstorage/classes.exactpathpurgeerror.ts +24 -0
- package/ts/objectstorage/classes.exactuploaderror.ts +25 -0
- package/ts/objectstorage/classes.file.ts +303 -0
- package/ts/objectstorage/classes.listcursor.ts +89 -0
- package/ts/objectstorage/classes.metadata.ts +134 -0
- package/ts/objectstorage/classes.smartbucket.ts +445 -0
- package/ts/objectstorage/classes.trash.ts +30 -0
- package/ts/objectstorage/classes.watcher.ts +289 -0
- package/ts/objectstorage/helpers.ts +254 -0
- package/ts/objectstorage/index.ts +13 -0
- package/ts/objectstorage/interfaces.ts +389 -0
- package/ts/objectstorage/internal.exactpathpurge.operations.ts +1936 -0
- package/ts/objectstorage/internal.exactupload.capability.ts +580 -0
- package/ts/objectstorage/internal.exactupload.operations.ts +1715 -0
- package/ts/objectstorage/internal.multipart.planner.ts +90 -0
- package/ts/objectstorage/internal.multipart.stream.ts +606 -0
- package/ts/objectstorage/internal.multipart.types.ts +106 -0
- package/ts/objectstorage/plugins.ts +35 -0
- package/ts/plugins.ts +4 -0
- package/ts/sqldb/classes.clickhouseconnection.ts +189 -0
- package/ts/sqldb/classes.sqlconnection.ts +350 -0
- package/ts/sqldb/classes.sqltable.ts +70 -0
- package/ts/sqldb/clickhouse/classes.metricwriter.ts +72 -0
- package/ts/sqldb/clickhouse/index.ts +16 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.ts +372 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.ts +52 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.ts +120 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.resultset.ts +44 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.ts +123 -0
- package/ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.ts +114 -0
- package/ts/sqldb/clickhouse/smartclickhouse.plugins.ts +5 -0
- package/ts/sqldb/clickhouse/smartclickhouse.types.ts +134 -0
- package/ts/sqldb/index.ts +6 -0
- package/ts/sqldb/interfaces.ts +61 -0
- package/ts/sqldb/internal.sqlpool.ts +179 -0
- package/ts/sqldb/plugins.clickhouse.ts +4 -0
- package/ts/sqldb/plugins.mariadb.ts +4 -0
|
@@ -0,0 +1,1110 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { getInertObjectIdBytes } from './classes.bsonobjectid.js';
|
|
3
|
+
import { assertBsonWithoutMutation } from './classes.bsonassertion.js';
|
|
4
|
+
import { getOrdinaryPersistencePolicy } from './classes.ordinarypersistence.js';
|
|
5
|
+
import { registerCollectionReconnectHandler } from './classes.collectionlifecycle.js';
|
|
6
|
+
import { acquireSmartdataSession } from './classes.session.js';
|
|
7
|
+
import { convertFilterForMongoDb, } from './classes.doc.js';
|
|
8
|
+
const exactPersistencePolicySymbol = Symbol.for('@push.rocks/smartdata.exactPersistencePolicy');
|
|
9
|
+
const storageMetadataKeys = ['_id', '_smartdataRevision'];
|
|
10
|
+
const reservedKeys = [
|
|
11
|
+
...storageMetadataKeys,
|
|
12
|
+
'_createdAt',
|
|
13
|
+
'_updatedAt',
|
|
14
|
+
];
|
|
15
|
+
export const isMongoObjectId = (valueArg) => valueArg instanceof plugins.mongodb.ObjectId;
|
|
16
|
+
export class SmartdataExactPersistenceError extends Error {
|
|
17
|
+
code;
|
|
18
|
+
constructor(codeArg, messageArg, optionsArg) {
|
|
19
|
+
super(messageArg, optionsArg);
|
|
20
|
+
this.name = 'SmartdataExactPersistenceError';
|
|
21
|
+
this.code = codeArg;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const exactCollectionCache = new WeakMap();
|
|
25
|
+
const bytesEqual = (leftArg, rightArg) => {
|
|
26
|
+
if (leftArg.byteLength !== rightArg.byteLength) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
for (let index = 0; index < leftArg.byteLength; index++) {
|
|
30
|
+
if (leftArg[index] !== rightArg[index]) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
const waitWithSignal = async (promiseArg, signalArg) => {
|
|
37
|
+
if (!signalArg)
|
|
38
|
+
return promiseArg;
|
|
39
|
+
signalArg.throwIfAborted();
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
41
|
+
let settled = false;
|
|
42
|
+
const beginSettlement = () => {
|
|
43
|
+
if (settled)
|
|
44
|
+
return false;
|
|
45
|
+
settled = true;
|
|
46
|
+
signalArg.removeEventListener('abort', onAbort);
|
|
47
|
+
return true;
|
|
48
|
+
};
|
|
49
|
+
const onAbort = () => {
|
|
50
|
+
if (beginSettlement())
|
|
51
|
+
reject(signalArg.reason);
|
|
52
|
+
};
|
|
53
|
+
signalArg.addEventListener('abort', onAbort, { once: true });
|
|
54
|
+
if (signalArg.aborted)
|
|
55
|
+
onAbort();
|
|
56
|
+
void promiseArg.then((valueArg) => {
|
|
57
|
+
if (beginSettlement())
|
|
58
|
+
resolve(valueArg);
|
|
59
|
+
}, (errorArg) => {
|
|
60
|
+
if (beginSettlement())
|
|
61
|
+
reject(errorArg);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
const hasOwn = (documentArg, keyArg) => Object.prototype.hasOwnProperty.call(documentArg, keyArg);
|
|
66
|
+
const isPlainObject = (valueArg) => {
|
|
67
|
+
if (typeof valueArg !== 'object' || valueArg === null) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
const prototype = Object.getPrototypeOf(valueArg);
|
|
71
|
+
return prototype === Object.prototype || prototype === null;
|
|
72
|
+
};
|
|
73
|
+
const hasActiveInheritedToBsonEncoder = (prototypeArg) => {
|
|
74
|
+
let prototype = prototypeArg;
|
|
75
|
+
while (prototype) {
|
|
76
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'toBSON');
|
|
77
|
+
if (descriptor &&
|
|
78
|
+
(!('value' in descriptor) ||
|
|
79
|
+
descriptor.value !== undefined)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
};
|
|
86
|
+
const maxExactSnapshotArrayLength = 100_000;
|
|
87
|
+
const maxExactSnapshotByteLength = 16 * 1024 * 1024;
|
|
88
|
+
const minSignedInt32 = -(2 ** 31);
|
|
89
|
+
const maxSignedInt32 = 2 ** 31 - 1;
|
|
90
|
+
const isSignedInt32 = (valueArg) => typeof valueArg === 'number' &&
|
|
91
|
+
Number.isInteger(valueArg) &&
|
|
92
|
+
!Object.is(valueArg, -0) &&
|
|
93
|
+
valueArg >= minSignedInt32 &&
|
|
94
|
+
valueArg <= maxSignedInt32;
|
|
95
|
+
const typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
96
|
+
const typedArrayBufferGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'buffer')?.get;
|
|
97
|
+
const typedArrayByteOffsetGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteOffset')?.get;
|
|
98
|
+
const typedArrayByteLengthGetter = Object.getOwnPropertyDescriptor(typedArrayPrototype, 'byteLength')?.get;
|
|
99
|
+
const regExpSourceGetter = Object.getOwnPropertyDescriptor(RegExp.prototype, 'source')?.get;
|
|
100
|
+
const regExpFlagGetters = [
|
|
101
|
+
['d', 'hasIndices'],
|
|
102
|
+
['g', 'global'],
|
|
103
|
+
['i', 'ignoreCase'],
|
|
104
|
+
['m', 'multiline'],
|
|
105
|
+
['s', 'dotAll'],
|
|
106
|
+
['u', 'unicode'],
|
|
107
|
+
['v', 'unicodeSets'],
|
|
108
|
+
['y', 'sticky'],
|
|
109
|
+
].map(([flag, property]) => ({
|
|
110
|
+
flag,
|
|
111
|
+
getter: Object.getOwnPropertyDescriptor(RegExp.prototype, property)?.get,
|
|
112
|
+
}));
|
|
113
|
+
const exactSnapshotError = (labelArg, detailArg) => new SmartdataExactPersistenceError('invalid_document', `${labelArg} ${detailArg}`);
|
|
114
|
+
const constructExactBsonScalar = (constructorArg, labelArg) => {
|
|
115
|
+
try {
|
|
116
|
+
return constructorArg();
|
|
117
|
+
}
|
|
118
|
+
catch (errorArg) {
|
|
119
|
+
if (errorArg instanceof SmartdataExactPersistenceError) {
|
|
120
|
+
throw errorArg;
|
|
121
|
+
}
|
|
122
|
+
throw new SmartdataExactPersistenceError('invalid_document', `${labelArg} contains malformed BSON scalar data.`, {
|
|
123
|
+
cause: errorArg,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const getOwnDataValue = (valueArg, keyArg, labelArg) => {
|
|
128
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, keyArg);
|
|
129
|
+
if (!descriptor || !('value' in descriptor)) {
|
|
130
|
+
throw exactSnapshotError(labelArg, `contains a non-inert "${keyArg}" property.`);
|
|
131
|
+
}
|
|
132
|
+
return descriptor.value;
|
|
133
|
+
};
|
|
134
|
+
const getExactSnapshotBytes = (valueArg, labelArg) => {
|
|
135
|
+
if (typeof valueArg !== 'object' ||
|
|
136
|
+
valueArg === null ||
|
|
137
|
+
plugins.nodeUtil.types.isProxy(valueArg) ||
|
|
138
|
+
!ArrayBuffer.isView(valueArg) ||
|
|
139
|
+
!typedArrayBufferGetter ||
|
|
140
|
+
!typedArrayByteOffsetGetter ||
|
|
141
|
+
!typedArrayByteLengthGetter) {
|
|
142
|
+
throw exactSnapshotError(labelArg, 'contains invalid byte data.');
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const buffer = Reflect.apply(typedArrayBufferGetter, valueArg, []);
|
|
146
|
+
const byteOffset = Reflect.apply(typedArrayByteOffsetGetter, valueArg, []);
|
|
147
|
+
const byteLength = Reflect.apply(typedArrayByteLengthGetter, valueArg, []);
|
|
148
|
+
if (!Number.isSafeInteger(byteOffset) ||
|
|
149
|
+
!Number.isSafeInteger(byteLength) ||
|
|
150
|
+
byteLength < 0 ||
|
|
151
|
+
byteLength > maxExactSnapshotByteLength) {
|
|
152
|
+
throw exactSnapshotError(labelArg, 'contains oversized byte data.');
|
|
153
|
+
}
|
|
154
|
+
return Uint8Array.from(new Uint8Array(buffer, byteOffset, byteLength));
|
|
155
|
+
}
|
|
156
|
+
catch (errorArg) {
|
|
157
|
+
if (errorArg instanceof SmartdataExactPersistenceError) {
|
|
158
|
+
throw errorArg;
|
|
159
|
+
}
|
|
160
|
+
throw exactSnapshotError(labelArg, 'contains invalid byte data.');
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const markInertBsonSnapshot = (valueArg) => {
|
|
164
|
+
Object.defineProperty(valueArg, 'toBSON', {
|
|
165
|
+
value: undefined,
|
|
166
|
+
enumerable: false,
|
|
167
|
+
});
|
|
168
|
+
return valueArg;
|
|
169
|
+
};
|
|
170
|
+
const snapshotInertExactValue = (valueArg, labelArg, seenArg = new WeakSet(), depthArg = 0) => {
|
|
171
|
+
if (typeof valueArg === 'function' || typeof valueArg === 'symbol') {
|
|
172
|
+
throw exactSnapshotError(labelArg, 'contains a value that cannot be inert BSON data.');
|
|
173
|
+
}
|
|
174
|
+
if (typeof valueArg !== 'object' || valueArg === null) {
|
|
175
|
+
return valueArg;
|
|
176
|
+
}
|
|
177
|
+
if (plugins.nodeUtil.types.isProxy(valueArg)) {
|
|
178
|
+
throw exactSnapshotError(labelArg, 'may not contain Proxy objects.');
|
|
179
|
+
}
|
|
180
|
+
if (seenArg.has(valueArg)) {
|
|
181
|
+
throw exactSnapshotError(labelArg, 'may not contain circular data.');
|
|
182
|
+
}
|
|
183
|
+
if (depthArg >= 100) {
|
|
184
|
+
throw exactSnapshotError(labelArg, 'exceeds the maximum supported nesting depth.');
|
|
185
|
+
}
|
|
186
|
+
seenArg.add(valueArg);
|
|
187
|
+
try {
|
|
188
|
+
const prototype = Object.getPrototypeOf(valueArg);
|
|
189
|
+
if (Array.isArray(valueArg)) {
|
|
190
|
+
if (prototype !== Array.prototype ||
|
|
191
|
+
valueArg.length > maxExactSnapshotArrayLength) {
|
|
192
|
+
throw exactSnapshotError(labelArg, 'must be a bounded ordinary array.');
|
|
193
|
+
}
|
|
194
|
+
if (hasActiveInheritedToBsonEncoder(prototype)) {
|
|
195
|
+
throw exactSnapshotError(labelArg, 'may not inherit a custom BSON encoder.');
|
|
196
|
+
}
|
|
197
|
+
const ownKeys = Reflect.ownKeys(valueArg);
|
|
198
|
+
const toBsonDescriptor = Object.getOwnPropertyDescriptor(valueArg, 'toBSON');
|
|
199
|
+
if (toBsonDescriptor &&
|
|
200
|
+
(!('value' in toBsonDescriptor) ||
|
|
201
|
+
toBsonDescriptor.value !== undefined ||
|
|
202
|
+
toBsonDescriptor.enumerable === true)) {
|
|
203
|
+
throw exactSnapshotError(labelArg, 'arrays may contain only an inert non-enumerable toBSON marker.');
|
|
204
|
+
}
|
|
205
|
+
const indexedKeys = ownKeys.filter((keyArg) => keyArg !== 'length' && keyArg !== 'toBSON');
|
|
206
|
+
if (indexedKeys.length !== valueArg.length ||
|
|
207
|
+
indexedKeys.some((keyArg) => {
|
|
208
|
+
if (typeof keyArg !== 'string' ||
|
|
209
|
+
!/^(0|[1-9]\d*)$/.test(keyArg)) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
const index = Number(keyArg);
|
|
213
|
+
return !Number.isSafeInteger(index) || index >= valueArg.length;
|
|
214
|
+
})) {
|
|
215
|
+
throw exactSnapshotError(labelArg, 'arrays must be dense and contain only indexed data properties.');
|
|
216
|
+
}
|
|
217
|
+
const snapshot = [];
|
|
218
|
+
for (let index = 0; index < valueArg.length; index++) {
|
|
219
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, String(index));
|
|
220
|
+
if (!descriptor ||
|
|
221
|
+
!('value' in descriptor) ||
|
|
222
|
+
descriptor.enumerable !== true) {
|
|
223
|
+
throw exactSnapshotError(labelArg, 'arrays may contain only inert enumerable data properties.');
|
|
224
|
+
}
|
|
225
|
+
snapshot.push(snapshotInertExactValue(descriptor.value, `${labelArg}.${index}`, seenArg, depthArg + 1));
|
|
226
|
+
}
|
|
227
|
+
return snapshot;
|
|
228
|
+
}
|
|
229
|
+
if (isPlainObject(valueArg)) {
|
|
230
|
+
const snapshot = Object.create(null);
|
|
231
|
+
for (const key of Reflect.ownKeys(valueArg)) {
|
|
232
|
+
if (typeof key !== 'string' ||
|
|
233
|
+
key === 'toBSON' ||
|
|
234
|
+
key === '_bsontype') {
|
|
235
|
+
throw exactSnapshotError(labelArg, 'may contain only ordinary string-keyed data.');
|
|
236
|
+
}
|
|
237
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, key);
|
|
238
|
+
if (!descriptor ||
|
|
239
|
+
!('value' in descriptor) ||
|
|
240
|
+
descriptor.enumerable !== true) {
|
|
241
|
+
throw exactSnapshotError(labelArg, 'may contain only inert enumerable data properties.');
|
|
242
|
+
}
|
|
243
|
+
snapshot[key] = snapshotInertExactValue(descriptor.value, `${labelArg}.${key}`, seenArg, depthArg + 1);
|
|
244
|
+
}
|
|
245
|
+
return snapshot;
|
|
246
|
+
}
|
|
247
|
+
if (hasActiveInheritedToBsonEncoder(prototype)) {
|
|
248
|
+
throw exactSnapshotError(labelArg, 'may not inherit a custom BSON encoder.');
|
|
249
|
+
}
|
|
250
|
+
if (prototype === Date.prototype) {
|
|
251
|
+
if (Reflect.ownKeys(valueArg).length !== 0) {
|
|
252
|
+
throw exactSnapshotError(labelArg, 'contains a customized Date.');
|
|
253
|
+
}
|
|
254
|
+
return markInertBsonSnapshot(new Date(Reflect.apply(Date.prototype.getTime, valueArg, [])));
|
|
255
|
+
}
|
|
256
|
+
if (prototype === RegExp.prototype) {
|
|
257
|
+
const ownKeys = Reflect.ownKeys(valueArg);
|
|
258
|
+
if (ownKeys.length !== 1 ||
|
|
259
|
+
ownKeys[0] !== 'lastIndex' ||
|
|
260
|
+
!regExpSourceGetter) {
|
|
261
|
+
throw exactSnapshotError(labelArg, 'contains a customized regular expression.');
|
|
262
|
+
}
|
|
263
|
+
const source = Reflect.apply(regExpSourceGetter, valueArg, []);
|
|
264
|
+
const flags = regExpFlagGetters
|
|
265
|
+
.filter(({ getter }) => getter && Reflect.apply(getter, valueArg, []))
|
|
266
|
+
.map(({ flag }) => flag)
|
|
267
|
+
.join('');
|
|
268
|
+
return markInertBsonSnapshot(new RegExp(source, flags));
|
|
269
|
+
}
|
|
270
|
+
if (prototype === Uint8Array.prototype) {
|
|
271
|
+
return markInertBsonSnapshot(getExactSnapshotBytes(valueArg, labelArg));
|
|
272
|
+
}
|
|
273
|
+
const scalarToBsonDescriptor = Object.getOwnPropertyDescriptor(valueArg, 'toBSON');
|
|
274
|
+
if (scalarToBsonDescriptor &&
|
|
275
|
+
(!('value' in scalarToBsonDescriptor) ||
|
|
276
|
+
scalarToBsonDescriptor.value !== undefined ||
|
|
277
|
+
scalarToBsonDescriptor.enumerable === true)) {
|
|
278
|
+
throw exactSnapshotError(labelArg, 'contains a customized BSON scalar encoder.');
|
|
279
|
+
}
|
|
280
|
+
let scalarSnapshot;
|
|
281
|
+
if (prototype === plugins.mongodb.ObjectId.prototype) {
|
|
282
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.ObjectId(getInertObjectIdBytes(valueArg, () => exactSnapshotError(labelArg, 'contains a malformed or non-inert ObjectId.'))), labelArg);
|
|
283
|
+
}
|
|
284
|
+
else if (prototype === plugins.mongodb.UUID.prototype) {
|
|
285
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.UUID(getExactSnapshotBytes(getOwnDataValue(valueArg, 'buffer', labelArg), labelArg)), labelArg);
|
|
286
|
+
}
|
|
287
|
+
else if (prototype === plugins.mongodb.Binary.prototype) {
|
|
288
|
+
const buffer = getExactSnapshotBytes(getOwnDataValue(valueArg, 'buffer', labelArg), labelArg);
|
|
289
|
+
const subType = getOwnDataValue(valueArg, 'sub_type', labelArg);
|
|
290
|
+
const position = getOwnDataValue(valueArg, 'position', labelArg);
|
|
291
|
+
if (typeof subType !== 'number' ||
|
|
292
|
+
!Number.isSafeInteger(subType) ||
|
|
293
|
+
typeof position !== 'number' ||
|
|
294
|
+
!Number.isSafeInteger(position) ||
|
|
295
|
+
position < 0 ||
|
|
296
|
+
position > buffer.length) {
|
|
297
|
+
throw exactSnapshotError(labelArg, 'contains invalid binary data.');
|
|
298
|
+
}
|
|
299
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Binary(buffer.subarray(0, position), subType), labelArg);
|
|
300
|
+
}
|
|
301
|
+
else if (prototype === plugins.mongodb.Decimal128.prototype) {
|
|
302
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Decimal128(getExactSnapshotBytes(getOwnDataValue(valueArg, 'bytes', labelArg), labelArg)), labelArg);
|
|
303
|
+
}
|
|
304
|
+
else if (prototype === plugins.mongodb.Int32.prototype) {
|
|
305
|
+
const value = getOwnDataValue(valueArg, 'value', labelArg);
|
|
306
|
+
if (!isSignedInt32(value)) {
|
|
307
|
+
throw exactSnapshotError(labelArg, 'contains an invalid Int32.');
|
|
308
|
+
}
|
|
309
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Int32(value), labelArg);
|
|
310
|
+
}
|
|
311
|
+
else if (prototype === plugins.mongodb.Double.prototype) {
|
|
312
|
+
const value = getOwnDataValue(valueArg, 'value', labelArg);
|
|
313
|
+
if (typeof value !== 'number') {
|
|
314
|
+
throw exactSnapshotError(labelArg, 'contains an invalid Double.');
|
|
315
|
+
}
|
|
316
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Double(value), labelArg);
|
|
317
|
+
}
|
|
318
|
+
else if (prototype === plugins.mongodb.Long.prototype) {
|
|
319
|
+
const low = getOwnDataValue(valueArg, 'low', labelArg);
|
|
320
|
+
const high = getOwnDataValue(valueArg, 'high', labelArg);
|
|
321
|
+
const unsigned = getOwnDataValue(valueArg, 'unsigned', labelArg);
|
|
322
|
+
if (!isSignedInt32(low) ||
|
|
323
|
+
!isSignedInt32(high) ||
|
|
324
|
+
typeof unsigned !== 'boolean') {
|
|
325
|
+
throw exactSnapshotError(labelArg, 'contains an invalid 64-bit value.');
|
|
326
|
+
}
|
|
327
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Long(low, high, unsigned), labelArg);
|
|
328
|
+
}
|
|
329
|
+
else if (prototype === plugins.mongodb.Timestamp.prototype) {
|
|
330
|
+
const low = getOwnDataValue(valueArg, 'low', labelArg);
|
|
331
|
+
const high = getOwnDataValue(valueArg, 'high', labelArg);
|
|
332
|
+
const unsigned = getOwnDataValue(valueArg, 'unsigned', labelArg);
|
|
333
|
+
if (!isSignedInt32(low) || !isSignedInt32(high) || unsigned !== true) {
|
|
334
|
+
throw exactSnapshotError(labelArg, 'contains an invalid Timestamp.');
|
|
335
|
+
}
|
|
336
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Timestamp(new plugins.mongodb.Long(low, high, true)), labelArg);
|
|
337
|
+
}
|
|
338
|
+
else if (prototype === plugins.mongodb.BSONRegExp.prototype) {
|
|
339
|
+
const pattern = getOwnDataValue(valueArg, 'pattern', labelArg);
|
|
340
|
+
const options = getOwnDataValue(valueArg, 'options', labelArg);
|
|
341
|
+
if (typeof pattern !== 'string' || typeof options !== 'string') {
|
|
342
|
+
throw exactSnapshotError(labelArg, 'contains an invalid BSON regex.');
|
|
343
|
+
}
|
|
344
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.BSONRegExp(pattern, options), labelArg);
|
|
345
|
+
}
|
|
346
|
+
else if (prototype === plugins.mongodb.BSONSymbol.prototype) {
|
|
347
|
+
const value = getOwnDataValue(valueArg, 'value', labelArg);
|
|
348
|
+
if (typeof value !== 'string') {
|
|
349
|
+
throw exactSnapshotError(labelArg, 'contains an invalid BSON symbol.');
|
|
350
|
+
}
|
|
351
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.BSONSymbol(value), labelArg);
|
|
352
|
+
}
|
|
353
|
+
else if (prototype === plugins.mongodb.Code.prototype) {
|
|
354
|
+
const code = getOwnDataValue(valueArg, 'code', labelArg);
|
|
355
|
+
const scope = getOwnDataValue(valueArg, 'scope', labelArg);
|
|
356
|
+
if (typeof code !== 'string') {
|
|
357
|
+
throw exactSnapshotError(labelArg, 'contains invalid BSON code.');
|
|
358
|
+
}
|
|
359
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.Code(code, scope === null
|
|
360
|
+
? null
|
|
361
|
+
: snapshotInertExactValue(scope, `${labelArg}.scope`, seenArg, depthArg + 1)), labelArg);
|
|
362
|
+
}
|
|
363
|
+
else if (prototype === plugins.mongodb.DBRef.prototype) {
|
|
364
|
+
const collection = getOwnDataValue(valueArg, 'collection', labelArg);
|
|
365
|
+
const oid = snapshotInertExactValue(getOwnDataValue(valueArg, 'oid', labelArg), `${labelArg}.oid`, seenArg, depthArg + 1);
|
|
366
|
+
const db = getOwnDataValue(valueArg, 'db', labelArg);
|
|
367
|
+
const fields = snapshotInertExactValue(getOwnDataValue(valueArg, 'fields', labelArg), `${labelArg}.fields`, seenArg, depthArg + 1);
|
|
368
|
+
if (typeof collection !== 'string' ||
|
|
369
|
+
!(oid instanceof plugins.mongodb.ObjectId) ||
|
|
370
|
+
(db !== undefined && typeof db !== 'string') ||
|
|
371
|
+
!isPlainObject(fields)) {
|
|
372
|
+
throw exactSnapshotError(labelArg, 'contains an invalid DBRef.');
|
|
373
|
+
}
|
|
374
|
+
scalarSnapshot = constructExactBsonScalar(() => new plugins.mongodb.DBRef(collection, oid, db, fields), labelArg);
|
|
375
|
+
}
|
|
376
|
+
else if (prototype === plugins.mongodb.MinKey.prototype) {
|
|
377
|
+
scalarSnapshot = new plugins.mongodb.MinKey();
|
|
378
|
+
}
|
|
379
|
+
else if (prototype === plugins.mongodb.MaxKey.prototype) {
|
|
380
|
+
scalarSnapshot = new plugins.mongodb.MaxKey();
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
throw exactSnapshotError(labelArg, 'contains an object with a custom BSON encoding boundary.');
|
|
384
|
+
}
|
|
385
|
+
return markInertBsonSnapshot(scalarSnapshot);
|
|
386
|
+
}
|
|
387
|
+
finally {
|
|
388
|
+
seenArg.delete(valueArg);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
const canonicalizeValue = (valueArg, seenArg = new WeakSet()) => {
|
|
392
|
+
if (typeof valueArg !== 'object' || valueArg === null) {
|
|
393
|
+
return valueArg;
|
|
394
|
+
}
|
|
395
|
+
const isArray = Array.isArray(valueArg);
|
|
396
|
+
if (!isArray && !isPlainObject(valueArg)) {
|
|
397
|
+
return valueArg;
|
|
398
|
+
}
|
|
399
|
+
if (seenArg.has(valueArg)) {
|
|
400
|
+
return valueArg;
|
|
401
|
+
}
|
|
402
|
+
seenArg.add(valueArg);
|
|
403
|
+
if (isArray) {
|
|
404
|
+
const canonicalArray = valueArg.map((entryArg) => canonicalizeValue(entryArg, seenArg));
|
|
405
|
+
seenArg.delete(valueArg);
|
|
406
|
+
return canonicalArray;
|
|
407
|
+
}
|
|
408
|
+
const canonical = Object.create(null);
|
|
409
|
+
for (const key of Object.keys(valueArg).sort()) {
|
|
410
|
+
const entry = valueArg[key];
|
|
411
|
+
if (entry !== undefined) {
|
|
412
|
+
canonical[key] = canonicalizeValue(entry, seenArg);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
seenArg.delete(valueArg);
|
|
416
|
+
return canonical;
|
|
417
|
+
};
|
|
418
|
+
const isDuplicateKeyError = (errorArg) => {
|
|
419
|
+
const mongoError = errorArg;
|
|
420
|
+
return mongoError?.code === 11000 || mongoError?.codeName === 'DuplicateKey';
|
|
421
|
+
};
|
|
422
|
+
const isTransientTransactionError = (errorArg, sessionArg) => Boolean(sessionArg)
|
|
423
|
+
&& typeof errorArg?.hasErrorLabel === 'function'
|
|
424
|
+
&& errorArg
|
|
425
|
+
.hasErrorLabel('TransientTransactionError');
|
|
426
|
+
const hasActiveTransaction = (sessionArg) => Boolean(sessionArg?.inTransaction());
|
|
427
|
+
const unsupportedExactSave = async () => {
|
|
428
|
+
throw new SmartdataExactPersistenceError('unsupported_operation', 'save() is unavailable for exact-persistence models. Use the model exact API.');
|
|
429
|
+
};
|
|
430
|
+
const forbiddenExactDelete = async () => {
|
|
431
|
+
throw new SmartdataExactPersistenceError('unsupported_operation', 'delete() is forbidden for exact-persistence models.');
|
|
432
|
+
};
|
|
433
|
+
export class SmartdataExactCollection {
|
|
434
|
+
modelConstructor;
|
|
435
|
+
collection;
|
|
436
|
+
options;
|
|
437
|
+
initializationPromise;
|
|
438
|
+
initializedCollection;
|
|
439
|
+
initializationTarget;
|
|
440
|
+
initializationGeneration = 0;
|
|
441
|
+
allowedPersistedKeys;
|
|
442
|
+
uniqueIndexes;
|
|
443
|
+
reconcileBy;
|
|
444
|
+
constructor(modelConstructor, collection, options) {
|
|
445
|
+
this.modelConstructor = modelConstructor;
|
|
446
|
+
this.collection = collection;
|
|
447
|
+
this.options = options;
|
|
448
|
+
// Field-decorator initializers materialize the model metadata on its
|
|
449
|
+
// prototype. Exact persistence uses that metadata as the ownership boundary.
|
|
450
|
+
new this.modelConstructor();
|
|
451
|
+
const prototype = this.modelConstructor.prototype;
|
|
452
|
+
this.allowedPersistedKeys = new Set([
|
|
453
|
+
...(prototype.globalSaveableProperties || []),
|
|
454
|
+
...(prototype.saveableProperties || []),
|
|
455
|
+
].filter((keyArg) => !reservedKeys.includes(keyArg)));
|
|
456
|
+
this.uniqueIndexes = [
|
|
457
|
+
...new Set(prototype.uniqueIndexes || []),
|
|
458
|
+
];
|
|
459
|
+
const identityValueTypes = prototype.identityValueTypes;
|
|
460
|
+
const numericIdentityField = this.uniqueIndexes.find((fieldArg) => identityValueTypes?.[fieldArg] === 'positiveSafeInteger');
|
|
461
|
+
if (numericIdentityField) {
|
|
462
|
+
throw new SmartdataExactPersistenceError('invalid_configuration', `Exact persistence identity field "${numericIdentityField}" must use the default string valueType.`);
|
|
463
|
+
}
|
|
464
|
+
const explicitReconcileBy = options.reconcileBy;
|
|
465
|
+
if (explicitReconcileBy) {
|
|
466
|
+
if (!this.allowedPersistedKeys.has(explicitReconcileBy) ||
|
|
467
|
+
!this.uniqueIndexes.includes(explicitReconcileBy)) {
|
|
468
|
+
throw new SmartdataExactPersistenceError('invalid_configuration', `Exact persistence reconcileBy field "${explicitReconcileBy}" must be a persisted field decorated with @unI().`);
|
|
469
|
+
}
|
|
470
|
+
this.reconcileBy = explicitReconcileBy;
|
|
471
|
+
}
|
|
472
|
+
else if (this.uniqueIndexes.length === 1) {
|
|
473
|
+
this.reconcileBy = this.uniqueIndexes[0];
|
|
474
|
+
}
|
|
475
|
+
else if (this.uniqueIndexes.length === 0) {
|
|
476
|
+
throw new SmartdataExactPersistenceError('invalid_configuration', 'Exact persistence requires at least one persisted field decorated with @unI().');
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
throw new SmartdataExactPersistenceError('invalid_configuration', `Exact persistence requires reconcileBy when the model has multiple @unI() fields.`);
|
|
480
|
+
}
|
|
481
|
+
registerCollectionReconnectHandler(this.collection, () => {
|
|
482
|
+
this.initializationGeneration++;
|
|
483
|
+
this.initializationPromise = undefined;
|
|
484
|
+
this.initializedCollection = undefined;
|
|
485
|
+
this.initializationTarget = undefined;
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
async initialize() {
|
|
489
|
+
await this.collection.init();
|
|
490
|
+
if (this.initializedCollection === this.collection.mongoDbCollection) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const targetCollection = this.collection.mongoDbCollection;
|
|
494
|
+
if (this.initializationTarget !== targetCollection) {
|
|
495
|
+
this.initializationTarget = targetCollection;
|
|
496
|
+
this.initializationPromise = undefined;
|
|
497
|
+
this.initializationGeneration++;
|
|
498
|
+
}
|
|
499
|
+
if (!this.initializationPromise) {
|
|
500
|
+
const generation = this.initializationGeneration;
|
|
501
|
+
const initializationPromise = this.initializeOnce(targetCollection)
|
|
502
|
+
.then(() => {
|
|
503
|
+
if (this.initializationGeneration === generation
|
|
504
|
+
&& this.collection.mongoDbCollection === targetCollection) {
|
|
505
|
+
this.initializedCollection = targetCollection;
|
|
506
|
+
}
|
|
507
|
+
})
|
|
508
|
+
.catch((errorArg) => {
|
|
509
|
+
if (this.initializationPromise === initializationPromise) {
|
|
510
|
+
this.initializationPromise = undefined;
|
|
511
|
+
}
|
|
512
|
+
throw errorArg;
|
|
513
|
+
});
|
|
514
|
+
this.initializationPromise = initializationPromise;
|
|
515
|
+
}
|
|
516
|
+
await this.initializationPromise;
|
|
517
|
+
if (this.initializedCollection !== this.collection.mongoDbCollection) {
|
|
518
|
+
await this.initialize();
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
async initializeOnce(targetCollectionArg) {
|
|
522
|
+
const missingUniqueIndexes = this.uniqueIndexes.filter((uniqueIndexArg) => !this.collection.uniqueIndexes.includes(uniqueIndexArg));
|
|
523
|
+
for (const uniqueIndex of missingUniqueIndexes) {
|
|
524
|
+
await targetCollectionArg.createIndex({ [uniqueIndex]: 1 }, { unique: true, name: `${uniqueIndex}_1` });
|
|
525
|
+
}
|
|
526
|
+
const regularIndexes = this.modelConstructor.prototype.regularIndexes || [];
|
|
527
|
+
const missingRegularIndexes = regularIndexes.filter((regularIndexArg) => !this.collection.regularIndexes.some((existingIndexArg) => existingIndexArg.field === regularIndexArg.field));
|
|
528
|
+
for (const regularIndex of missingRegularIndexes) {
|
|
529
|
+
await targetCollectionArg.createIndex({ [regularIndex.field]: 1 }, regularIndex.options);
|
|
530
|
+
}
|
|
531
|
+
if (this.collection.mongoDbCollection !== targetCollectionArg) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
for (const uniqueIndex of missingUniqueIndexes) {
|
|
535
|
+
if (!this.collection.uniqueIndexes.includes(uniqueIndex)) {
|
|
536
|
+
this.collection.uniqueIndexes.push(uniqueIndex);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
for (const regularIndex of missingRegularIndexes) {
|
|
540
|
+
if (!this.collection.regularIndexes.some((existingIndexArg) => existingIndexArg.field === regularIndex.field)) {
|
|
541
|
+
this.collection.regularIndexes.push(regularIndex);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
async prepare() {
|
|
546
|
+
await this.initialize();
|
|
547
|
+
}
|
|
548
|
+
async beginOperation(optionsArg, signalArg) {
|
|
549
|
+
signalArg?.throwIfAborted();
|
|
550
|
+
if (!optionsArg.session) {
|
|
551
|
+
await waitWithSignal(this.initialize(), signalArg);
|
|
552
|
+
signalArg?.throwIfAborted();
|
|
553
|
+
return { release: () => { } };
|
|
554
|
+
}
|
|
555
|
+
if (!this.collection.isInitializedForCurrentDatabase()
|
|
556
|
+
|| this.initializedCollection !== this.collection.mongoDbCollection) {
|
|
557
|
+
throw new SmartdataExactPersistenceError('unsupported_operation', 'Exact collection must be prepared before it participates in a transaction.');
|
|
558
|
+
}
|
|
559
|
+
const lease = acquireSmartdataSession(optionsArg.session, this.collection.smartdataDb);
|
|
560
|
+
if (signalArg?.aborted) {
|
|
561
|
+
lease.release();
|
|
562
|
+
signalArg.throwIfAborted();
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
session: lease.rawSession,
|
|
566
|
+
release: lease.release,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
async runOperation(optionsArg, operationArg, signalArg) {
|
|
570
|
+
const operation = await this.beginOperation(optionsArg, signalArg);
|
|
571
|
+
try {
|
|
572
|
+
signalArg?.throwIfAborted();
|
|
573
|
+
return await operationArg(operation.session);
|
|
574
|
+
}
|
|
575
|
+
finally {
|
|
576
|
+
operation.release();
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
canonicalizeDocument(documentArg, labelArg) {
|
|
580
|
+
let canonicalInput;
|
|
581
|
+
let serialized;
|
|
582
|
+
let canonical;
|
|
583
|
+
let reserialized;
|
|
584
|
+
try {
|
|
585
|
+
canonicalInput = canonicalizeValue(documentArg);
|
|
586
|
+
serialized = plugins.mongodb.BSON.serialize(canonicalInput);
|
|
587
|
+
canonical = canonicalizeValue(plugins.mongodb.BSON.deserialize(serialized));
|
|
588
|
+
reserialized = plugins.mongodb.BSON.serialize(canonical);
|
|
589
|
+
}
|
|
590
|
+
catch (errorArg) {
|
|
591
|
+
throw new SmartdataExactPersistenceError('invalid_document', `${labelArg} is not BSON serializable.`, { cause: errorArg });
|
|
592
|
+
}
|
|
593
|
+
if (!bytesEqual(serialized, reserialized)) {
|
|
594
|
+
throw new SmartdataExactPersistenceError('noncanonical_document', `${labelArg} is not byte-stable across a BSON roundtrip.`);
|
|
595
|
+
}
|
|
596
|
+
return canonical;
|
|
597
|
+
}
|
|
598
|
+
assertAllowedTopLevelKeys(documentArg, allowedMetadataKeysArg, labelArg) {
|
|
599
|
+
const allowedMetadataKeys = new Set(allowedMetadataKeysArg);
|
|
600
|
+
for (const key of Object.keys(documentArg)) {
|
|
601
|
+
if (reservedKeys.includes(key) &&
|
|
602
|
+
!allowedMetadataKeys.has(key)) {
|
|
603
|
+
throw new SmartdataExactPersistenceError('reserved_field', `${labelArg} may not define reserved field "${key}".`);
|
|
604
|
+
}
|
|
605
|
+
if (!this.allowedPersistedKeys.has(key) &&
|
|
606
|
+
!allowedMetadataKeys.has(key)) {
|
|
607
|
+
throw new SmartdataExactPersistenceError('invalid_document', `${labelArg} defines undeclared top-level field "${key}".`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
canonicalizePersistedDocument(documentArg) {
|
|
612
|
+
this.assertAllowedTopLevelKeys(documentArg, [], 'Persisted document');
|
|
613
|
+
const canonical = this.canonicalizeDocument(documentArg, 'Persisted document');
|
|
614
|
+
this.assertWithoutMutation(canonical, 'Persisted document');
|
|
615
|
+
return canonical;
|
|
616
|
+
}
|
|
617
|
+
canonicalizeStoredDocument(documentArg) {
|
|
618
|
+
this.assertAllowedTopLevelKeys(documentArg, storageMetadataKeys, 'Stored document');
|
|
619
|
+
const canonical = this.canonicalizeDocument(documentArg, 'Stored document');
|
|
620
|
+
const revision = canonical._smartdataRevision;
|
|
621
|
+
if (!isMongoObjectId(canonical._id)) {
|
|
622
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'Stored document _id must be a MongoDB ObjectId.');
|
|
623
|
+
}
|
|
624
|
+
if (revision !== undefined &&
|
|
625
|
+
(typeof revision !== 'string' || revision.length === 0)) {
|
|
626
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'Stored document _smartdataRevision must be a nonempty string when present.');
|
|
627
|
+
}
|
|
628
|
+
this.getPersistedBody(canonical);
|
|
629
|
+
return canonical;
|
|
630
|
+
}
|
|
631
|
+
assertWithoutMutation(documentArg, labelArg) {
|
|
632
|
+
assertBsonWithoutMutation(documentArg, this.options.assertDocument, (reasonArg, causeArg) => new SmartdataExactPersistenceError('invalid_document', `${labelArg} ${reasonArg === 'assertion' ? 'assertion failed.' :
|
|
633
|
+
reasonArg === 'bson' ? 'validator produced a non-BSON document.' :
|
|
634
|
+
'validator must not mutate the document.'}`, causeArg === undefined ? undefined : { cause: causeArg }));
|
|
635
|
+
}
|
|
636
|
+
getPersistedBody(storedDocumentArg) {
|
|
637
|
+
const body = Object.create(null);
|
|
638
|
+
for (const key of Object.keys(storedDocumentArg)) {
|
|
639
|
+
if (!reservedKeys.includes(key)) {
|
|
640
|
+
body[key] = storedDocumentArg[key];
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return this.canonicalizePersistedDocument(body);
|
|
644
|
+
}
|
|
645
|
+
persistedDocumentsEqual(leftArg, rightArg) {
|
|
646
|
+
return bytesEqual(plugins.mongodb.BSON.serialize(leftArg), plugins.mongodb.BSON.serialize(rightArg));
|
|
647
|
+
}
|
|
648
|
+
storedDocumentsEqual(leftArg, rightArg) {
|
|
649
|
+
if (!leftArg._id.equals(rightArg._id)) {
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
if (leftArg._smartdataRevision !== rightArg._smartdataRevision) {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
return this.persistedDocumentsEqual(this.getPersistedBody(leftArg), this.getPersistedBody(rightArg));
|
|
656
|
+
}
|
|
657
|
+
validateReconcileIdentity(documentArg) {
|
|
658
|
+
const value = documentArg[this.reconcileBy];
|
|
659
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
660
|
+
throw new SmartdataExactPersistenceError('invalid_document', `Exact persistence reconcileBy field "${this.reconcileBy}" must be a nonempty string.`);
|
|
661
|
+
}
|
|
662
|
+
return value;
|
|
663
|
+
}
|
|
664
|
+
async serializeModel(modelArg) {
|
|
665
|
+
const serialized = (await modelArg.createSavableObject());
|
|
666
|
+
if (typeof serialized !== 'object' ||
|
|
667
|
+
serialized === null ||
|
|
668
|
+
Array.isArray(serialized)) {
|
|
669
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'createSavableObject() must return a document object.');
|
|
670
|
+
}
|
|
671
|
+
for (const key of Object.keys(serialized)) {
|
|
672
|
+
if (!this.allowedPersistedKeys.has(key) &&
|
|
673
|
+
key !== '_createdAt' &&
|
|
674
|
+
key !== '_updatedAt') {
|
|
675
|
+
const code = reservedKeys.includes(key)
|
|
676
|
+
? 'reserved_field'
|
|
677
|
+
: 'invalid_document';
|
|
678
|
+
throw new SmartdataExactPersistenceError(code, `Model serialization produced forbidden top-level field "${key}".`);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const body = Object.create(null);
|
|
682
|
+
for (const key of this.allowedPersistedKeys) {
|
|
683
|
+
if (hasOwn(serialized, key)) {
|
|
684
|
+
body[key] = serialized[key];
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return this.canonicalizePersistedDocument(body);
|
|
688
|
+
}
|
|
689
|
+
async createPersistedDocument(documentArg) {
|
|
690
|
+
if (typeof documentArg !== 'object' || documentArg === null) {
|
|
691
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'Exact persistence insert input must be an object.');
|
|
692
|
+
}
|
|
693
|
+
if (documentArg instanceof this.modelConstructor) {
|
|
694
|
+
return this.serializeModel(documentArg);
|
|
695
|
+
}
|
|
696
|
+
return this.canonicalizePersistedDocument(documentArg);
|
|
697
|
+
}
|
|
698
|
+
hydrateStoredDocument(documentArg) {
|
|
699
|
+
return this.modelConstructor.createInstanceFromMongoDbNativeDoc(documentArg);
|
|
700
|
+
}
|
|
701
|
+
async findByReconcileIdentity(identityArg, sessionArg) {
|
|
702
|
+
const rawDocument = await this.collection.mongoDbCollection.findOne({
|
|
703
|
+
[this.reconcileBy]: identityArg,
|
|
704
|
+
}, { session: sessionArg });
|
|
705
|
+
return rawDocument
|
|
706
|
+
? this.canonicalizeStoredDocument(rawDocument)
|
|
707
|
+
: null;
|
|
708
|
+
}
|
|
709
|
+
ambiguousWriteError(messageArg, causeArg) {
|
|
710
|
+
return new SmartdataExactPersistenceError('ambiguous_write', messageArg, {
|
|
711
|
+
cause: causeArg,
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
canonicalizeDeleteCurrent(optionsArg) {
|
|
715
|
+
if (typeof optionsArg !== 'object' ||
|
|
716
|
+
optionsArg === null ||
|
|
717
|
+
plugins.nodeUtil.types.isProxy(optionsArg) ||
|
|
718
|
+
!isPlainObject(optionsArg)) {
|
|
719
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'Exact delete options must be an object containing only current.');
|
|
720
|
+
}
|
|
721
|
+
const optionKeys = Reflect.ownKeys(optionsArg);
|
|
722
|
+
const currentDescriptor = Object.getOwnPropertyDescriptor(optionsArg, 'current');
|
|
723
|
+
if (optionKeys.length !== 1 ||
|
|
724
|
+
optionKeys[0] !== 'current' ||
|
|
725
|
+
!currentDescriptor ||
|
|
726
|
+
!('value' in currentDescriptor) ||
|
|
727
|
+
currentDescriptor.enumerable !== true) {
|
|
728
|
+
throw new SmartdataExactPersistenceError('invalid_document', 'Exact delete options must contain one inert enumerable current data property.');
|
|
729
|
+
}
|
|
730
|
+
const currentSnapshot = snapshotInertExactValue(currentDescriptor.value, 'Exact delete current');
|
|
731
|
+
const current = this.canonicalizeStoredDocument(currentSnapshot);
|
|
732
|
+
const identity = this.validateReconcileIdentity(this.getPersistedBody(current));
|
|
733
|
+
return { current, identity };
|
|
734
|
+
}
|
|
735
|
+
async reconcileDeleteOutcome(currentArg, identityArg, causeArg, sessionArg) {
|
|
736
|
+
let reconciled;
|
|
737
|
+
try {
|
|
738
|
+
reconciled = await this.findByReconcileIdentity(identityArg, sessionArg);
|
|
739
|
+
}
|
|
740
|
+
catch (errorArg) {
|
|
741
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
742
|
+
throw errorArg;
|
|
743
|
+
}
|
|
744
|
+
throw this.ambiguousWriteError('Exact delete outcome was inconclusive and reconciliation could not be completed.', causeArg);
|
|
745
|
+
}
|
|
746
|
+
if (reconciled && reconciled._id.equals(currentArg._id)) {
|
|
747
|
+
return { status: 'concurrent_change', deletedCount: 0 };
|
|
748
|
+
}
|
|
749
|
+
throw this.ambiguousWriteError('Exact delete outcome was inconclusive and could not be authoritatively reconciled.', causeArg);
|
|
750
|
+
}
|
|
751
|
+
async insert(documentArg, optionsArg = {}) {
|
|
752
|
+
return this.runOperation(optionsArg, async (sessionArg) => {
|
|
753
|
+
const persistedDocument = await this.createPersistedDocument(documentArg);
|
|
754
|
+
const identity = this.validateReconcileIdentity(persistedDocument);
|
|
755
|
+
const expectedStoredDocument = this.canonicalizeStoredDocument({
|
|
756
|
+
_id: new plugins.mongodb.ObjectId(),
|
|
757
|
+
...persistedDocument,
|
|
758
|
+
});
|
|
759
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
760
|
+
const existing = await this.findByReconcileIdentity(identity, sessionArg);
|
|
761
|
+
if (existing) {
|
|
762
|
+
return this.persistedDocumentsEqual(this.getPersistedBody(existing), persistedDocument)
|
|
763
|
+
? { status: 'already_committed', document: existing }
|
|
764
|
+
: { status: 'conflict', document: existing };
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
let result;
|
|
768
|
+
try {
|
|
769
|
+
result = await this.collection.mongoDbCollection.insertOne(expectedStoredDocument, { session: sessionArg });
|
|
770
|
+
}
|
|
771
|
+
catch (errorArg) {
|
|
772
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
773
|
+
throw errorArg;
|
|
774
|
+
}
|
|
775
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
776
|
+
if (isDuplicateKeyError(errorArg)) {
|
|
777
|
+
throw new SmartdataExactPersistenceError('unique_conflict', 'Exact transactional insert conflicts with a unique index.', { cause: errorArg });
|
|
778
|
+
}
|
|
779
|
+
throw errorArg;
|
|
780
|
+
}
|
|
781
|
+
let reconciled;
|
|
782
|
+
try {
|
|
783
|
+
reconciled = await this.findByReconcileIdentity(identity, sessionArg);
|
|
784
|
+
}
|
|
785
|
+
catch (reconciliationError) {
|
|
786
|
+
if (isTransientTransactionError(reconciliationError, sessionArg)) {
|
|
787
|
+
throw reconciliationError;
|
|
788
|
+
}
|
|
789
|
+
if (isDuplicateKeyError(errorArg)) {
|
|
790
|
+
throw new SmartdataExactPersistenceError('unique_conflict', 'Exact insert conflicts with a unique index and reconciliation failed.', { cause: errorArg });
|
|
791
|
+
}
|
|
792
|
+
throw this.ambiguousWriteError('Exact insert failed and reconciliation could not be completed.', errorArg);
|
|
793
|
+
}
|
|
794
|
+
if (reconciled) {
|
|
795
|
+
if (this.persistedDocumentsEqual(this.getPersistedBody(reconciled), persistedDocument)) {
|
|
796
|
+
return { status: 'already_committed', document: reconciled };
|
|
797
|
+
}
|
|
798
|
+
if (isDuplicateKeyError(errorArg)) {
|
|
799
|
+
return { status: 'conflict', document: reconciled };
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
if (isDuplicateKeyError(errorArg)) {
|
|
803
|
+
throw new SmartdataExactPersistenceError('unique_conflict', 'Exact insert conflicts with a secondary unique index.', { cause: errorArg });
|
|
804
|
+
}
|
|
805
|
+
throw this.ambiguousWriteError('Exact insert failed and its outcome could not be reconciled.', errorArg);
|
|
806
|
+
}
|
|
807
|
+
if (!result.acknowledged) {
|
|
808
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
809
|
+
throw this.ambiguousWriteError('Exact transactional insert was not acknowledged.', result);
|
|
810
|
+
}
|
|
811
|
+
let reconciled;
|
|
812
|
+
try {
|
|
813
|
+
reconciled = await this.findByReconcileIdentity(identity, sessionArg);
|
|
814
|
+
}
|
|
815
|
+
catch (errorArg) {
|
|
816
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
817
|
+
throw errorArg;
|
|
818
|
+
}
|
|
819
|
+
throw this.ambiguousWriteError('Exact insert was not acknowledged and reconciliation could not be completed.', result);
|
|
820
|
+
}
|
|
821
|
+
if (reconciled &&
|
|
822
|
+
this.persistedDocumentsEqual(this.getPersistedBody(reconciled), persistedDocument)) {
|
|
823
|
+
return { status: 'already_committed', document: reconciled };
|
|
824
|
+
}
|
|
825
|
+
throw this.ambiguousWriteError('Exact insert was not acknowledged and could not be reconciled.', result);
|
|
826
|
+
}
|
|
827
|
+
return { status: 'inserted', document: expectedStoredDocument };
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
toPersisted(storedDocumentArg) {
|
|
831
|
+
const storedDocument = this.canonicalizeStoredDocument(storedDocumentArg);
|
|
832
|
+
const persistedDocument = this.getPersistedBody(storedDocument);
|
|
833
|
+
return plugins.mongodb.BSON.deserialize(plugins.mongodb.BSON.serialize(persistedDocument));
|
|
834
|
+
}
|
|
835
|
+
canonicalBytes(persistedDocumentArg) {
|
|
836
|
+
return plugins.mongodb.BSON.serialize(this.canonicalizePersistedDocument(persistedDocumentArg));
|
|
837
|
+
}
|
|
838
|
+
async findStoredOne(filterArg, optionsArg = {}) {
|
|
839
|
+
return this.runOperation(optionsArg, async (sessionArg) => {
|
|
840
|
+
const cursor = this.collection.mongoDbCollection.find(convertFilterForMongoDb(filterArg), {
|
|
841
|
+
session: sessionArg,
|
|
842
|
+
signal: optionsArg.signal,
|
|
843
|
+
singleBatch: true,
|
|
844
|
+
}).limit(1);
|
|
845
|
+
const nativeCursorClose = cursor.close.bind(cursor);
|
|
846
|
+
let cursorClosePromise;
|
|
847
|
+
cursor.close = ((...args) => {
|
|
848
|
+
cursorClosePromise ??= nativeCursorClose(...args);
|
|
849
|
+
return cursorClosePromise;
|
|
850
|
+
});
|
|
851
|
+
let storedDocument;
|
|
852
|
+
try {
|
|
853
|
+
const rawDocument = await cursor.next();
|
|
854
|
+
storedDocument = rawDocument
|
|
855
|
+
? this.canonicalizeStoredDocument(rawDocument)
|
|
856
|
+
: null;
|
|
857
|
+
}
|
|
858
|
+
catch (errorArg) {
|
|
859
|
+
try {
|
|
860
|
+
await cursor.close();
|
|
861
|
+
}
|
|
862
|
+
catch {
|
|
863
|
+
// Cleanup must not replace the exact primary operation error.
|
|
864
|
+
}
|
|
865
|
+
throw errorArg;
|
|
866
|
+
}
|
|
867
|
+
await cursor.close();
|
|
868
|
+
return storedDocument;
|
|
869
|
+
}, optionsArg.signal);
|
|
870
|
+
}
|
|
871
|
+
async findStored(optionsArg = {}) {
|
|
872
|
+
optionsArg.signal?.throwIfAborted();
|
|
873
|
+
return this.runOperation(optionsArg, async (sessionArg) => {
|
|
874
|
+
let cursor = this.collection.mongoDbCollection.find(convertFilterForMongoDb(optionsArg.filter || {}), { session: sessionArg, signal: optionsArg.signal });
|
|
875
|
+
// The driver abort listener does not await close, so every close must join
|
|
876
|
+
// the same native cleanup before runOperation releases its session lease.
|
|
877
|
+
const nativeCursorClose = cursor.close.bind(cursor);
|
|
878
|
+
let cursorClosePromise;
|
|
879
|
+
cursor.close = ((...args) => {
|
|
880
|
+
cursorClosePromise ??= nativeCursorClose(...args);
|
|
881
|
+
return cursorClosePromise;
|
|
882
|
+
});
|
|
883
|
+
let storedDocuments;
|
|
884
|
+
try {
|
|
885
|
+
if (optionsArg.sort) {
|
|
886
|
+
cursor = cursor.sort(optionsArg.sort);
|
|
887
|
+
}
|
|
888
|
+
if (optionsArg.skip !== undefined) {
|
|
889
|
+
cursor = cursor.skip(optionsArg.skip);
|
|
890
|
+
}
|
|
891
|
+
if (optionsArg.limit !== undefined) {
|
|
892
|
+
cursor = cursor.limit(optionsArg.limit);
|
|
893
|
+
}
|
|
894
|
+
const rawDocuments = await cursor.toArray();
|
|
895
|
+
storedDocuments = rawDocuments.map((documentArg) => this.canonicalizeStoredDocument(documentArg));
|
|
896
|
+
}
|
|
897
|
+
catch (errorArg) {
|
|
898
|
+
try {
|
|
899
|
+
await cursor.close();
|
|
900
|
+
}
|
|
901
|
+
catch {
|
|
902
|
+
// Cleanup must not replace the exact primary operation error.
|
|
903
|
+
}
|
|
904
|
+
throw errorArg;
|
|
905
|
+
}
|
|
906
|
+
await cursor.close();
|
|
907
|
+
return storedDocuments;
|
|
908
|
+
}, optionsArg.signal);
|
|
909
|
+
}
|
|
910
|
+
async count(filterArg = {}, optionsArg = {}) {
|
|
911
|
+
return this.runOperation(optionsArg, async (sessionArg) => this.collection.mongoDbCollection.countDocuments(convertFilterForMongoDb(filterArg), { session: sessionArg }));
|
|
912
|
+
}
|
|
913
|
+
async distinct(fieldArg, filterArg = {}, optionsArg = {}) {
|
|
914
|
+
return this.runOperation(optionsArg, async (sessionArg) => (await this.collection.mongoDbCollection.distinct(fieldArg, convertFilterForMongoDb(filterArg), { session: sessionArg })));
|
|
915
|
+
}
|
|
916
|
+
async transition(optionsArg, sessionOptionsArg = {}) {
|
|
917
|
+
return this.runOperation(sessionOptionsArg, async (sessionArg) => {
|
|
918
|
+
const current = this.canonicalizeStoredDocument(optionsArg.current);
|
|
919
|
+
const currentBody = this.getPersistedBody(current);
|
|
920
|
+
const currentIdentity = this.validateReconcileIdentity(currentBody);
|
|
921
|
+
const model = this.hydrateStoredDocument(current);
|
|
922
|
+
const untouchedBody = await this.serializeModel(model);
|
|
923
|
+
if (!this.persistedDocumentsEqual(currentBody, untouchedBody)) {
|
|
924
|
+
throw new SmartdataExactPersistenceError('noncanonical_document', 'Stored document does not survive an untouched model serialization roundtrip.');
|
|
925
|
+
}
|
|
926
|
+
const changeResult = optionsArg.change(model);
|
|
927
|
+
if (changeResult !== null &&
|
|
928
|
+
(typeof changeResult === 'object' || typeof changeResult === 'function') &&
|
|
929
|
+
typeof changeResult.then === 'function') {
|
|
930
|
+
void Promise.resolve(changeResult).catch(() => undefined);
|
|
931
|
+
throw new SmartdataExactPersistenceError('unsupported_operation', 'Exact persistence transition callbacks must be synchronous.');
|
|
932
|
+
}
|
|
933
|
+
const candidateBody = await this.serializeModel(model);
|
|
934
|
+
const candidateIdentity = this.validateReconcileIdentity(candidateBody);
|
|
935
|
+
if (candidateIdentity !== currentIdentity) {
|
|
936
|
+
throw new SmartdataExactPersistenceError('invalid_document', `Exact persistence reconcileBy field "${this.reconcileBy}" is immutable.`);
|
|
937
|
+
}
|
|
938
|
+
const newRevision = globalThis.crypto.randomUUID();
|
|
939
|
+
const expectedStoredDocument = this.canonicalizeStoredDocument({
|
|
940
|
+
_id: current._id,
|
|
941
|
+
...candidateBody,
|
|
942
|
+
_smartdataRevision: newRevision,
|
|
943
|
+
});
|
|
944
|
+
const selector = current._smartdataRevision !== undefined
|
|
945
|
+
? { _id: current._id, _smartdataRevision: current._smartdataRevision }
|
|
946
|
+
: { _id: current._id, _smartdataRevision: { $exists: false } };
|
|
947
|
+
try {
|
|
948
|
+
const postimage = await this.collection.mongoDbCollection.findOneAndReplace(selector, expectedStoredDocument, {
|
|
949
|
+
returnDocument: 'after',
|
|
950
|
+
includeResultMetadata: false,
|
|
951
|
+
upsert: false,
|
|
952
|
+
session: sessionArg,
|
|
953
|
+
});
|
|
954
|
+
if (!postimage) {
|
|
955
|
+
return { status: 'concurrent_change' };
|
|
956
|
+
}
|
|
957
|
+
const canonicalPostimage = this.canonicalizeStoredDocument(postimage);
|
|
958
|
+
if (!this.storedDocumentsEqual(canonicalPostimage, expectedStoredDocument)) {
|
|
959
|
+
throw new SmartdataExactPersistenceError('ambiguous_write', 'Exact transition returned a postimage different from the requested state.');
|
|
960
|
+
}
|
|
961
|
+
return { status: 'transitioned', document: canonicalPostimage };
|
|
962
|
+
}
|
|
963
|
+
catch (errorArg) {
|
|
964
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
965
|
+
throw errorArg;
|
|
966
|
+
}
|
|
967
|
+
if (isDuplicateKeyError(errorArg)) {
|
|
968
|
+
throw new SmartdataExactPersistenceError('unique_conflict', 'Exact transition conflicts with a secondary unique index.', { cause: errorArg });
|
|
969
|
+
}
|
|
970
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
971
|
+
throw errorArg;
|
|
972
|
+
}
|
|
973
|
+
try {
|
|
974
|
+
const reconciledRaw = await this.collection.mongoDbCollection.findOne({
|
|
975
|
+
_id: current._id,
|
|
976
|
+
}, { session: sessionArg });
|
|
977
|
+
if (reconciledRaw) {
|
|
978
|
+
const reconciled = this.canonicalizeStoredDocument(reconciledRaw);
|
|
979
|
+
if (reconciled._smartdataRevision === newRevision &&
|
|
980
|
+
this.storedDocumentsEqual(reconciled, expectedStoredDocument)) {
|
|
981
|
+
return { status: 'transitioned', document: reconciled };
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
catch (reconciliationError) {
|
|
986
|
+
if (isTransientTransactionError(reconciliationError, sessionArg)) {
|
|
987
|
+
throw reconciliationError;
|
|
988
|
+
}
|
|
989
|
+
throw this.ambiguousWriteError('Exact transition failed and reconciliation could not be completed.', errorArg);
|
|
990
|
+
}
|
|
991
|
+
throw this.ambiguousWriteError('Exact transition failed and its outcome could not be reconciled.', errorArg);
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
async delete(optionsArg, sessionOptionsArg = {}) {
|
|
996
|
+
const { current, identity } = this.canonicalizeDeleteCurrent(optionsArg);
|
|
997
|
+
return this.runOperation(sessionOptionsArg, async (sessionArg) => {
|
|
998
|
+
const selector = current._smartdataRevision !== undefined
|
|
999
|
+
? {
|
|
1000
|
+
_id: current._id,
|
|
1001
|
+
[this.reconcileBy]: identity,
|
|
1002
|
+
_smartdataRevision: current._smartdataRevision,
|
|
1003
|
+
}
|
|
1004
|
+
: {
|
|
1005
|
+
_id: current._id,
|
|
1006
|
+
[this.reconcileBy]: identity,
|
|
1007
|
+
_smartdataRevision: { $exists: false },
|
|
1008
|
+
};
|
|
1009
|
+
let result;
|
|
1010
|
+
try {
|
|
1011
|
+
result = await this.collection.mongoDbCollection.deleteOne(selector, {
|
|
1012
|
+
session: sessionArg,
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
catch (errorArg) {
|
|
1016
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
1017
|
+
throw errorArg;
|
|
1018
|
+
}
|
|
1019
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
1020
|
+
throw errorArg;
|
|
1021
|
+
}
|
|
1022
|
+
return this.reconcileDeleteOutcome(current, identity, errorArg, sessionArg);
|
|
1023
|
+
}
|
|
1024
|
+
if (result.acknowledged === true &&
|
|
1025
|
+
result.deletedCount === 1) {
|
|
1026
|
+
return { status: 'deleted', deletedCount: 1 };
|
|
1027
|
+
}
|
|
1028
|
+
if (result.acknowledged === true &&
|
|
1029
|
+
result.deletedCount === 0) {
|
|
1030
|
+
return { status: 'concurrent_change', deletedCount: 0 };
|
|
1031
|
+
}
|
|
1032
|
+
if (result.acknowledged === false) {
|
|
1033
|
+
if (hasActiveTransaction(sessionArg)) {
|
|
1034
|
+
throw this.ambiguousWriteError('Exact transactional delete was not acknowledged.', result);
|
|
1035
|
+
}
|
|
1036
|
+
return this.reconcileDeleteOutcome(current, identity, result, sessionArg);
|
|
1037
|
+
}
|
|
1038
|
+
try {
|
|
1039
|
+
await this.findByReconcileIdentity(identity, sessionArg);
|
|
1040
|
+
}
|
|
1041
|
+
catch (errorArg) {
|
|
1042
|
+
if (isTransientTransactionError(errorArg, sessionArg)) {
|
|
1043
|
+
throw errorArg;
|
|
1044
|
+
}
|
|
1045
|
+
throw this.ambiguousWriteError('Exact delete returned an invalid result and reconciliation could not be completed.', result);
|
|
1046
|
+
}
|
|
1047
|
+
throw this.ambiguousWriteError('Exact delete returned an invalid acknowledged result.', result);
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
export function exactPersistence(optionsArg) {
|
|
1052
|
+
return function classDecorator(valueArg, contextArg) {
|
|
1053
|
+
if (contextArg.kind !== 'class') {
|
|
1054
|
+
throw new Error('exactPersistence can only decorate classes.');
|
|
1055
|
+
}
|
|
1056
|
+
if (getOrdinaryPersistencePolicy(valueArg)) {
|
|
1057
|
+
throw new Error('Ordinary and exact persistence policies cannot be combined.');
|
|
1058
|
+
}
|
|
1059
|
+
const exactOptions = Object.freeze({ ...optionsArg });
|
|
1060
|
+
const constructor = valueArg;
|
|
1061
|
+
const exactPolicy = Object.freeze({
|
|
1062
|
+
options: exactOptions,
|
|
1063
|
+
unsupportedSave: unsupportedExactSave,
|
|
1064
|
+
forbiddenDelete: forbiddenExactDelete,
|
|
1065
|
+
});
|
|
1066
|
+
Object.defineProperty(constructor, exactPersistencePolicySymbol, {
|
|
1067
|
+
value: exactPolicy,
|
|
1068
|
+
enumerable: false,
|
|
1069
|
+
configurable: false,
|
|
1070
|
+
writable: false,
|
|
1071
|
+
});
|
|
1072
|
+
Object.defineProperty(constructor.prototype, 'save', {
|
|
1073
|
+
value: unsupportedExactSave,
|
|
1074
|
+
enumerable: false,
|
|
1075
|
+
configurable: false,
|
|
1076
|
+
writable: false,
|
|
1077
|
+
});
|
|
1078
|
+
Object.defineProperty(constructor.prototype, 'delete', {
|
|
1079
|
+
value: forbiddenExactDelete,
|
|
1080
|
+
enumerable: false,
|
|
1081
|
+
configurable: false,
|
|
1082
|
+
writable: false,
|
|
1083
|
+
});
|
|
1084
|
+
Object.defineProperty(constructor, 'exact', {
|
|
1085
|
+
get() {
|
|
1086
|
+
const receiver = this;
|
|
1087
|
+
if (typeof receiver !== 'function' || (receiver !== constructor
|
|
1088
|
+
&& !Object.prototype.isPrototypeOf.call(constructor, receiver))
|
|
1089
|
+
|| Reflect.get(receiver, exactPersistencePolicySymbol) !== exactPolicy) {
|
|
1090
|
+
throw new SmartdataExactPersistenceError('invalid_configuration', 'Exact persistence requires the decorated model or an inheriting receiver.');
|
|
1091
|
+
}
|
|
1092
|
+
const collection = receiver.collection;
|
|
1093
|
+
let byCollection = exactCollectionCache.get(receiver);
|
|
1094
|
+
if (!byCollection) {
|
|
1095
|
+
byCollection = new WeakMap();
|
|
1096
|
+
exactCollectionCache.set(receiver, byCollection);
|
|
1097
|
+
}
|
|
1098
|
+
let exactCollection = byCollection.get(collection);
|
|
1099
|
+
if (!exactCollection) {
|
|
1100
|
+
exactCollection = new SmartdataExactCollection(receiver, collection, exactOptions);
|
|
1101
|
+
byCollection.set(collection, exactCollection);
|
|
1102
|
+
}
|
|
1103
|
+
return exactCollection;
|
|
1104
|
+
},
|
|
1105
|
+
enumerable: false,
|
|
1106
|
+
configurable: false,
|
|
1107
|
+
});
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5leGFjdHBlcnNpc3RlbmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvbm9zcWxkYi9jbGFzc2VzLmV4YWN0cGVyc2lzdGVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdkUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFHaEYsT0FBTyxFQUFFLGtDQUFrQyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFdEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDL0QsT0FBTyxFQUNMLHVCQUF1QixHQUl4QixNQUFNLGtCQUFrQixDQUFDO0FBRTFCLE1BQU0sNEJBQTRCLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FDN0MsOENBQThDLENBQy9DLENBQUM7QUFFRixNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBSyxFQUFFLG9CQUFvQixDQUFVLENBQUM7QUFDbkUsTUFBTSxZQUFZLEdBQUc7SUFDbkIsR0FBRyxtQkFBbUI7SUFDdEIsWUFBWTtJQUNaLFlBQVk7Q0FDSixDQUFDO0FBa0dYLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUM3QixRQUFpQixFQUNxQixFQUFFLENBQ3hDLFFBQVEsWUFBWSxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQXdDL0MsTUFBTSxPQUFPLDhCQUErQixTQUFRLEtBQUs7SUFDdkMsSUFBSSxDQUE2QjtJQUVqRCxZQUNFLE9BQW1DLEVBQ25DLFVBQWtCLEVBQ2xCLFVBQXlCO1FBRXpCLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLElBQUksR0FBRyxn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
|