@classytic/mongokit 3.43.1 → 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.
Files changed (92) hide show
  1. package/README.md +18 -3
  2. package/dist/{PaginationEngine-DZnkbSrr.mjs → PaginationEngine-BRlLTQQz.mjs} +13 -27
  3. package/dist/{PaginationEngine-CRHyuUtw.d.mts → PaginationEngine-BWb-c47a.d.mts} +1 -3
  4. package/dist/{Repository-DnL4xk5w.d.mts → Repository-DJuRmBNx.d.mts} +44 -13
  5. package/dist/{Repository-Dj6xqPxJ.mjs → Repository-DheA7oW-.mjs} +330 -112
  6. package/dist/actions/index.d.mts +1 -1
  7. package/dist/actions/index.mjs +2 -2
  8. package/dist/{actions-ChYfkPYP.mjs → actions-DKQx9ToJ.mjs} +3 -4
  9. package/dist/adapter/index.d.mts +6 -10
  10. package/dist/adapter/index.mjs +1 -1
  11. package/dist/{adapter-CkMoMF83.mjs → adapter-Qzgc3ZD_.mjs} +4 -6
  12. package/dist/ai/index.d.mts +21 -8
  13. package/dist/ai/index.mjs +15 -9
  14. package/dist/better-auth/index.d.mts +21 -20
  15. package/dist/better-auth/index.mjs +12 -23
  16. package/dist/{coercion-BjdPX3YF.d.mts → coercion-COp9DRNw.d.mts} +0 -2
  17. package/dist/{create-repository-UjwPWR1z.mjs → create-repository-C9DHHcl7.mjs} +4 -5
  18. package/dist/{create-repository-CJtVdwig.d.mts → create-repository-DG-gwOf0.d.mts} +5 -7
  19. package/dist/{derive-DRBiegRH.mjs → derive-Dxsc31fV.mjs} +3 -6
  20. package/dist/{error-BuByZwKU.mjs → error-DjdmPLWO.mjs} +1 -2
  21. package/dist/{field-selection-FSQFLpsU.mjs → field-selection-DPFaFw9Y.mjs} +1 -2
  22. package/dist/{id-chunks-BmAwsqNk.mjs → id-chunks-DH-RAZWG.mjs} +13 -8
  23. package/dist/{id-resolution-BqDrk0S2.mjs → id-resolution-Cqh49d9J.mjs} +1 -2
  24. package/dist/idempotency/index.d.mts +4 -7
  25. package/dist/idempotency/index.mjs +1 -2
  26. package/dist/{index-SYF8N28D.d.mts → index-5mhQ63_B.d.mts} +3 -4
  27. package/dist/{index-C0AjVqX3.d.mts → index-ehGZLbrd.d.mts} +2 -8
  28. package/dist/index.d.mts +70 -102
  29. package/dist/index.mjs +36 -52
  30. package/dist/indexes/verify-indexes.d.mts +8 -11
  31. package/dist/indexes/verify-indexes.mjs +1 -2
  32. package/dist/{indexes-DIjMpYES.d.mts → indexes-FfyOuhDK.d.mts} +0 -2
  33. package/dist/{join-scope-DSAznE8E.mjs → join-scope-C1gOtZ59.mjs} +2 -3
  34. package/dist/kernel-conformance/index.d.mts +39 -13
  35. package/dist/kernel-conformance/index.mjs +4 -7
  36. package/dist/lock/index.d.mts +134 -7
  37. package/dist/lock/index.mjs +349 -14
  38. package/dist/{logger-K7dPmu2U.mjs → logger-hbWOlj_X.mjs} +1 -2
  39. package/dist/{method-registry.plugin-C63pGn1d.mjs → method-registry.plugin-BeJfQBJV.mjs} +5 -7
  40. package/dist/{model-registry-ClKtWiHa.mjs → model-registry-DrVfJ3Nt.mjs} +1 -2
  41. package/dist/{mongooseToJsonSchema-C3k4ide0.mjs → mongooseToJsonSchema-DMDotz4_.mjs} +2 -3
  42. package/dist/{multi-tenant.plugin-B_q9NUHc.d.mts → multi-tenant.plugin-BTPtCLNK.d.mts} +143 -11
  43. package/dist/{operations-XiFgG5US.d.mts → operations-D6XsHx4e.d.mts} +19 -11
  44. package/dist/outbox/index.d.mts +24 -9
  45. package/dist/outbox/index.mjs +17 -6
  46. package/dist/pagination/PaginationEngine.d.mts +1 -1
  47. package/dist/pagination/PaginationEngine.mjs +1 -1
  48. package/dist/pagination/utils/limits.d.mts +6 -9
  49. package/dist/pagination/utils/limits.mjs +2 -3
  50. package/dist/{pagination-D6psses0.d.mts → pagination-BAM9cA4N.d.mts} +6 -16
  51. package/dist/{plugin-options-Cirmb4Kp.d.mts → plugin-options-DrNGWV5b.d.mts} +2 -4
  52. package/dist/plugins/index.d.mts +6 -7
  53. package/dist/plugins/index.mjs +6 -7
  54. package/dist/query/primitives/coercion.d.mts +1 -1
  55. package/dist/query/primitives/coercion.mjs +2 -3
  56. package/dist/query/primitives/geo.d.mts +11 -14
  57. package/dist/query/primitives/geo.mjs +1 -2
  58. package/dist/query/primitives/indexes.d.mts +1 -1
  59. package/dist/query/primitives/indexes.mjs +1 -2
  60. package/dist/{query-defaults-BxUcSOoF.mjs → query-defaults-DwvWUjZU.mjs} +18 -54
  61. package/dist/read-model/index.d.mts +18 -21
  62. package/dist/read-model/index.mjs +3 -4
  63. package/dist/{repository-MqAP409e.d.mts → repository-B0aFVgP2.d.mts} +25 -29
  64. package/dist/retention-purge-CCd_VXUf.d.mts +38 -0
  65. package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-D8jQpDG7.mjs} +1 -2
  66. package/dist/search/index.d.mts +1 -1
  67. package/dist/search/index.mjs +1 -1
  68. package/dist/sync/index.d.mts +113 -17
  69. package/dist/sync/index.mjs +421 -65
  70. package/dist/tenant/index.d.mts +8 -11
  71. package/dist/tenant/index.mjs +1 -2
  72. package/dist/testkit/index.d.mts +179 -23
  73. package/dist/testkit/index.mjs +421 -23
  74. package/dist/{timestamp.plugin-DpOWavVI.mjs → timestamp.plugin-B-IJrlYb.mjs} +192 -49
  75. package/dist/{to-plain-vksRrLtc.mjs → to-plain-CEKv_ylg.mjs} +2 -4
  76. package/dist/{to-plain-o5tUY2nV.d.mts → to-plain-Do-8jTKC.d.mts} +2 -16
  77. package/dist/{transaction-DmiB4k2P.mjs → transaction-C6Oj941P.mjs} +18 -19
  78. package/dist/{type-utils-CLzRFtIA.d.mts → type-utils-CKvuewAL.d.mts} +0 -2
  79. package/dist/{update-WgeAUJ_I.mjs → update-CYaJMu6j.mjs} +13 -23
  80. package/dist/usage/index.d.mts +2 -5
  81. package/dist/usage/index.mjs +8 -6
  82. package/dist/utils/index.d.mts +8 -10
  83. package/dist/utils/index.mjs +7 -7
  84. package/dist/{validation-chain.plugin-BAeC5eVT.d.mts → validation-chain.plugin-COYrUdd8.d.mts} +150 -48
  85. package/dist/{validation-chain.plugin-DRApTmkN.mjs → validation-chain.plugin-DJplVJ12.mjs} +210 -55
  86. package/llms.txt +33 -0
  87. package/package.json +29 -25
  88. package/skills/mongokit/SKILL.md +112 -0
  89. package/skills/mongokit/references/pagination-search.md +87 -0
  90. package/skills/mongokit/references/plugins-tenancy.md +103 -0
  91. package/skills/mongokit/references/repository-api.md +83 -0
  92. package/skills/mongokit/references/transactions-outbox.md +103 -0
