@lossless.org/client 1.4.0 → 1.5.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.
Files changed (51) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/core/interfaces.d.ts +7 -0
  3. package/dist_ts/index.d.ts +1 -1
  4. package/dist_ts/nosqldb/classes.collection.js +2 -3
  5. package/dist_ts/nosqldb/classes.connection.d.ts +8 -3
  6. package/dist_ts/nosqldb/classes.connection.js +11 -6
  7. package/dist_ts/nosqldb/classes.db.d.ts +13 -0
  8. package/dist_ts/nosqldb/classes.db.js +28 -1
  9. package/dist_ts/nosqldb/classes.doc.js +10 -2
  10. package/dist_ts/nosqldb/classes.easystore.d.ts +13 -0
  11. package/dist_ts/nosqldb/classes.easystore.js +16 -1
  12. package/dist_ts/nosqldb/engineidentity.d.ts +31 -0
  13. package/dist_ts/nosqldb/engineidentity.js +105 -0
  14. package/dist_ts/nosqldb/index.d.ts +2 -0
  15. package/dist_ts/nosqldb/index.js +1 -1
  16. package/dist_ts/nosqldb/lineage.js +3 -1
  17. package/dist_ts/objectstorage/classes.connection.js +2 -2
  18. package/dist_ts/sqldb/classes.clickhouseconnection.js +3 -2
  19. package/dist_ts/sqldb/classes.sqlconnection.d.ts +7 -5
  20. package/dist_ts/sqldb/classes.sqlconnection.js +3 -3
  21. package/dist_ts/sqldb/interfaces.d.ts +5 -0
  22. package/dist_ts/sqldb/interfaces.js +1 -1
  23. package/dist_ts/sqldb/internal.lease.d.ts +15 -0
  24. package/dist_ts/sqldb/internal.lease.js +2 -0
  25. package/dist_ts/sqldb/internal.sqlpool.d.ts +2 -1
  26. package/dist_ts/sqldb/internal.sqlpool.js +1 -1
  27. package/dist_ts/sqldb/plugins.d.ts +4 -0
  28. package/dist_ts/sqldb/plugins.js +7 -0
  29. package/dist_ts/sqldb/plugins.mariadb.d.ts +2 -3
  30. package/dist_ts/sqldb/plugins.mariadb.js +4 -4
  31. package/package.json +3 -3
  32. package/readme.md +24 -19
  33. package/ts/00_commitinfo_data.ts +1 -1
  34. package/ts/core/interfaces.ts +7 -0
  35. package/ts/index.ts +1 -1
  36. package/ts/nosqldb/classes.collection.ts +1 -2
  37. package/ts/nosqldb/classes.connection.ts +19 -7
  38. package/ts/nosqldb/classes.db.ts +38 -0
  39. package/ts/nosqldb/classes.doc.ts +14 -1
  40. package/ts/nosqldb/classes.easystore.ts +16 -0
  41. package/ts/nosqldb/engineidentity.ts +153 -0
  42. package/ts/nosqldb/index.ts +11 -0
  43. package/ts/nosqldb/lineage.ts +2 -0
  44. package/ts/objectstorage/classes.connection.ts +1 -1
  45. package/ts/sqldb/classes.clickhouseconnection.ts +2 -1
  46. package/ts/sqldb/classes.sqlconnection.ts +14 -11
  47. package/ts/sqldb/interfaces.ts +5 -0
  48. package/ts/sqldb/internal.lease.ts +16 -0
  49. package/ts/sqldb/internal.sqlpool.ts +2 -1
  50. package/ts/sqldb/plugins.mariadb.ts +3 -3
  51. package/ts/sqldb/plugins.ts +7 -0
@@ -211,4 +211,4 @@ export class SqlPooledConnection {
211
211
  })();
212
212
  }
213
213
  }
