@lossless.org/client 1.2.0 → 1.4.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 +1 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.losslessorgclient.d.ts +2 -2
- package/dist_ts/core/drivers.js +3 -3
- package/dist_ts/nosqldb/classes.atomicdelete.js +3 -3
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +20 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +45 -2
- package/dist_ts/nosqldb/classes.atomicupdate.js +4 -4
- package/dist_ts/nosqldb/classes.collection.d.ts +37 -1
- package/dist_ts/nosqldb/classes.collection.js +152 -11
- package/dist_ts/nosqldb/classes.collectiontopology.d.ts +8 -0
- package/dist_ts/nosqldb/classes.collectiontopology.js +14 -3
- package/dist_ts/nosqldb/classes.cursor.d.ts +12 -1
- package/dist_ts/nosqldb/classes.cursor.js +20 -3
- package/dist_ts/nosqldb/classes.doc.d.ts +130 -11
- package/dist_ts/nosqldb/classes.doc.js +464 -89
- package/dist_ts/nosqldb/classes.namespaceinspection.js +2 -2
- package/dist_ts/nosqldb/classes.session.d.ts +15 -1
- package/dist_ts/nosqldb/classes.session.js +32 -6
- package/dist_ts/objectstorage/classes.directory.js +6 -3
- package/dist_ts/sqldb/classes.sqlconnection.d.ts +14 -1
- package/dist_ts/sqldb/classes.sqlconnection.js +1 -1
- package/dist_ts/sqldb/clickhouse/index.d.ts +3 -0
- package/dist_ts/sqldb/clickhouse/index.js +4 -1
- package/dist_ts/sqldb/index.d.ts +2 -5
- package/dist_ts/sqldb/index.js +3 -5
- package/dist_ts/sqldb/interfaces.d.ts +0 -12
- package/dist_ts/sqldb/interfaces.js +1 -1
- package/dist_ts/sqldb/mariadb/index.d.ts +6 -0
- package/dist_ts/sqldb/mariadb/index.js +5 -0
- package/package.json +12 -1
- package/readme.md +43 -6
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.losslessorgclient.ts +2 -2
- package/ts/core/drivers.ts +2 -2
- package/ts/nosqldb/classes.atomicdelete.ts +2 -4
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +69 -2
- package/ts/nosqldb/classes.atomicupdate.ts +3 -6
- package/ts/nosqldb/classes.collection.ts +240 -8
- package/ts/nosqldb/classes.collectiontopology.ts +31 -1
- package/ts/nosqldb/classes.cursor.ts +22 -2
- package/ts/nosqldb/classes.doc.ts +769 -130
- package/ts/nosqldb/classes.namespaceinspection.ts +1 -1
- package/ts/nosqldb/classes.session.ts +52 -13
- package/ts/objectstorage/classes.directory.ts +5 -2
- package/ts/sqldb/classes.sqlconnection.ts +14 -1
- package/ts/sqldb/clickhouse/index.ts +5 -0
- package/ts/sqldb/index.ts +2 -5
- package/ts/sqldb/interfaces.ts +0 -12
- package/ts/sqldb/mariadb/index.ts +7 -0
package/readme.md
CHANGED
|
@@ -17,11 +17,11 @@ Document access works immediately: `mongodb` is a dependency because the NoSQLDB
|
|
|
17
17
|
| Family | Additional install |
|
|
18
18
|
| --- | --- |
|
|
19
19
|
| `nosqldb` connections, `@lossless.org/client/nosqldb`, `@lossless.org/client/testsupport` | none |
|
|
20
|
-
| `sqldb` connections with backend `sqldb` or `mariadb` | `pnpm add mariadb` |
|
|
21
|
-
| `sqldb` connections with backend `clickhouse` | `pnpm add @clickhouse/client` |
|
|
20
|
+
| `sqldb` connections with backend `sqldb` or `mariadb`, `@lossless.org/client/sqldb/mariadb` | `pnpm add mariadb` |
|
|
21
|
+
| `sqldb` connections with backend `clickhouse`, `@lossless.org/client/sqldb/clickhouse` | `pnpm add @clickhouse/client` |
|
|
22
22
|
| `objectstorage` connections with backend `s3` | `pnpm add @aws-sdk/client-s3` |
|
|
23
23
|
|
|
24
|
-
The aggregate entry point imports a family only when the configuration names it, so an absent driver stays absent until it is used; `connect()` then fails with `driver_missing`, naming the package, the entry point and the install command.
|
|
24
|
+
The aggregate entry point imports a family only when the configuration names it, so an absent driver stays absent until it is used; `connect()` then fails with `driver_missing`, naming the package, the entry point and the install command. The two relational families also have an entry point each: `@lossless.org/client/sqldb/mariadb` needs `mariadb` only and `@lossless.org/client/sqldb/clickhouse` needs `@clickhouse/client` only, while `@lossless.org/client/sqldb` is their union and needs both, because it exports `SqlConnection` and `ClickHouseConnection` as values. Import the family you use. A direct family import resolves its driver as the module loads, so an absent driver fails there as Node's `ERR_MODULE_NOT_FOUND` naming the package; `driver_missing` is the aggregate entry point's refusal, and it names the family entry point that needs the driver. `optionalDrivers` exposes the same table to tooling.
|
|
25
25
|
|
|
26
26
|
```ts
|
|
27
27
|
import { LosslessOrgClient } from '@lossless.org/client';
|
|
@@ -72,7 +72,9 @@ Literal connection names and backend discriminators determine the return types.
|
|
|
72
72
|
| --- | --- |
|
|
73
73
|
| `@lossless.org/client` | `LosslessOrgClient`, configuration, capabilities, readiness, `LosslessClientError` |
|
|
74
74
|
| `@lossless.org/client/nosqldb` | Migrated SmartData models, decorators, collections, cursors, sessions, exact persistence and administration; `NoSqlConnection` |
|
|
75
|
-
| `@lossless.org/client/sqldb` | `SqlConnection`, `SqlTransaction`, `SqlTable`, `ClickHouseConnection`, `SmartClickHouseDb`, tables, query builders, `TimeDataTable`, `MetricWriter` |
|
|
75
|
+
| `@lossless.org/client/sqldb` | Both relational families: `SqlConnection`, `SqlTransaction`, `SqlTable`, `ClickHouseConnection`, `SmartClickHouseDb`, tables, query builders, `TimeDataTable`, `MetricWriter` |
|
|
76
|
+
| `@lossless.org/client/sqldb/mariadb` | `SqlConnection`, `SqlTransaction`, `SqlTable`, their options and `quoteIdentifier` |
|
|
77
|
+
| `@lossless.org/client/sqldb/clickhouse` | `ClickHouseConnection`, `SmartClickHouseDb`, tables, query builders, `TimeDataTable`, `MetricWriter`, their options and `quoteClickHouseIdentifier` |
|
|
76
78
|
| `@lossless.org/client/objectstorage` | Migrated `SmartBucket`, buckets, directories, files, metadata, watchers, exact operations; `ObjectStorageConnection` |
|
|
77
79
|
| `@lossless.org/client/testsupport` | Explicit disposable-database testing helpers |
|
|
78
80
|
|
|
@@ -85,9 +87,33 @@ Family imports preserve the established SmartData and SmartBucket names and cons
|
|
|
85
87
|
| Bounded plural upsert | `Model.atomicUpsertMany(operations, opts?)` — 1..1000 per-document filter/update pairs in one unordered round trip |
|
|
86
88
|
| Content-addressed primary keys | model option `identityAsDocumentId` on `defineCollectionModel()` and `@Collection()` |
|
|
87
89
|
| Identities on a migrated unique index | `@unI({ indexName })` names the index that backs the identity instead of `<field>_1` |
|
|
90
|
+
| Typed `null` predicates | read and atomic filters accept `null` for a field declared optional, so a value stored as an explicit null stays addressable |
|
|
91
|
+
| Owned sessions on cursors | `getCursor()` takes the handle from `db.createSession()` and keeps it leased until the cursor is closed |
|
|
92
|
+
| Named plural selectors | a non-empty `$in` anchors `atomicUpdateMany()`, `atomicDeleteMany()` and `atomicUpsertMany()`; singular operations are unchanged |
|
|
93
|
+
| Fields only atomic writes may update | `@svDb({ atomicOnly: true })` and `atomicOnlyFields` — seeded by every write that creates the document, never overwritten by a later `save()` |
|
|
94
|
+
| Defaults inside `$expr` | `{ $ifNull: ['$field', literal] }` operands, so a guard covers rows written before the field existed |
|
|
95
|
+
| Fenced instance saves | `instance.saveIf(fence, opts?)` — one non-upserting `updateOne`; `matchedCount === 0` means another writer moved the document first |
|
|
96
|
+
| Identity rotation | `Model.atomicFindOneAndReplace(filter, replacement, opts?)` — the one write that moves an `@unI()` identity, under the matched document's `_id` |
|
|
97
|
+
| Fail-fast on unprepared collections | a session-carrying call inside a transaction refuses instead of stalling on lazy index DDL until the client deadline |
|
|
98
|
+
| Migration-owned indexes | `toleratedIndexNames` on the model — named undeclared indexes are observed, never created, dropped or verified, and no longer make the topology divergent |
|
|
88
99
|
|
|
89
100
|
`docs/source/smartdata/readme.md` documents each one with its refusals.
|
|
90
101
|
|
|
102
|
+
### Document APIs that need a MongoDB backend
|
|
103
|
+
|
|
104
|
+
The document model runs on both NoSQLDB and MongoDB, but four APIs do not mean the same thing on both. The NoSQLDB engine is qualified at 8.0.2 and 10.2.0 (see [Verification](#verification)); both behave identically on every row below.
|
|
105
|
+
|
|
106
|
+
| Document API | On the NoSQLDB engine | On MongoDB |
|
|
107
|
+
| --- | --- | --- |
|
|
108
|
+
| `getGroupedTotals()` / `getGroupedTotalsPage()` with one `groupBy` field | exact, including `sums` | exact |
|
|
109
|
+
| the same with **two** `groupBy` fields | **returns a wrong answer without raising** — the engine leaves the composite group key unresolved and answers with a single row whose group values are the literal field paths (`'$owner'`) and whose count is the whole filtered collection. Do not call the two-field form against NoSQLDB | exact |
|
|
110
|
+
| guarded `$expr` atomic filters (`$add`, `$lte`, `$ifNull`) | refused by the engine: the fail-closed compilation uses `$cond`, which the engine rejects with `invalid argument: $cond`. The document is left untouched | exact |
|
|
111
|
+
| `watch()` change streams | unsupported. `NoSqlConnection` refuses with `unsupported_capability`; a plain `SmartdataDb` carries no backend declaration, so the refusal instead arrives from the engine as `CommandNotFound` once the change stream is read | supported on replica sets |
|
|
112
|
+
| model-declared partial indexes (`partialFilterExpression`) | not expressible: the index-option type rejects it and the runtime refuses it with `invalid_configuration`; the engine cannot create one either. Migration-owned partial indexes stay reachable through `toleratedIndexNames` | not expressible, but a migration may own one |
|
|
113
|
+
| aggregation-pipeline (array) updates | refused by the client with `invalid_argument` before any backend is contacted | same client refusal |
|
|
114
|
+
|
|
115
|
+
`test/nosqldb/smartdb/test.engine-capability-boundary.node.ts` asserts the grouped-totals, guarded-`$expr`, partial-index and pipeline-update rows against both qualified engines, so a boundary that moves shows up as a failing suite rather than as a changed number in a consumer. The `watch()` row is the contract refusal `ts/nosqldb/classes.collection.ts` states; the engine suite opens no change stream.
|
|
116
|
+
|
|
91
117
|
## Relational SQL
|
|
92
118
|
|
|
93
119
|
`SqlConnection` uses the official MariaDB connector for parameters, protocol, TLS and decoding. This client owns cancellable admission and TCP sockets from authentication onward. A transaction holds one physical session; releasing a session resets its state before reuse.
|
|
@@ -160,9 +186,20 @@ Fixes land here. @push.rocks/smartdata is no longer a release channel for this i
|
|
|
160
186
|
|
|
161
187
|
## Verification
|
|
162
188
|
|
|
163
|
-
`pnpm build` builds production declarations. `pnpm test` checks aggregate lifecycle and writers. `pnpm run test:nosqldb`, `test:mongodb`, `test:objectstorage` and `test:sqldb` exercise isolated backends. `pnpm run test:package` packs the package and resolves every entry point; `pnpm run test:install` installs the packed tarball into a scratch project and proves that a document-only consumer receives no relational or object driver, and that the aggregate client refuses a missing one by name. Wrappers own and remove their disposable servers, containers and data directories. Never supply a production database or bucket to these destructive suites.
|
|
189
|
+
`pnpm build` builds production declarations. `pnpm test` checks aggregate lifecycle and writers. `pnpm run test:nosqldb`, `test:nosqldb:qualified`, `test:mongodb`, `test:objectstorage` and `test:sqldb` exercise isolated backends. `pnpm run test:qualification` runs the aggregate, both engine suites and the MongoDB suite in one sequence; it is what the release preflight runs. `pnpm run test:package` packs the package and resolves every entry point; `pnpm run test:install` installs the packed tarball into a scratch project and proves that a document-only consumer receives no relational or object driver, and that the aggregate client refuses a missing one by name. Wrappers own and remove their disposable servers, containers and data directories. Never supply a production database or bucket to these destructive suites.
|
|
190
|
+
|
|
191
|
+
Qualified engines:
|
|
164
192
|
|
|
165
|
-
|
|
193
|
+
| Component | Qualified versions |
|
|
194
|
+
| --- | --- |
|
|
195
|
+
| NoSQLDB engine | **8.0.2 and 10.2.0** — the same `test/nosqldb/smartdb/` suite runs against both, through the single engine seam in `test/nosqldb/helpers/smartdb.ts`; `NOSQLDB_ENGINE=qualified` selects 10.2.0 |
|
|
196
|
+
| MongoDB | 8.0.26 replica sets |
|
|
197
|
+
| ObjectStorage | 10.1.0 |
|
|
198
|
+
| SQLDB | 0.2.3 |
|
|
199
|
+
| MariaDB | 11.8 |
|
|
200
|
+
| ClickHouse | 25.8 |
|
|
201
|
+
|
|
202
|
+
Both engine versions answer every assertion in the document suite identically, including the asserted boundaries in [Document APIs that need a MongoDB backend](#document-apis-that-need-a-mongodb-backend). Text search, the Lucene adapter and the broad read-filter surface are exercised against MongoDB only. `pnpm run test:minio` uses a digest-pinned MinIO image: `sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e`. That MinIO version enforces the tested conditional uploads but does not enforce conditional deletion; its exact-purge capability is correctly unavailable. ObjectStorage passes both live probes. AWS S3 has not been qualified against a live account in this migration; no universal S3 exact-operation guarantee is inferred from the SDK.
|
|
166
203
|
|
|
167
204
|
## License and Legal Information
|
|
168
205
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import type { NoSqlConnection, INoSqlConnectionOptions } from './nosqldb/classes.connection.js';
|
|
3
3
|
import type { ObjectStorageConnection, IObjectStorageConnectionOptions } from './objectstorage/classes.connection.js';
|
|
4
|
-
import type { SqlConnection } from './sqldb/classes.sqlconnection.js';
|
|
4
|
+
import type { SqlConnection, ISqlConnectionOptions } from './sqldb/classes.sqlconnection.js';
|
|
5
5
|
import type { ClickHouseConnection } from './sqldb/classes.clickhouseconnection.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { IClickHouseConnectionOptions } from './sqldb/interfaces.js';
|
|
7
7
|
import type { IOperationOptions, IReadiness } from './core/interfaces.js';
|
|
8
8
|
import { LosslessClientError } from './core/classes.error.js';
|
|
9
9
|
import { Operation } from './core/classes.operation.js';
|
package/ts/core/drivers.ts
CHANGED
|
@@ -14,9 +14,9 @@ export interface IOptionalDriver {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export const optionalDrivers: Readonly<Record<TOptionalDriverBackend, IOptionalDriver>> = Object.freeze({
|
|
17
|
-
mariadb: { package: 'mariadb', subpath: '@lossless.org/client/sqldb',
|
|
17
|
+
mariadb: { package: 'mariadb', subpath: '@lossless.org/client/sqldb/mariadb',
|
|
18
18
|
usage: 'sqldb connections with backend "sqldb" or "mariadb"' },
|
|
19
|
-
clickhouse: { package: '@clickhouse/client', subpath: '@lossless.org/client/sqldb',
|
|
19
|
+
clickhouse: { package: '@clickhouse/client', subpath: '@lossless.org/client/sqldb/clickhouse',
|
|
20
20
|
usage: 'sqldb connections with backend "clickhouse"' },
|
|
21
21
|
s3: { package: '@aws-sdk/client-s3', subpath: '@lossless.org/client/objectstorage',
|
|
22
22
|
usage: 'objectstorage connections with backend "s3"' },
|
|
@@ -26,8 +26,7 @@ export const executeAtomicDelete = async <T>(
|
|
|
26
26
|
{
|
|
27
27
|
ordinaryWrite: true,
|
|
28
28
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
29
|
-
|
|
30
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
29
|
+
collectionName: collectionArg.collectionName,
|
|
31
30
|
},
|
|
32
31
|
async (rawSessionArg) => {
|
|
33
32
|
await collectionArg.init();
|
|
@@ -64,8 +63,7 @@ export const executeAtomicDeleteMany = async <T>(
|
|
|
64
63
|
{
|
|
65
64
|
ordinaryWrite: true,
|
|
66
65
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
67
|
-
|
|
68
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
66
|
+
collectionName: collectionArg.collectionName,
|
|
69
67
|
},
|
|
70
68
|
async (rawSessionArg) => {
|
|
71
69
|
await collectionArg.init();
|
|
@@ -20,6 +20,10 @@ export type TAtomicFindOneAndUpdateExecutionResult =
|
|
|
20
20
|
| { status: 'upserted'; document: TRawDocument | null }
|
|
21
21
|
| { status: 'not_matched'; document: null };
|
|
22
22
|
|
|
23
|
+
export type TAtomicFindOneAndReplaceExecutionResult =
|
|
24
|
+
| { status: 'matched'; document: TRawDocument }
|
|
25
|
+
| { status: 'not_matched'; document: null };
|
|
26
|
+
|
|
23
27
|
const unsupportedResult = (): never => {
|
|
24
28
|
throw new SmartdataPersistenceError(
|
|
25
29
|
'unsupported_operation',
|
|
@@ -104,8 +108,7 @@ export const executeAtomicFindOneAndUpdate = async <T>(
|
|
|
104
108
|
{
|
|
105
109
|
ordinaryWrite: true,
|
|
106
110
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
107
|
-
|
|
108
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
111
|
+
collectionName: collectionArg.collectionName,
|
|
109
112
|
},
|
|
110
113
|
async (rawSessionArg) => {
|
|
111
114
|
if (policy && !rawSessionArg?.inTransaction()) {
|
|
@@ -150,3 +153,67 @@ export const executeAtomicFindOneAndUpdate = async <T>(
|
|
|
150
153
|
},
|
|
151
154
|
);
|
|
152
155
|
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Executes a model-validated atomic find-one-and-replace against MongoDB.
|
|
159
|
+
*
|
|
160
|
+
* This helper is package-internal. `SmartDataDbDoc.atomicFindOneAndReplace()`
|
|
161
|
+
* owns the public API and must validate the filter and the replacement body
|
|
162
|
+
* before calling this raw persistence boundary. The replacement never carries
|
|
163
|
+
* a stored `_id`, so the matched document keeps its own primary key while its
|
|
164
|
+
* declared identity changes.
|
|
165
|
+
*/
|
|
166
|
+
export const executeAtomicFindOneAndReplace = async <T>(
|
|
167
|
+
collectionArg: SmartdataCollection<T>,
|
|
168
|
+
filterArg: plugins.mongodb.Filter<plugins.mongodb.Document>,
|
|
169
|
+
replacementArg: plugins.mongodb.WithoutId<plugins.mongodb.Document>,
|
|
170
|
+
optionsArg: {
|
|
171
|
+
returnDocument: 'before' | 'after';
|
|
172
|
+
session?: TSmartdataOrdinarySession;
|
|
173
|
+
},
|
|
174
|
+
): Promise<TAtomicFindOneAndReplaceExecutionResult> => {
|
|
175
|
+
if (collectionArg.getBoundModelSchema()?.ordinaryPersistence) {
|
|
176
|
+
// A validated ordinary document owns its stored shape and primary key, so
|
|
177
|
+
// it is written through its own postimage path, never replaced wholesale.
|
|
178
|
+
throw new SmartdataPersistenceError('unsupported_operation',
|
|
179
|
+
'Validated ordinary models require transactional postimage updates.');
|
|
180
|
+
}
|
|
181
|
+
return runWithOrdinarySmartdataSession(
|
|
182
|
+
optionsArg.session,
|
|
183
|
+
collectionArg.smartdataDb,
|
|
184
|
+
{
|
|
185
|
+
ordinaryWrite: true,
|
|
186
|
+
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
187
|
+
collectionName: collectionArg.collectionName,
|
|
188
|
+
},
|
|
189
|
+
async (rawSessionArg) => {
|
|
190
|
+
await collectionArg.init();
|
|
191
|
+
try {
|
|
192
|
+
const result = await collectionArg.mongoDbCollection.findOneAndReplace(
|
|
193
|
+
filterArg,
|
|
194
|
+
replacementArg,
|
|
195
|
+
{
|
|
196
|
+
includeResultMetadata: true,
|
|
197
|
+
returnDocument: optionsArg.returnDocument,
|
|
198
|
+
upsert: false,
|
|
199
|
+
session: rawSessionArg,
|
|
200
|
+
},
|
|
201
|
+
);
|
|
202
|
+
const classified = classifyResult(result, {
|
|
203
|
+
returnDocument: optionsArg.returnDocument,
|
|
204
|
+
upsert: false,
|
|
205
|
+
});
|
|
206
|
+
if (classified.status === 'upserted') {
|
|
207
|
+
// Unreachable: this operation never requests an upsert.
|
|
208
|
+
return unsupportedResult();
|
|
209
|
+
}
|
|
210
|
+
return classified;
|
|
211
|
+
} catch (errorArg) {
|
|
212
|
+
return normalizeOrdinaryPersistenceError(
|
|
213
|
+
errorArg,
|
|
214
|
+
`Atomic find-one-and-replace conflicts with a unique index in collection "${collectionArg.collectionName}".`,
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
};
|
|
@@ -28,8 +28,7 @@ export const executeAtomicUpdate = async <T>(
|
|
|
28
28
|
{
|
|
29
29
|
ordinaryWrite: true,
|
|
30
30
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
31
|
-
|
|
32
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
31
|
+
collectionName: collectionArg.collectionName,
|
|
33
32
|
},
|
|
34
33
|
async (rawSessionArg) => {
|
|
35
34
|
await collectionArg.init();
|
|
@@ -83,8 +82,7 @@ export const executeAtomicUpsertMany = async <T>(
|
|
|
83
82
|
{
|
|
84
83
|
ordinaryWrite: true,
|
|
85
84
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
86
|
-
|
|
87
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
85
|
+
collectionName: collectionArg.collectionName,
|
|
88
86
|
},
|
|
89
87
|
async (rawSessionArg) => {
|
|
90
88
|
await collectionArg.init();
|
|
@@ -142,8 +140,7 @@ export const executeAtomicUpdateMany = async <T>(
|
|
|
142
140
|
{
|
|
143
141
|
ordinaryWrite: true,
|
|
144
142
|
prepared: collectionArg.isInitializedForCurrentDatabase(),
|
|
145
|
-
|
|
146
|
-
`Initialize collection "${collectionArg.collectionName}" before using an owned SmartData session.`,
|
|
143
|
+
collectionName: collectionArg.collectionName,
|
|
147
144
|
},
|
|
148
145
|
async (rawSessionArg) => {
|
|
149
146
|
await collectionArg.init();
|