package/README.md CHANGED
@@ -201,14 +201,17 @@ await orderRepo.withTransaction(async (txRepo) => {
201
201
  });
202
202
  ```
203
203
 
204
+ To serialise writers on a row, the write must change it. An update that sets a field to the value it already has is a no-op: it takes no write lock, so two transactions doing it at the same instant never conflict. Write something that changes (for example `$inc: { writes: 1 }` on a gate or lease row).
205
+
204
206
  ### Time Bounds And Concerns (`queryDefaults`)
205
207
 
206
208
  ```ts
207
- // Boot: every command is bounded; the boot check fails without it (and without CSOT timeoutMS).
208
- await mongoose.connect(uri, { timeoutMS: 30_000 });
209
+ // Boot: every command is bounded by a server-side maxTimeMS; the boot check fails without it.
210
+ // Do not pass `timeoutMS` to mongoose.connect(): the MongoDB driver ignores it since 7.8 (CVE-2026-119179).
211
+ await mongoose.connect(uri);
209
212
  configureQueryDefaults({ maxTimeMS: 5_000, writeConcern: { w: 'majority' } });
210
213
  configureAggregateDefaults({ maxTimeMs: 15_000 });
211
- assertQueryDefaultsConfigured(mongoose.connection);
214
+ assertQueryDefaultsConfigured();
212
215
 