214
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwuc3FscG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NxbGRiL2ludGVybmFsLnNxbHBvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxzQkFBc0IsQ0FBQztBQUVoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUsvRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFTVztJQUEyRDtJQVJ2RSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7SUFDN0MsSUFBSSxHQUEwQixFQUFFLENBQUM7SUFDakMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUM7SUFDN0IsTUFBTSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBQ2pELFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDYixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ2YsT0FBTyxDQUFpQjtJQUVoQyxZQUE2QixNQUF3QyxFQUFtQixLQUFhO1FBQXhFLFdBQU0sR0FBTixNQUFNLENBQWtDO1FBQW1CLFVBQUssR0FBTCxLQUFLLENBQVE7SUFBRyxDQUFDO0lBRWpHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBb0I7UUFDckMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxNQUFNLElBQUksbUJBQW1CLENBQUMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDaEYsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUMxQyxNQUFNLE1BQU0sR0FBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7d0JBQ2hFLElBQUksQ0FB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
214
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwuc3FscG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NxbGRiL2ludGVybmFsLnNxbHBvb2wudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxzQkFBc0IsQ0FBQztBQUdoRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUsvRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFTVztJQUEyRDtJQVJ2RSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7SUFDN0MsSUFBSSxHQUEwQixFQUFFLENBQUM7SUFDakMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUFXLENBQUM7SUFDN0IsTUFBTSxHQUFHLElBQUksR0FBRyxFQUF1QixDQUFDO0lBQ2pELFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDYixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ2YsT0FBTyxDQUFpQjtJQUVoQyxZQUE2QixNQUF3QyxFQUFtQixLQUFhO1FBQXhFLFdBQU0sR0FBTixNQUFNLENBQWtDO1FBQW1CLFVBQUssR0FBTCxLQUFLLENBQVE7SUFBRyxDQUFDO0lBRWpHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBb0I7UUFDckMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxNQUFNLElBQUksbUJBQW1CLENBQUMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDaEYsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUMxQyxNQUFNLE1BQU0sR0FBWSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUU7d0JBQ2hFLElBQUksQ0FB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
@@ -0,0 +1,4 @@
1
+ import * as net from 'node:net';
2
+ import * as stream from 'node:stream';
3
+ import * as tls from 'node:tls';
4
+ export { net, stream, tls };
@@ -0,0 +1,7 @@
1
+ // Node built-ins the relational families share. Driver packages stay in their own plugin modules,
2
+ // so a declaration that needs none of them never reaches an optional peer.
3
+ import * as net from 'node:net';
4
+ import * as stream from 'node:stream';
5
+ import * as tls from 'node:tls';
6
+ export { net, stream, tls };
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3NxbGRiL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsa0dBQWtHO0FBQ2xHLDJFQUEyRTtBQUMzRSxPQUFPLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLEtBQUssTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEtBQUssR0FBRyxNQUFNLFVBQVUsQ0FBQztBQUVoQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyJ9
@@ -1,4 +1,3 @@
1
1
  import * as mariadb from 'mariadb';
2
- import * as stream from 'node:stream';
3
- import * as net from 'node:net';
4
- export { mariadb, stream, net };
2
+ export * from './plugins.js';
3
+ export { mariadb };
@@ -1,5 +1,5 @@
1
+ // The MariaDB driver plus the shared Node built-ins. Only modules that speak to the driver import this.
1
2
  import * as mariadb from 'mariadb';
2
- import * as stream from 'node:stream';
3
- import * as net from 'node:net';
4
- export { mariadb, stream, net };
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5tYXJpYWRiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc3FsZGIvcGx1Z2lucy5tYXJpYWRiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBQ25DLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDIn0=
3
+ export * from './plugins.js';
4
+ export { mariadb };
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5tYXJpYWRiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc3FsZGIvcGx1Z2lucy5tYXJpYWRiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdHQUF3RztBQUN4RyxPQUFPLEtBQUssT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUNuQyxjQUFjLGNBQWMsQ0FBQztBQUM3QixPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lossless.org/client",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "private": false,
5
5
  "description": "One typed client for NoSQLDB, MongoDB, SQLDB, MariaDB, ClickHouse and S3 object storage.",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "@push.rocks/lik": "^6.4.0",
49
49
  "@push.rocks/smartdelay": "^3.0.5",
50
- "@push.rocks/smartlog": "^3.2.1",
50
+ "@push.rocks/smartlog": "^3.2.1 || ^4.0.0",
51
51
  "@push.rocks/smartmime": "^2.0.4",
52
52
  "@push.rocks/smartobject": "^1.0.12",
53
53
  "@push.rocks/smartpath": "^6.0.0",
@@ -85,7 +85,7 @@
85
85
  "@git.zone/tsrun": "2.0.6",
86
86
  "@git.zone/tstest": "6.1.1",
87
87
  "@lossless.org/nosqldb": "8.0.2",
88
- "@lossless.org/nosqldb-qualified": "npm:@lossless.org/nosqldb@10.2.0",
88
+ "@lossless.org/nosqldb-qualified": "npm:@lossless.org/nosqldb@10.5.0",
89
89
  "@lossless.org/objectstorage": "10.1.0",
90
90
  "@lossless.org/sqldb": "0.2.3",
91
91
  "@push.rocks/qenv": "^6.1.3",
package/readme.md CHANGED
@@ -68,15 +68,17 @@ Literal connection names and backend discriminators determine the return types.
68
68
 
69
69
  ## Interfaces
70
70
 
