@classytic/mongokit 3.44.0 → 3.45.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/README.md +4 -3
- package/dist/{PaginationEngine-C9iS0U5l.mjs → PaginationEngine-BRlLTQQz.mjs} +1 -1
- package/dist/{PaginationEngine-D17AthKw.d.mts → PaginationEngine-BWb-c47a.d.mts} +1 -1
- package/dist/{Repository-B6oL6OMv.d.mts → Repository-DJuRmBNx.d.mts} +16 -7
- package/dist/{Repository-eMRYZ_2Y.mjs → Repository-DheA7oW-.mjs} +135 -29
- package/dist/actions/index.d.mts +1 -1
- package/dist/actions/index.mjs +2 -2
- package/dist/{actions-DExyXMTy.mjs → actions-DKQx9ToJ.mjs} +1 -1
- package/dist/ai/index.d.mts +1 -1
- package/dist/better-auth/index.d.mts +5 -2
- package/dist/better-auth/index.mjs +10 -20
- package/dist/{create-repository-D7MQpIZo.mjs → create-repository-C9DHHcl7.mjs} +3 -3
- package/dist/{create-repository-BOFUYj1l.d.mts → create-repository-DG-gwOf0.d.mts} +5 -5
- package/dist/{index-8QUEsOFI.d.mts → index-5mhQ63_B.d.mts} +2 -2
- package/dist/index.d.mts +19 -18
- package/dist/index.mjs +10 -10
- package/dist/{method-registry.plugin-CGAepsBU.mjs → method-registry.plugin-BeJfQBJV.mjs} +2 -2
- package/dist/{multi-tenant.plugin-DfeDMiI8.d.mts → multi-tenant.plugin-BTPtCLNK.d.mts} +2 -2
- package/dist/{operations-Dw9OFV0V.d.mts → operations-D6XsHx4e.d.mts} +6 -7
- package/dist/outbox/index.d.mts +2 -2
- package/dist/outbox/index.mjs +2 -2
- package/dist/pagination/PaginationEngine.d.mts +1 -1
- package/dist/pagination/PaginationEngine.mjs +1 -1
- package/dist/pagination/utils/limits.d.mts +1 -1
- package/dist/{pagination-DAUg5zOY.d.mts → pagination-BAM9cA4N.d.mts} +5 -7
- package/dist/{plugin-options-Bpcuz9kS.d.mts → plugin-options-DrNGWV5b.d.mts} +2 -2
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +4 -4
- package/dist/{query-defaults-aUoKlEbh.mjs → query-defaults-DwvWUjZU.mjs} +16 -51
- package/dist/read-model/index.d.mts +1 -1
- package/dist/{repository-DzVIwhU2.d.mts → repository-B0aFVgP2.d.mts} +1 -1
- package/dist/{retention-purge-DqcYvRnG.d.mts → retention-purge-CCd_VXUf.d.mts} +4 -1
- package/dist/sync/index.d.mts +25 -9
- package/dist/sync/index.mjs +122 -12
- package/dist/testkit/index.d.mts +2 -2
- package/dist/testkit/index.mjs +1 -1
- package/dist/{timestamp.plugin-Bz_zL9PX.mjs → timestamp.plugin-B-IJrlYb.mjs} +1 -1
- package/dist/{to-plain-PO5r1Qoy.d.mts → to-plain-Do-8jTKC.d.mts} +2 -2
- package/dist/{transaction-C2PFxfIv.mjs → transaction-C6Oj941P.mjs} +14 -12
- package/dist/{update-DcfmNbJe.mjs → update-CYaJMu6j.mjs} +2 -4
- package/dist/utils/index.d.mts +1 -1
- package/dist/{validation-chain.plugin-B3gZCZj4.d.mts → validation-chain.plugin-COYrUdd8.d.mts} +19 -4
- package/dist/{validation-chain.plugin-DNY6MIF6.mjs → validation-chain.plugin-DJplVJ12.mjs} +10 -7
- package/package.json +11 -11
- package/skills/mongokit/references/plugins-tenancy.md +1 -0
- package/skills/mongokit/references/transactions-outbox.md +3 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { u as setTransactionDeadline } from "./query-defaults-DwvWUjZU.mjs";
|
|
2
2
|
import { t as createError } from "./error-DjdmPLWO.mjs";
|
|
3
3
|
import mongoose from "mongoose";
|
|
4
4
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
@@ -494,18 +494,17 @@ function timeoutError(cause, csot) {
|
|
|
494
494
|
}
|
|
495
495
|
/**
|
|
496
496
|
* The driver's convenient-transaction algorithm (start → callback → commit, label-based retry,
|
|
497
|
-
* jittered backoff, a deadline), run here
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
497
|
+
* jittered backoff, a deadline), run here and nowhere else: the driver's own `timeoutMS` / CSOT is a
|
|
498
|
+
* no-op since 7.8, so the budget is mongokit's. `transactionOptions.timeoutMS` is that budget, enforced
|
|
499
|
+
* by mongokit alone: every mongokit operation in the transaction is sent with `maxTimeMS` = what
|
|
500
|
+
* remains of it, the commit is bounded by `maxCommitTimeMS`, and the retry loop stops at the deadline
|
|
501
|
+
* (a spent budget before the commit aborts, so the outcome is known). Without it the deadline is 120 s
|
|
502
|
+
* (as the driver) and operations carry only their own bound. The client's `timeoutMS` is not read.
|
|
503
|
+
* Pinned by `tests/integration/transaction-budget-matrix.test.ts`.
|
|
503
504
|
*/
|
|
504
505
|
async function runTransaction(session, callback, transactionOptions = {}) {
|
|
505
506
|
assertSessionSurface(session, DRIVEN);
|
|
506
|
-
const { timeoutMS
|
|
507
|
-
const clientTimeout = session.timeoutMS;
|
|
508
|
-
const timeoutMS = explicitTimeout ?? clientTimeout;
|
|
507
|
+
const { timeoutMS, ...startOptions } = transactionOptions;
|
|
509
508
|
const csot = timeoutMS != null;
|
|
510
509
|
const deadline = performance.now() + (timeoutMS ?? MAX_TRANSACTION_TIMEOUT_MS);
|
|
511
510
|
let lastError;
|
|
@@ -517,7 +516,10 @@ async function runTransaction(session, callback, transactionOptions = {}) {
|
|
|
517
516
|
if (performance.now() + backoff >= deadline) throw timeoutError(lastError, csot);
|
|
518
517
|
await setTimeout$1(backoff);
|
|
519
518
|
}
|
|
520
|
-
session.startTransaction(startOptions
|
|
519
|
+
session.startTransaction(csot && startOptions.maxCommitTimeMS === void 0 ? {
|
|
520
|
+
...startOptions,
|
|
521
|
+
maxCommitTimeMS: Math.max(1, Math.floor(deadline - performance.now()))
|
|
522
|
+
} : startOptions);
|
|
521
523
|
let result;
|
|
522
524
|
try {
|
|
523
525
|
result = await callback(session);
|
|
@@ -539,7 +541,7 @@ async function runTransaction(session, callback, transactionOptions = {}) {
|
|
|
539
541
|
throw late;
|
|
540
542
|
}
|
|
541
543
|
try {
|
|
542
|
-
await session.commitTransaction(
|
|
544
|
+
await session.commitTransaction();
|
|
543
545
|
return result;
|
|
544
546
|
} catch (err) {
|
|
545
547
|
lastError = err;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.mjs";
|
|
2
2
|
import { t as createError } from "./error-DjdmPLWO.mjs";
|
|
3
3
|
import { n as warn } from "./logger-hbWOlj_X.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { r as applyToQuery } from "./query-defaults-DwvWUjZU.mjs";
|
|
5
5
|
import { coerceFilterDates, isFilter } from "@classytic/repo-core/filter";
|
|
6
6
|
// src/actions/create.ts
|
|
7
7
|
var create_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -17,8 +17,6 @@ var create_exports = /* @__PURE__ */ __exportAll({
|
|
|
17
17
|
async function create(Model, data, options = {}) {
|
|
18
18
|
const document = new Model(data);
|
|
19
19
|
const saveOptions = { session: options.session };
|
|
20
|
-
const bound = options.queryOptions?.maxTimeMS;
|
|
21
|
-
if (bound !== void 0) Object.assign(saveOptions, { timeoutMS: bound });
|
|
22
20
|
const wc = options.queryOptions?.writeConcern;
|
|
23
21
|
if (wc) Object.assign(saveOptions, { writeConcern: {
|
|
24
22
|
...wc.w !== void 0 ? { w: wc.w } : {},
|
|
@@ -71,7 +69,7 @@ async function createMany(Model, dataArray, options = {}) {
|
|
|
71
69
|
const wc = options.queryOptions?.writeConcern;
|
|
72
70
|
if (wc) Object.assign(insertOptions, { writeConcern: wc });
|
|
73
71
|
const bound = options.queryOptions?.maxTimeMS;
|
|
74
|
-
if (bound !== void 0) Object.assign(insertOptions, {
|
|
72
|
+
if (bound !== void 0) Object.assign(insertOptions, { maxTimeMS: bound });
|
|
75
73
|
return await Model.insertMany(dataArray, insertOptions);
|
|
76
74
|
} catch (err) {
|
|
77
75
|
const inserted = err.insertedDocs;
|
package/dist/utils/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as getMongooseProjection, a as createMemoryCache, b as createError, c as IdType, d as isObjectIdInstance, f as isValidIdForType, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, l as getSchemaIdType, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, p as toObjectId, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, v as CreateErrorOptions, y as ParseDuplicateKeyOptions } from "../to-plain-
|
|
1
|
+
import { _ as getMongooseProjection, a as createMemoryCache, b as createError, c as IdType, d as isObjectIdInstance, f as isValidIdForType, g as getFieldsForUser, h as filterResponseData, i as buildCrudSchemasFromMongooseSchema, l as getSchemaIdType, m as createFieldPreset, n as CrudSchemasFramework, o as LoggerConfig, p as toObjectId, r as buildCrudSchemasFromModel, s as configureLogger, t as toPlain, v as CreateErrorOptions, y as ParseDuplicateKeyOptions } from "../to-plain-Do-8jTKC.mjs";
|
|
2
2
|
import { ClientSession, Model } from "mongoose";
|
|
3
3
|
/**
|
|
4
4
|
* Default slice for `$in` fan-out. Larger than `runChunkedPurge`'s 1000 on purpose:
|
package/dist/{validation-chain.plugin-B3gZCZj4.d.mts → validation-chain.plugin-COYrUdd8.d.mts}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-
|
|
2
|
-
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-
|
|
3
|
-
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest } from "./retention-purge-
|
|
4
|
-
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-
|
|
1
|
+
import { A as ObjectId, F as SortSpec, N as SelectSpec, j as PopulateSpec } from "./pagination-BAM9cA4N.mjs";
|
|
2
|
+
import { h as RepositoryInstance, l as Plugin, p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
|
|
3
|
+
import { n as RetentionPurgeEvent, r as RetentionPurgeRequest } from "./retention-purge-CCd_VXUf.mjs";
|
|
4
|
+
import { c as ValidationChainOptions, i as Logger, l as ValidatorDefinition, o as SoftDeleteOptions, r as FieldPreset, t as CascadeOptions } from "./plugin-options-DrNGWV5b.mjs";
|
|
5
5
|
import { BulkWriteResult } from "@classytic/repo-core/repository";
|
|
6
6
|
import { OffsetPaginationResult } from "@classytic/repo-core/pagination";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -112,6 +112,13 @@ interface AppendOnlyPluginOptions {
|
|
|
112
112
|
* refused (403 `RETENTION_PURGE_DISABLED`).
|
|
113
113
|
*/
|
|
114
114
|
allowPurge?: boolean | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Allow `archiveByFilter(filter, sink, { retentionPurge })` to delete the rows its
|
|
117
|
+
* sink acknowledged, and nothing else: a retentionPurge delete without the run's
|
|
118
|
+
* attestation is still refused. Audited via `after:append-only-purge` with
|
|
119
|
+
* `archived: true`. Implied by `allowPurge`. Default `false`.
|
|
120
|
+
*/
|
|
121
|
+
allowArchive?: boolean | undefined;
|
|
115
122
|
}
|
|
116
123
|
/** Payload of `after:append-only-purge`: one per successful purge call. */
|
|
117
124
|
type AppendOnlyPurgeEvent = RetentionPurgeEvent;
|
|
@@ -127,6 +134,8 @@ interface BulkWriteOptions {
|
|
|
127
134
|
comment?: unknown;
|
|
128
135
|
let?: Record<string, unknown>;
|
|
129
136
|
ignoreUndefined?: boolean;
|
|
137
|
+
/** Server-side time bound for the write. */
|
|
138
|
+
maxTimeMS?: number;
|
|
130
139
|
/** Plugin context (tenant id, actor, ...) - spread into the op context. */
|
|
131
140
|
[key: string]: unknown;
|
|
132
141
|
}
|
|
@@ -358,6 +367,12 @@ interface ImmutableStatesPluginOptions {
|
|
|
358
367
|
* option is refused (403 `RETENTION_PURGE_DISABLED`).
|
|
359
368
|
*/
|
|
360
369
|
allowPurge?: boolean | undefined;
|
|
370
|
+
/**
|
|
371
|
+
* Allow `archiveByFilter(filter, sink, { retentionPurge })` to delete frozen rows its
|
|
372
|
+
* sink acknowledged, and nothing else (see `appendOnlyPlugin`'s `allowArchive`).
|
|
373
|
+
* Implied by `allowPurge`. Default `false`.
|
|
374
|
+
*/
|
|
375
|
+
allowArchive?: boolean | undefined;
|
|
361
376
|
/** Domain error to throw. Default: 403 `IMMUTABLE_STATE_VIOLATION`. */
|
|
362
377
|
errorFactory?: ((ctx: {
|
|
363
378
|
id: unknown;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { t as createError } from "./error-DjdmPLWO.mjs";
|
|
2
|
-
import { a as ALL_OPERATIONS, f as readRetentionPurge, p as retentionPurgeEvent, s as OP_REGISTRY } from "./Repository-
|
|
2
|
+
import { a as ALL_OPERATIONS, f as readRetentionPurge, p as retentionPurgeEvent, s as OP_REGISTRY } from "./Repository-DheA7oW-.mjs";
|
|
3
3
|
import { n as collectIds, r as idChunks, t as DEFAULT_ID_CHUNK } from "./id-chunks-DH-RAZWG.mjs";
|
|
4
|
-
import { w as upsert } from "./update-
|
|
4
|
+
import { w as upsert } from "./update-CYaJMu6j.mjs";
|
|
5
5
|
import { n as warn } from "./logger-hbWOlj_X.mjs";
|
|
6
|
-
import { c as tenantContextKeysOf, o as forwardScope } from "./timestamp.plugin-
|
|
6
|
+
import { c as tenantContextKeysOf, o as forwardScope } from "./timestamp.plugin-B-IJrlYb.mjs";
|
|
7
7
|
import { r as getFieldsForUser } from "./field-selection-DPFaFw9Y.mjs";
|
|
8
8
|
import mongoose from "mongoose";
|
|
9
9
|
import { HOOK_PRIORITY } from "@classytic/repo-core/hooks";
|
|
@@ -125,6 +125,7 @@ function aggregateHelpersPlugin() {
|
|
|
125
125
|
* applies). The same option is honoured by `immutableStatesPlugin`, so a
|
|
126
126
|
* repository with both plugins purges through one call. Prefer it over
|
|
127
127
|
* `bypassAppendOnly` for retention: it is delete-only and carries a reason.
|
|
128
|
+
* `allowArchive: true` admits only `archiveByFilter`'s attested chunk deletes.
|
|
128
129
|
*
|
|
129
130
|
* `skipPlugins` is deliberately IGNORED — same policy as tenant scope
|
|
130
131
|
* and soft delete: integrity fences don't have a convenience bypass.
|
|
@@ -154,7 +155,8 @@ function appendOnlyPlugin(options = {}) {
|
|
|
154
155
|
const modelName = repo.Model?.modelName ?? "model";
|
|
155
156
|
const purgeGuard = {
|
|
156
157
|
plugin: "appendOnlyPlugin",
|
|
157
|
-
allowPurge: options.allowPurge === true
|
|
158
|
+
allowPurge: options.allowPurge === true,
|
|
159
|
+
allowArchive: options.allowArchive === true
|
|
158
160
|
};
|
|
159
161
|
const priority = options.priority ?? HOOK_PRIORITY.POLICY;
|
|
160
162
|
for (const [op, meta] of Object.entries(OP_REGISTRY)) {
|
|
@@ -183,7 +185,7 @@ function appendOnlyPlugin(options = {}) {
|
|
|
183
185
|
});
|
|
184
186
|
}, { priority });
|
|
185
187
|
}
|
|
186
|
-
if (options.allowPurge) for (const op of ["delete", "deleteMany"]) repo.on(`after:${op}`, async (payload) => {
|
|
188
|
+
if (options.allowPurge || options.allowArchive) for (const op of ["delete", "deleteMany"]) repo.on(`after:${op}`, async (payload) => {
|
|
187
189
|
const event = retentionPurgeEvent(op, payload.context, payload.result);
|
|
188
190
|
if (event) await repo.emitAsync("after:append-only-purge", event);
|
|
189
191
|
});
|
|
@@ -827,7 +829,8 @@ function immutableStatesPlugin(options) {
|
|
|
827
829
|
};
|
|
828
830
|
const purgeGuard = {
|
|
829
831
|
plugin: "immutableStatesPlugin",
|
|
830
|
-
allowPurge: options.allowPurge === true
|
|
832
|
+
allowPurge: options.allowPurge === true,
|
|
833
|
+
allowArchive: options.allowArchive === true
|
|
831
834
|
};
|
|
832
835
|
const purgeRequest = (op, ctx) => readRetentionPurge(ctx, op, purgeGuard);
|
|
833
836
|
for (const op of [
|
|
@@ -842,7 +845,7 @@ function immutableStatesPlugin(options) {
|
|
|
842
845
|
await guardDelete(ctx);
|
|
843
846
|
});
|
|
844
847
|
const emitPurge = async (operation, context, result) => {
|
|
845
|
-
if (!options.allowPurge || context[internalFlag]) return;
|
|
848
|
+
if (!(options.allowPurge || options.allowArchive) || context[internalFlag]) return;
|
|
846
849
|
const base = retentionPurgeEvent(operation, context, result);
|
|
847
850
|
if (!base) return;
|
|
848
851
|
const event = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/mongokit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.45.0",
|
|
4
4
|
"description": "Production-grade MongoDB repositories - smart pagination, events, and plugins. Built on @classytic/repo-core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -152,9 +152,9 @@
|
|
|
152
152
|
},
|
|
153
153
|
"homepage": "https://github.com/classytic/mongokit#readme",
|
|
154
154
|
"peerDependencies": {
|
|
155
|
-
"@classytic/repo-core": ">=0.
|
|
155
|
+
"@classytic/repo-core": ">=0.38.0",
|
|
156
156
|
"mongodb-memory-server": ">=11.3.0",
|
|
157
|
-
"mongoose": ">=9.
|
|
157
|
+
"mongoose": ">=9.12.0"
|
|
158
158
|
},
|
|
159
159
|
"peerDependenciesMeta": {
|
|
160
160
|
"mongodb-memory-server": {
|
|
@@ -202,25 +202,25 @@
|
|
|
202
202
|
},
|
|
203
203
|
"devDependencies": {
|
|
204
204
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
205
|
-
"@better-auth/api-key": "^1.7.
|
|
206
|
-
"@better-auth/mongo-adapter": "^1.7.
|
|
207
|
-
"@biomejs/biome": "^2.6.
|
|
205
|
+
"@better-auth/api-key": "^1.7.18",
|
|
206
|
+
"@better-auth/mongo-adapter": "^1.7.18",
|
|
207
|
+
"@biomejs/biome": "^2.6.5",
|
|
208
208
|
"@classytic/dev-tools": "^0.2.1",
|
|
209
|
-
"@classytic/repo-core": "^0.
|
|
209
|
+
"@classytic/repo-core": "^0.38.0",
|
|
210
210
|
"@types/node": "^26.6.6",
|
|
211
211
|
"@vitest/coverage-v8": "^5.1.0",
|
|
212
212
|
"ajv": "^8.20.0",
|
|
213
213
|
"ajv-formats": "^3.0.1",
|
|
214
|
-
"better-auth": "^1.7.
|
|
214
|
+
"better-auth": "^1.7.18",
|
|
215
215
|
"dotenv": "^18.0.9",
|
|
216
216
|
"fast-check": "^4.10.2",
|
|
217
217
|
"knip": "^6.44.1",
|
|
218
|
-
"mongodb": "~7.
|
|
218
|
+
"mongodb": "~7.8.0",
|
|
219
219
|
"mongodb-memory-server": "^11.3.0",
|
|
220
|
-
"mongoose": "^9.
|
|
220
|
+
"mongoose": "^9.12.0",
|
|
221
221
|
"publint": "^0.3.25",
|
|
222
222
|
"ts-api": "npm:typescript@~5.9.3",
|
|
223
|
-
"tsdown": "^0.23.
|
|
223
|
+
"tsdown": "^0.23.5",
|
|
224
224
|
"typescript": "~7.0.2",
|
|
225
225
|
"vitest": "^5.1.0"
|
|
226
226
|
}
|
|
@@ -37,6 +37,7 @@ Retention purge (append-only or frozen rows): build `appendOnlyPlugin` and/or `i
|
|
|
37
37
|
`purgeByFilter(filter, { type: 'hard' }, { retentionPurge: { reason, actor } })` (or `deleteMany(filter, { mode: 'hard', retentionPurge })`).
|
|
38
38
|
Each delete call emits `after:append-only-purge` / `after:immutable-states-purge` with `deletedCount` and `session`. Listeners are awaited and a
|
|
39
39
|
throwing one fails the purge; write the audit row with `{ session: event.session }` so it commits or aborts with the delete. Ordinary deletes stay refused.
|
|
40
|
+
Archive (move to cold storage) on those repos: `allowArchive: true`, then `archiveByFilter(filter, sink, { retentionPurge })`; only chunks the sink acknowledged are deleted (event `archived: true`).
|
|
40
41
|
Function-form anonymize writes through the guarded `updateMany` (frozen / append-only rows refused); `immutableStatesPlugin` reads state in the call's session.
|
|
41
42
|
|
|
42
43
|
`leasePlugin` (after `methodRegistryPlugin`): `lease({ filter, leaseFor, leasedBy, now })` claims a pending row or a dead lease (a row
|
|
@@ -77,12 +77,14 @@ Resolution order: per call, then repository (`queryDefaults` option), then deplo
|
|
|
77
77
|
import { assertQueryDefaultsConfigured, configureAggregateDefaults, configureQueryDefaults } from '@classytic/mongokit';
|
|
78
78
|
configureQueryDefaults({ maxTimeMS: 15000, readConcern: 'majority', comment: 'api' });
|
|
79
79
|
configureAggregateDefaults({ maxTimeMs: 30000, allowDiskUse: true });
|
|
80
|
-
assertQueryDefaultsConfigured(
|
|
80
|
+
assertQueryDefaultsConfigured(); // boot gate: throws without a deployment maxTimeMS
|
|
81
81
|
await repo.getAll({ mode: 'offset', page: 1 }, { comment: 'orders.list', maxTimeMS: 5000, hint: { organizationId: 1, createdAt: -1 } });
|
|
82
82
|
```
|
|
83
83
|
|
|
84
84
|
Inside a transaction a default read or write concern is dropped (the transaction owns it); a per-call one is passed through.
|
|
85
85
|
|
|
86
|
+
The bound is the server-side `maxTimeMS`. The driver's `timeoutMS` (CSOT) is a no-op since 7.8, so never rely on it. A single `create()` (Mongoose `save()`) forwards no `maxTimeMS` and is not server-bounded; `createMany`, updates, deletes, `bulkWrite`, reads and aggregates are. `withTransaction({ transactionOptions: { timeoutMS } })` is mongokit's own budget for the whole transaction: each operation gets `maxTimeMS` = what remains, the commit gets `maxCommitTimeMS`.
|
|
87
|
+
|
|
86
88
|
## Verify indexes
|
|
87
89
|
|
|
88
90
|
```ts
|