213
216
  // Per repository, and per call (per call always wins):
214
217
  const repo = new Repository(Order, plugins, {}, { queryDefaults: { comment: 'orders' } });
@@ -529,6 +532,18 @@ await assertQueryPlan(() => repo.getAll({ filters: { status: 'open' }, sort: { a
529
532
  });
530
533
  ```
531
534
 
535
+ Reads are gated by default; pass `commands: ['findAndModify', 'update', 'delete']` to gate a write's match too.
536
+ `explainCommands(run, { connection, commands?, collections?, verbosity? })` returns the raw explain of every
537
+ command `run` sent (writes are explained, never re-run), for a plugin-built query such as a `leasePlugin` claim:
538
+
539
+ ```ts
540
+ import { explainCommands } from '@classytic/mongokit/testkit';
541
+ const { explains } = await explainCommands(() => jobs.lease({ leaseFor: 30_000, leasedBy }), {
542
+ connection, commands: ['findAndModify'], collections: ['jobs'],
543
+ });
544
+ explains[0].explain.executionStats; // what the claim examined
545
+ ```
546
+
532
547
  ## Kernel Conformance — `@classytic/mongokit/kernel-conformance`
533
548
 
534
549
  An **executable contract suite** for domain kernels built on `defineModels()`. A kernel that
@@ -1,13 +1,13 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { n as warn } from "./logger-K7dPmu2U.mjs";
3
- import { t as createError } from "./error-BuByZwKU.mjs";
4
- import { i as applyToQuery, r as applyToAggregate, u as resolveQueryOptions } from "./query-defaults-BxUcSOoF.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-D8jQpDG7.mjs";
2
+ import { l as resolveQueryOptions, n as applyToAggregate, r as applyToQuery } from "./query-defaults-DwvWUjZU.mjs";
3
+ import { t as createError } from "./error-DjdmPLWO.mjs";
4
+ import { n as warn } from "./logger-hbWOlj_X.mjs";
5
5
  import { calculateSkip, calculateTotalPages, shouldWarnDeepPagination, validateLimit, validatePage } from "./pagination/utils/limits.mjs";
6
6
  import mongoose from "mongoose";
7
7
  import { createTtlMemo } from "@classytic/repo-core/cache";
8
8
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
9
9
  import { CURSOR_ERROR_CODES } from "@classytic/repo-core/pagination";
10
- //#region src/pagination/utils/cursor-signing.ts
10
+ // src/pagination/utils/cursor-signing.ts
11
11
  /**
12
12
  * HMAC signing for pagination cursors.
13
13
  *
@@ -122,8 +122,7 @@ function verifySignature(token, secrets) {
122
122
  for (const key of secrets) if (matches(signature, sign(payload, key))) return payload;
123
123
  throw new Error("Invalid cursor token: signature does not verify (tampered, or issued under a retired key)");
124
124
  }
125
- //#endregion
126
- //#region src/pagination/defaults.ts
125
+ // src/pagination/defaults.ts
127
126
  /**
128
127
  * The policy lives on `globalThis` under a registered symbol, NOT in a module
129
128
  * `let`.
@@ -215,8 +214,7 @@ function define(target, key, explicit, fallback) {
215
214
  get: () => explicit !== void 0 ? explicit : policy()[key] ?? fallback
216
215
  });
217
216
  }
218
- //#endregion
219
- //#region src/pagination/utils/filter.ts
217
+ // src/pagination/utils/filter.ts
220
218
  /**
221
219
  * Combine the caller's filters with the keyset position predicate.
222
220
  *
@@ -327,8 +325,7 @@ function buildKeysetFilter(baseFilters, sort, cursorValue, cursorId, cursorValue
327
325
  if (orConditions.length === 0) return combine(baseFilters, { _id: { $in: [] } });
328
326
  return combine(baseFilters, { $or: orConditions });
329
327
  }
330
- //#endregion
331
- //#region src/pagination/utils/guards.ts
328
+ // src/pagination/utils/guards.ts
332
329
  /**
333
330
  * Pagination guards shared by every paged read: the deep-offset refusal, the unique `_id`
334
331
  * tiebreaker that makes a sort a total order, and the cursor SCOPE fingerprint — a hash of
@@ -446,8 +443,7 @@ function warnIfSortNotTotal(model, pipeline, warnFn) {
446
443
  warnedSortSites.add(site);
447
444
  warnFn(`[mongokit] aggregatePipelinePaginate on '${model}': the page sort is not provably total, so rows that tie can repeat or be skipped across pages. End the \$sort on a key unique per output row, then pass \`sortIsTotal: true\` (or sort on _id with no \$unwind/\$group/_id rewrite before the sort).`);
448
445
  }