71
- | Import | API |
72
- | --- | --- |
73
- | `@lossless.org/client` | `LosslessOrgClient`, configuration, capabilities, readiness, `LosslessClientError` |
74
- | `@lossless.org/client/nosqldb` | Migrated SmartData models, decorators, collections, cursors, sessions, exact persistence and administration; `NoSqlConnection` |
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` |
78
- | `@lossless.org/client/objectstorage` | Migrated `SmartBucket`, buckets, directories, files, metadata, watchers, exact operations; `ObjectStorageConnection` |
79
- | `@lossless.org/client/testsupport` | Explicit disposable-database testing helpers |
71
+ | Import | API | Peer its declarations need |
72
+ | --- | --- | --- |
73
+ | `@lossless.org/client` | `LosslessOrgClient`, configuration, capabilities, readiness, `LosslessClientError` | `@aws-sdk/client-s3` |
74
+ | `@lossless.org/client/nosqldb` | Migrated SmartData models, decorators, collections, cursors, sessions, exact persistence and administration; `NoSqlConnection` | none |
75
+ | `@lossless.org/client/sqldb` | Both relational families: `SqlConnection`, `SqlTransaction`, `SqlTable`, `ClickHouseConnection`, `SmartClickHouseDb`, tables, query builders, `TimeDataTable`, `MetricWriter` | none |
76
+ | `@lossless.org/client/sqldb/mariadb` | `SqlConnection`, `SqlTransaction`, `SqlTable`, their options and `quoteIdentifier` | none |
77
+ | `@lossless.org/client/sqldb/clickhouse` | `ClickHouseConnection`, `SmartClickHouseDb`, tables, query builders, `TimeDataTable`, `MetricWriter`, their options and `quoteClickHouseIdentifier` | none |
78
+ | `@lossless.org/client/objectstorage` | Migrated `SmartBucket`, buckets, directories, files, metadata, watchers, exact operations; `ObjectStorageConnection` | `@aws-sdk/client-s3` |
79
+ | `@lossless.org/client/testsupport` | Explicit disposable-database testing helpers | none |
80
+
81
+ The last column is about type-checking, not loading: an entry point's declarations name an optional peer only where its API is typed against that driver. `@lossless.org/client/objectstorage` exposes the S3 client, `SmartBucket.storageClient` and the outputs the SDK defines, so a consumer type-checks it only with `@aws-sdk/client-s3` installed, and the aggregate entry point reaches those declarations through `client.objectstorage()`. Every other entry point type-checks with no optional peer installed and without `skipLibCheck`; both relational families own every type in their public API and resolve their driver when the module loads. `test/client/test.entrypoints.node.ts` type-checks each entry point in a disposable consumer project that installed neither `mariadb` nor `@aws-sdk/client-s3` and holds that table to it.
80
82
 
81
83
  Family imports preserve the established SmartData and SmartBucket names and constructors. Their implementations live here; the client does not depend on the old packages. The aggregate loads only configured families. Direct family entry points do not initialize unrelated connections.
82
84
 
@@ -96,23 +98,26 @@ Family imports preserve the established SmartData and SmartBucket names and cons
96
98
  | Identity rotation | `Model.atomicFindOneAndReplace(filter, replacement, opts?)` — the one write that moves an `@unI()` identity, under the matched document's `_id` |
97
99
  | 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
100
  | Migration-owned indexes | `toleratedIndexNames` on the model — named undeclared indexes are observed, never created, dropped or verified, and no longer make the topology divergent |
101
+ | Key-value store readiness | `EasyStore.ensureInitialized()` — installs the store's declared index at startup, outside any transaction window, so a first `readKey()`/`writeKey()` needs no index DDL |
99
102
 
100
103
  `docs/source/smartdata/readme.md` documents each one with its refusals.
101
104
 
102
105
  ### Document APIs that need a MongoDB backend
103
106
 
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.
107
+ 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.5.0 (see [Verification](#verification)); the two releases part on one row below — 10.5.0 groups composite keys exactly, 8.0.2 does not — and answer every other row alike.
108
+
109
+ `init()` asks the connected engine what it is with one `buildInfo` command and records the answer on the database as `engineIdentity` (`{ product, version }`). NoSQLDB answers with its own `nosqldb` identity document from 10.3.0 onward; a MongoDB server answers `buildInfo` without one; an engine that refuses the command — NoSQLDB 8.0.2 answers `CommandNotFound` — stays `{ product: 'unknown', version: null }`. The identity is what states `capabilities` on a plain `SmartdataDb`, and an unidentified engine states none at all, so every capability-gated call refuses. `NoSqlConnection` keeps stating the capabilities of its declared backend from construction on.
105
110
 
106
111
  | Document API | On the NoSQLDB engine | On MongoDB |
107
112
  | --- | --- | --- |
108
113
  | `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 |
114
+ | the same with **two** `groupBy` fields | exact, `sums` included, on an engine that identifies itself as NoSQLDB 10.5.0 or newer: that release evaluates the composite group key per document. Below it the call is refused with `unsupported_operation` naming both fields and the single-field form, because 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; the refusal is the guard against that wrong number, not a fix for it | exact |
110
115
  | 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 |
116
+ | `watch()` change streams | unsupported. `NoSqlConnection` refuses with `unsupported_capability`, and so does a plain `SmartdataDb` whose engine identified itself; against an engine that answers no identity the refusal instead arrives from the engine as `CommandNotFound` once the change stream is read | supported on replica sets |
117
+ | 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 and refuses the option itself with `InvalidOptions` (72) on both qualified releases. Migration-owned partial indexes stay reachable through `toleratedIndexNames` | not expressible, but a migration may own one |
118
+ | aggregation-pipeline (array) updates | refused by the client with `invalid_argument` before any backend is contacted. A client-owned refusal, not an engine limit: both qualified engines apply a pipeline update themselves | same client refusal |
114
119
 
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.
120
+ `test/nosqldb/smartdb/test.engine-capability-boundary.node.ts` asserts the identity, 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 two halves of the grouped-totals row are separate tests, each bound to the engine that answers it, and the engine's own composite-key answer stays under assertion through the raw `aggregateGroupedTotals()` boundary — one literal row on 8.0.2, the two exact pairs on 10.5.0. The same boundary pins what 10.5.0 gained with it, a validated `$group` stage: a `$cond` inside a composite key and a non-document accumulator are refused with `TypeMismatch` (14) there, while 8.0.2 answers both. The `watch()` row is the contract refusal `ts/nosqldb/classes.collection.ts` states; the engine suite opens no change stream.
116
121
 
