@lossless.org/client 1.20.1 → 1.21.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.losslessorgclient.js +1 -1
- package/dist_ts/core/classes.error.js +1 -1
- package/dist_ts/core/classes.operation.js +1 -1
- package/dist_ts/nosqldb/classes.atomicdelete.js +3 -3
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +2 -2
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +6 -3
- package/dist_ts/nosqldb/classes.atomicupdate.js +4 -4
- package/dist_ts/nosqldb/classes.bootstraprecord.js +10 -5
- package/dist_ts/nosqldb/classes.bsonassertion.d.ts +1 -1
- package/dist_ts/nosqldb/classes.bsonsnapshot.js +1 -1
- package/dist_ts/nosqldb/classes.collection.js +91 -38
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +1 -1
- package/dist_ts/nosqldb/classes.collectiontopology.js +1 -1
- package/dist_ts/nosqldb/classes.connection.js +1 -1
- package/dist_ts/nosqldb/classes.cursor.d.ts +4 -1
- package/dist_ts/nosqldb/classes.cursor.js +14 -3
- package/dist_ts/nosqldb/classes.cursoroperation.d.ts +1 -1
- package/dist_ts/nosqldb/classes.db.d.ts +22 -0
- package/dist_ts/nosqldb/classes.db.js +25 -1
- package/dist_ts/nosqldb/classes.doc.js +35 -5
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +6 -0
- package/dist_ts/nosqldb/classes.exactpersistence.js +70 -13
- package/dist_ts/nosqldb/classes.lucene.adapter.js +1 -1
- package/dist_ts/nosqldb/classes.mongoadministration.js +1 -1
- package/dist_ts/nosqldb/classes.namespaceinspection.js +1 -1
- package/dist_ts/nosqldb/classes.operationdeadline.js +1 -1
- package/dist_ts/nosqldb/classes.readtracker.d.ts +87 -0
- package/dist_ts/nosqldb/classes.readtracker.js +876 -0
- package/dist_ts/nosqldb/classes.session.d.ts +32 -9
- package/dist_ts/nosqldb/classes.session.js +116 -26
- package/dist_ts/nosqldb/classes.storedinspection.js +12 -4
- package/dist_ts/nosqldb/classes.testdatabase.js +16 -9
- package/dist_ts/nosqldb/classes.writeobserver.d.ts +11 -0
- package/dist_ts/nosqldb/classes.writeobserver.js +1 -1
- package/dist_ts/objectstorage/classes.bucket.js +1 -1
- package/dist_ts/objectstorage/classes.connection.js +1 -1
- package/dist_ts/objectstorage/classes.directory.js +1 -1
- package/dist_ts/objectstorage/classes.file.js +1 -1
- package/dist_ts/objectstorage/classes.listcursor.js +1 -1
- package/dist_ts/objectstorage/classes.smartbucket.js +1 -1
- package/dist_ts/objectstorage/classes.watcher.js +1 -1
- package/dist_ts/objectstorage/internal.exactpathpurge.operations.js +1 -1
- package/dist_ts/objectstorage/internal.exactupload.capability.js +1 -1
- package/dist_ts/objectstorage/internal.exactupload.operations.js +1 -1
- package/dist_ts/sqldb/classes.clickhouseconnection.d.ts +1 -1
- package/dist_ts/sqldb/classes.clickhouseconnection.js +1 -1
- package/dist_ts/sqldb/classes.sqlconnection.js +1 -1
- package/dist_ts/sqldb/classes.sqltable.js +1 -1
- package/dist_ts/sqldb/clickhouse/classes.metricwriter.js +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.clickhousetable.js +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.d.ts +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.httpclient.js +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.querybuilder.js +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.smartclickhouse.js +1 -1
- package/dist_ts/sqldb/clickhouse/smartclickhouse.classes.timedatatable.js +1 -1
- package/dist_ts/sqldb/internal.sqlpool.js +1 -1
- package/package.json +2 -2
- package/readme.md +1 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/nosqldb/classes.atomicdelete.ts +16 -2
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +5 -0
- package/ts/nosqldb/classes.atomicupdate.ts +10 -1
- package/ts/nosqldb/classes.bootstraprecord.ts +7 -4
- package/ts/nosqldb/classes.collection.ts +112 -46
- package/ts/nosqldb/classes.cursor.ts +14 -1
- package/ts/nosqldb/classes.db.ts +32 -0
- package/ts/nosqldb/classes.doc.ts +32 -2
- package/ts/nosqldb/classes.exactpersistence.ts +93 -19
- package/ts/nosqldb/classes.readtracker.ts +1028 -0
- package/ts/nosqldb/classes.session.ts +163 -30
- package/ts/nosqldb/classes.storedinspection.ts +15 -3
- package/ts/nosqldb/classes.testdatabase.ts +14 -8
- package/ts/nosqldb/classes.writeobserver.ts +11 -0
|
@@ -10,9 +10,12 @@ import type { SmartdataSession } from './classes.session.js';
|
|
|
10
10
|
import {
|
|
11
11
|
acquireSmartdataSession,
|
|
12
12
|
reportSmartdataCollectionWrite,
|
|
13
|
+
reportSmartdataWriteFailure,
|
|
13
14
|
settleSmartdataOperationError,
|
|
14
15
|
resolveSmartdataOperationDeadline,
|
|
16
|
+
trackSmartdataRead,
|
|
15
17
|
} from './classes.session.js';
|
|
18
|
+
import { runSmartdataWrite } from './classes.readtracker.js';
|
|
16
19
|
import {
|
|
17
20
|
type SmartdataOperationDeadline,
|
|
18
21
|
requireOperationSignal,
|
|
@@ -1135,6 +1138,35 @@ export class SmartdataExactCollection<
|
|
|
1135
1138
|
}
|
|
1136
1139
|
}
|
|
1137
1140
|
|
|
1141
|
+
/**
|
|
1142
|
+
* Runs one exact write through `runOperation`. A write that fails once
|
|
1143
|
+
* started may still have applied, so it changes every open read set that
|
|
1144
|
+
* read the collection.
|
|
1145
|
+
*/
|
|
1146
|
+
private async runWriteOperation<TResult>(
|
|
1147
|
+
optionsArg: IExactBoundedOptions,
|
|
1148
|
+
operationArg: (
|
|
1149
|
+
sessionArg: plugins.mongodb.ClientSession | undefined,
|
|
1150
|
+
deadlineArg: SmartdataOperationDeadline,
|
|
1151
|
+
) => Promise<TResult>,
|
|
1152
|
+
): Promise<TResult> {
|
|
1153
|
+
let started = false;
|
|
1154
|
+
try {
|
|
1155
|
+
return await runSmartdataWrite(this.collection.smartdataDb, () =>
|
|
1156
|
+
this.runOperation(optionsArg, (sessionArg, deadlineArg) => {
|
|
1157
|
+
started = true;
|
|
1158
|
+
return operationArg(sessionArg, deadlineArg);
|
|
1159
|
+
}));
|
|
1160
|
+
} catch (errorArg) {
|
|
1161
|
+
if (started) {
|
|
1162
|
+
reportSmartdataWriteFailure(
|
|
1163
|
+
this.collection.smartdataDb, optionsArg.session, this.collection.collectionName,
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
throw errorArg;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1138
1170
|
/**
|
|
1139
1171
|
* The error of a non-transactional write that its client deadline or
|
|
1140
1172
|
* signal interrupted after the write was handed to the driver: the command
|
|
@@ -1531,7 +1563,7 @@ export class SmartdataExactCollection<
|
|
|
1531
1563
|
documentArg: TModel | TExactPersistedDocument<TPersisted>,
|
|
1532
1564
|
optionsArg: IExactBoundedOptions = {},
|
|
1533
1565
|
): Promise<TExactInsertResult<TPersisted>> {
|
|
1534
|
-
return this.
|
|
1566
|
+
return this.runWriteOperation(optionsArg, async (sessionArg, deadlineArg) => {
|
|
1535
1567
|
const persistedBytes = await this.createPersistedDocument(documentArg);
|
|
1536
1568
|
const persistedDocument = this.decodeCanonical<
|
|
1537
1569
|
TExactPersistedDocument<TPersisted>
|
|
@@ -1554,7 +1586,8 @@ export class SmartdataExactCollection<
|
|
|
1554
1586
|
const reportReconciledInsert = (storedArg: TStoredDocument<TPersisted>): void => {
|
|
1555
1587
|
if (storedArg._id.equals(expectedStoredDocument._id)) {
|
|
1556
1588
|
reportSmartdataCollectionWrite(
|
|
1557
|
-
this.collection, optionsArg.session, 'insert', [expectedStoredDocument],
|
|
1589
|
+
this.collection, optionsArg.session, 'insert', [expectedStoredDocument], undefined,
|
|
1590
|
+
{ images: 'after' },
|
|
1558
1591
|
);
|
|
1559
1592
|
}
|
|
1560
1593
|
};
|
|
@@ -1652,7 +1685,8 @@ export class SmartdataExactCollection<
|
|
|
1652
1685
|
);
|
|
1653
1686
|
}
|
|
1654
1687
|
reportSmartdataCollectionWrite(
|
|
1655
|
-
this.collection, optionsArg.session, 'insert', [expectedStoredDocument],
|
|
1688
|
+
this.collection, optionsArg.session, 'insert', [expectedStoredDocument], undefined,
|
|
1689
|
+
{ images: 'after' },
|
|
1656
1690
|
);
|
|
1657
1691
|
return { status: 'inserted', document: expectedStoredDocument };
|
|
1658
1692
|
});
|
|
@@ -1677,8 +1711,14 @@ export class SmartdataExactCollection<
|
|
|
1677
1711
|
optionsArg: IExactBoundedOptions = {},
|
|
1678
1712
|
): Promise<TStoredDocument<TPersisted> | null> {
|
|
1679
1713
|
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) => {
|
|
1714
|
+
const filter = convertFilterForMongoDb(filterArg);
|
|
1715
|
+
const tracked = trackSmartdataRead(this.collection, optionsArg.session, {
|
|
1716
|
+
kind: 'documents',
|
|
1717
|
+
filter,
|
|
1718
|
+
limited: true,
|
|
1719
|
+
});
|
|
1680
1720
|
const cursor = this.collection.mongoDbCollection.find(
|
|
1681
|
-
|
|
1721
|
+
filter,
|
|
1682
1722
|
{
|
|
1683
1723
|
session: sessionArg,
|
|
1684
1724
|
singleBatch: true,
|
|
@@ -1694,6 +1734,8 @@ export class SmartdataExactCollection<
|
|
|
1694
1734
|
let storedDocument: TStoredDocument<TPersisted> | null;
|
|
1695
1735
|
try {
|
|
1696
1736
|
const rawDocument = await cursor.next();
|
|
1737
|
+
if (rawDocument) tracked?.record(rawDocument);
|
|
1738
|
+
tracked?.settle();
|
|
1697
1739
|
storedDocument = rawDocument
|
|
1698
1740
|
? this.readStoredDocument(rawDocument).document
|
|
1699
1741
|
: null;
|
|
@@ -1714,8 +1756,17 @@ export class SmartdataExactCollection<
|
|
|
1714
1756
|
optionsArg: IFindStoredOptions<TPersisted> = {},
|
|
1715
1757
|
): Promise<Array<TStoredDocument<TPersisted>>> {
|
|
1716
1758
|
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) => {
|
|
1759
|
+
const filter = convertFilterForMongoDb(optionsArg.filter || {});
|
|
1760
|
+
// A skipped page depends on the documents before it, which it never returns.
|
|
1761
|
+
const tracked = trackSmartdataRead(this.collection, optionsArg.session, {
|
|
1762
|
+
kind: 'documents',
|
|
1763
|
+
filter,
|
|
1764
|
+
sort: optionsArg.sort,
|
|
1765
|
+
matches: optionsArg.skip !== undefined && optionsArg.skip > 0,
|
|
1766
|
+
limited: optionsArg.limit !== undefined,
|
|
1767
|
+
});
|
|
1717
1768
|
let cursor = this.collection.mongoDbCollection.find(
|
|
1718
|
-
|
|
1769
|
+
filter,
|
|
1719
1770
|
{ session: sessionArg, ...deadlineArg.cursorOptions() },
|
|
1720
1771
|
);
|
|
1721
1772
|
// The driver abort listener does not await close, so every close must join
|
|
@@ -1738,6 +1789,8 @@ export class SmartdataExactCollection<
|
|
|
1738
1789
|
cursor = cursor.limit(optionsArg.limit);
|
|
1739
1790
|
}
|
|
1740
1791
|
const rawDocuments = await cursor.toArray();
|
|
1792
|
+
for (const rawDocument of rawDocuments) tracked?.record(rawDocument);
|
|
1793
|
+
tracked?.settle();
|
|
1741
1794
|
storedDocuments = rawDocuments.map((documentArg) =>
|
|
1742
1795
|
this.readStoredDocument(documentArg).document,
|
|
1743
1796
|
);
|
|
@@ -1758,12 +1811,16 @@ export class SmartdataExactCollection<
|
|
|
1758
1811
|
filterArg: MongoFilter<TStoredDocument<TPersisted>> = {},
|
|
1759
1812
|
optionsArg: IExactBoundedOptions = {},
|
|
1760
1813
|
): Promise<number> {
|
|
1761
|
-
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) =>
|
|
1762
|
-
|
|
1763
|
-
|
|
1814
|
+
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) => {
|
|
1815
|
+
const filter = convertFilterForMongoDb(filterArg);
|
|
1816
|
+
const tracked = trackSmartdataRead(this.collection, optionsArg.session, { kind: 'count', filter });
|
|
1817
|
+
const count = await this.collection.mongoDbCollection.countDocuments(
|
|
1818
|
+
filter,
|
|
1764
1819
|
{ session: sessionArg, ...deadlineArg.commandOptions() },
|
|
1765
|
-
)
|
|
1766
|
-
|
|
1820
|
+
);
|
|
1821
|
+
tracked?.settle();
|
|
1822
|
+
return count;
|
|
1823
|
+
});
|
|
1767
1824
|
}
|
|
1768
1825
|
|
|
1769
1826
|
public async distinct<
|
|
@@ -1775,15 +1832,21 @@ export class SmartdataExactCollection<
|
|
|
1775
1832
|
): Promise<Array<TExactDistinctValue<
|
|
1776
1833
|
TExactDocumentPathValue<TStoredDocument<TPersisted>, TField>
|
|
1777
1834
|
>>> {
|
|
1778
|
-
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) =>
|
|
1779
|
-
|
|
1835
|
+
return this.runOperation(optionsArg, async (sessionArg, deadlineArg) => {
|
|
1836
|
+
const filter = convertFilterForMongoDb(filterArg);
|
|
1837
|
+
trackSmartdataRead(this.collection, optionsArg.session, {
|
|
1838
|
+
kind: 'documents',
|
|
1839
|
+
filter,
|
|
1840
|
+
matches: true,
|
|
1841
|
+
});
|
|
1842
|
+
return (await this.collection.mongoDbCollection.distinct(
|
|
1780
1843
|
fieldArg as string,
|
|
1781
|
-
|
|
1844
|
+
filter,
|
|
1782
1845
|
{ session: sessionArg, ...deadlineArg.commandOptions() },
|
|
1783
1846
|
)) as Array<TExactDistinctValue<
|
|
1784
1847
|
TExactDocumentPathValue<TStoredDocument<TPersisted>, TField>
|
|
1785
|
-
|
|
1786
|
-
);
|
|
1848
|
+
>>;
|
|
1849
|
+
});
|
|
1787
1850
|
}
|
|
1788
1851
|
|
|
1789
1852
|
public async transition(
|
|
@@ -1793,7 +1856,7 @@ export class SmartdataExactCollection<
|
|
|
1793
1856
|
},
|
|
1794
1857
|
sessionOptionsArg: IExactBoundedOptions = {},
|
|
1795
1858
|
): Promise<TExactTransitionResult<TPersisted>> {
|
|
1796
|
-
return this.
|
|
1859
|
+
return this.runWriteOperation(sessionOptionsArg, async (sessionArg, deadlineArg) => {
|
|
1797
1860
|
const { document: current, bodyBytes: currentBodyBytes } =
|
|
1798
1861
|
this.readStoredDocument(optionsArg.current);
|
|
1799
1862
|
const currentIdentity = this.validateReconcileIdentity(current);
|
|
@@ -1841,9 +1904,15 @@ export class SmartdataExactCollection<
|
|
|
1841
1904
|
? { _id: current._id, _smartdataRevision: current._smartdataRevision }
|
|
1842
1905
|
: { _id: current._id, _smartdataRevision: { $exists: false } };
|
|
1843
1906
|
|
|
1907
|
+
// Only a revision pins the stored body the selector matched.
|
|
1844
1908
|
const reportTransition = (): void => {
|
|
1845
1909
|
reportSmartdataCollectionWrite(
|
|
1846
|
-
this.collection,
|
|
1910
|
+
this.collection,
|
|
1911
|
+
sessionOptionsArg.session,
|
|
1912
|
+
'replace',
|
|
1913
|
+
[current, expectedStoredDocument],
|
|
1914
|
+
selector,
|
|
1915
|
+
{ images: current._smartdataRevision !== undefined ? 'beforeAndAfter' : 'after' },
|
|
1847
1916
|
);
|
|
1848
1917
|
};
|
|
1849
1918
|
const replaceOptions = {
|
|
@@ -1925,7 +1994,7 @@ export class SmartdataExactCollection<
|
|
|
1925
1994
|
sessionOptionsArg: IExactBoundedOptions = {},
|
|
1926
1995
|
): Promise<TExactDeleteResult> {
|
|
1927
1996
|
const { current, identity } = this.canonicalizeDeleteCurrent(optionsArg);
|
|
1928
|
-
return this.
|
|
1997
|
+
return this.runWriteOperation(sessionOptionsArg, async (sessionArg, deadlineArg) => {
|
|
1929
1998
|
const selector = current._smartdataRevision !== undefined
|
|
1930
1999
|
? {
|
|
1931
2000
|
_id: current._id,
|
|
@@ -1958,7 +2027,12 @@ export class SmartdataExactCollection<
|
|
|
1958
2027
|
result.deletedCount === 1
|
|
1959
2028
|
) {
|
|
1960
2029
|
reportSmartdataCollectionWrite(
|
|
1961
|
-
this.collection,
|
|
2030
|
+
this.collection,
|
|
2031
|
+
sessionOptionsArg.session,
|
|
2032
|
+
'delete',
|
|
2033
|
+
[current],
|
|
2034
|
+
selector,
|
|
2035
|
+
{ images: current._smartdataRevision !== undefined ? 'before' : 'none' },
|
|
1962
2036
|
);
|
|
1963
2037
|
return { status: 'deleted', deletedCount: 1 };
|
|
1964
2038
|
}
|