449
- //#endregion
450
- //#region src/pagination/utils/cursor.ts
446
+ // src/pagination/utils/cursor.ts
451
447
  /**
452
448
  * Cursor Utilities
453
449
  *
@@ -455,12 +451,8 @@ function warnIfSortNotTotal(model, pipeline, warnFn) {
455
451
  * Cursors are base64-encoded JSON containing position data and metadata.
456
452
  */
457
453
  var cursor_exports = /* @__PURE__ */ __exportAll({
458
- decodeCursor: () => decodeCursor,
459
454
  encodeCursor: () => encodeCursor,
460
- readSortValue: () => readSortValue,
461
- resolveCursorFilter: () => resolveCursorFilter,
462
- validateCursorSort: () => validateCursorSort,
463
- validateCursorVersion: () => validateCursorVersion
455
+ resolveCursorFilter: () => resolveCursorFilter
464
456
  });
465
457
  /**
466
458
  * Encodes document values and sort metadata into a base64 cursor token
@@ -655,8 +647,7 @@ function resolveCursorFilter(after, sort, cursorVersion, baseFilters, minCursorV
655
647
  validateCursorSort(cursor.sort, sort);
656
648
  return buildKeysetFilter(baseFilters, buildSort, cursor.value, cursor.id, cursor.values);
657
649
  }
658
- //#endregion
659
- //#region src/pagination/utils/index-hint.ts
650
+ // src/pagination/utils/index-hint.ts
660
651
  /**
661
652
  * The only operators that give the query planner a *bounded equality* it can
662
653
  * lead an index with. Everything else (`$ne`, `$nin`, `$gt(e)`, `$lt(e)`,
@@ -789,12 +780,9 @@ function hasCompatibleKeysetIndex(indexes, filterFields, sort) {
789
780
  }
790
781
  return false;
791
782
  }
792
- //#endregion
793
- //#region src/pagination/utils/sort.ts
783
+ // src/pagination/utils/sort.ts
794
784
  var sort_exports = /* @__PURE__ */ __exportAll({
795
785
  getPrimaryField: () => getPrimaryField,
796
- invertSort: () => invertSort,
797
- normalizeSort: () => normalizeSort,
798
786
  validateKeysetSort: () => validateKeysetSort
799
787
  });