117
122
  ## Relational SQL
118
123
 
@@ -157,7 +162,7 @@ New SQL methods accept `signal` and a total `timeoutMs` (30 seconds by default,
157
162
 
158
163
  `LosslessClientError` provides a safe outer message, a code, optional `backendCode`, `retryability`, `outcome` and acknowledged-row evidence. `cause` preserves the original error and can contain statement values; do not log it indiscriminately. The taxonomy includes invalid arguments, unsupported capability, a missing optional driver, authentication, conflict, timeout, cancellation, result limits, backend failure, partial writes and unknown write outcomes. There are no automatic write retries. A transient hint never establishes that retrying an ambiguous write is safe.
159
164
 
160
- Migrated document and object APIs retain their existing typed errors and exact-operation evidence. Their established per-operation timeout/ownership contracts continue to apply. `capabilities` distinguishes `available`, `unsupported` and `unknown`; MongoDB transaction/change-stream availability still depends on deployment topology. NoSQLDB change streams are explicitly unsupported. S3 exact-operation capability tests remain explicit and require owned disposable resources.
165
+ Migrated document and object APIs retain their existing typed errors and exact-operation evidence. Their established per-operation timeout/ownership contracts continue to apply. `capabilities` distinguishes `available`, `unsupported` and `unknown`; MongoDB transaction/change-stream availability still depends on deployment topology. NoSQLDB change streams are explicitly unsupported. `capabilities.compositeGrouping` is the one member with its own vocabulary — `exact` or `unsupported` — and states whether two-field grouped totals are evaluated exactly; MongoDB and NoSQLDB 10.5.0 and newer are `exact`, every earlier or unidentified engine and every relational or object connection is `unsupported`. On a plain `SmartdataDb` the whole statement is `undefined` until `init()` identifies the engine, and an absent statement means "not available". S3 exact-operation capability tests remain explicit and require owned disposable resources.
161
166
 
162
167
  ## Migrating existing applications
163
168
 
@@ -180,7 +185,7 @@ SmartClickHouse migration changes: replace RxJS `next/complete` insertion with a
180
185
 
181
186
  `@lossless.org/client/nosqldb` is a fork of @push.rocks/smartdata 11.14.2 (commit `9868817a63de72caef787bd8e68bac3deb9d6131`), taken on 2026-09-10; this repository continues that package's git history, so every upstream fix up to and including 11.14.2 is present here. `nosqldbLineage`, exported from the family entry point, carries the same baseline for runtime and tooling checks, and `docs/source/smartdata` keeps the upstream readme, hints and changelog.
182
187
 
183
- The fork departs from that baseline in three places: `NoSqlConnection` adds the client backend, capability and readiness contract; the family entry point exports it together with `nosqldbLineage`; and `watch()` refuses to open a change stream when the connected backend reports change streams as unsupported. The package version file was dropped, because versioning belongs to `@lossless.org/client`. Document-model capabilities added after the fork — `$max`/`$min`, identity seeding through `$setOnInsert`, `atomicUpsertMany()` and `identityAsDocumentId` — are this package's own additions and have no upstream counterpart.
188
+ The fork departs from that baseline in five places: `NoSqlConnection` adds the client backend, capability and readiness contract; the family entry point exports it together with `nosqldbLineage`; `watch()` refuses to open a change stream when the connected backend reports change streams as unsupported; `init()` identifies the engine and states the capabilities that identity implies; and two-field grouped totals are refused on a backend that does not group composite keys exactly. The package version file was dropped, because versioning belongs to `@lossless.org/client`. Document-model capabilities added after the fork — `$max`/`$min`, identity seeding through `$setOnInsert`, `atomicUpsertMany()` and `identityAsDocumentId` — are this package's own additions and have no upstream counterpart.
184
189
 
185
190
  Fixes land here. @push.rocks/smartdata is no longer a release channel for this implementation, so a later upstream version is not a source to merge from and not an upgrade path for consumers of this package.
186
191
 
@@ -192,14 +197,14 @@ Qualified engines:
192
197
 
193
198
  | Component | Qualified versions |
194
199
  | --- | --- |
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 |
200
+ | NoSQLDB engine | **8.0.2 and 10.5.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.5.0 |
196
201
  | MongoDB | 8.0.26 replica sets |
197
202
  | ObjectStorage | 10.1.0 |
198
203
  | SQLDB | 0.2.3 |
199
204
  | MariaDB | 11.8 |
200
205
  | ClickHouse | 25.8 |
201
206
 
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.
207
+ Both engine versions run the whole document suite. They part on one asserted boundary — 10.5.0 groups composite keys exactly and answers two-field grouped totals, 8.0.2 does neither and the client refuses there — which [Document APIs that need a MongoDB backend](#document-apis-that-need-a-mongodb-backend) states row by row. 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.
203
208
 
204
209
  ## License and Legal Information
205
210
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@lossless.org/client',
6
- version: '1.4.0',
6
+ version: '1.5.0',
7
7
  description: 'One typed client for NoSQLDB, MongoDB, SQLDB, MariaDB, ClickHouse and S3 object storage.'
8
8
  }
@@ -1,10 +1,17 @@
1
1
  export type TBackend = 'nosqldb' | 'mongodb' | 'sqldb' | 'mariadb' | 'clickhouse' | 'objectstorage' | 's3';
2
2
  export type TCapability = 'available' | 'unsupported' | 'unknown';
3
+ export type TCompositeGrouping = 'exact' | 'unsupported';
3
4
 
4
5
  export interface ICapabilities {
5
6
  readonly backend: TBackend;
6
7
  readonly transactions: TCapability;
7
8
  readonly changeStreams: TCapability;
9
+ /**
10
+ * Whether grouped totals over two fields are evaluated exactly. Only the
11
+ * document backends offer that API at all; every other backend reports
12
+ * `unsupported`.
13
+ */
14
+ readonly compositeGrouping: TCompositeGrouping;
8
15
  readonly objectMetrics: TCapability;
9
16
  readonly diskResidentScans: TCapability;
10
17
  }
package/ts/index.ts CHANGED
@@ -3,4 +3,4 @@ export type { ILosslessOrgClientOptions } from './classes.losslessorgclient.js';
3
3
  export { LosslessClientError } from './core/classes.error.js';
4
4
  export { optionalDrivers } from './core/drivers.js';
5
5
  export type { IOptionalDriver, TOptionalDriverBackend } from './core/drivers.js';
6
- export type { ICapabilities, IOperationOptions, IReadiness, TBackend, TCapability, TClientErrorCode } from './core/interfaces.js';
6
+ export type { ICapabilities, IOperationOptions, IReadiness, TBackend, TCapability, TClientErrorCode, TCompositeGrouping } from './core/interfaces.js';
@@ -2369,8 +2369,7 @@ export class SmartdataCollection<T> {
2369
2369
  opts: (plugins.mongodb.ChangeStreamOptions & { bufferTimeMs?: number }) = {},
2370
2370
  smartdataDbDocArg?: typeof SmartDataDbDoc,
2371
2371
  ): Promise<SmartdataDbWatcher> {
2372
- if ('capabilities' in this.smartdataDb &&
2373
- (this.smartdataDb.capabilities as { changeStreams?: string }).changeStreams === 'unsupported') {
2372
+ if (this.smartdataDb.capabilities?.changeStreams === 'unsupported') {
2374
2373
  throw new LosslessClientError('unsupported_capability', 'Change streams are unsupported by this backend.');
2375
2374
  }
2376
2375
  await this.init();
@@ -1,8 +1,14 @@
1
1
  import { SmartdataDb } from './classes.db.js';
2
+ import {
3
+ composeSmartdataCapabilities,
4
+ smartdataCompositeGrouping,
5
+ type ISmartdataEngineIdentity,
6
+ type TSmartdataEngineBackend,
7
+ } from './engineidentity.js';
2
8
  import type { ICapabilities, IOperationOptions, IReadiness } from '../core/interfaces.js';
3
9
 
4
10
  export interface INoSqlConnectionOptions {
5
- backend: 'nosqldb' | 'mongodb';
11
+ backend: TSmartdataEngineBackend;
6
12
  url: string;
7
13
  database: string;
8
14
  username?: string;
@@ -11,17 +17,23 @@ export interface INoSqlConnectionOptions {
11
17
  }
12
18
 
13
19
  export class NoSqlConnection extends SmartdataDb {
14
- public readonly backend: 'nosqldb' | 'mongodb';
15
- public readonly capabilities: ICapabilities;
20
+ public readonly backend: TSmartdataEngineBackend;
21
+ private declaredCapabilities: ICapabilities;
22
+ /** A declared backend states its capabilities before the first connect. */
23
+ public override get capabilities(): ICapabilities { return this.declaredCapabilities; }
16
24
  constructor(public readonly options: INoSqlConnectionOptions) {
17
25
  super({ mongoDbUrl: options.url, mongoDbName: options.database,
18
26
  mongoDbUser: options.username, mongoDbPass: options.password,
19
27
  ...(options.connectionLimit === undefined ? {} : { maxPoolSize: options.connectionLimit }) });
20
28
  this.backend = options.backend;
21
- this.capabilities = Object.freeze({ backend: options.backend,
22
- transactions: options.backend === 'nosqldb' ? 'available' : 'unknown',
23
- changeStreams: options.backend === 'nosqldb' ? 'unsupported' : 'unknown',
24
- objectMetrics: 'unsupported', diskResidentScans: 'available' });
29
+ this.declaredCapabilities = composeSmartdataCapabilities(this.backend,
30
+ smartdataCompositeGrouping(this.engineIdentity));
31
+ }
32
+ /** The declared backend outranks the probe; only the probe knows the engine release. */
33
+ protected override applyEngineIdentity(identityArg: ISmartdataEngineIdentity): void {
34
+ super.applyEngineIdentity(identityArg);
35
+ this.declaredCapabilities = composeSmartdataCapabilities(this.backend,
36
+ smartdataCompositeGrouping(identityArg));
25
37
  }
26
38
  public async connect(options: IOperationOptions = {}): Promise<void> { await this.init(options); }
27
39
  public async ready(options: IOperationOptions = {}): Promise<IReadiness> {
@@ -22,6 +22,15 @@ export type { TSmartdataOrdinarySession } from './classes.session.js';
22
22
 
23
23
  import { logger } from './logging.js';
24
24
  import { assertDataOptions, SmartdataOperationBudget } from './classes.operationbudget.js';
25
+ import {
26
+ composeSmartdataCapabilities,
27
+ probeSmartdataEngineIdentity,
28
+ smartdataCompositeGrouping,
29
+ smartdataEngineBackend,
30
+ unidentifiedSmartdataEngine,
31
+ type ISmartdataEngineIdentity,
32
+ } from './engineidentity.js';
33
+ import type { ICapabilities } from '../core/interfaces.js';
25
34
 
26
35
  /**
27
36
  * interface - indicates the connection status of the db
@@ -139,6 +148,8 @@ export class SmartdataDb {
139
148
  private lifecycleEpoch = 0;
140
149
  private activeLifecycleOperation: TSmartdataDbLifecycleOperation | null = null;
141
150
  private pendingClient?: plugins.mongodb.MongoClient;
151
+ private engineIdentityState: ISmartdataEngineIdentity = unidentifiedSmartdataEngine;
152
+ private capabilitiesState: ICapabilities | undefined;
142
153
 
143
154
  constructor(smartdataOptions: plugins.tsclass.database.IMongoDescriptor) {
144
155
  this.smartdataOptions = smartdataOptions;
@@ -146,6 +157,28 @@ export class SmartdataDb {
146
157
  void this.statusConnectedDeferred.promise.catch(() => {});
147
158
  }
148
159
 
160
+ /** What the last `init()` identified the connected engine as. */
161
+ public get engineIdentity(): ISmartdataEngineIdentity {
162
+ return this.engineIdentityState;
163
+ }
164
+
165
+ /**
166
+ * What the identified engine can do, or `undefined` while no engine is
167
+ * identified. A caller must read the absent statement as "not available".
168
+ */
169
+ public get capabilities(): ICapabilities | undefined {
170
+ return this.capabilitiesState;
171
+ }
172
+
173
+ /** Records the identity `init()` read and restates the capabilities it implies. */
174
+ protected applyEngineIdentity(identityArg: ISmartdataEngineIdentity): void {
175
+ this.engineIdentityState = identityArg;
176
+ const backend = smartdataEngineBackend(identityArg);
177
+ this.capabilitiesState = backend === undefined
178
+ ? undefined
179
+ : composeSmartdataCapabilities(backend, smartdataCompositeGrouping(identityArg));
180
+ }
181
+
149
182
  // easystore
150
183
  public async createEasyStore<T = unknown>(nameIdArg: string): Promise<EasyStore<T>> {
151
184
  const easyStore = new EasyStore<T>(nameIdArg, this);
@@ -224,6 +257,11 @@ export class SmartdataDb {
224
257
  collection.resetForDatabaseReconnect();
225
258
  }
226
259
  budget?.check();
260
+ // The engine is asked what it is before the connection is published, so
261
+ // no operation can run against a database whose capabilities are stale.
262
+ this.applyEngineIdentity(await probeSmartdataEngineIdentity(candidateDb, budget));
263
+ // The probe absorbs its own failures, so a budget that expired during it must still refuse here.
264
+ budget?.check();
227
265
  this.mongoDbClient = candidateClient;
228
266
  this.mongoDb = candidateDb;
229
267
  candidateClient = undefined;
@@ -5001,6 +5001,20 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
5001
5001
  120_000,
5002
5002
  );
5003
5003
  const timeoutMS = requireBoundedInteger(timeoutMSOption, 'Grouped totals timeoutMS', 120_000);
5004
+ const collection: SmartdataCollection<T> = (this as any).collection;
5005
+ if (
5006
+ groupByFields.length === 2
5007
+ && collection.smartdataDb.capabilities?.compositeGrouping !== 'exact'
5008
+ ) {
5009
+ // The backend would answer a composite group key without evaluating it,
5010
+ // and a wrong total that never raises is worse than no total at all.
5011
+ throw new SmartdataPersistenceError(
5012
+ 'unsupported_operation',
5013
+ `Grouped totals cannot group by "${groupByFields[0]}" and "${groupByFields[1]}" together: `
5014
+ + 'this backend does not evaluate a composite group key exactly. Group by one field per '
5015
+ + `call, such as groupBy: ["${groupByFields[0]}"].`,
5016
+ );
5017
+ }
5004
5018
  const groupStage: Record<string, unknown> = {
5005
5019
  _id: groupByFields.length === 1
5006
5020
  ? '$' + groupByFields[0]
@@ -5012,7 +5026,6 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
5012
5026
  for (const [index, sumField] of sumFields.entries()) {
5013
5027
  groupStage['__groupedTotalsSum' + index] = { $sum: '$' + sumField };
5014
5028
  }
5015
- const collection: SmartdataCollection<T> = (this as any).collection;
5016
5029
  const rows = await collection.aggregateGroupedTotals(
5017
5030
  filterOption !== undefined
5018
5031
  ? (this as any).normalizeReadFilter(filterOption)
@@ -50,6 +50,22 @@ export class EasyStore<T> {
50
50
  this.easyStoreClass = getEasyStoreClassForDb<T>(smartdataDbRefArg);
51
51
  }
52
52
 
53
+ /**
54
+ * Installs the store's declared `nameId` index before any caller opens a
55
+ * transaction, and resolves once the collection is initialized. Idempotent:
56
+ * every call after the first returns without touching the backend.
57
+ *
58
+ * A model's declared indexes are created on the first model-API touch of its
59
+ * collection, as unsessioned DDL. While a transaction holds that collection
60
+ * the DDL waits for it, so a first `readKey()`/`writeKey()` raced against a
61
+ * transaction stalls until the client deadline instead of answering. A
62
+ * consumer that opens transactions on the same database calls this once
63
+ * during startup, before the store is read or written.
64
+ */
65
+ public async ensureInitialized(): Promise<void> {
66
+ await (this.easyStoreClass as typeof SmartDataDbDoc).ensureInitialized();
67
+ }
68
+
53
69
  private easyStorePromise?: Promise<InstanceType<typeof this.easyStoreClass>>;
54
70
  private async getEasyStore(): Promise<InstanceType<typeof this.easyStoreClass>> {
55
71
  if (this.easyStorePromise) {
@@ -0,0 +1,153 @@
1
+ import * as plugins from './plugins.js';
2
+ import type { SmartdataOperationBudget } from './classes.operationbudget.js';
3
+ import type { ICapabilities, TCompositeGrouping } from '../core/interfaces.js';
4
+
5
+ /**
6
+ * What the connected engine states it is. `unknown` is the fail-closed answer:
7
+ * the engine either does not implement the identity probe or does not answer it
8
+ * in a shape that identifies anything.
9
+ */
10
+ export type TSmartdataEngineProduct = 'NoSQLDB' | 'MongoDB' | 'unknown';
11
+
12
+ /** The document backend a connection is actually talking to. */
13
+ export type TSmartdataEngineBackend = 'nosqldb' | 'mongodb';
14
+
15
+ export interface ISmartdataEngineIdentity {
16
+ readonly product: TSmartdataEngineProduct;
17
+ /**
18
+ * The engine's own version — NoSQLDB's released package version, MongoDB's
19
+ * server version — or `null` when the engine states none.
20
+ */
21
+ readonly version: string | null;
22
+ }
23
+
24
+ export const unidentifiedSmartdataEngine: ISmartdataEngineIdentity = Object.freeze({
25
+ product: 'unknown',
26
+ version: null,
27
+ });
28
+
29
+ /**
30
+ * The NoSQLDB release that evaluates a composite `$group` key instead of
31
+ * answering with the literal field paths: @lossless.org/nosqldb 10.5.0.
32
+ */
33
+ const compositeGroupingEngineRelease = '10.5.0';
34
+
35
+ const parseEngineVersion = (versionArg: string): readonly number[] | undefined => {
36
+ const parts = versionArg.split('.');
37
+ if (parts.length !== 3) {
38
+ return undefined;
39
+ }
40
+ const numbers = parts.map((partArg) =>
41
+ /^\d+$/.test(partArg) ? Number(partArg) : Number.NaN,
42
+ );
43
+ return numbers.some((numberArg) => !Number.isSafeInteger(numberArg)) ? undefined : numbers;
44
+ };
45
+
46
+ /**
47
+ * Compares two release versions. A version this cannot parse — a prerelease or
48
+ * any other shape — counts as below the minimum, so an engine only ever gains a
49
+ * capability by stating a release that plainly carries it.
50
+ */
51
+ const engineVersionReaches = (versionArg: string, minimumArg: string): boolean => {
52
+ const version = parseEngineVersion(versionArg);
53
+ const minimum = parseEngineVersion(minimumArg);
54
+ if (version === undefined || minimum === undefined) {
55
+ return false;
56
+ }
57
+ for (const [index, minimumPart] of minimum.entries()) {
58
+ if (version[index] !== minimumPart) {
59
+ return version[index] > minimumPart;
60
+ }
61
+ }
62
+ return true;
63
+ };
64
+
65
+ export const smartdataEngineBackend = (
66
+ identityArg: ISmartdataEngineIdentity,
67
+ ): TSmartdataEngineBackend | undefined => {
68
+ switch (identityArg.product) {
69
+ case 'NoSQLDB':
70
+ return 'nosqldb';
71
+ case 'MongoDB':
72
+ return 'mongodb';
73
+ case 'unknown':
74
+ return undefined;
75
+ }
76
+ };
77
+
78
+ export const smartdataCompositeGrouping = (
79
+ identityArg: ISmartdataEngineIdentity,
80
+ ): TCompositeGrouping => {
81
+ switch (identityArg.product) {
82
+ case 'MongoDB':
83
+ return 'exact';
84
+ case 'NoSQLDB':
85
+ return identityArg.version !== null
86
+ && engineVersionReaches(identityArg.version, compositeGroupingEngineRelease)
87
+ ? 'exact'
88
+ : 'unsupported';
89
+ case 'unknown':
90
+ return 'unsupported';
91
+ }
92
+ };
93
+
94
+ export const composeSmartdataCapabilities = (
95
+ backendArg: TSmartdataEngineBackend,
96
+ compositeGroupingArg: TCompositeGrouping,
97
+ ): ICapabilities => {
98
+ const capabilities: ICapabilities = {
99
+ backend: backendArg,
100
+ transactions: backendArg === 'nosqldb' ? 'available' : 'unknown',
101
+ changeStreams: backendArg === 'nosqldb' ? 'unsupported' : 'unknown',
102
+ compositeGrouping: compositeGroupingArg,
103
+ objectMetrics: 'unsupported',
104
+ diskResidentScans: 'available',
105
+ };
106
+ return Object.freeze(capabilities);
107
+ };
108
+
109
+ const isDocumentRecord = (valueArg: unknown): valueArg is Record<string, unknown> =>
110
+ typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg);
111
+
112
+ const readSmartdataEngineIdentity = (
113
+ answerArg: plugins.mongodb.Document,
114
+ ): ISmartdataEngineIdentity => {
115
+ const vendorDocument: unknown = answerArg.nosqldb;
116
+ if (vendorDocument === undefined) {
117
+ // No vendor document: a MongoDB `buildInfo`, whose `version` is the server's own.
118
+ const version: unknown = answerArg.version;
119
+ return Object.freeze({
120
+ product: 'MongoDB',
121
+ version: typeof version === 'string' ? version : null,
122
+ });
123
+ }
124
+ if (
125
+ isDocumentRecord(vendorDocument)
126
+ && vendorDocument.product === 'NoSQLDB'
127
+ && typeof vendorDocument.version === 'string'
128
+ ) {
129
+ return Object.freeze({ product: 'NoSQLDB', version: vendorDocument.version });
130
+ }
131
+ // A vendor document that states no product and version identifies nothing.
132
+ return unidentifiedSmartdataEngine;
133
+ };
134
+
135
+ /**
136
+ * Asks the connected engine what it is with one `buildInfo` command. NoSQLDB
137
+ * answers it pre-authentication and from build metadata alone; MongoDB answers
138
+ * it for every connection. An engine that refuses the command — NoSQLDB 8.0.2
139
+ * answers `CommandNotFound` (59) — stays unidentified, and an unidentified
140
+ * engine never enables a capability.
141
+ */
142
+ export const probeSmartdataEngineIdentity = async (
143
+ dbArg: plugins.mongodb.Db,
144
+ budgetArg?: SmartdataOperationBudget,
145
+ ): Promise<ISmartdataEngineIdentity> => {
146
+ try {
147
+ return readSmartdataEngineIdentity(
148
+ await dbArg.command({ buildInfo: 1 }, budgetArg?.operationOptions()),
149
+ );
150
+ } catch {
151
+ return unidentifiedSmartdataEngine;
152
+ }
153
+ };
@@ -3,6 +3,17 @@ import './shim.js';
3
3
 
4
4
  export { NoSqlConnection } from './classes.connection.js';
5
5
  export type { INoSqlConnectionOptions } from './classes.connection.js';
6
+ export type {
7
+ ISmartdataEngineIdentity,
8
+ TSmartdataEngineBackend,
9
+ TSmartdataEngineProduct,
10
+ } from './engineidentity.js';
11
+ export type {
12
+ ICapabilities,
13
+ TBackend,
14
+ TCapability,
15
+ TCompositeGrouping,
16
+ } from '../core/interfaces.js';
6
17
  export { nosqldbLineage } from './lineage.js';
7
18
  export type { INosqldbLineage } from './lineage.js';
8
19
 
@@ -20,6 +20,8 @@ export const nosqldbLineage: INosqldbLineage = Object.freeze({
20
20
  'classes.connection.ts adds NoSqlConnection with the client backend, capability and readiness contract.',
21
21
  'index.ts exports NoSqlConnection, INoSqlConnectionOptions and this lineage constant.',
22
22
  'classes.collection.ts refuses watch() when the connected backend reports change streams as unsupported.',
23
+ 'classes.db.ts identifies the engine at init() and states the capabilities that identity implies.',
24
+ 'classes.doc.ts refuses two-field grouped totals on a backend that does not group composite keys exactly.',
23
25
  'The package version file is dropped; versioning belongs to @lossless.org/client.',
24
26
  ]),
25
27
  });
@@ -26,7 +26,7 @@ export class ObjectStorageConnection extends SmartBucket {
26
26
  { forcePathStyle: options.forcePathStyle });
27
27
  this.backend = options.backend;
28
28
  this.capabilities = Object.freeze({ backend: this.backend, transactions: 'unsupported', changeStreams: 'unsupported',
29
- objectMetrics: 'unsupported', diskResidentScans: 'unknown' });
29
+ compositeGrouping: 'unsupported', objectMetrics: 'unsupported', diskResidentScans: 'unknown' });
30
30
  }
31
31
  public async ready(options: IOperationOptions = {}): Promise<IReadiness> {
32
32
  if (!this.options.readinessBucket) return { ready: false, reason: 'readiness_bucket_required' };