800
788
  /**
@@ -882,8 +870,7 @@ function invertSort(sort) {
882
870
  function getPrimaryField(sort) {
883
871
  return Object.keys(sort).find((k) => k !== "_id") || "_id";
884
872
  }
885
- //#endregion
886
- //#region src/pagination/PaginationEngine.ts
873
+ // src/pagination/PaginationEngine.ts
887
874
  /**
888
875
  * Pagination Engine
889
876
  *
@@ -1353,5 +1340,4 @@ var PaginationEngine = class {
1353
1340
  };
1354
1341
  }
1355
1342
  };
1356
- //#endregion
1357
1343
  export { resolveCursorSecrets as _, cursor_exports as a, PAGINATION_ERROR_CODES as c, withGroupTiebreak as d, withIdTiebreak as f, attachSignature as g, resetPaginationDefaults as h, validateKeysetSort as i, assertOffsetWithinCap as l, getPaginationDefaults as m, getPrimaryField as n, encodeCursor as o, configurePaginationDefaults as p, sort_exports as r, resolveCursorFilter as s, PaginationEngine as t, cursorScope as u, verifySignature as v };
@@ -1,8 +1,7 @@
1
- import { D as AnyDocument, c as MongokitPageExtras, f as CursorSecret, i as CountStrategy, l as OffsetPaginationOptions, s as KeysetPaginationOptions, t as AggregatePaginationOptions, u as PaginationConfig } from "./pagination-D6psses0.mjs";
1
+ import { D as AnyDocument, c as MongokitPageExtras, f as CursorSecret, i as CountStrategy, l as OffsetPaginationOptions, s as KeysetPaginationOptions, t as AggregatePaginationOptions, u as PaginationConfig } from "./pagination-BAM9cA4N.mjs";
2
2
  import { Model } from "mongoose";
3
3
  import { TtlMemo } from "@classytic/repo-core/cache";
4
4
  import { AggregatePaginationResult, KeysetPaginationResult, OffsetPaginationResult } from "@classytic/repo-core/pagination";
5
- //#region src/pagination/PaginationEngine.d.ts
6
5
  /**
7
6
  * Internal pagination config with required values
8
7
  */
@@ -138,5 +137,4 @@ declare class PaginationEngine<TDoc = AnyDocument> {
138
137
  */
139
138
  aggregatePaginate(options?: AggregatePaginationOptions): Promise<AggregatePaginationResult<TDoc, MongokitPageExtras>>;
140
139
  }
141
- //#endregion
142
140
  export { PaginationEngine as n, CountMemoKey as t };
@@ -1,7 +1,8 @@
1
- import { S as LookupOptions, _ as SessionOptions, b as WithTransactionOptions, c as DeleteResult, f as LookupPopulateOptions, g as ReadOptions, h as OperationOptions, i as CacheableOptions, l as FindOneAndUpdateOptions, n as AggregateOptions, o as CreateOptions, p as LookupPopulateResult, s as DeleteManyResult, t as AggregateCallOptions, u as GetByIdsOptions, v as UpdateManyResult, x as LookupBuilder, y as UpdateOptions } from "./operations-XiFgG5US.mjs";
2
- import { A as ObjectId, F as SortSpec$1, M as ReadPreferenceType, N as SelectSpec, c as MongokitPageExtras, i as CountStrategy, j as PopulateSpec, r as CollationOptions, t as AggregatePaginationOptions, u as PaginationConfig } from "./pagination-D6psses0.mjs";
3
- import { _ as RepositoryOptions, d as PluginType, f as PrioritizedHook, o as Middleware, p as RepositoryContext } from "./repository-MqAP409e.mjs";
4
- import { n as PaginationEngine } from "./PaginationEngine-CRHyuUtw.mjs";
1
+ import { A as ObjectId, F as SortSpec$1, M as ReadPreferenceType, N as SelectSpec, c as MongokitPageExtras, i as CountStrategy, j as PopulateSpec, r as CollationOptions, t as AggregatePaginationOptions, u as PaginationConfig } from "./pagination-BAM9cA4N.mjs";
2
+ import { r as RetentionPurgeRequest } from "./retention-purge-CCd_VXUf.mjs";
3
+ import { n as PaginationEngine } from "./PaginationEngine-BWb-c47a.mjs";
4
+ import { S as LookupOptions, _ as SessionOptions, b as WithTransactionOptions, c as DeleteResult, f as LookupPopulateOptions, g as ReadOptions, h as OperationOptions, i as CacheableOptions, l as FindOneAndUpdateOptions, n as AggregateOptions, o as CreateOptions, p as LookupPopulateResult, s as DeleteManyResult, t as AggregateCallOptions, u as GetByIdsOptions, v as UpdateManyResult, x as LookupBuilder, y as UpdateOptions } from "./operations-D6XsHx4e.mjs";
5
+ import { _ as RepositoryOptions, d as PluginType, f as PrioritizedHook, o as Middleware, p as RepositoryContext } from "./repository-B0aFVgP2.mjs";
5
6
  import { AggPaginationRequest, AggRequest, AggResult, ArchiveOptions, ArchiveResult, ArchiveSink, BulkUpsertOptions, BulkUpsertResult, ChangeEvent, FilterInput, KeysetAggPaginationResult, QueryOptions, RepoCapabilities, RepositoryBase, TenantPurgeOptions, TenantPurgeResult, TenantPurgeStrategy, WatchOptions } from "@classytic/repo-core/repository";
6
7
  import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
7
8
  import { Filter } from "@classytic/repo-core/filter";
@@ -9,7 +10,13 @@ import { RepositoryCacheHandle } from "@classytic/repo-core/cache";
9
10
  import { HttpError } from "@classytic/repo-core/errors";
10
11
  import { UpdateInput } from "@classytic/repo-core/update";
11
12
  import { AggregatePaginationResult, KeysetPaginationResult, OffsetPaginationResult, OffsetPaginationResultCore } from "@classytic/repo-core/pagination";
12
- //#region src/query/AggregationBuilder.d.ts
13
+ /**
14
+ * `purgeByFilter` / `purgeByField` options: repo-core's `TenantPurgeOptions`
15
+ * plus the audited `retentionPurge` (see `SessionOptions.retentionPurge`).
16
+ */
17
+ type RetentionTenantPurgeOptions = TenantPurgeOptions & {
18
+ retentionPurge?: RetentionPurgeRequest | undefined;
19
+ };
13
20
  /** Options for $vectorSearch stage (Atlas only) */
14
21
  interface VectorSearchOptions {
15
22
  /** Atlas Search index name */
@@ -475,8 +482,6 @@ declare class AggregationBuilder {
475
482
  * .exec(Model)
476
483
  * ```
477
484
  */
478
- //#endregion
479
- //#region src/Repository.d.ts
480
485
  /**
481
486
  * Plugin phase priorities (lower = runs first).
482
487
  *
@@ -865,7 +870,7 @@ declare class Repository<TDoc = unknown> extends RepositoryBase {
865
870
  }): Promise<string>;
866
871
  /**
867
872
  * Resumable keyset batches over `_id`: each batch is ONE bounded `find` (no long-lived server
868
- * cursor, so no cursor timeout and no CSOT lifetime budget), memory is one batch, and every
873
+ * cursor, so no cursor timeout and a bound on every batch), memory is one batch, and every
869
874
  * batch carries a `checkpoint`. Pass a checkpoint back as `after` to resume: rows written
870
875
  * behind it are not revisited, rows ahead of it are reached. A checkpoint is bound to the
871
876
  * collection, the post-policy filter (tenant included) and is refused elsewhere.
@@ -1397,8 +1402,26 @@ declare class Repository<TDoc = unknown> extends RepositoryBase {
1397
1402
  history?: string | false;
1398
1403
  /** Timestamp for the history entry — default `new Date()`. */
1399
1404
  at?: Date;
1405
+ /**
1406
+ * When the row entered its current state (the caller's read).
1407
+ * Adds `durationInPriorMs: max(0, occurredAt - priorAt)` to the
1408
+ * history entry, the same field primitives' `appendStatus` writes,
1409
+ * without a pre-read here. Pair it with a `where` (e.g.
1410
+ * `{ updatedAt: current.updatedAt }`) or `options.target` so a write
1411
+ * between the read and the claim makes the claim miss rather than
1412
+ * record a stale duration. Requires history (400 with `history: false`).
1413
+ */
1414
+ priorAt?: Date;
1415
+ /**
1416
+ * Extra fields merged into the history entry. May not contain the
1417
+ * reserved keys `status`, `occurredAt`, `by`, `note` or
1418
+ * `durationInPriorMs` (400). Requires history.
1419
+ */
1420
+ historyExtra?: Record<string, unknown>;
1400
1421
  }, options?: SessionOptions & {
1401
1422
  idField?: string;
1423
+ /** Forwarded to `claim()`: the caller's same-session read, pinned by version / `updatedAt`. */
1424
+ target?: Record<string, unknown>;
1402
1425
  }): Promise<TDoc>;
1403
1426
  /**
1404
1427
  * Optimistic-concurrency CAS via a version stamp.
@@ -1566,7 +1589,7 @@ declare class Repository<TDoc = unknown> extends RepositoryBase {
1566
1589
  * + strategy writes). See [actions/purge.ts](./actions/purge.ts) for
1567
1590
  * the port implementation.
1568
1591
  */
1569
- purgeByField(field: string, value: unknown, strategy: TenantPurgeStrategy, options?: TenantPurgeOptions): Promise<TenantPurgeResult>;
1592
+ purgeByField(field: string, value: unknown, strategy: TenantPurgeStrategy, options?: RetentionTenantPurgeOptions): Promise<TenantPurgeResult>;
1570
1593
  /**
1571
1594
  * Range/filter-scoped purge — see `StandardRepo.purgeByFilter` for the
1572
1595
  * cross-kit contract. The compliance primitive for "purge/anonymize a
@@ -1581,20 +1604,29 @@ declare class Repository<TDoc = unknown> extends RepositoryBase {
1581
1604
  * the same dual-dialect rule as `archiveByFilter` and every other verb.
1582
1605
  * See [actions/purge.ts](./actions/purge.ts) for the port.
1583
1606
  */
1584
- purgeByFilter(filter: Record<string, unknown> | Filter, strategy: TenantPurgeStrategy, options?: TenantPurgeOptions): Promise<TenantPurgeResult>;
1607
+ purgeByFilter(filter: Record<string, unknown> | Filter, strategy: TenantPurgeStrategy, options?: RetentionTenantPurgeOptions): Promise<TenantPurgeResult>;
1585
1608
  /**
1586
1609
  * Chunked cold-storage extraction — see `StandardRepo.archiveByFilter`
1587
1610
  * for the cross-kit contract (write-before-delete, at-least-once,
1588
1611
  * duplicate-tolerant sinks). Mongokit composes the kit-agnostic
1589
- * `runChunkedArchive` orchestrator with `createMongoArchivePort`
1612
+ * `runChunkedArchive` orchestrator with `createMongoArchiveRun`
1590
1613
  * (`_id`-ordered lean reads + plugin-routed deleteMany removal). See
1591
1614
  * [actions/archive.ts](./actions/archive.ts) for the port.
1592
1615
  *
1616
+ * `retentionPurge` rides every chunk delete with an attestation of the ids the
1617
+ * sink acknowledged, so a fence built with `allowArchive` (or `allowPurge`)
1618
+ * admits it; validated before any chunk is read. Each row is deleted only if its
1619
+ * `updatedAt` (+ `versionField`) still equals the exported value; an edited row stays
1620
+ * live for the next run.
1621
+ *
1593
1622
  * Accepts Filter IR or a Mongo-shaped filter record — compiled once via
1594
1623
  * `compileFilterToMongo`, same dual-dialect rule as every other verb.
1595
1624
  */
1596
1625
  archiveByFilter(filter: Record<string, unknown> | Filter, sink: ArchiveSink<TDoc>, options?: ArchiveOptions & {
1597
1626
  session?: ClientSession;
1627
+ retentionPurge?: RetentionPurgeRequest | undefined;
1628
+ /** Rows never change: skip the unchanged-since-export pin (refused without it when the schema has no timestamps). */
1629
+ immutable?: boolean | undefined;
1598
1630
  }): Promise<ArchiveResult>;
1599
1631
  /**
1600
1632
  * Many keyed upserts in ONE command with an exact per-row outcome (repo-core `bulkUpsert` IR).
@@ -1989,5 +2021,4 @@ declare class Repository<TDoc = unknown> extends RepositoryBase {
1989
2021
  _handleError(error: Error): HttpError;
1990
2022
  private _translateError;
1991
2023
  }
1992
- //#endregion
1993
- export { AggregationBuilder as a, ProjectionSpec as c, VectorSearchOptions as d, TransitionMachine as i, SortOrder as l, HOOK_PRIORITY as n, AggregationPlan as o, Repository as r, GroupSpec as s, GetAllParams as t, SortSpec as u };
2024
+ export { AggregationBuilder as a, ProjectionSpec as c, VectorSearchOptions as d, RetentionTenantPurgeOptions as f, TransitionMachine as i, SortOrder as l, HOOK_PRIORITY as n, AggregationPlan as o, Repository as r, GroupSpec as s, GetAllParams as t, SortSpec as u };